]> bbs.cooldavid.org Git - net-next-2.6.git/blame - fs/cifs/cifsfs.c
[CIFS] Do not log path names in lookup errors
[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
8b512d9a
TM
474 if (!(flags & MNT_FORCE))
475 return;
476 cifs_sb = CIFS_SB(vfsmnt->mnt_sb);
4523cc30 477 if (cifs_sb == NULL)
9e2e85f8
SF
478 return;
479
480 tcon = cifs_sb->tcon;
4523cc30 481 if (tcon == NULL)
9e2e85f8 482 return;
5e1253b5
SF
483 down(&tcon->tconSem);
484 if (atomic_read(&tcon->useCount) == 1)
485 tcon->tidStatus = CifsExiting;
486 up(&tcon->tconSem);
487
3a5ff61c 488 /* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */
7b7abfe3 489 /* cancel_notify_requests(tcon); */
50c2f753
SF
490 if (tcon->ses && tcon->ses->server) {
491 cFYI(1, ("wake up tasks now - umount begin not complete"));
9e2e85f8 492 wake_up_all(&tcon->ses->server->request_q);
6ab16d24
SF
493 wake_up_all(&tcon->ses->server->response_q);
494 msleep(1); /* yield */
495 /* we have to kick the requests once more */
496 wake_up_all(&tcon->ses->server->response_q);
497 msleep(1);
5e1253b5
SF
498 }
499/* BB FIXME - finish add checks for tidStatus BB */
68058e75
SF
500
501 return;
502}
68058e75 503
bf97d287
SF
504#ifdef CONFIG_CIFS_STATS2
505static int cifs_show_stats(struct seq_file *s, struct vfsmount *mnt)
506{
507 /* BB FIXME */
508 return 0;
509}
510#endif
511
1da177e4
LT
512static int cifs_remount(struct super_block *sb, int *flags, char *data)
513{
514 *flags |= MS_NODIRATIME;
515 return 0;
516}
517
ee9b6d61 518static const struct super_operations cifs_super_ops = {
1da177e4
LT
519 .read_inode = cifs_read_inode,
520 .put_super = cifs_put_super,
521 .statfs = cifs_statfs,
522 .alloc_inode = cifs_alloc_inode,
523 .destroy_inode = cifs_destroy_inode,
50c2f753
SF
524/* .drop_inode = generic_delete_inode,
525 .delete_inode = cifs_delete_inode, */ /* Do not need above two
526 functions unless later we add lazy close of inodes or unless the
527 kernel forgets to call us with the same number of releases (closes)
528 as opens */
1da177e4 529 .show_options = cifs_show_options,
7b7abfe3 530 .umount_begin = cifs_umount_begin,
1da177e4 531 .remount_fs = cifs_remount,
bf97d287 532#ifdef CONFIG_CIFS_STATS2
f46d3e11 533 .show_stats = cifs_show_stats,
bf97d287 534#endif
1da177e4
LT
535};
536
454e2398 537static int
1da177e4 538cifs_get_sb(struct file_system_type *fs_type,
454e2398 539 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
1da177e4
LT
540{
541 int rc;
542 struct super_block *sb = sget(fs_type, NULL, set_anon_super, NULL);
543
544 cFYI(1, ("Devname: %s flags: %d ", dev_name, flags));
545
546 if (IS_ERR(sb))
454e2398 547 return PTR_ERR(sb);
1da177e4
LT
548
549 sb->s_flags = flags;
550
9b04c997 551 rc = cifs_read_super(sb, data, dev_name, flags & MS_SILENT ? 1 : 0);
1da177e4
LT
552 if (rc) {
553 up_write(&sb->s_umount);
554 deactivate_super(sb);
454e2398 555 return rc;
1da177e4
LT
556 }
557 sb->s_flags |= MS_ACTIVE;
454e2398 558 return simple_set_mnt(mnt, sb);
1da177e4
LT
559}
560
027445c3
BP
561static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
562 unsigned long nr_segs, loff_t pos)
1da177e4 563{
e6a00296 564 struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode;
1da177e4
LT
565 ssize_t written;
566
027445c3 567 written = generic_file_aio_write(iocb, iov, nr_segs, pos);
87c89dd7
SF
568 if (!CIFS_I(inode)->clientCanCacheAll)
569 filemap_fdatawrite(inode->i_mapping);
1da177e4
LT
570 return written;
571}
572
c32a0b68
SF
573static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
574{
575 /* origin == SEEK_END => we must revalidate the cached file length */
0889a944 576 if (origin == SEEK_END) {
030e9d81
SF
577 int retval;
578
579 /* some applications poll for the file length in this strange
580 way so we must seek to end on non-oplocked files by
581 setting the revalidate time to zero */
c33f8d32 582 CIFS_I(file->f_path.dentry->d_inode)->time = 0;
030e9d81
SF
583
584 retval = cifs_revalidate(file->f_path.dentry);
c32a0b68
SF
585 if (retval < 0)
586 return (loff_t)retval;
587 }
588 return remote_llseek(file, offset, origin);
589}
590
e6ab1582 591struct file_system_type cifs_fs_type = {
1da177e4
LT
592 .owner = THIS_MODULE,
593 .name = "cifs",
594 .get_sb = cifs_get_sb,
595 .kill_sb = kill_anon_super,
596 /* .fs_flags */
597};
754661f1 598const struct inode_operations cifs_dir_inode_ops = {
1da177e4
LT
599 .create = cifs_create,
600 .lookup = cifs_lookup,
601 .getattr = cifs_getattr,
602 .unlink = cifs_unlink,
603 .link = cifs_hardlink,
604 .mkdir = cifs_mkdir,
605 .rmdir = cifs_rmdir,
606 .rename = cifs_rename,
607 .permission = cifs_permission,
608/* revalidate:cifs_revalidate, */
609 .setattr = cifs_setattr,
610 .symlink = cifs_symlink,
611 .mknod = cifs_mknod,
612#ifdef CONFIG_CIFS_XATTR
613 .setxattr = cifs_setxattr,
614 .getxattr = cifs_getxattr,
615 .listxattr = cifs_listxattr,
616 .removexattr = cifs_removexattr,
617#endif
618};
619
754661f1 620const struct inode_operations cifs_file_inode_ops = {
1da177e4
LT
621/* revalidate:cifs_revalidate, */
622 .setattr = cifs_setattr,
623 .getattr = cifs_getattr, /* do we need this anymore? */
624 .rename = cifs_rename,
625 .permission = cifs_permission,
626#ifdef CONFIG_CIFS_XATTR
627 .setxattr = cifs_setxattr,
628 .getxattr = cifs_getxattr,
629 .listxattr = cifs_listxattr,
630 .removexattr = cifs_removexattr,
50c2f753 631#endif
1da177e4
LT
632};
633
754661f1 634const struct inode_operations cifs_symlink_inode_ops = {
50c2f753 635 .readlink = generic_readlink,
1da177e4
LT
636 .follow_link = cifs_follow_link,
637 .put_link = cifs_put_link,
638 .permission = cifs_permission,
639 /* BB add the following two eventually */
640 /* revalidate: cifs_revalidate,
641 setattr: cifs_notify_change, *//* BB do we need notify change */
642#ifdef CONFIG_CIFS_XATTR
643 .setxattr = cifs_setxattr,
644 .getxattr = cifs_getxattr,
645 .listxattr = cifs_listxattr,
646 .removexattr = cifs_removexattr,
50c2f753 647#endif
1da177e4
LT
648};
649
4b6f5d20 650const struct file_operations cifs_file_ops = {
87c89dd7
SF
651 .read = do_sync_read,
652 .write = do_sync_write,
87c89dd7
SF
653 .aio_read = generic_file_aio_read,
654 .aio_write = cifs_file_aio_write,
1da177e4
LT
655 .open = cifs_open,
656 .release = cifs_close,
657 .lock = cifs_lock,
658 .fsync = cifs_fsync,
659 .flush = cifs_flush,
660 .mmap = cifs_file_mmap,
5ffc4ef4 661 .splice_read = generic_file_splice_read,
c32a0b68 662 .llseek = cifs_llseek,
c67593a0
SF
663#ifdef CONFIG_CIFS_POSIX
664 .ioctl = cifs_ioctl,
665#endif /* CONFIG_CIFS_POSIX */
666
1da177e4 667#ifdef CONFIG_CIFS_EXPERIMENTAL
1da177e4
LT
668 .dir_notify = cifs_dir_notify,
669#endif /* CONFIG_CIFS_EXPERIMENTAL */
670};
671
4b6f5d20 672const struct file_operations cifs_file_direct_ops = {
50c2f753 673 /* no mmap, no aio, no readv -
1da177e4
LT
674 BB reevaluate whether they can be done with directio, no cache */
675 .read = cifs_user_read,
676 .write = cifs_user_write,
677 .open = cifs_open,
678 .release = cifs_close,
679 .lock = cifs_lock,
680 .fsync = cifs_fsync,
681 .flush = cifs_flush,
5ffc4ef4 682 .splice_read = generic_file_splice_read,
c67593a0
SF
683#ifdef CONFIG_CIFS_POSIX
684 .ioctl = cifs_ioctl,
685#endif /* CONFIG_CIFS_POSIX */
c32a0b68 686 .llseek = cifs_llseek,
1da177e4
LT
687#ifdef CONFIG_CIFS_EXPERIMENTAL
688 .dir_notify = cifs_dir_notify,
689#endif /* CONFIG_CIFS_EXPERIMENTAL */
690};
4b6f5d20 691const struct file_operations cifs_file_nobrl_ops = {
87c89dd7
SF
692 .read = do_sync_read,
693 .write = do_sync_write,
87c89dd7
SF
694 .aio_read = generic_file_aio_read,
695 .aio_write = cifs_file_aio_write,
696 .open = cifs_open,
697 .release = cifs_close,
698 .fsync = cifs_fsync,
699 .flush = cifs_flush,
700 .mmap = cifs_file_mmap,
5ffc4ef4 701 .splice_read = generic_file_splice_read,
c32a0b68 702 .llseek = cifs_llseek,
8b94bcb9 703#ifdef CONFIG_CIFS_POSIX
87c89dd7 704 .ioctl = cifs_ioctl,
8b94bcb9
SF
705#endif /* CONFIG_CIFS_POSIX */
706
707#ifdef CONFIG_CIFS_EXPERIMENTAL
87c89dd7 708 .dir_notify = cifs_dir_notify,
8b94bcb9
SF
709#endif /* CONFIG_CIFS_EXPERIMENTAL */
710};
711
4b6f5d20 712const struct file_operations cifs_file_direct_nobrl_ops = {
50c2f753 713 /* no mmap, no aio, no readv -
87c89dd7
SF
714 BB reevaluate whether they can be done with directio, no cache */
715 .read = cifs_user_read,
716 .write = cifs_user_write,
717 .open = cifs_open,
718 .release = cifs_close,
719 .fsync = cifs_fsync,
720 .flush = cifs_flush,
5ffc4ef4 721 .splice_read = generic_file_splice_read,
8b94bcb9 722#ifdef CONFIG_CIFS_POSIX
87c89dd7 723 .ioctl = cifs_ioctl,
8b94bcb9 724#endif /* CONFIG_CIFS_POSIX */
c32a0b68 725 .llseek = cifs_llseek,
8b94bcb9 726#ifdef CONFIG_CIFS_EXPERIMENTAL
87c89dd7 727 .dir_notify = cifs_dir_notify,
8b94bcb9
SF
728#endif /* CONFIG_CIFS_EXPERIMENTAL */
729};
1da177e4 730
4b6f5d20 731const struct file_operations cifs_dir_ops = {
1da177e4
LT
732 .readdir = cifs_readdir,
733 .release = cifs_closedir,
734 .read = generic_read_dir,
735#ifdef CONFIG_CIFS_EXPERIMENTAL
736 .dir_notify = cifs_dir_notify,
737#endif /* CONFIG_CIFS_EXPERIMENTAL */
50c2f753 738 .ioctl = cifs_ioctl,
1da177e4
LT
739};
740
741static void
4ba9b9d0 742cifs_init_once(struct kmem_cache *cachep, void *inode)
1da177e4
LT
743{
744 struct cifsInodeInfo *cifsi = inode;
745
a35afb83
CL
746 inode_init_once(&cifsi->vfs_inode);
747 INIT_LIST_HEAD(&cifsi->lockList);
1da177e4
LT
748}
749
750static int
751cifs_init_inodecache(void)
752{
753 cifs_inode_cachep = kmem_cache_create("cifs_inode_cache",
26f57364 754 sizeof(struct cifsInodeInfo),
fffb60f9
PJ
755 0, (SLAB_RECLAIM_ACCOUNT|
756 SLAB_MEM_SPREAD),
20c2df83 757 cifs_init_once);
1da177e4
LT
758 if (cifs_inode_cachep == NULL)
759 return -ENOMEM;
760
761 return 0;
762}
763
764static void
765cifs_destroy_inodecache(void)
766{
1a1d92c1 767 kmem_cache_destroy(cifs_inode_cachep);
1da177e4
LT
768}
769
770static int
771cifs_init_request_bufs(void)
772{
4523cc30 773 if (CIFSMaxBufSize < 8192) {
1da177e4
LT
774 /* Buffer size can not be smaller than 2 * PATH_MAX since maximum
775 Unicode path name has to fit in any SMB/CIFS path based frames */
776 CIFSMaxBufSize = 8192;
777 } else if (CIFSMaxBufSize > 1024*127) {
778 CIFSMaxBufSize = 1024 * 127;
779 } else {
780 CIFSMaxBufSize &= 0x1FE00; /* Round size to even 512 byte mult*/
781 }
782/* cERROR(1,("CIFSMaxBufSize %d 0x%x",CIFSMaxBufSize,CIFSMaxBufSize)); */
783 cifs_req_cachep = kmem_cache_create("cifs_request",
784 CIFSMaxBufSize +
785 MAX_CIFS_HDR_SIZE, 0,
20c2df83 786 SLAB_HWCACHE_ALIGN, NULL);
1da177e4
LT
787 if (cifs_req_cachep == NULL)
788 return -ENOMEM;
789
4523cc30 790 if (cifs_min_rcv < 1)
1da177e4
LT
791 cifs_min_rcv = 1;
792 else if (cifs_min_rcv > 64) {
793 cifs_min_rcv = 64;
50c2f753 794 cERROR(1, ("cifs_min_rcv set to maximum (64)"));
1da177e4
LT
795 }
796
93d2341c
MD
797 cifs_req_poolp = mempool_create_slab_pool(cifs_min_rcv,
798 cifs_req_cachep);
1da177e4 799
4523cc30 800 if (cifs_req_poolp == NULL) {
1da177e4
LT
801 kmem_cache_destroy(cifs_req_cachep);
802 return -ENOMEM;
803 }
ec637e3f 804 /* MAX_CIFS_SMALL_BUFFER_SIZE bytes is enough for most SMB responses and
1da177e4
LT
805 almost all handle based requests (but not write response, nor is it
806 sufficient for path based requests). A smaller size would have
50c2f753 807 been more efficient (compacting multiple slab items on one 4k page)
1da177e4
LT
808 for the case in which debug was on, but this larger size allows
809 more SMBs to use small buffer alloc and is still much more
6dc0f87e 810 efficient to alloc 1 per page off the slab compared to 17K (5page)
1da177e4
LT
811 alloc of large cifs buffers even when page debugging is on */
812 cifs_sm_req_cachep = kmem_cache_create("cifs_small_rq",
6dc0f87e 813 MAX_CIFS_SMALL_BUFFER_SIZE, 0, SLAB_HWCACHE_ALIGN,
20c2df83 814 NULL);
1da177e4
LT
815 if (cifs_sm_req_cachep == NULL) {
816 mempool_destroy(cifs_req_poolp);
817 kmem_cache_destroy(cifs_req_cachep);
6dc0f87e 818 return -ENOMEM;
1da177e4
LT
819 }
820
4523cc30 821 if (cifs_min_small < 2)
1da177e4
LT
822 cifs_min_small = 2;
823 else if (cifs_min_small > 256) {
824 cifs_min_small = 256;
6dc0f87e 825 cFYI(1, ("cifs_min_small set to maximum (256)"));
1da177e4
LT
826 }
827
93d2341c
MD
828 cifs_sm_req_poolp = mempool_create_slab_pool(cifs_min_small,
829 cifs_sm_req_cachep);
1da177e4 830
4523cc30 831 if (cifs_sm_req_poolp == NULL) {
1da177e4
LT
832 mempool_destroy(cifs_req_poolp);
833 kmem_cache_destroy(cifs_req_cachep);
834 kmem_cache_destroy(cifs_sm_req_cachep);
835 return -ENOMEM;
836 }
837
838 return 0;
839}
840
841static void
842cifs_destroy_request_bufs(void)
843{
844 mempool_destroy(cifs_req_poolp);
1a1d92c1 845 kmem_cache_destroy(cifs_req_cachep);
1da177e4 846 mempool_destroy(cifs_sm_req_poolp);
1a1d92c1 847 kmem_cache_destroy(cifs_sm_req_cachep);
1da177e4
LT
848}
849
850static int
851cifs_init_mids(void)
852{
853 cifs_mid_cachep = kmem_cache_create("cifs_mpx_ids",
26f57364
SF
854 sizeof(struct mid_q_entry), 0,
855 SLAB_HWCACHE_ALIGN, NULL);
1da177e4
LT
856 if (cifs_mid_cachep == NULL)
857 return -ENOMEM;
858
93d2341c
MD
859 /* 3 is a reasonable minimum number of simultaneous operations */
860 cifs_mid_poolp = mempool_create_slab_pool(3, cifs_mid_cachep);
4523cc30 861 if (cifs_mid_poolp == NULL) {
1da177e4
LT
862 kmem_cache_destroy(cifs_mid_cachep);
863 return -ENOMEM;
864 }
865
866 cifs_oplock_cachep = kmem_cache_create("cifs_oplock_structs",
26f57364
SF
867 sizeof(struct oplock_q_entry), 0,
868 SLAB_HWCACHE_ALIGN, NULL);
1da177e4 869 if (cifs_oplock_cachep == NULL) {
1da177e4 870 mempool_destroy(cifs_mid_poolp);
e6985c7f 871 kmem_cache_destroy(cifs_mid_cachep);
1da177e4
LT
872 return -ENOMEM;
873 }
874
875 return 0;
876}
877
878static void
879cifs_destroy_mids(void)
880{
881 mempool_destroy(cifs_mid_poolp);
1a1d92c1
AD
882 kmem_cache_destroy(cifs_mid_cachep);
883 kmem_cache_destroy(cifs_oplock_cachep);
1da177e4
LT
884}
885
50c2f753 886static int cifs_oplock_thread(void *dummyarg)
1da177e4 887{
6dc0f87e 888 struct oplock_q_entry *oplock_item;
1da177e4 889 struct cifsTconInfo *pTcon;
6dc0f87e 890 struct inode *inode;
1da177e4 891 __u16 netfid;
cea21805 892 int rc, waitrc = 0;
1da177e4 893
83144186 894 set_freezable();
1da177e4 895 do {
6dc0f87e 896 if (try_to_freeze())
ede1327e 897 continue;
50c2f753 898
1da177e4 899 spin_lock(&GlobalMid_Lock);
4523cc30 900 if (list_empty(&GlobalOplock_Q)) {
1da177e4
LT
901 spin_unlock(&GlobalMid_Lock);
902 set_current_state(TASK_INTERRUPTIBLE);
903 schedule_timeout(39*HZ);
904 } else {
6dc0f87e 905 oplock_item = list_entry(GlobalOplock_Q.next,
1da177e4 906 struct oplock_q_entry, qhead);
4523cc30 907 if (oplock_item) {
50c2f753 908 cFYI(1, ("found oplock item to write out"));
1da177e4
LT
909 pTcon = oplock_item->tcon;
910 inode = oplock_item->pinode;
911 netfid = oplock_item->netfid;
912 spin_unlock(&GlobalMid_Lock);
913 DeleteOplockQEntry(oplock_item);
914 /* can not grab inode sem here since it would
6dc0f87e 915 deadlock when oplock received on delete
1b1dcc1b 916 since vfs_unlink holds the i_mutex across
1da177e4 917 the call */
1b1dcc1b 918 /* mutex_lock(&inode->i_mutex);*/
1da177e4 919 if (S_ISREG(inode->i_mode)) {
26f57364
SF
920 rc =
921 filemap_fdatawrite(inode->i_mapping);
50c2f753
SF
922 if (CIFS_I(inode)->clientCanCacheRead
923 == 0) {
cea21805 924 waitrc = filemap_fdatawait(inode->i_mapping);
1da177e4
LT
925 invalidate_remote_inode(inode);
926 }
cea21805
JL
927 if (rc == 0)
928 rc = waitrc;
1da177e4
LT
929 } else
930 rc = 0;
1b1dcc1b 931 /* mutex_unlock(&inode->i_mutex);*/
1da177e4
LT
932 if (rc)
933 CIFS_I(inode)->write_behind_rc = rc;
6dc0f87e
SF
934 cFYI(1, ("Oplock flush inode %p rc %d",
935 inode, rc));
936
937 /* releasing stale oplock after recent reconnect
938 of smb session using a now incorrect file
939 handle is not a data integrity issue but do
940 not bother sending an oplock release if session
941 to server still is disconnected since oplock
1da177e4 942 already released by the server in that case */
4523cc30 943 if (pTcon->tidStatus != CifsNeedReconnect) {
1da177e4 944 rc = CIFSSMBLock(0, pTcon, netfid,
6dc0f87e 945 0 /* len */ , 0 /* offset */, 0,
1da177e4
LT
946 0, LOCKING_ANDX_OPLOCK_RELEASE,
947 0 /* wait flag */);
26f57364 948 cFYI(1, ("Oplock release rc = %d", rc));
1da177e4
LT
949 }
950 } else
951 spin_unlock(&GlobalMid_Lock);
68058e75
SF
952 set_current_state(TASK_INTERRUPTIBLE);
953 schedule_timeout(1); /* yield in case q were corrupt */
1da177e4 954 }
45af7a0f
SF
955 } while (!kthread_should_stop());
956
957 return 0;
1da177e4
LT
958}
959
50c2f753 960static int cifs_dnotify_thread(void *dummyarg)
8d0d5094 961{
6ab16d24
SF
962 struct list_head *tmp;
963 struct cifsSesInfo *ses;
964
8d0d5094 965 do {
0fd1ffe0 966 if (try_to_freeze())
16abbecd 967 continue;
8d0d5094 968 set_current_state(TASK_INTERRUPTIBLE);
6ab16d24
SF
969 schedule_timeout(15*HZ);
970 read_lock(&GlobalSMBSeslock);
971 /* check if any stuck requests that need
972 to be woken up and wakeq so the
973 thread can wake up and error out */
974 list_for_each(tmp, &GlobalSMBSessionList) {
6dc0f87e 975 ses = list_entry(tmp, struct cifsSesInfo,
6ab16d24 976 cifsSessionList);
6dc0f87e 977 if (ses && ses->server &&
2a138ebb 978 atomic_read(&ses->server->inFlight))
6ab16d24
SF
979 wake_up_all(&ses->server->response_q);
980 }
981 read_unlock(&GlobalSMBSeslock);
45af7a0f
SF
982 } while (!kthread_should_stop());
983
984 return 0;
1da177e4
LT
985}
986
987static int __init
988init_cifs(void)
989{
990 int rc = 0;
991#ifdef CONFIG_PROC_FS
992 cifs_proc_init();
993#endif
2cd646a2 994/* INIT_LIST_HEAD(&GlobalServerList);*/ /* BB not implemented yet */
1da177e4
LT
995 INIT_LIST_HEAD(&GlobalSMBSessionList);
996 INIT_LIST_HEAD(&GlobalTreeConnectionList);
997 INIT_LIST_HEAD(&GlobalOplock_Q);
4ca9c190
SF
998#ifdef CONFIG_CIFS_EXPERIMENTAL
999 INIT_LIST_HEAD(&GlobalDnotifyReqList);
1000 INIT_LIST_HEAD(&GlobalDnotifyRsp_Q);
6dc0f87e 1001#endif
1da177e4
LT
1002/*
1003 * Initialize Global counters
1004 */
1005 atomic_set(&sesInfoAllocCount, 0);
1006 atomic_set(&tconInfoAllocCount, 0);
6dc0f87e 1007 atomic_set(&tcpSesAllocCount, 0);
1da177e4
LT
1008 atomic_set(&tcpSesReconnectCount, 0);
1009 atomic_set(&tconInfoReconnectCount, 0);
1010
1011 atomic_set(&bufAllocCount, 0);
4498eed5
SF
1012 atomic_set(&smBufAllocCount, 0);
1013#ifdef CONFIG_CIFS_STATS2
1014 atomic_set(&totBufAllocCount, 0);
1015 atomic_set(&totSmBufAllocCount, 0);
1016#endif /* CONFIG_CIFS_STATS2 */
1017
1da177e4
LT
1018 atomic_set(&midCount, 0);
1019 GlobalCurrentXid = 0;
1020 GlobalTotalActiveXid = 0;
1021 GlobalMaxActiveXid = 0;
2cd646a2 1022 memset(Local_System_Name, 0, 15);
1da177e4
LT
1023 rwlock_init(&GlobalSMBSeslock);
1024 spin_lock_init(&GlobalMid_Lock);
1025
4523cc30 1026 if (cifs_max_pending < 2) {
1da177e4 1027 cifs_max_pending = 2;
6dc0f87e 1028 cFYI(1, ("cifs_max_pending set to min of 2"));
4523cc30 1029 } else if (cifs_max_pending > 256) {
1da177e4 1030 cifs_max_pending = 256;
6dc0f87e 1031 cFYI(1, ("cifs_max_pending set to max of 256"));
1da177e4
LT
1032 }
1033
1034 rc = cifs_init_inodecache();
45af7a0f
SF
1035 if (rc)
1036 goto out_clean_proc;
1037
1038 rc = cifs_init_mids();
1039 if (rc)
1040 goto out_destroy_inodecache;
1041
1042 rc = cifs_init_request_bufs();
1043 if (rc)
1044 goto out_destroy_mids;
1045
1046 rc = register_filesystem(&cifs_fs_type);
1047 if (rc)
1048 goto out_destroy_request_bufs;
84a15b93
JL
1049#ifdef CONFIG_CIFS_UPCALL
1050 rc = register_key_type(&cifs_spnego_key_type);
1051 if (rc)
1052 goto out_unregister_filesystem;
6103335d
SF
1053#endif
1054#ifdef CONFIG_CIFS_DFS_UPCALL
1055 rc = register_key_type(&key_type_dns_resolver);
1056 if (rc)
1057 goto out_unregister_key_type;
84a15b93 1058#endif
45af7a0f
SF
1059 oplockThread = kthread_run(cifs_oplock_thread, NULL, "cifsoplockd");
1060 if (IS_ERR(oplockThread)) {
1061 rc = PTR_ERR(oplockThread);
6dc0f87e 1062 cERROR(1, ("error %d create oplock thread", rc));
6103335d 1063 goto out_unregister_dfs_key_type;
1da177e4 1064 }
45af7a0f
SF
1065
1066 dnotifyThread = kthread_run(cifs_dnotify_thread, NULL, "cifsdnotifyd");
1067 if (IS_ERR(dnotifyThread)) {
1068 rc = PTR_ERR(dnotifyThread);
6dc0f87e 1069 cERROR(1, ("error %d create dnotify thread", rc));
45af7a0f
SF
1070 goto out_stop_oplock_thread;
1071 }
1072
1073 return 0;
1074
1075 out_stop_oplock_thread:
1076 kthread_stop(oplockThread);
6103335d
SF
1077 out_unregister_dfs_key_type:
1078#ifdef CONFIG_CIFS_DFS_UPCALL
1079 unregister_key_type(&key_type_dns_resolver);
84a15b93 1080 out_unregister_key_type:
6103335d 1081#endif
84a15b93
JL
1082#ifdef CONFIG_CIFS_UPCALL
1083 unregister_key_type(&cifs_spnego_key_type);
45af7a0f 1084 out_unregister_filesystem:
84a15b93 1085#endif
45af7a0f
SF
1086 unregister_filesystem(&cifs_fs_type);
1087 out_destroy_request_bufs:
1088 cifs_destroy_request_bufs();
1089 out_destroy_mids:
1090 cifs_destroy_mids();
1091 out_destroy_inodecache:
1092 cifs_destroy_inodecache();
1093 out_clean_proc:
1da177e4
LT
1094#ifdef CONFIG_PROC_FS
1095 cifs_proc_clean();
1096#endif
1097 return rc;
1098}
1099
1100static void __exit
1101exit_cifs(void)
1102{
63135e08 1103 cFYI(0, ("exit_cifs"));
1da177e4
LT
1104#ifdef CONFIG_PROC_FS
1105 cifs_proc_clean();
84a15b93 1106#endif
6103335d
SF
1107#ifdef CONFIG_CIFS_DFS_UPCALL
1108 unregister_key_type(&key_type_dns_resolver);
1109#endif
84a15b93
JL
1110#ifdef CONFIG_CIFS_UPCALL
1111 unregister_key_type(&cifs_spnego_key_type);
1da177e4
LT
1112#endif
1113 unregister_filesystem(&cifs_fs_type);
1114 cifs_destroy_inodecache();
1115 cifs_destroy_mids();
1116 cifs_destroy_request_bufs();
45af7a0f
SF
1117 kthread_stop(oplockThread);
1118 kthread_stop(dnotifyThread);
1da177e4
LT
1119}
1120
1121MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>");
6dc0f87e 1122MODULE_LICENSE("GPL"); /* combination of LGPL + GPL source behaves as GPL */
1da177e4 1123MODULE_DESCRIPTION
63135e08
SF
1124 ("VFS to access servers complying with the SNIA CIFS Specification "
1125 "e.g. Samba and Windows");
1da177e4
LT
1126MODULE_VERSION(CIFS_VERSION);
1127module_init(init_cifs)
1128module_exit(exit_cifs)