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