From: NeilBrown The read-ahead structures were not being initialised properly, and were not having the use-count decremented after use, making them fairly useless (since Apr 2002!). From: Colin Gibbs Signed-off-by: Neil Brown Signed-off-by: Andrew Morton --- 25-akpm/fs/nfsd/vfs.c | 14 +++++++++----- 1 files changed, 9 insertions(+), 5 deletions(-) diff -puN fs/nfsd/vfs.c~fix-readahead-handling-in-knfsd fs/nfsd/vfs.c --- 25/fs/nfsd/vfs.c~fix-readahead-handling-in-knfsd 2004-05-31 21:04:11.042460624 -0700 +++ 25-akpm/fs/nfsd/vfs.c 2004-05-31 21:04:11.047459864 -0700 @@ -567,7 +567,7 @@ nfsd_sync_dir(struct dentry *dp) static spinlock_t ra_lock = SPIN_LOCK_UNLOCKED; static inline struct raparms * -nfsd_get_raparms(dev_t dev, ino_t ino) +nfsd_get_raparms(dev_t dev, ino_t ino, struct address_space *mapping) { struct raparms *ra, **rap, **frap = NULL; int depth = 0; @@ -589,7 +589,7 @@ nfsd_get_raparms(dev_t dev, ino_t ino) ra = *frap; ra->p_dev = dev; ra->p_ino = ino; - memset(&ra->p_ra, 0, sizeof(ra->p_ra)); + file_ra_state_init(&ra->p_ra, mapping); found: if (rap != &raparm_cache) { *rap = ra->p_next; @@ -661,7 +661,8 @@ nfsd_read(struct svc_rqst *rqstp, struct #endif /* Get readahead parameters */ - ra = nfsd_get_raparms(inode->i_sb->s_dev, inode->i_ino); + ra = nfsd_get_raparms(inode->i_sb->s_dev, inode->i_ino, + inode->i_mapping->host->i_mapping); if (ra) file.f_ra = ra->p_ra; @@ -677,9 +678,12 @@ nfsd_read(struct svc_rqst *rqstp, struct } /* Write back readahead params */ - if (ra) + if (ra) { + spin_lock(&ra_lock); ra->p_ra = file.f_ra; - + ra->p_count--; + spin_unlock(&ra_lock); + } if (err >= 0) { nfsdstats.io_read += err; *count = err; _