diff options
-rw-r--r-- | fs/cifs/cifsproto.h | 1 | ||||
-rw-r--r-- | fs/cifs/dir.c | 43 | ||||
-rw-r--r-- | fs/cifs/file.c | 17 |
3 files changed, 30 insertions, 31 deletions
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index fb1657e0fdb8..fb6318b81509 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -106,7 +106,6 @@ extern struct cifsFileInfo *cifs_new_fileinfo(struct inode *newinode, | |||
106 | __u16 fileHandle, struct file *file, | 106 | __u16 fileHandle, struct file *file, |
107 | struct vfsmount *mnt, unsigned int oflags); | 107 | struct vfsmount *mnt, unsigned int oflags); |
108 | extern int cifs_posix_open(char *full_path, struct inode **pinode, | 108 | extern int cifs_posix_open(char *full_path, struct inode **pinode, |
109 | struct vfsmount *mnt, | ||
110 | struct super_block *sb, | 109 | struct super_block *sb, |
111 | int mode, int oflags, | 110 | int mode, int oflags, |
112 | __u32 *poplock, __u16 *pnetfid, int xid); | 111 | __u32 *poplock, __u16 *pnetfid, int xid); |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 391816b461ca..f49afb9980e7 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -188,8 +188,7 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, | |||
188 | } | 188 | } |
189 | 189 | ||
190 | int cifs_posix_open(char *full_path, struct inode **pinode, | 190 | int cifs_posix_open(char *full_path, struct inode **pinode, |
191 | struct vfsmount *mnt, struct super_block *sb, | 191 | struct super_block *sb, int mode, int oflags, |
192 | int mode, int oflags, | ||
193 | __u32 *poplock, __u16 *pnetfid, int xid) | 192 | __u32 *poplock, __u16 *pnetfid, int xid) |
194 | { | 193 | { |
195 | int rc; | 194 | int rc; |
@@ -258,19 +257,6 @@ int cifs_posix_open(char *full_path, struct inode **pinode, | |||
258 | cifs_fattr_to_inode(*pinode, &fattr); | 257 | cifs_fattr_to_inode(*pinode, &fattr); |
259 | } | 258 | } |
260 | 259 | ||
261 | /* | ||
262 | * cifs_fill_filedata() takes care of setting cifsFileInfo pointer to | ||
263 | * file->private_data. | ||
264 | */ | ||
265 | if (mnt) { | ||
266 | struct cifsFileInfo *pfile_info; | ||
267 | |||
268 | pfile_info = cifs_new_fileinfo(*pinode, *pnetfid, NULL, mnt, | ||
269 | oflags); | ||
270 | if (pfile_info == NULL) | ||
271 | rc = -ENOMEM; | ||
272 | } | ||
273 | |||
274 | posix_open_ret: | 260 | posix_open_ret: |
275 | kfree(presp_data); | 261 | kfree(presp_data); |
276 | return rc; | 262 | return rc; |
@@ -298,7 +284,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
298 | int create_options = CREATE_NOT_DIR; | 284 | int create_options = CREATE_NOT_DIR; |
299 | __u32 oplock = 0; | 285 | __u32 oplock = 0; |
300 | int oflags; | 286 | int oflags; |
301 | bool posix_create = false; | ||
302 | /* | 287 | /* |
303 | * BB below access is probably too much for mknod to request | 288 | * BB below access is probably too much for mknod to request |
304 | * but we have to do query and setpathinfo so requesting | 289 | * but we have to do query and setpathinfo so requesting |
@@ -339,7 +324,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
339 | (CIFS_UNIX_POSIX_PATH_OPS_CAP & | 324 | (CIFS_UNIX_POSIX_PATH_OPS_CAP & |
340 | le64_to_cpu(tcon->fsUnixInfo.Capability))) { | 325 | le64_to_cpu(tcon->fsUnixInfo.Capability))) { |
341 | rc = cifs_posix_open(full_path, &newinode, | 326 | rc = cifs_posix_open(full_path, &newinode, |
342 | nd ? nd->path.mnt : NULL, | ||
343 | inode->i_sb, mode, oflags, &oplock, &fileHandle, xid); | 327 | inode->i_sb, mode, oflags, &oplock, &fileHandle, xid); |
344 | /* EIO could indicate that (posix open) operation is not | 328 | /* EIO could indicate that (posix open) operation is not |
345 | supported, despite what server claimed in capability | 329 | supported, despite what server claimed in capability |
@@ -347,7 +331,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
347 | handled in posix open */ | 331 | handled in posix open */ |
348 | 332 | ||
349 | if (rc == 0) { | 333 | if (rc == 0) { |
350 | posix_create = true; | ||
351 | if (newinode == NULL) /* query inode info */ | 334 | if (newinode == NULL) /* query inode info */ |
352 | goto cifs_create_get_file_info; | 335 | goto cifs_create_get_file_info; |
353 | else /* success, no need to query */ | 336 | else /* success, no need to query */ |
@@ -478,11 +461,7 @@ cifs_create_set_dentry: | |||
478 | else | 461 | else |
479 | cFYI(1, "Create worked, get_inode_info failed rc = %d", rc); | 462 | cFYI(1, "Create worked, get_inode_info failed rc = %d", rc); |
480 | 463 | ||
481 | /* nfsd case - nfs srv does not set nd */ | 464 | if (newinode && nd && (nd->flags & LOOKUP_OPEN)) { |
482 | if ((nd == NULL) || (!(nd->flags & LOOKUP_OPEN))) { | ||
483 | /* mknod case - do not leave file open */ | ||
484 | CIFSSMBClose(xid, tcon, fileHandle); | ||
485 | } else if (!(posix_create) && (newinode)) { | ||
486 | struct cifsFileInfo *pfile_info; | 465 | struct cifsFileInfo *pfile_info; |
487 | /* | 466 | /* |
488 | * cifs_fill_filedata() takes care of setting cifsFileInfo | 467 | * cifs_fill_filedata() takes care of setting cifsFileInfo |
@@ -492,7 +471,10 @@ cifs_create_set_dentry: | |||
492 | nd->path.mnt, oflags); | 471 | nd->path.mnt, oflags); |
493 | if (pfile_info == NULL) | 472 | if (pfile_info == NULL) |
494 | rc = -ENOMEM; | 473 | rc = -ENOMEM; |
474 | } else { | ||
475 | CIFSSMBClose(xid, tcon, fileHandle); | ||
495 | } | 476 | } |
477 | |||
496 | cifs_create_out: | 478 | cifs_create_out: |
497 | kfree(buf); | 479 | kfree(buf); |
498 | kfree(full_path); | 480 | kfree(full_path); |
@@ -636,6 +618,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
636 | bool posix_open = false; | 618 | bool posix_open = false; |
637 | struct cifs_sb_info *cifs_sb; | 619 | struct cifs_sb_info *cifs_sb; |
638 | struct cifsTconInfo *pTcon; | 620 | struct cifsTconInfo *pTcon; |
621 | struct cifsFileInfo *cfile; | ||
639 | struct inode *newInode = NULL; | 622 | struct inode *newInode = NULL; |
640 | char *full_path = NULL; | 623 | char *full_path = NULL; |
641 | struct file *filp; | 624 | struct file *filp; |
@@ -703,7 +686,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
703 | if (nd && !(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) && | 686 | if (nd && !(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) && |
704 | (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open && | 687 | (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open && |
705 | (nd->intent.open.flags & O_CREAT)) { | 688 | (nd->intent.open.flags & O_CREAT)) { |
706 | rc = cifs_posix_open(full_path, &newInode, nd->path.mnt, | 689 | rc = cifs_posix_open(full_path, &newInode, |
707 | parent_dir_inode->i_sb, | 690 | parent_dir_inode->i_sb, |
708 | nd->intent.open.create_mode, | 691 | nd->intent.open.create_mode, |
709 | nd->intent.open.flags, &oplock, | 692 | nd->intent.open.flags, &oplock, |
@@ -733,8 +716,17 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
733 | else | 716 | else |
734 | direntry->d_op = &cifs_dentry_ops; | 717 | direntry->d_op = &cifs_dentry_ops; |
735 | d_add(direntry, newInode); | 718 | d_add(direntry, newInode); |
736 | if (posix_open) | 719 | if (posix_open) { |
720 | cfile = cifs_new_fileinfo(newInode, fileHandle, NULL, | ||
721 | nd->path.mnt, | ||
722 | nd->intent.open.flags); | ||
723 | if (cfile == NULL) { | ||
724 | CIFSSMBClose(xid, pTcon, fileHandle); | ||
725 | rc = -ENOMEM; | ||
726 | goto lookup_out; | ||
727 | } | ||
737 | filp = lookup_instantiate_filp(nd, direntry, NULL); | 728 | filp = lookup_instantiate_filp(nd, direntry, NULL); |
729 | } | ||
738 | /* since paths are not looked up by component - the parent | 730 | /* since paths are not looked up by component - the parent |
739 | directories are presumed to be good here */ | 731 | directories are presumed to be good here */ |
740 | renew_parental_timestamps(direntry); | 732 | renew_parental_timestamps(direntry); |
@@ -755,6 +747,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
755 | is a common return code */ | 747 | is a common return code */ |
756 | } | 748 | } |
757 | 749 | ||
750 | lookup_out: | ||
758 | kfree(full_path); | 751 | kfree(full_path); |
759 | FreeXid(xid); | 752 | FreeXid(xid); |
760 | return ERR_PTR(rc); | 753 | return ERR_PTR(rc); |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 75541af4b3db..542e0c874d64 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -299,8 +299,7 @@ int cifs_open(struct inode *inode, struct file *file) | |||
299 | int oflags = (int) cifs_posix_convert_flags(file->f_flags); | 299 | int oflags = (int) cifs_posix_convert_flags(file->f_flags); |
300 | oflags |= SMB_O_CREAT; | 300 | oflags |= SMB_O_CREAT; |
301 | /* can not refresh inode info since size could be stale */ | 301 | /* can not refresh inode info since size could be stale */ |
302 | rc = cifs_posix_open(full_path, &inode, file->f_path.mnt, | 302 | rc = cifs_posix_open(full_path, &inode, inode->i_sb, |
303 | inode->i_sb, | ||
304 | cifs_sb->mnt_file_mode /* ignored */, | 303 | cifs_sb->mnt_file_mode /* ignored */, |
305 | oflags, &oplock, &netfid, xid); | 304 | oflags, &oplock, &netfid, xid); |
306 | if (rc == 0) { | 305 | if (rc == 0) { |
@@ -308,7 +307,16 @@ int cifs_open(struct inode *inode, struct file *file) | |||
308 | /* no need for special case handling of setting mode | 307 | /* no need for special case handling of setting mode |
309 | on read only files needed here */ | 308 | on read only files needed here */ |
310 | 309 | ||
311 | pCifsFile = cifs_fill_filedata(file); | 310 | pCifsFile = cifs_new_fileinfo(inode, netfid, file, |
311 | file->f_path.mnt, | ||
312 | oflags); | ||
313 | if (pCifsFile == NULL) { | ||
314 | CIFSSMBClose(xid, tcon, netfid); | ||
315 | rc = -ENOMEM; | ||
316 | goto out; | ||
317 | } | ||
318 | file->private_data = pCifsFile; | ||
319 | |||
312 | cifs_posix_open_inode_helper(inode, file, pCifsInode, | 320 | cifs_posix_open_inode_helper(inode, file, pCifsInode, |
313 | oplock, netfid); | 321 | oplock, netfid); |
314 | goto out; | 322 | goto out; |
@@ -513,8 +521,7 @@ reopen_error_exit: | |||
513 | le64_to_cpu(tcon->fsUnixInfo.Capability))) { | 521 | le64_to_cpu(tcon->fsUnixInfo.Capability))) { |
514 | int oflags = (int) cifs_posix_convert_flags(file->f_flags); | 522 | int oflags = (int) cifs_posix_convert_flags(file->f_flags); |
515 | /* can not refresh inode info since size could be stale */ | 523 | /* can not refresh inode info since size could be stale */ |
516 | rc = cifs_posix_open(full_path, NULL, file->f_path.mnt, | 524 | rc = cifs_posix_open(full_path, NULL, inode->i_sb, |
517 | inode->i_sb, | ||
518 | cifs_sb->mnt_file_mode /* ignored */, | 525 | cifs_sb->mnt_file_mode /* ignored */, |
519 | oflags, &oplock, &netfid, xid); | 526 | oflags, &oplock, &netfid, xid); |
520 | if (rc == 0) { | 527 | if (rc == 0) { |