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

Re: class_device_add error in SCSI with 2.6.17-rc2-g52824b6b (fwd)



Apologies for not including debian-alpha prior to now...

There seems to be a problem with the kernel implementation of strncpy()
on the Alpha processor that surfaced in 2.6.17-rc1.  Specifically, when
code was added to drivers/scsi/sd.c that calls strncpy(), no more than
one device on each SCSI bus could be registered.  Further investigation
by Mathieu indicates strncpy() is doing some bizarre things.

His messages are appended below.  This is either a long-lurking bug
within the strncpy() routine (in which case we should all buy lottery
tickets given our luck in not getting hit by this before now), or
what is more likely, a gcc issue (optimization?).  I'm using a slightly
different compiler version (Debian 1:3.3.5-13), but with identical
results to what Mathieu is getting with the Gentoo 3.4.4-r1 compiler.

Please omit James and linux-scsi from any followups: this is clearly
not their problem -- they were simply the canaries in the coal mine.

-- 
-----------------------------------------------------------------------
Bob Tracy                   WTO + WIPO = DMCA? http://www.anti-dmca.org
rct@frus.com
-----------------------------------------------------------------------

----- Forwarded message from Mathieu Chouquet-Stringer -----

>Date:	Thu, 20 Apr 2006 12:14:48 +0200
>From:	Mathieu Chouquet-Stringer <mchouque@free.fr>
>To:	Bob Tracy <rct@gherkin.frus.com>
>Cc:	linux-kernel@vger.kernel.org, linux-scsi@vger.kernel.org,
>	James.Bottomley@SteelEye.com, linux-alpha@vger.kernel.org
>Subject: Re: class_device_add error in SCSI with 2.6.17-rc2-g52824b6b

On Wed, Apr 19, 2006 at 04:58:03PM -0500, Bob Tracy wrote:
> Similar error previously reported by me for 2.6.17-rc1, except sda got
> added fine: error occurred when attempting to add/register sdb. 
> Thankfully, you were able to append a trace...

In my case, I was able to solve the problem by replacing this call at
line 1648 in drivers/scsi/sd.c (patch attached):
strncpy(sdkp->cdev.class_id, sdp->sdev_gendev.bus_id, BUS_ID_SIZE);

by

snprintf(sdkp->cdev.class_id, BUS_ID_SIZE, "%s", sdp->sdev_gendev.bus_id);

Then it works.

While debugging the whole thing, I was printk'ing the value of
sdkp->cdev.class_id right after the strncpy call and here's what I
getting (basically only the first 4 chars + final \0): 
"0:0:"

So I guess the strncpy routine on alpha is fscked up or gcc is doing
something crazy. The function is under arch/alpha/lib/strncpy.S, time to
learn assembly.


--- linux-2.6/drivers/scsi/sd.c	2006-03-28 13:28:24.000000000 +0200
+++ linux-2.6-mat/drivers/scsi/sd.c	2006-04-20 12:12:36.000000000 +0200
@@ -1645,7 +1645,8 @@
 	class_device_initialize(&sdkp->cdev);
 	sdkp->cdev.dev = &sdp->sdev_gendev;
 	sdkp->cdev.class = &sd_disk_class;
-	strncpy(sdkp->cdev.class_id, sdp->sdev_gendev.bus_id, BUS_ID_SIZE);
+	snprintf(sdkp->cdev.class_id, BUS_ID_SIZE, "%s",
+		sdp->sdev_gendev.bus_id);
 
 	if (class_device_add(&sdkp->cdev))
 		goto out_put;


-- 
Mathieu Chouquet-Stringer                           mchouque@free.fr
    "Le disparu, si l'on v?n?re sa m?moire, est plus pr?sent et
                 plus puissant que le vivant".
           -- Antoine de Saint-Exup?ry, Citadelle --

----- End of forwarded message from Mathieu Chouquet-Stringer -----

----- Forwarded message from Mathieu Chouquet-Stringer -----
>Date:	Thu, 20 Apr 2006 12:57:09 +0200
>From:	Mathieu Chouquet-Stringer <mchouque@free.fr>
>To:	Bob Tracy <rct@gherkin.frus.com>, linux-kernel@vger.kernel.org,
>	linux-scsi@vger.kernel.org, James.Bottomley@SteelEye.com,
>	linux-alpha@vger.kernel.org
>Subject: Re: class_device_add error in SCSI with 2.6.17-rc2-g52824b6b

On Thu, Apr 20, 2006 at 12:14:48PM +0200, Mathieu Chouquet-Stringer wrote:
> So I guess the strncpy routine on alpha is fscked up or gcc is doing
> something crazy. The function is under arch/alpha/lib/strncpy.S, time to
> learn assembly.

Replying to myself here, i've created the following test program and
redefined strncpy to mystrncpy (I used strncpy.S and stxncpy.S from
arch/alpha/lib):

=============================================================================
#include <stdio.h>
#include <string.h>
#define FOO 50

extern char *mystrncpy(char *dest, const char *src, size_t count);

int main(int argc, char **argv)
{

	char src[FOO] = "";
	char dest[FOO];
	char letter[] = "a";
	int i;

	for (i = 0; i < FOO - 1; i++) {
		size_t beflen, aftlen;

		letter[0] = 'a' + i;
		strncat(src, letter, FOO);
		beflen = strlen(src);

		mystrncpy(dest, src, FOO);
		aftlen = strlen(dest);
		if (beflen != aftlen)
			printf("fails for strlen = %ld (copied %ld)\n",
				beflen, aftlen);
	}


	return 0;
}
=============================================================================

And here's the output using gcc version 3.4.4 (Gentoo 3.4.4-r1,
ssp-3.4.4-1.0, pie-8.7.8), note i didn't use flag except -Wall:

fails for strlen = 3 (copied 2)
fails for strlen = 4 (copied 2)
fails for strlen = 5 (copied 2)
fails for strlen = 6 (copied 2)
fails for strlen = 7 (copied 2)
fails for strlen = 11 (copied 10)
fails for strlen = 12 (copied 10)
fails for strlen = 13 (copied 10)
fails for strlen = 14 (copied 10)
fails for strlen = 15 (copied 10)
fails for strlen = 19 (copied 18)
fails for strlen = 20 (copied 18)
fails for strlen = 21 (copied 18)
fails for strlen = 22 (copied 18)
fails for strlen = 23 (copied 18)
fails for strlen = 27 (copied 26)
fails for strlen = 28 (copied 26)
fails for strlen = 29 (copied 26)
fails for strlen = 30 (copied 26)
fails for strlen = 31 (copied 26)
fails for strlen = 35 (copied 34)
fails for strlen = 36 (copied 34)
fails for strlen = 37 (copied 34)
fails for strlen = 38 (copied 34)
fails for strlen = 39 (copied 34)
fails for strlen = 43 (copied 42)
fails for strlen = 44 (copied 42)
fails for strlen = 45 (copied 42)
fails for strlen = 46 (copied 42)
fails for strlen = 47 (copied 42)


So much for this function...  I'll look at the assembly to see if I can
understand what's going on: it always copy a multiple of 8 + 2 bytes (as
in 8x + 2).
-- 
Mathieu Chouquet-Stringer                           mchouque@free.fr

----- End of forwarded message from Mathieu Chouquet-Stringer -----



Reply to: