On Wed, Apr 04, 2012 at 03:51:38PM +0200, Mike Belopuhov wrote: > On Wed, Apr 04, 2012 at 14:42 +0400, Alexander Polakov wrote: > > This is a diff from NetBSD pr.34583: > > http://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=34583 > > > > Quoting the author: > > > > "I noticed that when writing large file (hundreds of megabytes) > > to an msdos disk, the writing speed to a file decreases with the > > file length. > > Since I have some experience with messydos filesystems (I wrote > > MSH: for the Amiga) I took a look. > > The obvious suspicion with operations that slow down with the > > length of a file is an excessive traversal of the FAT cluster > > chain. However, there is a cache that caches 2 positions: the > > last cluster in the file, and the "most recently looked up" one. > > Debugging info showed however that frequent full traversals were > > still made. So, apparently when extending a file and after > > updating the end cluster, the previous end is again needed. > > Adding a 3rd entry in the cache, which keeps the end position > > from just before extending a file. > > This has the desired effect of keeping the write speed constant. > > (What it is that needs that position I have not been able to > > ascertain from the filesystem code; it doesn't seem to make > > sense, actually, to read or write clusters before the original > > EOF. I was hoping to find the place where the cache is trashed > > and rewrite it to get the desired info from it beforehand, so > > that the extra cache entry is again unneeded, but alas.)" > > > > While there, I changed 0 to NULL for two pointer arguments of > > extendfile(). > > > > i agree that this is a great find. i don't really like the diff though. > i see no point in introducing this macro. what do others think?
Agreed. I like this version better. .... Ken > > Index: msdosfs/denode.h > =================================================================== > RCS file: /cvs/src/sys/msdosfs/denode.h,v > retrieving revision 1.23 > diff -u -p -r1.23 denode.h > --- msdosfs/denode.h 17 Jul 2010 19:27:07 -0000 1.23 > +++ msdosfs/denode.h 4 Apr 2012 12:20:23 -0000 > @@ -116,10 +116,11 @@ struct fatcache { > * cache is probably pretty worthless if a file is opened by multiple > * processes. > */ > -#define FC_SIZE 2 /* number of entries in the cache */ > +#define FC_SIZE 3 /* number of entries in the cache */ > #define FC_LASTMAP 0 /* entry the last call to pcbmap() > resolved > * to */ > #define FC_LASTFC 1 /* entry for the last cluster in the > file */ > +#define FC_OLASTFC 2 /* entry for the previous last cluster > */ > > #define FCE_EMPTY 0xffffffff /* doesn't represent an actual > cluster # */ > > Index: msdosfs/msdosfs_fat.c > =================================================================== > RCS file: /cvs/src/sys/msdosfs/msdosfs_fat.c,v > retrieving revision 1.22 > diff -u -p -r1.22 msdosfs_fat.c > --- msdosfs/msdosfs_fat.c 4 Jul 2011 04:30:41 -0000 1.22 > +++ msdosfs/msdosfs_fat.c 4 Apr 2012 12:20:26 -0000 > @@ -952,6 +952,13 @@ extendfile(struct denode *dep, uint32_t > return (error); > } > > + /* > + * Preserve value for the last cluster before extending the file > + * to speed up further lookups. > + */ > + fc_setcache(dep, FC_OLASTFC, dep->de_fc[FC_LASTFC].fc_frcn, > + dep->de_fc[FC_LASTFC].fc_fsrcn); > + > while (count > 0) { > /* > * Allocate a new cluster chain and cat onto the end of the