diff options
author | trhodes <trhodes@FreeBSD.org> | 2007-01-16 23:43:14 +0000 |
---|---|---|
committer | trhodes <trhodes@FreeBSD.org> | 2007-01-16 23:43:14 +0000 |
commit | 317819a5f62502c2daad8b2f578f62e1cd7f4017 (patch) | |
tree | 938e2f8802f8611f8eddb5688d22683c2de30c63 /sys/fs | |
parent | d4434aa6e90019d12652d4a92904d14ca5765d53 (diff) | |
download | FreeBSD-src-317819a5f62502c2daad8b2f578f62e1cd7f4017.zip FreeBSD-src-317819a5f62502c2daad8b2f578f62e1cd7f4017.tar.gz |
Add 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. And yes, that helps a lot
copying large files always at full speed now, and I have seen
improvements using benchmarks/bonnie.
Stolen from: NetBSD
Reviewed by: bde
Diffstat (limited to 'sys/fs')
-rw-r--r-- | sys/fs/msdosfs/denode.h | 11 | ||||
-rw-r--r-- | sys/fs/msdosfs/msdosfs_fat.c | 11 |
2 files changed, 19 insertions, 3 deletions
diff --git a/sys/fs/msdosfs/denode.h b/sys/fs/msdosfs/denode.h index 4fa51aa..3aac0bc 100644 --- a/sys/fs/msdosfs/denode.h +++ b/sys/fs/msdosfs/denode.h @@ -116,10 +116,12 @@ 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_NEXTTOLASTFC 2 /* entry for a close to the last cluster in + * the file */ #define FCE_EMPTY 0xffffffff /* doesn't represent an actual cluster # */ @@ -130,6 +132,13 @@ struct fatcache { (dep)->de_fc[(slot)].fc_frcn = (frcn); \ (dep)->de_fc[(slot)].fc_fsrcn = (fsrcn); +#define fc_last_to_nexttolast(dep) do { \ + (dep)->de_fc[FC_NEXTTOLASTFC].fc_frcn = \ + (dep)->de_fc[FC_LASTFC].fc_frcn; \ + (dep)->de_fc[FC_NEXTTOLASTFC].fc_fsrcn = \ + (dep)->de_fc[FC_LASTFC].fc_fsrcn; \ +} while (0) + /* * This is the in memory variant of a dos directory entry. It is usually * contained within a vnode. diff --git a/sys/fs/msdosfs/msdosfs_fat.c b/sys/fs/msdosfs/msdosfs_fat.c index 31cf977..1d57a9c 100644 --- a/sys/fs/msdosfs/msdosfs_fat.c +++ b/sys/fs/msdosfs/msdosfs_fat.c @@ -79,6 +79,8 @@ static int fc_bmapcalls; /* # of times pcbmap was called */ static int fc_lmdistance[LMMAX];/* counters for how far off the last * cluster mapped entry was. */ static int fc_largedistance; /* off by more than LMMAX */ +static int fc_wherefrom, fc_whereto, fc_lastclust; +static int pm_fatblocksize; static int chainalloc(struct msdosfsmount *pmp, u_long start, u_long count, u_long fillwith, u_long *retcluster, @@ -119,6 +121,7 @@ fatblock(pmp, ofs, bnp, sizep, bop) *sizep = size; if (bop) *bop = ofs % pmp->pm_fatblocksize; + pm_fatblocksize = pmp->pm_fatblocksize; } /* @@ -210,9 +213,12 @@ pcbmap(dep, findcn, bnp, cnp, sp) */ i = 0; fc_lookup(dep, findcn, &i, &cn); - if ((bn = findcn - i) >= LMMAX) + if ((bn = findcn - i) >= LMMAX) { fc_largedistance++; - else + fc_wherefrom = i; + fc_whereto = findcn; + fc_lastclust = dep->de_fc[FC_LASTFC].fc_frcn; + } else fc_lmdistance[bn]++; /* @@ -1025,6 +1031,7 @@ extendfile(dep, count, bpp, ncp, flags) return (error); } + fc_last_to_nexttolast(dep); while (count > 0) { /* * Allocate a new cluster chain and cat onto the end of the |