vserver 1.9.3
[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) {
259                                 if (cifs_sb->tcon->ses->userName)
260                                         seq_printf(s, ",username=%s",
261                                            cifs_sb->tcon->ses->userName);
262                                 if(cifs_sb->tcon->ses->domainName)
263                                         seq_printf(s, ",domain=%s",
264                                            cifs_sb->tcon->ses->domainName);
265                         }
266                 }
267                 seq_printf(s, ",rsize=%d",cifs_sb->rsize);
268                 seq_printf(s, ",wsize=%d",cifs_sb->wsize);
269         }
270         return 0;
271 }
272
273 #ifdef CONFIG_CIFS_QUOTA
274 int cifs_xquota_set(struct super_block * sb, int quota_type, qid_t qid,
275                 struct fs_disk_quota * pdquota)
276 {
277         int xid;
278         int rc = 0;
279         struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
280         struct cifsTconInfo *pTcon;
281         
282         if(cifs_sb)
283                 pTcon = cifs_sb->tcon;
284         else
285                 return -EIO;
286
287
288         xid = GetXid();
289         if(pTcon) {
290                 cFYI(1,("set type: 0x%x id: %d",quota_type,qid));               
291         } else {
292                 return -EIO;
293         }
294
295         FreeXid(xid);
296         return rc;
297 }
298
299 int cifs_xquota_get(struct super_block * sb, int quota_type, qid_t qid,
300                 struct fs_disk_quota * pdquota)
301 {
302         int xid;
303         int rc = 0;
304         struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
305         struct cifsTconInfo *pTcon;
306
307         if(cifs_sb)
308                 pTcon = cifs_sb->tcon;
309         else
310                 return -EIO;
311
312         xid = GetXid();
313         if(pTcon) {
314                 cFYI(1,("set type: 0x%x id: %d",quota_type,qid));
315         } else {
316                 rc = -EIO;
317         }
318
319         FreeXid(xid);
320         return rc;
321 }
322
323 int cifs_xstate_set(struct super_block * sb, unsigned int flags, int operation)
324 {
325         int xid; 
326         int rc = 0;
327         struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
328         struct cifsTconInfo *pTcon;
329
330         if(cifs_sb)
331                 pTcon = cifs_sb->tcon;
332         else
333                 return -EIO;
334
335         xid = GetXid();
336         if(pTcon) {
337                 cFYI(1,("flags: 0x%x operation: 0x%x",flags,operation));
338         } else {
339                 rc = -EIO;
340         }
341
342         FreeXid(xid);
343         return rc;
344 }
345
346 int cifs_xstate_get(struct super_block * sb, struct fs_quota_stat *qstats)
347 {
348         int xid;
349         int rc = 0;
350         struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
351         struct cifsTconInfo *pTcon;
352
353         if(cifs_sb) {
354                 pTcon = cifs_sb->tcon;
355         } else {
356                 return -EIO;
357         }
358         xid = GetXid();
359         if(pTcon) {
360                 cFYI(1,("pqstats %p",qstats));          
361         } else {
362                 rc = -EIO;
363         }
364
365         FreeXid(xid);
366         return rc;
367 }
368
369 static struct quotactl_ops cifs_quotactl_ops = {
370         .set_xquota     = cifs_xquota_set,
371         .get_xquota     = cifs_xquota_set,
372         .set_xstate     = cifs_xstate_set,
373         .get_xstate     = cifs_xstate_get,
374 };
375 #endif
376
377 static int cifs_remount(struct super_block *sb, int *flags, char *data)
378 {
379         *flags |= MS_NODIRATIME;
380         return 0;
381 }
382
383 struct super_operations cifs_super_ops = {
384         .read_inode = cifs_read_inode,
385         .put_super = cifs_put_super,
386         .statfs = cifs_statfs,
387         .alloc_inode = cifs_alloc_inode,
388         .destroy_inode = cifs_destroy_inode,
389 /*      .drop_inode         = generic_delete_inode, 
390         .delete_inode   = cifs_delete_inode,  *//* Do not need the above two functions     
391    unless later we add lazy close of inodes or unless the kernel forgets to call
392    us with the same number of releases (closes) as opens */
393         .show_options = cifs_show_options,
394 /*    .umount_begin   = cifs_umount_begin, *//* consider adding in the future */
395         .remount_fs = cifs_remount,
396 };
397
398 static struct super_block *
399 cifs_get_sb(struct file_system_type *fs_type,
400             int flags, const char *dev_name, void *data)
401 {
402         int rc;
403         struct super_block *sb = sget(fs_type, NULL, set_anon_super, NULL);
404
405         cFYI(1, ("Devname: %s flags: %d ", dev_name, flags));
406
407         if (IS_ERR(sb))
408                 return sb;
409
410         sb->s_flags = flags;
411
412         rc = cifs_read_super(sb, data, dev_name, flags & MS_VERBOSE ? 1 : 0);
413         if (rc) {
414                 up_write(&sb->s_umount);
415                 deactivate_super(sb);
416                 return ERR_PTR(rc);
417         }
418         sb->s_flags |= MS_ACTIVE;
419         return sb;
420 }
421
422 static ssize_t
423 cifs_read_wrapper(struct file * file, char __user *read_data, size_t read_size,
424           loff_t * poffset)
425 {
426         if(file == NULL)
427                 return -EIO;
428         else if(file->f_dentry == NULL)
429                 return -EIO;
430         else if(file->f_dentry->d_inode == NULL)
431                 return -EIO;
432
433         cFYI(1,("In read_wrapper size %zd at %lld",read_size,*poffset));
434         if(CIFS_I(file->f_dentry->d_inode)->clientCanCacheRead) {
435                 return generic_file_read(file,read_data,read_size,poffset);
436         } else {
437                 /* BB do we need to lock inode from here until after invalidate? */
438 /*              if(file->f_dentry->d_inode->i_mapping) {
439                         filemap_fdatawrite(file->f_dentry->d_inode->i_mapping);
440                         filemap_fdatawait(file->f_dentry->d_inode->i_mapping);
441                 }*/
442 /*              cifs_revalidate(file->f_dentry);*/ /* BB fixme */
443
444                 /* BB we should make timer configurable - perhaps 
445                    by simply calling cifs_revalidate here */
446                 /* invalidate_remote_inode(file->f_dentry->d_inode);*/
447                 return generic_file_read(file,read_data,read_size,poffset);
448         }
449 }
450
451 static ssize_t
452 cifs_write_wrapper(struct file * file, const char __user *write_data,
453            size_t write_size, loff_t * poffset) 
454 {
455         ssize_t written;
456
457         if(file == NULL)
458                 return -EIO;
459         else if(file->f_dentry == NULL)
460                 return -EIO;
461         else if(file->f_dentry->d_inode == NULL)
462                 return -EIO;
463
464         cFYI(1,("In write_wrapper size %zd at %lld",write_size,*poffset));
465
466         /* check whether we can cache writes locally */
467         written = generic_file_write(file,write_data,write_size,poffset);
468         if(!CIFS_I(file->f_dentry->d_inode)->clientCanCacheAll)  {
469                 if(file->f_dentry->d_inode->i_mapping) {
470                         filemap_fdatawrite(file->f_dentry->d_inode->i_mapping);
471                 }
472         }
473         return written;
474 }
475
476
477 static struct file_system_type cifs_fs_type = {
478         .owner = THIS_MODULE,
479         .name = "cifs",
480         .get_sb = cifs_get_sb,
481         .kill_sb = kill_anon_super,
482         /*  .fs_flags */
483 };
484 struct inode_operations cifs_dir_inode_ops = {
485         .create = cifs_create,
486         .lookup = cifs_lookup,
487         .getattr = cifs_getattr,
488         .unlink = cifs_unlink,
489         .link = cifs_hardlink,
490         .mkdir = cifs_mkdir,
491         .rmdir = cifs_rmdir,
492         .rename = cifs_rename,
493         .permission = cifs_permission,
494 /*      revalidate:cifs_revalidate,   */
495         .setattr = cifs_setattr,
496         .symlink = cifs_symlink,
497         .mknod   = cifs_mknod,
498 };
499
500 struct inode_operations cifs_file_inode_ops = {
501 /*      revalidate:cifs_revalidate, */
502         .setattr = cifs_setattr,
503         .getattr = cifs_getattr, /* do we need this anymore? */
504         .rename = cifs_rename,
505         .permission = cifs_permission,
506 #ifdef CONFIG_CIFS_XATTR
507         .setxattr = cifs_setxattr,
508         .getxattr = cifs_getxattr,
509         .listxattr = cifs_listxattr,
510         .removexattr = cifs_removexattr,
511 #endif 
512 };
513
514 struct inode_operations cifs_symlink_inode_ops = {
515         .readlink = generic_readlink, 
516         .follow_link = cifs_follow_link,
517         .put_link = cifs_put_link,
518         .permission = cifs_permission,
519         /* BB add the following two eventually */
520         /* revalidate: cifs_revalidate,
521            setattr:    cifs_notify_change, *//* BB do we need notify change */
522 #ifdef CONFIG_CIFS_XATTR
523         .setxattr = cifs_setxattr,
524         .getxattr = cifs_getxattr,
525         .listxattr = cifs_listxattr,
526         .removexattr = cifs_removexattr,
527 #endif 
528 };
529
530 struct file_operations cifs_file_ops = {
531         .read = cifs_read_wrapper,
532         .write = cifs_write_wrapper, 
533         .open = cifs_open,
534         .release = cifs_close,
535         .lock = cifs_lock,
536         .fsync = cifs_fsync,
537         .flush = cifs_flush,
538         .mmap  = cifs_file_mmap,
539         .sendfile = generic_file_sendfile,
540         .dir_notify = cifs_dir_notify,
541 };
542
543 struct file_operations cifs_dir_ops = {
544         .readdir = cifs_readdir,
545         .release = cifs_closedir,
546         .read    = generic_read_dir,
547         .dir_notify = cifs_dir_notify,
548 };
549
550 static void
551 cifs_init_once(void *inode, kmem_cache_t * cachep, unsigned long flags)
552 {
553         struct cifsInodeInfo *cifsi = (struct cifsInodeInfo *) inode;
554
555         if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) ==
556             SLAB_CTOR_CONSTRUCTOR) {
557                 inode_init_once(&cifsi->vfs_inode);
558                 INIT_LIST_HEAD(&cifsi->lockList);
559         }
560 }
561
562 static int
563 cifs_init_inodecache(void)
564 {
565         cifs_inode_cachep = kmem_cache_create("cifs_inode_cache",
566                                               sizeof (struct cifsInodeInfo),
567                                               0, SLAB_RECLAIM_ACCOUNT,
568                                               cifs_init_once, NULL);
569         if (cifs_inode_cachep == NULL)
570                 return -ENOMEM;
571
572         return 0;
573 }
574
575 static void
576 cifs_destroy_inodecache(void)
577 {
578         if (kmem_cache_destroy(cifs_inode_cachep))
579                 printk(KERN_WARNING "cifs_inode_cache: error freeing\n");
580 }
581
582 static int
583 cifs_init_request_bufs(void)
584 {
585         cifs_req_cachep = kmem_cache_create("cifs_request",
586                                             CIFS_MAX_MSGSIZE +
587                                             MAX_CIFS_HDR_SIZE, 0,
588                                             SLAB_HWCACHE_ALIGN, NULL, NULL);
589         if (cifs_req_cachep == NULL)
590                 return -ENOMEM;
591
592         cifs_req_poolp = mempool_create(CIFS_MIN_RCV_POOL,
593                                         mempool_alloc_slab,
594                                         mempool_free_slab,
595                                         cifs_req_cachep);
596
597         if(cifs_req_poolp == NULL) {
598                 kmem_cache_destroy(cifs_req_cachep);
599                 return -ENOMEM;
600         }
601
602         return 0;
603 }
604
605 static void
606 cifs_destroy_request_bufs(void)
607 {
608         mempool_destroy(cifs_req_poolp);
609         if (kmem_cache_destroy(cifs_req_cachep))
610                 printk(KERN_WARNING
611                        "cifs_destroy_request_cache: error not all structures were freed\n");
612 }
613
614 static int
615 cifs_init_mids(void)
616 {
617         cifs_mid_cachep = kmem_cache_create("cifs_mpx_ids",
618                                 sizeof (struct mid_q_entry), 0,
619                                 SLAB_HWCACHE_ALIGN, NULL, NULL);
620         if (cifs_mid_cachep == NULL)
621                 return -ENOMEM;
622
623         cifs_mid_poolp = mempool_create(3 /* a reasonable min simultan opers */,
624                                         mempool_alloc_slab,
625                                         mempool_free_slab,
626                                         cifs_mid_cachep);
627         if(cifs_mid_poolp == NULL) {
628                 kmem_cache_destroy(cifs_mid_cachep);
629                 return -ENOMEM;
630         }
631
632         cifs_oplock_cachep = kmem_cache_create("cifs_oplock_structs",
633                                 sizeof (struct oplock_q_entry), 0,
634                                 SLAB_HWCACHE_ALIGN, NULL, NULL);
635         if (cifs_oplock_cachep == NULL) {
636                 kmem_cache_destroy(cifs_mid_cachep);
637                 mempool_destroy(cifs_mid_poolp);
638                 return -ENOMEM;
639         }
640
641         return 0;
642 }
643
644 static void
645 cifs_destroy_mids(void)
646 {
647         mempool_destroy(cifs_mid_poolp);
648         if (kmem_cache_destroy(cifs_mid_cachep))
649                 printk(KERN_WARNING
650                        "cifs_destroy_mids: error not all structures were freed\n");
651
652         if (kmem_cache_destroy(cifs_oplock_cachep))
653                 printk(KERN_WARNING
654                        "error not all oplock structures were freed\n");
655 }
656
657 static int cifs_oplock_thread(void * dummyarg)
658 {
659         struct oplock_q_entry * oplock_item;
660         struct cifsTconInfo *pTcon;
661         struct inode * inode;
662         __u16  netfid;
663         int rc;
664
665         daemonize("cifsoplockd");
666         allow_signal(SIGTERM);
667
668         oplockThread = current;
669         do {
670                 set_current_state(TASK_INTERRUPTIBLE);
671                 
672                 schedule_timeout(1*HZ);  
673                 spin_lock(&GlobalMid_Lock);
674                 if(list_empty(&GlobalOplock_Q)) {
675                         spin_unlock(&GlobalMid_Lock);
676                         set_current_state(TASK_INTERRUPTIBLE);
677                         schedule_timeout(39*HZ);
678                 } else {
679                         oplock_item = list_entry(GlobalOplock_Q.next, 
680                                 struct oplock_q_entry, qhead);
681                         if(oplock_item) {
682                                 cFYI(1,("found oplock item to write out")); 
683                                 pTcon = oplock_item->tcon;
684                                 inode = oplock_item->pinode;
685                                 netfid = oplock_item->netfid;
686                                 spin_unlock(&GlobalMid_Lock);
687                                 DeleteOplockQEntry(oplock_item);
688                                 /* can not grab inode sem here since it would
689                                 deadlock when oplock received on delete 
690                                 since vfs_unlink holds the i_sem across
691                                 the call */
692                                 /* down(&inode->i_sem);*/
693                                 if (S_ISREG(inode->i_mode)) {
694                                         rc = filemap_fdatawrite(inode->i_mapping);
695                                         if(CIFS_I(inode)->clientCanCacheRead == 0) {
696                                                 filemap_fdatawait(inode->i_mapping);
697                                                 invalidate_remote_inode(inode);
698                                         }
699                                 } else
700                                         rc = 0;
701                                 /* up(&inode->i_sem);*/
702                                 if (rc)
703                                         CIFS_I(inode)->write_behind_rc = rc;
704                                 cFYI(1,("Oplock flush inode %p rc %d",inode,rc));
705
706                                 /* releasing a stale oplock after recent reconnection 
707                                 of smb session using a now incorrect file 
708                                 handle is not a data integrity issue but do  
709                                 not bother sending an oplock release if session 
710                                 to server still is disconnected since oplock 
711                                 already released by the server in that case */
712                                 if(pTcon->tidStatus != CifsNeedReconnect) {
713                                     rc = CIFSSMBLock(0, pTcon, netfid,
714                                             0 /* len */ , 0 /* offset */, 0, 
715                                             0, LOCKING_ANDX_OPLOCK_RELEASE,
716                                             0 /* wait flag */);
717                                         cFYI(1,("Oplock release rc = %d ",rc));
718                                 }
719                         } else
720                                 spin_unlock(&GlobalMid_Lock);
721                 }
722         } while(!signal_pending(current));
723         complete_and_exit (&cifs_oplock_exited, 0);
724 }
725
726 static int __init
727 init_cifs(void)
728 {
729         int rc = 0;
730 #ifdef CONFIG_PROC_FS
731         cifs_proc_init();
732 #endif
733         INIT_LIST_HEAD(&GlobalServerList);      /* BB not implemented yet */
734         INIT_LIST_HEAD(&GlobalSMBSessionList);
735         INIT_LIST_HEAD(&GlobalTreeConnectionList);
736         INIT_LIST_HEAD(&GlobalOplock_Q);
737 /*
738  *  Initialize Global counters
739  */
740         atomic_set(&sesInfoAllocCount, 0);
741         atomic_set(&tconInfoAllocCount, 0);
742         atomic_set(&tcpSesAllocCount,0);
743         atomic_set(&tcpSesReconnectCount, 0);
744         atomic_set(&tconInfoReconnectCount, 0);
745
746         atomic_set(&bufAllocCount, 0);
747         atomic_set(&midCount, 0);
748         GlobalCurrentXid = 0;
749         GlobalTotalActiveXid = 0;
750         GlobalMaxActiveXid = 0;
751         GlobalSMBSeslock = RW_LOCK_UNLOCKED;
752         GlobalMid_Lock = SPIN_LOCK_UNLOCKED;
753
754         rc = cifs_init_inodecache();
755         if (!rc) {
756                 rc = cifs_init_mids();
757                 if (!rc) {
758                         rc = cifs_init_request_bufs();
759                         if (!rc) {
760                                 rc = register_filesystem(&cifs_fs_type);
761                                 if (!rc) {                
762                                         rc = (int)kernel_thread(cifs_oplock_thread, NULL, 
763                                                 CLONE_FS | CLONE_FILES | CLONE_VM);
764                                         if(rc > 0)
765                                                 return 0;
766                                         else 
767                                                 cERROR(1,("error %d create oplock thread",rc));
768                                 }
769                                 cifs_destroy_request_bufs();
770                         }
771                         cifs_destroy_mids();
772                 }
773                 cifs_destroy_inodecache();
774         }
775 #ifdef CONFIG_PROC_FS
776         cifs_proc_clean();
777 #endif
778         return rc;
779 }
780
781 static void __exit
782 exit_cifs(void)
783 {
784         cFYI(0, ("In unregister ie exit_cifs"));
785 #ifdef CONFIG_PROC_FS
786         cifs_proc_clean();
787 #endif
788         unregister_filesystem(&cifs_fs_type);
789         cifs_destroy_inodecache();
790         cifs_destroy_mids();
791         cifs_destroy_request_bufs();
792         if(oplockThread) {
793                 send_sig(SIGTERM, oplockThread, 1);
794                 wait_for_completion(&cifs_oplock_exited);
795         }
796 }
797
798 MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>");
799 MODULE_LICENSE("GPL");          /* combination of LGPL + GPL source behaves as GPL */
800 MODULE_DESCRIPTION
801     ("VFS to access servers complying with the SNIA CIFS Specification e.g. Samba and Windows");
802 MODULE_VERSION(CIFS_VERSION);
803 module_init(init_cifs)
804 module_exit(exit_cifs)