diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-17 16:15:55 -0500 |
commit | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch) | |
tree | a8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /fs/cifs/cifsfs.c | |
parent | 406089d01562f1e2bf9f089fd7637009ebaad589 (diff) |
Patched in Tegra support.
Diffstat (limited to 'fs/cifs/cifsfs.c')
-rw-r--r-- | fs/cifs/cifsfs.c | 226 |
1 files changed, 100 insertions, 126 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index de7f9168a11..54b8f1e7da9 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/kthread.h> | 36 | #include <linux/kthread.h> |
37 | #include <linux/freezer.h> | 37 | #include <linux/freezer.h> |
38 | #include <linux/namei.h> | 38 | #include <linux/namei.h> |
39 | #include <linux/random.h> | ||
40 | #include <net/ipv6.h> | 39 | #include <net/ipv6.h> |
41 | #include "cifsfs.h" | 40 | #include "cifsfs.h" |
42 | #include "cifspdu.h" | 41 | #include "cifspdu.h" |
@@ -49,48 +48,44 @@ | |||
49 | #include <linux/key-type.h> | 48 | #include <linux/key-type.h> |
50 | #include "cifs_spnego.h" | 49 | #include "cifs_spnego.h" |
51 | #include "fscache.h" | 50 | #include "fscache.h" |
52 | #ifdef CONFIG_CIFS_SMB2 | 51 | #define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDUs */ |
53 | #include "smb2pdu.h" | ||
54 | #endif | ||
55 | 52 | ||
56 | int cifsFYI = 0; | 53 | int cifsFYI = 0; |
54 | int cifsERROR = 1; | ||
57 | int traceSMB = 0; | 55 | int traceSMB = 0; |
58 | bool enable_oplocks = true; | 56 | unsigned int oplockEnabled = 1; |
59 | unsigned int linuxExtEnabled = 1; | 57 | unsigned int linuxExtEnabled = 1; |
60 | unsigned int lookupCacheEnabled = 1; | 58 | unsigned int lookupCacheEnabled = 1; |
59 | unsigned int multiuser_mount = 0; | ||
61 | unsigned int global_secflags = CIFSSEC_DEF; | 60 | unsigned int global_secflags = CIFSSEC_DEF; |
62 | /* unsigned int ntlmv2_support = 0; */ | 61 | /* unsigned int ntlmv2_support = 0; */ |
63 | unsigned int sign_CIFS_PDUs = 1; | 62 | unsigned int sign_CIFS_PDUs = 1; |
64 | static const struct super_operations cifs_super_ops; | 63 | static const struct super_operations cifs_super_ops; |
65 | unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE; | 64 | unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE; |
66 | module_param(CIFSMaxBufSize, uint, 0); | 65 | module_param(CIFSMaxBufSize, int, 0); |
67 | MODULE_PARM_DESC(CIFSMaxBufSize, "Network buffer size (not including header). " | 66 | MODULE_PARM_DESC(CIFSMaxBufSize, "Network buffer size (not including header). " |
68 | "Default: 16384 Range: 8192 to 130048"); | 67 | "Default: 16384 Range: 8192 to 130048"); |
69 | unsigned int cifs_min_rcv = CIFS_MIN_RCV_POOL; | 68 | unsigned int cifs_min_rcv = CIFS_MIN_RCV_POOL; |
70 | module_param(cifs_min_rcv, uint, 0); | 69 | module_param(cifs_min_rcv, int, 0); |
71 | MODULE_PARM_DESC(cifs_min_rcv, "Network buffers in pool. Default: 4 Range: " | 70 | MODULE_PARM_DESC(cifs_min_rcv, "Network buffers in pool. Default: 4 Range: " |
72 | "1 to 64"); | 71 | "1 to 64"); |
73 | unsigned int cifs_min_small = 30; | 72 | unsigned int cifs_min_small = 30; |
74 | module_param(cifs_min_small, uint, 0); | 73 | module_param(cifs_min_small, int, 0); |
75 | MODULE_PARM_DESC(cifs_min_small, "Small network buffers in pool. Default: 30 " | 74 | MODULE_PARM_DESC(cifs_min_small, "Small network buffers in pool. Default: 30 " |
76 | "Range: 2 to 256"); | 75 | "Range: 2 to 256"); |
77 | unsigned int cifs_max_pending = CIFS_MAX_REQ; | 76 | unsigned int cifs_max_pending = CIFS_MAX_REQ; |
78 | module_param(cifs_max_pending, uint, 0444); | 77 | module_param(cifs_max_pending, int, 0); |
79 | MODULE_PARM_DESC(cifs_max_pending, "Simultaneous requests to server. " | 78 | MODULE_PARM_DESC(cifs_max_pending, "Simultaneous requests to server. " |
80 | "Default: 32767 Range: 2 to 32767."); | 79 | "Default: 50 Range: 2 to 256"); |
81 | module_param(enable_oplocks, bool, 0644); | 80 | unsigned short echo_retries = 5; |
82 | MODULE_PARM_DESC(enable_oplocks, "Enable or disable oplocks. Default: y/Y/1"); | 81 | module_param(echo_retries, ushort, 0644); |
83 | 82 | MODULE_PARM_DESC(echo_retries, "Number of echo attempts before giving up and " | |
83 | "reconnecting server. Default: 5. 0 means " | ||
84 | "never reconnect."); | ||
84 | extern mempool_t *cifs_sm_req_poolp; | 85 | extern mempool_t *cifs_sm_req_poolp; |
85 | extern mempool_t *cifs_req_poolp; | 86 | extern mempool_t *cifs_req_poolp; |
86 | extern mempool_t *cifs_mid_poolp; | 87 | extern mempool_t *cifs_mid_poolp; |
87 | 88 | ||
88 | struct workqueue_struct *cifsiod_wq; | ||
89 | |||
90 | #ifdef CONFIG_CIFS_SMB2 | ||
91 | __u8 cifs_client_guid[SMB2_CLIENT_GUID_SIZE]; | ||
92 | #endif | ||
93 | |||
94 | static int | 89 | static int |
95 | cifs_read_super(struct super_block *sb) | 90 | cifs_read_super(struct super_block *sb) |
96 | { | 91 | { |
@@ -120,32 +115,37 @@ cifs_read_super(struct super_block *sb) | |||
120 | 115 | ||
121 | if (IS_ERR(inode)) { | 116 | if (IS_ERR(inode)) { |
122 | rc = PTR_ERR(inode); | 117 | rc = PTR_ERR(inode); |
118 | inode = NULL; | ||
123 | goto out_no_root; | 119 | goto out_no_root; |
124 | } | 120 | } |
125 | 121 | ||
126 | sb->s_root = d_make_root(inode); | 122 | sb->s_root = d_alloc_root(inode); |
123 | |||
127 | if (!sb->s_root) { | 124 | if (!sb->s_root) { |
128 | rc = -ENOMEM; | 125 | rc = -ENOMEM; |
129 | goto out_no_root; | 126 | goto out_no_root; |
130 | } | 127 | } |
131 | 128 | ||
132 | /* do that *after* d_make_root() - we want NULL ->d_op for root here */ | 129 | /* do that *after* d_alloc_root() - we want NULL ->d_op for root here */ |
133 | if (cifs_sb_master_tcon(cifs_sb)->nocase) | 130 | if (cifs_sb_master_tcon(cifs_sb)->nocase) |
134 | sb->s_d_op = &cifs_ci_dentry_ops; | 131 | sb->s_d_op = &cifs_ci_dentry_ops; |
135 | else | 132 | else |
136 | sb->s_d_op = &cifs_dentry_ops; | 133 | sb->s_d_op = &cifs_dentry_ops; |
137 | 134 | ||
138 | #ifdef CONFIG_CIFS_NFSD_EXPORT | 135 | #ifdef CIFS_NFSD_EXPORT |
139 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { | 136 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { |
140 | cFYI(1, "export ops supported"); | 137 | cFYI(1, "export ops supported"); |
141 | sb->s_export_op = &cifs_export_ops; | 138 | sb->s_export_op = &cifs_export_ops; |
142 | } | 139 | } |
143 | #endif /* CONFIG_CIFS_NFSD_EXPORT */ | 140 | #endif /* CIFS_NFSD_EXPORT */ |
144 | 141 | ||
145 | return 0; | 142 | return 0; |
146 | 143 | ||
147 | out_no_root: | 144 | out_no_root: |
148 | cERROR(1, "cifs_read_super: get root inode failed"); | 145 | cERROR(1, "cifs_read_super: get root inode failed"); |
146 | if (inode) | ||
147 | iput(inode); | ||
148 | |||
149 | return rc; | 149 | return rc; |
150 | } | 150 | } |
151 | 151 | ||
@@ -162,11 +162,12 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
162 | struct super_block *sb = dentry->d_sb; | 162 | struct super_block *sb = dentry->d_sb; |
163 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); | 163 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
164 | struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); | 164 | struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); |
165 | struct TCP_Server_Info *server = tcon->ses->server; | 165 | int rc = -EOPNOTSUPP; |
166 | unsigned int xid; | 166 | int xid; |
167 | int rc = 0; | 167 | |
168 | xid = GetXid(); | ||
168 | 169 | ||
169 | xid = get_xid(); | 170 | buf->f_type = CIFS_MAGIC_NUMBER; |
170 | 171 | ||
171 | /* | 172 | /* |
172 | * PATH_MAX may be too long - it would presumably be total path, | 173 | * PATH_MAX may be too long - it would presumably be total path, |
@@ -179,10 +180,29 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
179 | buf->f_files = 0; /* undefined */ | 180 | buf->f_files = 0; /* undefined */ |
180 | buf->f_ffree = 0; /* unlimited */ | 181 | buf->f_ffree = 0; /* unlimited */ |
181 | 182 | ||
182 | if (server->ops->queryfs) | 183 | /* |
183 | rc = server->ops->queryfs(xid, tcon, buf); | 184 | * We could add a second check for a QFS Unix capability bit |
185 | */ | ||
186 | if ((tcon->ses->capabilities & CAP_UNIX) && | ||
187 | (CIFS_POSIX_EXTENSIONS & le64_to_cpu(tcon->fsUnixInfo.Capability))) | ||
188 | rc = CIFSSMBQFSPosixInfo(xid, tcon, buf); | ||
189 | |||
190 | /* | ||
191 | * Only need to call the old QFSInfo if failed on newer one, | ||
192 | * e.g. by OS/2. | ||
193 | **/ | ||
194 | if (rc && (tcon->ses->capabilities & CAP_NT_SMBS)) | ||
195 | rc = CIFSSMBQFSInfo(xid, tcon, buf); | ||
196 | |||
197 | /* | ||
198 | * Some old Windows servers also do not support level 103, retry with | ||
199 | * older level one if old server failed the previous call or we | ||
200 | * bypassed it because we detected that this was an older LANMAN sess | ||
201 | */ | ||
202 | if (rc) | ||
203 | rc = SMBOldQFSInfo(xid, tcon, buf); | ||
184 | 204 | ||
185 | free_xid(xid); | 205 | FreeXid(xid); |
186 | return 0; | 206 | return 0; |
187 | } | 207 | } |
188 | 208 | ||
@@ -221,10 +241,9 @@ cifs_alloc_inode(struct super_block *sb) | |||
221 | return NULL; | 241 | return NULL; |
222 | cifs_inode->cifsAttrs = 0x20; /* default */ | 242 | cifs_inode->cifsAttrs = 0x20; /* default */ |
223 | cifs_inode->time = 0; | 243 | cifs_inode->time = 0; |
224 | /* | 244 | /* Until the file is open and we have gotten oplock |
225 | * Until the file is open and we have gotten oplock info back from the | 245 | info back from the server, can not assume caching of |
226 | * server, can not assume caching of file data or metadata. | 246 | file data or metadata */ |
227 | */ | ||
228 | cifs_set_oplock_level(cifs_inode, 0); | 247 | cifs_set_oplock_level(cifs_inode, 0); |
229 | cifs_inode->delete_pending = false; | 248 | cifs_inode->delete_pending = false; |
230 | cifs_inode->invalid_mapping = false; | 249 | cifs_inode->invalid_mapping = false; |
@@ -232,22 +251,18 @@ cifs_alloc_inode(struct super_block *sb) | |||
232 | cifs_inode->server_eof = 0; | 251 | cifs_inode->server_eof = 0; |
233 | cifs_inode->uniqueid = 0; | 252 | cifs_inode->uniqueid = 0; |
234 | cifs_inode->createtime = 0; | 253 | cifs_inode->createtime = 0; |
235 | #ifdef CONFIG_CIFS_SMB2 | 254 | |
236 | get_random_bytes(cifs_inode->lease_key, SMB2_LEASE_KEY_SIZE); | 255 | /* Can not set i_flags here - they get immediately overwritten |
237 | #endif | 256 | to zero by the VFS */ |
238 | /* | 257 | /* cifs_inode->vfs_inode.i_flags = S_NOATIME | S_NOCMTIME;*/ |
239 | * Can not set i_flags here - they get immediately overwritten to zero | ||
240 | * by the VFS. | ||
241 | */ | ||
242 | /* cifs_inode->vfs_inode.i_flags = S_NOATIME | S_NOCMTIME; */ | ||
243 | INIT_LIST_HEAD(&cifs_inode->openFileList); | 258 | INIT_LIST_HEAD(&cifs_inode->openFileList); |
244 | INIT_LIST_HEAD(&cifs_inode->llist); | ||
245 | return &cifs_inode->vfs_inode; | 259 | return &cifs_inode->vfs_inode; |
246 | } | 260 | } |
247 | 261 | ||
248 | static void cifs_i_callback(struct rcu_head *head) | 262 | static void cifs_i_callback(struct rcu_head *head) |
249 | { | 263 | { |
250 | struct inode *inode = container_of(head, struct inode, i_rcu); | 264 | struct inode *inode = container_of(head, struct inode, i_rcu); |
265 | INIT_LIST_HEAD(&inode->i_dentry); | ||
251 | kmem_cache_free(cifs_inode_cachep, CIFS_I(inode)); | 266 | kmem_cache_free(cifs_inode_cachep, CIFS_I(inode)); |
252 | } | 267 | } |
253 | 268 | ||
@@ -261,7 +276,7 @@ static void | |||
261 | cifs_evict_inode(struct inode *inode) | 276 | cifs_evict_inode(struct inode *inode) |
262 | { | 277 | { |
263 | truncate_inode_pages(&inode->i_data, 0); | 278 | truncate_inode_pages(&inode->i_data, 0); |
264 | clear_inode(inode); | 279 | end_writeback(inode); |
265 | cifs_fscache_release_inode_cookie(inode); | 280 | cifs_fscache_release_inode_cookie(inode); |
266 | } | 281 | } |
267 | 282 | ||
@@ -318,38 +333,22 @@ cifs_show_security(struct seq_file *s, struct TCP_Server_Info *server) | |||
318 | seq_printf(s, "i"); | 333 | seq_printf(s, "i"); |
319 | } | 334 | } |
320 | 335 | ||
321 | static void | ||
322 | cifs_show_cache_flavor(struct seq_file *s, struct cifs_sb_info *cifs_sb) | ||
323 | { | ||
324 | seq_printf(s, ",cache="); | ||
325 | |||
326 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO) | ||
327 | seq_printf(s, "strict"); | ||
328 | else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) | ||
329 | seq_printf(s, "none"); | ||
330 | else | ||
331 | seq_printf(s, "loose"); | ||
332 | } | ||
333 | |||
334 | /* | 336 | /* |
335 | * cifs_show_options() is for displaying mount options in /proc/mounts. | 337 | * cifs_show_options() is for displaying mount options in /proc/mounts. |
336 | * Not all settable options are displayed but most of the important | 338 | * Not all settable options are displayed but most of the important |
337 | * ones are. | 339 | * ones are. |
338 | */ | 340 | */ |
339 | static int | 341 | static int |
340 | cifs_show_options(struct seq_file *s, struct dentry *root) | 342 | cifs_show_options(struct seq_file *s, struct vfsmount *m) |
341 | { | 343 | { |
342 | struct cifs_sb_info *cifs_sb = CIFS_SB(root->d_sb); | 344 | struct cifs_sb_info *cifs_sb = CIFS_SB(m->mnt_sb); |
343 | struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); | 345 | struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); |
344 | struct sockaddr *srcaddr; | 346 | struct sockaddr *srcaddr; |
345 | srcaddr = (struct sockaddr *)&tcon->ses->server->srcaddr; | 347 | srcaddr = (struct sockaddr *)&tcon->ses->server->srcaddr; |
346 | 348 | ||
347 | seq_printf(s, ",vers=%s", tcon->ses->server->vals->version_string); | ||
348 | cifs_show_security(s, tcon->ses->server); | 349 | cifs_show_security(s, tcon->ses->server); |
349 | cifs_show_cache_flavor(s, cifs_sb); | ||
350 | 350 | ||
351 | seq_printf(s, ",unc="); | 351 | seq_printf(s, ",unc=%s", tcon->treeName); |
352 | seq_escape(s, tcon->treeName, " \t\n\\"); | ||
353 | 352 | ||
354 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) | 353 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) |
355 | seq_printf(s, ",multiuser"); | 354 | seq_printf(s, ",multiuser"); |
@@ -375,13 +374,13 @@ cifs_show_options(struct seq_file *s, struct dentry *root) | |||
375 | (int)(srcaddr->sa_family)); | 374 | (int)(srcaddr->sa_family)); |
376 | } | 375 | } |
377 | 376 | ||
378 | seq_printf(s, ",uid=%u", cifs_sb->mnt_uid); | 377 | seq_printf(s, ",uid=%d", cifs_sb->mnt_uid); |
379 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) | 378 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) |
380 | seq_printf(s, ",forceuid"); | 379 | seq_printf(s, ",forceuid"); |
381 | else | 380 | else |
382 | seq_printf(s, ",noforceuid"); | 381 | seq_printf(s, ",noforceuid"); |
383 | 382 | ||
384 | seq_printf(s, ",gid=%u", cifs_sb->mnt_gid); | 383 | seq_printf(s, ",gid=%d", cifs_sb->mnt_gid); |
385 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) | 384 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) |
386 | seq_printf(s, ",forcegid"); | 385 | seq_printf(s, ",forcegid"); |
387 | else | 386 | else |
@@ -390,7 +389,7 @@ cifs_show_options(struct seq_file *s, struct dentry *root) | |||
390 | cifs_show_address(s, tcon->ses->server); | 389 | cifs_show_address(s, tcon->ses->server); |
391 | 390 | ||
392 | if (!tcon->unix_ext) | 391 | if (!tcon->unix_ext) |
393 | seq_printf(s, ",file_mode=0%ho,dir_mode=0%ho", | 392 | seq_printf(s, ",file_mode=0%o,dir_mode=0%o", |
394 | cifs_sb->mnt_file_mode, | 393 | cifs_sb->mnt_file_mode, |
395 | cifs_sb->mnt_dir_mode); | 394 | cifs_sb->mnt_dir_mode); |
396 | if (tcon->seal) | 395 | if (tcon->seal) |
@@ -413,6 +412,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root) | |||
413 | seq_printf(s, ",rwpidforward"); | 412 | seq_printf(s, ",rwpidforward"); |
414 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) | 413 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) |
415 | seq_printf(s, ",forcemand"); | 414 | seq_printf(s, ",forcemand"); |
415 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) | ||
416 | seq_printf(s, ",directio"); | ||
416 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) | 417 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) |
417 | seq_printf(s, ",nouser_xattr"); | 418 | seq_printf(s, ",nouser_xattr"); |
418 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR) | 419 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR) |
@@ -425,25 +426,17 @@ cifs_show_options(struct seq_file *s, struct dentry *root) | |||
425 | seq_printf(s, ",cifsacl"); | 426 | seq_printf(s, ",cifsacl"); |
426 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) | 427 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) |
427 | seq_printf(s, ",dynperm"); | 428 | seq_printf(s, ",dynperm"); |
428 | if (root->d_sb->s_flags & MS_POSIXACL) | 429 | if (m->mnt_sb->s_flags & MS_POSIXACL) |
429 | seq_printf(s, ",acl"); | 430 | seq_printf(s, ",acl"); |
430 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) | 431 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) |
431 | seq_printf(s, ",mfsymlinks"); | 432 | seq_printf(s, ",mfsymlinks"); |
432 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE) | 433 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE) |
433 | seq_printf(s, ",fsc"); | 434 | seq_printf(s, ",fsc"); |
434 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC) | 435 | |
435 | seq_printf(s, ",nostrictsync"); | 436 | seq_printf(s, ",rsize=%d", cifs_sb->rsize); |
436 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) | 437 | seq_printf(s, ",wsize=%d", cifs_sb->wsize); |
437 | seq_printf(s, ",noperm"); | ||
438 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPUID) | ||
439 | seq_printf(s, ",backupuid=%u", cifs_sb->mnt_backupuid); | ||
440 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPGID) | ||
441 | seq_printf(s, ",backupgid=%u", cifs_sb->mnt_backupgid); | ||
442 | |||
443 | seq_printf(s, ",rsize=%u", cifs_sb->rsize); | ||
444 | seq_printf(s, ",wsize=%u", cifs_sb->wsize); | ||
445 | /* convert actimeo and display it in seconds */ | 438 | /* convert actimeo and display it in seconds */ |
446 | seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ); | 439 | seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ); |
447 | 440 | ||
448 | return 0; | 441 | return 0; |
449 | } | 442 | } |
@@ -485,7 +478,7 @@ static void cifs_umount_begin(struct super_block *sb) | |||
485 | } | 478 | } |
486 | 479 | ||
487 | #ifdef CONFIG_CIFS_STATS2 | 480 | #ifdef CONFIG_CIFS_STATS2 |
488 | static int cifs_show_stats(struct seq_file *s, struct dentry *root) | 481 | static int cifs_show_stats(struct seq_file *s, struct vfsmount *mnt) |
489 | { | 482 | { |
490 | /* BB FIXME */ | 483 | /* BB FIXME */ |
491 | return 0; | 484 | return 0; |
@@ -537,6 +530,7 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb) | |||
537 | char *full_path = NULL; | 530 | char *full_path = NULL; |
538 | char *s, *p; | 531 | char *s, *p; |
539 | char sep; | 532 | char sep; |
533 | int xid; | ||
540 | 534 | ||
541 | full_path = cifs_build_path_to_root(vol, cifs_sb, | 535 | full_path = cifs_build_path_to_root(vol, cifs_sb, |
542 | cifs_sb_master_tcon(cifs_sb)); | 536 | cifs_sb_master_tcon(cifs_sb)); |
@@ -545,6 +539,7 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb) | |||
545 | 539 | ||
546 | cFYI(1, "Get root dentry for %s", full_path); | 540 | cFYI(1, "Get root dentry for %s", full_path); |
547 | 541 | ||
542 | xid = GetXid(); | ||
548 | sep = CIFS_DIR_SEP(cifs_sb); | 543 | sep = CIFS_DIR_SEP(cifs_sb); |
549 | dentry = dget(sb->s_root); | 544 | dentry = dget(sb->s_root); |
550 | p = s = full_path; | 545 | p = s = full_path; |
@@ -575,6 +570,7 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb) | |||
575 | dput(dentry); | 570 | dput(dentry); |
576 | dentry = child; | 571 | dentry = child; |
577 | } while (!IS_ERR(dentry)); | 572 | } while (!IS_ERR(dentry)); |
573 | _FreeXid(xid); | ||
578 | kfree(full_path); | 574 | kfree(full_path); |
579 | return dentry; | 575 | return dentry; |
580 | } | 576 | } |
@@ -629,10 +625,7 @@ cifs_do_mount(struct file_system_type *fs_type, | |||
629 | mnt_data.cifs_sb = cifs_sb; | 625 | mnt_data.cifs_sb = cifs_sb; |
630 | mnt_data.flags = flags; | 626 | mnt_data.flags = flags; |
631 | 627 | ||
632 | /* BB should we make this contingent on mount parm? */ | 628 | sb = sget(fs_type, cifs_match_super, cifs_set_super, &mnt_data); |
633 | flags |= MS_NODIRATIME | MS_NOATIME; | ||
634 | |||
635 | sb = sget(fs_type, cifs_match_super, cifs_set_super, flags, &mnt_data); | ||
636 | if (IS_ERR(sb)) { | 629 | if (IS_ERR(sb)) { |
637 | root = ERR_CAST(sb); | 630 | root = ERR_CAST(sb); |
638 | cifs_umount(cifs_sb); | 631 | cifs_umount(cifs_sb); |
@@ -643,6 +636,10 @@ cifs_do_mount(struct file_system_type *fs_type, | |||
643 | cFYI(1, "Use existing superblock"); | 636 | cFYI(1, "Use existing superblock"); |
644 | cifs_umount(cifs_sb); | 637 | cifs_umount(cifs_sb); |
645 | } else { | 638 | } else { |
639 | sb->s_flags = flags; | ||
640 | /* BB should we make this contingent on mount parm? */ | ||
641 | sb->s_flags |= MS_NODIRATIME | MS_NOATIME; | ||
642 | |||
646 | rc = cifs_read_super(sb); | 643 | rc = cifs_read_super(sb); |
647 | if (rc) { | 644 | if (rc) { |
648 | root = ERR_PTR(rc); | 645 | root = ERR_PTR(rc); |
@@ -693,13 +690,13 @@ static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, | |||
693 | return written; | 690 | return written; |
694 | } | 691 | } |
695 | 692 | ||
696 | static loff_t cifs_llseek(struct file *file, loff_t offset, int whence) | 693 | static loff_t cifs_llseek(struct file *file, loff_t offset, int origin) |
697 | { | 694 | { |
698 | /* | 695 | /* |
699 | * whence == SEEK_END || SEEK_DATA || SEEK_HOLE => we must revalidate | 696 | * origin == SEEK_END || SEEK_DATA || SEEK_HOLE => we must revalidate |
700 | * the cached file length | 697 | * the cached file length |
701 | */ | 698 | */ |
702 | if (whence != SEEK_SET && whence != SEEK_CUR) { | 699 | if (origin != SEEK_SET || origin != SEEK_CUR) { |
703 | int rc; | 700 | int rc; |
704 | struct inode *inode = file->f_path.dentry->d_inode; | 701 | struct inode *inode = file->f_path.dentry->d_inode; |
705 | 702 | ||
@@ -726,7 +723,7 @@ static loff_t cifs_llseek(struct file *file, loff_t offset, int whence) | |||
726 | if (rc < 0) | 723 | if (rc < 0) |
727 | return (loff_t)rc; | 724 | return (loff_t)rc; |
728 | } | 725 | } |
729 | return generic_file_llseek(file, offset, whence); | 726 | return generic_file_llseek_unlocked(file, offset, origin); |
730 | } | 727 | } |
731 | 728 | ||
732 | static int cifs_setlease(struct file *file, long arg, struct file_lock **lease) | 729 | static int cifs_setlease(struct file *file, long arg, struct file_lock **lease) |
@@ -768,7 +765,6 @@ struct file_system_type cifs_fs_type = { | |||
768 | }; | 765 | }; |
769 | const struct inode_operations cifs_dir_inode_ops = { | 766 | const struct inode_operations cifs_dir_inode_ops = { |
770 | .create = cifs_create, | 767 | .create = cifs_create, |
771 | .atomic_open = cifs_atomic_open, | ||
772 | .lookup = cifs_lookup, | 768 | .lookup = cifs_lookup, |
773 | .getattr = cifs_getattr, | 769 | .getattr = cifs_getattr, |
774 | .unlink = cifs_unlink, | 770 | .unlink = cifs_unlink, |
@@ -946,7 +942,7 @@ cifs_init_once(void *inode) | |||
946 | struct cifsInodeInfo *cifsi = inode; | 942 | struct cifsInodeInfo *cifsi = inode; |
947 | 943 | ||
948 | inode_init_once(&cifsi->vfs_inode); | 944 | inode_init_once(&cifsi->vfs_inode); |
949 | init_rwsem(&cifsi->lock_sem); | 945 | INIT_LIST_HEAD(&cifsi->lockList); |
950 | } | 946 | } |
951 | 947 | ||
952 | static int | 948 | static int |
@@ -966,25 +962,12 @@ cifs_init_inodecache(void) | |||
966 | static void | 962 | static void |
967 | cifs_destroy_inodecache(void) | 963 | cifs_destroy_inodecache(void) |
968 | { | 964 | { |
969 | /* | ||
970 | * Make sure all delayed rcu free inodes are flushed before we | ||
971 | * destroy cache. | ||
972 | */ | ||
973 | rcu_barrier(); | ||
974 | kmem_cache_destroy(cifs_inode_cachep); | 965 | kmem_cache_destroy(cifs_inode_cachep); |
975 | } | 966 | } |
976 | 967 | ||
977 | static int | 968 | static int |
978 | cifs_init_request_bufs(void) | 969 | cifs_init_request_bufs(void) |
979 | { | 970 | { |
980 | size_t max_hdr_size = MAX_CIFS_HDR_SIZE; | ||
981 | #ifdef CONFIG_CIFS_SMB2 | ||
982 | /* | ||
983 | * SMB2 maximum header size is bigger than CIFS one - no problems to | ||
984 | * allocate some more bytes for CIFS. | ||
985 | */ | ||
986 | max_hdr_size = MAX_SMB2_HDR_SIZE; | ||
987 | #endif | ||
988 | if (CIFSMaxBufSize < 8192) { | 971 | if (CIFSMaxBufSize < 8192) { |
989 | /* Buffer size can not be smaller than 2 * PATH_MAX since maximum | 972 | /* Buffer size can not be smaller than 2 * PATH_MAX since maximum |
990 | Unicode path name has to fit in any SMB/CIFS path based frames */ | 973 | Unicode path name has to fit in any SMB/CIFS path based frames */ |
@@ -996,7 +979,8 @@ cifs_init_request_bufs(void) | |||
996 | } | 979 | } |
997 | /* cERROR(1, "CIFSMaxBufSize %d 0x%x",CIFSMaxBufSize,CIFSMaxBufSize); */ | 980 | /* cERROR(1, "CIFSMaxBufSize %d 0x%x",CIFSMaxBufSize,CIFSMaxBufSize); */ |
998 | cifs_req_cachep = kmem_cache_create("cifs_request", | 981 | cifs_req_cachep = kmem_cache_create("cifs_request", |
999 | CIFSMaxBufSize + max_hdr_size, 0, | 982 | CIFSMaxBufSize + |
983 | MAX_CIFS_HDR_SIZE, 0, | ||
1000 | SLAB_HWCACHE_ALIGN, NULL); | 984 | SLAB_HWCACHE_ALIGN, NULL); |
1001 | if (cifs_req_cachep == NULL) | 985 | if (cifs_req_cachep == NULL) |
1002 | return -ENOMEM; | 986 | return -ENOMEM; |
@@ -1121,27 +1105,17 @@ init_cifs(void) | |||
1121 | spin_lock_init(&cifs_file_list_lock); | 1105 | spin_lock_init(&cifs_file_list_lock); |
1122 | spin_lock_init(&GlobalMid_Lock); | 1106 | spin_lock_init(&GlobalMid_Lock); |
1123 | 1107 | ||
1124 | #ifdef CONFIG_CIFS_SMB2 | ||
1125 | get_random_bytes(cifs_client_guid, SMB2_CLIENT_GUID_SIZE); | ||
1126 | #endif | ||
1127 | |||
1128 | if (cifs_max_pending < 2) { | 1108 | if (cifs_max_pending < 2) { |
1129 | cifs_max_pending = 2; | 1109 | cifs_max_pending = 2; |
1130 | cFYI(1, "cifs_max_pending set to min of 2"); | 1110 | cFYI(1, "cifs_max_pending set to min of 2"); |
1131 | } else if (cifs_max_pending > CIFS_MAX_REQ) { | 1111 | } else if (cifs_max_pending > 256) { |
1132 | cifs_max_pending = CIFS_MAX_REQ; | 1112 | cifs_max_pending = 256; |
1133 | cFYI(1, "cifs_max_pending set to max of %u", CIFS_MAX_REQ); | 1113 | cFYI(1, "cifs_max_pending set to max of 256"); |
1134 | } | ||
1135 | |||
1136 | cifsiod_wq = alloc_workqueue("cifsiod", WQ_FREEZABLE|WQ_MEM_RECLAIM, 0); | ||
1137 | if (!cifsiod_wq) { | ||
1138 | rc = -ENOMEM; | ||
1139 | goto out_clean_proc; | ||
1140 | } | 1114 | } |
1141 | 1115 | ||
1142 | rc = cifs_fscache_register(); | 1116 | rc = cifs_fscache_register(); |
1143 | if (rc) | 1117 | if (rc) |
1144 | goto out_destroy_wq; | 1118 | goto out_clean_proc; |
1145 | 1119 | ||
1146 | rc = cifs_init_inodecache(); | 1120 | rc = cifs_init_inodecache(); |
1147 | if (rc) | 1121 | if (rc) |
@@ -1189,8 +1163,6 @@ out_destroy_inodecache: | |||
1189 | cifs_destroy_inodecache(); | 1163 | cifs_destroy_inodecache(); |
1190 | out_unreg_fscache: | 1164 | out_unreg_fscache: |
1191 | cifs_fscache_unregister(); | 1165 | cifs_fscache_unregister(); |
1192 | out_destroy_wq: | ||
1193 | destroy_workqueue(cifsiod_wq); | ||
1194 | out_clean_proc: | 1166 | out_clean_proc: |
1195 | cifs_proc_clean(); | 1167 | cifs_proc_clean(); |
1196 | return rc; | 1168 | return rc; |
@@ -1200,20 +1172,22 @@ static void __exit | |||
1200 | exit_cifs(void) | 1172 | exit_cifs(void) |
1201 | { | 1173 | { |
1202 | cFYI(DBG2, "exit_cifs"); | 1174 | cFYI(DBG2, "exit_cifs"); |
1203 | unregister_filesystem(&cifs_fs_type); | 1175 | cifs_proc_clean(); |
1176 | cifs_fscache_unregister(); | ||
1177 | #ifdef CONFIG_CIFS_DFS_UPCALL | ||
1204 | cifs_dfs_release_automount_timer(); | 1178 | cifs_dfs_release_automount_timer(); |
1179 | #endif | ||
1205 | #ifdef CONFIG_CIFS_ACL | 1180 | #ifdef CONFIG_CIFS_ACL |
1181 | cifs_destroy_idmaptrees(); | ||
1206 | exit_cifs_idmap(); | 1182 | exit_cifs_idmap(); |
1207 | #endif | 1183 | #endif |
1208 | #ifdef CONFIG_CIFS_UPCALL | 1184 | #ifdef CONFIG_CIFS_UPCALL |
1209 | unregister_key_type(&cifs_spnego_key_type); | 1185 | unregister_key_type(&cifs_spnego_key_type); |
1210 | #endif | 1186 | #endif |
1211 | cifs_destroy_request_bufs(); | 1187 | unregister_filesystem(&cifs_fs_type); |
1212 | cifs_destroy_mids(); | ||
1213 | cifs_destroy_inodecache(); | 1188 | cifs_destroy_inodecache(); |
1214 | cifs_fscache_unregister(); | 1189 | cifs_destroy_mids(); |
1215 | destroy_workqueue(cifsiod_wq); | 1190 | cifs_destroy_request_bufs(); |
1216 | cifs_proc_clean(); | ||
1217 | } | 1191 | } |
1218 | 1192 | ||
1219 | MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>"); | 1193 | MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>"); |