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