We need to set file->f_ra _after_ calling blkdev_open(), when inode->i_mapping points at the right thing. And we need to get it from inode->i_mapping->host->i_mapping too, which represents the underlying device. Also, don't test for null file->f_mapping in the O_DIRECT checks. Signed-off-by: Andrew Morton --- 25-akpm/fs/open.c | 10 +++++----- 1 files changed, 5 insertions(+), 5 deletions(-) diff -puN fs/open.c~blockdev-readahead-fix fs/open.c --- 25/fs/open.c~blockdev-readahead-fix Tue May 25 15:38:15 2004 +++ 25-akpm/fs/open.c Tue May 25 17:15:17 2004 @@ -790,7 +790,6 @@ struct file *dentry_open(struct dentry * } f->f_mapping = inode->i_mapping; - file_ra_state_init(&f->f_ra, f->f_mapping); f->f_dentry = dentry; f->f_vfsmnt = mnt; f->f_pos = 0; @@ -804,12 +803,13 @@ struct file *dentry_open(struct dentry * } f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); + file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping); + /* NB: we're sure to have correct a_ops only after f_op->open */ if (f->f_flags & O_DIRECT) { - if (!f->f_mapping || !f->f_mapping->a_ops || - !f->f_mapping->a_ops->direct_IO) { - fput(f); - f = ERR_PTR(-EINVAL); + if (!f->f_mapping->a_ops || !f->f_mapping->a_ops->direct_IO) { + fput(f); + f = ERR_PTR(-EINVAL); } } _