From 317819a5f62502c2daad8b2f578f62e1cd7f4017 Mon Sep 17 00:00:00 2001 From: trhodes Date: Tue, 16 Jan 2007 23:43:14 +0000 Subject: 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 --- sys/fs/msdosfs/denode.h | 11 ++++++++++- sys/fs/msdosfs/msdosfs_fat.c | 11 +++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) (limited to 'sys/fs/msdosfs') 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 -- cgit v1.1