diff options
author | Chris Metcalf <cmetcalf@tilera.com> | 2010-07-06 13:45:24 -0400 |
---|---|---|
committer | Chris Metcalf <cmetcalf@tilera.com> | 2010-07-06 13:45:24 -0400 |
commit | a2262d8a231e92742651859a10c9a4430a5e899a (patch) | |
tree | b5a823e3f6a3f60e1dd995f113caf0b350228d84 /fs/cifs/dir.c | |
parent | ef06f55a5c936a395f3ee2e1237bbebdb4396c65 (diff) | |
parent | 815c4163b6c8ebf8152f42b0a5fd015cfdcedc78 (diff) |
Merge branch 'master' into for-linus
Diffstat (limited to 'fs/cifs/dir.c')
-rw-r--r-- | fs/cifs/dir.c | 76 |
1 files changed, 44 insertions, 32 deletions
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 391816b461ca..e7ae78b66fa1 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/namei.h> | 26 | #include <linux/namei.h> |
27 | #include <linux/mount.h> | 27 | #include <linux/mount.h> |
28 | #include <linux/file.h> | ||
28 | #include "cifsfs.h" | 29 | #include "cifsfs.h" |
29 | #include "cifspdu.h" | 30 | #include "cifspdu.h" |
30 | #include "cifsglob.h" | 31 | #include "cifsglob.h" |
@@ -184,12 +185,13 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, | |||
184 | } | 185 | } |
185 | write_unlock(&GlobalSMBSeslock); | 186 | write_unlock(&GlobalSMBSeslock); |
186 | 187 | ||
188 | file->private_data = pCifsFile; | ||
189 | |||
187 | return pCifsFile; | 190 | return pCifsFile; |
188 | } | 191 | } |
189 | 192 | ||
190 | int cifs_posix_open(char *full_path, struct inode **pinode, | 193 | int cifs_posix_open(char *full_path, struct inode **pinode, |
191 | struct vfsmount *mnt, struct super_block *sb, | 194 | struct super_block *sb, int mode, int oflags, |
192 | int mode, int oflags, | ||
193 | __u32 *poplock, __u16 *pnetfid, int xid) | 195 | __u32 *poplock, __u16 *pnetfid, int xid) |
194 | { | 196 | { |
195 | int rc; | 197 | int rc; |
@@ -258,19 +260,6 @@ int cifs_posix_open(char *full_path, struct inode **pinode, | |||
258 | cifs_fattr_to_inode(*pinode, &fattr); | 260 | cifs_fattr_to_inode(*pinode, &fattr); |
259 | } | 261 | } |
260 | 262 | ||
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: | 263 | posix_open_ret: |
275 | kfree(presp_data); | 264 | kfree(presp_data); |
276 | return rc; | 265 | return rc; |
@@ -298,7 +287,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
298 | int create_options = CREATE_NOT_DIR; | 287 | int create_options = CREATE_NOT_DIR; |
299 | __u32 oplock = 0; | 288 | __u32 oplock = 0; |
300 | int oflags; | 289 | int oflags; |
301 | bool posix_create = false; | ||
302 | /* | 290 | /* |
303 | * BB below access is probably too much for mknod to request | 291 | * BB below access is probably too much for mknod to request |
304 | * but we have to do query and setpathinfo so requesting | 292 | * but we have to do query and setpathinfo so requesting |
@@ -339,7 +327,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
339 | (CIFS_UNIX_POSIX_PATH_OPS_CAP & | 327 | (CIFS_UNIX_POSIX_PATH_OPS_CAP & |
340 | le64_to_cpu(tcon->fsUnixInfo.Capability))) { | 328 | le64_to_cpu(tcon->fsUnixInfo.Capability))) { |
341 | rc = cifs_posix_open(full_path, &newinode, | 329 | rc = cifs_posix_open(full_path, &newinode, |
342 | nd ? nd->path.mnt : NULL, | ||
343 | inode->i_sb, mode, oflags, &oplock, &fileHandle, xid); | 330 | inode->i_sb, mode, oflags, &oplock, &fileHandle, xid); |
344 | /* EIO could indicate that (posix open) operation is not | 331 | /* EIO could indicate that (posix open) operation is not |
345 | supported, despite what server claimed in capability | 332 | supported, despite what server claimed in capability |
@@ -347,7 +334,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
347 | handled in posix open */ | 334 | handled in posix open */ |
348 | 335 | ||
349 | if (rc == 0) { | 336 | if (rc == 0) { |
350 | posix_create = true; | ||
351 | if (newinode == NULL) /* query inode info */ | 337 | if (newinode == NULL) /* query inode info */ |
352 | goto cifs_create_get_file_info; | 338 | goto cifs_create_get_file_info; |
353 | else /* success, no need to query */ | 339 | else /* success, no need to query */ |
@@ -478,21 +464,28 @@ cifs_create_set_dentry: | |||
478 | else | 464 | else |
479 | cFYI(1, "Create worked, get_inode_info failed rc = %d", rc); | 465 | cFYI(1, "Create worked, get_inode_info failed rc = %d", rc); |
480 | 466 | ||
481 | /* nfsd case - nfs srv does not set nd */ | 467 | 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; | 468 | struct cifsFileInfo *pfile_info; |
487 | /* | 469 | struct file *filp; |
488 | * cifs_fill_filedata() takes care of setting cifsFileInfo | 470 | |
489 | * pointer to file->private_data. | 471 | filp = lookup_instantiate_filp(nd, direntry, generic_file_open); |
490 | */ | 472 | if (IS_ERR(filp)) { |
491 | pfile_info = cifs_new_fileinfo(newinode, fileHandle, NULL, | 473 | rc = PTR_ERR(filp); |
474 | CIFSSMBClose(xid, tcon, fileHandle); | ||
475 | goto cifs_create_out; | ||
476 | } | ||
477 | |||
478 | pfile_info = cifs_new_fileinfo(newinode, fileHandle, filp, | ||
492 | nd->path.mnt, oflags); | 479 | nd->path.mnt, oflags); |
493 | if (pfile_info == NULL) | 480 | if (pfile_info == NULL) { |
481 | fput(filp); | ||
482 | CIFSSMBClose(xid, tcon, fileHandle); | ||
494 | rc = -ENOMEM; | 483 | rc = -ENOMEM; |
484 | } | ||
485 | } else { | ||
486 | CIFSSMBClose(xid, tcon, fileHandle); | ||
495 | } | 487 | } |
488 | |||
496 | cifs_create_out: | 489 | cifs_create_out: |
497 | kfree(buf); | 490 | kfree(buf); |
498 | kfree(full_path); | 491 | kfree(full_path); |
@@ -636,6 +629,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
636 | bool posix_open = false; | 629 | bool posix_open = false; |
637 | struct cifs_sb_info *cifs_sb; | 630 | struct cifs_sb_info *cifs_sb; |
638 | struct cifsTconInfo *pTcon; | 631 | struct cifsTconInfo *pTcon; |
632 | struct cifsFileInfo *cfile; | ||
639 | struct inode *newInode = NULL; | 633 | struct inode *newInode = NULL; |
640 | char *full_path = NULL; | 634 | char *full_path = NULL; |
641 | struct file *filp; | 635 | struct file *filp; |
@@ -703,7 +697,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
703 | if (nd && !(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) && | 697 | if (nd && !(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) && |
704 | (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open && | 698 | (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open && |
705 | (nd->intent.open.flags & O_CREAT)) { | 699 | (nd->intent.open.flags & O_CREAT)) { |
706 | rc = cifs_posix_open(full_path, &newInode, nd->path.mnt, | 700 | rc = cifs_posix_open(full_path, &newInode, |
707 | parent_dir_inode->i_sb, | 701 | parent_dir_inode->i_sb, |
708 | nd->intent.open.create_mode, | 702 | nd->intent.open.create_mode, |
709 | nd->intent.open.flags, &oplock, | 703 | nd->intent.open.flags, &oplock, |
@@ -733,8 +727,25 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
733 | else | 727 | else |
734 | direntry->d_op = &cifs_dentry_ops; | 728 | direntry->d_op = &cifs_dentry_ops; |
735 | d_add(direntry, newInode); | 729 | d_add(direntry, newInode); |
736 | if (posix_open) | 730 | if (posix_open) { |
737 | filp = lookup_instantiate_filp(nd, direntry, NULL); | 731 | filp = lookup_instantiate_filp(nd, direntry, |
732 | generic_file_open); | ||
733 | if (IS_ERR(filp)) { | ||
734 | rc = PTR_ERR(filp); | ||
735 | CIFSSMBClose(xid, pTcon, fileHandle); | ||
736 | goto lookup_out; | ||
737 | } | ||
738 | |||
739 | cfile = cifs_new_fileinfo(newInode, fileHandle, filp, | ||
740 | nd->path.mnt, | ||
741 | nd->intent.open.flags); | ||
742 | if (cfile == NULL) { | ||
743 | fput(filp); | ||
744 | CIFSSMBClose(xid, pTcon, fileHandle); | ||
745 | rc = -ENOMEM; | ||
746 | goto lookup_out; | ||
747 | } | ||
748 | } | ||
738 | /* since paths are not looked up by component - the parent | 749 | /* since paths are not looked up by component - the parent |
739 | directories are presumed to be good here */ | 750 | directories are presumed to be good here */ |
740 | renew_parental_timestamps(direntry); | 751 | renew_parental_timestamps(direntry); |
@@ -755,6 +766,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
755 | is a common return code */ | 766 | is a common return code */ |
756 | } | 767 | } |
757 | 768 | ||
769 | lookup_out: | ||
758 | kfree(full_path); | 770 | kfree(full_path); |
759 | FreeXid(xid); | 771 | FreeXid(xid); |
760 | return ERR_PTR(rc); | 772 | return ERR_PTR(rc); |