Date: Sat, 28 May 2005 15:40:34 +0100 From: Dominic Marks <dom@goodforbusiness.co.uk> To: Bruce Evans <bde@zeta.org.au> Cc: freebsd-fs@FreeBSD.org, freebsd-gnats-submit@FreeBSD.org, banhalmi@field.hu Subject: Re: i386/68719: [usb] USB 2.0 mobil rack+ fat32 performance problem Message-ID: <200505281540.35116.dom@goodforbusiness.co.uk> In-Reply-To: <200505281213.42118.dom@goodforbusiness.co.uk> References: <200505271328.58072.dom@goodforbusiness.co.uk> <20050528194126.W3563@epsplex.bde.org> <200505281213.42118.dom@goodforbusiness.co.uk>
next in thread | previous in thread | raw e-mail | index | archive | help
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.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200505281540.35116.dom>