i386/68719: [usb] USB 2.0 mobil rack+ fat32 performance problem
Dominic Marks
dom at goodforbusiness.co.uk
Sat May 28 08:10:05 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: <james>
Cc: <freebsd-fs at FreeBSD.org>,
<freebsd-gnats-submit at FreeBSD.org>,
<banhalmi at field.hu>
Subject: Re: i386/68719: [usb] USB 2.0 mobil rack+ fat32 performance problem
Date: Sat, 28 May 2005 16:00:22 +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.
_______________________________________________
freebsd-fs at freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-fs
To unsubscribe, send any mail to "freebsd-fs-unsubscribe at freebsd.org"
More information about the freebsd-usb
mailing list