NFS client regression, simple test program

From: Jakob Oestergaard
Date: Fri Mar 31 2006 - 06:20:44 EST



Attached is a small test program that exposes the regression.

Kernel LEADING_EMPTY_SPACE wall-clock time to run
2.6.15 0 0.2s
2.6.15 1 29.3s
2.6.14.7 0 0.2s
2.6.14.7 1 0.2s

So it seems that if a file is repeatedly read from and written to, it
matters a lot for later kernels whether or not the blocks that are
worked on, are offset a single byte or not...

Any ideas?

--

/ jakob

/*
* Tiny benchmark for Linux NFS client problem 2.6.14.7->2.6.15
*
* By Jakob Oestergaard, joe@xxxxxxxxxxxxx / joe@xxxxxxxxxxxx
*
* Compile as:
* gcc -o nfsbench -O3 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 nfsbench.c
*/

#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdint.h>

#define MYBLOCKSIZE 32768
#define MYSUBSIZE 1024

/* Set this define to non-zero to expose the regression */
#define LEADING_EMPTY_SPACE 1

int main(int argc, char **argv)
{
int testfd = open("testfile", O_RDWR|O_CREAT|O_TRUNC, 0666);
off_t blockoff;
uint8_t garbage[MYBLOCKSIZE];

memset(garbage, 42, sizeof garbage);

for (blockoff = LEADING_EMPTY_SPACE;
blockoff < 10 * 1024 * 1024;
blockoff += MYBLOCKSIZE) {
off_t inblockoff;
lseek(testfd, blockoff, SEEK_SET);
write(testfd, garbage, MYBLOCKSIZE);

for (inblockoff = MYBLOCKSIZE / 4;
inblockoff < MYBLOCKSIZE * 3 / 4;
inblockoff += MYSUBSIZE * 2) {
uint8_t gdata[MYBLOCKSIZE];
lseek(testfd, blockoff, SEEK_SET);
read(testfd, gdata, MYBLOCKSIZE);
lseek(testfd, -inblockoff, SEEK_CUR);
write(testfd, gdata + inblockoff, MYSUBSIZE);
}
}

close(testfd);
}