From nobody@FreeBSD.ORG  Wed Jun  7 00:00:57 2000
Return-Path: <nobody@FreeBSD.ORG>
Received: by hub.freebsd.org (Postfix, from userid 32767)
	id 6C64437B8C4; Wed,  7 Jun 2000 00:00:57 -0700 (PDT)
Message-Id: <20000607070057.6C64437B8C4@hub.freebsd.org>
Date: Wed,  7 Jun 2000 00:00:57 -0700 (PDT)
From: phiber@phiber.com
Sender: nobody@FreeBSD.ORG
To: freebsd-gnats-submit@FreeBSD.org
Subject: pseudo-device vn doesn't work properly with msdos filesystems
X-Send-Pr-Version: www-1.0

>Number:         19086
>Category:       misc
>Synopsis:       pseudo-device vn doesn't work properly with msdos filesystems
>Confidential:   no
>Severity:       non-critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jun 07 00:10:04 PDT 2000
>Closed-Date:    Fri Oct 27 02:51:40 PDT 2000
>Last-Modified:  Fri Oct 27 02:58:25 PDT 2000
>Originator:     Mark Abene
>Release:        4.0-RELEASE/Alpha
>Organization:
Crossbar Security, Inc.
>Environment:
FreeBSD ziggurat.phiber.com 4.0-RELEASE FreeBSD 4.0-RELEASE #11: Wed Jun  7 00:32:12 EDT 2000     phiber@ziggurat.phiber.com:/usr/src/sys/compile/ZIGGURAT  alpha
>Description:
When mapping an msdos disk image to a vn device and mounting it,
trying to read or write more than exactly 1024 bytes returns an
"Argument list too long" error and fails.
This problem does not exist on FreeBSD 3.4.  Nor is there a problem
when working with disklabels and ffs filesystems.  It only seems to
affect msdos filesystems.  It also makes no difference whether vn is
compiled into the kernel or loaded as a module.


>How-To-Repeat:
dd if=/dev/zero of=/tmp/img bs=1k count=1440
vnconfig vn0c /tmp/img
newfs_msdos -f 1440 /dev/vn0c
mount -tmsdos /dev/vn0c /mnt
cp some_file_bigger_than_1K /mnt
cp: some_file_bigger_than_1K: Argument list too long

The file gets created with a size of zero bytes, but df shows the
actual space was used, and is now unrecoverable.  I also see the problem
with actual disk images that were dd'ed directly from dos floppies.
Trying to cat a file also stops with the above error message after reading
1024 bytes.

>Fix:


>Release-Note:
>Audit-Trail:

From: Bruce Evans <bde@zeta.org.au>
To: Mark Abene <phiber@radicalmedia.com>
Cc: freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: misc/19086: pseudo-device vn doesn't work properly with msdos
 filesystems
Date: Thu, 8 Jun 2000 16:47:24 +1000 (EST)

 On Wed, 7 Jun 2000, Mark Abene wrote:
 
 > I just did some poking around, and the problem is *not* with the vn driver
 > at all, but the msdosfs driver.  I just tried mounting a dos floppy and
 > tried to read/write it, and ran into the exact same problem with
 > "Argument list too long".  I have MSDOSFS compiled into the kernel.
 > Unfortunately, I don't have 4.0-RELEASE on any Intel boxes, only Alpha.
 > I can verify that this problem doesn't exist with 3.4-RELEASE on Intel.
 
 The following quick fix seems to be sufficient on i386's with 64-bit longs:
 
 ---
 diff -c2 msdosfsmount.h~ msdosfsmount.h
 *** msdosfsmount.h~	Thu Jun  8 15:56:37 2000
 --- msdosfsmount.h	Thu Jun  8 16:01:44 2000
 ***************
 *** 85,89 ****
   	u_long pm_fatblocksec;	/* size of fat blocks in sectors */
   	u_long pm_fatsize;	/* size of fat in bytes */
 ! 	u_long pm_fatmask;	/* mask to use for fat numbers */
   	u_long pm_fsinfo;	/* fsinfo block number */
   	u_long pm_nxtfree;	/* next free cluster in fsinfo block */
 --- 85,89 ----
   	u_long pm_fatblocksec;	/* size of fat blocks in sectors */
   	u_long pm_fatsize;	/* size of fat in bytes */
 ! 	u_int32_t pm_fatmask;	/* mask to use for fat numbers */
   	u_long pm_fsinfo;	/* fsinfo block number */
   	u_long pm_nxtfree;	/* next free cluster in fsinfo block */
 ---
 
 pm_fatmask is 0xfff for 12-bit fats, so its complement is 0xfffffffffffff000
 on machines with 64-bit longs, so comparisions like
 
     (cn | ~pmp->pm_fatmask) == CLUST_RSRVD)	/* CLUST_RSVRD is 0xfffffff6 */
 
 always fail on such machines.  The quick fix fixes at least this bug on
 machines with ints no larger than 32 bit.  The big is subtler on machines
 with ints larger than 32 bits.  On such machines, u_int32_t has precisely
 32 bits, so it must be smaller than int, so in the calculation of its
 complement, it will be promoted before taking complements, again giving
 too many high bits.
 
 The correct fix is:
 - replace ~pmp->pm_fatmask by (~pmp->pm_fatmask & 0xffffffff) everywhere
   (actually use a macro instead of 0xffffffff).
 - finish implementing <inttypes.h> (actually <stdint.h>).
 - use uint_least32_t from <inttypes.h> for pm_fatmask.  Don't use u_int32_t,
   since it is a deprecated spelling of uint32_t.  Don't use uint32_t or
   u_long, since they may be pessimal.  u_long _is_ pessimal on i386's with
   64-bit longs.  Similarly for many other types in the kernel.
 
 Bruce
 
 

From: Mark Abene <phiber@radicalmedia.com>
To: Bruce Evans <bde@zeta.org.au>
Cc: freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: misc/19086: pseudo-device vn doesn't work properly with msdos filesystems
Date: Thu, 8 Jun 2000 06:21:59 -0400

 I just spent the past few hours narrowing the problem down to the very same
 thing.  Only now with this patch the kernel panics with an "unexpected machine
 check" when trying to write more than 1024 bytes to a dos floppy.
 Not good.  The program counter shows it to be bombing out in the
 unaligned_fixup routine.  I'm stumped for the time being.
 I'll investigate further but would be really curious to hear if you know
 why this should be happening.
 
 Cheers,
 -Mark
 
 On Thu, Jun 08, 2000 at 04:47:24PM +1000, Bruce Evans wrote:
 > The following quick fix seems to be sufficient on i386's with 64-bit longs:
 > 
 > ---
 > diff -c2 msdosfsmount.h~ msdosfsmount.h
 > *** msdosfsmount.h~	Thu Jun  8 15:56:37 2000
 > --- msdosfsmount.h	Thu Jun  8 16:01:44 2000
 > ***************
 > *** 85,89 ****
 >   	u_long pm_fatblocksec;	/* size of fat blocks in sectors */
 >   	u_long pm_fatsize;	/* size of fat in bytes */
 > ! 	u_long pm_fatmask;	/* mask to use for fat numbers */
 >   	u_long pm_fsinfo;	/* fsinfo block number */
 >   	u_long pm_nxtfree;	/* next free cluster in fsinfo block */
 > --- 85,89 ----
 >   	u_long pm_fatblocksec;	/* size of fat blocks in sectors */
 >   	u_long pm_fatsize;	/* size of fat in bytes */
 > ! 	u_int32_t pm_fatmask;	/* mask to use for fat numbers */
 >   	u_long pm_fsinfo;	/* fsinfo block number */
 >   	u_long pm_nxtfree;	/* next free cluster in fsinfo block */
 > ---
 > 
 

From: Bruce Evans <bde@zeta.org.au>
To: Mark Abene <phiber@radicalmedia.com>
Cc: freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: misc/19086: pseudo-device vn doesn't work properly with msdos
 filesystems
Date: Fri, 9 Jun 2000 00:06:35 +1000 (EST)

 On Thu, 8 Jun 2000, Mark Abene wrote:
 
 > I just spent the past few hours narrowing the problem down to the very same
 > thing.  Only now with this patch the kernel panics with an "unexpected machine
 > check" when trying to write more than 1024 bytes to a dos floppy.
 > Not good.  The program counter shows it to be bombing out in the
 > unaligned_fixup routine.  I'm stumped for the time being.
 > I'll investigate further but would be really curious to hear if you know
 > why this should be happening.
 
 msdosfs metadata is riddled with unaligned fields in Intel (little endian)
 order.  naligned_fixup() apparently has problems fixing up the unaligned
 accesses related to this.  Try changing getushort(), etc., in msdosfs to
 do byte accesses even in the little endian case.  These macros currently
 only do byte access to fix up the byte order in the big endian case.  It
 should use something like ntohs() for that and be more careful about
 unaligned accesses.
 
 Bruce
 
 

From: Mark Abene <phiber@radicalmedia.com>
To: Bruce Evans <bde@zeta.org.au>
Cc: freebsd-gnats-submit@FreeBSD.ORG, freebsd-alpha@FreeBSD.ORG
Subject: Re: misc/19086: pseudo-device vn doesn't work properly with msdos filesystems
Date: Thu, 8 Jun 2000 16:47:02 -0400

 On Fri, Jun 09, 2000 at 12:06:35AM +1000, Bruce Evans wrote:
 > msdosfs metadata is riddled with unaligned fields in Intel (little endian)
 > order.  naligned_fixup() apparently has problems fixing up the unaligned
 > accesses related to this.  Try changing getushort(), etc., in msdosfs to
 > do byte accesses even in the little endian case.  These macros currently
 > only do byte access to fix up the byte order in the big endian case.  It
 > should use something like ntohs() for that and be more careful about
 > unaligned accesses.
 > 
 > Bruce
 > 
 
 That did the trick!  It's now working nicely.  Please accept the following
 interim patch against 4.0-RELEASE, and thanks for the assistance!
 
 **cut here**
 --- msdosfs.orig/bpb.h	Fri Aug 27 20:48:07 1999
 +++ msdosfs/bpb.h	Thu Jun  8 16:25:15 2000
 @@ -114,7 +114,7 @@
   * use the macros for the big-endian case.
   */
  #include <machine/endian.h>
 -#if (BYTE_ORDER == LITTLE_ENDIAN) 			/* && defined(UNALIGNED_ACCESS) */
 +#if (BYTE_ORDER == LITTLE_ENDIAN) && !defined(__alpha__)	/* && defined(UNALIGNED_ACCESS) */
  #define	getushort(x)	*((u_int16_t *)(x))
  #define	getulong(x)	*((u_int32_t *)(x))
  #define	putushort(p, v)	(*((u_int16_t *)(p)) = (v))
 --- msdosfs.orig/msdosfsmount.h	Thu Jan 27 09:43:07 2000
 +++ msdosfs/msdosfsmount.h	Thu Jun  8 16:14:18 2000
 @@ -84,7 +84,7 @@
  	u_long pm_fatblocksize;	/* size of fat blocks in bytes */
  	u_long pm_fatblocksec;	/* size of fat blocks in sectors */
  	u_long pm_fatsize;	/* size of fat in bytes */
 -	u_long pm_fatmask;	/* mask to use for fat numbers */
 +	u_int32_t pm_fatmask;	/* mask to use for fat numbers */
  	u_long pm_fsinfo;	/* fsinfo block number */
  	u_long pm_nxtfree;	/* next free cluster in fsinfo block */
  	u_int pm_fatmult;	/* these 2 values are used in fat */
 **cut here**
 
 Cheers,
 -Mark
 
 

From: Sheldon Hearn <sheldonh@uunet.co.za>
To: freebsd-gnats-submit@freebsd.org
Cc:  
Subject: misc/19086
Date: Fri, 25 Aug 2000 11:13:22 +0200

 A quick note for the audit trail.  A quick fix applied by bde as:
 
 	1.8       +8 -2      src/sys/msdosfs/bpb.h
 	1.22      +2 -2      src/sys/msdosfs/msdosfsmount.h
 
 Ciao,
 Sheldon.
 
State-Changed-From-To: open->closed 
State-Changed-By: bde 
State-Changed-When: Fri Oct 27 02:51:40 PDT 2000 
State-Changed-Why:  
Hopefully fixed.  Suggested patches applied without testing by me in all 
versions back to RELENG_3. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=19086 
>Unformatted:
