Blame view

fs/cifs/cifsfs.c 26 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
  /*
   *   fs/cifs/cifsfs.c
   *
2b280fab1   Steve French   [CIFS] add more c...
4
   *   Copyright (C) International Business Machines  Corp., 2002,2008
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
   *   Author(s): Steve French (sfrench@us.ibm.com)
   *
   *   Common Internet FileSystem (CIFS) client
   *
   *   This library is free software; you can redistribute it and/or modify
   *   it under the terms of the GNU Lesser General Public License as published
   *   by the Free Software Foundation; either version 2.1 of the License, or
   *   (at your option) any later version.
   *
   *   This library is distributed in the hope that it will be useful,
   *   but WITHOUT ANY WARRANTY; without even the implied warranty of
   *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
   *   the GNU Lesser General Public License for more details.
   *
   *   You should have received a copy of the GNU Lesser General Public License
   *   along with this library; if not, write to the Free Software
   *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
   */
  
  /* Note that BB means BUGBUG (ie something to fix eventually) */
  
  #include <linux/module.h>
  #include <linux/fs.h>
  #include <linux/mount.h>
  #include <linux/slab.h>
  #include <linux/init.h>
  #include <linux/list.h>
  #include <linux/seq_file.h>
  #include <linux/vfs.h>
  #include <linux/mempool.h>
6ab16d249   Steve French   [CIFS] Fix umount...
35
  #include <linux/delay.h>
45af7a0f2   Steve French   [CIFS] Use the kt...
36
  #include <linux/kthread.h>
7dfb71030   Nigel Cunningham   [PATCH] Add inclu...
37
  #include <linux/freezer.h>
67e55205e   Alessio Igor Bogani   vfs: umount_begin...
38
  #include <linux/smp_lock.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
39
40
41
42
43
44
45
46
  #include "cifsfs.h"
  #include "cifspdu.h"
  #define DECLARE_GLOBALS_HERE
  #include "cifsglob.h"
  #include "cifsproto.h"
  #include "cifs_debug.h"
  #include "cifs_fs_sb.h"
  #include <linux/mm.h>
84a15b935   Jeff Layton   [CIFS] Register a...
47
  #include <linux/key-type.h>
e545937a5   Jeff Layton   [CIFS] add OIDs f...
48
  #include "cifs_spnego.h"
f579cf3cf   Suresh Jayaraman   cifs: register CI...
49
  #include "fscache.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50
  #define CIFS_MAGIC_NUMBER 0xFF534D42	/* the first four bytes of SMB PDUs */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
51
52
53
54
55
56
57
58
  int cifsFYI = 0;
  int cifsERROR = 1;
  int traceSMB = 0;
  unsigned int oplockEnabled = 1;
  unsigned int experimEnabled = 0;
  unsigned int linuxExtEnabled = 1;
  unsigned int lookupCacheEnabled = 1;
  unsigned int multiuser_mount = 0;
04912d6a2   Jeff Layton   cifs: rename "ext...
59
  unsigned int global_secflags = CIFSSEC_DEF;
3979877e5   Steve French   [CIFS] Support fo...
60
  /* unsigned int ntlmv2_support = 0; */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
61
  unsigned int sign_CIFS_PDUs = 1;
ee9b6d61a   Josef 'Jeff' Sipek   [PATCH] Mark stru...
62
  static const struct super_operations cifs_super_ops;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
63
64
  unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;
  module_param(CIFSMaxBufSize, int, 0);
63135e088   Steve French   [CIFS] More white...
65
66
  MODULE_PARM_DESC(CIFSMaxBufSize, "Network buffer size (not including header). "
  				 "Default: 16384 Range: 8192 to 130048");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
67
68
  unsigned int cifs_min_rcv = CIFS_MIN_RCV_POOL;
  module_param(cifs_min_rcv, int, 0);
63135e088   Steve French   [CIFS] More white...
69
70
  MODULE_PARM_DESC(cifs_min_rcv, "Network buffers in pool. Default: 4 Range: "
  				"1 to 64");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71
72
  unsigned int cifs_min_small = 30;
  module_param(cifs_min_small, int, 0);
63135e088   Steve French   [CIFS] More white...
73
74
  MODULE_PARM_DESC(cifs_min_small, "Small network buffers in pool. Default: 30 "
  				 "Range: 2 to 256");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
75
76
  unsigned int cifs_max_pending = CIFS_MAX_REQ;
  module_param(cifs_max_pending, int, 0);
63135e088   Steve French   [CIFS] More white...
77
78
  MODULE_PARM_DESC(cifs_max_pending, "Simultaneous requests to server. "
  				   "Default: 50 Range: 2 to 256");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
79

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
80
81
82
  extern mempool_t *cifs_sm_req_poolp;
  extern mempool_t *cifs_req_poolp;
  extern mempool_t *cifs_mid_poolp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
83
84
85
86
87
88
89
  static int
  cifs_read_super(struct super_block *sb, void *data,
  		const char *devname, int silent)
  {
  	struct inode *inode;
  	struct cifs_sb_info *cifs_sb;
  	int rc = 0;
50c2f7538   Steve French   [CIFS] whitespace...
90

1b2b21260   Steve French   [CIFS] mtime boun...
91
92
  	/* BB should we make this contingent on mount parm? */
  	sb->s_flags |= MS_NODIRATIME | MS_NOATIME;
790fe579f   Steve French   [CIFS] more white...
93
  	sb->s_fs_info = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
94
  	cifs_sb = CIFS_SB(sb);
4523cc304   Steve French   [CIFS] UID/GID ov...
95
  	if (cifs_sb == NULL)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
96
  		return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
97

8044f7f46   Jens Axboe   cifs: add bdi bac...
98
99
100
101
102
  	rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY);
  	if (rc) {
  		kfree(cifs_sb);
  		return rc;
  	}
e6ab15827   Igor Mammedov   [CIFS] DFS suppor...
103
104
105
106
107
108
109
110
  #ifdef CONFIG_CIFS_DFS_UPCALL
  	/* copy mount params to sb for use in submounts */
  	/* BB: should we move this after the mount so we
  	 * do not have to do the copy on failed mounts?
  	 * BB: May be it is better to do simple copy before
  	 * complex operation (mount), and in case of fail
  	 * just exit instead of doing mount and attempting
  	 * undo it if this copy fails?*/
79ee9a8b2   Steve French   [CIFS] cifs: fix ...
111
112
113
114
  	if (data) {
  		int len = strlen(data);
  		cifs_sb->mountdata = kzalloc(len + 1, GFP_KERNEL);
  		if (cifs_sb->mountdata == NULL) {
8044f7f46   Jens Axboe   cifs: add bdi bac...
115
  			bdi_destroy(&cifs_sb->bdi);
79ee9a8b2   Steve French   [CIFS] cifs: fix ...
116
117
118
119
120
121
  			kfree(sb->s_fs_info);
  			sb->s_fs_info = NULL;
  			return -ENOMEM;
  		}
  		strncpy(cifs_sb->mountdata, data, len + 1);
  		cifs_sb->mountdata[len] = '\0';
e6ab15827   Igor Mammedov   [CIFS] DFS suppor...
122
  	}
e6ab15827   Igor Mammedov   [CIFS] DFS suppor...
123
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
124
125
126
127
  	rc = cifs_mount(sb, cifs_sb, data, devname);
  
  	if (rc) {
  		if (!silent)
b6b38f704   Joe Perches   [CIFS] Neaten cER...
128
  			cERROR(1, "cifs_mount failed w/return code = %d", rc);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
129
130
131
132
133
  		goto out_mount_failed;
  	}
  
  	sb->s_magic = CIFS_MAGIC_NUMBER;
  	sb->s_op = &cifs_super_ops;
8044f7f46   Jens Axboe   cifs: add bdi bac...
134
  	sb->s_bdi = &cifs_sb->bdi;
4523cc304   Steve French   [CIFS] UID/GID ov...
135
  /*	if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512)
790fe579f   Steve French   [CIFS] more white...
136
137
  	    sb->s_blocksize =
  		cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
138
139
  	sb->s_blocksize = CIFS_MAX_MSGSIZE;
  	sb->s_blocksize_bits = 14;	/* default 2**14 = CIFS_MAX_MSGSIZE */
bd433d4cf   Jeff Layton   cifs: rename cifs...
140
  	inode = cifs_root_iget(sb, ROOT_I);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
141

ce634ab28   David Howells   iget: stop CIFS f...
142
143
144
  	if (IS_ERR(inode)) {
  		rc = PTR_ERR(inode);
  		inode = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
145
146
147
148
149
150
151
152
153
  		goto out_no_root;
  	}
  
  	sb->s_root = d_alloc_root(inode);
  
  	if (!sb->s_root) {
  		rc = -ENOMEM;
  		goto out_no_root;
  	}
50c2f7538   Steve French   [CIFS] whitespace...
154

7521a3c56   Steve French   [CIFS] Fix oops i...
155
156
  #ifdef CONFIG_CIFS_EXPERIMENTAL
  	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
157
  		cFYI(1, "export ops supported");
7521a3c56   Steve French   [CIFS] Fix oops i...
158
159
160
  		sb->s_export_op = &cifs_export_ops;
  	}
  #endif /* EXPERIMENTAL */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
161
162
163
164
  
  	return 0;
  
  out_no_root:
b6b38f704   Joe Perches   [CIFS] Neaten cER...
165
  	cERROR(1, "cifs_read_super: get root inode failed");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
166
167
  	if (inode)
  		iput(inode);
54b4602d5   Steve French   [CIFS] remove tra...
168

2c731afb0   Steve French   [CIFS] if get roo...
169
  	cifs_umount(sb, cifs_sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
170
171
  
  out_mount_failed:
4523cc304   Steve French   [CIFS] UID/GID ov...
172
  	if (cifs_sb) {
e6ab15827   Igor Mammedov   [CIFS] DFS suppor...
173
174
175
176
177
178
  #ifdef CONFIG_CIFS_DFS_UPCALL
  		if (cifs_sb->mountdata) {
  			kfree(cifs_sb->mountdata);
  			cifs_sb->mountdata = NULL;
  		}
  #endif
6d729e44a   Thomas Gleixner   fs: Make unload_n...
179
  		unload_nls(cifs_sb->local_nls);
8044f7f46   Jens Axboe   cifs: add bdi bac...
180
  		bdi_destroy(&cifs_sb->bdi);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
181
182
183
184
185
186
187
188
189
190
  		kfree(cifs_sb);
  	}
  	return rc;
  }
  
  static void
  cifs_put_super(struct super_block *sb)
  {
  	int rc = 0;
  	struct cifs_sb_info *cifs_sb;
b6b38f704   Joe Perches   [CIFS] Neaten cER...
191
  	cFYI(1, "In cifs_put_super");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
192
  	cifs_sb = CIFS_SB(sb);
4523cc304   Steve French   [CIFS] UID/GID ov...
193
  	if (cifs_sb == NULL) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
194
  		cFYI(1, "Empty cifs superblock info passed to unmount");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
195
196
  		return;
  	}
6cfd01484   Christoph Hellwig   push BKL down int...
197
198
  
  	lock_kernel();
790fe579f   Steve French   [CIFS] more white...
199
  	rc = cifs_umount(sb, cifs_sb);
ad7a2926b   Steve French   [CIFS] reduce che...
200
  	if (rc)
b6b38f704   Joe Perches   [CIFS] Neaten cER...
201
  		cERROR(1, "cifs_umount failed with return code %d", rc);
e6ab15827   Igor Mammedov   [CIFS] DFS suppor...
202
203
204
205
206
207
  #ifdef CONFIG_CIFS_DFS_UPCALL
  	if (cifs_sb->mountdata) {
  		kfree(cifs_sb->mountdata);
  		cifs_sb->mountdata = NULL;
  	}
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
208
  	unload_nls(cifs_sb->local_nls);
8044f7f46   Jens Axboe   cifs: add bdi bac...
209
  	bdi_destroy(&cifs_sb->bdi);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
210
  	kfree(cifs_sb);
6cfd01484   Christoph Hellwig   push BKL down int...
211
212
  
  	unlock_kernel();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
213
214
215
  }
  
  static int
726c33422   David Howells   [PATCH] VFS: Perm...
216
  cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
217
  {
726c33422   David Howells   [PATCH] VFS: Perm...
218
  	struct super_block *sb = dentry->d_sb;
39da98471   Steve French   [CIFS] Fix statfs...
219
220
  	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
  	struct cifsTconInfo *tcon = cifs_sb->tcon;
c81156dd2   Steve French   [PATCH] cifs: cle...
221
  	int rc = -EOPNOTSUPP;
39da98471   Steve French   [CIFS] Fix statfs...
222
  	int xid;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
223
224
  
  	xid = GetXid();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
225
  	buf->f_type = CIFS_MAGIC_NUMBER;
39da98471   Steve French   [CIFS] Fix statfs...
226
227
228
229
230
231
232
233
  	/*
  	 * PATH_MAX may be too long - it would presumably be total path,
  	 * but note that some servers (includinng Samba 3) have a shorter
  	 * maximum path.
  	 *
  	 * Instead could get the real value via SMB_QUERY_FS_ATTRIBUTE_INFO.
  	 */
  	buf->f_namelen = PATH_MAX;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
234
235
  	buf->f_files = 0;	/* undefined */
  	buf->f_ffree = 0;	/* unlimited */
39da98471   Steve French   [CIFS] Fix statfs...
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
  	/*
  	 * We could add a second check for a QFS Unix capability bit
  	 */
  	if ((tcon->ses->capabilities & CAP_UNIX) &&
  	    (CIFS_POSIX_EXTENSIONS & le64_to_cpu(tcon->fsUnixInfo.Capability)))
  		rc = CIFSSMBQFSPosixInfo(xid, tcon, buf);
  
  	/*
  	 * Only need to call the old QFSInfo if failed on newer one,
  	 * e.g. by OS/2.
  	 **/
  	if (rc && (tcon->ses->capabilities & CAP_NT_SMBS))
  		rc = CIFSSMBQFSInfo(xid, tcon, buf);
  
  	/*
  	 * Some old Windows servers also do not support level 103, retry with
  	 * older level one if old server failed the previous call or we
  	 * bypassed it because we detected that this was an older LANMAN sess
  	 */
4523cc304   Steve French   [CIFS] UID/GID ov...
255
  	if (rc)
39da98471   Steve French   [CIFS] Fix statfs...
256
  		rc = SMBOldQFSInfo(xid, tcon, buf);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
257
  	FreeXid(xid);
39da98471   Steve French   [CIFS] Fix statfs...
258
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
259
  }
e6305c43e   Al Viro   [PATCH] sanitize ...
260
  static int cifs_permission(struct inode *inode, int mask)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
261
262
263
264
  {
  	struct cifs_sb_info *cifs_sb;
  
  	cifs_sb = CIFS_SB(inode->i_sb);
f696a3659   Miklos Szeredi   [PATCH] move exec...
265
266
267
268
269
270
  	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) {
  		if ((mask & MAY_EXEC) && !execute_ok(inode))
  			return -EACCES;
  		else
  			return 0;
  	} else /* file mode might have been restricted at mount time
50c2f7538   Steve French   [CIFS] whitespace...
271
  		on the client (above and beyond ACL on servers) for
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
272
  		servers which do not support setting and viewing mode bits,
50c2f7538   Steve French   [CIFS] whitespace...
273
  		so allowing client to check permissions is useful */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
274
275
  		return generic_permission(inode, mask, NULL);
  }
e18b890bb   Christoph Lameter   [PATCH] slab: rem...
276
277
278
  static struct kmem_cache *cifs_inode_cachep;
  static struct kmem_cache *cifs_req_cachep;
  static struct kmem_cache *cifs_mid_cachep;
e18b890bb   Christoph Lameter   [PATCH] slab: rem...
279
  static struct kmem_cache *cifs_sm_req_cachep;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
280
281
282
283
284
285
286
287
  mempool_t *cifs_sm_req_poolp;
  mempool_t *cifs_req_poolp;
  mempool_t *cifs_mid_poolp;
  
  static struct inode *
  cifs_alloc_inode(struct super_block *sb)
  {
  	struct cifsInodeInfo *cifs_inode;
e94b17660   Christoph Lameter   [PATCH] slab: rem...
288
  	cifs_inode = kmem_cache_alloc(cifs_inode_cachep, GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
289
290
291
  	if (!cifs_inode)
  		return NULL;
  	cifs_inode->cifsAttrs = 0x20;	/* default */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
292
  	cifs_inode->time = 0;
cea218054   Jeff Layton   [CIFS] Fix potent...
293
  	cifs_inode->write_behind_rc = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
294
295
296
  	/* Until the file is open and we have gotten oplock
  	info back from the server, can not assume caching of
  	file data or metadata */
4b18f2a9c   Steve French   [CIFS] convert us...
297
298
  	cifs_inode->clientCanCacheRead = false;
  	cifs_inode->clientCanCacheAll = false;
9a8165fce   Jeff Layton   cifs: track Delet...
299
  	cifs_inode->delete_pending = false;
df2cf170c   Jeff Layton   cifs: overhaul ci...
300
  	cifs_inode->invalid_mapping = false;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
301
  	cifs_inode->vfs_inode.i_blkbits = 14;  /* 2**14 = CIFS_MAX_MSGSIZE */
fbec9ab95   Jeff Layton   cifs: vary timeou...
302
  	cifs_inode->server_eof = 0;
50c2f7538   Steve French   [CIFS] whitespace...
303

1b2b21260   Steve French   [CIFS] mtime boun...
304
305
306
  	/* Can not set i_flags here - they get immediately overwritten
  	   to zero by the VFS */
  /*	cifs_inode->vfs_inode.i_flags = S_NOATIME | S_NOCMTIME;*/
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
307
308
309
310
311
312
313
314
315
  	INIT_LIST_HEAD(&cifs_inode->openFileList);
  	return &cifs_inode->vfs_inode;
  }
  
  static void
  cifs_destroy_inode(struct inode *inode)
  {
  	kmem_cache_free(cifs_inode_cachep, CIFS_I(inode));
  }
61f98ffd7   Jeff Layton   cifs: display sco...
316
  static void
b57922d97   Al Viro   convert remaining...
317
  cifs_evict_inode(struct inode *inode)
9451a9a52   Suresh Jayaraman   cifs: define inod...
318
  {
b57922d97   Al Viro   convert remaining...
319
320
  	truncate_inode_pages(&inode->i_data, 0);
  	end_writeback(inode);
9451a9a52   Suresh Jayaraman   cifs: define inod...
321
322
323
324
  	cifs_fscache_release_inode_cookie(inode);
  }
  
  static void
61f98ffd7   Jeff Layton   cifs: display sco...
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
  cifs_show_address(struct seq_file *s, struct TCP_Server_Info *server)
  {
  	seq_printf(s, ",addr=");
  
  	switch (server->addr.sockAddr.sin_family) {
  	case AF_INET:
  		seq_printf(s, "%pI4", &server->addr.sockAddr.sin_addr.s_addr);
  		break;
  	case AF_INET6:
  		seq_printf(s, "%pI6",
  			   &server->addr.sockAddr6.sin6_addr.s6_addr);
  		if (server->addr.sockAddr6.sin6_scope_id)
  			seq_printf(s, "%%%u",
  				   server->addr.sockAddr6.sin6_scope_id);
  		break;
  	default:
  		seq_printf(s, "(unknown)");
  	}
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
344
345
346
347
348
349
350
351
  /*
   * cifs_show_options() is for displaying mount options in /proc/mounts.
   * Not all settable options are displayed but most of the important
   * ones are.
   */
  static int
  cifs_show_options(struct seq_file *s, struct vfsmount *m)
  {
8e047d09e   Jeff Layton   cifs: use tcon po...
352
353
  	struct cifs_sb_info *cifs_sb = CIFS_SB(m->mnt_sb);
  	struct cifsTconInfo *tcon = cifs_sb->tcon;
8616e0fc1   Jeff Layton   cifs: remove unne...
354

8e047d09e   Jeff Layton   cifs: use tcon po...
355
  	seq_printf(s, ",unc=%s", tcon->treeName);
8616e0fc1   Jeff Layton   cifs: remove unne...
356
357
358
359
  	if (tcon->ses->userName)
  		seq_printf(s, ",username=%s", tcon->ses->userName);
  	if (tcon->ses->domainName)
  		seq_printf(s, ",domain=%s", tcon->ses->domainName);
8616e0fc1   Jeff Layton   cifs: remove unne...
360
  	seq_printf(s, ",uid=%d", cifs_sb->mnt_uid);
340481a36   Jeff Layton   cifs: have cifs_s...
361
362
  	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
  		seq_printf(s, ",forceuid");
4486d6ede   Jeff Layton   cifs: show noforc...
363
364
  	else
  		seq_printf(s, ",noforceuid");
340481a36   Jeff Layton   cifs: have cifs_s...
365

8616e0fc1   Jeff Layton   cifs: remove unne...
366
  	seq_printf(s, ",gid=%d", cifs_sb->mnt_gid);
340481a36   Jeff Layton   cifs: have cifs_s...
367
368
  	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
  		seq_printf(s, ",forcegid");
4486d6ede   Jeff Layton   cifs: show noforc...
369
370
  	else
  		seq_printf(s, ",noforcegid");
8616e0fc1   Jeff Layton   cifs: remove unne...
371

61f98ffd7   Jeff Layton   cifs: display sco...
372
  	cifs_show_address(s, tcon->ses->server);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
373

8616e0fc1   Jeff Layton   cifs: remove unne...
374
375
  	if (!tcon->unix_ext)
  		seq_printf(s, ",file_mode=0%o,dir_mode=0%o",
2b280fab1   Steve French   [CIFS] add more c...
376
377
  					   cifs_sb->mnt_file_mode,
  					   cifs_sb->mnt_dir_mode);
8616e0fc1   Jeff Layton   cifs: remove unne...
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
  	if (tcon->seal)
  		seq_printf(s, ",seal");
  	if (tcon->nocase)
  		seq_printf(s, ",nocase");
  	if (tcon->retry)
  		seq_printf(s, ",hard");
  	if (cifs_sb->prepath)
  		seq_printf(s, ",prepath=%s", cifs_sb->prepath);
  	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
  		seq_printf(s, ",posixpaths");
  	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)
  		seq_printf(s, ",setuids");
  	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
  		seq_printf(s, ",serverino");
  	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
  		seq_printf(s, ",directio");
  	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
  		seq_printf(s, ",nouser_xattr");
  	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR)
  		seq_printf(s, ",mapchars");
  	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
  		seq_printf(s, ",sfu");
  	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
  		seq_printf(s, ",nobrl");
  	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
  		seq_printf(s, ",cifsacl");
  	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
  		seq_printf(s, ",dynperm");
  	if (m->mnt_sb->s_flags & MS_POSIXACL)
  		seq_printf(s, ",acl");
  
  	seq_printf(s, ",rsize=%d", cifs_sb->rsize);
  	seq_printf(s, ",wsize=%d", cifs_sb->wsize);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
411
412
  	return 0;
  }
42faad996   Al Viro   [PATCH] restore s...
413
  static void cifs_umount_begin(struct super_block *sb)
68058e757   Steve French   [CIFS] Reduce CIF...
414
  {
42faad996   Al Viro   [PATCH] restore s...
415
  	struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
50c2f7538   Steve French   [CIFS] whitespace...
416
  	struct cifsTconInfo *tcon;
68058e757   Steve French   [CIFS] Reduce CIF...
417

4523cc304   Steve French   [CIFS] UID/GID ov...
418
  	if (cifs_sb == NULL)
9e2e85f82   Steve French   [CIFS] Fix minor ...
419
420
421
  		return;
  
  	tcon = cifs_sb->tcon;
4523cc304   Steve French   [CIFS] UID/GID ov...
422
  	if (tcon == NULL)
9e2e85f82   Steve French   [CIFS] Fix minor ...
423
  		return;
f1987b44f   Jeff Layton   cifs: reinstate s...
424
425
  
  	read_lock(&cifs_tcp_ses_lock);
ad8034f19   Steve French   [CIFS] remove bkl...
426
427
428
429
430
431
432
  	if ((tcon->tc_count > 1) || (tcon->tidStatus == CifsExiting)) {
  		/* we have other mounts to same share or we have
  		   already tried to force umount this and woken up
  		   all waiting network requests, nothing to do */
  		read_unlock(&cifs_tcp_ses_lock);
  		return;
  	} else if (tcon->tc_count == 1)
5e1253b50   Steve French   [CIFS] Correct ci...
433
  		tcon->tidStatus = CifsExiting;
f1987b44f   Jeff Layton   cifs: reinstate s...
434
  	read_unlock(&cifs_tcp_ses_lock);
5e1253b50   Steve French   [CIFS] Correct ci...
435

3a5ff61c1   Steve French   [CIFS] Do not tim...
436
  	/* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */
7b7abfe3d   Steve French   (7b7abfe3dd81d659...
437
  	/* cancel_notify_requests(tcon); */
50c2f7538   Steve French   [CIFS] whitespace...
438
  	if (tcon->ses && tcon->ses->server) {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
439
  		cFYI(1, "wake up tasks now - umount begin not complete");
9e2e85f82   Steve French   [CIFS] Fix minor ...
440
  		wake_up_all(&tcon->ses->server->request_q);
6ab16d249   Steve French   [CIFS] Fix umount...
441
442
443
444
445
  		wake_up_all(&tcon->ses->server->response_q);
  		msleep(1); /* yield */
  		/* we have to kick the requests once more */
  		wake_up_all(&tcon->ses->server->response_q);
  		msleep(1);
5e1253b50   Steve French   [CIFS] Correct ci...
446
  	}
68058e757   Steve French   [CIFS] Reduce CIF...
447
448
449
  
  	return;
  }
68058e757   Steve French   [CIFS] Reduce CIF...
450

bf97d2871   Steve French   [CIFS] CIFS suppo...
451
452
453
454
455
456
457
  #ifdef CONFIG_CIFS_STATS2
  static int cifs_show_stats(struct seq_file *s, struct vfsmount *mnt)
  {
  	/* BB FIXME */
  	return 0;
  }
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
458
459
460
461
462
  static int cifs_remount(struct super_block *sb, int *flags, char *data)
  {
  	*flags |= MS_NODIRATIME;
  	return 0;
  }
45321ac54   Al Viro   Make ->drop_inode...
463
  static int cifs_drop_inode(struct inode *inode)
12420ac34   Jeff Layton   cifs: implement d...
464
465
  {
  	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
45321ac54   Al Viro   Make ->drop_inode...
466
467
468
  	/* no serverino => unconditional eviction */
  	return !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) ||
  		generic_drop_inode(inode);
12420ac34   Jeff Layton   cifs: implement d...
469
  }
ee9b6d61a   Josef 'Jeff' Sipek   [PATCH] Mark stru...
470
  static const struct super_operations cifs_super_ops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
471
472
473
474
  	.put_super = cifs_put_super,
  	.statfs = cifs_statfs,
  	.alloc_inode = cifs_alloc_inode,
  	.destroy_inode = cifs_destroy_inode,
12420ac34   Jeff Layton   cifs: implement d...
475
  	.drop_inode	= cifs_drop_inode,
b57922d97   Al Viro   convert remaining...
476
  	.evict_inode	= cifs_evict_inode,
12420ac34   Jeff Layton   cifs: implement d...
477
478
  /*	.delete_inode	= cifs_delete_inode,  */  /* Do not need above
  	function unless later we add lazy close of inodes or unless the
50c2f7538   Steve French   [CIFS] whitespace...
479
480
  	kernel forgets to call us with the same number of releases (closes)
  	as opens */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
481
  	.show_options = cifs_show_options,
7b7abfe3d   Steve French   (7b7abfe3dd81d659...
482
  	.umount_begin   = cifs_umount_begin,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
483
  	.remount_fs = cifs_remount,
bf97d2871   Steve French   [CIFS] CIFS suppo...
484
  #ifdef CONFIG_CIFS_STATS2
f46d3e119   Steve French   [CIFS] Fix typo i...
485
  	.show_stats = cifs_show_stats,
bf97d2871   Steve French   [CIFS] CIFS suppo...
486
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
487
  };
454e2398b   David Howells   [PATCH] VFS: Perm...
488
  static int
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
489
  cifs_get_sb(struct file_system_type *fs_type,
454e2398b   David Howells   [PATCH] VFS: Perm...
490
  	    int flags, const char *dev_name, void *data, struct vfsmount *mnt)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
491
492
493
  {
  	int rc;
  	struct super_block *sb = sget(fs_type, NULL, set_anon_super, NULL);
b6b38f704   Joe Perches   [CIFS] Neaten cER...
494
  	cFYI(1, "Devname: %s flags: %d ", dev_name, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
495
496
  
  	if (IS_ERR(sb))
454e2398b   David Howells   [PATCH] VFS: Perm...
497
  		return PTR_ERR(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
498
499
  
  	sb->s_flags = flags;
9b04c997b   Theodore Ts'o   [PATCH] vfs: MS_V...
500
  	rc = cifs_read_super(sb, data, dev_name, flags & MS_SILENT ? 1 : 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
501
  	if (rc) {
6f5bbff9a   Al Viro   Convert obvious p...
502
  		deactivate_locked_super(sb);
454e2398b   David Howells   [PATCH] VFS: Perm...
503
  		return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
504
505
  	}
  	sb->s_flags |= MS_ACTIVE;
a3ec947c8   Sukadev Bhattiprolu   vfs: simple_set_m...
506
507
  	simple_set_mnt(mnt, sb);
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
508
  }
027445c37   Badari Pulavarty   [PATCH] Vectorize...
509
510
  static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
  				   unsigned long nr_segs, loff_t pos)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
511
  {
e6a002964   Josef "Jeff" Sipek   [PATCH] cifs: cha...
512
  	struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
513
  	ssize_t written;
027445c37   Badari Pulavarty   [PATCH] Vectorize...
514
  	written = generic_file_aio_write(iocb, iov, nr_segs, pos);
87c89dd73   Steve French   [CIFS] Vectored a...
515
516
  	if (!CIFS_I(inode)->clientCanCacheAll)
  		filemap_fdatawrite(inode->i_mapping);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
517
518
  	return written;
  }
c32a0b689   Steve French   [CIFS] Allow loca...
519
520
521
  static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
  {
  	/* origin == SEEK_END => we must revalidate the cached file length */
0889a9441   Steve French   CIFS: Use SEEK_EN...
522
  	if (origin == SEEK_END) {
030e9d814   Steve French   [CIFS] lseek poll...
523
524
525
526
527
  		int retval;
  
  		/* some applications poll for the file length in this strange
  		   way so we must seek to end on non-oplocked files by
  		   setting the revalidate time to zero */
c33f8d327   Christoph Hellwig   [CIFS] Remove unn...
528
  		CIFS_I(file->f_path.dentry->d_inode)->time = 0;
030e9d814   Steve French   [CIFS] lseek poll...
529

abab095d1   Jeff Layton   cifs: add cifs_re...
530
  		retval = cifs_revalidate_file(file);
c32a0b689   Steve French   [CIFS] Allow loca...
531
532
533
  		if (retval < 0)
  			return (loff_t)retval;
  	}
9465efc9e   Andi Kleen   Remove BKL from r...
534
  	return generic_file_llseek_unlocked(file, offset, origin);
c32a0b689   Steve French   [CIFS] Allow loca...
535
  }
84210e912   Steve French   [CIFS] improve se...
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
  static int cifs_setlease(struct file *file, long arg, struct file_lock **lease)
  {
  	/* note that this is called by vfs setlease with the BKL held
  	   although I doubt that BKL is needed here in cifs */
  	struct inode *inode = file->f_path.dentry->d_inode;
  
  	if (!(S_ISREG(inode->i_mode)))
  		return -EINVAL;
  
  	/* check if file is oplocked */
  	if (((arg == F_RDLCK) &&
  		(CIFS_I(inode)->clientCanCacheRead)) ||
  	    ((arg == F_WRLCK) &&
  		(CIFS_I(inode)->clientCanCacheAll)))
  		return generic_setlease(file, arg, lease);
  	else if (CIFS_SB(inode->i_sb)->tcon->local_lease &&
  			!CIFS_I(inode)->clientCanCacheRead)
  		/* If the server claims to support oplock on this
  		   file, then we still need to check oplock even
  		   if the local_lease mount option is set, but there
  		   are servers which do not support oplock for which
  		   this mount option may be useful if the user
  		   knows that the file won't be changed on the server
  		   by anyone else */
  		return generic_setlease(file, arg, lease);
  	else
  		return -EAGAIN;
  }
84210e912   Steve French   [CIFS] improve se...
564

e6ab15827   Igor Mammedov   [CIFS] DFS suppor...
565
  struct file_system_type cifs_fs_type = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
566
567
568
569
570
571
  	.owner = THIS_MODULE,
  	.name = "cifs",
  	.get_sb = cifs_get_sb,
  	.kill_sb = kill_anon_super,
  	/*  .fs_flags */
  };
754661f14   Arjan van de Ven   [PATCH] mark stru...
572
  const struct inode_operations cifs_dir_inode_ops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
  	.create = cifs_create,
  	.lookup = cifs_lookup,
  	.getattr = cifs_getattr,
  	.unlink = cifs_unlink,
  	.link = cifs_hardlink,
  	.mkdir = cifs_mkdir,
  	.rmdir = cifs_rmdir,
  	.rename = cifs_rename,
  	.permission = cifs_permission,
  /*	revalidate:cifs_revalidate,   */
  	.setattr = cifs_setattr,
  	.symlink = cifs_symlink,
  	.mknod   = cifs_mknod,
  #ifdef CONFIG_CIFS_XATTR
  	.setxattr = cifs_setxattr,
  	.getxattr = cifs_getxattr,
  	.listxattr = cifs_listxattr,
  	.removexattr = cifs_removexattr,
  #endif
  };
754661f14   Arjan van de Ven   [PATCH] mark stru...
593
  const struct inode_operations cifs_file_inode_ops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
594
595
596
597
598
599
600
601
602
603
  /*	revalidate:cifs_revalidate, */
  	.setattr = cifs_setattr,
  	.getattr = cifs_getattr, /* do we need this anymore? */
  	.rename = cifs_rename,
  	.permission = cifs_permission,
  #ifdef CONFIG_CIFS_XATTR
  	.setxattr = cifs_setxattr,
  	.getxattr = cifs_getxattr,
  	.listxattr = cifs_listxattr,
  	.removexattr = cifs_removexattr,
50c2f7538   Steve French   [CIFS] whitespace...
604
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
605
  };
754661f14   Arjan van de Ven   [PATCH] mark stru...
606
  const struct inode_operations cifs_symlink_inode_ops = {
50c2f7538   Steve French   [CIFS] whitespace...
607
  	.readlink = generic_readlink,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
608
609
610
611
612
613
614
615
616
617
618
  	.follow_link = cifs_follow_link,
  	.put_link = cifs_put_link,
  	.permission = cifs_permission,
  	/* BB add the following two eventually */
  	/* revalidate: cifs_revalidate,
  	   setattr:    cifs_notify_change, *//* BB do we need notify change */
  #ifdef CONFIG_CIFS_XATTR
  	.setxattr = cifs_setxattr,
  	.getxattr = cifs_getxattr,
  	.listxattr = cifs_listxattr,
  	.removexattr = cifs_removexattr,
50c2f7538   Steve French   [CIFS] whitespace...
619
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
620
  };
4b6f5d20b   Arjan van de Ven   [PATCH] Make most...
621
  const struct file_operations cifs_file_ops = {
87c89dd73   Steve French   [CIFS] Vectored a...
622
623
  	.read = do_sync_read,
  	.write = do_sync_write,
87c89dd73   Steve French   [CIFS] Vectored a...
624
625
  	.aio_read = generic_file_aio_read,
  	.aio_write = cifs_file_aio_write,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
626
627
628
629
630
631
  	.open = cifs_open,
  	.release = cifs_close,
  	.lock = cifs_lock,
  	.fsync = cifs_fsync,
  	.flush = cifs_flush,
  	.mmap  = cifs_file_mmap,
5ffc4ef45   Jens Axboe   sendfile: remove ...
632
  	.splice_read = generic_file_splice_read,
c32a0b689   Steve French   [CIFS] Allow loca...
633
  	.llseek = cifs_llseek,
c67593a03   Steve French   [PATCH] cifs: Ena...
634
  #ifdef CONFIG_CIFS_POSIX
f9ddcca4c   Steve French   [CIFS] BKL-remova...
635
  	.unlocked_ioctl	= cifs_ioctl,
c67593a03   Steve French   [PATCH] cifs: Ena...
636
  #endif /* CONFIG_CIFS_POSIX */
84210e912   Steve French   [CIFS] improve se...
637
  	.setlease = cifs_setlease,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
638
  };
4b6f5d20b   Arjan van de Ven   [PATCH] Make most...
639
  const struct file_operations cifs_file_direct_ops = {
a994b8fa6   Steve French   [CIFS] Enable mma...
640
  	/* no aio, no readv -
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
641
642
643
644
645
646
647
648
  	   BB reevaluate whether they can be done with directio, no cache */
  	.read = cifs_user_read,
  	.write = cifs_user_write,
  	.open = cifs_open,
  	.release = cifs_close,
  	.lock = cifs_lock,
  	.fsync = cifs_fsync,
  	.flush = cifs_flush,
a994b8fa6   Steve French   [CIFS] Enable mma...
649
  	.mmap = cifs_file_mmap,
5ffc4ef45   Jens Axboe   sendfile: remove ...
650
  	.splice_read = generic_file_splice_read,
c67593a03   Steve French   [PATCH] cifs: Ena...
651
  #ifdef CONFIG_CIFS_POSIX
f9ddcca4c   Steve French   [CIFS] BKL-remova...
652
  	.unlocked_ioctl  = cifs_ioctl,
c67593a03   Steve French   [PATCH] cifs: Ena...
653
  #endif /* CONFIG_CIFS_POSIX */
c32a0b689   Steve French   [CIFS] Allow loca...
654
  	.llseek = cifs_llseek,
84210e912   Steve French   [CIFS] improve se...
655
  	.setlease = cifs_setlease,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
656
  };
4b6f5d20b   Arjan van de Ven   [PATCH] Make most...
657
  const struct file_operations cifs_file_nobrl_ops = {
87c89dd73   Steve French   [CIFS] Vectored a...
658
659
  	.read = do_sync_read,
  	.write = do_sync_write,
87c89dd73   Steve French   [CIFS] Vectored a...
660
661
662
663
664
665
666
  	.aio_read = generic_file_aio_read,
  	.aio_write = cifs_file_aio_write,
  	.open = cifs_open,
  	.release = cifs_close,
  	.fsync = cifs_fsync,
  	.flush = cifs_flush,
  	.mmap  = cifs_file_mmap,
5ffc4ef45   Jens Axboe   sendfile: remove ...
667
  	.splice_read = generic_file_splice_read,
c32a0b689   Steve French   [CIFS] Allow loca...
668
  	.llseek = cifs_llseek,
8b94bcb92   Steve French   [CIFS] Fix CIFS "...
669
  #ifdef CONFIG_CIFS_POSIX
f9ddcca4c   Steve French   [CIFS] BKL-remova...
670
  	.unlocked_ioctl	= cifs_ioctl,
8b94bcb92   Steve French   [CIFS] Fix CIFS "...
671
  #endif /* CONFIG_CIFS_POSIX */
84210e912   Steve French   [CIFS] improve se...
672
  	.setlease = cifs_setlease,
8b94bcb92   Steve French   [CIFS] Fix CIFS "...
673
  };
4b6f5d20b   Arjan van de Ven   [PATCH] Make most...
674
  const struct file_operations cifs_file_direct_nobrl_ops = {
50c2f7538   Steve French   [CIFS] whitespace...
675
  	/* no mmap, no aio, no readv -
87c89dd73   Steve French   [CIFS] Vectored a...
676
677
678
679
680
681
682
  	   BB reevaluate whether they can be done with directio, no cache */
  	.read = cifs_user_read,
  	.write = cifs_user_write,
  	.open = cifs_open,
  	.release = cifs_close,
  	.fsync = cifs_fsync,
  	.flush = cifs_flush,
810627a01   Pavel Shilovsky   [CIFS] Add mmap f...
683
  	.mmap = cifs_file_mmap,
5ffc4ef45   Jens Axboe   sendfile: remove ...
684
  	.splice_read = generic_file_splice_read,
8b94bcb92   Steve French   [CIFS] Fix CIFS "...
685
  #ifdef CONFIG_CIFS_POSIX
f9ddcca4c   Steve French   [CIFS] BKL-remova...
686
  	.unlocked_ioctl  = cifs_ioctl,
8b94bcb92   Steve French   [CIFS] Fix CIFS "...
687
  #endif /* CONFIG_CIFS_POSIX */
c32a0b689   Steve French   [CIFS] Allow loca...
688
  	.llseek = cifs_llseek,
84210e912   Steve French   [CIFS] improve se...
689
  	.setlease = cifs_setlease,
8b94bcb92   Steve French   [CIFS] Fix CIFS "...
690
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
691

4b6f5d20b   Arjan van de Ven   [PATCH] Make most...
692
  const struct file_operations cifs_dir_ops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
693
694
695
  	.readdir = cifs_readdir,
  	.release = cifs_closedir,
  	.read    = generic_read_dir,
f9ddcca4c   Steve French   [CIFS] BKL-remova...
696
  	.unlocked_ioctl  = cifs_ioctl,
3222a3e55   Christoph Hellwig   [PATCH] fix ->lls...
697
  	.llseek = generic_file_llseek,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
698
699
700
  };
  
  static void
51cc50685   Alexey Dobriyan   SL*B: drop kmem c...
701
  cifs_init_once(void *inode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
702
703
  {
  	struct cifsInodeInfo *cifsi = inode;
a35afb830   Christoph Lameter   Remove SLAB_CTOR_...
704
705
  	inode_init_once(&cifsi->vfs_inode);
  	INIT_LIST_HEAD(&cifsi->lockList);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
706
707
708
709
710
711
  }
  
  static int
  cifs_init_inodecache(void)
  {
  	cifs_inode_cachep = kmem_cache_create("cifs_inode_cache",
26f57364d   Steve French   [CIFS] formatting...
712
  					      sizeof(struct cifsInodeInfo),
fffb60f93   Paul Jackson   [PATCH] cpuset me...
713
714
  					      0, (SLAB_RECLAIM_ACCOUNT|
  						SLAB_MEM_SPREAD),
20c2df83d   Paul Mundt   mm: Remove slab d...
715
  					      cifs_init_once);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
716
717
718
719
720
721
722
723
724
  	if (cifs_inode_cachep == NULL)
  		return -ENOMEM;
  
  	return 0;
  }
  
  static void
  cifs_destroy_inodecache(void)
  {
1a1d92c10   Alexey Dobriyan   [PATCH] Really ig...
725
  	kmem_cache_destroy(cifs_inode_cachep);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
726
727
728
729
730
  }
  
  static int
  cifs_init_request_bufs(void)
  {
4523cc304   Steve French   [CIFS] UID/GID ov...
731
  	if (CIFSMaxBufSize < 8192) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
732
733
734
735
736
737
738
739
  	/* Buffer size can not be smaller than 2 * PATH_MAX since maximum
  	Unicode path name has to fit in any SMB/CIFS path based frames */
  		CIFSMaxBufSize = 8192;
  	} else if (CIFSMaxBufSize > 1024*127) {
  		CIFSMaxBufSize = 1024 * 127;
  	} else {
  		CIFSMaxBufSize &= 0x1FE00; /* Round size to even 512 byte mult*/
  	}
b6b38f704   Joe Perches   [CIFS] Neaten cER...
740
  /*	cERROR(1, "CIFSMaxBufSize %d 0x%x",CIFSMaxBufSize,CIFSMaxBufSize); */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
741
742
743
  	cifs_req_cachep = kmem_cache_create("cifs_request",
  					    CIFSMaxBufSize +
  					    MAX_CIFS_HDR_SIZE, 0,
20c2df83d   Paul Mundt   mm: Remove slab d...
744
  					    SLAB_HWCACHE_ALIGN, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
745
746
  	if (cifs_req_cachep == NULL)
  		return -ENOMEM;
4523cc304   Steve French   [CIFS] UID/GID ov...
747
  	if (cifs_min_rcv < 1)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
748
749
750
  		cifs_min_rcv = 1;
  	else if (cifs_min_rcv > 64) {
  		cifs_min_rcv = 64;
b6b38f704   Joe Perches   [CIFS] Neaten cER...
751
  		cERROR(1, "cifs_min_rcv set to maximum (64)");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
752
  	}
93d2341c7   Matthew Dobson   [PATCH] mempool: ...
753
754
  	cifs_req_poolp = mempool_create_slab_pool(cifs_min_rcv,
  						  cifs_req_cachep);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
755

4523cc304   Steve French   [CIFS] UID/GID ov...
756
  	if (cifs_req_poolp == NULL) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
757
758
759
  		kmem_cache_destroy(cifs_req_cachep);
  		return -ENOMEM;
  	}
ec637e3ff   Steve French   [CIFS] Avoid extr...
760
  	/* MAX_CIFS_SMALL_BUFFER_SIZE bytes is enough for most SMB responses and
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
761
762
  	almost all handle based requests (but not write response, nor is it
  	sufficient for path based requests).  A smaller size would have
50c2f7538   Steve French   [CIFS] whitespace...
763
  	been more efficient (compacting multiple slab items on one 4k page)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
764
765
  	for the case in which debug was on, but this larger size allows
  	more SMBs to use small buffer alloc and is still much more
6dc0f87e3   Steve French   [CIFS] whitespace...
766
  	efficient to alloc 1 per page off the slab compared to 17K (5page)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
767
768
  	alloc of large cifs buffers even when page debugging is on */
  	cifs_sm_req_cachep = kmem_cache_create("cifs_small_rq",
6dc0f87e3   Steve French   [CIFS] whitespace...
769
  			MAX_CIFS_SMALL_BUFFER_SIZE, 0, SLAB_HWCACHE_ALIGN,
20c2df83d   Paul Mundt   mm: Remove slab d...
770
  			NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
771
772
773
  	if (cifs_sm_req_cachep == NULL) {
  		mempool_destroy(cifs_req_poolp);
  		kmem_cache_destroy(cifs_req_cachep);
6dc0f87e3   Steve French   [CIFS] whitespace...
774
  		return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
775
  	}
4523cc304   Steve French   [CIFS] UID/GID ov...
776
  	if (cifs_min_small < 2)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
777
778
779
  		cifs_min_small = 2;
  	else if (cifs_min_small > 256) {
  		cifs_min_small = 256;
b6b38f704   Joe Perches   [CIFS] Neaten cER...
780
  		cFYI(1, "cifs_min_small set to maximum (256)");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
781
  	}
93d2341c7   Matthew Dobson   [PATCH] mempool: ...
782
783
  	cifs_sm_req_poolp = mempool_create_slab_pool(cifs_min_small,
  						     cifs_sm_req_cachep);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
784

4523cc304   Steve French   [CIFS] UID/GID ov...
785
  	if (cifs_sm_req_poolp == NULL) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
786
787
788
789
790
791
792
793
794
795
796
797
798
  		mempool_destroy(cifs_req_poolp);
  		kmem_cache_destroy(cifs_req_cachep);
  		kmem_cache_destroy(cifs_sm_req_cachep);
  		return -ENOMEM;
  	}
  
  	return 0;
  }
  
  static void
  cifs_destroy_request_bufs(void)
  {
  	mempool_destroy(cifs_req_poolp);
1a1d92c10   Alexey Dobriyan   [PATCH] Really ig...
799
  	kmem_cache_destroy(cifs_req_cachep);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
800
  	mempool_destroy(cifs_sm_req_poolp);
1a1d92c10   Alexey Dobriyan   [PATCH] Really ig...
801
  	kmem_cache_destroy(cifs_sm_req_cachep);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
802
803
804
805
806
807
  }
  
  static int
  cifs_init_mids(void)
  {
  	cifs_mid_cachep = kmem_cache_create("cifs_mpx_ids",
26f57364d   Steve French   [CIFS] formatting...
808
809
  					    sizeof(struct mid_q_entry), 0,
  					    SLAB_HWCACHE_ALIGN, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
810
811
  	if (cifs_mid_cachep == NULL)
  		return -ENOMEM;
93d2341c7   Matthew Dobson   [PATCH] mempool: ...
812
813
  	/* 3 is a reasonable minimum number of simultaneous operations */
  	cifs_mid_poolp = mempool_create_slab_pool(3, cifs_mid_cachep);
4523cc304   Steve French   [CIFS] UID/GID ov...
814
  	if (cifs_mid_poolp == NULL) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
815
816
817
  		kmem_cache_destroy(cifs_mid_cachep);
  		return -ENOMEM;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
818
819
820
821
822
823
824
  	return 0;
  }
  
  static void
  cifs_destroy_mids(void)
  {
  	mempool_destroy(cifs_mid_poolp);
1a1d92c10   Alexey Dobriyan   [PATCH] Really ig...
825
  	kmem_cache_destroy(cifs_mid_cachep);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
826
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
827
828
829
830
  static int __init
  init_cifs(void)
  {
  	int rc = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
831
  	cifs_proc_init();
e7ddee903   Jeff Layton   cifs: disable sha...
832
  	INIT_LIST_HEAD(&cifs_tcp_ses_list);
4ca9c190d   Steve French   [CIFS] Fix oops i...
833
834
835
  #ifdef CONFIG_CIFS_EXPERIMENTAL
  	INIT_LIST_HEAD(&GlobalDnotifyReqList);
  	INIT_LIST_HEAD(&GlobalDnotifyRsp_Q);
6dc0f87e3   Steve French   [CIFS] whitespace...
836
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
837
838
839
840
841
  /*
   *  Initialize Global counters
   */
  	atomic_set(&sesInfoAllocCount, 0);
  	atomic_set(&tconInfoAllocCount, 0);
6dc0f87e3   Steve French   [CIFS] whitespace...
842
  	atomic_set(&tcpSesAllocCount, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
843
844
845
846
  	atomic_set(&tcpSesReconnectCount, 0);
  	atomic_set(&tconInfoReconnectCount, 0);
  
  	atomic_set(&bufAllocCount, 0);
4498eed50   Steve French   [CIFS] Add extend...
847
848
849
850
851
  	atomic_set(&smBufAllocCount, 0);
  #ifdef CONFIG_CIFS_STATS2
  	atomic_set(&totBufAllocCount, 0);
  	atomic_set(&totSmBufAllocCount, 0);
  #endif /* CONFIG_CIFS_STATS2 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
852
853
854
855
  	atomic_set(&midCount, 0);
  	GlobalCurrentXid = 0;
  	GlobalTotalActiveXid = 0;
  	GlobalMaxActiveXid = 0;
2cd646a2d   Steve French   [CIFS] Remove sta...
856
  	memset(Local_System_Name, 0, 15);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
857
  	rwlock_init(&GlobalSMBSeslock);
e7ddee903   Jeff Layton   cifs: disable sha...
858
  	rwlock_init(&cifs_tcp_ses_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
859
  	spin_lock_init(&GlobalMid_Lock);
4523cc304   Steve French   [CIFS] UID/GID ov...
860
  	if (cifs_max_pending < 2) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
861
  		cifs_max_pending = 2;
b6b38f704   Joe Perches   [CIFS] Neaten cER...
862
  		cFYI(1, "cifs_max_pending set to min of 2");
4523cc304   Steve French   [CIFS] UID/GID ov...
863
  	} else if (cifs_max_pending > 256) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
864
  		cifs_max_pending = 256;
b6b38f704   Joe Perches   [CIFS] Neaten cER...
865
  		cFYI(1, "cifs_max_pending set to max of 256");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
866
  	}
f579cf3cf   Suresh Jayaraman   cifs: register CI...
867
868
869
  	rc = cifs_fscache_register();
  	if (rc)
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
870
  	rc = cifs_init_inodecache();
45af7a0f2   Steve French   [CIFS] Use the kt...
871
872
873
874
875
876
877
878
879
880
881
882
883
884
  	if (rc)
  		goto out_clean_proc;
  
  	rc = cifs_init_mids();
  	if (rc)
  		goto out_destroy_inodecache;
  
  	rc = cifs_init_request_bufs();
  	if (rc)
  		goto out_destroy_mids;
  
  	rc = register_filesystem(&cifs_fs_type);
  	if (rc)
  		goto out_destroy_request_bufs;
84a15b935   Jeff Layton   [CIFS] Register a...
885
886
887
888
889
  #ifdef CONFIG_CIFS_UPCALL
  	rc = register_key_type(&cifs_spnego_key_type);
  	if (rc)
  		goto out_unregister_filesystem;
  #endif
45af7a0f2   Steve French   [CIFS] Use the kt...
890

45af7a0f2   Steve French   [CIFS] Use the kt...
891
  	return 0;
84a15b935   Jeff Layton   [CIFS] Register a...
892
  #ifdef CONFIG_CIFS_UPCALL
45af7a0f2   Steve French   [CIFS] Use the kt...
893
894
   out_unregister_filesystem:
  	unregister_filesystem(&cifs_fs_type);
1fc7995d1   Linus Torvalds   Merge git://git.k...
895
  #endif
45af7a0f2   Steve French   [CIFS] Use the kt...
896
897
898
899
900
901
902
   out_destroy_request_bufs:
  	cifs_destroy_request_bufs();
   out_destroy_mids:
  	cifs_destroy_mids();
   out_destroy_inodecache:
  	cifs_destroy_inodecache();
   out_clean_proc:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
903
  	cifs_proc_clean();
f579cf3cf   Suresh Jayaraman   cifs: register CI...
904
905
  	cifs_fscache_unregister();
   out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
906
907
908
909
910
911
  	return rc;
  }
  
  static void __exit
  exit_cifs(void)
  {
b6b38f704   Joe Perches   [CIFS] Neaten cER...
912
  	cFYI(DBG2, "exit_cifs");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
913
  	cifs_proc_clean();
f579cf3cf   Suresh Jayaraman   cifs: register CI...
914
  	cifs_fscache_unregister();
6103335de   Steve French   [CIFS] DNS name r...
915
  #ifdef CONFIG_CIFS_DFS_UPCALL
78d31a3a8   Igor Mammedov   cifs: timeout dfs...
916
  	cifs_dfs_release_automount_timer();
6103335de   Steve French   [CIFS] DNS name r...
917
  #endif
84a15b935   Jeff Layton   [CIFS] Register a...
918
919
920
  #ifdef CONFIG_CIFS_UPCALL
  	unregister_key_type(&cifs_spnego_key_type);
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
921
922
923
924
  	unregister_filesystem(&cifs_fs_type);
  	cifs_destroy_inodecache();
  	cifs_destroy_mids();
  	cifs_destroy_request_bufs();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
925
926
927
  }
  
  MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>");
6dc0f87e3   Steve French   [CIFS] whitespace...
928
  MODULE_LICENSE("GPL");	/* combination of LGPL + GPL source behaves as GPL */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
929
  MODULE_DESCRIPTION
63135e088   Steve French   [CIFS] More white...
930
931
      ("VFS to access servers complying with the SNIA CIFS Specification "
       "e.g. Samba and Windows");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
932
933
934
  MODULE_VERSION(CIFS_VERSION);
  module_init(init_cifs)
  module_exit(exit_cifs)