]> bbs.cooldavid.org Git - net-next-2.6.git/blame - fs/cifs/cifsfs.c
iget: stop BFS from using iget() and read_inode()
[net-next-2.6.git] / fs / cifs / cifsfs.c
CommitLineData
1da177e4
LT
1/*
2 * fs/cifs/cifsfs.c
3 *
35c11fdd 4 * Copyright (C) International Business Machines Corp., 2002,2007
1da177e4
LT
5 * Author(s): Steve French (sfrench@us.ibm.com)
6 *
7 * Common Internet FileSystem (CIFS) client
8 *
9 * This library is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as published
11 * by the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
17 * the GNU Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24/* Note that BB means BUGBUG (ie something to fix eventually) */
25
26#include <linux/module.h>
27#include <linux/fs.h>
28#include <linux/mount.h>
29#include <linux/slab.h>
30#include <linux/init.h>
31#include <linux/list.h>
32#include <linux/seq_file.h>
33#include <linux/vfs.h>
34#include <linux/mempool.h>
6ab16d24 35#include <linux/delay.h>
45af7a0f 36#include <linux/kthread.h>
7dfb7103 37#include <linux/freezer.h>
1da177e4
LT
38#include "cifsfs.h"
39#include "cifspdu.h"
40#define DECLARE_GLOBALS_HERE
41#include "cifsglob.h"
42#include "cifsproto.h"
43#include "cifs_debug.h"
44#include "cifs_fs_sb.h"
45#include <linux/mm.h>
84a15b93 46#include <linux/key-type.h>
6103335d 47#include "dns_resolve.h"
e545937a 48#include "cifs_spnego.h"
1da177e4
LT
49#define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDUs */
50
51#ifdef CONFIG_CIFS_QUOTA
52static struct quotactl_ops cifs_quotactl_ops;
35c11fdd
SF
53#endif /* QUOTA */
54
1da177e4
LT
55int cifsFYI = 0;
56int cifsERROR = 1;
57int traceSMB = 0;
58unsigned int oplockEnabled = 1;
59unsigned int experimEnabled = 0;
60unsigned int linuxExtEnabled = 1;
61unsigned int lookupCacheEnabled = 1;
62unsigned int multiuser_mount = 0;
3979877e
SF
63unsigned int extended_security = CIFSSEC_DEF;
64/* unsigned int ntlmv2_support = 0; */
1da177e4 65unsigned int sign_CIFS_PDUs = 1;
6dc0f87e
SF
66extern struct task_struct *oplockThread; /* remove sparse warning */
67struct task_struct *oplockThread = NULL;
99ee4dbd 68/* extern struct task_struct * dnotifyThread; remove sparse warning */
6dc0f87e 69static struct task_struct *dnotifyThread = NULL;
ee9b6d61 70static const struct super_operations cifs_super_ops;
1da177e4
LT
71unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;
72module_param(CIFSMaxBufSize, int, 0);
63135e08
SF
73MODULE_PARM_DESC(CIFSMaxBufSize, "Network buffer size (not including header). "
74 "Default: 16384 Range: 8192 to 130048");
1da177e4
LT
75unsigned int cifs_min_rcv = CIFS_MIN_RCV_POOL;
76module_param(cifs_min_rcv, int, 0);
63135e08
SF
77MODULE_PARM_DESC(cifs_min_rcv, "Network buffers in pool. Default: 4 Range: "
78 "1 to 64");
1da177e4
LT
79unsigned int cifs_min_small = 30;
80module_param(cifs_min_small, int, 0);
63135e08
SF
81MODULE_PARM_DESC(cifs_min_small, "Small network buffers in pool. Default: 30 "
82 "Range: 2 to 256");
1da177e4
LT
83unsigned int cifs_max_pending = CIFS_MAX_REQ;
84module_param(cifs_max_pending, int, 0);
63135e08
SF
85MODULE_PARM_DESC(cifs_max_pending, "Simultaneous requests to server. "
86 "Default: 50 Range: 2 to 256");
1da177e4 87
1da177e4
LT
88extern mempool_t *cifs_sm_req_poolp;
89extern mempool_t *cifs_req_poolp;
90extern mempool_t *cifs_mid_poolp;
91
e18b890b 92extern struct kmem_cache *cifs_oplock_cachep;
1da177e4
LT
93
94static int
95cifs_read_super(struct super_block *sb, void *data,
96 const char *devname, int silent)
97{
98 struct inode *inode;
99 struct cifs_sb_info *cifs_sb;
e6ab1582
IM
100#ifdef CONFIG_CIFS_DFS_UPCALL
101 int len;
102#endif
1da177e4 103 int rc = 0;
50c2f753 104
1b2b2126
SF
105 /* BB should we make this contingent on mount parm? */
106 sb->s_flags |= MS_NODIRATIME | MS_NOATIME;
790fe579 107 sb->s_fs_info = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL);
1da177e4 108 cifs_sb = CIFS_SB(sb);
4523cc30 109 if (cifs_sb == NULL)
1da177e4 110 return -ENOMEM;
1da177e4 111
e6ab1582
IM
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
1da177e4
LT
131 rc = cifs_mount(sb, cifs_sb, data, devname);
132
133 if (rc) {
134 if (!silent)
135 cERROR(1,
136 ("cifs_mount failed w/return code = %d", rc));
137 goto out_mount_failed;
138 }
139
140 sb->s_magic = CIFS_MAGIC_NUMBER;
141 sb->s_op = &cifs_super_ops;
4523cc30 142/* if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512)
790fe579
SF
143 sb->s_blocksize =
144 cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */
1da177e4
LT
145#ifdef CONFIG_CIFS_QUOTA
146 sb->s_qcop = &cifs_quotactl_ops;
147#endif
148 sb->s_blocksize = CIFS_MAX_MSGSIZE;
149 sb->s_blocksize_bits = 14; /* default 2**14 = CIFS_MAX_MSGSIZE */
150 inode = iget(sb, ROOT_I);
151
152 if (!inode) {
153 rc = -ENOMEM;
154 goto out_no_root;
155 }
156
157 sb->s_root = d_alloc_root(inode);
158
159 if (!sb->s_root) {
160 rc = -ENOMEM;
161 goto out_no_root;
162 }
50c2f753 163
7521a3c5
SF
164#ifdef CONFIG_CIFS_EXPERIMENTAL
165 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
166 cFYI(1, ("export ops supported"));
167 sb->s_export_op = &cifs_export_ops;
168 }
169#endif /* EXPERIMENTAL */
1da177e4
LT
170
171 return 0;
172
173out_no_root:
174 cERROR(1, ("cifs_read_super: get root inode failed"));
175 if (inode)
176 iput(inode);
177
178out_mount_failed:
4523cc30 179 if (cifs_sb) {
e6ab1582
IM
180#ifdef CONFIG_CIFS_DFS_UPCALL
181 if (cifs_sb->mountdata) {
182 kfree(cifs_sb->mountdata);
183 cifs_sb->mountdata = NULL;
184 }
185#endif
4523cc30 186 if (cifs_sb->local_nls)
50c2f753 187 unload_nls(cifs_sb->local_nls);
1da177e4
LT
188 kfree(cifs_sb);
189 }
190 return rc;
191}
192
193static void
194cifs_put_super(struct super_block *sb)
195{
196 int rc = 0;
197 struct cifs_sb_info *cifs_sb;
198
199 cFYI(1, ("In cifs_put_super"));
200 cifs_sb = CIFS_SB(sb);
4523cc30 201 if (cifs_sb == NULL) {
790fe579 202 cFYI(1, ("Empty cifs superblock info passed to unmount"));
1da177e4
LT
203 return;
204 }
790fe579 205 rc = cifs_umount(sb, cifs_sb);
1da177e4
LT
206 if (rc) {
207 cERROR(1, ("cifs_umount failed with return code %d", rc));
208 }
e6ab1582
IM
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
1da177e4
LT
216 unload_nls(cifs_sb->local_nls);
217 kfree(cifs_sb);
218 return;
219}
220
221static int
726c3342 222cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
1da177e4 223{
726c3342 224 struct super_block *sb = dentry->d_sb;
790fe579 225 int xid;
c81156dd 226 int rc = -EOPNOTSUPP;
1da177e4
LT
227 struct cifs_sb_info *cifs_sb;
228 struct cifsTconInfo *pTcon;
229
230 xid = GetXid();
231
232 cifs_sb = CIFS_SB(sb);
233 pTcon = cifs_sb->tcon;
234
235 buf->f_type = CIFS_MAGIC_NUMBER;
236
237 /* instead could get the real value via SMB_QUERY_FS_ATTRIBUTE_INFO */
790fe579 238 buf->f_namelen = PATH_MAX; /* PATH_MAX may be too long - it would
c81156dd
SF
239 presumably be total path, but note
240 that some servers (includinng Samba 3)
241 have a shorter maximum path */
1da177e4
LT
242 buf->f_files = 0; /* undefined */
243 buf->f_ffree = 0; /* unlimited */
244
1da177e4 245/* BB we could add a second check for a QFS Unix capability bit */
f28ac91b 246/* BB FIXME check CIFS_POSIX_EXTENSIONS Unix cap first FIXME BB */
c81156dd
SF
247 if ((pTcon->ses->capabilities & CAP_UNIX) && (CIFS_POSIX_EXTENSIONS &
248 le64_to_cpu(pTcon->fsUnixInfo.Capability)))
737b758c 249 rc = CIFSSMBQFSPosixInfo(xid, pTcon, buf);
1da177e4
LT
250
251 /* Only need to call the old QFSInfo if failed
252 on newer one */
4523cc30
SF
253 if (rc)
254 if (pTcon->ses->capabilities & CAP_NT_SMBS)
9ac00b7d 255 rc = CIFSSMBQFSInfo(xid, pTcon, buf); /* not supported by OS2 */
1da177e4 256
9ac00b7d
SF
257 /* Some old Windows servers also do not support level 103, retry with
258 older level one if old server failed the previous call or we
259 bypassed it because we detected that this was an older LANMAN sess */
4523cc30 260 if (rc)
20962438 261 rc = SMBOldQFSInfo(xid, pTcon, buf);
790fe579 262 /* int f_type;
1da177e4
LT
263 __fsid_t f_fsid;
264 int f_namelen; */
c81156dd 265 /* BB get from info in tcon struct at mount time call to QFSAttrInfo */
1da177e4 266 FreeXid(xid);
c81156dd
SF
267 return 0; /* always return success? what if volume is no
268 longer available? */
1da177e4
LT
269}
270
50c2f753 271static int cifs_permission(struct inode *inode, int mask, struct nameidata *nd)
1da177e4
LT
272{
273 struct cifs_sb_info *cifs_sb;
274
275 cifs_sb = CIFS_SB(inode->i_sb);
276
26f57364 277 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
1da177e4 278 return 0;
26f57364 279 else /* file mode might have been restricted at mount time
50c2f753 280 on the client (above and beyond ACL on servers) for
1da177e4 281 servers which do not support setting and viewing mode bits,
50c2f753 282 so allowing client to check permissions is useful */
1da177e4
LT
283 return generic_permission(inode, mask, NULL);
284}
285
e18b890b
CL
286static struct kmem_cache *cifs_inode_cachep;
287static struct kmem_cache *cifs_req_cachep;
288static struct kmem_cache *cifs_mid_cachep;
289struct kmem_cache *cifs_oplock_cachep;
290static struct kmem_cache *cifs_sm_req_cachep;
1da177e4
LT
291mempool_t *cifs_sm_req_poolp;
292mempool_t *cifs_req_poolp;
293mempool_t *cifs_mid_poolp;
294
295static struct inode *
296cifs_alloc_inode(struct super_block *sb)
297{
298 struct cifsInodeInfo *cifs_inode;
e94b1766 299 cifs_inode = kmem_cache_alloc(cifs_inode_cachep, GFP_KERNEL);
1da177e4
LT
300 if (!cifs_inode)
301 return NULL;
302 cifs_inode->cifsAttrs = 0x20; /* default */
303 atomic_set(&cifs_inode->inUse, 0);
304 cifs_inode->time = 0;
cea21805 305 cifs_inode->write_behind_rc = 0;
1da177e4
LT
306 /* Until the file is open and we have gotten oplock
307 info back from the server, can not assume caching of
308 file data or metadata */
309 cifs_inode->clientCanCacheRead = FALSE;
310 cifs_inode->clientCanCacheAll = FALSE;
1da177e4 311 cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */
50c2f753 312
1b2b2126
SF
313 /* Can not set i_flags here - they get immediately overwritten
314 to zero by the VFS */
315/* cifs_inode->vfs_inode.i_flags = S_NOATIME | S_NOCMTIME;*/
1da177e4
LT
316 INIT_LIST_HEAD(&cifs_inode->openFileList);
317 return &cifs_inode->vfs_inode;
318}
319
320static void
321cifs_destroy_inode(struct inode *inode)
322{
323 kmem_cache_free(cifs_inode_cachep, CIFS_I(inode));
324}
325
326/*
327 * cifs_show_options() is for displaying mount options in /proc/mounts.
328 * Not all settable options are displayed but most of the important
329 * ones are.
330 */
331static int
332cifs_show_options(struct seq_file *s, struct vfsmount *m)
333{
334 struct cifs_sb_info *cifs_sb;
335
336 cifs_sb = CIFS_SB(m->mnt_sb);
337
338 if (cifs_sb) {
339 if (cifs_sb->tcon) {
004c46b9 340/* BB add prepath to mount options displayed */
1da177e4
LT
341 seq_printf(s, ",unc=%s", cifs_sb->tcon->treeName);
342 if (cifs_sb->tcon->ses) {
343 if (cifs_sb->tcon->ses->userName)
344 seq_printf(s, ",username=%s",
345 cifs_sb->tcon->ses->userName);
4523cc30 346 if (cifs_sb->tcon->ses->domainName)
1da177e4
LT
347 seq_printf(s, ",domain=%s",
348 cifs_sb->tcon->ses->domainName);
349 }
d5d18501
SF
350 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) ||
351 !(cifs_sb->tcon->unix_ext))
352 seq_printf(s, ",uid=%d", cifs_sb->mnt_uid);
353 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) ||
354 !(cifs_sb->tcon->unix_ext))
355 seq_printf(s, ",gid=%d", cifs_sb->mnt_gid);
1da177e4 356 }
4523cc30
SF
357 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
358 seq_printf(s, ",posixpaths");
50c2f753
SF
359 seq_printf(s, ",rsize=%d", cifs_sb->rsize);
360 seq_printf(s, ",wsize=%d", cifs_sb->wsize);
1da177e4
LT
361 }
362 return 0;
363}
364
365#ifdef CONFIG_CIFS_QUOTA
50c2f753
SF
366int cifs_xquota_set(struct super_block *sb, int quota_type, qid_t qid,
367 struct fs_disk_quota *pdquota)
1da177e4
LT
368{
369 int xid;
370 int rc = 0;
371 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
372 struct cifsTconInfo *pTcon;
50c2f753 373
4523cc30 374 if (cifs_sb)
1da177e4
LT
375 pTcon = cifs_sb->tcon;
376 else
377 return -EIO;
378
379
380 xid = GetXid();
4523cc30 381 if (pTcon) {
50c2f753 382 cFYI(1, ("set type: 0x%x id: %d", quota_type, qid));
1da177e4 383 } else {
95ba7362 384 rc = -EIO;
1da177e4
LT
385 }
386
387 FreeXid(xid);
388 return rc;
389}
390
50c2f753
SF
391int cifs_xquota_get(struct super_block *sb, int quota_type, qid_t qid,
392 struct fs_disk_quota *pdquota)
1da177e4
LT
393{
394 int xid;
395 int rc = 0;
396 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
397 struct cifsTconInfo *pTcon;
398
4523cc30 399 if (cifs_sb)
1da177e4
LT
400 pTcon = cifs_sb->tcon;
401 else
402 return -EIO;
403
404 xid = GetXid();
4523cc30 405 if (pTcon) {
50c2f753 406 cFYI(1, ("set type: 0x%x id: %d", quota_type, qid));
1da177e4
LT
407 } else {
408 rc = -EIO;
409 }
410
411 FreeXid(xid);
412 return rc;
413}
414
50c2f753 415int cifs_xstate_set(struct super_block *sb, unsigned int flags, int operation)
1da177e4 416{
50c2f753 417 int xid;
1da177e4
LT
418 int rc = 0;
419 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
420 struct cifsTconInfo *pTcon;
421
4523cc30 422 if (cifs_sb)
1da177e4
LT
423 pTcon = cifs_sb->tcon;
424 else
425 return -EIO;
426
427 xid = GetXid();
4523cc30 428 if (pTcon) {
50c2f753 429 cFYI(1, ("flags: 0x%x operation: 0x%x", flags, operation));
1da177e4
LT
430 } else {
431 rc = -EIO;
432 }
433
434 FreeXid(xid);
435 return rc;
436}
437
50c2f753 438int cifs_xstate_get(struct super_block *sb, struct fs_quota_stat *qstats)
1da177e4
LT
439{
440 int xid;
441 int rc = 0;
442 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
443 struct cifsTconInfo *pTcon;
444
4523cc30 445 if (cifs_sb) {
1da177e4
LT
446 pTcon = cifs_sb->tcon;
447 } else {
448 return -EIO;
449 }
450 xid = GetXid();
4523cc30 451 if (pTcon) {
50c2f753 452 cFYI(1, ("pqstats %p", qstats));
1da177e4
LT
453 } else {
454 rc = -EIO;
455 }
456
457 FreeXid(xid);
458 return rc;
459}
460
461static struct quotactl_ops cifs_quotactl_ops = {
462 .set_xquota = cifs_xquota_set,
463 .get_xquota = cifs_xquota_set,
464 .set_xstate = cifs_xstate_set,
465 .get_xstate = cifs_xstate_get,
466};
467#endif
468
50c2f753 469static void cifs_umount_begin(struct vfsmount *vfsmnt, int flags)
68058e75 470{
5e1253b5 471 struct cifs_sb_info *cifs_sb;
50c2f753 472 struct cifsTconInfo *tcon;
68058e75 473
6d5ae0de
IM
474#ifdef CONFIG_CIFS_DFS_UPCALL
475 dfs_shrink_umount_helper(vfsmnt);
476#endif /* CONFIG CIFS_DFS_UPCALL */
477
8b512d9a
TM
478 if (!(flags & MNT_FORCE))
479 return;
480 cifs_sb = CIFS_SB(vfsmnt->mnt_sb);
4523cc30 481 if (cifs_sb == NULL)
9e2e85f8
SF
482 return;
483
484 tcon = cifs_sb->tcon;
4523cc30 485 if (tcon == NULL)
9e2e85f8 486 return;
5e1253b5
SF
487 down(&tcon->tconSem);
488 if (atomic_read(&tcon->useCount) == 1)
489 tcon->tidStatus = CifsExiting;
490 up(&tcon->tconSem);
491
3a5ff61c 492 /* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */
7b7abfe3 493 /* cancel_notify_requests(tcon); */
50c2f753
SF
494 if (tcon->ses && tcon->ses->server) {
495 cFYI(1, ("wake up tasks now - umount begin not complete"));
9e2e85f8 496 wake_up_all(&tcon->ses->server->request_q);
6ab16d24
SF
497 wake_up_all(&tcon->ses->server->response_q);
498 msleep(1); /* yield */
499 /* we have to kick the requests once more */
500 wake_up_all(&tcon->ses->server->response_q);
501 msleep(1);
5e1253b5
SF
502 }
503/* BB FIXME - finish add checks for tidStatus BB */
68058e75
SF
504
505 return;
506}
68058e75 507
bf97d287
SF
508#ifdef CONFIG_CIFS_STATS2
509static int cifs_show_stats(struct seq_file *s, struct vfsmount *mnt)
510{
511 /* BB FIXME */
512 return 0;
513}
514#endif
515
1da177e4
LT
516static int cifs_remount(struct super_block *sb, int *flags, char *data)
517{
518 *flags |= MS_NODIRATIME;
519 return 0;
520}
521
ee9b6d61 522static const struct super_operations cifs_super_ops = {
1da177e4
LT
523 .read_inode = cifs_read_inode,
524 .put_super = cifs_put_super,
525 .statfs = cifs_statfs,
526 .alloc_inode = cifs_alloc_inode,
527 .destroy_inode = cifs_destroy_inode,
50c2f753
SF
528/* .drop_inode = generic_delete_inode,
529 .delete_inode = cifs_delete_inode, */ /* Do not need above two
530 functions unless later we add lazy close of inodes or unless the
531 kernel forgets to call us with the same number of releases (closes)
532 as opens */
1da177e4 533 .show_options = cifs_show_options,
7b7abfe3 534 .umount_begin = cifs_umount_begin,
1da177e4 535 .remount_fs = cifs_remount,
bf97d287 536#ifdef CONFIG_CIFS_STATS2
f46d3e11 537 .show_stats = cifs_show_stats,
bf97d287 538#endif
1da177e4
LT
539};
540
454e2398 541static int
1da177e4 542cifs_get_sb(struct file_system_type *fs_type,
454e2398 543 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
1da177e4
LT
544{
545 int rc;
546 struct super_block *sb = sget(fs_type, NULL, set_anon_super, NULL);
547
548 cFYI(1, ("Devname: %s flags: %d ", dev_name, flags));
549
550 if (IS_ERR(sb))
454e2398 551 return PTR_ERR(sb);
1da177e4
LT
552
553 sb->s_flags = flags;
554
9b04c997 555 rc = cifs_read_super(sb, data, dev_name, flags & MS_SILENT ? 1 : 0);
1da177e4
LT
556 if (rc) {
557 up_write(&sb->s_umount);
558 deactivate_super(sb);
454e2398 559 return rc;
1da177e4
LT
560 }
561 sb->s_flags |= MS_ACTIVE;
454e2398 562 return simple_set_mnt(mnt, sb);
1da177e4
LT
563}
564
027445c3
BP
565static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
566 unsigned long nr_segs, loff_t pos)
1da177e4 567{
e6a00296 568 struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode;
1da177e4
LT
569 ssize_t written;
570
027445c3 571 written = generic_file_aio_write(iocb, iov, nr_segs, pos);
87c89dd7
SF
572 if (!CIFS_I(inode)->clientCanCacheAll)
573 filemap_fdatawrite(inode->i_mapping);
1da177e4
LT
574 return written;
575}
576
c32a0b68
SF
577static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
578{
579 /* origin == SEEK_END => we must revalidate the cached file length */
0889a944 580 if (origin == SEEK_END) {
030e9d81
SF
581 int retval;
582
583 /* some applications poll for the file length in this strange
584 way so we must seek to end on non-oplocked files by
585 setting the revalidate time to zero */
c33f8d32 586 CIFS_I(file->f_path.dentry->d_inode)->time = 0;
030e9d81
SF
587
588 retval = cifs_revalidate(file->f_path.dentry);
c32a0b68
SF
589 if (retval < 0)
590 return (loff_t)retval;
591 }
592 return remote_llseek(file, offset, origin);
593}
594
e6ab1582 595struct file_system_type cifs_fs_type = {
1da177e4
LT
596 .owner = THIS_MODULE,
597 .name = "cifs",
598 .get_sb = cifs_get_sb,
599 .kill_sb = kill_anon_super,
600 /* .fs_flags */
601};
754661f1 602const struct inode_operations cifs_dir_inode_ops = {
1da177e4
LT
603 .create = cifs_create,
604 .lookup = cifs_lookup,
605 .getattr = cifs_getattr,
606 .unlink = cifs_unlink,
607 .link = cifs_hardlink,
608 .mkdir = cifs_mkdir,
609 .rmdir = cifs_rmdir,
610 .rename = cifs_rename,
611 .permission = cifs_permission,
612/* revalidate:cifs_revalidate, */
613 .setattr = cifs_setattr,
614 .symlink = cifs_symlink,
615 .mknod = cifs_mknod,
616#ifdef CONFIG_CIFS_XATTR
617 .setxattr = cifs_setxattr,
618 .getxattr = cifs_getxattr,
619 .listxattr = cifs_listxattr,
620 .removexattr = cifs_removexattr,
621#endif
622};
623
754661f1 624const struct inode_operations cifs_file_inode_ops = {
1da177e4
LT
625/* revalidate:cifs_revalidate, */
626 .setattr = cifs_setattr,
627 .getattr = cifs_getattr, /* do we need this anymore? */
628 .rename = cifs_rename,
629 .permission = cifs_permission,
630#ifdef CONFIG_CIFS_XATTR
631 .setxattr = cifs_setxattr,
632 .getxattr = cifs_getxattr,
633 .listxattr = cifs_listxattr,
634 .removexattr = cifs_removexattr,
50c2f753 635#endif
1da177e4
LT
636};
637
754661f1 638const struct inode_operations cifs_symlink_inode_ops = {
50c2f753 639 .readlink = generic_readlink,
1da177e4
LT
640 .follow_link = cifs_follow_link,
641 .put_link = cifs_put_link,
642 .permission = cifs_permission,
643 /* BB add the following two eventually */
644 /* revalidate: cifs_revalidate,
645 setattr: cifs_notify_change, *//* BB do we need notify change */
646#ifdef CONFIG_CIFS_XATTR
647 .setxattr = cifs_setxattr,
648 .getxattr = cifs_getxattr,
649 .listxattr = cifs_listxattr,
650 .removexattr = cifs_removexattr,
50c2f753 651#endif
1da177e4
LT
652};
653
4b6f5d20 654const struct file_operations cifs_file_ops = {
87c89dd7
SF
655 .read = do_sync_read,
656 .write = do_sync_write,
87c89dd7
SF
657 .aio_read = generic_file_aio_read,
658 .aio_write = cifs_file_aio_write,
1da177e4
LT
659 .open = cifs_open,
660 .release = cifs_close,
661 .lock = cifs_lock,
662 .fsync = cifs_fsync,
663 .flush = cifs_flush,
664 .mmap = cifs_file_mmap,
5ffc4ef4 665 .splice_read = generic_file_splice_read,
c32a0b68 666 .llseek = cifs_llseek,
c67593a0
SF
667#ifdef CONFIG_CIFS_POSIX
668 .ioctl = cifs_ioctl,
669#endif /* CONFIG_CIFS_POSIX */
670
1da177e4 671#ifdef CONFIG_CIFS_EXPERIMENTAL
1da177e4
LT
672 .dir_notify = cifs_dir_notify,
673#endif /* CONFIG_CIFS_EXPERIMENTAL */
674};
675
4b6f5d20 676const struct file_operations cifs_file_direct_ops = {
50c2f753 677 /* no mmap, no aio, no readv -
1da177e4
LT
678 BB reevaluate whether they can be done with directio, no cache */
679 .read = cifs_user_read,
680 .write = cifs_user_write,
681 .open = cifs_open,
682 .release = cifs_close,
683 .lock = cifs_lock,
684 .fsync = cifs_fsync,
685 .flush = cifs_flush,
5ffc4ef4 686 .splice_read = generic_file_splice_read,
c67593a0
SF
687#ifdef CONFIG_CIFS_POSIX
688 .ioctl = cifs_ioctl,
689#endif /* CONFIG_CIFS_POSIX */
c32a0b68 690 .llseek = cifs_llseek,
1da177e4
LT
691#ifdef CONFIG_CIFS_EXPERIMENTAL
692 .dir_notify = cifs_dir_notify,
693#endif /* CONFIG_CIFS_EXPERIMENTAL */
694};
4b6f5d20 695const struct file_operations cifs_file_nobrl_ops = {
87c89dd7
SF
696 .read = do_sync_read,
697 .write = do_sync_write,
87c89dd7
SF
698 .aio_read = generic_file_aio_read,
699 .aio_write = cifs_file_aio_write,
700 .open = cifs_open,
701 .release = cifs_close,
702 .fsync = cifs_fsync,
703 .flush = cifs_flush,
704 .mmap = cifs_file_mmap,
5ffc4ef4 705 .splice_read = generic_file_splice_read,
c32a0b68 706 .llseek = cifs_llseek,
8b94bcb9 707#ifdef CONFIG_CIFS_POSIX
87c89dd7 708 .ioctl = cifs_ioctl,
8b94bcb9
SF
709#endif /* CONFIG_CIFS_POSIX */
710
711#ifdef CONFIG_CIFS_EXPERIMENTAL
87c89dd7 712 .dir_notify = cifs_dir_notify,
8b94bcb9
SF
713#endif /* CONFIG_CIFS_EXPERIMENTAL */
714};
715
4b6f5d20 716const struct file_operations cifs_file_direct_nobrl_ops = {
50c2f753 717 /* no mmap, no aio, no readv -
87c89dd7
SF
718 BB reevaluate whether they can be done with directio, no cache */
719 .read = cifs_user_read,
720 .write = cifs_user_write,
721 .open = cifs_open,
722 .release = cifs_close,
723 .fsync = cifs_fsync,
724 .flush = cifs_flush,
5ffc4ef4 725 .splice_read = generic_file_splice_read,
8b94bcb9 726#ifdef CONFIG_CIFS_POSIX
87c89dd7 727 .ioctl = cifs_ioctl,
8b94bcb9 728#endif /* CONFIG_CIFS_POSIX */
c32a0b68 729 .llseek = cifs_llseek,
8b94bcb9 730#ifdef CONFIG_CIFS_EXPERIMENTAL
87c89dd7 731 .dir_notify = cifs_dir_notify,
8b94bcb9
SF
732#endif /* CONFIG_CIFS_EXPERIMENTAL */
733};
1da177e4 734
4b6f5d20 735const struct file_operations cifs_dir_ops = {
1da177e4
LT
736 .readdir = cifs_readdir,
737 .release = cifs_closedir,
738 .read = generic_read_dir,
739#ifdef CONFIG_CIFS_EXPERIMENTAL
740 .dir_notify = cifs_dir_notify,
741#endif /* CONFIG_CIFS_EXPERIMENTAL */
50c2f753 742 .ioctl = cifs_ioctl,
1da177e4
LT
743};
744
745static void
4ba9b9d0 746cifs_init_once(struct kmem_cache *cachep, void *inode)
1da177e4
LT
747{
748 struct cifsInodeInfo *cifsi = inode;
749
a35afb83
CL
750 inode_init_once(&cifsi->vfs_inode);
751 INIT_LIST_HEAD(&cifsi->lockList);
1da177e4
LT
752}
753
754static int
755cifs_init_inodecache(void)
756{
757 cifs_inode_cachep = kmem_cache_create("cifs_inode_cache",
26f57364 758 sizeof(struct cifsInodeInfo),
fffb60f9
PJ
759 0, (SLAB_RECLAIM_ACCOUNT|
760 SLAB_MEM_SPREAD),
20c2df83 761 cifs_init_once);
1da177e4
LT
762 if (cifs_inode_cachep == NULL)
763 return -ENOMEM;
764
765 return 0;
766}
767
768static void
769cifs_destroy_inodecache(void)
770{
1a1d92c1 771 kmem_cache_destroy(cifs_inode_cachep);
1da177e4
LT
772}
773
774static int
775cifs_init_request_bufs(void)
776{
4523cc30 777 if (CIFSMaxBufSize < 8192) {
1da177e4
LT
778 /* Buffer size can not be smaller than 2 * PATH_MAX since maximum
779 Unicode path name has to fit in any SMB/CIFS path based frames */
780 CIFSMaxBufSize = 8192;
781 } else if (CIFSMaxBufSize > 1024*127) {
782 CIFSMaxBufSize = 1024 * 127;
783 } else {
784 CIFSMaxBufSize &= 0x1FE00; /* Round size to even 512 byte mult*/
785 }
786/* cERROR(1,("CIFSMaxBufSize %d 0x%x",CIFSMaxBufSize,CIFSMaxBufSize)); */
787 cifs_req_cachep = kmem_cache_create("cifs_request",
788 CIFSMaxBufSize +
789 MAX_CIFS_HDR_SIZE, 0,
20c2df83 790 SLAB_HWCACHE_ALIGN, NULL);
1da177e4
LT
791 if (cifs_req_cachep == NULL)
792 return -ENOMEM;
793
4523cc30 794 if (cifs_min_rcv < 1)
1da177e4
LT
795 cifs_min_rcv = 1;
796 else if (cifs_min_rcv > 64) {
797 cifs_min_rcv = 64;
50c2f753 798 cERROR(1, ("cifs_min_rcv set to maximum (64)"));
1da177e4
LT
799 }
800
93d2341c
MD
801 cifs_req_poolp = mempool_create_slab_pool(cifs_min_rcv,
802 cifs_req_cachep);
1da177e4 803
4523cc30 804 if (cifs_req_poolp == NULL) {
1da177e4
LT
805 kmem_cache_destroy(cifs_req_cachep);
806 return -ENOMEM;
807 }
ec637e3f 808 /* MAX_CIFS_SMALL_BUFFER_SIZE bytes is enough for most SMB responses and
1da177e4
LT
809 almost all handle based requests (but not write response, nor is it
810 sufficient for path based requests). A smaller size would have
50c2f753 811 been more efficient (compacting multiple slab items on one 4k page)
1da177e4
LT
812 for the case in which debug was on, but this larger size allows
813 more SMBs to use small buffer alloc and is still much more
6dc0f87e 814 efficient to alloc 1 per page off the slab compared to 17K (5page)
1da177e4
LT
815 alloc of large cifs buffers even when page debugging is on */
816 cifs_sm_req_cachep = kmem_cache_create("cifs_small_rq",
6dc0f87e 817 MAX_CIFS_SMALL_BUFFER_SIZE, 0, SLAB_HWCACHE_ALIGN,
20c2df83 818 NULL);
1da177e4
LT
819 if (cifs_sm_req_cachep == NULL) {
820 mempool_destroy(cifs_req_poolp);
821 kmem_cache_destroy(cifs_req_cachep);
6dc0f87e 822 return -ENOMEM;
1da177e4
LT
823 }
824
4523cc30 825 if (cifs_min_small < 2)
1da177e4
LT
826 cifs_min_small = 2;
827 else if (cifs_min_small > 256) {
828 cifs_min_small = 256;
6dc0f87e 829 cFYI(1, ("cifs_min_small set to maximum (256)"));
1da177e4
LT
830 }
831
93d2341c
MD
832 cifs_sm_req_poolp = mempool_create_slab_pool(cifs_min_small,
833 cifs_sm_req_cachep);
1da177e4 834
4523cc30 835 if (cifs_sm_req_poolp == NULL) {
1da177e4
LT
836 mempool_destroy(cifs_req_poolp);
837 kmem_cache_destroy(cifs_req_cachep);
838 kmem_cache_destroy(cifs_sm_req_cachep);
839 return -ENOMEM;
840 }
841
842 return 0;
843}
844
845static void
846cifs_destroy_request_bufs(void)
847{
848 mempool_destroy(cifs_req_poolp);
1a1d92c1 849 kmem_cache_destroy(cifs_req_cachep);
1da177e4 850 mempool_destroy(cifs_sm_req_poolp);
1a1d92c1 851 kmem_cache_destroy(cifs_sm_req_cachep);
1da177e4
LT
852}
853
854static int
855cifs_init_mids(void)
856{
857 cifs_mid_cachep = kmem_cache_create("cifs_mpx_ids",
26f57364
SF
858 sizeof(struct mid_q_entry), 0,
859 SLAB_HWCACHE_ALIGN, NULL);
1da177e4
LT
860 if (cifs_mid_cachep == NULL)
861 return -ENOMEM;
862
93d2341c
MD
863 /* 3 is a reasonable minimum number of simultaneous operations */
864 cifs_mid_poolp = mempool_create_slab_pool(3, cifs_mid_cachep);
4523cc30 865 if (cifs_mid_poolp == NULL) {
1da177e4
LT
866 kmem_cache_destroy(cifs_mid_cachep);
867 return -ENOMEM;
868 }
869
870 cifs_oplock_cachep = kmem_cache_create("cifs_oplock_structs",
26f57364
SF
871 sizeof(struct oplock_q_entry), 0,
872 SLAB_HWCACHE_ALIGN, NULL);
1da177e4 873 if (cifs_oplock_cachep == NULL) {
1da177e4 874 mempool_destroy(cifs_mid_poolp);
e6985c7f 875 kmem_cache_destroy(cifs_mid_cachep);
1da177e4
LT
876 return -ENOMEM;
877 }
878
879 return 0;
880}
881
882static void
883cifs_destroy_mids(void)
884{
885 mempool_destroy(cifs_mid_poolp);
1a1d92c1
AD
886 kmem_cache_destroy(cifs_mid_cachep);
887 kmem_cache_destroy(cifs_oplock_cachep);
1da177e4
LT
888}
889
50c2f753 890static int cifs_oplock_thread(void *dummyarg)
1da177e4 891{
6dc0f87e 892 struct oplock_q_entry *oplock_item;
1da177e4 893 struct cifsTconInfo *pTcon;
6dc0f87e 894 struct inode *inode;
1da177e4 895 __u16 netfid;
cea21805 896 int rc, waitrc = 0;
1da177e4 897
83144186 898 set_freezable();
1da177e4 899 do {
6dc0f87e 900 if (try_to_freeze())
ede1327e 901 continue;
50c2f753 902
1da177e4 903 spin_lock(&GlobalMid_Lock);
4523cc30 904 if (list_empty(&GlobalOplock_Q)) {
1da177e4
LT
905 spin_unlock(&GlobalMid_Lock);
906 set_current_state(TASK_INTERRUPTIBLE);
907 schedule_timeout(39*HZ);
908 } else {
6dc0f87e 909 oplock_item = list_entry(GlobalOplock_Q.next,
1da177e4 910 struct oplock_q_entry, qhead);
4523cc30 911 if (oplock_item) {
50c2f753 912 cFYI(1, ("found oplock item to write out"));
1da177e4
LT
913 pTcon = oplock_item->tcon;
914 inode = oplock_item->pinode;
915 netfid = oplock_item->netfid;
916 spin_unlock(&GlobalMid_Lock);
917 DeleteOplockQEntry(oplock_item);
918 /* can not grab inode sem here since it would
6dc0f87e 919 deadlock when oplock received on delete
1b1dcc1b 920 since vfs_unlink holds the i_mutex across
1da177e4 921 the call */
1b1dcc1b 922 /* mutex_lock(&inode->i_mutex);*/
1da177e4 923 if (S_ISREG(inode->i_mode)) {
26f57364
SF
924 rc =
925 filemap_fdatawrite(inode->i_mapping);
50c2f753
SF
926 if (CIFS_I(inode)->clientCanCacheRead
927 == 0) {
cea21805 928 waitrc = filemap_fdatawait(inode->i_mapping);
1da177e4
LT
929 invalidate_remote_inode(inode);
930 }
cea21805
JL
931 if (rc == 0)
932 rc = waitrc;
1da177e4
LT
933 } else
934 rc = 0;
1b1dcc1b 935 /* mutex_unlock(&inode->i_mutex);*/
1da177e4
LT
936 if (rc)
937 CIFS_I(inode)->write_behind_rc = rc;
6dc0f87e
SF
938 cFYI(1, ("Oplock flush inode %p rc %d",
939 inode, rc));
940
941 /* releasing stale oplock after recent reconnect
942 of smb session using a now incorrect file
943 handle is not a data integrity issue but do
944 not bother sending an oplock release if session
945 to server still is disconnected since oplock
1da177e4 946 already released by the server in that case */
4523cc30 947 if (pTcon->tidStatus != CifsNeedReconnect) {
1da177e4 948 rc = CIFSSMBLock(0, pTcon, netfid,
6dc0f87e 949 0 /* len */ , 0 /* offset */, 0,
1da177e4
LT
950 0, LOCKING_ANDX_OPLOCK_RELEASE,
951 0 /* wait flag */);
26f57364 952 cFYI(1, ("Oplock release rc = %d", rc));
1da177e4
LT
953 }
954 } else
955 spin_unlock(&GlobalMid_Lock);
68058e75
SF
956 set_current_state(TASK_INTERRUPTIBLE);
957 schedule_timeout(1); /* yield in case q were corrupt */
1da177e4 958 }
45af7a0f
SF
959 } while (!kthread_should_stop());
960
961 return 0;
1da177e4
LT
962}
963
50c2f753 964static int cifs_dnotify_thread(void *dummyarg)
8d0d5094 965{
6ab16d24
SF
966 struct list_head *tmp;
967 struct cifsSesInfo *ses;
968
8d0d5094 969 do {
0fd1ffe0 970 if (try_to_freeze())
16abbecd 971 continue;
8d0d5094 972 set_current_state(TASK_INTERRUPTIBLE);
6ab16d24
SF
973 schedule_timeout(15*HZ);
974 read_lock(&GlobalSMBSeslock);
975 /* check if any stuck requests that need
976 to be woken up and wakeq so the
977 thread can wake up and error out */
978 list_for_each(tmp, &GlobalSMBSessionList) {
6dc0f87e 979 ses = list_entry(tmp, struct cifsSesInfo,
6ab16d24 980 cifsSessionList);
6dc0f87e 981 if (ses && ses->server &&
2a138ebb 982 atomic_read(&ses->server->inFlight))
6ab16d24
SF
983 wake_up_all(&ses->server->response_q);
984 }
985 read_unlock(&GlobalSMBSeslock);
45af7a0f
SF
986 } while (!kthread_should_stop());
987
988 return 0;
1da177e4
LT
989}
990
991static int __init
992init_cifs(void)
993{
994 int rc = 0;
995#ifdef CONFIG_PROC_FS
996 cifs_proc_init();
997#endif
2cd646a2 998/* INIT_LIST_HEAD(&GlobalServerList);*/ /* BB not implemented yet */
1da177e4
LT
999 INIT_LIST_HEAD(&GlobalSMBSessionList);
1000 INIT_LIST_HEAD(&GlobalTreeConnectionList);
1001 INIT_LIST_HEAD(&GlobalOplock_Q);
4ca9c190
SF
1002#ifdef CONFIG_CIFS_EXPERIMENTAL
1003 INIT_LIST_HEAD(&GlobalDnotifyReqList);
1004 INIT_LIST_HEAD(&GlobalDnotifyRsp_Q);
6dc0f87e 1005#endif
1da177e4
LT
1006/*
1007 * Initialize Global counters
1008 */
1009 atomic_set(&sesInfoAllocCount, 0);
1010 atomic_set(&tconInfoAllocCount, 0);
6dc0f87e 1011 atomic_set(&tcpSesAllocCount, 0);
1da177e4
LT
1012 atomic_set(&tcpSesReconnectCount, 0);
1013 atomic_set(&tconInfoReconnectCount, 0);
1014
1015 atomic_set(&bufAllocCount, 0);
4498eed5
SF
1016 atomic_set(&smBufAllocCount, 0);
1017#ifdef CONFIG_CIFS_STATS2
1018 atomic_set(&totBufAllocCount, 0);
1019 atomic_set(&totSmBufAllocCount, 0);
1020#endif /* CONFIG_CIFS_STATS2 */
1021
1da177e4
LT
1022 atomic_set(&midCount, 0);
1023 GlobalCurrentXid = 0;
1024 GlobalTotalActiveXid = 0;
1025 GlobalMaxActiveXid = 0;
2cd646a2 1026 memset(Local_System_Name, 0, 15);
1da177e4
LT
1027 rwlock_init(&GlobalSMBSeslock);
1028 spin_lock_init(&GlobalMid_Lock);
1029
4523cc30 1030 if (cifs_max_pending < 2) {
1da177e4 1031 cifs_max_pending = 2;
6dc0f87e 1032 cFYI(1, ("cifs_max_pending set to min of 2"));
4523cc30 1033 } else if (cifs_max_pending > 256) {
1da177e4 1034 cifs_max_pending = 256;
6dc0f87e 1035 cFYI(1, ("cifs_max_pending set to max of 256"));
1da177e4
LT
1036 }
1037
1038 rc = cifs_init_inodecache();
45af7a0f
SF
1039 if (rc)
1040 goto out_clean_proc;
1041
1042 rc = cifs_init_mids();
1043 if (rc)
1044 goto out_destroy_inodecache;
1045
1046 rc = cifs_init_request_bufs();
1047 if (rc)
1048 goto out_destroy_mids;
1049
1050 rc = register_filesystem(&cifs_fs_type);
1051 if (rc)
1052 goto out_destroy_request_bufs;
84a15b93
JL
1053#ifdef CONFIG_CIFS_UPCALL
1054 rc = register_key_type(&cifs_spnego_key_type);
1055 if (rc)
1056 goto out_unregister_filesystem;
6103335d
SF
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;
84a15b93 1062#endif
45af7a0f
SF
1063 oplockThread = kthread_run(cifs_oplock_thread, NULL, "cifsoplockd");
1064 if (IS_ERR(oplockThread)) {
1065 rc = PTR_ERR(oplockThread);
6dc0f87e 1066 cERROR(1, ("error %d create oplock thread", rc));
6103335d 1067 goto out_unregister_dfs_key_type;
1da177e4 1068 }
45af7a0f
SF
1069
1070 dnotifyThread = kthread_run(cifs_dnotify_thread, NULL, "cifsdnotifyd");
1071 if (IS_ERR(dnotifyThread)) {
1072 rc = PTR_ERR(dnotifyThread);
6dc0f87e 1073 cERROR(1, ("error %d create dnotify thread", rc));
45af7a0f
SF
1074 goto out_stop_oplock_thread;
1075 }
1076
1077 return 0;
1078
1079 out_stop_oplock_thread:
1080 kthread_stop(oplockThread);
6103335d
SF
1081 out_unregister_dfs_key_type:
1082#ifdef CONFIG_CIFS_DFS_UPCALL
1083 unregister_key_type(&key_type_dns_resolver);
84a15b93 1084 out_unregister_key_type:
6103335d 1085#endif
84a15b93
JL
1086#ifdef CONFIG_CIFS_UPCALL
1087 unregister_key_type(&cifs_spnego_key_type);
45af7a0f 1088 out_unregister_filesystem:
84a15b93 1089#endif
45af7a0f
SF
1090 unregister_filesystem(&cifs_fs_type);
1091 out_destroy_request_bufs:
1092 cifs_destroy_request_bufs();
1093 out_destroy_mids:
1094 cifs_destroy_mids();
1095 out_destroy_inodecache:
1096 cifs_destroy_inodecache();
1097 out_clean_proc:
1da177e4
LT
1098#ifdef CONFIG_PROC_FS
1099 cifs_proc_clean();
1100#endif
1101 return rc;
1102}
1103
1104static void __exit
1105exit_cifs(void)
1106{
63135e08 1107 cFYI(0, ("exit_cifs"));
1da177e4
LT
1108#ifdef CONFIG_PROC_FS
1109 cifs_proc_clean();
84a15b93 1110#endif
6103335d
SF
1111#ifdef CONFIG_CIFS_DFS_UPCALL
1112 unregister_key_type(&key_type_dns_resolver);
1113#endif
84a15b93
JL
1114#ifdef CONFIG_CIFS_UPCALL
1115 unregister_key_type(&cifs_spnego_key_type);
1da177e4
LT
1116#endif
1117 unregister_filesystem(&cifs_fs_type);
1118 cifs_destroy_inodecache();
1119 cifs_destroy_mids();
1120 cifs_destroy_request_bufs();
45af7a0f
SF
1121 kthread_stop(oplockThread);
1122 kthread_stop(dnotifyThread);
1da177e4
LT
1123}
1124
1125MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>");
6dc0f87e 1126MODULE_LICENSE("GPL"); /* combination of LGPL + GPL source behaves as GPL */
1da177e4 1127MODULE_DESCRIPTION
63135e08
SF
1128 ("VFS to access servers complying with the SNIA CIFS Specification "
1129 "e.g. Samba and Windows");
1da177e4
LT
1130MODULE_VERSION(CIFS_VERSION);
1131module_init(init_cifs)
1132module_exit(exit_cifs)