[fs] various filesystem updates

UPDATE: misc ext4 tweaks

UPDATE: more FS tweaks

fs: mark_inode_dirty barrier fix

    Filesystems appear to be using ->dirty_inode, expecting that the dirtying
    operating is done and visible to all CPUs (eg. setting private inode dirty
    bits, without any barriers themselves). So release the dirty "critical
    section" with a barrier before calling ->dirty_inode.

    Cost is not significantly changed, because we're just moving the barrier.
    Those filesystems that do use ->dirty_inode should have to care slightly
    less about barriers, which is a good thing.

    Signed-off-by: Nick Piggin <npiggin@kernel.dk>

fs: simple fsync race fix

    It is incorrect to test inode dirty bits without participating in the inode
    writeback protocol. Inode writeback sets I_SYNC and clears I_DIRTY_?, then
    writes out the particular bits, then clears I_SYNC when it is done. BTW. it
    may not completely write all pages out, so I_DIRTY_PAGES would get set
    again.

    This is a standard pattern used throughout the kernel's writeback caches
    (I_SYNC ~= I_WRITEBACK, if that makes it clearer).

    And so it is not possible to determine an inode's dirty status just by
    checking I_DIRTY bits. Especially not for the purpose of data integrity
    syncs.

    Missing the check for these bits means that fsync can complete while
    writeback to the inode is underway. Inode writeback functions get this
    right, so call into them rather than try to shortcut things by testing
    dirty state improperly.

    Signed-off-by: Nick Piggin <npiggin@kernel.dk>

tmpfs: fix race between truncate and writepage

    commit 826267cf1e6c6899eda1325a19f1b1d15c558b20 upstream.

    While running fsx on tmpfs with a memhog then swapoff, swapoff was hanging
    (interruptibly), repeatedly failing to locate the owner of a 0xff entry in
    the swap_map.

    Although shmem_writepage() does abandon when it sees incoming page index
    is beyond eof, there was still a window in which shmem_truncate_range()
    could come in between writepage's dropping lock and updating swap_map,
    find the half-completed swap_map entry, and in trying to free it,
    leave it in a state that swap_shmem_alloc() could not correct.

    Arguably a bug in __swap_duplicate()'s and swap_entry_free()'s handling
    of the different cases, but easiest to fix by moving swap_shmem_alloc()
    under cover of the lock.

    More interesting than the bug: it's been there since 2.6.33, why could
    I not see it with earlier kernels?  The mmotm of two weeks ago seems to
    have some magic for generating races, this is just one of three I found.

    With yesterday's git I first saw this in mainline, bisected in search of
    that magic, but the easy reproducibility evaporated.  Oh well, fix the bug.

    Signed-off-by: Hugh Dickins <hughd@google.com>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

Ext4: fail if we try to use hole punch

    Ext4 doesn't have the ability to punch holes yet, so make sure we return
    EOPNOTSUPP if we try to use hole punching through fallocate.  This support can
    be added later.  Thanks,

    Acked-by: Jan Kara <jack@suse.cz>
    Signed-off-by: Josef Bacik <josef@redhat.com>
    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

fs: add hole punching to fallocate

    Hole punching has already been implemented by XFS and OCFS2, and has the
    potential to be implemented on both BTRFS and EXT4 so we need a generic way to
    get to this feature.  The simplest way in my mind is to add FALLOC_FL_PUNCH_HOLE
    to fallocate() since it already looks like the normal fallocate() operation.
    I've tested this patch with XFS and BTRFS to make sure XFS did what it's
    supposed to do and that BTRFS failed like it was supposed to.  Thank you,

    Signed-off-by: Josef Bacik <josef@redhat.com>
    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

fs/select.c: fix information leak to userspace

    On some architectures __kernel_suseconds_t is int.  On these archs struct
    timeval has padding bytes at the end.  This struct is copied to userspace
    with these padding bytes uninitialized.  This leads to leaking of contents
    of kernel stack memory.

    This bug was added with v2.6.27-rc5-286-gb773ad4.

    [akpm@linux-foundation.org: avoid the memset on architectures which don't need it]
    Signed-off-by: Vasiliy Kulikov <segooon@gmail.com>
    Cc: Al Viro <viro@zeniv.linux.org.uk>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

fs: Use this_cpu_xx operations in buffer.c

    Optimize various per cpu area operations through these new percpu
    operations.  These operations avoid address calculations through the
    use of segment prefixes and multiple memory references through RMW
    instructions etc.

    Reduces code size:

    Before:

    christoph@linux-2.6$ size fs/buffer.o
       text	   data	    bss	    dec	    hex	filename
      19169	     80	     28	  19277	   4b4d	fs/buffer.o

    After:

    christoph@linux-2.6$ size fs/buffer.o
       text	   data	    bss	    dec	    hex	filename
      19138	     80	     28	  19246	   4b2e	fs/buffer.o

    V3->V4:
    	- Move the use of this_cpu_inc_return into a later patch so that
    	  this one can go in without percpu infrastructure changes.

    Cc: Wu Fengguang <fengguang.wu@intel.com>
    Cc: Christoph Hellwig <hch@lst.de>
    Acked-by: H. Peter Anvin <hpa@zytor.com>
    Signed-off-by: Christoph Lameter <cl@linux.com>
    Signed-off-by: Tejun Heo <tj@kernel.org>

fs: Use this_cpu_inc_return in buffer.c

    __this_cpu_inc can create a single instruction with the same effect
    as the _get_cpu_var(..)++ construct in buffer.c.

    Cc: Wu Fengguang <fengguang.wu@intel.com>
    Cc: Christoph Hellwig <hch@lst.de>
    Acked-by: H. Peter Anvin <hpa@zytor.com>
    Signed-off-by: Christoph Lameter <cl@linux.com>
    Signed-off-by: Tejun Heo <tj@kernel.org>