1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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>
35#include <linux/delay.h>
36#include <linux/kthread.h>
37#include <linux/freezer.h>
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>
46#include <linux/key-type.h>
47#include "cifs_spnego.h"
48#define CIFS_MAGIC_NUMBER 0xFF534D42
49
50#ifdef CONFIG_CIFS_QUOTA
51static struct quotactl_ops cifs_quotactl_ops;
52#endif
53
54int cifsFYI = 0;
55int cifsERROR = 1;
56int traceSMB = 0;
57unsigned int oplockEnabled = 1;
58unsigned int experimEnabled = 0;
59unsigned int linuxExtEnabled = 1;
60unsigned int lookupCacheEnabled = 1;
61unsigned int multiuser_mount = 0;
62unsigned int extended_security = CIFSSEC_DEF;
63
64unsigned int sign_CIFS_PDUs = 1;
65extern struct task_struct *oplockThread;
66struct task_struct *oplockThread = NULL;
67
68static struct task_struct *dnotifyThread = NULL;
69static const struct super_operations cifs_super_ops;
70unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;
71module_param(CIFSMaxBufSize, int, 0);
72MODULE_PARM_DESC(CIFSMaxBufSize, "Network buffer size (not including header). "
73 "Default: 16384 Range: 8192 to 130048");
74unsigned int cifs_min_rcv = CIFS_MIN_RCV_POOL;
75module_param(cifs_min_rcv, int, 0);
76MODULE_PARM_DESC(cifs_min_rcv, "Network buffers in pool. Default: 4 Range: "
77 "1 to 64");
78unsigned int cifs_min_small = 30;
79module_param(cifs_min_small, int, 0);
80MODULE_PARM_DESC(cifs_min_small, "Small network buffers in pool. Default: 30 "
81 "Range: 2 to 256");
82unsigned int cifs_max_pending = CIFS_MAX_REQ;
83module_param(cifs_max_pending, int, 0);
84MODULE_PARM_DESC(cifs_max_pending, "Simultaneous requests to server. "
85 "Default: 50 Range: 2 to 256");
86
87extern mempool_t *cifs_sm_req_poolp;
88extern mempool_t *cifs_req_poolp;
89extern mempool_t *cifs_mid_poolp;
90
91extern struct kmem_cache *cifs_oplock_cachep;
92
93static int
94cifs_read_super(struct super_block *sb, void *data,
95 const char *devname, int silent)
96{
97 struct inode *inode;
98 struct cifs_sb_info *cifs_sb;
99 int rc = 0;
100
101
102 sb->s_flags |= MS_NODIRATIME | MS_NOATIME;
103 sb->s_fs_info = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL);
104 cifs_sb = CIFS_SB(sb);
105 if (cifs_sb == NULL)
106 return -ENOMEM;
107
108 rc = cifs_mount(sb, cifs_sb, data, devname);
109
110 if (rc) {
111 if (!silent)
112 cERROR(1,
113 ("cifs_mount failed w/return code = %d", rc));
114 goto out_mount_failed;
115 }
116
117 sb->s_magic = CIFS_MAGIC_NUMBER;
118 sb->s_op = &cifs_super_ops;
119
120
121
122#ifdef CONFIG_CIFS_QUOTA
123 sb->s_qcop = &cifs_quotactl_ops;
124#endif
125 sb->s_blocksize = CIFS_MAX_MSGSIZE;
126 sb->s_blocksize_bits = 14;
127 inode = iget(sb, ROOT_I);
128
129 if (!inode) {
130 rc = -ENOMEM;
131 goto out_no_root;
132 }
133
134 sb->s_root = d_alloc_root(inode);
135
136 if (!sb->s_root) {
137 rc = -ENOMEM;
138 goto out_no_root;
139 }
140
141#ifdef CONFIG_CIFS_EXPERIMENTAL
142 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
143 cFYI(1, ("export ops supported"));
144 sb->s_export_op = &cifs_export_ops;
145 }
146#endif
147
148 return 0;
149
150out_no_root:
151 cERROR(1, ("cifs_read_super: get root inode failed"));
152 if (inode)
153 iput(inode);
154
155out_mount_failed:
156 if (cifs_sb) {
157 if (cifs_sb->local_nls)
158 unload_nls(cifs_sb->local_nls);
159 kfree(cifs_sb);
160 }
161 return rc;
162}
163
164static void
165cifs_put_super(struct super_block *sb)
166{
167 int rc = 0;
168 struct cifs_sb_info *cifs_sb;
169
170 cFYI(1, ("In cifs_put_super"));
171 cifs_sb = CIFS_SB(sb);
172 if (cifs_sb == NULL) {
173 cFYI(1, ("Empty cifs superblock info passed to unmount"));
174 return;
175 }
176 rc = cifs_umount(sb, cifs_sb);
177 if (rc) {
178 cERROR(1, ("cifs_umount failed with return code %d", rc));
179 }
180 unload_nls(cifs_sb->local_nls);
181 kfree(cifs_sb);
182 return;
183}
184
185static int
186cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
187{
188 struct super_block *sb = dentry->d_sb;
189 int xid;
190 int rc = -EOPNOTSUPP;
191 struct cifs_sb_info *cifs_sb;
192 struct cifsTconInfo *pTcon;
193
194 xid = GetXid();
195
196 cifs_sb = CIFS_SB(sb);
197 pTcon = cifs_sb->tcon;
198
199 buf->f_type = CIFS_MAGIC_NUMBER;
200
201
202 buf->f_namelen = PATH_MAX;
203
204
205
206 buf->f_files = 0;
207 buf->f_ffree = 0;
208
209
210
211 if ((pTcon->ses->capabilities & CAP_UNIX) && (CIFS_POSIX_EXTENSIONS &
212 le64_to_cpu(pTcon->fsUnixInfo.Capability)))
213 rc = CIFSSMBQFSPosixInfo(xid, pTcon, buf);
214
215
216
217 if (rc)
218 if (pTcon->ses->capabilities & CAP_NT_SMBS)
219 rc = CIFSSMBQFSInfo(xid, pTcon, buf);
220
221
222
223
224 if (rc)
225 rc = SMBOldQFSInfo(xid, pTcon, buf);
226
227
228
229
230 FreeXid(xid);
231 return 0;
232
233}
234
235static int cifs_permission(struct inode *inode, int mask, struct nameidata *nd)
236{
237 struct cifs_sb_info *cifs_sb;
238
239 cifs_sb = CIFS_SB(inode->i_sb);
240
241 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
242 return 0;
243 else
244
245
246
247 return generic_permission(inode, mask, NULL);
248}
249
250static struct kmem_cache *cifs_inode_cachep;
251static struct kmem_cache *cifs_req_cachep;
252static struct kmem_cache *cifs_mid_cachep;
253struct kmem_cache *cifs_oplock_cachep;
254static struct kmem_cache *cifs_sm_req_cachep;
255mempool_t *cifs_sm_req_poolp;
256mempool_t *cifs_req_poolp;
257mempool_t *cifs_mid_poolp;
258
259static struct inode *
260cifs_alloc_inode(struct super_block *sb)
261{
262 struct cifsInodeInfo *cifs_inode;
263 cifs_inode = kmem_cache_alloc(cifs_inode_cachep, GFP_KERNEL);
264 if (!cifs_inode)
265 return NULL;
266 cifs_inode->cifsAttrs = 0x20;
267 atomic_set(&cifs_inode->inUse, 0);
268 cifs_inode->time = 0;
269 cifs_inode->write_behind_rc = 0;
270
271
272
273 cifs_inode->clientCanCacheRead = FALSE;
274 cifs_inode->clientCanCacheAll = FALSE;
275 cifs_inode->vfs_inode.i_blkbits = 14;
276
277
278
279
280 INIT_LIST_HEAD(&cifs_inode->openFileList);
281 return &cifs_inode->vfs_inode;
282}
283
284static void
285cifs_destroy_inode(struct inode *inode)
286{
287 kmem_cache_free(cifs_inode_cachep, CIFS_I(inode));
288}
289
290
291
292
293
294
295static int
296cifs_show_options(struct seq_file *s, struct vfsmount *m)
297{
298 struct cifs_sb_info *cifs_sb;
299
300 cifs_sb = CIFS_SB(m->mnt_sb);
301
302 if (cifs_sb) {
303 if (cifs_sb->tcon) {
304
305 seq_printf(s, ",unc=%s", cifs_sb->tcon->treeName);
306 if (cifs_sb->tcon->ses) {
307 if (cifs_sb->tcon->ses->userName)
308 seq_printf(s, ",username=%s",
309 cifs_sb->tcon->ses->userName);
310 if (cifs_sb->tcon->ses->domainName)
311 seq_printf(s, ",domain=%s",
312 cifs_sb->tcon->ses->domainName);
313 }
314 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) ||
315 !(cifs_sb->tcon->unix_ext))
316 seq_printf(s, ",uid=%d", cifs_sb->mnt_uid);
317 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) ||
318 !(cifs_sb->tcon->unix_ext))
319 seq_printf(s, ",gid=%d", cifs_sb->mnt_gid);
320 }
321 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
322 seq_printf(s, ",posixpaths");
323 seq_printf(s, ",rsize=%d", cifs_sb->rsize);
324 seq_printf(s, ",wsize=%d", cifs_sb->wsize);
325 }
326 return 0;
327}
328
329#ifdef CONFIG_CIFS_QUOTA
330int cifs_xquota_set(struct super_block *sb, int quota_type, qid_t qid,
331 struct fs_disk_quota *pdquota)
332{
333 int xid;
334 int rc = 0;
335 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
336 struct cifsTconInfo *pTcon;
337
338 if (cifs_sb)
339 pTcon = cifs_sb->tcon;
340 else
341 return -EIO;
342
343
344 xid = GetXid();
345 if (pTcon) {
346 cFYI(1, ("set type: 0x%x id: %d", quota_type, qid));
347 } else {
348 rc = -EIO;
349 }
350
351 FreeXid(xid);
352 return rc;
353}
354
355int cifs_xquota_get(struct super_block *sb, int quota_type, qid_t qid,
356 struct fs_disk_quota *pdquota)
357{
358 int xid;
359 int rc = 0;
360 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
361 struct cifsTconInfo *pTcon;
362
363 if (cifs_sb)
364 pTcon = cifs_sb->tcon;
365 else
366 return -EIO;
367
368 xid = GetXid();
369 if (pTcon) {
370 cFYI(1, ("set type: 0x%x id: %d", quota_type, qid));
371 } else {
372 rc = -EIO;
373 }
374
375 FreeXid(xid);
376 return rc;
377}
378
379int cifs_xstate_set(struct super_block *sb, unsigned int flags, int operation)
380{
381 int xid;
382 int rc = 0;
383 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
384 struct cifsTconInfo *pTcon;
385
386 if (cifs_sb)
387 pTcon = cifs_sb->tcon;
388 else
389 return -EIO;
390
391 xid = GetXid();
392 if (pTcon) {
393 cFYI(1, ("flags: 0x%x operation: 0x%x", flags, operation));
394 } else {
395 rc = -EIO;
396 }
397
398 FreeXid(xid);
399 return rc;
400}
401
402int cifs_xstate_get(struct super_block *sb, struct fs_quota_stat *qstats)
403{
404 int xid;
405 int rc = 0;
406 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
407 struct cifsTconInfo *pTcon;
408
409 if (cifs_sb) {
410 pTcon = cifs_sb->tcon;
411 } else {
412 return -EIO;
413 }
414 xid = GetXid();
415 if (pTcon) {
416 cFYI(1, ("pqstats %p", qstats));
417 } else {
418 rc = -EIO;
419 }
420
421 FreeXid(xid);
422 return rc;
423}
424
425static struct quotactl_ops cifs_quotactl_ops = {
426 .set_xquota = cifs_xquota_set,
427 .get_xquota = cifs_xquota_set,
428 .set_xstate = cifs_xstate_set,
429 .get_xstate = cifs_xstate_get,
430};
431#endif
432
433static void cifs_umount_begin(struct vfsmount *vfsmnt, int flags)
434{
435 struct cifs_sb_info *cifs_sb;
436 struct cifsTconInfo *tcon;
437
438 if (!(flags & MNT_FORCE))
439 return;
440 cifs_sb = CIFS_SB(vfsmnt->mnt_sb);
441 if (cifs_sb == NULL)
442 return;
443
444 tcon = cifs_sb->tcon;
445 if (tcon == NULL)
446 return;
447 down(&tcon->tconSem);
448 if (atomic_read(&tcon->useCount) == 1)
449 tcon->tidStatus = CifsExiting;
450 up(&tcon->tconSem);
451
452
453
454 if (tcon->ses && tcon->ses->server) {
455 cFYI(1, ("wake up tasks now - umount begin not complete"));
456 wake_up_all(&tcon->ses->server->request_q);
457 wake_up_all(&tcon->ses->server->response_q);
458 msleep(1);
459
460 wake_up_all(&tcon->ses->server->response_q);
461 msleep(1);
462 }
463
464
465 return;
466}
467
468#ifdef CONFIG_CIFS_STATS2
469static int cifs_show_stats(struct seq_file *s, struct vfsmount *mnt)
470{
471
472 return 0;
473}
474#endif
475
476static int cifs_remount(struct super_block *sb, int *flags, char *data)
477{
478 *flags |= MS_NODIRATIME;
479 return 0;
480}
481
482static const struct super_operations cifs_super_ops = {
483 .read_inode = cifs_read_inode,
484 .put_super = cifs_put_super,
485 .statfs = cifs_statfs,
486 .alloc_inode = cifs_alloc_inode,
487 .destroy_inode = cifs_destroy_inode,
488
489
490
491
492
493 .show_options = cifs_show_options,
494 .umount_begin = cifs_umount_begin,
495 .remount_fs = cifs_remount,
496#ifdef CONFIG_CIFS_STATS2
497 .show_stats = cifs_show_stats,
498#endif
499};
500
501static int
502cifs_get_sb(struct file_system_type *fs_type,
503 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
504{
505 int rc;
506 struct super_block *sb = sget(fs_type, NULL, set_anon_super, NULL);
507
508 cFYI(1, ("Devname: %s flags: %d ", dev_name, flags));
509
510 if (IS_ERR(sb))
511 return PTR_ERR(sb);
512
513 sb->s_flags = flags;
514
515 rc = cifs_read_super(sb, data, dev_name, flags & MS_SILENT ? 1 : 0);
516 if (rc) {
517 up_write(&sb->s_umount);
518 deactivate_super(sb);
519 return rc;
520 }
521 sb->s_flags |= MS_ACTIVE;
522 return simple_set_mnt(mnt, sb);
523}
524
525static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
526 unsigned long nr_segs, loff_t pos)
527{
528 struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode;
529 ssize_t written;
530
531 written = generic_file_aio_write(iocb, iov, nr_segs, pos);
532 if (!CIFS_I(inode)->clientCanCacheAll)
533 filemap_fdatawrite(inode->i_mapping);
534 return written;
535}
536
537static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
538{
539
540 if (origin == SEEK_END) {
541 int retval;
542
543
544
545
546 CIFS_I(file->f_path.dentry->d_inode)->time = 0;
547
548 retval = cifs_revalidate(file->f_path.dentry);
549 if (retval < 0)
550 return (loff_t)retval;
551 }
552 return remote_llseek(file, offset, origin);
553}
554
555static struct file_system_type cifs_fs_type = {
556 .owner = THIS_MODULE,
557 .name = "cifs",
558 .get_sb = cifs_get_sb,
559 .kill_sb = kill_anon_super,
560
561};
562const struct inode_operations cifs_dir_inode_ops = {
563 .create = cifs_create,
564 .lookup = cifs_lookup,
565 .getattr = cifs_getattr,
566 .unlink = cifs_unlink,
567 .link = cifs_hardlink,
568 .mkdir = cifs_mkdir,
569 .rmdir = cifs_rmdir,
570 .rename = cifs_rename,
571 .permission = cifs_permission,
572
573 .setattr = cifs_setattr,
574 .symlink = cifs_symlink,
575 .mknod = cifs_mknod,
576#ifdef CONFIG_CIFS_XATTR
577 .setxattr = cifs_setxattr,
578 .getxattr = cifs_getxattr,
579 .listxattr = cifs_listxattr,
580 .removexattr = cifs_removexattr,
581#endif
582};
583
584const struct inode_operations cifs_file_inode_ops = {
585
586 .setattr = cifs_setattr,
587 .getattr = cifs_getattr,
588 .rename = cifs_rename,
589 .permission = cifs_permission,
590#ifdef CONFIG_CIFS_XATTR
591 .setxattr = cifs_setxattr,
592 .getxattr = cifs_getxattr,
593 .listxattr = cifs_listxattr,
594 .removexattr = cifs_removexattr,
595#endif
596};
597
598const struct inode_operations cifs_symlink_inode_ops = {
599 .readlink = generic_readlink,
600 .follow_link = cifs_follow_link,
601 .put_link = cifs_put_link,
602 .permission = cifs_permission,
603
604
605
606#ifdef CONFIG_CIFS_XATTR
607 .setxattr = cifs_setxattr,
608 .getxattr = cifs_getxattr,
609 .listxattr = cifs_listxattr,
610 .removexattr = cifs_removexattr,
611#endif
612};
613
614const struct file_operations cifs_file_ops = {
615 .read = do_sync_read,
616 .write = do_sync_write,
617 .aio_read = generic_file_aio_read,
618 .aio_write = cifs_file_aio_write,
619 .open = cifs_open,
620 .release = cifs_close,
621 .lock = cifs_lock,
622 .fsync = cifs_fsync,
623 .flush = cifs_flush,
624 .mmap = cifs_file_mmap,
625 .splice_read = generic_file_splice_read,
626 .llseek = cifs_llseek,
627#ifdef CONFIG_CIFS_POSIX
628 .ioctl = cifs_ioctl,
629#endif
630
631#ifdef CONFIG_CIFS_EXPERIMENTAL
632 .dir_notify = cifs_dir_notify,
633#endif
634};
635
636const struct file_operations cifs_file_direct_ops = {
637
638
639 .read = cifs_user_read,
640 .write = cifs_user_write,
641 .open = cifs_open,
642 .release = cifs_close,
643 .lock = cifs_lock,
644 .fsync = cifs_fsync,
645 .flush = cifs_flush,
646 .splice_read = generic_file_splice_read,
647#ifdef CONFIG_CIFS_POSIX
648 .ioctl = cifs_ioctl,
649#endif
650 .llseek = cifs_llseek,
651#ifdef CONFIG_CIFS_EXPERIMENTAL
652 .dir_notify = cifs_dir_notify,
653#endif
654};
655const struct file_operations cifs_file_nobrl_ops = {
656 .read = do_sync_read,
657 .write = do_sync_write,
658 .aio_read = generic_file_aio_read,
659 .aio_write = cifs_file_aio_write,
660 .open = cifs_open,
661 .release = cifs_close,
662 .fsync = cifs_fsync,
663 .flush = cifs_flush,
664 .mmap = cifs_file_mmap,
665 .splice_read = generic_file_splice_read,
666 .llseek = cifs_llseek,
667#ifdef CONFIG_CIFS_POSIX
668 .ioctl = cifs_ioctl,
669#endif
670
671#ifdef CONFIG_CIFS_EXPERIMENTAL
672 .dir_notify = cifs_dir_notify,
673#endif
674};
675
676const struct file_operations cifs_file_direct_nobrl_ops = {
677
678
679 .read = cifs_user_read,
680 .write = cifs_user_write,
681 .open = cifs_open,
682 .release = cifs_close,
683 .fsync = cifs_fsync,
684 .flush = cifs_flush,
685 .splice_read = generic_file_splice_read,
686#ifdef CONFIG_CIFS_POSIX
687 .ioctl = cifs_ioctl,
688#endif
689 .llseek = cifs_llseek,
690#ifdef CONFIG_CIFS_EXPERIMENTAL
691 .dir_notify = cifs_dir_notify,
692#endif
693};
694
695const struct file_operations cifs_dir_ops = {
696 .readdir = cifs_readdir,
697 .release = cifs_closedir,
698 .read = generic_read_dir,
699#ifdef CONFIG_CIFS_EXPERIMENTAL
700 .dir_notify = cifs_dir_notify,
701#endif
702 .ioctl = cifs_ioctl,
703};
704
705static void
706cifs_init_once(struct kmem_cache *cachep, void *inode)
707{
708 struct cifsInodeInfo *cifsi = inode;
709
710 inode_init_once(&cifsi->vfs_inode);
711 INIT_LIST_HEAD(&cifsi->lockList);
712}
713
714static int
715cifs_init_inodecache(void)
716{
717 cifs_inode_cachep = kmem_cache_create("cifs_inode_cache",
718 sizeof(struct cifsInodeInfo),
719 0, (SLAB_RECLAIM_ACCOUNT|
720 SLAB_MEM_SPREAD),
721 cifs_init_once);
722 if (cifs_inode_cachep == NULL)
723 return -ENOMEM;
724
725 return 0;
726}
727
728static void
729cifs_destroy_inodecache(void)
730{
731 kmem_cache_destroy(cifs_inode_cachep);
732}
733
734static int
735cifs_init_request_bufs(void)
736{
737 if (CIFSMaxBufSize < 8192) {
738
739
740 CIFSMaxBufSize = 8192;
741 } else if (CIFSMaxBufSize > 1024*127) {
742 CIFSMaxBufSize = 1024 * 127;
743 } else {
744 CIFSMaxBufSize &= 0x1FE00;
745 }
746
747 cifs_req_cachep = kmem_cache_create("cifs_request",
748 CIFSMaxBufSize +
749 MAX_CIFS_HDR_SIZE, 0,
750 SLAB_HWCACHE_ALIGN, NULL);
751 if (cifs_req_cachep == NULL)
752 return -ENOMEM;
753
754 if (cifs_min_rcv < 1)
755 cifs_min_rcv = 1;
756 else if (cifs_min_rcv > 64) {
757 cifs_min_rcv = 64;
758 cERROR(1, ("cifs_min_rcv set to maximum (64)"));
759 }
760
761 cifs_req_poolp = mempool_create_slab_pool(cifs_min_rcv,
762 cifs_req_cachep);
763
764 if (cifs_req_poolp == NULL) {
765 kmem_cache_destroy(cifs_req_cachep);
766 return -ENOMEM;
767 }
768
769
770
771
772
773
774
775
776 cifs_sm_req_cachep = kmem_cache_create("cifs_small_rq",
777 MAX_CIFS_SMALL_BUFFER_SIZE, 0, SLAB_HWCACHE_ALIGN,
778 NULL);
779 if (cifs_sm_req_cachep == NULL) {
780 mempool_destroy(cifs_req_poolp);
781 kmem_cache_destroy(cifs_req_cachep);
782 return -ENOMEM;
783 }
784
785 if (cifs_min_small < 2)
786 cifs_min_small = 2;
787 else if (cifs_min_small > 256) {
788 cifs_min_small = 256;
789 cFYI(1, ("cifs_min_small set to maximum (256)"));
790 }
791
792 cifs_sm_req_poolp = mempool_create_slab_pool(cifs_min_small,
793 cifs_sm_req_cachep);
794
795 if (cifs_sm_req_poolp == NULL) {
796 mempool_destroy(cifs_req_poolp);
797 kmem_cache_destroy(cifs_req_cachep);
798 kmem_cache_destroy(cifs_sm_req_cachep);
799 return -ENOMEM;
800 }
801
802 return 0;
803}
804
805static void
806cifs_destroy_request_bufs(void)
807{
808 mempool_destroy(cifs_req_poolp);
809 kmem_cache_destroy(cifs_req_cachep);
810 mempool_destroy(cifs_sm_req_poolp);
811 kmem_cache_destroy(cifs_sm_req_cachep);
812}
813
814static int
815cifs_init_mids(void)
816{
817 cifs_mid_cachep = kmem_cache_create("cifs_mpx_ids",
818 sizeof(struct mid_q_entry), 0,
819 SLAB_HWCACHE_ALIGN, NULL);
820 if (cifs_mid_cachep == NULL)
821 return -ENOMEM;
822
823
824 cifs_mid_poolp = mempool_create_slab_pool(3, cifs_mid_cachep);
825 if (cifs_mid_poolp == NULL) {
826 kmem_cache_destroy(cifs_mid_cachep);
827 return -ENOMEM;
828 }
829
830 cifs_oplock_cachep = kmem_cache_create("cifs_oplock_structs",
831 sizeof(struct oplock_q_entry), 0,
832 SLAB_HWCACHE_ALIGN, NULL);
833 if (cifs_oplock_cachep == NULL) {
834 mempool_destroy(cifs_mid_poolp);
835 kmem_cache_destroy(cifs_mid_cachep);
836 return -ENOMEM;
837 }
838
839 return 0;
840}
841
842static void
843cifs_destroy_mids(void)
844{
845 mempool_destroy(cifs_mid_poolp);
846 kmem_cache_destroy(cifs_mid_cachep);
847 kmem_cache_destroy(cifs_oplock_cachep);
848}
849
850static int cifs_oplock_thread(void *dummyarg)
851{
852 struct oplock_q_entry *oplock_item;
853 struct cifsTconInfo *pTcon;
854 struct inode *inode;
855 __u16 netfid;
856 int rc, waitrc = 0;
857
858 set_freezable();
859 do {
860 if (try_to_freeze())
861 continue;
862
863 spin_lock(&GlobalMid_Lock);
864 if (list_empty(&GlobalOplock_Q)) {
865 spin_unlock(&GlobalMid_Lock);
866 set_current_state(TASK_INTERRUPTIBLE);
867 schedule_timeout(39*HZ);
868 } else {
869 oplock_item = list_entry(GlobalOplock_Q.next,
870 struct oplock_q_entry, qhead);
871 if (oplock_item) {
872 cFYI(1, ("found oplock item to write out"));
873 pTcon = oplock_item->tcon;
874 inode = oplock_item->pinode;
875 netfid = oplock_item->netfid;
876 spin_unlock(&GlobalMid_Lock);
877 DeleteOplockQEntry(oplock_item);
878
879
880
881
882
883 if (S_ISREG(inode->i_mode)) {
884 rc =
885 filemap_fdatawrite(inode->i_mapping);
886 if (CIFS_I(inode)->clientCanCacheRead
887 == 0) {
888 waitrc = filemap_fdatawait(inode->i_mapping);
889 invalidate_remote_inode(inode);
890 }
891 if (rc == 0)
892 rc = waitrc;
893 } else
894 rc = 0;
895
896 if (rc)
897 CIFS_I(inode)->write_behind_rc = rc;
898 cFYI(1, ("Oplock flush inode %p rc %d",
899 inode, rc));
900
901
902
903
904
905
906
907 if (pTcon->tidStatus != CifsNeedReconnect) {
908 rc = CIFSSMBLock(0, pTcon, netfid,
909 0 , 0 , 0,
910 0, LOCKING_ANDX_OPLOCK_RELEASE,
911 0 );
912 cFYI(1, ("Oplock release rc = %d", rc));
913 }
914 } else
915 spin_unlock(&GlobalMid_Lock);
916 set_current_state(TASK_INTERRUPTIBLE);
917 schedule_timeout(1);
918 }
919 } while (!kthread_should_stop());
920
921 return 0;
922}
923
924static int cifs_dnotify_thread(void *dummyarg)
925{
926 struct list_head *tmp;
927 struct cifsSesInfo *ses;
928
929 do {
930 if (try_to_freeze())
931 continue;
932 set_current_state(TASK_INTERRUPTIBLE);
933 schedule_timeout(15*HZ);
934 read_lock(&GlobalSMBSeslock);
935
936
937
938 list_for_each(tmp, &GlobalSMBSessionList) {
939 ses = list_entry(tmp, struct cifsSesInfo,
940 cifsSessionList);
941 if (ses && ses->server &&
942 atomic_read(&ses->server->inFlight))
943 wake_up_all(&ses->server->response_q);
944 }
945 read_unlock(&GlobalSMBSeslock);
946 } while (!kthread_should_stop());
947
948 return 0;
949}
950
951static int __init
952init_cifs(void)
953{
954 int rc = 0;
955#ifdef CONFIG_PROC_FS
956 cifs_proc_init();
957#endif
958
959 INIT_LIST_HEAD(&GlobalSMBSessionList);
960 INIT_LIST_HEAD(&GlobalTreeConnectionList);
961 INIT_LIST_HEAD(&GlobalOplock_Q);
962#ifdef CONFIG_CIFS_EXPERIMENTAL
963 INIT_LIST_HEAD(&GlobalDnotifyReqList);
964 INIT_LIST_HEAD(&GlobalDnotifyRsp_Q);
965#endif
966
967
968
969 atomic_set(&sesInfoAllocCount, 0);
970 atomic_set(&tconInfoAllocCount, 0);
971 atomic_set(&tcpSesAllocCount, 0);
972 atomic_set(&tcpSesReconnectCount, 0);
973 atomic_set(&tconInfoReconnectCount, 0);
974
975 atomic_set(&bufAllocCount, 0);
976 atomic_set(&smBufAllocCount, 0);
977#ifdef CONFIG_CIFS_STATS2
978 atomic_set(&totBufAllocCount, 0);
979 atomic_set(&totSmBufAllocCount, 0);
980#endif
981
982 atomic_set(&midCount, 0);
983 GlobalCurrentXid = 0;
984 GlobalTotalActiveXid = 0;
985 GlobalMaxActiveXid = 0;
986 memset(Local_System_Name, 0, 15);
987 rwlock_init(&GlobalSMBSeslock);
988 spin_lock_init(&GlobalMid_Lock);
989
990 if (cifs_max_pending < 2) {
991 cifs_max_pending = 2;
992 cFYI(1, ("cifs_max_pending set to min of 2"));
993 } else if (cifs_max_pending > 256) {
994 cifs_max_pending = 256;
995 cFYI(1, ("cifs_max_pending set to max of 256"));
996 }
997
998 rc = cifs_init_inodecache();
999 if (rc)
1000 goto out_clean_proc;
1001
1002 rc = cifs_init_mids();
1003 if (rc)
1004 goto out_destroy_inodecache;
1005
1006 rc = cifs_init_request_bufs();
1007 if (rc)
1008 goto out_destroy_mids;
1009
1010 rc = register_filesystem(&cifs_fs_type);
1011 if (rc)
1012 goto out_destroy_request_bufs;
1013#ifdef CONFIG_CIFS_UPCALL
1014 rc = register_key_type(&cifs_spnego_key_type);
1015 if (rc)
1016 goto out_unregister_filesystem;
1017#endif
1018 oplockThread = kthread_run(cifs_oplock_thread, NULL, "cifsoplockd");
1019 if (IS_ERR(oplockThread)) {
1020 rc = PTR_ERR(oplockThread);
1021 cERROR(1, ("error %d create oplock thread", rc));
1022 goto out_unregister_key_type;
1023 }
1024
1025 dnotifyThread = kthread_run(cifs_dnotify_thread, NULL, "cifsdnotifyd");
1026 if (IS_ERR(dnotifyThread)) {
1027 rc = PTR_ERR(dnotifyThread);
1028 cERROR(1, ("error %d create dnotify thread", rc));
1029 goto out_stop_oplock_thread;
1030 }
1031
1032 return 0;
1033
1034 out_stop_oplock_thread:
1035 kthread_stop(oplockThread);
1036 out_unregister_key_type:
1037#ifdef CONFIG_CIFS_UPCALL
1038 unregister_key_type(&cifs_spnego_key_type);
1039 out_unregister_filesystem:
1040#endif
1041 unregister_filesystem(&cifs_fs_type);
1042 out_destroy_request_bufs:
1043 cifs_destroy_request_bufs();
1044 out_destroy_mids:
1045 cifs_destroy_mids();
1046 out_destroy_inodecache:
1047 cifs_destroy_inodecache();
1048 out_clean_proc:
1049#ifdef CONFIG_PROC_FS
1050 cifs_proc_clean();
1051#endif
1052 return rc;
1053}
1054
1055static void __exit
1056exit_cifs(void)
1057{
1058 cFYI(0, ("exit_cifs"));
1059#ifdef CONFIG_PROC_FS
1060 cifs_proc_clean();
1061#endif
1062#ifdef CONFIG_CIFS_UPCALL
1063 unregister_key_type(&cifs_spnego_key_type);
1064#endif
1065 unregister_filesystem(&cifs_fs_type);
1066 cifs_destroy_inodecache();
1067 cifs_destroy_mids();
1068 cifs_destroy_request_bufs();
1069 kthread_stop(oplockThread);
1070 kthread_stop(dnotifyThread);
1071}
1072
1073MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>");
1074MODULE_LICENSE("GPL");
1075MODULE_DESCRIPTION
1076 ("VFS to access servers complying with the SNIA CIFS Specification "
1077 "e.g. Samba and Windows");
1078MODULE_VERSION(CIFS_VERSION);
1079module_init(init_cifs)
1080module_exit(exit_cifs)
1081