--- 2.4.9aa3/mm/filemap.c.~1~ Sun Aug 19 06:59:36 2001 +++ 2.4.9aa3/mm/filemap.c Sun Aug 19 07:33:24 2001 @@ -1645,11 +1645,18 @@ * pages in the previous window. */ if ((pgoff + (ra_window >> 1)) == vma->vm_raend) { - unsigned long start = vma->vm_pgoff + vma->vm_raend; + unsigned long vm_raend = *(volatile unsigned long *) &vma->vm_raend; + unsigned long start = vma->vm_pgoff + vm_raend; unsigned long end = start + ra_window; if (end > ((vma->vm_end >> PAGE_SHIFT) + vma->vm_pgoff)) end = (vma->vm_end >> PAGE_SHIFT) + vma->vm_pgoff; + /* + * Sanitize 'start' as well because vm_raend is racy when only + * the read sem is acquired like here. + */ + if (start < vma->vm_pgoff) + return; if (start > end) return; @@ -1663,10 +1670,10 @@ /* if we're far enough past the beginning of this area, recycle pages that are in the previous window. */ - if (vma->vm_raend > (vma->vm_pgoff + ra_window + ra_window)) { + if (vm_raend > (vma->vm_pgoff + ra_window + ra_window)) { unsigned long window = ra_window << PAGE_SHIFT; - end = vma->vm_start + (vma->vm_raend << PAGE_SHIFT); + end = vma->vm_start + (vm_raend << PAGE_SHIFT); end -= window + window; filemap_sync(vma, end - window, window, MS_INVALIDATE); }