[linux-cifs-client] Re: [GIT] CIFS Fix
Luca Tettamanti
kronos.it at gmail.com
Thu May 21 21:53:14 GMT 2009
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 <kronos.it at gmail.com>
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;
More information about the linux-cifs-client
mailing list