aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-06-26 22:39:22 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-06-26 22:39:22 -0400
commit804a007f5401f87fc6e7da1e8884dc32912e35d0 (patch)
treec94fda93a6c85b655bb8c13703a97295ce4314f6 /fs
parent8abf55883431a91d4877933240c8419b7fc17274 (diff)
parent9403c9c598e91d473c0582066e47ed2289292e45 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: cifs: propagate errors from cifs_get_root() to mount(2) cifs: tidy cifs_do_mount() up a bit cifs: more breakage on mount failures cifs: close sget() races cifs: pull freeing mountdata/dropping nls/freeing cifs_sb into cifs_umount() cifs: move cifs_umount() call into ->kill_sb() cifs: pull cifs_mount() call up sanitize cifs_umount() prototype cifs: initialize ->tlink_tree in cifs_setup_cifs_sb() cifs: allocate mountdata earlier cifs: leak on mount if we share superblock cifs: don't pass superblock to cifs_mount() cifs: don't leak nls on mount failure cifs: double free on mount failure take bdi setup/destruction into cifs_mount/cifs_umount Acked-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/cifs_fs_sb.h1
-rw-r--r--fs/cifs/cifsfs.c156
-rw-r--r--fs/cifs/cifsproto.h8
-rw-r--r--fs/cifs/connect.c49
4 files changed, 98 insertions, 116 deletions
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index ffb1459dc6ec..7260e11e21f8 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -42,6 +42,7 @@
42#define CIFS_MOUNT_MULTIUSER 0x20000 /* multiuser mount */ 42#define CIFS_MOUNT_MULTIUSER 0x20000 /* multiuser mount */
43#define CIFS_MOUNT_STRICT_IO 0x40000 /* strict cache mode */ 43#define CIFS_MOUNT_STRICT_IO 0x40000 /* strict cache mode */
44#define CIFS_MOUNT_RWPIDFORWARD 0x80000 /* use pid forwarding for rw */ 44#define CIFS_MOUNT_RWPIDFORWARD 0x80000 /* use pid forwarding for rw */
45#define CIFS_MOUNT_POSIXACL 0x100000 /* mirror of MS_POSIXACL in mnt_cifs_flags */
45 46
46struct cifs_sb_info { 47struct cifs_sb_info {
47 struct rb_root tlink_tree; 48 struct rb_root tlink_tree;
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 2f0c58646c10..35f9154615fa 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -104,8 +104,7 @@ cifs_sb_deactive(struct super_block *sb)
104} 104}
105 105
106static int 106static int
107cifs_read_super(struct super_block *sb, struct smb_vol *volume_info, 107cifs_read_super(struct super_block *sb)
108 const char *devname, int silent)
109{ 108{
110 struct inode *inode; 109 struct inode *inode;
111 struct cifs_sb_info *cifs_sb; 110 struct cifs_sb_info *cifs_sb;
@@ -113,22 +112,16 @@ cifs_read_super(struct super_block *sb, struct smb_vol *volume_info,
113 112
114 cifs_sb = CIFS_SB(sb); 113 cifs_sb = CIFS_SB(sb);
115 114
116 spin_lock_init(&cifs_sb->tlink_tree_lock); 115 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIXACL)
117 cifs_sb->tlink_tree = RB_ROOT; 116 sb->s_flags |= MS_POSIXACL;
118 117
119 rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY); 118 if (cifs_sb_master_tcon(cifs_sb)->ses->capabilities & CAP_LARGE_FILES)
120 if (rc) 119 sb->s_maxbytes = MAX_LFS_FILESIZE;
121 return rc; 120 else
122 121 sb->s_maxbytes = MAX_NON_LFS;
123 cifs_sb->bdi.ra_pages = default_backing_dev_info.ra_pages;
124 122
125 rc = cifs_mount(sb, cifs_sb, volume_info, devname); 123 /* BB FIXME fix time_gran to be larger for LANMAN sessions */
126 124 sb->s_time_gran = 100;
127 if (rc) {
128 if (!silent)
129 cERROR(1, "cifs_mount failed w/return code = %d", rc);
130 goto out_mount_failed;
131 }
132 125
133 sb->s_magic = CIFS_MAGIC_NUMBER; 126 sb->s_magic = CIFS_MAGIC_NUMBER;
134 sb->s_op = &cifs_super_ops; 127 sb->s_op = &cifs_super_ops;
@@ -170,37 +163,14 @@ out_no_root:
170 if (inode) 163 if (inode)
171 iput(inode); 164 iput(inode);
172 165
173 cifs_umount(sb, cifs_sb);
174
175out_mount_failed:
176 bdi_destroy(&cifs_sb->bdi);
177 return rc; 166 return rc;
178} 167}
179 168
180static void 169static void cifs_kill_sb(struct super_block *sb)
181cifs_put_super(struct super_block *sb)
182{ 170{
183 int rc = 0; 171 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
184 struct cifs_sb_info *cifs_sb; 172 kill_anon_super(sb);
185 173 cifs_umount(cifs_sb);
186 cFYI(1, "In cifs_put_super");
187 cifs_sb = CIFS_SB(sb);
188 if (cifs_sb == NULL) {
189 cFYI(1, "Empty cifs superblock info passed to unmount");
190 return;
191 }
192
193 rc = cifs_umount(sb, cifs_sb);
194 if (rc)
195 cERROR(1, "cifs_umount failed with return code %d", rc);
196 if (cifs_sb->mountdata) {
197 kfree(cifs_sb->mountdata);
198 cifs_sb->mountdata = NULL;
199 }
200
201 unload_nls(cifs_sb->local_nls);
202 bdi_destroy(&cifs_sb->bdi);
203 kfree(cifs_sb);
204} 174}
205 175
206static int 176static int
@@ -548,7 +518,6 @@ static int cifs_drop_inode(struct inode *inode)
548} 518}
549 519
550static const struct super_operations cifs_super_ops = { 520static const struct super_operations cifs_super_ops = {
551 .put_super = cifs_put_super,
552 .statfs = cifs_statfs, 521 .statfs = cifs_statfs,
553 .alloc_inode = cifs_alloc_inode, 522 .alloc_inode = cifs_alloc_inode,
554 .destroy_inode = cifs_destroy_inode, 523 .destroy_inode = cifs_destroy_inode,
@@ -585,7 +554,7 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb)
585 full_path = cifs_build_path_to_root(vol, cifs_sb, 554 full_path = cifs_build_path_to_root(vol, cifs_sb,
586 cifs_sb_master_tcon(cifs_sb)); 555 cifs_sb_master_tcon(cifs_sb));
587 if (full_path == NULL) 556 if (full_path == NULL)
588 return NULL; 557 return ERR_PTR(-ENOMEM);
589 558
590 cFYI(1, "Get root dentry for %s", full_path); 559 cFYI(1, "Get root dentry for %s", full_path);
591 560
@@ -614,7 +583,7 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb)
614 dchild = d_alloc(dparent, &name); 583 dchild = d_alloc(dparent, &name);
615 if (dchild == NULL) { 584 if (dchild == NULL) {
616 dput(dparent); 585 dput(dparent);
617 dparent = NULL; 586 dparent = ERR_PTR(-ENOMEM);
618 goto out; 587 goto out;
619 } 588 }
620 } 589 }
@@ -632,7 +601,7 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb)
632 if (rc) { 601 if (rc) {
633 dput(dchild); 602 dput(dchild);
634 dput(dparent); 603 dput(dparent);
635 dparent = NULL; 604 dparent = ERR_PTR(rc);
636 goto out; 605 goto out;
637 } 606 }
638 alias = d_materialise_unique(dchild, inode); 607 alias = d_materialise_unique(dchild, inode);
@@ -640,7 +609,7 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb)
640 dput(dchild); 609 dput(dchild);
641 if (IS_ERR(alias)) { 610 if (IS_ERR(alias)) {
642 dput(dparent); 611 dput(dparent);
643 dparent = NULL; 612 dparent = ERR_PTR(-EINVAL); /* XXX */
644 goto out; 613 goto out;
645 } 614 }
646 dchild = alias; 615 dchild = alias;
@@ -660,6 +629,13 @@ out:
660 return dparent; 629 return dparent;
661} 630}
662 631
632static int cifs_set_super(struct super_block *sb, void *data)
633{
634 struct cifs_mnt_data *mnt_data = data;
635 sb->s_fs_info = mnt_data->cifs_sb;
636 return set_anon_super(sb, NULL);
637}
638
663static struct dentry * 639static struct dentry *
664cifs_do_mount(struct file_system_type *fs_type, 640cifs_do_mount(struct file_system_type *fs_type,
665 int flags, const char *dev_name, void *data) 641 int flags, const char *dev_name, void *data)
@@ -680,75 +656,73 @@ cifs_do_mount(struct file_system_type *fs_type,
680 cifs_sb = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL); 656 cifs_sb = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL);
681 if (cifs_sb == NULL) { 657 if (cifs_sb == NULL) {
682 root = ERR_PTR(-ENOMEM); 658 root = ERR_PTR(-ENOMEM);
683 goto out; 659 goto out_nls;
660 }
661
662 cifs_sb->mountdata = kstrndup(data, PAGE_SIZE, GFP_KERNEL);
663 if (cifs_sb->mountdata == NULL) {
664 root = ERR_PTR(-ENOMEM);
665 goto out_cifs_sb;
684 } 666 }
685 667
686 cifs_setup_cifs_sb(volume_info, cifs_sb); 668 cifs_setup_cifs_sb(volume_info, cifs_sb);
687 669
670 rc = cifs_mount(cifs_sb, volume_info);
671 if (rc) {
672 if (!(flags & MS_SILENT))
673 cERROR(1, "cifs_mount failed w/return code = %d", rc);
674 root = ERR_PTR(rc);
675 goto out_mountdata;
676 }
677
688 mnt_data.vol = volume_info; 678 mnt_data.vol = volume_info;
689 mnt_data.cifs_sb = cifs_sb; 679 mnt_data.cifs_sb = cifs_sb;
690 mnt_data.flags = flags; 680 mnt_data.flags = flags;
691 681
692 sb = sget(fs_type, cifs_match_super, set_anon_super, &mnt_data); 682 sb = sget(fs_type, cifs_match_super, cifs_set_super, &mnt_data);
693 if (IS_ERR(sb)) { 683 if (IS_ERR(sb)) {
694 root = ERR_CAST(sb); 684 root = ERR_CAST(sb);
695 goto out_cifs_sb; 685 cifs_umount(cifs_sb);
686 goto out;
696 } 687 }
697 688
698 if (sb->s_fs_info) { 689 if (sb->s_root) {
699 cFYI(1, "Use existing superblock"); 690 cFYI(1, "Use existing superblock");
700 goto out_shared; 691 cifs_umount(cifs_sb);
701 } 692 } else {
702 693 sb->s_flags = flags;
703 /* 694 /* BB should we make this contingent on mount parm? */
704 * Copy mount params for use in submounts. Better to do 695 sb->s_flags |= MS_NODIRATIME | MS_NOATIME;
705 * the copy here and deal with the error before cleanup gets 696
706 * complicated post-mount. 697 rc = cifs_read_super(sb);
707 */ 698 if (rc) {
708 cifs_sb->mountdata = kstrndup(data, PAGE_SIZE, GFP_KERNEL); 699 root = ERR_PTR(rc);
709 if (cifs_sb->mountdata == NULL) { 700 goto out_super;
710 root = ERR_PTR(-ENOMEM); 701 }
711 goto out_super;
712 }
713
714 sb->s_flags = flags;
715 /* BB should we make this contingent on mount parm? */
716 sb->s_flags |= MS_NODIRATIME | MS_NOATIME;
717 sb->s_fs_info = cifs_sb;
718 702
719 rc = cifs_read_super(sb, volume_info, dev_name, 703 sb->s_flags |= MS_ACTIVE;
720 flags & MS_SILENT ? 1 : 0);
721 if (rc) {
722 root = ERR_PTR(rc);
723 goto out_super;
724 } 704 }
725 705
726 sb->s_flags |= MS_ACTIVE;
727
728 root = cifs_get_root(volume_info, sb); 706 root = cifs_get_root(volume_info, sb);
729 if (root == NULL) 707 if (IS_ERR(root))
730 goto out_super; 708 goto out_super;
731 709
732 cFYI(1, "dentry root is: %p", root); 710 cFYI(1, "dentry root is: %p", root);
733 goto out; 711 goto out;
734 712
735out_shared:
736 root = cifs_get_root(volume_info, sb);
737 if (root)
738 cFYI(1, "dentry root is: %p", root);
739 goto out;
740
741out_super: 713out_super:
742 kfree(cifs_sb->mountdata);
743 deactivate_locked_super(sb); 714 deactivate_locked_super(sb);
744
745out_cifs_sb:
746 unload_nls(cifs_sb->local_nls);
747 kfree(cifs_sb);
748
749out: 715out:
750 cifs_cleanup_volume_info(&volume_info); 716 cifs_cleanup_volume_info(&volume_info);
751 return root; 717 return root;
718
719out_mountdata:
720 kfree(cifs_sb->mountdata);
721out_cifs_sb:
722 kfree(cifs_sb);
723out_nls:
724 unload_nls(volume_info->local_nls);
725 goto out;
752} 726}
753 727
754static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, 728static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
@@ -837,7 +811,7 @@ struct file_system_type cifs_fs_type = {
837 .owner = THIS_MODULE, 811 .owner = THIS_MODULE,
838 .name = "cifs", 812 .name = "cifs",
839 .mount = cifs_do_mount, 813 .mount = cifs_do_mount,
840 .kill_sb = kill_anon_super, 814 .kill_sb = cifs_kill_sb,
841 /* .fs_flags */ 815 /* .fs_flags */
842}; 816};
843const struct inode_operations cifs_dir_inode_ops = { 817const struct inode_operations cifs_dir_inode_ops = {
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 953f84413c77..257f312ede42 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -157,9 +157,8 @@ extern int cifs_match_super(struct super_block *, void *);
157extern void cifs_cleanup_volume_info(struct smb_vol **pvolume_info); 157extern void cifs_cleanup_volume_info(struct smb_vol **pvolume_info);
158extern int cifs_setup_volume_info(struct smb_vol **pvolume_info, 158extern int cifs_setup_volume_info(struct smb_vol **pvolume_info,
159 char *mount_data, const char *devname); 159 char *mount_data, const char *devname);
160extern int cifs_mount(struct super_block *, struct cifs_sb_info *, 160extern int cifs_mount(struct cifs_sb_info *, struct smb_vol *);
161 struct smb_vol *, const char *); 161extern void cifs_umount(struct cifs_sb_info *);
162extern int cifs_umount(struct super_block *, struct cifs_sb_info *);
163extern void cifs_dfs_release_automount_timer(void); 162extern void cifs_dfs_release_automount_timer(void);
164void cifs_proc_init(void); 163void cifs_proc_init(void);
165void cifs_proc_clean(void); 164void cifs_proc_clean(void);
@@ -218,7 +217,8 @@ extern int get_dfs_path(int xid, struct cifs_ses *pSesInfo,
218 struct dfs_info3_param **preferrals, 217 struct dfs_info3_param **preferrals,
219 int remap); 218 int remap);
220extern void reset_cifs_unix_caps(int xid, struct cifs_tcon *tcon, 219extern void reset_cifs_unix_caps(int xid, struct cifs_tcon *tcon,
221 struct super_block *sb, struct smb_vol *vol); 220 struct cifs_sb_info *cifs_sb,
221 struct smb_vol *vol);
222extern int CIFSSMBQFSInfo(const int xid, struct cifs_tcon *tcon, 222extern int CIFSSMBQFSInfo(const int xid, struct cifs_tcon *tcon,
223 struct kstatfs *FSData); 223 struct kstatfs *FSData);
224extern int SMBOldQFSInfo(const int xid, struct cifs_tcon *tcon, 224extern int SMBOldQFSInfo(const int xid, struct cifs_tcon *tcon,
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index c761935eab8c..7f540df52527 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2546,7 +2546,7 @@ ip_connect(struct TCP_Server_Info *server)
2546} 2546}
2547 2547
2548void reset_cifs_unix_caps(int xid, struct cifs_tcon *tcon, 2548void reset_cifs_unix_caps(int xid, struct cifs_tcon *tcon,
2549 struct super_block *sb, struct smb_vol *vol_info) 2549 struct cifs_sb_info *cifs_sb, struct smb_vol *vol_info)
2550{ 2550{
2551 /* if we are reconnecting then should we check to see if 2551 /* if we are reconnecting then should we check to see if
2552 * any requested capabilities changed locally e.g. via 2552 * any requested capabilities changed locally e.g. via
@@ -2600,22 +2600,23 @@ void reset_cifs_unix_caps(int xid, struct cifs_tcon *tcon,
2600 cap &= ~CIFS_UNIX_POSIX_ACL_CAP; 2600 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
2601 else if (CIFS_UNIX_POSIX_ACL_CAP & cap) { 2601 else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
2602 cFYI(1, "negotiated posix acl support"); 2602 cFYI(1, "negotiated posix acl support");
2603 if (sb) 2603 if (cifs_sb)
2604 sb->s_flags |= MS_POSIXACL; 2604 cifs_sb->mnt_cifs_flags |=
2605 CIFS_MOUNT_POSIXACL;
2605 } 2606 }
2606 2607
2607 if (vol_info && vol_info->posix_paths == 0) 2608 if (vol_info && vol_info->posix_paths == 0)
2608 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP; 2609 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
2609 else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) { 2610 else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
2610 cFYI(1, "negotiate posix pathnames"); 2611 cFYI(1, "negotiate posix pathnames");
2611 if (sb) 2612 if (cifs_sb)
2612 CIFS_SB(sb)->mnt_cifs_flags |= 2613 cifs_sb->mnt_cifs_flags |=
2613 CIFS_MOUNT_POSIX_PATHS; 2614 CIFS_MOUNT_POSIX_PATHS;
2614 } 2615 }
2615 2616
2616 if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) { 2617 if (cifs_sb && (cifs_sb->rsize > 127 * 1024)) {
2617 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) { 2618 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
2618 CIFS_SB(sb)->rsize = 127 * 1024; 2619 cifs_sb->rsize = 127 * 1024;
2619 cFYI(DBG2, "larger reads not supported by srv"); 2620 cFYI(DBG2, "larger reads not supported by srv");
2620 } 2621 }
2621 } 2622 }
@@ -2662,6 +2663,9 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
2662{ 2663{
2663 INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks); 2664 INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks);
2664 2665
2666 spin_lock_init(&cifs_sb->tlink_tree_lock);
2667 cifs_sb->tlink_tree = RB_ROOT;
2668
2665 if (pvolume_info->rsize > CIFSMaxBufSize) { 2669 if (pvolume_info->rsize > CIFSMaxBufSize) {
2666 cERROR(1, "rsize %d too large, using MaxBufSize", 2670 cERROR(1, "rsize %d too large, using MaxBufSize",
2667 pvolume_info->rsize); 2671 pvolume_info->rsize);
@@ -2982,8 +2986,7 @@ out:
2982} 2986}
2983 2987
2984int 2988int
2985cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, 2989cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info)
2986 struct smb_vol *volume_info, const char *devname)
2987{ 2990{
2988 int rc = 0; 2991 int rc = 0;
2989 int xid; 2992 int xid;
@@ -2994,6 +2997,13 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2994 struct tcon_link *tlink; 2997 struct tcon_link *tlink;
2995#ifdef CONFIG_CIFS_DFS_UPCALL 2998#ifdef CONFIG_CIFS_DFS_UPCALL
2996 int referral_walks_count = 0; 2999 int referral_walks_count = 0;
3000
3001 rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY);
3002 if (rc)
3003 return rc;
3004
3005 cifs_sb->bdi.ra_pages = default_backing_dev_info.ra_pages;
3006
2997try_mount_again: 3007try_mount_again:
2998 /* cleanup activities if we're chasing a referral */ 3008 /* cleanup activities if we're chasing a referral */
2999 if (referral_walks_count) { 3009 if (referral_walks_count) {
@@ -3018,6 +3028,7 @@ try_mount_again:
3018 srvTcp = cifs_get_tcp_session(volume_info); 3028 srvTcp = cifs_get_tcp_session(volume_info);
3019 if (IS_ERR(srvTcp)) { 3029 if (IS_ERR(srvTcp)) {
3020 rc = PTR_ERR(srvTcp); 3030 rc = PTR_ERR(srvTcp);
3031 bdi_destroy(&cifs_sb->bdi);
3021 goto out; 3032 goto out;
3022 } 3033 }
3023 3034
@@ -3029,14 +3040,6 @@ try_mount_again:
3029 goto mount_fail_check; 3040 goto mount_fail_check;
3030 } 3041 }
3031 3042
3032 if (pSesInfo->capabilities & CAP_LARGE_FILES)
3033 sb->s_maxbytes = MAX_LFS_FILESIZE;
3034 else
3035 sb->s_maxbytes = MAX_NON_LFS;
3036
3037 /* BB FIXME fix time_gran to be larger for LANMAN sessions */
3038 sb->s_time_gran = 100;
3039
3040 /* search for existing tcon to this server share */ 3043 /* search for existing tcon to this server share */
3041 tcon = cifs_get_tcon(pSesInfo, volume_info); 3044 tcon = cifs_get_tcon(pSesInfo, volume_info);
3042 if (IS_ERR(tcon)) { 3045 if (IS_ERR(tcon)) {
@@ -3049,7 +3052,7 @@ try_mount_again:
3049 if (tcon->ses->capabilities & CAP_UNIX) { 3052 if (tcon->ses->capabilities & CAP_UNIX) {
3050 /* reset of caps checks mount to see if unix extensions 3053 /* reset of caps checks mount to see if unix extensions
3051 disabled for just this mount */ 3054 disabled for just this mount */
3052 reset_cifs_unix_caps(xid, tcon, sb, volume_info); 3055 reset_cifs_unix_caps(xid, tcon, cifs_sb, volume_info);
3053 if ((tcon->ses->server->tcpStatus == CifsNeedReconnect) && 3056 if ((tcon->ses->server->tcpStatus == CifsNeedReconnect) &&
3054 (le64_to_cpu(tcon->fsUnixInfo.Capability) & 3057 (le64_to_cpu(tcon->fsUnixInfo.Capability) &
3055 CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)) { 3058 CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)) {
@@ -3172,6 +3175,7 @@ mount_fail_check:
3172 cifs_put_smb_ses(pSesInfo); 3175 cifs_put_smb_ses(pSesInfo);
3173 else 3176 else
3174 cifs_put_tcp_session(srvTcp); 3177 cifs_put_tcp_session(srvTcp);
3178 bdi_destroy(&cifs_sb->bdi);
3175 goto out; 3179 goto out;
3176 } 3180 }
3177 3181
@@ -3346,8 +3350,8 @@ CIFSTCon(unsigned int xid, struct cifs_ses *ses,
3346 return rc; 3350 return rc;
3347} 3351}
3348 3352
3349int 3353void
3350cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) 3354cifs_umount(struct cifs_sb_info *cifs_sb)
3351{ 3355{
3352 struct rb_root *root = &cifs_sb->tlink_tree; 3356 struct rb_root *root = &cifs_sb->tlink_tree;
3353 struct rb_node *node; 3357 struct rb_node *node;
@@ -3368,7 +3372,10 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3368 } 3372 }
3369 spin_unlock(&cifs_sb->tlink_tree_lock); 3373 spin_unlock(&cifs_sb->tlink_tree_lock);
3370 3374
3371 return 0; 3375 bdi_destroy(&cifs_sb->bdi);
3376 kfree(cifs_sb->mountdata);
3377 unload_nls(cifs_sb->local_nls);
3378 kfree(cifs_sb);
3372} 3379}
3373 3380
3374int cifs_negotiate_protocol(unsigned int xid, struct cifs_ses *ses) 3381int cifs_negotiate_protocol(unsigned int xid, struct cifs_ses *ses)