13 Jan, 2012

1 commit

  • When a user with the CAP_SYS_RESOURCE cap tries to F_SETPIPE_SZ a pipe
    with size bigger than kmalloc() can alloc it spits out an ugly warning:

    ------------[ cut here ]------------
    WARNING: at mm/page_alloc.c:2095 __alloc_pages_nodemask+0x5d3/0x7a0()
    Pid: 733, comm: a.out Not tainted 3.2.0-rc1+ #4
    Call Trace:
    warn_slowpath_common+0x75/0xb0
    warn_slowpath_null+0x15/0x20
    __alloc_pages_nodemask+0x5d3/0x7a0
    __get_free_pages+0x12/0x50
    __kmalloc+0x12b/0x150
    pipe_set_size+0x75/0x120
    pipe_fcntl+0xf8/0x140
    do_fcntl+0x2d4/0x410
    sys_fcntl+0x66/0xa0
    system_call_fastpath+0x16/0x1b
    ---[ end trace 432f702e6db7b5ee ]---

    Instead, make kcalloc() handle the overflow case and fail quietly.

    [akpm@linux-foundation.org: switch to sizeof(*bufs) for 80-column niceness]
    Signed-off-by: Sasha Levin
    Cc: Alexander Viro
    Acked-by: Pekka Enberg
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Sasha Levin
     

04 Jan, 2012

1 commit


01 Nov, 2011

1 commit

  • Currently a statfs on a pipe's /proc//fd/ link returns -ENOSYS. Wire
    pipfs up so that the statfs succeeds.

    This is required by checkpoint-restart in the userspace to make it
    possible to distinguish pipes from fifos.

    When we dump information about task's open files we use the /proc/pid/fd
    directoy's symlinks and the fact that opening any of them gives us exactly
    the same dentry->inode pair as the original process has. Now if a task
    we're dumping has opened pipe and fifo we need to detect this and act
    accordingly. Knowing that an fd with type S_ISFIFO resides on a pipefs is
    the most precise way.

    Signed-off-by: Pavel Emelyanov
    Reviewed-by: Tejun Heo
    Acked-by: Serge Hallyn
    Signed-off-by: Cyrill Gorcunov
    Cc: Al Viro
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Pavel Emelyanov
     

27 Jul, 2011

1 commit


24 Jul, 2011

1 commit

  • For a number of file systems that don't have a mount point (e.g. sockfs
    and pipefs), they are not marked as long term. Therefore in
    mntput_no_expire, all locks in vfs_mount lock are taken instead of just
    local cpu's lock to aggregate reference counts when we release
    reference to file objects. In fact, only local lock need to have been
    taken to update ref counts as these file systems are in no danger of
    going away until we are ready to unregister them.

    The attached patch marks file systems using kern_mount without
    mount point as long term. The contentions of vfs_mount lock
    is now eliminated. Before un-registering such file system,
    kern_unmount should be called to remove the long term flag and
    make the mount point ready to be freed.

    Signed-off-by: Tim Chen
    Signed-off-by: Al Viro

    Tim Chen
     

21 Jan, 2011

1 commit

  • Commit e462c448fdc8 ("pipe: use event aware wakeups") optimized the pipe
    event wakeup calls to avoid wakeups if the events do not match the
    requested set.

    However, the optimization was buggy, in that it didn't actually use the
    correct sets for the events: when we make room for more data to be
    written, the pipe poll() routine will return both the POLLOUT _and_
    POLLWRNORM bits. Similarly for read.

    And most critically, when a pipe is released, that will potentially
    result in POLLHUP|POLLERR (depending on whether it was the last reader
    or writer), not just the regular POLLIN|POLLOUT.

    This bug showed itself as a hung gnome-screensaver-dialog process, stuck
    forever (or at least until it was poked by a signal or by being traced)
    in a poll() system call.

    Cc: Davide Libenzi
    Cc: David S. Miller
    Cc: Eric Dumazet
    Cc: Jens Axboe
    Cc: Andrew Morton
    Signed-off-by: Linus Torvalds

    Linus Torvalds
     

17 Jan, 2011

1 commit

  • Instead of splitting refcount between (per-cpu) mnt_count
    and (SMP-only) mnt_longrefs, make all references contribute
    to mnt_count again and keep track of how many are longterm
    ones.

    Accounting rules for longterm count:
    * 1 for each fs_struct.root.mnt
    * 1 for each fs_struct.pwd.mnt
    * 1 for having non-NULL ->mnt_ns
    * decrement to 0 happens only under vfsmount lock exclusive

    That allows nice common case for mntput() - since we can't drop the
    final reference until after mnt_longterm has reached 0 due to the rules
    above, mntput() can grab vfsmount lock shared and check mnt_longterm.
    If it turns out to be non-zero (which is the common case), we know
    that this is not the final mntput() and can just blindly decrement
    percpu mnt_count. Otherwise we grab vfsmount lock exclusive and
    do usual decrement-and-check of percpu mnt_count.

    For fs_struct.c we have mnt_make_longterm() and mnt_make_shortterm();
    namespace.c uses the latter in places where we don't already hold
    vfsmount lock exclusive and opencodes a few remaining spots where
    we need to manipulate mnt_longterm.

    Note that we mostly revert the code outside of fs/namespace.c back
    to what we used to have; in particular, normal code doesn't need
    to care about two kinds of references, etc. And we get to keep
    the optimization Nick's variant had bought us...

    Signed-off-by: Al Viro

    Al Viro
     

14 Jan, 2011

2 commits

  • * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: (41 commits)
    fs: add documentation on fallocate hole punching
    Gfs2: fail if we try to use hole punch
    Btrfs: fail if we try to use hole punch
    Ext4: fail if we try to use hole punch
    Ocfs2: handle hole punching via fallocate properly
    XFS: handle hole punching via fallocate properly
    fs: add hole punching to fallocate
    vfs: pass struct file to do_truncate on O_TRUNC opens (try #2)
    fix signedness mess in rw_verify_area() on 64bit architectures
    fs: fix kernel-doc for dcache::prepend_path
    fs: fix kernel-doc for dcache::d_validate
    sanitize ecryptfs ->mount()
    switch afs
    move internal-only parts of ncpfs headers to fs/ncpfs
    switch ncpfs
    switch 9p
    pass default dentry_operations to mount_pseudo()
    switch hostfs
    switch affs
    switch configfs
    ...

    Linus Torvalds
     
  • Send the events the wakeup refers to, so that epoll, and even the new poll
    code in fs/select.c can avoid wakeups if the events do not match the
    requested set.

    Signed-off-by: Davide Libenzi
    Acked-by: David S. Miller
    Acked-by: Eric Dumazet
    Cc: Jens Axboe
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Davide Libenzi
     

13 Jan, 2011

1 commit


07 Jan, 2011

4 commits

  • The problem that this patch aims to fix is vfsmount refcounting scalability.
    We need to take a reference on the vfsmount for every successful path lookup,
    which often go to the same mount point.

    The fundamental difficulty is that a "simple" reference count can never be made
    scalable, because any time a reference is dropped, we must check whether that
    was the last reference. To do that requires communication with all other CPUs
    that may have taken a reference count.

    We can make refcounts more scalable in a couple of ways, involving keeping
    distributed counters, and checking for the global-zero condition less
    frequently.

    - check the global sum once every interval (this will delay zero detection
    for some interval, so it's probably a showstopper for vfsmounts).

    - keep a local count and only taking the global sum when local reaches 0 (this
    is difficult for vfsmounts, because we can't hold preempt off for the life of
    a reference, so a counter would need to be per-thread or tied strongly to a
    particular CPU which requires more locking).

    - keep a local difference of increments and decrements, which allows us to sum
    the total difference and hence find the refcount when summing all CPUs. Then,
    keep a single integer "long" refcount for slow and long lasting references,
    and only take the global sum of local counters when the long refcount is 0.

    This last scheme is what I implemented here. Attached mounts and process root
    and working directory references are "long" references, and everything else is
    a short reference.

    This allows scalable vfsmount references during path walking over mounted
    subtrees and unattached (lazy umounted) mounts with processes still running
    in them.

    This results in one fewer atomic op in the fastpath: mntget is now just a
    per-CPU inc, rather than an atomic inc; and mntput just requires a spinlock
    and non-atomic decrement in the common case. However code is otherwise bigger
    and heavier, so single threaded performance is basically a wash.

    Signed-off-by: Nick Piggin

    Nick Piggin
     
  • Regardless of how much we possibly try to scale dcache, there is likely
    always going to be some fundamental contention when adding or removing children
    under the same parent. Pseudo filesystems do not seem need to have connected
    dentries because by definition they are disconnected.

    Signed-off-by: Nick Piggin

    Nick Piggin
     
  • Reduce some branches and memory accesses in dcache lookup by adding dentry
    flags to indicate common d_ops are set, rather than having to check them.
    This saves a pointer memory access (dentry->d_op) in common path lookup
    situations, and saves another pointer load and branch in cases where we
    have d_op but not the particular operation.

    Patched with:

    git grep -E '[.>]([[:space:]])*d_op([[:space:]])*=' | xargs sed -e 's/\([^\t ]*\)->d_op = \(.*\);/d_set_d_op(\1, \2);/' -e 's/\([^\t ]*\)\.d_op = \(.*\);/d_set_d_op(\&\1, \2);/' -i

    Signed-off-by: Nick Piggin

    Nick Piggin
     
  • Pseudo filesystems that don't put inode on RCU list or reachable by
    rcu-walk dentries do not need to RCU free their inodes.

    Signed-off-by: Nick Piggin

    Nick Piggin
     

29 Nov, 2010

2 commits

  • This avoids some include-file hell, and the function isn't really
    important enough to be inlined anyway.

    Reported-by: Ingo Molnar
    Signed-off-by: Linus Torvalds

    Linus Torvalds
     
  • And in particular, use it in 'pipe_fcntl()'.

    The other pipe functions do not need to use the 'careful' version, since
    they are only ever called for things that are already known to be pipes.

    The normal read/write/ioctl functions are called through the file
    operations structures, so if a file isn't a pipe, they'd never get
    called. But pipe_fcntl() is special, and called directly from the
    generic fcntl code, and needs to use the same careful function that the
    splice code is using.

    Cc: Jens Axboe
    Cc: Andrew Morton
    Cc: Al Viro
    Cc: Dave Jones
    Signed-off-by: Linus Torvalds

    Linus Torvalds
     

29 Oct, 2010

1 commit


26 Oct, 2010

1 commit

  • Instead of always assigning an increasing inode number in new_inode
    move the call to assign it into those callers that actually need it.
    For now callers that need it is estimated conservatively, that is
    the call is added to all filesystems that do not assign an i_ino
    by themselves. For a few more filesystems we can avoid assigning
    any inode number given that they aren't user visible, and for others
    it could be done lazily when an inode number is actually needed,
    but that's left for later patches.

    Signed-off-by: Christoph Hellwig
    Signed-off-by: Dave Chinner
    Signed-off-by: Al Viro

    Christoph Hellwig
     

21 Oct, 2010

1 commit


11 Jun, 2010

2 commits

  • As it stands this check compares the number of pages to the page size.
    This makes no sense and makes the fcntl fail in almost any sane case.

    Fix it by checking if nr_pages is not zero (it can become zero only if
    arg is too big and round_pipe_size() overflows).

    Signed-off-by: Miklos Szeredi
    Signed-off-by: Jens Axboe

    Miklos Szeredi
     
  • pipe_set_size() needs to copy pipe bufs from the old circular buffer
    to the new.

    The current code gets this wrong in multiple ways, resulting in oops.

    Test program is available here:
    http://www.kernel.org/pub/linux/kernel/people/mszeredi/piperesize/

    Signed-off-by: Miklos Szeredi
    Signed-off-by: Jens Axboe

    Miklos Szeredi
     

03 Jun, 2010

3 commits


01 Jun, 2010

1 commit


31 May, 2010

1 commit


28 May, 2010

1 commit

  • Add a mutex_unlock missing on the error path. At other exists from the
    function that return an error flag, the mutex is unlocked, so do the same
    here.

    The semantic match that finds this problem is as follows:
    (http://coccinelle.lip6.fr/)

    //
    @@
    expression E1;
    @@

    * mutex_lock(E1,...);

    * mutex_unlock(E1,...);
    //

    Signed-off-by: Julia Lawall
    Signed-off-by: Al Viro

    Julia Lawall
     

26 May, 2010

1 commit


25 May, 2010

2 commits


22 May, 2010

2 commits


17 Dec, 2009

3 commits


22 Oct, 2009

1 commit

  • This patch fixes a null pointer exception in pipe_rdwr_open() which
    generates the stack trace:

    > Unable to handle kernel NULL pointer dereference at 0000000000000028 RIP:
    > [] pipe_rdwr_open+0x35/0x70
    > [] __dentry_open+0x13c/0x230
    > [] do_filp_open+0x2d/0x40
    > [] do_sys_open+0x5a/0x100
    > [] sysenter_do_call+0x1b/0x67

    The failure mode is triggered by an attempt to open an anonymous
    pipe via /proc/pid/fd/* as exemplified by this script:

    =============================================================
    while : ; do
    { echo y ; sleep 1 ; } | { while read ; do echo z$REPLY; done ; } &
    PID=$!
    OUT=$(ps -efl | grep 'sleep 1' | grep -v grep |
    { read PID REST ; echo $PID; } )
    OUT="${OUT%% *}"
    DELAY=$((RANDOM * 1000 / 32768))
    usleep $((DELAY * 1000 + RANDOM % 1000 ))
    echo n > /proc/$OUT/fd/1 # Trigger defect
    done
    =============================================================

    Note that the failure window is quite small and I could only
    reliably reproduce the defect by inserting a small delay
    in pipe_rdwr_open(). For example:

    static int
    pipe_rdwr_open(struct inode *inode, struct file *filp)
    {
    msleep(100);
    mutex_lock(&inode->i_mutex);

    Although the defect was observed in pipe_rdwr_open(), I think it
    makes sense to replicate the change through all the pipe_*_open()
    functions.

    The core of the change is to verify that inode->i_pipe has not
    been released before attempting to manipulate it. If inode->i_pipe
    is no longer present, return ENOENT to indicate so.

    The comment about potentially using atomic_t for i_pipe->readers
    and i_pipe->writers has also been removed because it is no longer
    relevant in this context. The inode->i_mutex lock must be used so
    that inode->i_pipe can be dealt with correctly.

    Signed-off-by: Earl Chew
    Cc: stable@kernel.org
    Signed-off-by: Linus Torvalds

    Earl Chew
     

23 Jul, 2009

1 commit

  • The presumed use of the pipe_double_lock() routine is to lock 2 locks in
    a deadlock free way by ordering the locks by their address. However it
    fails to keep the specified lock classes in order and explicitly
    annotates a deadlock.

    Rectify this.

    Signed-off-by: Peter Zijlstra
    Acked-by: Miklos Szeredi
    LKML-Reference:

    Peter Zijlstra
     

11 May, 2009

1 commit

  • If f_op->splice_read() is not implemented, fall back to a plain read.
    Use vfs_readv() to read into previously allocated pages.

    This will allow splice and functions using splice, such as the loop
    device, to work on all filesystems. This includes "direct_io" files
    in fuse which bypass the page cache.

    Signed-off-by: Miklos Szeredi
    Signed-off-by: Jens Axboe

    Miklos Szeredi
     

15 Apr, 2009

1 commit

  • There are lots of sequences like this, especially in splice code:

    if (pipe->inode)
    mutex_lock(&pipe->inode->i_mutex);
    /* do something */
    if (pipe->inode)
    mutex_unlock(&pipe->inode->i_mutex);

    so introduce helpers which do the conditional locking and unlocking.
    Also replace the inode_double_lock() call with a pipe_double_lock()
    helper to avoid spreading the use of this functionality beyond the
    pipe code.

    This patch is just a cleanup, and should cause no behavioral changes.

    Signed-off-by: Miklos Szeredi
    Signed-off-by: Jens Axboe

    Miklos Szeredi
     

28 Mar, 2009

1 commit

  • * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: (37 commits)
    fs: avoid I_NEW inodes
    Merge code for single and multiple-instance mounts
    Remove get_init_pts_sb()
    Move common mknod_ptmx() calls into caller
    Parse mount options just once and copy them to super block
    Unroll essentials of do_remount_sb() into devpts
    vfs: simple_set_mnt() should return void
    fs: move bdev code out of buffer.c
    constify dentry_operations: rest
    constify dentry_operations: configfs
    constify dentry_operations: sysfs
    constify dentry_operations: JFS
    constify dentry_operations: OCFS2
    constify dentry_operations: GFS2
    constify dentry_operations: FAT
    constify dentry_operations: FUSE
    constify dentry_operations: procfs
    constify dentry_operations: ecryptfs
    constify dentry_operations: CIFS
    constify dentry_operations: AFS
    ...

    Linus Torvalds