i386/68719: [usb] USB 2.0 mobil rack+ fat32 performance problem

Dominic Marks dom at goodforbusiness.co.uk
Sat May 28 07:40:17 PDT 2005


The following reply was made to PR i386/68719; it has been noted by GNATS.

From: Dominic Marks <dom at goodforbusiness.co.uk>
To: Bruce Evans <bde at zeta.org.au>
Cc: freebsd-gnats-submit at FreeBSD.org,
 banhalmi at field.hu,
 freebsd-fs at FreeBSD.org
Subject: Re: i386/68719: [usb] USB 2.0 mobil rack+ fat32 performance problem
Date: Sat, 28 May 2005 15:40:34 +0100

 On Saturday 28 May 2005 12:13, Dominic Marks wrote:
 > On Saturday 28 May 2005 11:36, Bruce Evans wrote:
 
 <snip>
 
 > >
 > > I use the following to improve transfer rates for msdosfs.  The patch is
 > > for an old version so it might not apply directly.
 > >
 > > %%%
 > > Index: msdosfs_vnops.c
 > > ===================================================================
 > > RCS file: /home/ncvs/src/sys/fs/msdosfs/msdosfs_vnops.c,v
 > > retrieving revision 1.147
 > > diff -u -2 -r1.147 msdosfs_vnops.c
 > > --- msdosfs_vnops.c	4 Feb 2004 21:52:53 -0000	1.147
 > > +++ msdosfs_vnops.c	22 Feb 2004 07:27:15 -0000
 > > @@ -608,4 +622,5 @@
 > >   	int error = 0;
 > >   	u_long count;
 > > +	int seqcount;
 > >   	daddr_t bn, lastcn;
 > >   	struct buf *bp;
 > > @@ -693,4 +714,5 @@
 > >   		lastcn = de_clcount(pmp, osize) - 1;
 > >
 > > +	seqcount = ioflag >> IO_SEQSHIFT;
 > >   	do {
 > >   		if (de_cluster(pmp, uio->uio_offset) > lastcn) {
 > > @@ -718,5 +740,5 @@
 > >   			 */
 > >   			bp = getblk(thisvp, bn, pmp->pm_bpcluster, 0, 0, 0);
 > > -			clrbuf(bp);
 > > +			vfs_bio_clrbuf(bp);
 > >   			/*
 > >   			 * Do the bmap now, since pcbmap needs buffers
 > > @@ -767,11 +789,19 @@
 > >   		 * without delay.  Otherwise do a delayed write because we
 > >   		 * may want to write somemore into the block later.
 > > +		 * XXX comment not updated with code.
 > >   		 */
 > > +		if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERW) == 0)
 > > +			bp->b_flags |= B_CLUSTEROK;
 > >   		if (ioflag & IO_SYNC)
 > > -			(void) bwrite(bp);
 > > -		else if (n + croffset == pmp->pm_bpcluster)
 > > +			(void)bwrite(bp);
 > > +		else if (vm_page_count_severe() || buf_dirty_count_severe())
 > >   			bawrite(bp);
 > > -		else
 > > -			bdwrite(bp);
 > > +		else if (n + croffset == pmp->pm_bpcluster) {
 > > +			if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERW) == 0)
 > > +				cluster_write(bp, dep->de_FileSize, seqcount);
 > > +			else
 > > +				bawrite(bp);
 > > +  		} else
 > > +  			bdwrite(bp);
 > >   		dep->de_flag |= DE_UPDATE;
 > >   	} while (error == 0 && uio->uio_resid > 0);
 > > %%%
 >
 > Thanks! I'll try my three tests again with this patch.
 
 Index: msdosfs_vnops.c
 ===================================================================
 RCS file: /usr/cvs/src/sys/fs/msdosfs/msdosfs_vnops.c,v
 retrieving revision 1.149.2.1
 diff -u -r1.149.2.1 msdosfs_vnops.c
 --- msdosfs_vnops.c	31 Jan 2005 23:25:56 -0000	1.149.2.1
 +++ msdosfs_vnops.c	28 May 2005 14:26:59 -0000
 @@ -607,6 +607,7 @@
  		struct uio *a_uio;
  		int a_ioflag;
  		struct ucred *a_cred;
 +		int seqcount;
  	} */ *ap;
  {
  	int n;
 @@ -615,6 +616,7 @@
  	u_long osize;
  	int error = 0;
  	u_long count;
 +	int seqcount;
  	daddr_t bn, lastcn;
  	struct buf *bp;
  	int ioflag = ap->a_ioflag;
 @@ -692,7 +694,7 @@
  	 */
  	if (uio->uio_offset + resid > osize) {
  		count = de_clcount(pmp, uio->uio_offset + resid) -
 -			de_clcount(pmp, osize);
 +		   	de_clcount(pmp, osize);
  		error = extendfile(dep, count, NULL, NULL, 0);
  		if (error &&  (error != ENOSPC || (ioflag & IO_UNIT)))
  			goto errexit;
 @@ -700,6 +702,7 @@
  	} else
  		lastcn = de_clcount(pmp, osize) - 1;
  
 +	seqcount = ioflag >> IO_SEQSHIFT;
  	do {
  		if (de_cluster(pmp, uio->uio_offset) > lastcn) {
  			error = ENOSPC;
 @@ -725,7 +728,7 @@
  			 * then no need to read data from disk.
  			 */
  			bp = getblk(thisvp, bn, pmp->pm_bpcluster, 0, 0, 0);
 -			clrbuf(bp);
 +			vfs_bio_clrbuf(bp);
  			/*
  			 * Do the bmap now, since pcbmap needs buffers
  			 * for the fat table. (see msdosfs_strategy)
 @@ -775,6 +778,7 @@
  		 * without delay.  Otherwise do a delayed write because we
  		 * may want to write somemore into the block later.
  		 */
 +		 /*
  		if (ioflag & IO_SYNC)
  			(void) bwrite(bp);
  		else if (n + croffset == pmp->pm_bpcluster)
 @@ -782,6 +786,24 @@
  		else
  			bdwrite(bp);
  		dep->de_flag |= DE_UPDATE;
 +		*/
 +		/*
 +		 * XXX Patch.
 +		 */
 +                if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERW) == 0)
 +                       bp->b_flags |= B_CLUSTEROK;
 +                if (ioflag & IO_SYNC)
 +                       (void)bwrite(bp);
 +                else if (vm_page_count_severe() || buf_dirty_count_severe())
 +                       bawrite(bp);
 +                else if (n + croffset == pmp->pm_bpcluster) {
 +                       if ((vp->v_mount->mnt_flag & MNT_NOCLUSTERW) == 0)
 +                               cluster_write(bp, dep->de_FileSize, seqcount);
 +                       else
 +                               bawrite(bp);
 +               } else
 +                       bdwrite(bp);
 +                dep->de_flag |= DE_UPDATE;
  	} while (error == 0 && uio->uio_resid > 0);
  
  	/*
 
 Your patch works for me on 5.4-STABLE. It improves write performance 
 dramatically. I did another test, reading and writing 1GB chunks of data.
 
 # dd if=<in> of=<out> bs=512k count=2k
 
 ufs2/read:	28.25MB/s
 ufs2/write:	23.47MB/s
 
 msdosfs/read:	 5.08MB/s
 msdosfs/write:	23.13MB/s
 
 Raising vfs.read_max to 64 (from 8) seems to have improved the read 
 performance a little too but I have not measured how much yet.
 
 Since the patch is to the _write function is it safe to assume the same method 
 could be used to fix read performance if applied properly in the correct 
 function?
 
 Cheers,
 -- 
 Dominic
 GoodforBusiness.co.uk
 I.T. Services for SMEs in the UK.


More information about the freebsd-usb mailing list