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