Re: [GIT] CIFS Fix
Luca Tettamanti <[email protected]>
| Newsgroups | gmane.linux.file-systems.cifs |
|---|---|
| Message-ID | <[email protected]> |
On Thu, May 21, 2009 at 04:01:15PM -0500, Steve French wrote: > Same thing but fixed the long line. > > Unless problems are found (I will continue to test, to supplement was > Shirish is doing), I can put this in my tree, ASAP I confirm that the patch fixes the bug. Tested-By: Luca Tettamanti <[email protected]> thanks, Luca > diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c > index 11431ed..f49d684 100644 > --- a/fs/cifs/dir.c > +++ b/fs/cifs/dir.c > @@ -225,6 +225,7 @@ int cifs_posix_open(char *full_path, struct inode **pinode, > if (!(oflags & FMODE_READ)) > write_only = true; > > + mode &= ~current_umask(); > rc = CIFSPOSIXCreate(xid, cifs_sb->tcon, posix_flags, mode, > pnetfid, presp_data, &oplock, full_path, > cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & > @@ -310,7 +311,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, > return -ENOMEM; > } > > - mode &= ~current_umask(); > if (oplockEnabled) > oplock = REQ_OPLOCK; > > @@ -336,7 +336,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, > else /* success, no need to query */ > goto cifs_create_set_dentry; > } else if ((rc != -EIO) && (rc != -EREMOTE) && > - (rc != -EOPNOTSUPP)) /* path not found or net err */ > + (rc != -EOPNOTSUPP) && (rc != -EINVAL)) > goto cifs_create_out; > /* else fallthrough to retry, using older open call, this is > case where server does not support this SMB level, and > @@ -609,7 +609,6 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, > int xid; > int rc = 0; /* to get around spurious gcc warning, set to zero here */ > int oplock = 0; > - int mode; > __u16 fileHandle = 0; > bool posix_open = false; > struct cifs_sb_info *cifs_sb; > @@ -660,13 +659,12 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, > > if (pTcon->unix_ext) { > if (!(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) && > - (nd->flags & LOOKUP_OPEN)) { > + (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open) { > if (!((nd->intent.open.flags & O_CREAT) && > (nd->intent.open.flags & O_EXCL))) { > - mode = nd->intent.open.create_mode & > - ~current_umask(); > rc = cifs_posix_open(full_path, &newInode, > - parent_dir_inode->i_sb, mode, > + parent_dir_inode->i_sb, > + nd->intent.open.create_mode, > nd->intent.open.flags, &oplock, > &fileHandle, xid); > /* > @@ -681,6 +679,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, > */ > if ((rc != -EINVAL) && (rc != -EOPNOTSUPP)) > posix_open = true; > + else > + pTcon->broken_posix_open = true; > } > } > if (!posix_open) > diff --git a/fs/cifs/file.c b/fs/cifs/file.c > index 38c06f8..302ea15 100644 > --- a/fs/cifs/file.c > +++ b/fs/cifs/file.c > @@ -130,10 +130,6 @@ static inline int cifs_posix_open_inode_helper(struct inode *inode, > struct cifsFileInfo *pCifsFile, int oplock, u16 netfid) > { > > - file->private_data = kmalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); > - if (file->private_data == NULL) > - return -ENOMEM; > - pCifsFile = cifs_init_private(file->private_data, inode, file, netfid); > write_lock(&GlobalSMBSeslock); > > pCifsInode = CIFS_I(file->f_path.dentry->d_inode); > @@ -184,6 +180,38 @@ psx_client_can_cache: > return 0; > } > > +static struct cifsFileInfo * > +cifs_fill_filedata(struct file *file) > +{ > + struct list_head *tmp; > + struct cifsFileInfo *pCifsFile = NULL; > + struct cifsInodeInfo *pCifsInode = NULL; > + > + /* search inode for this file and fill in file->private_data */ > + pCifsInode = CIFS_I(file->f_path.dentry->d_inode); > + read_lock(&GlobalSMBSeslock); > + list_for_each(tmp, &pCifsInode->openFileList) { > + pCifsFile = list_entry(tmp, struct cifsFileInfo, flist); > + if ((pCifsFile->pfile == NULL) && > + (pCifsFile->pid == current->tgid)) { > + /* mode set in cifs_create */ > + > + /* needed for writepage */ > + pCifsFile->pfile = file; > + file->private_data = pCifsFile; > + break; > + } > + } > + read_unlock(&GlobalSMBSeslock); > + > + if (file->private_data != NULL) { > + return pCifsFile; > + } else if ((file->f_flags & O_CREAT) && (file->f_flags & O_EXCL)) > + cERROR(1, ("could not find file instance for " > + "new file %p", file)); > + return NULL; > +} > + > /* all arguments to this function must be checked for validity in caller */ > static inline int cifs_open_inode_helper(struct inode *inode, struct file *file, > struct cifsInodeInfo *pCifsInode, struct cifsFileInfo *pCifsFile, > @@ -258,7 +286,6 @@ int cifs_open(struct inode *inode, struct file *file) > struct cifsTconInfo *tcon; > struct cifsFileInfo *pCifsFile; > struct cifsInodeInfo *pCifsInode; > - struct list_head *tmp; > char *full_path = NULL; > int desiredAccess; > int disposition; > @@ -270,32 +297,12 @@ int cifs_open(struct inode *inode, struct file *file) > cifs_sb = CIFS_SB(inode->i_sb); > tcon = cifs_sb->tcon; > > - /* search inode for this file and fill in file->private_data */ > pCifsInode = CIFS_I(file->f_path.dentry->d_inode); > - read_lock(&GlobalSMBSeslock); > - list_for_each(tmp, &pCifsInode->openFileList) { > - pCifsFile = list_entry(tmp, struct cifsFileInfo, > - flist); > - if ((pCifsFile->pfile == NULL) && > - (pCifsFile->pid == current->tgid)) { > - /* mode set in cifs_create */ > - > - /* needed for writepage */ > - pCifsFile->pfile = file; > - > - file->private_data = pCifsFile; > - break; > - } > - } > - read_unlock(&GlobalSMBSeslock); > - > - if (file->private_data != NULL) { > - rc = 0; > + pCifsFile = cifs_fill_filedata(file); > + if (pCifsFile) { > FreeXid(xid); > - return rc; > - } else if ((file->f_flags & O_CREAT) && (file->f_flags & O_EXCL)) > - cERROR(1, ("could not find file instance for " > - "new file %p", file)); > + return 0; > + } > > full_path = build_path_from_dentry(file->f_path.dentry); > if (full_path == NULL) { > @@ -325,6 +332,7 @@ int cifs_open(struct inode *inode, struct file *file) > /* no need for special case handling of setting mode > on read only files needed here */ > > + pCifsFile = cifs_fill_filedata(file); > cifs_posix_open_inode_helper(inode, file, pCifsInode, > pCifsFile, oplock, netfid); > goto out;