• Stephen C. Tweedie's avatar
    [PATCH] ext3 directio block leak fix · edafeee3
    Stephen C. Tweedie authored
    The orphan list holds inodes that need to be truncated on recovery.  In the
    O_DIRECT case, it's used if we extend the inode --- the truncate on recovery
    means we'll recover the newly-allocated disk blocks if we crash after the IO
    starts but before i_size is updated on disk.
    
    Now, the orphan list is *also* used to delete inodes that are unlinked but
    still-open.  Those get truncated but also deleted on recovery.
    
    The orphan list is held both in memory and on disk.  So the rules are that the
    inode can't be reclaimed while on the orphan list.  There are only two cases
    --- either the inode is actively being written(O_DIRECT) or truncated (in
    which case the inode is by definition not going to be reused), or it's
    unlinked but still open (again, non-reclaimable).
    
    But in the case where you're truncating or write(O_DIRECT)ing a file that is
    *ALSO* unlinked, there's a problem --- the final unlink would put the inode on
    the orphan list, but the write/truncate would try to add/remove it.  End
    result is that the inode disappears from the orphan list while it's still
    unlinked-but-in-use.
    
    That's just a leak-on-crash, it's not going to be detectable in normal use. 
    But it's still a bug, and the way we fix it is for direct-IO and truncate not
    to do the ext3_orphan_del if the file is unlinked (ie.  i_nlink==0).
    Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
    edafeee3
inode.c 89.8 KB