Commit a15ae93f authored by Linus Torvalds's avatar Linus Torvalds
parents afc27887 703a3b8e
...@@ -225,6 +225,7 @@ int cifs_posix_open(char *full_path, struct inode **pinode, ...@@ -225,6 +225,7 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
if (!(oflags & FMODE_READ)) if (!(oflags & FMODE_READ))
write_only = true; write_only = true;
mode &= ~current_umask();
rc = CIFSPOSIXCreate(xid, cifs_sb->tcon, posix_flags, mode, rc = CIFSPOSIXCreate(xid, cifs_sb->tcon, posix_flags, mode,
pnetfid, presp_data, &oplock, full_path, pnetfid, presp_data, &oplock, full_path,
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
...@@ -310,7 +311,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, ...@@ -310,7 +311,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
return -ENOMEM; return -ENOMEM;
} }
mode &= ~current_umask();
if (oplockEnabled) if (oplockEnabled)
oplock = REQ_OPLOCK; oplock = REQ_OPLOCK;
...@@ -336,7 +336,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, ...@@ -336,7 +336,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
else /* success, no need to query */ else /* success, no need to query */
goto cifs_create_set_dentry; goto cifs_create_set_dentry;
} else if ((rc != -EIO) && (rc != -EREMOTE) && } else if ((rc != -EIO) && (rc != -EREMOTE) &&
(rc != -EOPNOTSUPP)) /* path not found or net err */ (rc != -EOPNOTSUPP) && (rc != -EINVAL))
goto cifs_create_out; goto cifs_create_out;
/* else fallthrough to retry, using older open call, this is /* else fallthrough to retry, using older open call, this is
case where server does not support this SMB level, and case where server does not support this SMB level, and
...@@ -609,7 +609,6 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, ...@@ -609,7 +609,6 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
int xid; int xid;
int rc = 0; /* to get around spurious gcc warning, set to zero here */ int rc = 0; /* to get around spurious gcc warning, set to zero here */
int oplock = 0; int oplock = 0;
int mode;
__u16 fileHandle = 0; __u16 fileHandle = 0;
bool posix_open = false; bool posix_open = false;
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
...@@ -660,13 +659,12 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, ...@@ -660,13 +659,12 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
if (pTcon->unix_ext) { if (pTcon->unix_ext) {
if (!(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) && 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) && if (!((nd->intent.open.flags & O_CREAT) &&
(nd->intent.open.flags & O_EXCL))) { (nd->intent.open.flags & O_EXCL))) {
mode = nd->intent.open.create_mode &
~current_umask();
rc = cifs_posix_open(full_path, &newInode, 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, nd->intent.open.flags, &oplock,
&fileHandle, xid); &fileHandle, xid);
/* /*
...@@ -681,6 +679,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, ...@@ -681,6 +679,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
*/ */
if ((rc != -EINVAL) && (rc != -EOPNOTSUPP)) if ((rc != -EINVAL) && (rc != -EOPNOTSUPP))
posix_open = true; posix_open = true;
else
pTcon->broken_posix_open = true;
} }
} }
if (!posix_open) if (!posix_open)
......
...@@ -130,10 +130,6 @@ static inline int cifs_posix_open_inode_helper(struct inode *inode, ...@@ -130,10 +130,6 @@ static inline int cifs_posix_open_inode_helper(struct inode *inode,
struct cifsFileInfo *pCifsFile, int oplock, u16 netfid) 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); write_lock(&GlobalSMBSeslock);
pCifsInode = CIFS_I(file->f_path.dentry->d_inode); pCifsInode = CIFS_I(file->f_path.dentry->d_inode);
...@@ -184,6 +180,38 @@ static inline int cifs_posix_open_inode_helper(struct inode *inode, ...@@ -184,6 +180,38 @@ static inline int cifs_posix_open_inode_helper(struct inode *inode,
return 0; 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 */ /* 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, static inline int cifs_open_inode_helper(struct inode *inode, struct file *file,
struct cifsInodeInfo *pCifsInode, struct cifsFileInfo *pCifsFile, struct cifsInodeInfo *pCifsInode, struct cifsFileInfo *pCifsFile,
...@@ -258,7 +286,6 @@ int cifs_open(struct inode *inode, struct file *file) ...@@ -258,7 +286,6 @@ int cifs_open(struct inode *inode, struct file *file)
struct cifsTconInfo *tcon; struct cifsTconInfo *tcon;
struct cifsFileInfo *pCifsFile; struct cifsFileInfo *pCifsFile;
struct cifsInodeInfo *pCifsInode; struct cifsInodeInfo *pCifsInode;
struct list_head *tmp;
char *full_path = NULL; char *full_path = NULL;
int desiredAccess; int desiredAccess;
int disposition; int disposition;
...@@ -270,32 +297,12 @@ int cifs_open(struct inode *inode, struct file *file) ...@@ -270,32 +297,12 @@ int cifs_open(struct inode *inode, struct file *file)
cifs_sb = CIFS_SB(inode->i_sb); cifs_sb = CIFS_SB(inode->i_sb);
tcon = cifs_sb->tcon; tcon = cifs_sb->tcon;
/* search inode for this file and fill in file->private_data */
pCifsInode = CIFS_I(file->f_path.dentry->d_inode); pCifsInode = CIFS_I(file->f_path.dentry->d_inode);
read_lock(&GlobalSMBSeslock); pCifsFile = cifs_fill_filedata(file);
list_for_each(tmp, &pCifsInode->openFileList) { if (pCifsFile) {
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;
FreeXid(xid); FreeXid(xid);
return rc; return 0;
} else if ((file->f_flags & O_CREAT) && (file->f_flags & O_EXCL)) }
cERROR(1, ("could not find file instance for "
"new file %p", file));
full_path = build_path_from_dentry(file->f_path.dentry); full_path = build_path_from_dentry(file->f_path.dentry);
if (full_path == NULL) { if (full_path == NULL) {
...@@ -325,6 +332,7 @@ int cifs_open(struct inode *inode, struct file *file) ...@@ -325,6 +332,7 @@ int cifs_open(struct inode *inode, struct file *file)
/* no need for special case handling of setting mode /* no need for special case handling of setting mode
on read only files needed here */ on read only files needed here */
pCifsFile = cifs_fill_filedata(file);
cifs_posix_open_inode_helper(inode, file, pCifsInode, cifs_posix_open_inode_helper(inode, file, pCifsInode,
pCifsFile, oplock, netfid); pCifsFile, oplock, netfid);
goto out; goto out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment