public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
From: Douglas Gilbert <dougg@torque.net>
To: Hannes Reinecke <hare@suse.de>
Cc: linux-scsi@vger.kernel.org, James.Bottomley@SteelEye.com
Subject: Re: [PATCH] ALUA support for scsi_debug
Date: Thu, 19 Oct 2006 10:50:30 -0400	[thread overview]
Message-ID: <453790B6.9000802@torque.net> (raw)
In-Reply-To: <45377943.8090906@suse.de>

Hannes Reinecke wrote:
> Douglas Gilbert wrote:
>> Hannes,
>> Here is my counter patch for you to consider.
>> I suspect my machine was running into stack
>> problems so I moved some arrays onto the heap.
>>
> Ah. Good. To tell the truth I was a bit concerned once I've
> discovered that all information pages are infact statically allocated ...

I wasn't aware that statically allocated data (file or local
scope) would add to stack problems on a driver loaded as a
module. The arrays I moved to the heap were "auto" (i.e. non-static).

Most of the data scsi_debug keeps static are (manufacturer's)
default mode pages. They are constant. Keeping the current mode
page in static store is a bit more problematic: it may be
logically correct depending on the mode page policy (a VPD page)
but accesses probably should be locked if the page can be
modified (e.g. MRIE in the IEC mode page).


Over zealous error processing ....
I have made this mistake often enough, along with
many others, so hopefully some readers will take note:

<snip>
> +#define SDEBUG_MAX_TGTPGS_ARR_SZ 1412
> +
> +static int resp_report_tgtpgs(struct scsi_cmnd * scp,
> +			      struct sdebug_dev_info * devip)
> +{
> +	unsigned char *cmd = (unsigned char *)scp->cmnd;
> +	unsigned char * arr;
> +	int host_no = devip->sdbg_host->shost->host_no;
> +	int n, ret, alloc_len, rlen;
> +	int target_dev_id, port_group_a, port_group_b, port_a, port_b;
> +
> +	alloc_len = ((cmd[6] << 24) + (cmd[7] << 16) + (cmd[8] << 8)
> +		     + cmd[9]);
> +	if (alloc_len < 4 + (11 * 2)) {
> +		mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
> +			       	0);
> +		return check_condition_result;
> +	}
> +	
> +	arr = kzalloc(SDEBUG_MAX_TGTPGS_ARR_SZ, GFP_KERNEL);
> +	n = 4;
> +	/*
> +	 * Each host has it's own target port group.
> +	 * The asymmetric access state is cycled according to the host_id.
> +	 */
> +	target_dev_id = ((host_no + 1) * 2000) +
> +			(devip->target * 1000) - 3;
> +	port_a = target_dev_id + 1;
> +	port_b = target_dev_id + 2;
> +	port_group_a = (((host_no + 1) & 0x7f) << 8) + 
> +	    (devip->channel & 0xff);
> +	port_group_b = (((host_no + 1) & 0x7f) << 8) + 
> +	    (devip->channel & 0xff) + 0x80;
> +	if (0 == scsi_debug_vpd_use_hostno) {
> +	    arr[n++] = host_no % 3; /* Asymm access state */
> +	    arr[n++] = 0x0F; /* claim: all states are supported */
> +	} else {
> +	    arr[n++] = 0x0; /* Active/Optimized path */
> +	    arr[n++] = 0x01; /* claim: only support active/optimized paths */
> +	}
> +	arr[n++] = (port_group_a >> 8) & 0xff;
> +	arr[n++] = port_group_a & 0xff;
> +	arr[n++] = 0;    /* Reserved */
> +	arr[n++] = 0;    /* Status code */
> +	arr[n++] = 0;    /* Vendor unique */
> +	arr[n++] = 0x1;  /* One port per group */
> +	arr[n++] = 0;    /* Reserved */
> +	arr[n++] = 0;    /* Reserved */
> +	arr[n++] = (port_a >> 8) & 0xff;
> +	arr[n++] = port_a & 0xff;
> +	arr[n++] = 3;    /* Port unavailable */
> +	arr[n++] = 0x0F; /* claim: all states are supported */
> +	arr[n++] = (port_group_b >> 8) & 0xff;
> +	arr[n++] = port_group_b & 0xff;
> +	arr[n++] = 0;    /* Reserved */
> +	arr[n++] = 0;    /* Status code */
> +	arr[n++] = 0;    /* Vendor unique */
> +	arr[n++] = 0x1;  /* One port per group */
> +	arr[n++] = 0;    /* Reserved */
> +	arr[n++] = 0;    /* Reserved */
> +	arr[n++] = (port_b >> 8) & 0xff;
> +	arr[n++] = port_b & 0xff;
> +
> +	rlen = n - 4;
> +	arr[0] = (rlen >> 24) & 0xff;
> +	arr[1] = (rlen >> 16) & 0xff;
> +	arr[2] = (rlen >> 8) & 0xff;
> +	arr[3] = rlen & 0xff;
> +
> +	if (alloc_len < n) {
> +		mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB,
> +			       	0);
> +		kfree(arr);
> +		return check_condition_result;
> +	}
> +	
> +	ret = fill_from_dev_buffer(scp, arr,
> +				   min(n, SDEBUG_MAX_TGTPGS_ARR_SZ));
> +	kfree(arr);
> +	return ret;
> +}
<snip>

The above code is building a response to the REPORT TARGET
PORT GROUPS command. The first 4 bytes of the response are
the length of the response irrespective of whether the response
is truncated by alloc_len (a field in the RTPG command).
It is _not_ an error if alloc_len < n (see spc4r07a.pdf section
4.3.4.6). This allows the application client to ask for a 4
byte response if it is worried about how big the response
will be, then issue the command again with an appropriate
allocation length. This is a common paradigm with mode and
log pages.

So the "if (alloc_len < 4 + (11 * 2))" block should be
removed. Also the "if (alloc_len < n)" block should be
removed and "min" should be (possibly a cleaner version of):
  min(min(alloc_len, n), SDEBUG_MAX_TGTPGS_ARR_SZ))

Doug Gilbert

  reply	other threads:[~2006-10-19 14:49 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-10-18 14:50 [PATCH] ALUA support for scsi_debug Hannes Reinecke
2006-10-18 17:11 ` Douglas Gilbert
2006-10-19  7:08   ` Hannes Reinecke
2006-10-18 19:50 ` James Bottomley
2006-10-18 20:18 ` Douglas Gilbert
2006-10-19 13:10   ` Hannes Reinecke
2006-10-19 14:50     ` Douglas Gilbert [this message]
2006-10-20  7:58       ` Hannes Reinecke
2006-10-20 20:39         ` Douglas Gilbert

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=453790B6.9000802@torque.net \
    --to=dougg@torque.net \
    --cc=James.Bottomley@SteelEye.com \
    --cc=hare@suse.de \
    --cc=linux-scsi@vger.kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox