]> bbs.cooldavid.org Git - net-next-2.6.git/blame - fs/cifs/cifsfs.c
[CIFS] Do not send newer QFSInfo to legacy servers which can not support it
[net-next-2.6.git] / fs / cifs / cifsfs.c
CommitLineData
1da177e4
LT
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>
6ab16d24 35#include <linux/delay.h>
45af7a0f 36#include <linux/kthread.h>
1da177e4
LT
37#include "cifsfs.h"
38#include "cifspdu.h"
39#define DECLARE_GLOBALS_HERE
40#include "cifsglob.h"
41#include "cifsproto.h"
42#include "cifs_debug.h"
43#include "cifs_fs_sb.h"
44#include <linux/mm.h>
45#define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDUs */
46
47#ifdef CONFIG_CIFS_QUOTA
48static struct quotactl_ops cifs_quotactl_ops;
49#endif
50
51int cifsFYI = 0;
52int cifsERROR = 1;
53int traceSMB = 0;
54unsigned int oplockEnabled = 1;
55unsigned int experimEnabled = 0;
56unsigned int linuxExtEnabled = 1;
57unsigned int lookupCacheEnabled = 1;
58unsigned int multiuser_mount = 0;
3979877e
SF
59unsigned int extended_security = CIFSSEC_DEF;
60/* unsigned int ntlmv2_support = 0; */
1da177e4
LT
61unsigned int sign_CIFS_PDUs = 1;
62extern struct task_struct * oplockThread; /* remove sparse warning */
63struct task_struct * oplockThread = NULL;
8d0d5094
SF
64extern struct task_struct * dnotifyThread; /* remove sparse warning */
65struct task_struct * dnotifyThread = NULL;
e33c74d0 66static struct super_operations cifs_super_ops;
1da177e4
LT
67unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;
68module_param(CIFSMaxBufSize, int, 0);
69MODULE_PARM_DESC(CIFSMaxBufSize,"Network buffer size (not including header). Default: 16384 Range: 8192 to 130048");
70unsigned int cifs_min_rcv = CIFS_MIN_RCV_POOL;
71module_param(cifs_min_rcv, int, 0);
72MODULE_PARM_DESC(cifs_min_rcv,"Network buffers in pool. Default: 4 Range: 1 to 64");
73unsigned int cifs_min_small = 30;
74module_param(cifs_min_small, int, 0);
75MODULE_PARM_DESC(cifs_min_small,"Small network buffers in pool. Default: 30 Range: 2 to 256");
76unsigned int cifs_max_pending = CIFS_MAX_REQ;
77module_param(cifs_max_pending, int, 0);
78MODULE_PARM_DESC(cifs_max_pending,"Simultaneous requests to server. Default: 50 Range: 2 to 256");
79
1da177e4
LT
80extern mempool_t *cifs_sm_req_poolp;
81extern mempool_t *cifs_req_poolp;
82extern mempool_t *cifs_mid_poolp;
83
84extern kmem_cache_t *cifs_oplock_cachep;
85
86static int
87cifs_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 */
a048d7a8 95 sb->s_fs_info = kzalloc(sizeof(struct cifs_sb_info),GFP_KERNEL);
1da177e4
LT
96 cifs_sb = CIFS_SB(sb);
97 if(cifs_sb == NULL)
98 return -ENOMEM;
1da177e4
LT
99
100 rc = cifs_mount(sb, cifs_sb, data, devname);
101
102 if (rc) {
103 if (!silent)
104 cERROR(1,
105 ("cifs_mount failed w/return code = %d", rc));
106 goto out_mount_failed;
107 }
108
109 sb->s_magic = CIFS_MAGIC_NUMBER;
110 sb->s_op = &cifs_super_ops;
111/* if(cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512)
112 sb->s_blocksize = cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */
113#ifdef CONFIG_CIFS_QUOTA
114 sb->s_qcop = &cifs_quotactl_ops;
115#endif
116 sb->s_blocksize = CIFS_MAX_MSGSIZE;
117 sb->s_blocksize_bits = 14; /* default 2**14 = CIFS_MAX_MSGSIZE */
118 inode = iget(sb, ROOT_I);
119
120 if (!inode) {
121 rc = -ENOMEM;
122 goto out_no_root;
123 }
124
125 sb->s_root = d_alloc_root(inode);
126
127 if (!sb->s_root) {
128 rc = -ENOMEM;
129 goto out_no_root;
130 }
131
132 return 0;
133
134out_no_root:
135 cERROR(1, ("cifs_read_super: get root inode failed"));
136 if (inode)
137 iput(inode);
138
139out_mount_failed:
140 if(cifs_sb) {
141 if(cifs_sb->local_nls)
142 unload_nls(cifs_sb->local_nls);
143 kfree(cifs_sb);
144 }
145 return rc;
146}
147
148static void
149cifs_put_super(struct super_block *sb)
150{
151 int rc = 0;
152 struct cifs_sb_info *cifs_sb;
153
154 cFYI(1, ("In cifs_put_super"));
155 cifs_sb = CIFS_SB(sb);
156 if(cifs_sb == NULL) {
157 cFYI(1,("Empty cifs superblock info passed to unmount"));
158 return;
159 }
160 rc = cifs_umount(sb, cifs_sb);
161 if (rc) {
162 cERROR(1, ("cifs_umount failed with return code %d", rc));
163 }
164 unload_nls(cifs_sb->local_nls);
165 kfree(cifs_sb);
166 return;
167}
168
169static int
726c3342 170cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
1da177e4 171{
726c3342 172 struct super_block *sb = dentry->d_sb;
c81156dd
SF
173 int xid;
174 int rc = -EOPNOTSUPP;
1da177e4
LT
175 struct cifs_sb_info *cifs_sb;
176 struct cifsTconInfo *pTcon;
177
178 xid = GetXid();
179
180 cifs_sb = CIFS_SB(sb);
181 pTcon = cifs_sb->tcon;
182
183 buf->f_type = CIFS_MAGIC_NUMBER;
184
185 /* instead could get the real value via SMB_QUERY_FS_ATTRIBUTE_INFO */
c81156dd
SF
186 buf->f_namelen = PATH_MAX; /* PATH_MAX may be too long - it would
187 presumably be total path, but note
188 that some servers (includinng Samba 3)
189 have a shorter maximum path */
1da177e4
LT
190 buf->f_files = 0; /* undefined */
191 buf->f_ffree = 0; /* unlimited */
192
1da177e4 193/* BB we could add a second check for a QFS Unix capability bit */
f28ac91b 194/* BB FIXME check CIFS_POSIX_EXTENSIONS Unix cap first FIXME BB */
c81156dd
SF
195 if ((pTcon->ses->capabilities & CAP_UNIX) && (CIFS_POSIX_EXTENSIONS &
196 le64_to_cpu(pTcon->fsUnixInfo.Capability)))
737b758c 197 rc = CIFSSMBQFSPosixInfo(xid, pTcon, buf);
1da177e4
LT
198
199 /* Only need to call the old QFSInfo if failed
200 on newer one */
201 if(rc)
9ac00b7d
SF
202 if((pTcon->ses->flags & CIFS_SES_LANMAN) == 0)
203 rc = CIFSSMBQFSInfo(xid, pTcon, buf); /* not supported by OS2 */
1da177e4 204
9ac00b7d
SF
205 /* Some old Windows servers also do not support level 103, retry with
206 older level one if old server failed the previous call or we
207 bypassed it because we detected that this was an older LANMAN sess */
20962438
SF
208 if(rc)
209 rc = SMBOldQFSInfo(xid, pTcon, buf);
1da177e4
LT
210 /*
211 int f_type;
212 __fsid_t f_fsid;
213 int f_namelen; */
c81156dd 214 /* BB get from info in tcon struct at mount time call to QFSAttrInfo */
1da177e4 215 FreeXid(xid);
c81156dd
SF
216 return 0; /* always return success? what if volume is no
217 longer available? */
1da177e4
LT
218}
219
220static int cifs_permission(struct inode * inode, int mask, struct nameidata *nd)
221{
222 struct cifs_sb_info *cifs_sb;
223
224 cifs_sb = CIFS_SB(inode->i_sb);
225
226 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) {
227 return 0;
228 } else /* file mode might have been restricted at mount time
229 on the client (above and beyond ACL on servers) for
230 servers which do not support setting and viewing mode bits,
231 so allowing client to check permissions is useful */
232 return generic_permission(inode, mask, NULL);
233}
234
235static kmem_cache_t *cifs_inode_cachep;
236static kmem_cache_t *cifs_req_cachep;
237static kmem_cache_t *cifs_mid_cachep;
238kmem_cache_t *cifs_oplock_cachep;
239static kmem_cache_t *cifs_sm_req_cachep;
240mempool_t *cifs_sm_req_poolp;
241mempool_t *cifs_req_poolp;
242mempool_t *cifs_mid_poolp;
243
244static struct inode *
245cifs_alloc_inode(struct super_block *sb)
246{
247 struct cifsInodeInfo *cifs_inode;
248 cifs_inode = kmem_cache_alloc(cifs_inode_cachep, SLAB_KERNEL);
249 if (!cifs_inode)
250 return NULL;
251 cifs_inode->cifsAttrs = 0x20; /* default */
252 atomic_set(&cifs_inode->inUse, 0);
253 cifs_inode->time = 0;
254 /* Until the file is open and we have gotten oplock
255 info back from the server, can not assume caching of
256 file data or metadata */
257 cifs_inode->clientCanCacheRead = FALSE;
258 cifs_inode->clientCanCacheAll = FALSE;
259 cifs_inode->vfs_inode.i_blksize = CIFS_MAX_MSGSIZE;
260 cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */
e30dcf3a 261 cifs_inode->vfs_inode.i_flags = S_NOATIME | S_NOCMTIME;
1da177e4
LT
262 INIT_LIST_HEAD(&cifs_inode->openFileList);
263 return &cifs_inode->vfs_inode;
264}
265
266static void
267cifs_destroy_inode(struct inode *inode)
268{
269 kmem_cache_free(cifs_inode_cachep, CIFS_I(inode));
270}
271
272/*
273 * cifs_show_options() is for displaying mount options in /proc/mounts.
274 * Not all settable options are displayed but most of the important
275 * ones are.
276 */
277static int
278cifs_show_options(struct seq_file *s, struct vfsmount *m)
279{
280 struct cifs_sb_info *cifs_sb;
281
282 cifs_sb = CIFS_SB(m->mnt_sb);
283
284 if (cifs_sb) {
285 if (cifs_sb->tcon) {
286 seq_printf(s, ",unc=%s", cifs_sb->tcon->treeName);
287 if (cifs_sb->tcon->ses) {
288 if (cifs_sb->tcon->ses->userName)
289 seq_printf(s, ",username=%s",
290 cifs_sb->tcon->ses->userName);
291 if(cifs_sb->tcon->ses->domainName)
292 seq_printf(s, ",domain=%s",
293 cifs_sb->tcon->ses->domainName);
294 }
295 }
296 seq_printf(s, ",rsize=%d",cifs_sb->rsize);
297 seq_printf(s, ",wsize=%d",cifs_sb->wsize);
298 }
299 return 0;
300}
301
302#ifdef CONFIG_CIFS_QUOTA
303int cifs_xquota_set(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
317 xid = GetXid();
318 if(pTcon) {
319 cFYI(1,("set type: 0x%x id: %d",quota_type,qid));
320 } else {
321 return -EIO;
322 }
323
324 FreeXid(xid);
325 return rc;
326}
327
328int cifs_xquota_get(struct super_block * sb, int quota_type, qid_t qid,
329 struct fs_disk_quota * pdquota)
330{
331 int xid;
332 int rc = 0;
333 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
334 struct cifsTconInfo *pTcon;
335
336 if(cifs_sb)
337 pTcon = cifs_sb->tcon;
338 else
339 return -EIO;
340
341 xid = GetXid();
342 if(pTcon) {
343 cFYI(1,("set type: 0x%x id: %d",quota_type,qid));
344 } else {
345 rc = -EIO;
346 }
347
348 FreeXid(xid);
349 return rc;
350}
351
352int cifs_xstate_set(struct super_block * sb, unsigned int flags, int operation)
353{
354 int xid;
355 int rc = 0;
356 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
357 struct cifsTconInfo *pTcon;
358
359 if(cifs_sb)
360 pTcon = cifs_sb->tcon;
361 else
362 return -EIO;
363
364 xid = GetXid();
365 if(pTcon) {
366 cFYI(1,("flags: 0x%x operation: 0x%x",flags,operation));
367 } else {
368 rc = -EIO;
369 }
370
371 FreeXid(xid);
372 return rc;
373}
374
375int cifs_xstate_get(struct super_block * sb, struct fs_quota_stat *qstats)
376{
377 int xid;
378 int rc = 0;
379 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
380 struct cifsTconInfo *pTcon;
381
382 if(cifs_sb) {
383 pTcon = cifs_sb->tcon;
384 } else {
385 return -EIO;
386 }
387 xid = GetXid();
388 if(pTcon) {
389 cFYI(1,("pqstats %p",qstats));
390 } else {
391 rc = -EIO;
392 }
393
394 FreeXid(xid);
395 return rc;
396}
397
398static struct quotactl_ops cifs_quotactl_ops = {
399 .set_xquota = cifs_xquota_set,
400 .get_xquota = cifs_xquota_set,
401 .set_xstate = cifs_xstate_set,
402 .get_xstate = cifs_xstate_get,
403};
404#endif
405
8b512d9a 406static void cifs_umount_begin(struct vfsmount * vfsmnt, int flags)
68058e75 407{
5e1253b5 408 struct cifs_sb_info *cifs_sb;
9e2e85f8 409 struct cifsTconInfo * tcon;
68058e75 410
8b512d9a
TM
411 if (!(flags & MNT_FORCE))
412 return;
413 cifs_sb = CIFS_SB(vfsmnt->mnt_sb);
5e1253b5 414 if(cifs_sb == NULL)
9e2e85f8
SF
415 return;
416
417 tcon = cifs_sb->tcon;
418 if(tcon == NULL)
419 return;
5e1253b5
SF
420 down(&tcon->tconSem);
421 if (atomic_read(&tcon->useCount) == 1)
422 tcon->tidStatus = CifsExiting;
423 up(&tcon->tconSem);
424
3a5ff61c 425 /* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */
7b7abfe3 426 /* cancel_notify_requests(tcon); */
9e2e85f8 427 if(tcon->ses && tcon->ses->server)
5e1253b5 428 {
7b7abfe3 429 cFYI(1,("wake up tasks now - umount begin not complete"));
9e2e85f8 430 wake_up_all(&tcon->ses->server->request_q);
6ab16d24
SF
431 wake_up_all(&tcon->ses->server->response_q);
432 msleep(1); /* yield */
433 /* we have to kick the requests once more */
434 wake_up_all(&tcon->ses->server->response_q);
435 msleep(1);
5e1253b5
SF
436 }
437/* BB FIXME - finish add checks for tidStatus BB */
68058e75
SF
438
439 return;
440}
68058e75 441
bf97d287
SF
442#ifdef CONFIG_CIFS_STATS2
443static int cifs_show_stats(struct seq_file *s, struct vfsmount *mnt)
444{
445 /* BB FIXME */
446 return 0;
447}
448#endif
449
1da177e4
LT
450static int cifs_remount(struct super_block *sb, int *flags, char *data)
451{
452 *flags |= MS_NODIRATIME;
453 return 0;
454}
455
2cd646a2 456static struct super_operations cifs_super_ops = {
1da177e4
LT
457 .read_inode = cifs_read_inode,
458 .put_super = cifs_put_super,
459 .statfs = cifs_statfs,
460 .alloc_inode = cifs_alloc_inode,
461 .destroy_inode = cifs_destroy_inode,
462/* .drop_inode = generic_delete_inode,
463 .delete_inode = cifs_delete_inode, *//* Do not need the above two functions
464 unless later we add lazy close of inodes or unless the kernel forgets to call
465 us with the same number of releases (closes) as opens */
466 .show_options = cifs_show_options,
7b7abfe3 467 .umount_begin = cifs_umount_begin,
1da177e4 468 .remount_fs = cifs_remount,
bf97d287 469#ifdef CONFIG_CIFS_STATS2
f46d3e11 470 .show_stats = cifs_show_stats,
bf97d287 471#endif
1da177e4
LT
472};
473
454e2398 474static int
1da177e4 475cifs_get_sb(struct file_system_type *fs_type,
454e2398 476 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
1da177e4
LT
477{
478 int rc;
479 struct super_block *sb = sget(fs_type, NULL, set_anon_super, NULL);
480
481 cFYI(1, ("Devname: %s flags: %d ", dev_name, flags));
482
483 if (IS_ERR(sb))
454e2398 484 return PTR_ERR(sb);
1da177e4
LT
485
486 sb->s_flags = flags;
487
9b04c997 488 rc = cifs_read_super(sb, data, dev_name, flags & MS_SILENT ? 1 : 0);
1da177e4
LT
489 if (rc) {
490 up_write(&sb->s_umount);
491 deactivate_super(sb);
454e2398 492 return rc;
1da177e4
LT
493 }
494 sb->s_flags |= MS_ACTIVE;
454e2398 495 return simple_set_mnt(mnt, sb);
1da177e4
LT
496}
497
87c89dd7
SF
498static ssize_t cifs_file_writev(struct file *file, const struct iovec *iov,
499 unsigned long nr_segs, loff_t *ppos)
1da177e4 500{
87c89dd7
SF
501 struct inode *inode = file->f_dentry->d_inode;
502 ssize_t written;
1da177e4 503
87c89dd7
SF
504 written = generic_file_writev(file, iov, nr_segs, ppos);
505 if (!CIFS_I(inode)->clientCanCacheAll)
506 filemap_fdatawrite(inode->i_mapping);
507 return written;
1da177e4
LT
508}
509
87c89dd7
SF
510static ssize_t cifs_file_aio_write(struct kiocb *iocb, const char __user *buf,
511 size_t count, loff_t pos)
1da177e4 512{
87c89dd7 513 struct inode *inode = iocb->ki_filp->f_dentry->d_inode;
1da177e4
LT
514 ssize_t written;
515
87c89dd7
SF
516 written = generic_file_aio_write(iocb, buf, count, pos);
517 if (!CIFS_I(inode)->clientCanCacheAll)
518 filemap_fdatawrite(inode->i_mapping);
1da177e4
LT
519 return written;
520}
521
c32a0b68
SF
522static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
523{
524 /* origin == SEEK_END => we must revalidate the cached file length */
0889a944 525 if (origin == SEEK_END) {
c32a0b68
SF
526 int retval = cifs_revalidate(file->f_dentry);
527 if (retval < 0)
528 return (loff_t)retval;
529 }
530 return remote_llseek(file, offset, origin);
531}
532
1da177e4
LT
533static struct file_system_type cifs_fs_type = {
534 .owner = THIS_MODULE,
535 .name = "cifs",
536 .get_sb = cifs_get_sb,
537 .kill_sb = kill_anon_super,
538 /* .fs_flags */
539};
540struct inode_operations cifs_dir_inode_ops = {
541 .create = cifs_create,
542 .lookup = cifs_lookup,
543 .getattr = cifs_getattr,
544 .unlink = cifs_unlink,
545 .link = cifs_hardlink,
546 .mkdir = cifs_mkdir,
547 .rmdir = cifs_rmdir,
548 .rename = cifs_rename,
549 .permission = cifs_permission,
550/* revalidate:cifs_revalidate, */
551 .setattr = cifs_setattr,
552 .symlink = cifs_symlink,
553 .mknod = cifs_mknod,
554#ifdef CONFIG_CIFS_XATTR
555 .setxattr = cifs_setxattr,
556 .getxattr = cifs_getxattr,
557 .listxattr = cifs_listxattr,
558 .removexattr = cifs_removexattr,
559#endif
560};
561
562struct inode_operations cifs_file_inode_ops = {
563/* revalidate:cifs_revalidate, */
564 .setattr = cifs_setattr,
565 .getattr = cifs_getattr, /* do we need this anymore? */
566 .rename = cifs_rename,
567 .permission = cifs_permission,
568#ifdef CONFIG_CIFS_XATTR
569 .setxattr = cifs_setxattr,
570 .getxattr = cifs_getxattr,
571 .listxattr = cifs_listxattr,
572 .removexattr = cifs_removexattr,
573#endif
574};
575
576struct inode_operations cifs_symlink_inode_ops = {
577 .readlink = generic_readlink,
578 .follow_link = cifs_follow_link,
579 .put_link = cifs_put_link,
580 .permission = cifs_permission,
581 /* BB add the following two eventually */
582 /* revalidate: cifs_revalidate,
583 setattr: cifs_notify_change, *//* BB do we need notify change */
584#ifdef CONFIG_CIFS_XATTR
585 .setxattr = cifs_setxattr,
586 .getxattr = cifs_getxattr,
587 .listxattr = cifs_listxattr,
588 .removexattr = cifs_removexattr,
589#endif
590};
591
4b6f5d20 592const struct file_operations cifs_file_ops = {
87c89dd7
SF
593 .read = do_sync_read,
594 .write = do_sync_write,
595 .readv = generic_file_readv,
596 .writev = cifs_file_writev,
597 .aio_read = generic_file_aio_read,
598 .aio_write = cifs_file_aio_write,
1da177e4
LT
599 .open = cifs_open,
600 .release = cifs_close,
601 .lock = cifs_lock,
602 .fsync = cifs_fsync,
603 .flush = cifs_flush,
604 .mmap = cifs_file_mmap,
605 .sendfile = generic_file_sendfile,
c32a0b68 606 .llseek = cifs_llseek,
c67593a0
SF
607#ifdef CONFIG_CIFS_POSIX
608 .ioctl = cifs_ioctl,
609#endif /* CONFIG_CIFS_POSIX */
610
1da177e4 611#ifdef CONFIG_CIFS_EXPERIMENTAL
1da177e4
LT
612 .dir_notify = cifs_dir_notify,
613#endif /* CONFIG_CIFS_EXPERIMENTAL */
614};
615
4b6f5d20 616const struct file_operations cifs_file_direct_ops = {
1da177e4
LT
617 /* no mmap, no aio, no readv -
618 BB reevaluate whether they can be done with directio, no cache */
619 .read = cifs_user_read,
620 .write = cifs_user_write,
621 .open = cifs_open,
622 .release = cifs_close,
623 .lock = cifs_lock,
624 .fsync = cifs_fsync,
625 .flush = cifs_flush,
626 .sendfile = generic_file_sendfile, /* BB removeme BB */
c67593a0
SF
627#ifdef CONFIG_CIFS_POSIX
628 .ioctl = cifs_ioctl,
629#endif /* CONFIG_CIFS_POSIX */
c32a0b68 630 .llseek = cifs_llseek,
1da177e4
LT
631#ifdef CONFIG_CIFS_EXPERIMENTAL
632 .dir_notify = cifs_dir_notify,
633#endif /* CONFIG_CIFS_EXPERIMENTAL */
634};
4b6f5d20 635const struct file_operations cifs_file_nobrl_ops = {
87c89dd7
SF
636 .read = do_sync_read,
637 .write = do_sync_write,
638 .readv = generic_file_readv,
639 .writev = cifs_file_writev,
640 .aio_read = generic_file_aio_read,
641 .aio_write = cifs_file_aio_write,
642 .open = cifs_open,
643 .release = cifs_close,
644 .fsync = cifs_fsync,
645 .flush = cifs_flush,
646 .mmap = cifs_file_mmap,
647 .sendfile = generic_file_sendfile,
c32a0b68 648 .llseek = cifs_llseek,
8b94bcb9 649#ifdef CONFIG_CIFS_POSIX
87c89dd7 650 .ioctl = cifs_ioctl,
8b94bcb9
SF
651#endif /* CONFIG_CIFS_POSIX */
652
653#ifdef CONFIG_CIFS_EXPERIMENTAL
87c89dd7 654 .dir_notify = cifs_dir_notify,
8b94bcb9
SF
655#endif /* CONFIG_CIFS_EXPERIMENTAL */
656};
657
4b6f5d20 658const struct file_operations cifs_file_direct_nobrl_ops = {
87c89dd7
SF
659 /* no mmap, no aio, no readv -
660 BB reevaluate whether they can be done with directio, no cache */
661 .read = cifs_user_read,
662 .write = cifs_user_write,
663 .open = cifs_open,
664 .release = cifs_close,
665 .fsync = cifs_fsync,
666 .flush = cifs_flush,
667 .sendfile = generic_file_sendfile, /* BB removeme BB */
8b94bcb9 668#ifdef CONFIG_CIFS_POSIX
87c89dd7 669 .ioctl = cifs_ioctl,
8b94bcb9 670#endif /* CONFIG_CIFS_POSIX */
c32a0b68 671 .llseek = cifs_llseek,
8b94bcb9 672#ifdef CONFIG_CIFS_EXPERIMENTAL
87c89dd7 673 .dir_notify = cifs_dir_notify,
8b94bcb9
SF
674#endif /* CONFIG_CIFS_EXPERIMENTAL */
675};
1da177e4 676
4b6f5d20 677const struct file_operations cifs_dir_ops = {
1da177e4
LT
678 .readdir = cifs_readdir,
679 .release = cifs_closedir,
680 .read = generic_read_dir,
681#ifdef CONFIG_CIFS_EXPERIMENTAL
682 .dir_notify = cifs_dir_notify,
683#endif /* CONFIG_CIFS_EXPERIMENTAL */
f28ac91b 684 .ioctl = cifs_ioctl,
1da177e4
LT
685};
686
687static void
688cifs_init_once(void *inode, kmem_cache_t * cachep, unsigned long flags)
689{
690 struct cifsInodeInfo *cifsi = inode;
691
692 if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) ==
693 SLAB_CTOR_CONSTRUCTOR) {
694 inode_init_once(&cifsi->vfs_inode);
695 INIT_LIST_HEAD(&cifsi->lockList);
696 }
697}
698
699static int
700cifs_init_inodecache(void)
701{
702 cifs_inode_cachep = kmem_cache_create("cifs_inode_cache",
703 sizeof (struct cifsInodeInfo),
fffb60f9
PJ
704 0, (SLAB_RECLAIM_ACCOUNT|
705 SLAB_MEM_SPREAD),
1da177e4
LT
706 cifs_init_once, NULL);
707 if (cifs_inode_cachep == NULL)
708 return -ENOMEM;
709
710 return 0;
711}
712
713static void
714cifs_destroy_inodecache(void)
715{
716 if (kmem_cache_destroy(cifs_inode_cachep))
717 printk(KERN_WARNING "cifs_inode_cache: error freeing\n");
718}
719
720static int
721cifs_init_request_bufs(void)
722{
723 if(CIFSMaxBufSize < 8192) {
724 /* Buffer size can not be smaller than 2 * PATH_MAX since maximum
725 Unicode path name has to fit in any SMB/CIFS path based frames */
726 CIFSMaxBufSize = 8192;
727 } else if (CIFSMaxBufSize > 1024*127) {
728 CIFSMaxBufSize = 1024 * 127;
729 } else {
730 CIFSMaxBufSize &= 0x1FE00; /* Round size to even 512 byte mult*/
731 }
732/* cERROR(1,("CIFSMaxBufSize %d 0x%x",CIFSMaxBufSize,CIFSMaxBufSize)); */
733 cifs_req_cachep = kmem_cache_create("cifs_request",
734 CIFSMaxBufSize +
735 MAX_CIFS_HDR_SIZE, 0,
736 SLAB_HWCACHE_ALIGN, NULL, NULL);
737 if (cifs_req_cachep == NULL)
738 return -ENOMEM;
739
740 if(cifs_min_rcv < 1)
741 cifs_min_rcv = 1;
742 else if (cifs_min_rcv > 64) {
743 cifs_min_rcv = 64;
744 cERROR(1,("cifs_min_rcv set to maximum (64)"));
745 }
746
93d2341c
MD
747 cifs_req_poolp = mempool_create_slab_pool(cifs_min_rcv,
748 cifs_req_cachep);
1da177e4
LT
749
750 if(cifs_req_poolp == NULL) {
751 kmem_cache_destroy(cifs_req_cachep);
752 return -ENOMEM;
753 }
ec637e3f 754 /* MAX_CIFS_SMALL_BUFFER_SIZE bytes is enough for most SMB responses and
1da177e4
LT
755 almost all handle based requests (but not write response, nor is it
756 sufficient for path based requests). A smaller size would have
757 been more efficient (compacting multiple slab items on one 4k page)
758 for the case in which debug was on, but this larger size allows
759 more SMBs to use small buffer alloc and is still much more
760 efficient to alloc 1 per page off the slab compared to 17K (5page)
761 alloc of large cifs buffers even when page debugging is on */
762 cifs_sm_req_cachep = kmem_cache_create("cifs_small_rq",
ec637e3f
SF
763 MAX_CIFS_SMALL_BUFFER_SIZE, 0, SLAB_HWCACHE_ALIGN,
764 NULL, NULL);
1da177e4
LT
765 if (cifs_sm_req_cachep == NULL) {
766 mempool_destroy(cifs_req_poolp);
767 kmem_cache_destroy(cifs_req_cachep);
768 return -ENOMEM;
769 }
770
771 if(cifs_min_small < 2)
772 cifs_min_small = 2;
773 else if (cifs_min_small > 256) {
774 cifs_min_small = 256;
775 cFYI(1,("cifs_min_small set to maximum (256)"));
776 }
777
93d2341c
MD
778 cifs_sm_req_poolp = mempool_create_slab_pool(cifs_min_small,
779 cifs_sm_req_cachep);
1da177e4
LT
780
781 if(cifs_sm_req_poolp == NULL) {
782 mempool_destroy(cifs_req_poolp);
783 kmem_cache_destroy(cifs_req_cachep);
784 kmem_cache_destroy(cifs_sm_req_cachep);
785 return -ENOMEM;
786 }
787
788 return 0;
789}
790
791static void
792cifs_destroy_request_bufs(void)
793{
794 mempool_destroy(cifs_req_poolp);
795 if (kmem_cache_destroy(cifs_req_cachep))
796 printk(KERN_WARNING
797 "cifs_destroy_request_cache: error not all structures were freed\n");
798 mempool_destroy(cifs_sm_req_poolp);
799 if (kmem_cache_destroy(cifs_sm_req_cachep))
800 printk(KERN_WARNING
801 "cifs_destroy_request_cache: cifs_small_rq free error\n");
802}
803
804static int
805cifs_init_mids(void)
806{
807 cifs_mid_cachep = kmem_cache_create("cifs_mpx_ids",
808 sizeof (struct mid_q_entry), 0,
809 SLAB_HWCACHE_ALIGN, NULL, NULL);
810 if (cifs_mid_cachep == NULL)
811 return -ENOMEM;
812
93d2341c
MD
813 /* 3 is a reasonable minimum number of simultaneous operations */
814 cifs_mid_poolp = mempool_create_slab_pool(3, cifs_mid_cachep);
1da177e4
LT
815 if(cifs_mid_poolp == NULL) {
816 kmem_cache_destroy(cifs_mid_cachep);
817 return -ENOMEM;
818 }
819
820 cifs_oplock_cachep = kmem_cache_create("cifs_oplock_structs",
821 sizeof (struct oplock_q_entry), 0,
822 SLAB_HWCACHE_ALIGN, NULL, NULL);
823 if (cifs_oplock_cachep == NULL) {
824 kmem_cache_destroy(cifs_mid_cachep);
825 mempool_destroy(cifs_mid_poolp);
826 return -ENOMEM;
827 }
828
829 return 0;
830}
831
832static void
833cifs_destroy_mids(void)
834{
835 mempool_destroy(cifs_mid_poolp);
836 if (kmem_cache_destroy(cifs_mid_cachep))
837 printk(KERN_WARNING
838 "cifs_destroy_mids: error not all structures were freed\n");
839
840 if (kmem_cache_destroy(cifs_oplock_cachep))
841 printk(KERN_WARNING
842 "error not all oplock structures were freed\n");
843}
844
845static int cifs_oplock_thread(void * dummyarg)
846{
847 struct oplock_q_entry * oplock_item;
848 struct cifsTconInfo *pTcon;
849 struct inode * inode;
850 __u16 netfid;
851 int rc;
852
1da177e4 853 do {
ede1327e
SF
854 if (try_to_freeze())
855 continue;
1da177e4 856
1da177e4
LT
857 spin_lock(&GlobalMid_Lock);
858 if(list_empty(&GlobalOplock_Q)) {
859 spin_unlock(&GlobalMid_Lock);
860 set_current_state(TASK_INTERRUPTIBLE);
861 schedule_timeout(39*HZ);
862 } else {
863 oplock_item = list_entry(GlobalOplock_Q.next,
864 struct oplock_q_entry, qhead);
865 if(oplock_item) {
866 cFYI(1,("found oplock item to write out"));
867 pTcon = oplock_item->tcon;
868 inode = oplock_item->pinode;
869 netfid = oplock_item->netfid;
870 spin_unlock(&GlobalMid_Lock);
871 DeleteOplockQEntry(oplock_item);
872 /* can not grab inode sem here since it would
873 deadlock when oplock received on delete
1b1dcc1b 874 since vfs_unlink holds the i_mutex across
1da177e4 875 the call */
1b1dcc1b 876 /* mutex_lock(&inode->i_mutex);*/
1da177e4
LT
877 if (S_ISREG(inode->i_mode)) {
878 rc = filemap_fdatawrite(inode->i_mapping);
879 if(CIFS_I(inode)->clientCanCacheRead == 0) {
880 filemap_fdatawait(inode->i_mapping);
881 invalidate_remote_inode(inode);
882 }
883 } else
884 rc = 0;
1b1dcc1b 885 /* mutex_unlock(&inode->i_mutex);*/
1da177e4
LT
886 if (rc)
887 CIFS_I(inode)->write_behind_rc = rc;
888 cFYI(1,("Oplock flush inode %p rc %d",inode,rc));
889
890 /* releasing a stale oplock after recent reconnection
891 of smb session using a now incorrect file
892 handle is not a data integrity issue but do
893 not bother sending an oplock release if session
894 to server still is disconnected since oplock
895 already released by the server in that case */
896 if(pTcon->tidStatus != CifsNeedReconnect) {
897 rc = CIFSSMBLock(0, pTcon, netfid,
898 0 /* len */ , 0 /* offset */, 0,
899 0, LOCKING_ANDX_OPLOCK_RELEASE,
900 0 /* wait flag */);
901 cFYI(1,("Oplock release rc = %d ",rc));
902 }
903 } else
904 spin_unlock(&GlobalMid_Lock);
68058e75
SF
905 set_current_state(TASK_INTERRUPTIBLE);
906 schedule_timeout(1); /* yield in case q were corrupt */
1da177e4 907 }
45af7a0f
SF
908 } while (!kthread_should_stop());
909
910 return 0;
1da177e4
LT
911}
912
8d0d5094
SF
913static int cifs_dnotify_thread(void * dummyarg)
914{
6ab16d24
SF
915 struct list_head *tmp;
916 struct cifsSesInfo *ses;
917
8d0d5094 918 do {
0fd1ffe0 919 if (try_to_freeze())
16abbecd 920 continue;
8d0d5094 921 set_current_state(TASK_INTERRUPTIBLE);
6ab16d24
SF
922 schedule_timeout(15*HZ);
923 read_lock(&GlobalSMBSeslock);
924 /* check if any stuck requests that need
925 to be woken up and wakeq so the
926 thread can wake up and error out */
927 list_for_each(tmp, &GlobalSMBSessionList) {
928 ses = list_entry(tmp, struct cifsSesInfo,
929 cifsSessionList);
930 if(ses && ses->server &&
2a138ebb 931 atomic_read(&ses->server->inFlight))
6ab16d24
SF
932 wake_up_all(&ses->server->response_q);
933 }
934 read_unlock(&GlobalSMBSeslock);
45af7a0f
SF
935 } while (!kthread_should_stop());
936
937 return 0;
1da177e4
LT
938}
939
940static int __init
941init_cifs(void)
942{
943 int rc = 0;
944#ifdef CONFIG_PROC_FS
945 cifs_proc_init();
946#endif
2cd646a2 947/* INIT_LIST_HEAD(&GlobalServerList);*/ /* BB not implemented yet */
1da177e4
LT
948 INIT_LIST_HEAD(&GlobalSMBSessionList);
949 INIT_LIST_HEAD(&GlobalTreeConnectionList);
950 INIT_LIST_HEAD(&GlobalOplock_Q);
4ca9c190
SF
951#ifdef CONFIG_CIFS_EXPERIMENTAL
952 INIT_LIST_HEAD(&GlobalDnotifyReqList);
953 INIT_LIST_HEAD(&GlobalDnotifyRsp_Q);
954#endif
1da177e4
LT
955/*
956 * Initialize Global counters
957 */
958 atomic_set(&sesInfoAllocCount, 0);
959 atomic_set(&tconInfoAllocCount, 0);
960 atomic_set(&tcpSesAllocCount,0);
961 atomic_set(&tcpSesReconnectCount, 0);
962 atomic_set(&tconInfoReconnectCount, 0);
963
964 atomic_set(&bufAllocCount, 0);
4498eed5
SF
965 atomic_set(&smBufAllocCount, 0);
966#ifdef CONFIG_CIFS_STATS2
967 atomic_set(&totBufAllocCount, 0);
968 atomic_set(&totSmBufAllocCount, 0);
969#endif /* CONFIG_CIFS_STATS2 */
970
1da177e4
LT
971 atomic_set(&midCount, 0);
972 GlobalCurrentXid = 0;
973 GlobalTotalActiveXid = 0;
974 GlobalMaxActiveXid = 0;
2cd646a2 975 memset(Local_System_Name, 0, 15);
1da177e4
LT
976 rwlock_init(&GlobalSMBSeslock);
977 spin_lock_init(&GlobalMid_Lock);
978
979 if(cifs_max_pending < 2) {
980 cifs_max_pending = 2;
981 cFYI(1,("cifs_max_pending set to min of 2"));
982 } else if(cifs_max_pending > 256) {
983 cifs_max_pending = 256;
984 cFYI(1,("cifs_max_pending set to max of 256"));
985 }
986
987 rc = cifs_init_inodecache();
45af7a0f
SF
988 if (rc)
989 goto out_clean_proc;
990
991 rc = cifs_init_mids();
992 if (rc)
993 goto out_destroy_inodecache;
994
995 rc = cifs_init_request_bufs();
996 if (rc)
997 goto out_destroy_mids;
998
999 rc = register_filesystem(&cifs_fs_type);
1000 if (rc)
1001 goto out_destroy_request_bufs;
1002
1003 oplockThread = kthread_run(cifs_oplock_thread, NULL, "cifsoplockd");
1004 if (IS_ERR(oplockThread)) {
1005 rc = PTR_ERR(oplockThread);
1006 cERROR(1,("error %d create oplock thread", rc));
1007 goto out_unregister_filesystem;
1da177e4 1008 }
45af7a0f
SF
1009
1010 dnotifyThread = kthread_run(cifs_dnotify_thread, NULL, "cifsdnotifyd");
1011 if (IS_ERR(dnotifyThread)) {
1012 rc = PTR_ERR(dnotifyThread);
1013 cERROR(1,("error %d create dnotify thread", rc));
1014 goto out_stop_oplock_thread;
1015 }
1016
1017 return 0;
1018
1019 out_stop_oplock_thread:
1020 kthread_stop(oplockThread);
1021 out_unregister_filesystem:
1022 unregister_filesystem(&cifs_fs_type);
1023 out_destroy_request_bufs:
1024 cifs_destroy_request_bufs();
1025 out_destroy_mids:
1026 cifs_destroy_mids();
1027 out_destroy_inodecache:
1028 cifs_destroy_inodecache();
1029 out_clean_proc:
1da177e4
LT
1030#ifdef CONFIG_PROC_FS
1031 cifs_proc_clean();
1032#endif
1033 return rc;
1034}
1035
1036static void __exit
1037exit_cifs(void)
1038{
1039 cFYI(0, ("In unregister ie exit_cifs"));
1040#ifdef CONFIG_PROC_FS
1041 cifs_proc_clean();
1042#endif
1043 unregister_filesystem(&cifs_fs_type);
1044 cifs_destroy_inodecache();
1045 cifs_destroy_mids();
1046 cifs_destroy_request_bufs();
45af7a0f
SF
1047 kthread_stop(oplockThread);
1048 kthread_stop(dnotifyThread);
1da177e4
LT
1049}
1050
1051MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>");
1052MODULE_LICENSE("GPL"); /* combination of LGPL + GPL source behaves as GPL */
1053MODULE_DESCRIPTION
1054 ("VFS to access servers complying with the SNIA CIFS Specification e.g. Samba and Windows");
1055MODULE_VERSION(CIFS_VERSION);
1056module_init(init_cifs)
1057module_exit(exit_cifs)