aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifsfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/cifsfs.c')
-rw-r--r--fs/cifs/cifsfs.c56
1 files changed, 54 insertions, 2 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 093beaa3900d..e9f4ec701092 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -44,6 +44,7 @@
44#include "cifs_fs_sb.h" 44#include "cifs_fs_sb.h"
45#include <linux/mm.h> 45#include <linux/mm.h>
46#include <linux/key-type.h> 46#include <linux/key-type.h>
47#include "dns_resolve.h"
47#include "cifs_spnego.h" 48#include "cifs_spnego.h"
48#define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDUs */ 49#define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDUs */
49 50
@@ -96,6 +97,9 @@ cifs_read_super(struct super_block *sb, void *data,
96{ 97{
97 struct inode *inode; 98 struct inode *inode;
98 struct cifs_sb_info *cifs_sb; 99 struct cifs_sb_info *cifs_sb;
100#ifdef CONFIG_CIFS_DFS_UPCALL
101 int len;
102#endif
99 int rc = 0; 103 int rc = 0;
100 104
101 /* BB should we make this contingent on mount parm? */ 105 /* BB should we make this contingent on mount parm? */
@@ -105,6 +109,25 @@ cifs_read_super(struct super_block *sb, void *data,
105 if (cifs_sb == NULL) 109 if (cifs_sb == NULL)
106 return -ENOMEM; 110 return -ENOMEM;
107 111
112#ifdef CONFIG_CIFS_DFS_UPCALL
113 /* copy mount params to sb for use in submounts */
114 /* BB: should we move this after the mount so we
115 * do not have to do the copy on failed mounts?
116 * BB: May be it is better to do simple copy before
117 * complex operation (mount), and in case of fail
118 * just exit instead of doing mount and attempting
119 * undo it if this copy fails?*/
120 len = strlen(data);
121 cifs_sb->mountdata = kzalloc(len + 1, GFP_KERNEL);
122 if (cifs_sb->mountdata == NULL) {
123 kfree(sb->s_fs_info);
124 sb->s_fs_info = NULL;
125 return -ENOMEM;
126 }
127 strncpy(cifs_sb->mountdata, data, len + 1);
128 cifs_sb->mountdata[len] = '\0';
129#endif
130
108 rc = cifs_mount(sb, cifs_sb, data, devname); 131 rc = cifs_mount(sb, cifs_sb, data, devname);
109 132
110 if (rc) { 133 if (rc) {
@@ -154,6 +177,12 @@ out_no_root:
154 177
155out_mount_failed: 178out_mount_failed:
156 if (cifs_sb) { 179 if (cifs_sb) {
180#ifdef CONFIG_CIFS_DFS_UPCALL
181 if (cifs_sb->mountdata) {
182 kfree(cifs_sb->mountdata);
183 cifs_sb->mountdata = NULL;
184 }
185#endif
157 if (cifs_sb->local_nls) 186 if (cifs_sb->local_nls)
158 unload_nls(cifs_sb->local_nls); 187 unload_nls(cifs_sb->local_nls);
159 kfree(cifs_sb); 188 kfree(cifs_sb);
@@ -177,6 +206,13 @@ cifs_put_super(struct super_block *sb)
177 if (rc) { 206 if (rc) {
178 cERROR(1, ("cifs_umount failed with return code %d", rc)); 207 cERROR(1, ("cifs_umount failed with return code %d", rc));
179 } 208 }
209#ifdef CONFIG_CIFS_DFS_UPCALL
210 if (cifs_sb->mountdata) {
211 kfree(cifs_sb->mountdata);
212 cifs_sb->mountdata = NULL;
213 }
214#endif
215
180 unload_nls(cifs_sb->local_nls); 216 unload_nls(cifs_sb->local_nls);
181 kfree(cifs_sb); 217 kfree(cifs_sb);
182 return; 218 return;
@@ -435,6 +471,10 @@ static void cifs_umount_begin(struct vfsmount *vfsmnt, int flags)
435 struct cifs_sb_info *cifs_sb; 471 struct cifs_sb_info *cifs_sb;
436 struct cifsTconInfo *tcon; 472 struct cifsTconInfo *tcon;
437 473
474#ifdef CONFIG_CIFS_DFS_UPCALL
475 dfs_shrink_umount_helper(vfsmnt);
476#endif /* CONFIG CIFS_DFS_UPCALL */
477
438 if (!(flags & MNT_FORCE)) 478 if (!(flags & MNT_FORCE))
439 return; 479 return;
440 cifs_sb = CIFS_SB(vfsmnt->mnt_sb); 480 cifs_sb = CIFS_SB(vfsmnt->mnt_sb);
@@ -552,7 +592,7 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
552 return remote_llseek(file, offset, origin); 592 return remote_llseek(file, offset, origin);
553} 593}
554 594
555static struct file_system_type cifs_fs_type = { 595struct file_system_type cifs_fs_type = {
556 .owner = THIS_MODULE, 596 .owner = THIS_MODULE,
557 .name = "cifs", 597 .name = "cifs",
558 .get_sb = cifs_get_sb, 598 .get_sb = cifs_get_sb,
@@ -1015,11 +1055,16 @@ init_cifs(void)
1015 if (rc) 1055 if (rc)
1016 goto out_unregister_filesystem; 1056 goto out_unregister_filesystem;
1017#endif 1057#endif
1058#ifdef CONFIG_CIFS_DFS_UPCALL
1059 rc = register_key_type(&key_type_dns_resolver);
1060 if (rc)
1061 goto out_unregister_key_type;
1062#endif
1018 oplockThread = kthread_run(cifs_oplock_thread, NULL, "cifsoplockd"); 1063 oplockThread = kthread_run(cifs_oplock_thread, NULL, "cifsoplockd");
1019 if (IS_ERR(oplockThread)) { 1064 if (IS_ERR(oplockThread)) {
1020 rc = PTR_ERR(oplockThread); 1065 rc = PTR_ERR(oplockThread);
1021 cERROR(1, ("error %d create oplock thread", rc)); 1066 cERROR(1, ("error %d create oplock thread", rc));
1022 goto out_unregister_key_type; 1067 goto out_unregister_dfs_key_type;
1023 } 1068 }
1024 1069
1025 dnotifyThread = kthread_run(cifs_dnotify_thread, NULL, "cifsdnotifyd"); 1070 dnotifyThread = kthread_run(cifs_dnotify_thread, NULL, "cifsdnotifyd");
@@ -1033,7 +1078,11 @@ init_cifs(void)
1033 1078
1034 out_stop_oplock_thread: 1079 out_stop_oplock_thread:
1035 kthread_stop(oplockThread); 1080 kthread_stop(oplockThread);
1081 out_unregister_dfs_key_type:
1082#ifdef CONFIG_CIFS_DFS_UPCALL
1083 unregister_key_type(&key_type_dns_resolver);
1036 out_unregister_key_type: 1084 out_unregister_key_type:
1085#endif
1037#ifdef CONFIG_CIFS_UPCALL 1086#ifdef CONFIG_CIFS_UPCALL
1038 unregister_key_type(&cifs_spnego_key_type); 1087 unregister_key_type(&cifs_spnego_key_type);
1039 out_unregister_filesystem: 1088 out_unregister_filesystem:
@@ -1059,6 +1108,9 @@ exit_cifs(void)
1059#ifdef CONFIG_PROC_FS 1108#ifdef CONFIG_PROC_FS
1060 cifs_proc_clean(); 1109 cifs_proc_clean();
1061#endif 1110#endif
1111#ifdef CONFIG_CIFS_DFS_UPCALL
1112 unregister_key_type(&key_type_dns_resolver);
1113#endif
1062#ifdef CONFIG_CIFS_UPCALL 1114#ifdef CONFIG_CIFS_UPCALL
1063 unregister_key_type(&cifs_spnego_key_type); 1115 unregister_key_type(&cifs_spnego_key_type);
1064#endif 1116#endif