]> bbs.cooldavid.org Git - net-next-2.6.git/blame - fs/cifs/cifsfs.c
[PATCH] cifs: Do not interpret oplock break responses as responses to an unrelated...
[net-next-2.6.git] / fs / cifs / cifsfs.c
CommitLineData
1da177e4
LT
1/*
2 * fs/cifs/cifsfs.c
3 *
4 * Copyright (C) International Business Machines Corp., 2002,2004
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>
35#include "cifsfs.h"
36#include "cifspdu.h"
37#define DECLARE_GLOBALS_HERE
38#include "cifsglob.h"
39#include "cifsproto.h"
40#include "cifs_debug.h"
41#include "cifs_fs_sb.h"
42#include <linux/mm.h>
43#define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDUs */
44
45#ifdef CONFIG_CIFS_QUOTA
46static struct quotactl_ops cifs_quotactl_ops;
47#endif
48
49int cifsFYI = 0;
50int cifsERROR = 1;
51int traceSMB = 0;
52unsigned int oplockEnabled = 1;
53unsigned int experimEnabled = 0;
54unsigned int linuxExtEnabled = 1;
55unsigned int lookupCacheEnabled = 1;
56unsigned int multiuser_mount = 0;
57unsigned int extended_security = 0;
58unsigned int ntlmv2_support = 0;
59unsigned int sign_CIFS_PDUs = 1;
60extern struct task_struct * oplockThread; /* remove sparse warning */
61struct task_struct * oplockThread = NULL;
62unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;
63module_param(CIFSMaxBufSize, int, 0);
64MODULE_PARM_DESC(CIFSMaxBufSize,"Network buffer size (not including header). Default: 16384 Range: 8192 to 130048");
65unsigned int cifs_min_rcv = CIFS_MIN_RCV_POOL;
66module_param(cifs_min_rcv, int, 0);
67MODULE_PARM_DESC(cifs_min_rcv,"Network buffers in pool. Default: 4 Range: 1 to 64");
68unsigned int cifs_min_small = 30;
69module_param(cifs_min_small, int, 0);
70MODULE_PARM_DESC(cifs_min_small,"Small network buffers in pool. Default: 30 Range: 2 to 256");
71unsigned int cifs_max_pending = CIFS_MAX_REQ;
72module_param(cifs_max_pending, int, 0);
73MODULE_PARM_DESC(cifs_max_pending,"Simultaneous requests to server. Default: 50 Range: 2 to 256");
74
75static DECLARE_COMPLETION(cifs_oplock_exited);
76
77extern mempool_t *cifs_sm_req_poolp;
78extern mempool_t *cifs_req_poolp;
79extern mempool_t *cifs_mid_poolp;
80
81extern kmem_cache_t *cifs_oplock_cachep;
82
83static int
84cifs_read_super(struct super_block *sb, void *data,
85 const char *devname, int silent)
86{
87 struct inode *inode;
88 struct cifs_sb_info *cifs_sb;
89 int rc = 0;
90
91 sb->s_flags |= MS_NODIRATIME; /* and probably even noatime */
92 sb->s_fs_info = kmalloc(sizeof(struct cifs_sb_info),GFP_KERNEL);
93 cifs_sb = CIFS_SB(sb);
94 if(cifs_sb == NULL)
95 return -ENOMEM;
96 else
97 memset(cifs_sb,0,sizeof(struct cifs_sb_info));
98
99
100 rc = cifs_mount(sb, cifs_sb, data, devname);
101
102 if (rc) {
103 if (!silent)
104 cERROR(1,
105 ("cifs_mount failed w/return code = %d", rc));
106 goto out_mount_failed;
107 }
108
109 sb->s_magic = CIFS_MAGIC_NUMBER;
110 sb->s_op = &cifs_super_ops;
111/* if(cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512)
112 sb->s_blocksize = cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */
113#ifdef CONFIG_CIFS_QUOTA
114 sb->s_qcop = &cifs_quotactl_ops;
115#endif
116 sb->s_blocksize = CIFS_MAX_MSGSIZE;
117 sb->s_blocksize_bits = 14; /* default 2**14 = CIFS_MAX_MSGSIZE */
118 inode = iget(sb, ROOT_I);
119
120 if (!inode) {
121 rc = -ENOMEM;
122 goto out_no_root;
123 }
124
125 sb->s_root = d_alloc_root(inode);
126
127 if (!sb->s_root) {
128 rc = -ENOMEM;
129 goto out_no_root;
130 }
131
132 return 0;
133
134out_no_root:
135 cERROR(1, ("cifs_read_super: get root inode failed"));
136 if (inode)
137 iput(inode);
138
139out_mount_failed:
140 if(cifs_sb) {
141 if(cifs_sb->local_nls)
142 unload_nls(cifs_sb->local_nls);
143 kfree(cifs_sb);
144 }
145 return rc;
146}
147
148static void
149cifs_put_super(struct super_block *sb)
150{
151 int rc = 0;
152 struct cifs_sb_info *cifs_sb;
153
154 cFYI(1, ("In cifs_put_super"));
155 cifs_sb = CIFS_SB(sb);
156 if(cifs_sb == NULL) {
157 cFYI(1,("Empty cifs superblock info passed to unmount"));
158 return;
159 }
160 rc = cifs_umount(sb, cifs_sb);
161 if (rc) {
162 cERROR(1, ("cifs_umount failed with return code %d", rc));
163 }
164 unload_nls(cifs_sb->local_nls);
165 kfree(cifs_sb);
166 return;
167}
168
169static int
170cifs_statfs(struct super_block *sb, struct kstatfs *buf)
171{
172 int xid, rc = -EOPNOTSUPP;
173 struct cifs_sb_info *cifs_sb;
174 struct cifsTconInfo *pTcon;
175
176 xid = GetXid();
177
178 cifs_sb = CIFS_SB(sb);
179 pTcon = cifs_sb->tcon;
180
181 buf->f_type = CIFS_MAGIC_NUMBER;
182
183 /* instead could get the real value via SMB_QUERY_FS_ATTRIBUTE_INFO */
184 buf->f_namelen = PATH_MAX; /* PATH_MAX may be too long - it would presumably
185 be length of total path, note that some servers may be
186 able to support more than this, but best to be safe
187 since Win2k and others can not handle very long filenames */
188 buf->f_files = 0; /* undefined */
189 buf->f_ffree = 0; /* unlimited */
190
191#ifdef CONFIG_CIFS_EXPERIMENTAL
192/* BB we could add a second check for a QFS Unix capability bit */
193 if (pTcon->ses->capabilities & CAP_UNIX)
737b758c 194 rc = CIFSSMBQFSPosixInfo(xid, pTcon, buf);
1da177e4
LT
195
196 /* Only need to call the old QFSInfo if failed
197 on newer one */
198 if(rc)
199#endif /* CIFS_EXPERIMENTAL */
737b758c 200 rc = CIFSSMBQFSInfo(xid, pTcon, buf);
1da177e4
LT
201
202 /*
203 int f_type;
204 __fsid_t f_fsid;
205 int f_namelen; */
206 /* BB get from info put in tcon struct at mount time with call to QFSAttrInfo */
207 FreeXid(xid);
208 return 0; /* always return success? what if volume is no longer available? */
209}
210
211static int cifs_permission(struct inode * inode, int mask, struct nameidata *nd)
212{
213 struct cifs_sb_info *cifs_sb;
214
215 cifs_sb = CIFS_SB(inode->i_sb);
216
217 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) {
218 return 0;
219 } else /* file mode might have been restricted at mount time
220 on the client (above and beyond ACL on servers) for
221 servers which do not support setting and viewing mode bits,
222 so allowing client to check permissions is useful */
223 return generic_permission(inode, mask, NULL);
224}
225
226static kmem_cache_t *cifs_inode_cachep;
227static kmem_cache_t *cifs_req_cachep;
228static kmem_cache_t *cifs_mid_cachep;
229kmem_cache_t *cifs_oplock_cachep;
230static kmem_cache_t *cifs_sm_req_cachep;
231mempool_t *cifs_sm_req_poolp;
232mempool_t *cifs_req_poolp;
233mempool_t *cifs_mid_poolp;
234
235static struct inode *
236cifs_alloc_inode(struct super_block *sb)
237{
238 struct cifsInodeInfo *cifs_inode;
239 cifs_inode = kmem_cache_alloc(cifs_inode_cachep, SLAB_KERNEL);
240 if (!cifs_inode)
241 return NULL;
242 cifs_inode->cifsAttrs = 0x20; /* default */
243 atomic_set(&cifs_inode->inUse, 0);
244 cifs_inode->time = 0;
245 /* Until the file is open and we have gotten oplock
246 info back from the server, can not assume caching of
247 file data or metadata */
248 cifs_inode->clientCanCacheRead = FALSE;
249 cifs_inode->clientCanCacheAll = FALSE;
250 cifs_inode->vfs_inode.i_blksize = CIFS_MAX_MSGSIZE;
251 cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */
252
253 INIT_LIST_HEAD(&cifs_inode->openFileList);
254 return &cifs_inode->vfs_inode;
255}
256
257static void
258cifs_destroy_inode(struct inode *inode)
259{
260 kmem_cache_free(cifs_inode_cachep, CIFS_I(inode));
261}
262
263/*
264 * cifs_show_options() is for displaying mount options in /proc/mounts.
265 * Not all settable options are displayed but most of the important
266 * ones are.
267 */
268static int
269cifs_show_options(struct seq_file *s, struct vfsmount *m)
270{
271 struct cifs_sb_info *cifs_sb;
272
273 cifs_sb = CIFS_SB(m->mnt_sb);
274
275 if (cifs_sb) {
276 if (cifs_sb->tcon) {
277 seq_printf(s, ",unc=%s", cifs_sb->tcon->treeName);
278 if (cifs_sb->tcon->ses) {
279 if (cifs_sb->tcon->ses->userName)
280 seq_printf(s, ",username=%s",
281 cifs_sb->tcon->ses->userName);
282 if(cifs_sb->tcon->ses->domainName)
283 seq_printf(s, ",domain=%s",
284 cifs_sb->tcon->ses->domainName);
285 }
286 }
287 seq_printf(s, ",rsize=%d",cifs_sb->rsize);
288 seq_printf(s, ",wsize=%d",cifs_sb->wsize);
289 }
290 return 0;
291}
292
293#ifdef CONFIG_CIFS_QUOTA
294int cifs_xquota_set(struct super_block * sb, int quota_type, qid_t qid,
295 struct fs_disk_quota * pdquota)
296{
297 int xid;
298 int rc = 0;
299 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
300 struct cifsTconInfo *pTcon;
301
302 if(cifs_sb)
303 pTcon = cifs_sb->tcon;
304 else
305 return -EIO;
306
307
308 xid = GetXid();
309 if(pTcon) {
310 cFYI(1,("set type: 0x%x id: %d",quota_type,qid));
311 } else {
312 return -EIO;
313 }
314
315 FreeXid(xid);
316 return rc;
317}
318
319int cifs_xquota_get(struct super_block * sb, int quota_type, qid_t qid,
320 struct fs_disk_quota * pdquota)
321{
322 int xid;
323 int rc = 0;
324 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
325 struct cifsTconInfo *pTcon;
326
327 if(cifs_sb)
328 pTcon = cifs_sb->tcon;
329 else
330 return -EIO;
331
332 xid = GetXid();
333 if(pTcon) {
334 cFYI(1,("set type: 0x%x id: %d",quota_type,qid));
335 } else {
336 rc = -EIO;
337 }
338
339 FreeXid(xid);
340 return rc;
341}
342
343int cifs_xstate_set(struct super_block * sb, unsigned int flags, int operation)
344{
345 int xid;
346 int rc = 0;
347 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
348 struct cifsTconInfo *pTcon;
349
350 if(cifs_sb)
351 pTcon = cifs_sb->tcon;
352 else
353 return -EIO;
354
355 xid = GetXid();
356 if(pTcon) {
357 cFYI(1,("flags: 0x%x operation: 0x%x",flags,operation));
358 } else {
359 rc = -EIO;
360 }
361
362 FreeXid(xid);
363 return rc;
364}
365
366int cifs_xstate_get(struct super_block * sb, struct fs_quota_stat *qstats)
367{
368 int xid;
369 int rc = 0;
370 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
371 struct cifsTconInfo *pTcon;
372
373 if(cifs_sb) {
374 pTcon = cifs_sb->tcon;
375 } else {
376 return -EIO;
377 }
378 xid = GetXid();
379 if(pTcon) {
380 cFYI(1,("pqstats %p",qstats));
381 } else {
382 rc = -EIO;
383 }
384
385 FreeXid(xid);
386 return rc;
387}
388
389static struct quotactl_ops cifs_quotactl_ops = {
390 .set_xquota = cifs_xquota_set,
391 .get_xquota = cifs_xquota_set,
392 .set_xstate = cifs_xstate_set,
393 .get_xstate = cifs_xstate_get,
394};
395#endif
396
397static int cifs_remount(struct super_block *sb, int *flags, char *data)
398{
399 *flags |= MS_NODIRATIME;
400 return 0;
401}
402
403struct super_operations cifs_super_ops = {
404 .read_inode = cifs_read_inode,
405 .put_super = cifs_put_super,
406 .statfs = cifs_statfs,
407 .alloc_inode = cifs_alloc_inode,
408 .destroy_inode = cifs_destroy_inode,
409/* .drop_inode = generic_delete_inode,
410 .delete_inode = cifs_delete_inode, *//* Do not need the above two functions
411 unless later we add lazy close of inodes or unless the kernel forgets to call
412 us with the same number of releases (closes) as opens */
413 .show_options = cifs_show_options,
414/* .umount_begin = cifs_umount_begin, *//* consider adding in the future */
415 .remount_fs = cifs_remount,
416};
417
418static struct super_block *
419cifs_get_sb(struct file_system_type *fs_type,
420 int flags, const char *dev_name, void *data)
421{
422 int rc;
423 struct super_block *sb = sget(fs_type, NULL, set_anon_super, NULL);
424
425 cFYI(1, ("Devname: %s flags: %d ", dev_name, flags));
426
427 if (IS_ERR(sb))
428 return sb;
429
430 sb->s_flags = flags;
431
432 rc = cifs_read_super(sb, data, dev_name, flags & MS_VERBOSE ? 1 : 0);
433 if (rc) {
434 up_write(&sb->s_umount);
435 deactivate_super(sb);
436 return ERR_PTR(rc);
437 }
438 sb->s_flags |= MS_ACTIVE;
439 return sb;
440}
441
442static ssize_t
443cifs_read_wrapper(struct file * file, char __user *read_data, size_t read_size,
444 loff_t * poffset)
445{
446 if(file->f_dentry == NULL)
447 return -EIO;
448 else if(file->f_dentry->d_inode == NULL)
449 return -EIO;
450
451 cFYI(1,("In read_wrapper size %zd at %lld",read_size,*poffset));
452
453 if(CIFS_I(file->f_dentry->d_inode)->clientCanCacheRead) {
454 return generic_file_read(file,read_data,read_size,poffset);
455 } else {
456 /* BB do we need to lock inode from here until after invalidate? */
457/* if(file->f_dentry->d_inode->i_mapping) {
458 filemap_fdatawrite(file->f_dentry->d_inode->i_mapping);
459 filemap_fdatawait(file->f_dentry->d_inode->i_mapping);
460 }*/
461/* cifs_revalidate(file->f_dentry);*/ /* BB fixme */
462
463 /* BB we should make timer configurable - perhaps
464 by simply calling cifs_revalidate here */
465 /* invalidate_remote_inode(file->f_dentry->d_inode);*/
466 return generic_file_read(file,read_data,read_size,poffset);
467 }
468}
469
470static ssize_t
471cifs_write_wrapper(struct file * file, const char __user *write_data,
472 size_t write_size, loff_t * poffset)
473{
474 ssize_t written;
475
476 if(file->f_dentry == NULL)
477 return -EIO;
478 else if(file->f_dentry->d_inode == NULL)
479 return -EIO;
480
481 cFYI(1,("In write_wrapper size %zd at %lld",write_size,*poffset));
482
483 written = generic_file_write(file,write_data,write_size,poffset);
484 if(!CIFS_I(file->f_dentry->d_inode)->clientCanCacheAll) {
485 if(file->f_dentry->d_inode->i_mapping) {
486 filemap_fdatawrite(file->f_dentry->d_inode->i_mapping);
487 }
488 }
489 return written;
490}
491
492
493static struct file_system_type cifs_fs_type = {
494 .owner = THIS_MODULE,
495 .name = "cifs",
496 .get_sb = cifs_get_sb,
497 .kill_sb = kill_anon_super,
498 /* .fs_flags */
499};
500struct inode_operations cifs_dir_inode_ops = {
501 .create = cifs_create,
502 .lookup = cifs_lookup,
503 .getattr = cifs_getattr,
504 .unlink = cifs_unlink,
505 .link = cifs_hardlink,
506 .mkdir = cifs_mkdir,
507 .rmdir = cifs_rmdir,
508 .rename = cifs_rename,
509 .permission = cifs_permission,
510/* revalidate:cifs_revalidate, */
511 .setattr = cifs_setattr,
512 .symlink = cifs_symlink,
513 .mknod = cifs_mknod,
514#ifdef CONFIG_CIFS_XATTR
515 .setxattr = cifs_setxattr,
516 .getxattr = cifs_getxattr,
517 .listxattr = cifs_listxattr,
518 .removexattr = cifs_removexattr,
519#endif
520};
521
522struct inode_operations cifs_file_inode_ops = {
523/* revalidate:cifs_revalidate, */
524 .setattr = cifs_setattr,
525 .getattr = cifs_getattr, /* do we need this anymore? */
526 .rename = cifs_rename,
527 .permission = cifs_permission,
528#ifdef CONFIG_CIFS_XATTR
529 .setxattr = cifs_setxattr,
530 .getxattr = cifs_getxattr,
531 .listxattr = cifs_listxattr,
532 .removexattr = cifs_removexattr,
533#endif
534};
535
536struct inode_operations cifs_symlink_inode_ops = {
537 .readlink = generic_readlink,
538 .follow_link = cifs_follow_link,
539 .put_link = cifs_put_link,
540 .permission = cifs_permission,
541 /* BB add the following two eventually */
542 /* revalidate: cifs_revalidate,
543 setattr: cifs_notify_change, *//* BB do we need notify change */
544#ifdef CONFIG_CIFS_XATTR
545 .setxattr = cifs_setxattr,
546 .getxattr = cifs_getxattr,
547 .listxattr = cifs_listxattr,
548 .removexattr = cifs_removexattr,
549#endif
550};
551
552struct file_operations cifs_file_ops = {
553 .read = cifs_read_wrapper,
554 .write = cifs_write_wrapper,
555 .open = cifs_open,
556 .release = cifs_close,
557 .lock = cifs_lock,
558 .fsync = cifs_fsync,
559 .flush = cifs_flush,
560 .mmap = cifs_file_mmap,
561 .sendfile = generic_file_sendfile,
c67593a0
SF
562#ifdef CONFIG_CIFS_POSIX
563 .ioctl = cifs_ioctl,
564#endif /* CONFIG_CIFS_POSIX */
565
1da177e4
LT
566#ifdef CONFIG_CIFS_EXPERIMENTAL
567 .readv = generic_file_readv,
568 .writev = generic_file_writev,
569 .aio_read = generic_file_aio_read,
570 .aio_write = generic_file_aio_write,
571 .dir_notify = cifs_dir_notify,
572#endif /* CONFIG_CIFS_EXPERIMENTAL */
573};
574
575struct file_operations cifs_file_direct_ops = {
576 /* no mmap, no aio, no readv -
577 BB reevaluate whether they can be done with directio, no cache */
578 .read = cifs_user_read,
579 .write = cifs_user_write,
580 .open = cifs_open,
581 .release = cifs_close,
582 .lock = cifs_lock,
583 .fsync = cifs_fsync,
584 .flush = cifs_flush,
585 .sendfile = generic_file_sendfile, /* BB removeme BB */
c67593a0
SF
586#ifdef CONFIG_CIFS_POSIX
587 .ioctl = cifs_ioctl,
588#endif /* CONFIG_CIFS_POSIX */
589
1da177e4
LT
590#ifdef CONFIG_CIFS_EXPERIMENTAL
591 .dir_notify = cifs_dir_notify,
592#endif /* CONFIG_CIFS_EXPERIMENTAL */
593};
594
595struct file_operations cifs_dir_ops = {
596 .readdir = cifs_readdir,
597 .release = cifs_closedir,
598 .read = generic_read_dir,
599#ifdef CONFIG_CIFS_EXPERIMENTAL
600 .dir_notify = cifs_dir_notify,
601#endif /* CONFIG_CIFS_EXPERIMENTAL */
602};
603
604static void
605cifs_init_once(void *inode, kmem_cache_t * cachep, unsigned long flags)
606{
607 struct cifsInodeInfo *cifsi = inode;
608
609 if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) ==
610 SLAB_CTOR_CONSTRUCTOR) {
611 inode_init_once(&cifsi->vfs_inode);
612 INIT_LIST_HEAD(&cifsi->lockList);
613 }
614}
615
616static int
617cifs_init_inodecache(void)
618{
619 cifs_inode_cachep = kmem_cache_create("cifs_inode_cache",
620 sizeof (struct cifsInodeInfo),
621 0, SLAB_RECLAIM_ACCOUNT,
622 cifs_init_once, NULL);
623 if (cifs_inode_cachep == NULL)
624 return -ENOMEM;
625
626 return 0;
627}
628
629static void
630cifs_destroy_inodecache(void)
631{
632 if (kmem_cache_destroy(cifs_inode_cachep))
633 printk(KERN_WARNING "cifs_inode_cache: error freeing\n");
634}
635
636static int
637cifs_init_request_bufs(void)
638{
639 if(CIFSMaxBufSize < 8192) {
640 /* Buffer size can not be smaller than 2 * PATH_MAX since maximum
641 Unicode path name has to fit in any SMB/CIFS path based frames */
642 CIFSMaxBufSize = 8192;
643 } else if (CIFSMaxBufSize > 1024*127) {
644 CIFSMaxBufSize = 1024 * 127;
645 } else {
646 CIFSMaxBufSize &= 0x1FE00; /* Round size to even 512 byte mult*/
647 }
648/* cERROR(1,("CIFSMaxBufSize %d 0x%x",CIFSMaxBufSize,CIFSMaxBufSize)); */
649 cifs_req_cachep = kmem_cache_create("cifs_request",
650 CIFSMaxBufSize +
651 MAX_CIFS_HDR_SIZE, 0,
652 SLAB_HWCACHE_ALIGN, NULL, NULL);
653 if (cifs_req_cachep == NULL)
654 return -ENOMEM;
655
656 if(cifs_min_rcv < 1)
657 cifs_min_rcv = 1;
658 else if (cifs_min_rcv > 64) {
659 cifs_min_rcv = 64;
660 cERROR(1,("cifs_min_rcv set to maximum (64)"));
661 }
662
663 cifs_req_poolp = mempool_create(cifs_min_rcv,
664 mempool_alloc_slab,
665 mempool_free_slab,
666 cifs_req_cachep);
667
668 if(cifs_req_poolp == NULL) {
669 kmem_cache_destroy(cifs_req_cachep);
670 return -ENOMEM;
671 }
672 /* 256 (MAX_CIFS_HDR_SIZE bytes is enough for most SMB responses and
673 almost all handle based requests (but not write response, nor is it
674 sufficient for path based requests). A smaller size would have
675 been more efficient (compacting multiple slab items on one 4k page)
676 for the case in which debug was on, but this larger size allows
677 more SMBs to use small buffer alloc and is still much more
678 efficient to alloc 1 per page off the slab compared to 17K (5page)
679 alloc of large cifs buffers even when page debugging is on */
680 cifs_sm_req_cachep = kmem_cache_create("cifs_small_rq",
681 MAX_CIFS_HDR_SIZE, 0, SLAB_HWCACHE_ALIGN, NULL, NULL);
682 if (cifs_sm_req_cachep == NULL) {
683 mempool_destroy(cifs_req_poolp);
684 kmem_cache_destroy(cifs_req_cachep);
685 return -ENOMEM;
686 }
687
688 if(cifs_min_small < 2)
689 cifs_min_small = 2;
690 else if (cifs_min_small > 256) {
691 cifs_min_small = 256;
692 cFYI(1,("cifs_min_small set to maximum (256)"));
693 }
694
695 cifs_sm_req_poolp = mempool_create(cifs_min_small,
696 mempool_alloc_slab,
697 mempool_free_slab,
698 cifs_sm_req_cachep);
699
700 if(cifs_sm_req_poolp == NULL) {
701 mempool_destroy(cifs_req_poolp);
702 kmem_cache_destroy(cifs_req_cachep);
703 kmem_cache_destroy(cifs_sm_req_cachep);
704 return -ENOMEM;
705 }
706
707 return 0;
708}
709
710static void
711cifs_destroy_request_bufs(void)
712{
713 mempool_destroy(cifs_req_poolp);
714 if (kmem_cache_destroy(cifs_req_cachep))
715 printk(KERN_WARNING
716 "cifs_destroy_request_cache: error not all structures were freed\n");
717 mempool_destroy(cifs_sm_req_poolp);
718 if (kmem_cache_destroy(cifs_sm_req_cachep))
719 printk(KERN_WARNING
720 "cifs_destroy_request_cache: cifs_small_rq free error\n");
721}
722
723static int
724cifs_init_mids(void)
725{
726 cifs_mid_cachep = kmem_cache_create("cifs_mpx_ids",
727 sizeof (struct mid_q_entry), 0,
728 SLAB_HWCACHE_ALIGN, NULL, NULL);
729 if (cifs_mid_cachep == NULL)
730 return -ENOMEM;
731
732 cifs_mid_poolp = mempool_create(3 /* a reasonable min simultan opers */,
733 mempool_alloc_slab,
734 mempool_free_slab,
735 cifs_mid_cachep);
736 if(cifs_mid_poolp == NULL) {
737 kmem_cache_destroy(cifs_mid_cachep);
738 return -ENOMEM;
739 }
740
741 cifs_oplock_cachep = kmem_cache_create("cifs_oplock_structs",
742 sizeof (struct oplock_q_entry), 0,
743 SLAB_HWCACHE_ALIGN, NULL, NULL);
744 if (cifs_oplock_cachep == NULL) {
745 kmem_cache_destroy(cifs_mid_cachep);
746 mempool_destroy(cifs_mid_poolp);
747 return -ENOMEM;
748 }
749
750 return 0;
751}
752
753static void
754cifs_destroy_mids(void)
755{
756 mempool_destroy(cifs_mid_poolp);
757 if (kmem_cache_destroy(cifs_mid_cachep))
758 printk(KERN_WARNING
759 "cifs_destroy_mids: error not all structures were freed\n");
760
761 if (kmem_cache_destroy(cifs_oplock_cachep))
762 printk(KERN_WARNING
763 "error not all oplock structures were freed\n");
764}
765
766static int cifs_oplock_thread(void * dummyarg)
767{
768 struct oplock_q_entry * oplock_item;
769 struct cifsTconInfo *pTcon;
770 struct inode * inode;
771 __u16 netfid;
772 int rc;
773
774 daemonize("cifsoplockd");
775 allow_signal(SIGTERM);
776
777 oplockThread = current;
778 do {
779 set_current_state(TASK_INTERRUPTIBLE);
780
781 schedule_timeout(1*HZ);
782 spin_lock(&GlobalMid_Lock);
783 if(list_empty(&GlobalOplock_Q)) {
784 spin_unlock(&GlobalMid_Lock);
785 set_current_state(TASK_INTERRUPTIBLE);
786 schedule_timeout(39*HZ);
787 } else {
788 oplock_item = list_entry(GlobalOplock_Q.next,
789 struct oplock_q_entry, qhead);
790 if(oplock_item) {
791 cFYI(1,("found oplock item to write out"));
792 pTcon = oplock_item->tcon;
793 inode = oplock_item->pinode;
794 netfid = oplock_item->netfid;
795 spin_unlock(&GlobalMid_Lock);
796 DeleteOplockQEntry(oplock_item);
797 /* can not grab inode sem here since it would
798 deadlock when oplock received on delete
799 since vfs_unlink holds the i_sem across
800 the call */
801 /* down(&inode->i_sem);*/
802 if (S_ISREG(inode->i_mode)) {
803 rc = filemap_fdatawrite(inode->i_mapping);
804 if(CIFS_I(inode)->clientCanCacheRead == 0) {
805 filemap_fdatawait(inode->i_mapping);
806 invalidate_remote_inode(inode);
807 }
808 } else
809 rc = 0;
810 /* up(&inode->i_sem);*/
811 if (rc)
812 CIFS_I(inode)->write_behind_rc = rc;
813 cFYI(1,("Oplock flush inode %p rc %d",inode,rc));
814
815 /* releasing a stale oplock after recent reconnection
816 of smb session using a now incorrect file
817 handle is not a data integrity issue but do
818 not bother sending an oplock release if session
819 to server still is disconnected since oplock
820 already released by the server in that case */
821 if(pTcon->tidStatus != CifsNeedReconnect) {
822 rc = CIFSSMBLock(0, pTcon, netfid,
823 0 /* len */ , 0 /* offset */, 0,
824 0, LOCKING_ANDX_OPLOCK_RELEASE,
825 0 /* wait flag */);
826 cFYI(1,("Oplock release rc = %d ",rc));
827 }
828 } else
829 spin_unlock(&GlobalMid_Lock);
830 }
831 } while(!signal_pending(current));
832 complete_and_exit (&cifs_oplock_exited, 0);
833}
834
835static int __init
836init_cifs(void)
837{
838 int rc = 0;
839#ifdef CONFIG_PROC_FS
840 cifs_proc_init();
841#endif
842 INIT_LIST_HEAD(&GlobalServerList); /* BB not implemented yet */
843 INIT_LIST_HEAD(&GlobalSMBSessionList);
844 INIT_LIST_HEAD(&GlobalTreeConnectionList);
845 INIT_LIST_HEAD(&GlobalOplock_Q);
846/*
847 * Initialize Global counters
848 */
849 atomic_set(&sesInfoAllocCount, 0);
850 atomic_set(&tconInfoAllocCount, 0);
851 atomic_set(&tcpSesAllocCount,0);
852 atomic_set(&tcpSesReconnectCount, 0);
853 atomic_set(&tconInfoReconnectCount, 0);
854
855 atomic_set(&bufAllocCount, 0);
856 atomic_set(&midCount, 0);
857 GlobalCurrentXid = 0;
858 GlobalTotalActiveXid = 0;
859 GlobalMaxActiveXid = 0;
860 rwlock_init(&GlobalSMBSeslock);
861 spin_lock_init(&GlobalMid_Lock);
862
863 if(cifs_max_pending < 2) {
864 cifs_max_pending = 2;
865 cFYI(1,("cifs_max_pending set to min of 2"));
866 } else if(cifs_max_pending > 256) {
867 cifs_max_pending = 256;
868 cFYI(1,("cifs_max_pending set to max of 256"));
869 }
870
871 rc = cifs_init_inodecache();
872 if (!rc) {
873 rc = cifs_init_mids();
874 if (!rc) {
875 rc = cifs_init_request_bufs();
876 if (!rc) {
877 rc = register_filesystem(&cifs_fs_type);
878 if (!rc) {
879 rc = (int)kernel_thread(cifs_oplock_thread, NULL,
880 CLONE_FS | CLONE_FILES | CLONE_VM);
881 if(rc > 0)
882 return 0;
883 else
884 cERROR(1,("error %d create oplock thread",rc));
885 }
886 cifs_destroy_request_bufs();
887 }
888 cifs_destroy_mids();
889 }
890 cifs_destroy_inodecache();
891 }
892#ifdef CONFIG_PROC_FS
893 cifs_proc_clean();
894#endif
895 return rc;
896}
897
898static void __exit
899exit_cifs(void)
900{
901 cFYI(0, ("In unregister ie exit_cifs"));
902#ifdef CONFIG_PROC_FS
903 cifs_proc_clean();
904#endif
905 unregister_filesystem(&cifs_fs_type);
906 cifs_destroy_inodecache();
907 cifs_destroy_mids();
908 cifs_destroy_request_bufs();
909 if(oplockThread) {
910 send_sig(SIGTERM, oplockThread, 1);
911 wait_for_completion(&cifs_oplock_exited);
912 }
913}
914
915MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>");
916MODULE_LICENSE("GPL"); /* combination of LGPL + GPL source behaves as GPL */
917MODULE_DESCRIPTION
918 ("VFS to access servers complying with the SNIA CIFS Specification e.g. Samba and Windows");
919MODULE_VERSION(CIFS_VERSION);
920module_init(init_cifs)
921module_exit(exit_cifs)