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

Reply via email to