lkml.org 
[lkml]   [2012]   [Aug]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[ 071/122] cifs: ensure that we always do cifsFileInfo_get under the spinlock
    Date
    From: Greg KH <gregkh@linuxfoundation.org>

    3.5-stable review patch. If anyone has any objections, please let me know.

    ------------------

    From: Jeff Layton <jlayton@redhat.com>

    commit 764a1b1acecedfe204cb2e80d8e2cc7c6df1b0b8 upstream.

    The readpages bug is a regression that was introduced in 6993f74a5.
    This also fixes a couple of similar bugs in the uncached read and write
    codepaths.

    Also, prevent this sort of thing in the future by having cifsFileInfo_get
    take the spinlock itself, and adding a _locked variant for use in places
    that are already holding the lock. The _put code has always done that
    so this makes for a less confusing interface.

    Reviewed-by: Pavel Shilovsky <pshilovsky@samba.org>
    Signed-off-by: Jeff Layton <jlayton@redhat.com>
    Signed-off-by: Steve French <smfrench@gmail.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    fs/cifs/cifsglob.h | 6 +++---
    fs/cifs/file.c | 17 ++++++++++++-----
    2 files changed, 15 insertions(+), 8 deletions(-)

    --- a/fs/cifs/cifsglob.h
    +++ b/fs/cifs/cifsglob.h
    @@ -657,13 +657,13 @@ struct cifs_io_parms {
    * Take a reference on the file private data. Must be called with
    * cifs_file_list_lock held.
    */
    -static inline
    -struct cifsFileInfo *cifsFileInfo_get(struct cifsFileInfo *cifs_file)
    +static inline void
    +cifsFileInfo_get_locked(struct cifsFileInfo *cifs_file)
    {
    ++cifs_file->count;
    - return cifs_file;
    }

    +struct cifsFileInfo *cifsFileInfo_get(struct cifsFileInfo *cifs_file);
    void cifsFileInfo_put(struct cifsFileInfo *cifs_file);

    /*
    --- a/fs/cifs/file.c
    +++ b/fs/cifs/file.c
    @@ -284,6 +284,15 @@ cifs_new_fileinfo(__u16 fileHandle, stru

    static void cifs_del_lock_waiters(struct cifsLockInfo *lock);

    +struct cifsFileInfo *
    +cifsFileInfo_get(struct cifsFileInfo *cifs_file)
    +{
    + spin_lock(&cifs_file_list_lock);
    + cifsFileInfo_get_locked(cifs_file);
    + spin_unlock(&cifs_file_list_lock);
    + return cifs_file;
    +}
    +
    /*
    * Release a reference on the file private data. This may involve closing
    * the filehandle out on the server. Must be called without holding
    @@ -1563,7 +1572,7 @@ struct cifsFileInfo *find_readable_file(
    if (!open_file->invalidHandle) {
    /* found a good file */
    /* lock it so it will not be closed on us */
    - cifsFileInfo_get(open_file);
    + cifsFileInfo_get_locked(open_file);
    spin_unlock(&cifs_file_list_lock);
    return open_file;
    } /* else might as well continue, and look for
    @@ -1615,7 +1624,7 @@ refind_writable:
    if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) {
    if (!open_file->invalidHandle) {
    /* found a good writable file */
    - cifsFileInfo_get(open_file);
    + cifsFileInfo_get_locked(open_file);
    spin_unlock(&cifs_file_list_lock);
    return open_file;
    } else {
    @@ -1632,7 +1641,7 @@ refind_writable:

    if (inv_file) {
    any_available = false;
    - cifsFileInfo_get(inv_file);
    + cifsFileInfo_get_locked(inv_file);
    }

    spin_unlock(&cifs_file_list_lock);
    @@ -3082,8 +3091,6 @@ static int cifs_readpages(struct file *f
    break;
    }

    - spin_lock(&cifs_file_list_lock);
    - spin_unlock(&cifs_file_list_lock);
    rdata->cfile = cifsFileInfo_get(open_file);
    rdata->mapping = mapping;
    rdata->offset = offset;



    \
     
     \ /
      Last update: 2012-08-08 01:01    [W:3.616 / U:0.524 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site