lkml.org 
[lkml]   [2010]   [Jul]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[patch 123/149] CIFS: Allow null nd (as nfs server uses) on create
    2.6.32-stable review patch.  If anyone has any objections, please let us know.

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

    From: Steve French <sfrench@us.ibm.com>

    commit fa588e0c57048b3d4bfcd772d80dc0615f83fd35 upstream.

    While creating a file on a server which supports unix extensions
    such as Samba, if a file is being created which does not supply
    nameidata (i.e. nd is null), cifs client can oops when calling
    cifs_posix_open.

    Signed-off-by: Shirish Pargaonkar <shirishp@us.ibm.com>
    Signed-off-by: Steve French <sfrench@us.ibm.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    ---
    fs/cifs/cifsproto.h | 6 ++++--
    fs/cifs/dir.c | 20 ++++++++++++--------
    fs/cifs/file.c | 11 +++++++----
    3 files changed, 23 insertions(+), 14 deletions(-)

    --- a/fs/cifs/cifsproto.h
    +++ b/fs/cifs/cifsproto.h
    @@ -95,8 +95,10 @@ extern struct cifsFileInfo *cifs_new_fil
    __u16 fileHandle, struct file *file,
    struct vfsmount *mnt, unsigned int oflags);
    extern int cifs_posix_open(char *full_path, struct inode **pinode,
    - struct vfsmount *mnt, int mode, int oflags,
    - __u32 *poplock, __u16 *pnetfid, int xid);
    + struct vfsmount *mnt,
    + struct super_block *sb,
    + int mode, int oflags,
    + __u32 *poplock, __u16 *pnetfid, int xid);
    extern void cifs_unix_basic_to_fattr(struct cifs_fattr *fattr,
    FILE_UNIX_BASIC_INFO *info,
    struct cifs_sb_info *cifs_sb);
    --- a/fs/cifs/dir.c
    +++ b/fs/cifs/dir.c
    @@ -183,13 +183,14 @@ cifs_new_fileinfo(struct inode *newinode
    }

    int cifs_posix_open(char *full_path, struct inode **pinode,
    - struct vfsmount *mnt, int mode, int oflags,
    - __u32 *poplock, __u16 *pnetfid, int xid)
    + struct vfsmount *mnt, struct super_block *sb,
    + int mode, int oflags,
    + __u32 *poplock, __u16 *pnetfid, int xid)
    {
    int rc;
    FILE_UNIX_BASIC_INFO *presp_data;
    __u32 posix_flags = 0;
    - struct cifs_sb_info *cifs_sb = CIFS_SB(mnt->mnt_sb);
    + struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
    struct cifs_fattr fattr;

    cFYI(1, ("posix open %s", full_path));
    @@ -241,7 +242,7 @@ int cifs_posix_open(char *full_path, str

    /* get new inode and set it up */
    if (*pinode == NULL) {
    - *pinode = cifs_iget(mnt->mnt_sb, &fattr);
    + *pinode = cifs_iget(sb, &fattr);
    if (!*pinode) {
    rc = -ENOMEM;
    goto posix_open_ret;
    @@ -250,7 +251,8 @@ int cifs_posix_open(char *full_path, str
    cifs_fattr_to_inode(*pinode, &fattr);
    }

    - cifs_new_fileinfo(*pinode, *pnetfid, NULL, mnt, oflags);
    + if (mnt)
    + cifs_new_fileinfo(*pinode, *pnetfid, NULL, mnt, oflags);

    posix_open_ret:
    kfree(presp_data);
    @@ -314,13 +316,14 @@ cifs_create(struct inode *inode, struct
    if (nd && (nd->flags & LOOKUP_OPEN))
    oflags = nd->intent.open.flags;
    else
    - oflags = FMODE_READ;
    + oflags = FMODE_READ | SMB_O_CREAT;

    if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) &&
    (CIFS_UNIX_POSIX_PATH_OPS_CAP &
    le64_to_cpu(tcon->fsUnixInfo.Capability))) {
    - rc = cifs_posix_open(full_path, &newinode, nd->path.mnt,
    - mode, oflags, &oplock, &fileHandle, xid);
    + rc = cifs_posix_open(full_path, &newinode,
    + nd ? nd->path.mnt : NULL,
    + inode->i_sb, mode, oflags, &oplock, &fileHandle, xid);
    /* EIO could indicate that (posix open) operation is not
    supported, despite what server claimed in capability
    negotation. EREMOTE indicates DFS junction, which is not
    @@ -677,6 +680,7 @@ cifs_lookup(struct inode *parent_dir_ino
    (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open &&
    (nd->intent.open.flags & O_CREAT)) {
    rc = cifs_posix_open(full_path, &newInode, nd->path.mnt,
    + parent_dir_inode->i_sb,
    nd->intent.open.create_mode,
    nd->intent.open.flags, &oplock,
    &fileHandle, xid);
    --- a/fs/cifs/file.c
    +++ b/fs/cifs/file.c
    @@ -295,10 +295,12 @@ int cifs_open(struct inode *inode, struc
    (CIFS_UNIX_POSIX_PATH_OPS_CAP &
    le64_to_cpu(tcon->fsUnixInfo.Capability))) {
    int oflags = (int) cifs_posix_convert_flags(file->f_flags);
    + oflags |= SMB_O_CREAT;
    /* can not refresh inode info since size could be stale */
    rc = cifs_posix_open(full_path, &inode, file->f_path.mnt,
    - cifs_sb->mnt_file_mode /* ignored */,
    - oflags, &oplock, &netfid, xid);
    + inode->i_sb,
    + cifs_sb->mnt_file_mode /* ignored */,
    + oflags, &oplock, &netfid, xid);
    if (rc == 0) {
    cFYI(1, ("posix open succeeded"));
    /* no need for special case handling of setting mode
    @@ -510,8 +512,9 @@ reopen_error_exit:
    int oflags = (int) cifs_posix_convert_flags(file->f_flags);
    /* can not refresh inode info since size could be stale */
    rc = cifs_posix_open(full_path, NULL, file->f_path.mnt,
    - cifs_sb->mnt_file_mode /* ignored */,
    - oflags, &oplock, &netfid, xid);
    + inode->i_sb,
    + cifs_sb->mnt_file_mode /* ignored */,
    + oflags, &oplock, &netfid, xid);
    if (rc == 0) {
    cFYI(1, ("posix reopen succeeded"));
    goto reopen_success;



    \
     
     \ /
      Last update: 2010-07-01 20:47    [W:2.779 / U:0.324 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site