RE: Possible bug in scsi_lib.c:scsi_req_map_sg()
Hello All, I am noticing the following panic on SLES 10 ( as well as Redhat 5 ). I modified "scsi_lib.c" to print some debugging information. Our driver is a Multipath failover module and we are using "scsi_execute_async" API for routing IO's. In earlier kernels we used "scsi_do_req" API. Messages Mar 1 20:20:35 linux kernel: mppLnx_do_queuecommand :: cs 10, bufflen 110592 use_sg 27 Mar 1 20:20:35 linux kernel: mppLnx_do_queuecommand :: cs 10, bufflen 4096 use_sg 1 Mar 1 20:20:35 linux kernel: mppLnx_do_queuecommand :: cs 10, bufflen 4096 use_sg 1 Mar 1 20:20:35 linux kernel: mppLnx_do_queuecommand :: cs 10, bufflen 4096 use_sg 1 Mar 1 20:20:35 linux kernel: mppLnx_do_queuecommand :: cs 10, bufflen 4096 use_sg 1 Mar 1 20:20:35 linux kernel: mppLnx_do_queuecommand :: cs 10, bufflen 7168 use_sg 7 Mar 1 20:20:35 linux kernel: scsi_req_map_sg:: calling bio_put Mar 1 20:20:35 linux kernel: scsi_req_map_sg::i=2,len=1024,data_len=3072,off=2048,PAGE_SIZE=4096,byte s=1024,nr_vecs=0, nr_pages=0 Mar 1 20:20:35 linux kernel: scsi_req_map_sg:: bio->bi_io_vec is NULL Mar 1 20:20:35 linux kernel: Unable to handle kernel paging request at 82bcfe3c0030 RIP: Mar 1 20:20:35 linux kernel: {kmem_cache_free+86} Mar 1 20:20:35 linux kernel: PGD 0 Mar 1 20:20:35 linux kernel: Oops: [1] SMP Mar 1 20:20:35 linux kernel: last sysfs file: /class/mppUpper/mppUpper/dev Mar 1 20:20:35 linux kernel: CPU 0 Mar 1 20:20:35 linux kernel: Modules linked in: ipv6 af_packet button battery ac apparmor aamatch_pcre loop dm_mod shpchp pci_hotplug hw_random ide_cd ehci_hcd uhci_hcd cdrom usbcore e1000 i8xx_tco parport_pc lp parport ext3 jbd mppVhba edd fan thermal processor mptfc aacraid lpfc qla2xxx firmware_class scsi_transport_fc mptspi mptscsih mptbase scsi_transport_spi ata_piix libata piix mppUpper sg sd_mod scsi_mod ide_disk ide_core Mar 1 20:20:35 linux kernel: Pid: 1085, comm: mpp_dcr Tainted: G U 2.6.16.16-1.6-smp #1 Mar 1 20:20:35 linux kernel: RIP: 0010:[] {kmem_cache_free+86} Mar 1 20:20:35 linux kernel: RSP: 0018:81007c2fdd88 EFLAGS: 00010086 Mar 1 20:20:35 linux kernel: RAX: 82bcfe3c RBX: 810037fbd000 RCX: 003f Mar 1 20:20:35 linux kernel: RDX: 8100c000 RSI: RDI: 0007f000 Mar 1 20:20:35 linux kernel: RBP: 810037fdf640 R08: 803d2240 R09: 81007c2fdb78 Mar 1 20:20:35 linux kernel: R10: 0001 R11: 8015a4e0 R12: 81007da72880 Mar 1 20:20:35 linux kernel: R13: 0296 R14: 0800 R15: Mar 1 20:20:35 linux kernel: FS: 2b7d68de36d0() GS:80444000() knlGS: Mar 1 20:20:35 linux kernel: CS: 0010 DS: ES: CR0: 8005003b Mar 1 20:20:35 linux kernel: CR2: 82bcfe3c0030 CR3: 67dc6000 CR4: 06e0 Mar 1 20:20:35 linux kernel: Process mpp_dcr (pid: 1085, threadinfo 81007c2fc000, task 81007c9bd850) Mar 1 20:20:35 linux kernel: Stack: 81007c69f328 0400 810063368d00 Mar 1 20:20:35 linux kernel:810037fdf640 0400 810063368d00 8017ef77 Mar 1 20:20:35 linux kernel:0400 810054239188 Mar 1 20:20:35 linux kernel: Call Trace: {bio_free+51} {:scsi_mod:scsi_execute_async+480} Mar 1 20:20:35 linux kernel: {:mppVhba:mppLnx_do_queuecommand+2577} Mar 1 20:20:35 linux kernel: {:mppVhba:mppLnx_scsi_done+0} {:mppVhba:mppLnx_dpc_handler+531} Mar 1 20:20:35 linux kernel:{child_rip+8} {:mppVhba:mppLnx_dpc_handler+0} Mar 1 20:20:35 linux kernel:{child_rip+0} Mar 1 20:20:35 linux kernel: Mar 1 20:20:35 linux kernel: Code: 48 8b 48 30 0f b7 51 28 65 8b 04 25 30 00 00 00 39 c2 0f 84 Mar 1 20:20:35 linux kernel: RIP {kmem_cache_free+86} RSP Mar 1 20:20:35 linux kernel: CR2: 82bcfe3c0030 Scsi_lib.c ( scsi_req_map_sg ) -- static int scsi_req_map_sg(struct request *rq, struct scatterlist *sgl, int nsegs, unsigned bufflen, gfp_t gfp) { struct request_queue *q = rq->q; int nr_pages = (bufflen + sgl[0].offset + PAGE_SIZE - 1) >> PAGE_SHIFT; unsigned int data_len = 0, len, bytes, off; struct page *page; struct bio *bio = NULL; int i, err, nr_vecs = 0; for (i = 0; i < nsegs; i++) { page = sgl[i].page; off = sgl[i].offset; len = sgl[i].length; data_len += len; while (len > 0) { bytes = min_t(unsigned int, len, PAGE_SIZE - off); if (!bio) { nr_vecs = min_t(int, BIO_MAX_PAGES, nr_pages); nr_pages -= nr_vecs; bio = bio_alloc(gfp, nr_vecs); if (!bio) { err = -ENOMEM;
Re: Possible bug in scsi_lib.c:scsi_req_map_sg()
Dachepalli, Sudhir wrote: > scsi_req_map_sg::i=2,len=1024,data_len=3072,off=2048,PAGE_SIZE=4096,byte > s=1024,nr_vecs=0, nr_pages=0 > if (bio_add_pc_page(q, bio, page, bytes, off) != > bytes) { > printk("scsi_req_map_sg:: calling > bio_put \n"); > > printk("scsi_req_map_sg::i=%d,len=%d,data_len=%d,off=%d,PAGE_SIZE=%ld,by > tes=%d,nr_vecs=%d, nr_pages=%d\n", > > i,len,data_len,off,PAGE_SIZE,bytes,nr_vecs,nr_pages); > if( bio->bi_io_vec == NULL ) I think Boaz's first patch in this thread that counts the offsets correctly should be merged. I am not sure about the second one. If allocating a bio with zero vecs is valid, then I guess the patch should be merged. bio_alloc_bioset looks like it allows this, but people probably never do it (just when they hit bugs like this one :)). But I think if we are counting segments correctly we will not need that patch for this problem will we Boaz? Boaz, maybe you could also send the first patch in a seperate mail so that it can be merged (I do not think James wants to cut and paste two patches from one mail). Also, you do not want to use scsi_execute_async. I am trying to kill it. The original patches, never had that function and the later patches had a warning that you should not use it and that you should just use the request and the blk_rq* helpers directly. - To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Possible bug in scsi_lib.c:scsi_req_map_sg()
Mike Christie wrote: > Dachepalli, Sudhir wrote: >> scsi_req_map_sg::i=2,len=1024,data_len=3072,off=2048,PAGE_SIZE=4096,byte >> s=1024,nr_vecs=0, nr_pages=0 > > >> if (bio_add_pc_page(q, bio, page, bytes, off) != >> bytes) { >> printk("scsi_req_map_sg:: calling >> bio_put \n"); >> >> printk("scsi_req_map_sg::i=%d,len=%d,data_len=%d,off=%d,PAGE_SIZE=%ld,by >> tes=%d,nr_vecs=%d, nr_pages=%d\n", >> >> i,len,data_len,off,PAGE_SIZE,bytes,nr_vecs,nr_pages); >> if( bio->bi_io_vec == NULL ) > > > I think Boaz's first patch in this thread that counts the offsets > correctly should be merged. Just one clarification. When I wrote scsi_execute_async, it was meant as a temp hack so we would kill scsi_request and fix scatterlists for drivers like iscsi_tcp and ib_iser, but in the original patches and the patches I am sending now I modify the blk helpers and have sg use them directly. scsi_execute_async was meant to be temporary only supported what sg and st and other mainline drivers were sending at the time, so it did not support something like: sg[0].offset 0; sg[0].length = 4096; sg[1].offset = 1024; sg[1].offset = 3072; because sg and st can only have a offset for the first sg element (offsets for the sg element is supported). If we are going to support whatever scsi_do_req supported the we should merge Boaz's patch. If scsi_execute_async is going to be limited to what is in mainline until I can kill it, then we may not want to merge Boaz's patch and just have people convert the code to use blk_get_request, blk_rq_map_kern or blk_rq_map_user and blk_execute_rq_nowait. - To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] iscsi tcp set queue dma alignment to zero
Pete Wyckoff wrote: > Add a slave_configure function to iSCSI TCP to remove any DMA > alignment restriction. This permits the use of direct IO from > arbitrary addresses. > > Signed-off-by: Pete Wyckoff <[EMAIL PROTECTED]> > --- > drivers/scsi/iscsi_tcp.c | 11 +++ > 1 files changed, 11 insertions(+), 0 deletions(-) > > diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c > index 4376840..f48eedd 100644 > --- a/drivers/scsi/iscsi_tcp.c > +++ b/drivers/scsi/iscsi_tcp.c > @@ -2132,6 +2132,16 @@ static void iscsi_tcp_session_destroy(struct > iscsi_cls_session *cls_session) > iscsi_session_teardown(cls_session); > } > > +/* > + * New device attached. Turn off the DMA alignment restriction on > + * the request queue. > + */ > +static int iscsi_tcp_slave_configure(struct scsi_device *sdev) > +{ > + blk_queue_dma_alignment(sdev->request_queue, 0); > + return 0; > +} > + I think the comments are not needed, but that is not a big deal. I will put this in my tree and send it to James if he does not pick it up from linux-scsi. Thanks for the patch. Erez, I do not think ib_iser should have any limit either (I only looked at the code for a little bit though). You may want to do the the same for iser. - To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: Possible bug in scsi_lib.c:scsi_req_map_sg()
Mike, I applied "patch 1" posted by Boaz Harrosh to my SLES 10 kernel. So far IO's are running for 45 minutes which is the longest in my numerous re-tries. We were not aware that "scsi_execute_async" was temperory workaround. Where is the depricated warning that you mentioned about ? I tried to look in scsi_lib.c and scsi_device.h Regards, Sudhir -Original Message- From: Mike Christie [mailto:[EMAIL PROTECTED] Sent: Friday, March 02, 2007 4:00 PM To: Dachepalli, Sudhir Cc: Benny Halevy; Jens Axboe; Boaz Harrosh; linux-scsi@vger.kernel.org; James Bottomley Subject: Re: Possible bug in scsi_lib.c:scsi_req_map_sg() Mike Christie wrote: > Dachepalli, Sudhir wrote: >> scsi_req_map_sg::i=2,len=1024,data_len=3072,off=2048,PAGE_SIZE=4096,b >> yte >> s=1024,nr_vecs=0, nr_pages=0 > > >> if (bio_add_pc_page(q, bio, page, bytes, off) != >> bytes) { >> printk("scsi_req_map_sg:: calling >> bio_put \n"); >> >> printk("scsi_req_map_sg::i=%d,len=%d,data_len=%d,off=%d,PAGE_SIZE=%ld >> ,by >> tes=%d,nr_vecs=%d, nr_pages=%d\n", >> >> i,len,data_len,off,PAGE_SIZE,bytes,nr_vecs,nr_pages); >> if( bio->bi_io_vec == NULL ) > > > I think Boaz's first patch in this thread that counts the offsets > correctly should be merged. Just one clarification. When I wrote scsi_execute_async, it was meant as a temp hack so we would kill scsi_request and fix scatterlists for drivers like iscsi_tcp and ib_iser, but in the original patches and the patches I am sending now I modify the blk helpers and have sg use them directly. scsi_execute_async was meant to be temporary only supported what sg and st and other mainline drivers were sending at the time, so it did not support something like: sg[0].offset 0; sg[0].length = 4096; sg[1].offset = 1024; sg[1].offset = 3072; because sg and st can only have a offset for the first sg element (offsets for the sg element is supported). If we are going to support whatever scsi_do_req supported the we should merge Boaz's patch. If scsi_execute_async is going to be limited to what is in mainline until I can kill it, then we may not want to merge Boaz's patch and just have people convert the code to use blk_get_request, blk_rq_map_kern or blk_rq_map_user and blk_execute_rq_nowait. - To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/3] tgt fixes
This patchset fixes sense buffer handling bugs and scsi command leak with cleanups to remove bio hacks. The patchset are made over scsi-rc-fixes tree. - To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] tgt: rm bio hacks in scsi tgt
From: Mike Christie <[EMAIL PROTECTED]> scsi tgt breaks up a command into multple scatterlists if we cannot fit all the data in one. This was because the block rq helpers did not support large requests and because we can get a command of any old size so it is hard to preallocate pages for scatterlist large enough (we cannot really preallocate pages with the bio map user path). In 2.6.20, we added large request support to the block layer helper, blk_rq_map_user. And at LSF, we talked about increasing SCSI_MAX_PHYS_SEGMENTS for scsi tgt if we want to support really really :) large (greater than 256 * PAGE_SIZE in the worst mapping case) requests. The only target currently implemented does not even support the multiple scatterlists stuff and only supports smaller requests, so this patch just coverts scsi tgt to use blk_rq_map_user. Signed-off-by: Mike Christie <[EMAIL PROTECTED]> Signed-off-by: FUJITA Tomonori <[EMAIL PROTECTED]> --- drivers/scsi/scsi_tgt_lib.c | 133 +++ include/scsi/scsi_cmnd.h|3 - 2 files changed, 34 insertions(+), 102 deletions(-) diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c index d402aff..47c29a9 100644 --- a/drivers/scsi/scsi_tgt_lib.c +++ b/drivers/scsi/scsi_tgt_lib.c @@ -28,7 +28,6 @@ #include #include #include #include -#include <../drivers/md/dm-bio-list.h> #include "scsi_tgt_priv.h" @@ -42,9 +41,8 @@ static struct kmem_cache *scsi_tgt_cmd_c struct scsi_tgt_cmd { /* TODO replace work with James b's code */ struct work_struct work; - /* TODO replace the lists with a large bio */ - struct bio_list xfer_done_list; - struct bio_list xfer_list; + /* TODO fix limits of some drivers */ + struct bio *bio; struct list_head hash_list; struct request *rq; @@ -93,7 +91,12 @@ struct scsi_cmnd *scsi_host_get_command( if (!tcmd) goto put_dev; - rq = blk_get_request(shost->uspace_req_q, write, gfp_mask); + /* +* The blk helpers are used to the READ/WRITE requests +* transfering data from a initiator point of view. Since +* we are in target mode we want the opposite. +*/ + rq = blk_get_request(shost->uspace_req_q, !write, gfp_mask); if (!rq) goto free_tcmd; @@ -111,8 +114,6 @@ struct scsi_cmnd *scsi_host_get_command( rq->cmd_flags |= REQ_TYPE_BLOCK_PC; rq->end_io_data = tcmd; - bio_list_init(&tcmd->xfer_list); - bio_list_init(&tcmd->xfer_done_list); tcmd->rq = rq; return cmd; @@ -157,22 +158,6 @@ void scsi_host_put_command(struct Scsi_H } EXPORT_SYMBOL_GPL(scsi_host_put_command); -static void scsi_unmap_user_pages(struct scsi_tgt_cmd *tcmd) -{ - struct bio *bio; - - /* must call bio_endio in case bio was bounced */ - while ((bio = bio_list_pop(&tcmd->xfer_done_list))) { - bio_endio(bio, bio->bi_size, 0); - bio_unmap_user(bio); - } - - while ((bio = bio_list_pop(&tcmd->xfer_list))) { - bio_endio(bio, bio->bi_size, 0); - bio_unmap_user(bio); - } -} - static void cmd_hashlist_del(struct scsi_cmnd *cmd) { struct request_queue *q = cmd->request->q; @@ -185,6 +170,11 @@ static void cmd_hashlist_del(struct scsi spin_unlock_irqrestore(&qdata->cmd_hash_lock, flags); } +static void scsi_unmap_user_pages(struct scsi_tgt_cmd *tcmd) +{ + blk_rq_unmap_user(tcmd->bio); +} + static void scsi_tgt_cmd_destroy(struct work_struct *work) { struct scsi_tgt_cmd *tcmd = @@ -193,16 +183,6 @@ static void scsi_tgt_cmd_destroy(struct dprintk("cmd %p %d %lu\n", cmd, cmd->sc_data_direction, rq_data_dir(cmd->request)); - /* -* We fix rq->cmd_flags here since when we told bio_map_user -* to write vm for WRITE commands, blk_rq_bio_prep set -* rq_data_dir the flags to READ. -*/ - if (cmd->sc_data_direction == DMA_TO_DEVICE) - cmd->request->cmd_flags |= REQ_RW; - else - cmd->request->cmd_flags &= ~REQ_RW; - scsi_unmap_user_pages(tcmd); scsi_host_put_command(scsi_tgt_cmd_to_host(cmd), cmd); } @@ -215,6 +195,7 @@ static void init_scsi_tgt_cmd(struct req struct list_head *head; tcmd->tag = tag; + tcmd->bio = NULL; INIT_WORK(&tcmd->work, scsi_tgt_cmd_destroy); spin_lock_irqsave(&qdata->cmd_hash_lock, flags); head = &qdata->cmd_hash[cmd_hashfn(tag)]; @@ -419,52 +400,33 @@ static int scsi_map_user_pages(struct sc struct request *rq = cmd->request; void *uaddr = tcmd->buffer; unsigned int len = tcmd->bufflen; - struct bio *bio; int err; - while (len > 0) { - dprintk("%lx %u\n", (unsigned long) uaddr, len); - bio = bio_map_user(q, NULL, (unsigned long) uaddr, len, rw); -
[PATCH 3/3] tgt: fix scsi command leak
The failure to map user-space pages leads to scsi command leak. It can happens mostly because of user-space daemon bugs (or OOM). This patch makes tgt just notify a LLD of the failure with sense when blk_rq_map_user() fails. Signed-off-by: FUJITA Tomonori <[EMAIL PROTECTED]> Signed-off-by: Mike Christie <[EMAIL PROTECTED]> --- drivers/scsi/scsi_tgt_lib.c | 23 --- 1 files changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c index dc8781a..c05dff9 100644 --- a/drivers/scsi/scsi_tgt_lib.c +++ b/drivers/scsi/scsi_tgt_lib.c @@ -459,6 +459,16 @@ static struct request *tgt_cmd_hash_look return rq; } +static void scsi_tgt_build_sense(unsigned char *sense_buffer, unsigned char key, +unsigned char asc, unsigned char asq) +{ + sense_buffer[0] = 0x70; + sense_buffer[2] = key; + sense_buffer[7] = 0xa; + sense_buffer[12] = asc; + sense_buffer[13] = asq; +} + int scsi_tgt_kspace_exec(int host_no, int result, u64 tag, unsigned long uaddr, u32 len, unsigned long sense_uaddr, u32 sense_len, u8 rw) @@ -514,9 +524,16 @@ int scsi_tgt_kspace_exec(int host_no, in if (len) { err = scsi_map_user_pages(rq->end_io_data, cmd, uaddr, len, rw); if (err) { - eprintk("%p %d\n", cmd, err); - err = -EAGAIN; - goto done; + /* +* user-space daemon bugs or OOM +* TODO: we can do better for OOM. +*/ + eprintk("cmd %p ret %d uaddr %lx len %d rw %d\n", + cmd, err, uaddr, len, rw); + cmd->result = SAM_STAT_CHECK_CONDITION; + memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); + scsi_tgt_build_sense(cmd->sense_buffer, +HARDWARE_ERROR, 0, 0); } } err = scsi_tgt_transfer_response(cmd); -- 1.4.3.2 - To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3] tgt: fix sesnse buffer problems
This patch simplify the way to notify LLDs of the command completion and addresses the following sense buffer problems: - can't handle both data and sense. - forces user-space to use aligned sense buffer tgt copies sense_data from userspace to cmnd->sense_buffer (if necessary), maps user-space pages (if necessary) and then calls host->transfer_response (host->transfer_data is removed). Signed-off-by: FUJITA Tomonori <[EMAIL PROTECTED]> Signed-off-by: Mike Christie <[EMAIL PROTECTED]> --- drivers/scsi/ibmvscsi/ibmvstgt.c | 21 ++- drivers/scsi/scsi_tgt_if.c |6 +- drivers/scsi/scsi_tgt_lib.c | 120 +++-- drivers/scsi/scsi_tgt_priv.h |5 +- include/scsi/scsi_host.h | 19 ++- include/scsi/scsi_tgt_if.h |6 +- 6 files changed, 44 insertions(+), 133 deletions(-) diff --git a/drivers/scsi/ibmvscsi/ibmvstgt.c b/drivers/scsi/ibmvscsi/ibmvstgt.c index e28260f..07e5cbe 100644 --- a/drivers/scsi/ibmvscsi/ibmvstgt.c +++ b/drivers/scsi/ibmvscsi/ibmvstgt.c @@ -273,23 +273,9 @@ static int ibmvstgt_rdma(struct scsi_cmn rest -= mlen; } out: - return 0; } -static int ibmvstgt_transfer_data(struct scsi_cmnd *sc, - void (*done)(struct scsi_cmnd *)) -{ - struct iu_entry *iue = (struct iu_entry *) sc->SCp.ptr; - int err; - - err = srp_transfer_data(sc, &vio_iu(iue)->srp.cmd, ibmvstgt_rdma, 1, 1); - - done(sc); - - return err; -} - static int ibmvstgt_cmd_done(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)) { @@ -297,7 +283,11 @@ static int ibmvstgt_cmd_done(struct scsi struct iu_entry *iue = (struct iu_entry *) sc->SCp.ptr; struct srp_target *target = iue->target; - dprintk("%p %p %x\n", iue, target, vio_iu(iue)->srp.cmd.cdb[0]); + dprintk("%p %p %x %u\n", iue, target, vio_iu(iue)->srp.cmd.cdb[0], + cmd->usg_sg); + + if (sc->use_sg) + srp_transfer_data(sc, &vio_iu(iue)->srp.cmd, ibmvstgt_rdma, 1, 1); spin_lock_irqsave(&target->lock, flags); list_del(&iue->ilist); @@ -794,7 +784,6 @@ static struct scsi_host_template ibmvstg .use_clustering = DISABLE_CLUSTERING, .max_sectors= DEFAULT_MAX_SECTORS, .transfer_response = ibmvstgt_cmd_done, - .transfer_data = ibmvstgt_transfer_data, .eh_abort_handler = ibmvstgt_eh_abort_handler, .tsk_mgmt_response = ibmvstgt_tsk_mgmt_response, .shost_attrs= ibmvstgt_attrs, diff --git a/drivers/scsi/scsi_tgt_if.c b/drivers/scsi/scsi_tgt_if.c index f5d4412..7e18310 100644 --- a/drivers/scsi/scsi_tgt_if.c +++ b/drivers/scsi/scsi_tgt_if.c @@ -179,10 +179,12 @@ static int event_recv_msg(struct tgt_eve switch (ev->hdr.type) { case TGT_UEVENT_CMD_RSP: err = scsi_tgt_kspace_exec(ev->p.cmd_rsp.host_no, - ev->p.cmd_rsp.tag, ev->p.cmd_rsp.result, - ev->p.cmd_rsp.len, + ev->p.cmd_rsp.tag, ev->p.cmd_rsp.uaddr, + ev->p.cmd_rsp.len, + ev->p.cmd_rsp.sense_uaddr, + ev->p.cmd_rsp.sense_len, ev->p.cmd_rsp.rw); break; case TGT_UEVENT_TSK_MGMT_RSP: diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c index 47c29a9..dc8781a 100644 --- a/drivers/scsi/scsi_tgt_lib.c +++ b/drivers/scsi/scsi_tgt_lib.c @@ -47,9 +47,6 @@ struct scsi_tgt_cmd { struct list_head hash_list; struct request *rq; u64 tag; - - void *buffer; - unsigned bufflen; }; #define TGT_HASH_ORDER 4 @@ -330,10 +327,14 @@ static void scsi_tgt_cmd_done(struct scs dprintk("cmd %p %lu\n", cmd, rq_data_dir(cmd->request)); scsi_tgt_uspace_send_status(cmd, tcmd->tag); + + if (cmd->request_buffer) + scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len); + queue_work(scsi_tgtd, &tcmd->work); } -static int __scsi_tgt_transfer_response(struct scsi_cmnd *cmd) +static int scsi_tgt_transfer_response(struct scsi_cmnd *cmd) { struct Scsi_Host *shost = scsi_tgt_cmd_to_host(cmd); int err; @@ -346,30 +347,12 @@ static int __scsi_tgt_transfer_response( case SCSI_MLQUEUE_DEVICE_BUSY: return -EAGAIN; } - return 0; } -static void scsi_tgt_transfer_response(struct scsi_cmnd *cmd) -{ - struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data; - int err; - - err = __scsi_tgt_transfer_response(cmd); - if (!err) - return; - - cmd->result = DID_BUS_BU