From 8fac418a89fbb00fa745b5cd78c1981484584008 Mon Sep 17 00:00:00 2001 From: trhodes Date: Thu, 8 Mar 2007 03:01:00 +0000 Subject: [PATCH] MFC: 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 | 12 ++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/sys/fs/msdosfs/denode.h b/sys/fs/msdosfs/denode.h index cbba8e79af11..4d73f92185a6 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 31cf977f17ed..9ecee880d8b2 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,8 @@ 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