diff options
Diffstat (limited to 'fs/cifs/dir.c')
-rw-r--r-- | fs/cifs/dir.c | 65 |
1 files changed, 48 insertions, 17 deletions
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 23ec28a4c11f..bb3ea06ca6f4 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -137,7 +137,6 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, struct file *file, | |||
137 | { | 137 | { |
138 | struct cifsFileInfo *pCifsFile; | 138 | struct cifsFileInfo *pCifsFile; |
139 | struct cifsInodeInfo *pCifsInode; | 139 | struct cifsInodeInfo *pCifsInode; |
140 | struct cifs_sb_info *cifs_sb = CIFS_SB(mnt->mnt_sb); | ||
141 | 140 | ||
142 | pCifsFile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); | 141 | pCifsFile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); |
143 | if (pCifsFile == NULL) | 142 | if (pCifsFile == NULL) |
@@ -191,7 +190,8 @@ int cifs_posix_open(char *full_path, struct inode **pinode, | |||
191 | __u32 posix_flags = 0; | 190 | __u32 posix_flags = 0; |
192 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); | 191 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
193 | struct cifs_fattr fattr; | 192 | struct cifs_fattr fattr; |
194 | struct cifsTconInfo *tcon = cifs_sb_tcon(cifs_sb); | 193 | struct tcon_link *tlink; |
194 | struct cifsTconInfo *tcon; | ||
195 | 195 | ||
196 | cFYI(1, "posix open %s", full_path); | 196 | cFYI(1, "posix open %s", full_path); |
197 | 197 | ||
@@ -226,10 +226,20 @@ int cifs_posix_open(char *full_path, struct inode **pinode, | |||
226 | posix_flags |= SMB_O_DIRECT; | 226 | posix_flags |= SMB_O_DIRECT; |
227 | 227 | ||
228 | mode &= ~current_umask(); | 228 | mode &= ~current_umask(); |
229 | |||
230 | tlink = cifs_sb_tlink(cifs_sb); | ||
231 | if (IS_ERR(tlink)) { | ||
232 | rc = PTR_ERR(tlink); | ||
233 | goto posix_open_ret; | ||
234 | } | ||
235 | |||
236 | tcon = tlink_tcon(tlink); | ||
229 | rc = CIFSPOSIXCreate(xid, tcon, posix_flags, mode, pnetfid, presp_data, | 237 | rc = CIFSPOSIXCreate(xid, tcon, posix_flags, mode, pnetfid, presp_data, |
230 | poplock, full_path, cifs_sb->local_nls, | 238 | poplock, full_path, cifs_sb->local_nls, |
231 | cifs_sb->mnt_cifs_flags & | 239 | cifs_sb->mnt_cifs_flags & |
232 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 240 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
241 | cifs_put_tlink(tlink); | ||
242 | |||
233 | if (rc) | 243 | if (rc) |
234 | goto posix_open_ret; | 244 | goto posix_open_ret; |
235 | 245 | ||
@@ -290,6 +300,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
290 | int desiredAccess = GENERIC_READ | GENERIC_WRITE; | 300 | int desiredAccess = GENERIC_READ | GENERIC_WRITE; |
291 | __u16 fileHandle; | 301 | __u16 fileHandle; |
292 | struct cifs_sb_info *cifs_sb; | 302 | struct cifs_sb_info *cifs_sb; |
303 | struct tcon_link *tlink; | ||
293 | struct cifsTconInfo *tcon; | 304 | struct cifsTconInfo *tcon; |
294 | char *full_path = NULL; | 305 | char *full_path = NULL; |
295 | FILE_ALL_INFO *buf = NULL; | 306 | FILE_ALL_INFO *buf = NULL; |
@@ -299,13 +310,12 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
299 | xid = GetXid(); | 310 | xid = GetXid(); |
300 | 311 | ||
301 | cifs_sb = CIFS_SB(inode->i_sb); | 312 | cifs_sb = CIFS_SB(inode->i_sb); |
302 | tcon = cifs_sb_tcon(cifs_sb); | 313 | tlink = cifs_sb_tlink(cifs_sb); |
303 | 314 | if (IS_ERR(tlink)) { | |
304 | full_path = build_path_from_dentry(direntry); | 315 | FreeXid(xid); |
305 | if (full_path == NULL) { | 316 | return PTR_ERR(tlink); |
306 | rc = -ENOMEM; | ||
307 | goto cifs_create_out; | ||
308 | } | 317 | } |
318 | tcon = tlink_tcon(tlink); | ||
309 | 319 | ||
310 | if (oplockEnabled) | 320 | if (oplockEnabled) |
311 | oplock = REQ_OPLOCK; | 321 | oplock = REQ_OPLOCK; |
@@ -315,6 +325,12 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
315 | else | 325 | else |
316 | oflags = FMODE_READ | SMB_O_CREAT; | 326 | oflags = FMODE_READ | SMB_O_CREAT; |
317 | 327 | ||
328 | full_path = build_path_from_dentry(direntry); | ||
329 | if (full_path == NULL) { | ||
330 | rc = -ENOMEM; | ||
331 | goto cifs_create_out; | ||
332 | } | ||
333 | |||
318 | if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) && | 334 | if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) && |
319 | (CIFS_UNIX_POSIX_PATH_OPS_CAP & | 335 | (CIFS_UNIX_POSIX_PATH_OPS_CAP & |
320 | le64_to_cpu(tcon->fsUnixInfo.Capability))) { | 336 | le64_to_cpu(tcon->fsUnixInfo.Capability))) { |
@@ -481,6 +497,7 @@ cifs_create_set_dentry: | |||
481 | cifs_create_out: | 497 | cifs_create_out: |
482 | kfree(buf); | 498 | kfree(buf); |
483 | kfree(full_path); | 499 | kfree(full_path); |
500 | cifs_put_tlink(tlink); | ||
484 | FreeXid(xid); | 501 | FreeXid(xid); |
485 | return rc; | 502 | return rc; |
486 | } | 503 | } |
@@ -491,6 +508,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, | |||
491 | int rc = -EPERM; | 508 | int rc = -EPERM; |
492 | int xid; | 509 | int xid; |
493 | struct cifs_sb_info *cifs_sb; | 510 | struct cifs_sb_info *cifs_sb; |
511 | struct tcon_link *tlink; | ||
494 | struct cifsTconInfo *pTcon; | 512 | struct cifsTconInfo *pTcon; |
495 | char *full_path = NULL; | 513 | char *full_path = NULL; |
496 | struct inode *newinode = NULL; | 514 | struct inode *newinode = NULL; |
@@ -503,10 +521,14 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, | |||
503 | if (!old_valid_dev(device_number)) | 521 | if (!old_valid_dev(device_number)) |
504 | return -EINVAL; | 522 | return -EINVAL; |
505 | 523 | ||
506 | xid = GetXid(); | ||
507 | |||
508 | cifs_sb = CIFS_SB(inode->i_sb); | 524 | cifs_sb = CIFS_SB(inode->i_sb); |
509 | pTcon = cifs_sb_tcon(cifs_sb); | 525 | tlink = cifs_sb_tlink(cifs_sb); |
526 | if (IS_ERR(tlink)) | ||
527 | return PTR_ERR(tlink); | ||
528 | |||
529 | pTcon = tlink_tcon(tlink); | ||
530 | |||
531 | xid = GetXid(); | ||
510 | 532 | ||
511 | full_path = build_path_from_dentry(direntry); | 533 | full_path = build_path_from_dentry(direntry); |
512 | if (full_path == NULL) { | 534 | if (full_path == NULL) { |
@@ -606,6 +628,7 @@ mknod_out: | |||
606 | kfree(full_path); | 628 | kfree(full_path); |
607 | kfree(buf); | 629 | kfree(buf); |
608 | FreeXid(xid); | 630 | FreeXid(xid); |
631 | cifs_put_tlink(tlink); | ||
609 | return rc; | 632 | return rc; |
610 | } | 633 | } |
611 | 634 | ||
@@ -619,6 +642,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
619 | __u16 fileHandle = 0; | 642 | __u16 fileHandle = 0; |
620 | bool posix_open = false; | 643 | bool posix_open = false; |
621 | struct cifs_sb_info *cifs_sb; | 644 | struct cifs_sb_info *cifs_sb; |
645 | struct tcon_link *tlink; | ||
622 | struct cifsTconInfo *pTcon; | 646 | struct cifsTconInfo *pTcon; |
623 | struct cifsFileInfo *cfile; | 647 | struct cifsFileInfo *cfile; |
624 | struct inode *newInode = NULL; | 648 | struct inode *newInode = NULL; |
@@ -633,7 +657,12 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
633 | /* check whether path exists */ | 657 | /* check whether path exists */ |
634 | 658 | ||
635 | cifs_sb = CIFS_SB(parent_dir_inode->i_sb); | 659 | cifs_sb = CIFS_SB(parent_dir_inode->i_sb); |
636 | pTcon = cifs_sb_tcon(cifs_sb); | 660 | tlink = cifs_sb_tlink(cifs_sb); |
661 | if (IS_ERR(tlink)) { | ||
662 | FreeXid(xid); | ||
663 | return (struct dentry *)tlink; | ||
664 | } | ||
665 | pTcon = tlink_tcon(tlink); | ||
637 | 666 | ||
638 | /* | 667 | /* |
639 | * Don't allow the separator character in a path component. | 668 | * Don't allow the separator character in a path component. |
@@ -644,8 +673,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
644 | for (i = 0; i < direntry->d_name.len; i++) | 673 | for (i = 0; i < direntry->d_name.len; i++) |
645 | if (direntry->d_name.name[i] == '\\') { | 674 | if (direntry->d_name.name[i] == '\\') { |
646 | cFYI(1, "Invalid file name"); | 675 | cFYI(1, "Invalid file name"); |
647 | FreeXid(xid); | 676 | rc = -EINVAL; |
648 | return ERR_PTR(-EINVAL); | 677 | goto lookup_out; |
649 | } | 678 | } |
650 | } | 679 | } |
651 | 680 | ||
@@ -655,7 +684,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
655 | */ | 684 | */ |
656 | if (nd && (nd->flags & LOOKUP_EXCL)) { | 685 | if (nd && (nd->flags & LOOKUP_EXCL)) { |
657 | d_instantiate(direntry, NULL); | 686 | d_instantiate(direntry, NULL); |
658 | return NULL; | 687 | rc = 0; |
688 | goto lookup_out; | ||
659 | } | 689 | } |
660 | 690 | ||
661 | /* can not grab the rename sem here since it would | 691 | /* can not grab the rename sem here since it would |
@@ -663,8 +693,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
663 | in which we already have the sb rename sem */ | 693 | in which we already have the sb rename sem */ |
664 | full_path = build_path_from_dentry(direntry); | 694 | full_path = build_path_from_dentry(direntry); |
665 | if (full_path == NULL) { | 695 | if (full_path == NULL) { |
666 | FreeXid(xid); | 696 | rc = -ENOMEM; |
667 | return ERR_PTR(-ENOMEM); | 697 | goto lookup_out; |
668 | } | 698 | } |
669 | 699 | ||
670 | if (direntry->d_inode != NULL) { | 700 | if (direntry->d_inode != NULL) { |
@@ -760,6 +790,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
760 | 790 | ||
761 | lookup_out: | 791 | lookup_out: |
762 | kfree(full_path); | 792 | kfree(full_path); |
793 | cifs_put_tlink(tlink); | ||
763 | FreeXid(xid); | 794 | FreeXid(xid); |
764 | return ERR_PTR(rc); | 795 | return ERR_PTR(rc); |
765 | } | 796 | } |