• Nick Piggin's avatar
    fs: symlink write_begin allocation context fix · 54566b2c
    Nick Piggin authored
    With the write_begin/write_end aops, page_symlink was broken because it
    could no longer pass a GFP_NOFS type mask into the point where the
    allocations happened.  They are done in write_begin, which would always
    assume that the filesystem can be entered from reclaim.  This bug could
    cause filesystem deadlocks.
    
    The funny thing with having a gfp_t mask there is that it doesn't really
    allow the caller to arbitrarily tinker with the context in which it can be
    called.  It couldn't ever be GFP_ATOMIC, for example, because it needs to
    take the page lock.  The only thing any callers care about is __GFP_FS
    anyway, so turn that into a single flag.
    
    Add a new flag for write_begin, AOP_FLAG_NOFS.  Filesystems can now act on
    this flag in their write_begin function.  Change __grab_cache_page to
    accept a nofs argument as well, to honour that flag (while we're there,
    change the name to grab_cache_page_write_begin which is more instructive
    and does away with random leading underscores).
    
    This is really a more flexible way to go in the end anyway -- if a
    filesystem happens to want any extra allocations aside from the pagecache
    ones in ints write_begin function, it may now use GFP_KERNEL (rather than
    GFP_NOFS) for common case allocations (eg.  ocfs2_alloc_write_ctxt, for a
    random example).
    
    [kosaki.motohiro@jp.fujitsu.com: fix ubifs]
    [kosaki.motohiro@jp.fujitsu.com: fix fuse]
    Signed-off-by: default avatarNick Piggin <npiggin@suse.de>
    Reviewed-by: default avatarKOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
    Cc: <stable@kernel.org>		[2.6.28.x]
    Signed-off-by: default avatarKOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    [ Cleaned up the calling convention: just pass in the AOP flags
      untouched to the grab_cache_page_write_begin() function.  That
      just simplifies everybody, and may even allow future expansion of the
      logic.   - Linus ]
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    54566b2c
file.c 23.6 KB