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

Dominic Marks dom at goodforbusiness.co.uk
Sat May 28 07:39:16 PDT 2005


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-fs mailing list