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

3 commits

  • * '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
     
  • Signed-off-by: Al Viro

    Al Viro
     
  • The last user of do_pipe is in arch/alpha/, after replacing it with
    do_pipe_flags, the do_pipe can be totally dropped.

    Signed-off-by: Cheng Renquan
    Acked-by: Richard Henderson
    Signed-off-by: Al Viro

    Cheng Renquan
     

16 Mar, 2009

1 commit

  • Most fasync implementations do something like:

    return fasync_helper(...);

    But fasync_helper() will return a positive value at times - a feature used
    in at least one place. Thus, a number of other drivers do:

    err = fasync_helper(...);
    if (err < 0)
    return err;
    return 0;

    In the interests of consistency and more concise code, it makes sense to
    map positive return values onto zero where ->fasync() is called.

    Cc: Al Viro
    Signed-off-by: Jonathan Corbet

    Jonathan Corbet
     

13 Mar, 2009

1 commit

  • If the second fasync_helper() fails, pipe_rdwr_fasync() returns the error
    but leaves the file on ->fasync_readers.

    This was always wrong, but since 233e70f4228e78eb2f80dc6650f65d3ae3dbf17c
    "saner FASYNC handling on file close" we have the new problem. Because in
    this case setfl() doesn't set FASYNC bit, __fput() will not do
    ->fasync(0), and we leak fasync_struct with ->fa_file pointing to the
    freed file.

    Signed-off-by: Oleg Nesterov
    Cc: Al Viro
    Cc: Andi Kleen
    Cc: Jonathan Corbet
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Oleg Nesterov
     

14 Jan, 2009

3 commits


05 Jan, 2009

1 commit


14 Nov, 2008

1 commit

  • Wrap access to task credentials so that they can be separated more easily from
    the task_struct during the introduction of COW creds.

    Change most current->(|e|s|fs)[ug]id to current_(|e|s|fs)[ug]id().

    Change some task->e?[ug]id to task_e?[ug]id(). In some places it makes more
    sense to use RCU directly rather than a convenient wrapper; these will be
    addressed by later patches.

    Signed-off-by: David Howells
    Reviewed-by: James Morris
    Acked-by: Serge Hallyn
    Cc: Al Viro
    Signed-off-by: James Morris

    David Howells
     

02 Nov, 2008

1 commit

  • As it is, all instances of ->release() for files that have ->fasync()
    need to remember to evict file from fasync lists; forgetting that
    creates a hole and we actually have a bunch that *does* forget.

    So let's keep our lives simple - let __fput() check FASYNC in
    file->f_flags and call ->fasync() there if it's been set. And lose that
    crap in ->release() instances - leaving it there is still valid, but we
    don't have to bother anymore.

    Signed-off-by: Al Viro
    Signed-off-by: Linus Torvalds

    Al Viro
     

27 Jul, 2008

1 commit


25 Jul, 2008

2 commits

  • This patch adds O_NONBLOCK support to pipe2. It is minimally more involved
    than the patches for eventfd et.al but still trivial. The interfaces of the
    create_write_pipe and create_read_pipe helper functions were changed and the
    one other caller as well.

    The following test must be adjusted for architectures other than x86 and
    x86-64 and in case the syscall numbers changed.

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    #include
    #include
    #include
    #include

    #ifndef __NR_pipe2
    # ifdef __x86_64__
    # define __NR_pipe2 293
    # elif defined __i386__
    # define __NR_pipe2 331
    # else
    # error "need __NR_pipe2"
    # endif
    #endif

    int
    main (void)
    {
    int fds[2];
    if (syscall (__NR_pipe2, fds, 0) == -1)
    {
    puts ("pipe2(0) failed");
    return 1;
    }
    for (int i = 0; i < 2; ++i)
    {
    int fl = fcntl (fds[i], F_GETFL);
    if (fl == -1)
    {
    puts ("fcntl failed");
    return 1;
    }
    if (fl & O_NONBLOCK)
    {
    printf ("pipe2(0) set non-blocking mode for fds[%d]\n", i);
    return 1;
    }
    close (fds[i]);
    }

    if (syscall (__NR_pipe2, fds, O_NONBLOCK) == -1)
    {
    puts ("pipe2(O_NONBLOCK) failed");
    return 1;
    }
    for (int i = 0; i < 2; ++i)
    {
    int fl = fcntl (fds[i], F_GETFL);
    if (fl == -1)
    {
    puts ("fcntl failed");
    return 1;
    }
    if ((fl & O_NONBLOCK) == 0)
    {
    printf ("pipe2(O_NONBLOCK) does not set non-blocking mode for fds[%d]\n", i);
    return 1;
    }
    close (fds[i]);
    }

    puts ("OK");

    return 0;
    }
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Signed-off-by: Ulrich Drepper
    Acked-by: Davide Libenzi
    Cc: Michael Kerrisk
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ulrich Drepper
     
  • This patch introduces the new syscall pipe2 which is like pipe but it also
    takes an additional parameter which takes a flag value. This patch implements
    the handling of O_CLOEXEC for the flag. I did not add support for the new
    syscall for the architectures which have a special sys_pipe implementation. I
    think the maintainers of those archs have the chance to go with the unified
    implementation but that's up to them.

    The implementation introduces do_pipe_flags. I did that instead of changing
    all callers of do_pipe because some of the callers are written in assembler.
    I would probably screw up changing the assembly code. To avoid breaking code
    do_pipe is now a small wrapper around do_pipe_flags. Once all callers are
    changed over to do_pipe_flags the old do_pipe function can be removed.

    The following test must be adjusted for architectures other than x86 and
    x86-64 and in case the syscall numbers changed.

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    #include
    #include
    #include
    #include

    #ifndef __NR_pipe2
    # ifdef __x86_64__
    # define __NR_pipe2 293
    # elif defined __i386__
    # define __NR_pipe2 331
    # else
    # error "need __NR_pipe2"
    # endif
    #endif

    int
    main (void)
    {
    int fd[2];
    if (syscall (__NR_pipe2, fd, 0) != 0)
    {
    puts ("pipe2(0) failed");
    return 1;
    }
    for (int i = 0; i < 2; ++i)
    {
    int coe = fcntl (fd[i], F_GETFD);
    if (coe == -1)
    {
    puts ("fcntl failed");
    return 1;
    }
    if (coe & FD_CLOEXEC)
    {
    printf ("pipe2(0) set close-on-exit for fd[%d]\n", i);
    return 1;
    }
    }
    close (fd[0]);
    close (fd[1]);

    if (syscall (__NR_pipe2, fd, O_CLOEXEC) != 0)
    {
    puts ("pipe2(O_CLOEXEC) failed");
    return 1;
    }
    for (int i = 0; i < 2; ++i)
    {
    int coe = fcntl (fd[i], F_GETFD);
    if (coe == -1)
    {
    puts ("fcntl failed");
    return 1;
    }
    if ((coe & FD_CLOEXEC) == 0)
    {
    printf ("pipe2(O_CLOEXEC) does not set close-on-exit for fd[%d]\n", i);
    return 1;
    }
    }
    close (fd[0]);
    close (fd[1]);

    puts ("OK");

    return 0;
    }
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Signed-off-by: Ulrich Drepper
    Acked-by: Davide Libenzi
    Cc: Michael Kerrisk
    Cc:
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Ulrich Drepper
     

23 Jun, 2008

1 commit


09 May, 2008

1 commit


04 May, 2008

1 commit

  • This replaces the duplicated arch-specific versions of "sys_pipe()" with
    one unified implementation. This removes almost 250 lines of duplicated
    code.

    It's marked __weak, so that *if* an architecture wants to override the
    default implementation it can do so by simply having its own replacement
    version, since many architectures use alternate calling conventions for
    the 'pipe()' system call for legacy reasons (ie traditional UNIX
    implementations often return the two file descriptors in registers)

    I still haven't changed the cris version even though Linus says the BKL
    isn't needed. The arch maintainer can easily do it if there are really
    no obstacles.

    Signed-off-by: Ulrich Drepper
    Signed-off-by: Linus Torvalds

    Ulrich Drepper
     

23 Apr, 2008

1 commit


19 Mar, 2008

1 commit

  • Some new uses of get_empty_filp() have crept in; switched
    to alloc_file() to make sure that pieces of initialization
    won't be missing.

    We really need to kill get_empty_filp().

    [AV] fixed dentry leak on failure exit in anon_inode_getfd()

    Cc: Erez Zadok
    Cc: Trond Myklebust
    Cc: "J Bruce Fields"
    Acked-by: Al Viro
    Signed-off-by: Christoph Hellwig
    Signed-off-by: Andrew Morton
    Signed-off-by: Dave Hansen
    Signed-off-by: Al Viro

    Dave Hansen
     

14 Feb, 2008

1 commit


09 Feb, 2008

1 commit


15 Oct, 2007

2 commits


27 Jul, 2007

1 commit


10 Jul, 2007

2 commits


09 May, 2007

1 commit

  • 1) Introduces a new method in 'struct dentry_operations'. This method
    called d_dname() might be called from d_path() to build a pathname for
    special filesystems. It is called without locks.

    Future patches (if we succeed in having one common dentry for all
    pipes/sockets) may need to change prototype of this method, but we now
    use : char *d_dname(struct dentry *dentry, char *buffer, int buflen);

    2) Adds a dynamic_dname() helper function that eases d_dname() implementations

    3) Defines d_dname method for sockets : No more sprintf() at socket
    creation. This is delayed up to the moment someone does an access to
    /proc/pid/fd/...

    4) Defines d_dname method for pipes : No more sprintf() at pipe
    creation. This is delayed up to the moment someone does an access to
    /proc/pid/fd/...

    A benchmark consisting of 1.000.000 calls to pipe()/close()/close() gives a
    *nice* speedup on my Pentium(M) 1.6 Ghz :

    3.090 s instead of 3.450 s

    Signed-off-by: Eric Dumazet
    Acked-by: Christoph Hellwig
    Acked-by: Linus Torvalds
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Eric Dumazet
     

18 Feb, 2007

1 commit

  • Provide an audit record of the descriptor pair returned by pipe() and
    socketpair(). Rewritten from the original posted to linux-audit by
    John D. Ramsdell

    Signed-off-by: Al Viro

    Al Viro
     

21 Dec, 2006

1 commit


14 Dec, 2006

1 commit

  • - pipe/splice should use const pipe_buf_operations and file_operations

    - struct pipe_inode_info has an unused field "start" : get rid of it.

    Signed-off-by: Eric Dumazet
    Cc: Jens Axboe
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Eric Dumazet
     

09 Dec, 2006

1 commit

  • This patch changes struct file to use struct path instead of having
    independent pointers to struct dentry and struct vfsmount, and converts all
    users of f_{dentry,vfsmnt} in fs/ to use f_path.{dentry,mnt}.

    Additionally, it adds two #define's to make the transition easier for users of
    the f_dentry and f_vfsmnt.

    Signed-off-by: Josef "Jeff" Sipek
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Josef "Jeff" Sipek
     

08 Dec, 2006

1 commit

  • We currently insert pipe dentries into the global dentry hashtable. This
    is suboptimal because there is currently no way these entries can be used
    for a lookup(). (/proc/xxx/fd/xxx uses a different mechanism). Inserting
    them in dentry hashtable slows dcache lookups.

    To let __dpath() still work correctly (ie not adding a " (deleted)") after
    dentry name, we do :

    - Right after d_alloc(), pretend they are hashed by clearing the
    DCACHE_UNHASHED bit.

    - Call d_instantiate() instead of d_add() : dentry is not inserted in
    hash table.

    __dpath() & friends work as intended during dentry lifetime.

    - At dismantle time, once dput() must clear the dentry, setting again
    DCACHE_UNHASHED bit inside the custom d_delete() function provided by
    pipe code, so that dput() can just kill_it.

    This patch, combined with (avoid RCU for never hashed dentries) reduced
    time of { pipe(p); close(p[0]); close(p[1]);} on my UP machine (1.6GHz
    Pentium-M) from 3.23 us to 2.86 us (But this patch does not depend on other
    patches, only bench results)

    Signed-off-by: Eric Dumazet
    Acked-by: David Miller
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Eric Dumazet
     

01 Oct, 2006

2 commits

  • Split the big and hard to read do_pipe function into smaller pieces.

    This creates new create_write_pipe/free_write_pipe/create_read_pipe
    functions. These functions are made global so that they can be used by
    other parts of the kernel.

    The resulting code is more generic and easier to read and has cleaner error
    handling and less gotos.

    [akpm@osdl.org: cleanup]
    Signed-off-by: Andi Kleen
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Andi Kleen
     
  • This patch removes readv() and writev() methods and replaces them with
    aio_read()/aio_write() methods.

    Signed-off-by: Badari Pulavarty
    Signed-off-by: Christoph Hellwig
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Badari Pulavarty
     

27 Sep, 2006

1 commit

  • This eliminates the i_blksize field from struct inode. Filesystems that want
    to provide a per-inode st_blksize can do so by providing their own getattr
    routine instead of using the generic_fillattr() function.

    Note that some filesystems were providing pretty much random (and incorrect)
    values for i_blksize.

    [bunk@stusta.de: cleanup]
    [akpm@osdl.org: generic_fillattr() fix]
    Signed-off-by: "Theodore Ts'o"
    Signed-off-by: Adrian Bunk
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Theodore Ts'o
     

23 Jun, 2006

1 commit

  • Extend the get_sb() filesystem operation to take an extra argument that
    permits the VFS to pass in the target vfsmount that defines the mountpoint.

    The filesystem is then required to manually set the superblock and root dentry
    pointers. For most filesystems, this should be done with simple_set_mnt()
    which will set the superblock pointer and then set the root dentry to the
    superblock's s_root (as per the old default behaviour).

    The get_sb() op now returns an integer as there's now no need to return the
    superblock pointer.

    This patch permits a superblock to be implicitly shared amongst several mount
    points, such as can be done with NFS to avoid potential inode aliasing. In
    such a case, simple_set_mnt() would not be called, and instead the mnt_root
    and mnt_sb would be set directly.

    The patch also makes the following changes:

    (*) the get_sb_*() convenience functions in the core kernel now take a vfsmount
    pointer argument and return an integer, so most filesystems have to change
    very little.

    (*) If one of the convenience function is not used, then get_sb() should
    normally call simple_set_mnt() to instantiate the vfsmount. This will
    always return 0, and so can be tail-called from get_sb().

    (*) generic_shutdown_super() now calls shrink_dcache_sb() to clean up the
    dcache upon superblock destruction rather than shrink_dcache_anon().

    This is required because the superblock may now have multiple trees that
    aren't actually bound to s_root, but that still need to be cleaned up. The
    currently called functions assume that the whole tree is rooted at s_root,
    and that anonymous dentries are not the roots of trees which results in
    dentries being left unculled.

    However, with the way NFS superblock sharing are currently set to be
    implemented, these assumptions are violated: the root of the filesystem is
    simply a dummy dentry and inode (the real inode for '/' may well be
    inaccessible), and all the vfsmounts are rooted on anonymous[*] dentries
    with child trees.

    [*] Anonymous until discovered from another tree.

    (*) The documentation has been adjusted, including the additional bit of
    changing ext2_* into foo_* in the documentation.

    [akpm@osdl.org: convert ipath_fs, do other stuff]
    Signed-off-by: David Howells
    Acked-by: Al Viro
    Cc: Nathan Scott
    Cc: Roland Dreier
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    David Howells