aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/dir.c
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2010-04-22 15:21:55 -0400
committerSteve French <sfrench@us.ibm.com>2010-04-22 15:21:55 -0400
commitfa588e0c57048b3d4bfcd772d80dc0615f83fd35 (patch)
treea357298481dc4a8ab7f00998b065b9fee7e36d20 /fs/cifs/dir.c
parent2c964d1f7c87eb71f7902111cd7c8fbba225e4b6 (diff)
[CIFS] Allow null nd (as nfs server uses) on create
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>
Diffstat (limited to 'fs/cifs/dir.c')
-rw-r--r--fs/cifs/dir.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 4aa2fe3f535f..d791d0763a9c 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -182,13 +182,14 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle,
182} 182}
183 183
184int cifs_posix_open(char *full_path, struct inode **pinode, 184int cifs_posix_open(char *full_path, struct inode **pinode,
185 struct vfsmount *mnt, int mode, int oflags, 185 struct vfsmount *mnt, struct super_block *sb,
186 __u32 *poplock, __u16 *pnetfid, int xid) 186 int mode, int oflags,
187 __u32 *poplock, __u16 *pnetfid, int xid)
187{ 188{
188 int rc; 189 int rc;
189 FILE_UNIX_BASIC_INFO *presp_data; 190 FILE_UNIX_BASIC_INFO *presp_data;
190 __u32 posix_flags = 0; 191 __u32 posix_flags = 0;
191 struct cifs_sb_info *cifs_sb = CIFS_SB(mnt->mnt_sb); 192 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
192 struct cifs_fattr fattr; 193 struct cifs_fattr fattr;
193 194
194 cFYI(1, "posix open %s", full_path); 195 cFYI(1, "posix open %s", full_path);
@@ -241,7 +242,7 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
241 242
242 /* get new inode and set it up */ 243 /* get new inode and set it up */
243 if (*pinode == NULL) { 244 if (*pinode == NULL) {
244 *pinode = cifs_iget(mnt->mnt_sb, &fattr); 245 *pinode = cifs_iget(sb, &fattr);
245 if (!*pinode) { 246 if (!*pinode) {
246 rc = -ENOMEM; 247 rc = -ENOMEM;
247 goto posix_open_ret; 248 goto posix_open_ret;
@@ -250,7 +251,8 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
250 cifs_fattr_to_inode(*pinode, &fattr); 251 cifs_fattr_to_inode(*pinode, &fattr);
251 } 252 }
252 253
253 cifs_new_fileinfo(*pinode, *pnetfid, NULL, mnt, oflags); 254 if (mnt)
255 cifs_new_fileinfo(*pinode, *pnetfid, NULL, mnt, oflags);
254 256
255posix_open_ret: 257posix_open_ret:
256 kfree(presp_data); 258 kfree(presp_data);
@@ -314,13 +316,14 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
314 if (nd && (nd->flags & LOOKUP_OPEN)) 316 if (nd && (nd->flags & LOOKUP_OPEN))
315 oflags = nd->intent.open.flags; 317 oflags = nd->intent.open.flags;
316 else 318 else
317 oflags = FMODE_READ; 319 oflags = FMODE_READ | SMB_O_CREAT;
318 320
319 if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) && 321 if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) &&
320 (CIFS_UNIX_POSIX_PATH_OPS_CAP & 322 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
321 le64_to_cpu(tcon->fsUnixInfo.Capability))) { 323 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
322 rc = cifs_posix_open(full_path, &newinode, nd->path.mnt, 324 rc = cifs_posix_open(full_path, &newinode,
323 mode, oflags, &oplock, &fileHandle, xid); 325 nd ? nd->path.mnt : NULL,
326 inode->i_sb, mode, oflags, &oplock, &fileHandle, xid);
324 /* EIO could indicate that (posix open) operation is not 327 /* EIO could indicate that (posix open) operation is not
325 supported, despite what server claimed in capability 328 supported, despite what server claimed in capability
326 negotation. EREMOTE indicates DFS junction, which is not 329 negotation. EREMOTE indicates DFS junction, which is not
@@ -677,6 +680,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
677 (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open && 680 (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open &&
678 (nd->intent.open.flags & O_CREAT)) { 681 (nd->intent.open.flags & O_CREAT)) {
679 rc = cifs_posix_open(full_path, &newInode, nd->path.mnt, 682 rc = cifs_posix_open(full_path, &newInode, nd->path.mnt,
683 parent_dir_inode->i_sb,
680 nd->intent.open.create_mode, 684 nd->intent.open.create_mode,
681 nd->intent.open.flags, &oplock, 685 nd->intent.open.flags, &oplock,
682 &fileHandle, xid); 686 &fileHandle, xid);