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