WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [linux-2.6.18-xen] pvSCSI: Sanity check for REPORT_LUN e

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [linux-2.6.18-xen] pvSCSI: Sanity check for REPORT_LUN emulation
From: "Xen patchbot-linux-2.6.18-xen" <patchbot-linux-2.6.18-xen@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 16 Jul 2008 07:30:13 -0700
Delivery-date: Wed, 16 Jul 2008 07:30:22 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1216203554 -3600
# Node ID bd4b58143713a9d379570707a755079c7cb4f62d
# Parent  a682229d0eacf0bdd25b87a27143d451792f251b
pvSCSI: Sanity check for REPORT_LUN emulation

- Sanity check for REPORT_LUN emulation.
- Return "residual" value from backend to frontend. The residual value
  is used to represent difference between request size the frontend
  requested and size backend actually responded.

Signed-off-by: Tomonari Horikoshi <t.horikoshi@xxxxxxxxxxxxxx>
Signed-off-by: Jun Kamada <kama@xxxxxxxxxxxxxx>
---
 drivers/xen/scsiback/common.h      |    3 -
 drivers/xen/scsiback/emulate.c     |   83 ++++++++++++++++++++++++++-----------
 drivers/xen/scsiback/scsiback.c    |   16 ++++---
 drivers/xen/scsifront/scsifront.c  |    2 
 include/xen/interface/io/vscsiif.h |    4 +
 5 files changed, 76 insertions(+), 32 deletions(-)

diff -r a682229d0eac -r bd4b58143713 drivers/xen/scsiback/common.h
--- a/drivers/xen/scsiback/common.h     Tue Jul 15 16:39:39 2008 +0100
+++ b/drivers/xen/scsiback/common.h     Wed Jul 16 11:19:14 2008 +0100
@@ -124,6 +124,7 @@ typedef struct {
        grant_ref_t gref[VSCSIIF_SG_TABLESIZE];
 
        int32_t rslt;
+       uint32_t resid;
        uint8_t sense_buffer[VSCSIIF_SENSE_BUFFERSIZE];
 
        struct list_head free_list;
@@ -169,7 +170,7 @@ void scsiback_release_translation_entry(
 
 void scsiback_cmd_exec(pending_req_t *pending_req);
 void scsiback_do_resp_with_sense(char *sense_buffer, int32_t result,
-                               pending_req_t *pending_req);
+                       uint32_t resid, pending_req_t *pending_req);
 void scsiback_fast_flush_area(pending_req_t *req);
 
 void scsiback_rsp_emulation(pending_req_t *pending_req);
diff -r a682229d0eac -r bd4b58143713 drivers/xen/scsiback/emulate.c
--- a/drivers/xen/scsiback/emulate.c    Tue Jul 15 16:39:39 2008 +0100
+++ b/drivers/xen/scsiback/emulate.c    Wed Jul 16 11:19:14 2008 +0100
@@ -73,6 +73,10 @@
 #define VSCSI_MAX_SCSI_OP_CODE         256
 static unsigned char bitmap[VSCSI_MAX_SCSI_OP_CODE];
 
+/* REPORT LUNS Header*/
+#define VSCSI_REPORT_LUNS_HEADER       8
+
+
 /*
   Emulation routines for each SCSI op_code.
 */
@@ -97,7 +101,8 @@ static void resp_not_supported_cmd(pendi
 {
        scsiback_mk_sense_buffer(pending_req->sense_buffer, ILLEGAL_REQUEST,
                INVALID_OPCODE, 0);
-       pending_req->rslt = check_condition_result;
+       pending_req->resid = 0;
+       pending_req->rslt  = check_condition_result;
 }
 
 
@@ -180,6 +185,21 @@ static int __copy_from_sg(struct scatter
        return 0;
 }
 
+static int __nr_luns_under_host(struct vscsibk_info *info)
+{
+       struct v2p_entry *entry;
+       struct list_head *head = &(info->v2p_entry_lists);
+       unsigned long flags;
+       int lun_cnt = 0;
+
+       spin_lock_irqsave(&info->v2p_lock, flags);
+       list_for_each_entry(entry, head, l) {
+                       lun_cnt++;
+       }
+       spin_unlock_irqrestore(&info->v2p_lock, flags);
+
+       return (lun_cnt);
+}
 
 /* quoted scsi_debug.c/resp_report_luns() */
 static void __report_luns(pending_req_t *pending_req, void *data)
@@ -190,9 +210,11 @@ static void __report_luns(pending_req_t 
        unsigned int        nr_seg  = pending_req->nr_segments;
        unsigned char *cmd = (unsigned char *)pending_req->cmnd;
        
-       unsigned char *rq_buff = NULL;
+       unsigned char *buff = NULL;
        unsigned char alloc_len;
-       unsigned int buff_len = 0;
+       unsigned int alloc_luns = 0;
+       unsigned int req_bufflen = 0;
+       unsigned int actual_len = 0;
        int select_report = (int)cmd[2];
        int i, lun_cnt = 0, lun, upper, err = 0;
        
@@ -202,25 +224,31 @@ static void __report_luns(pending_req_t 
        
        struct scsi_lun *one_lun;
 
-       alloc_len = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24);
-       if ((alloc_len < 4) || (select_report != 0))
+       req_bufflen = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24);
+       if ((req_bufflen < 4) || (select_report != 0))
                goto fail;
-       
-       for (i = 0; i < nr_seg; i++)
-               buff_len += pending_req->sgl[i].length;
-
-       if ((rq_buff = kmalloc(buff_len, GFP_KERNEL)) == NULL) {
+
+       alloc_luns = __nr_luns_under_host(info);
+       alloc_len  = sizeof(struct scsi_lun) * alloc_luns
+                               + VSCSI_REPORT_LUNS_HEADER;
+
+       if ((buff = kmalloc(alloc_len, GFP_KERNEL)) == NULL) {
                printk(KERN_ERR "scsiback:%s kmalloc err\n", __FUNCTION__);
                goto fail;
        }
 
-       memset(rq_buff, 0, buff_len);
-
-       one_lun = (struct scsi_lun *) &rq_buff[8];
+       memset(buff, 0, alloc_len);
+
+       one_lun = (struct scsi_lun *) &buff[8];
        spin_lock_irqsave(&info->v2p_lock, flags);
        list_for_each_entry(entry, head, l) {
                if ((entry->v.chn == channel) &&
                    (entry->v.tgt == target)) {
+                       
+                       /* check overflow */
+                       if (lun_cnt >= alloc_luns)
+                               goto fail;
+
                        lun = entry->v.lun;
                        upper = (lun >> 8) & 0x3f;
                        if (upper)
@@ -232,25 +260,34 @@ static void __report_luns(pending_req_t 
 
        spin_unlock_irqrestore(&info->v2p_lock, flags);
 
-       rq_buff[2] = ((sizeof(struct scsi_lun) * lun_cnt) >> 8) & 0xff;
-       rq_buff[3] = (sizeof(struct scsi_lun) * lun_cnt) & 0xff;
-
-       err = __copy_to_sg(pending_req->sgl, nr_seg, rq_buff, buff_len);
+       buff[2] = ((sizeof(struct scsi_lun) * lun_cnt) >> 8) & 0xff;
+       buff[3] = (sizeof(struct scsi_lun) * lun_cnt) & 0xff;
+
+       actual_len = lun_cnt * sizeof(struct scsi_lun) 
+                               + VSCSI_REPORT_LUNS_HEADER;
+       req_bufflen = 0;
+       for (i = 0; i < nr_seg; i++)
+               req_bufflen += pending_req->sgl[i].length;
+
+       err = __copy_to_sg(pending_req->sgl, nr_seg, buff, 
+                               min(req_bufflen, actual_len));
        if (err)
                goto fail;
 
        memset(pending_req->sense_buffer, 0, VSCSIIF_SENSE_BUFFERSIZE);
        pending_req->rslt = 0x00;
-
-       kfree(rq_buff);
+       pending_req->resid = req_bufflen - min(req_bufflen, actual_len);
+
+       kfree(buff);
        return;
 
 fail:
        scsiback_mk_sense_buffer(pending_req->sense_buffer, ILLEGAL_REQUEST,
                INVALID_FIELD_IN_CDB, 0);
-       pending_req->rslt = check_condition_result;
-       if (rq_buff)
-               kfree(rq_buff);
+       pending_req->rslt  = check_condition_result;
+       pending_req->resid = 0;
+       if (buff)
+               kfree(buff);
        return;
 }
 
@@ -294,7 +331,7 @@ void scsiback_req_emulation_or_cmdexec(p
        else {
                scsiback_fast_flush_area(pending_req);
                scsiback_do_resp_with_sense(pending_req->sense_buffer,
-                       pending_req->rslt, pending_req);
+                 pending_req->rslt, pending_req->resid, pending_req);
        }
 }
 
diff -r a682229d0eac -r bd4b58143713 drivers/xen/scsiback/scsiback.c
--- a/drivers/xen/scsiback/scsiback.c   Tue Jul 15 16:39:39 2008 +0100
+++ b/drivers/xen/scsiback/scsiback.c   Wed Jul 16 11:19:14 2008 +0100
@@ -142,7 +142,7 @@ static void scsiback_notify_work(struct 
 }
 
 void scsiback_do_resp_with_sense(char *sense_buffer, int32_t result,
-                               pending_req_t *pending_req)
+                       uint32_t resid, pending_req_t *pending_req)
 {
        vscsiif_response_t *ring_res;
        struct vscsibk_info *info = pending_req->info;
@@ -167,6 +167,8 @@ void scsiback_do_resp_with_sense(char *s
        } else {
                ring_res->sense_len = 0;
        }
+
+       ring_res->residual_len = resid;
 
        RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&info->ring, notify);
        if (info->ring.rsp_prod_pvt == info->ring.req_cons) {
@@ -209,8 +211,10 @@ static void scsiback_cmd_done(struct req
 {
        pending_req_t *pending_req = req->end_io_data;
        unsigned char *sense_buffer;
+       unsigned int resid;
 
        sense_buffer = req->sense;
+       resid        = req->data_len;
 
        if (errors != 0) {
                if (log_print_stat)
@@ -220,7 +224,7 @@ static void scsiback_cmd_done(struct req
        scsiback_rsp_emulation(pending_req);
 
        scsiback_fast_flush_area(pending_req);
-       scsiback_do_resp_with_sense(sense_buffer, errors, pending_req);
+       scsiback_do_resp_with_sense(sense_buffer, errors, resid, pending_req);
        scsiback_put(pending_req->info);
 
        __blk_put_request(req->q, req);
@@ -473,7 +477,7 @@ static void scsiback_device_reset_exec(p
        scsiback_get(info);
        err = scsi_reset_provider(sdev, SCSI_TRY_RESET_DEVICE);
 
-       scsiback_do_resp_with_sense(NULL, err, pending_req);
+       scsiback_do_resp_with_sense(NULL, err, 0, pending_req);
        scsiback_put(info);
 
        return;
@@ -592,11 +596,11 @@ static int scsiback_do_cmd_fn(struct vsc
                                                pending_req);
                if (err == -EINVAL) {
                        scsiback_do_resp_with_sense(NULL, (DRIVER_ERROR << 24),
-                               pending_req);
+                               0, pending_req);
                        continue;
                } else if (err == -ENODEV) {
                        scsiback_do_resp_with_sense(NULL, (DID_NO_CONNECT << 
16),
-                               pending_req);
+                               0, pending_req);
                        continue;
                }
 
@@ -607,7 +611,7 @@ static int scsiback_do_cmd_fn(struct vsc
                } else {
                        printk(KERN_ERR "scsiback: invalid parameter for 
request\n");
                        scsiback_do_resp_with_sense(NULL, (DRIVER_ERROR << 24),
-                               pending_req);
+                               0, pending_req);
                        continue;
                }
        }
diff -r a682229d0eac -r bd4b58143713 drivers/xen/scsifront/scsifront.c
--- a/drivers/xen/scsifront/scsifront.c Tue Jul 15 16:39:39 2008 +0100
+++ b/drivers/xen/scsifront/scsifront.c Wed Jul 16 11:19:14 2008 +0100
@@ -147,7 +147,7 @@ static void scsifront_cdb_cmd_done(struc
        add_id_to_freelist(info, id);
 
        sc->result = ring_res->rslt;
-       sc->resid  = 0;
+       sc->resid  = ring_res->residual_len;
 
        if (ring_res->sense_len > VSCSIIF_SENSE_BUFFERSIZE)
                sense_len = VSCSIIF_SENSE_BUFFERSIZE;
diff -r a682229d0eac -r bd4b58143713 include/xen/interface/io/vscsiif.h
--- a/include/xen/interface/io/vscsiif.h        Tue Jul 15 16:39:39 2008 +0100
+++ b/include/xen/interface/io/vscsiif.h        Wed Jul 16 11:19:14 2008 +0100
@@ -84,7 +84,9 @@ struct vscsiif_response {
     uint8_t sense_len;
     uint8_t sense_buffer[VSCSIIF_SENSE_BUFFERSIZE];
     int32_t rslt;
-    uint32_t reserved[37];
+    uint32_t residual_len;     /* request bufflen - 
+                                  return the value from physical device */
+    uint32_t reserved[36];
 };
 typedef struct vscsiif_response vscsiif_response_t;
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [linux-2.6.18-xen] pvSCSI: Sanity check for REPORT_LUN emulation, Xen patchbot-linux-2.6.18-xen <=