• Zach Brown's avatar
    [PATCH] dio: invalidate clean pages before dio write · 65b8291c
    Zach Brown authored
    This patch fixes a user-triggerable oops that was reported by Leonid
    Ananiev as archived at http://lkml.org/lkml/2007/2/8/337.
    
    dio writes invalidate clean pages that intersect the written region so that
    subsequent buffered reads go to disk to read the new data.  If this fails
    the interface tries to tell the caller that the cache is inconsistent by
    returning EIO.
    
    Before this patch we had the problem where this invalidation failure would
    clobber -EIOCBQUEUED as it made its way from fs/direct-io.c to fs/aio.c.
    Both fs/aio.c and bio completion call aio_complete() and we reference freed
    memory, usually oopsing.
    
    This patch addresses this problem by invalidating before the write so that
    we can cleanly return -EIO before ->direct_IO() has had a chance to return
    -EIOCBQUEUED.
    
    There is a compromise here.  During the dio write we can fault in mmap()ed
    pages which intersect the written range with get_user_pages() if the user
    provided them for the source buffer.  This is a crazy thing to do, but we
    can make it mostly work in most cases by trying the invalidation again.
    The compromise is that we won't return an error if this second invalidation
    fails if it's an AIO write and we have -EIOCBQUEUED.
    
    This was tested by having two processes race performing large O_DIRECT and
    buffered ordered writes.  Within minutes ext3 would see a race between
    ext3_releasepage() and jbd holding a reference on ordered data buffers and
    would cause invalidation to fail, panicing the box.  The test can be found
    in the 'aio_dio_bugs' test group in test.kernel.org/autotest.  After this
    patch the test passes.
    Signed-off-by: default avatarZach Brown <zach.brown@oracle.com>
    Signed-off-by: default avatarBenjamin LaHaise <bcrl@kvack.org>
    Cc: Leonid Ananiev <leonid.i.ananiev@linux.intel.com>
    Cc: Nick Piggin <nickpiggin@yahoo.com.au>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    65b8291c
filemap.c 63.5 KB