diff options
Diffstat (limited to 'fs/cifs/cifsfs.c')
-rw-r--r-- | fs/cifs/cifsfs.c | 56 |
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 | ||
155 | out_mount_failed: | 178 | out_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 | ||
555 | static struct file_system_type cifs_fs_type = { | 595 | struct 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 |