diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-12-28 15:37:14 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-12-28 15:37:14 -0500 |
commit | 54a696bd07c14d3b1192d03ce7269bc59b45209a (patch) | |
tree | 2da3a0ce28e08bde17a0fba8bb807480849cf410 /fs/cifs/inode.c | |
parent | 1d248b2593e92db6c51ca07235985a95c625a93f (diff) | |
parent | 359d67d6ad054ae11ad459665fdfb883aca87782 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6: (31 commits)
[CIFS] Remove redundant test
[CIFS] make sure that DFS pathnames are properly formed
Remove an already-checked error condition in SendReceiveBlockingLock
Streamline SendReceiveBlockingLock: Use "goto out:" in an error condition
Streamline SendReceiveBlockingLock: Use "goto out:" in an error condition
[CIFS] Streamline SendReceive[2] by using "goto out:" in an error condition
Slightly streamline SendReceive[2]
Check the return value of cifs_sign_smb[2]
[CIFS] Cleanup: Move the check for too large R/W requests
[CIFS] Slightly simplify wait_for_free_request(), remove an unnecessary "else" branch
Simplify allocate_mid() slightly: Remove some unnecessary "else" branches
[CIFS] In SendReceive, move consistency check out of the mutexed region
cifs: store password in tcon
cifs: have calc_lanman_hash take more granular args
cifs: zero out session password before freeing it
cifs: fix wait_for_response to time out sleeping processes correctly
[CIFS] Can not mount with prefixpath if root directory of share is inaccessible
[CIFS] various minor cleanups pointed out by checkpatch script
[CIFS] fix typo
[CIFS] remove sparse warning
...
Fix trivial conflict in fs/cifs/cifs_fs_sb.h due to comment changes for
the CIFS_MOUNT_xyz bit definitions between cifs updates and security
updates.
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r-- | fs/cifs/inode.c | 58 |
1 files changed, 53 insertions, 5 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 8b7305e73d7e..f247da9f4edc 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * fs/cifs/inode.c | 2 | * fs/cifs/inode.c |
3 | * | 3 | * |
4 | * Copyright (C) International Business Machines Corp., 2002,2007 | 4 | * Copyright (C) International Business Machines Corp., 2002,2008 |
5 | * Author(s): Steve French (sfrench@us.ibm.com) | 5 | * Author(s): Steve French (sfrench@us.ibm.com) |
6 | * | 6 | * |
7 | * This library is free software; you can redistribute it and/or modify | 7 | * This library is free software; you can redistribute it and/or modify |
@@ -621,6 +621,47 @@ static const struct inode_operations cifs_ipc_inode_ops = { | |||
621 | .lookup = cifs_lookup, | 621 | .lookup = cifs_lookup, |
622 | }; | 622 | }; |
623 | 623 | ||
624 | static char *build_path_to_root(struct cifs_sb_info *cifs_sb) | ||
625 | { | ||
626 | int pplen = cifs_sb->prepathlen; | ||
627 | int dfsplen; | ||
628 | char *full_path = NULL; | ||
629 | |||
630 | /* if no prefix path, simply set path to the root of share to "" */ | ||
631 | if (pplen == 0) { | ||
632 | full_path = kmalloc(1, GFP_KERNEL); | ||
633 | if (full_path) | ||
634 | full_path[0] = 0; | ||
635 | return full_path; | ||
636 | } | ||
637 | |||
638 | if (cifs_sb->tcon && (cifs_sb->tcon->Flags & SMB_SHARE_IS_IN_DFS)) | ||
639 | dfsplen = strnlen(cifs_sb->tcon->treeName, MAX_TREE_SIZE + 1); | ||
640 | else | ||
641 | dfsplen = 0; | ||
642 | |||
643 | full_path = kmalloc(dfsplen + pplen + 1, GFP_KERNEL); | ||
644 | if (full_path == NULL) | ||
645 | return full_path; | ||
646 | |||
647 | if (dfsplen) { | ||
648 | strncpy(full_path, cifs_sb->tcon->treeName, dfsplen); | ||
649 | /* switch slash direction in prepath depending on whether | ||
650 | * windows or posix style path names | ||
651 | */ | ||
652 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) { | ||
653 | int i; | ||
654 | for (i = 0; i < dfsplen; i++) { | ||
655 | if (full_path[i] == '\\') | ||
656 | full_path[i] = '/'; | ||
657 | } | ||
658 | } | ||
659 | } | ||
660 | strncpy(full_path + dfsplen, cifs_sb->prepath, pplen); | ||
661 | full_path[dfsplen + pplen] = 0; /* add trailing null */ | ||
662 | return full_path; | ||
663 | } | ||
664 | |||
624 | /* gets root inode */ | 665 | /* gets root inode */ |
625 | struct inode *cifs_iget(struct super_block *sb, unsigned long ino) | 666 | struct inode *cifs_iget(struct super_block *sb, unsigned long ino) |
626 | { | 667 | { |
@@ -628,6 +669,7 @@ struct inode *cifs_iget(struct super_block *sb, unsigned long ino) | |||
628 | struct cifs_sb_info *cifs_sb; | 669 | struct cifs_sb_info *cifs_sb; |
629 | struct inode *inode; | 670 | struct inode *inode; |
630 | long rc; | 671 | long rc; |
672 | char *full_path; | ||
631 | 673 | ||
632 | inode = iget_locked(sb, ino); | 674 | inode = iget_locked(sb, ino); |
633 | if (!inode) | 675 | if (!inode) |
@@ -636,13 +678,17 @@ struct inode *cifs_iget(struct super_block *sb, unsigned long ino) | |||
636 | return inode; | 678 | return inode; |
637 | 679 | ||
638 | cifs_sb = CIFS_SB(inode->i_sb); | 680 | cifs_sb = CIFS_SB(inode->i_sb); |
639 | xid = GetXid(); | 681 | full_path = build_path_to_root(cifs_sb); |
682 | if (full_path == NULL) | ||
683 | return ERR_PTR(-ENOMEM); | ||
640 | 684 | ||
685 | xid = GetXid(); | ||
641 | if (cifs_sb->tcon->unix_ext) | 686 | if (cifs_sb->tcon->unix_ext) |
642 | rc = cifs_get_inode_info_unix(&inode, "", inode->i_sb, xid); | 687 | rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb, |
688 | xid); | ||
643 | else | 689 | else |
644 | rc = cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid, | 690 | rc = cifs_get_inode_info(&inode, full_path, NULL, inode->i_sb, |
645 | NULL); | 691 | xid, NULL); |
646 | if (rc && cifs_sb->tcon->ipc) { | 692 | if (rc && cifs_sb->tcon->ipc) { |
647 | cFYI(1, ("ipc connection - fake read inode")); | 693 | cFYI(1, ("ipc connection - fake read inode")); |
648 | inode->i_mode |= S_IFDIR; | 694 | inode->i_mode |= S_IFDIR; |
@@ -652,6 +698,7 @@ struct inode *cifs_iget(struct super_block *sb, unsigned long ino) | |||
652 | inode->i_uid = cifs_sb->mnt_uid; | 698 | inode->i_uid = cifs_sb->mnt_uid; |
653 | inode->i_gid = cifs_sb->mnt_gid; | 699 | inode->i_gid = cifs_sb->mnt_gid; |
654 | } else if (rc) { | 700 | } else if (rc) { |
701 | kfree(full_path); | ||
655 | _FreeXid(xid); | 702 | _FreeXid(xid); |
656 | iget_failed(inode); | 703 | iget_failed(inode); |
657 | return ERR_PTR(rc); | 704 | return ERR_PTR(rc); |
@@ -659,6 +706,7 @@ struct inode *cifs_iget(struct super_block *sb, unsigned long ino) | |||
659 | 706 | ||
660 | unlock_new_inode(inode); | 707 | unlock_new_inode(inode); |
661 | 708 | ||
709 | kfree(full_path); | ||
662 | /* can not call macro FreeXid here since in a void func | 710 | /* can not call macro FreeXid here since in a void func |
663 | * TODO: This is no longer true | 711 | * TODO: This is no longer true |
664 | */ | 712 | */ |