[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [linux-2.6.18-xen] scsiback: fix retry handling in __report_luns()


  • To: xen-changelog@xxxxxxxxxxxxxxxxxxx
  • From: Xen patchbot-linux-2.6.18-xen <patchbot@xxxxxxx>
  • Date: Wed, 02 Jul 2014 13:11:03 +0000
  • Delivery-date: Wed, 02 Jul 2014 13:11:14 +0000
  • List-id: "Change log for Mercurial \(receive only\)" <xen-changelog.lists.xen.org>

# HG changeset patch
# User Jan Beulich <jbeulich@xxxxxxxx>
# Date 1404306249 -7200
# Node ID 930d1b2ecc2f6a145a6f95e25db8cb54a366eb69
# Parent  0a5bb80edc458252c0150fbe58c286cf83ad9580
scsiback: fix retry handling in __report_luns()

Neither did lun_cnt get reset when invoking a retry here, nor did the
intermediate buffer get resized to fit the larger amount. Fix this, at
once
- adding spare extra buffer space growing with the number of retries,
- fix the type of alloc_len (it having been "unsigned char", this set
  us up for memory corruption),
- correct a couple of signed/unsigned issues here and its helper
  function __nr_luns_under_host(),
- remove a couple of pointless initializers,
- drop pointless NULL checks before kfree() invocations (not only does
  kfree() deal fine with NULL, in the first of the two cases it was
  plain impossible for the pointer to be NULL).

Reported-by: Juergen Gross <jgross@xxxxxxxx>
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
Reviewed-by: Juergen Gross <jgross@xxxxxxxx>
---


diff -r 0a5bb80edc45 -r 930d1b2ecc2f drivers/xen/scsiback/emulate.c
--- a/drivers/xen/scsiback/emulate.c    Wed Jul 02 14:56:24 2014 +0200
+++ b/drivers/xen/scsiback/emulate.c    Wed Jul 02 15:04:09 2014 +0200
@@ -193,12 +193,12 @@ static int __copy_from_sg(struct scatter
        return 0;
 }
 
-static int __nr_luns_under_host(struct vscsibk_info *info)
+static unsigned 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;
+       unsigned int lun_cnt = 0;
 
        spin_lock_irqsave(&info->v2p_lock, flags);
        list_for_each_entry(entry, head, l) {
@@ -213,6 +213,7 @@ static int __nr_luns_under_host(struct v
 /* REPORT LUNS Define*/
 #define VSCSI_REPORT_LUNS_HEADER       8
 #define VSCSI_REPORT_LUNS_RETRY                3
+#define VSCSI_REPORT_LUNS_SPARE                3
 
 /* quoted scsi_debug.c/resp_report_luns() */
 static void __report_luns(pending_req_t *pending_req, void *data)
@@ -224,13 +225,11 @@ static void __report_luns(pending_req_t 
        unsigned char *cmd = (unsigned char *)pending_req->cmnd;
        
        unsigned char *buff = NULL;
-       unsigned char alloc_len;
-       unsigned int alloc_luns = 0;
-       unsigned int req_bufflen = 0;
-       unsigned int actual_len = 0;
+       size_t alloc_len;
+       unsigned int alloc_luns, req_bufflen, actual_len;
        unsigned int retry_cnt = 0;
-       int select_report = (int)cmd[2];
-       int i, lun_cnt = 0, lun, upper, err = 0;
+       int err, select_report = (int)cmd[2];
+       unsigned int i, lun_cnt, lun, upper;
        
        struct v2p_entry *entry;
        struct list_head *head = &(info->v2p_entry_lists);
@@ -242,16 +241,18 @@ static void __report_luns(pending_req_t 
        if ((req_bufflen < 4) || (select_report != 0))
                goto fail;
 
-       alloc_luns = __nr_luns_under_host(info);
+retry:
+       alloc_luns = __nr_luns_under_host(info)
+                    + retry_cnt * VSCSI_REPORT_LUNS_SPARE;
        alloc_len  = sizeof(struct scsi_lun) * alloc_luns
                                + VSCSI_REPORT_LUNS_HEADER;
-retry:
        if ((buff = kzalloc(alloc_len, GFP_KERNEL)) == NULL) {
                printk(KERN_ERR "scsiback:%s kmalloc err\n", __FUNCTION__);
                goto fail;
        }
 
-       one_lun = (struct scsi_lun *) &buff[8];
+       one_lun = (struct scsi_lun *)&buff[VSCSI_REPORT_LUNS_HEADER];
+       lun_cnt = 0;
        spin_lock_irqsave(&info->v2p_lock, flags);
        list_for_each_entry(entry, head, l) {
                if ((entry->v.chn == channel) &&
@@ -264,8 +265,7 @@ retry:
 
                                if (retry_cnt < VSCSI_REPORT_LUNS_RETRY) {
                                        retry_cnt++;
-                                       if (buff)
-                                               kfree(buff);
+                                       kfree(buff);
                                        goto retry;
                                }
 
@@ -309,8 +309,7 @@ fail:
                INVALID_FIELD_IN_CDB, 0);
        pending_req->rslt  = check_condition_result;
        pending_req->resid = 0;
-       if (buff)
-               kfree(buff);
+       kfree(buff);
        return;
 }
 

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.