• Nick Piggin's avatar
    fs: fix nobh error handling · a4b0672d
    Nick Piggin authored
    nobh mode error handling is not just pretty slack, it's wrong.
    
    One cannot zero out the whole page to ensure new blocks are zeroed, because
    it just brings the whole page "uptodate" with zeroes even if that may not
    be the correct uptodate data.  Also, other parts of the page may already
    contain dirty data which would get lost by zeroing it out.  Thirdly, the
    writeback of zeroes to the new blocks will also erase existing blocks.  All
    these conditions are pagecache and/or filesystem corruption.
    
    The problem comes about because we didn't keep track of which buffers
    actually are new or old.  However it is not enough just to keep only this
    state, because at the point we start dirtying parts of the page (new
    blocks, with zeroes), the handling of IO errors becomes impossible without
    buffers because the page may only be partially uptodate, in which case the
    page flags allone cannot capture the state of the parts of the page.
    
    So allocate all buffers for the page upfront, but leave them unattached so
    that they don't pick up any other references and can be freed when we're
    done.  If the error path is hit, then zero the new buffers as the regular
    buffer path does, then attach the buffers to the page so that it can
    actually be written out correctly and be subject to the normal IO error
    handling paths.
    
    As an upshot, we save 1K of kernel stack on ia64 or powerpc 64K page
    systems.
    Signed-off-by: default avatarNick Piggin <npiggin@suse.de>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    a4b0672d
buffer.c 81.4 KB