aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/Kconfig20
-rw-r--r--fs/cifs/Makefile4
-rw-r--r--fs/cifs/README5
-rw-r--r--fs/cifs/cifs_debug.c56
-rw-r--r--fs/cifs/cifs_debug.h4
-rw-r--r--fs/cifs/cifsfs.c25
-rw-r--r--fs/cifs/cifsglob.h114
-rw-r--r--fs/cifs/cifsproto.h20
-rw-r--r--fs/cifs/cifssmb.c189
-rw-r--r--fs/cifs/connect.c182
-rw-r--r--fs/cifs/file.c783
-rw-r--r--fs/cifs/ioctl.c8
-rw-r--r--fs/cifs/misc.c155
-rw-r--r--fs/cifs/readdir.c15
-rw-r--r--fs/cifs/smb1ops.c243
-rw-r--r--fs/cifs/smb2ops.c27
-rw-r--r--fs/cifs/transport.c78
17 files changed, 1202 insertions, 726 deletions
diff --git a/fs/cifs/Kconfig b/fs/cifs/Kconfig
index 2b243af70aa3..a08306a8bec9 100644
--- a/fs/cifs/Kconfig
+++ b/fs/cifs/Kconfig
@@ -158,3 +158,23 @@ config CIFS_NFSD_EXPORT
158 depends on CIFS && EXPERIMENTAL && BROKEN 158 depends on CIFS && EXPERIMENTAL && BROKEN
159 help 159 help
160 Allows NFS server to export a CIFS mounted share (nfsd over cifs) 160 Allows NFS server to export a CIFS mounted share (nfsd over cifs)
161
162config CIFS_SMB2
163 bool "SMB2 network file system support (EXPERIMENTAL)"
164 depends on EXPERIMENTAL && INET && BROKEN
165 select NLS
166 select KEYS
167 select FSCACHE
168 select DNS_RESOLVER
169
170 help
171 This enables experimental support for the SMB2 (Server Message Block
172 version 2) protocol. The SMB2 protocol is the successor to the
173 popular CIFS and SMB network file sharing protocols. SMB2 is the
174 native file sharing mechanism for recent versions of Windows
175 operating systems (since Vista). SMB2 enablement will eventually
176 allow users better performance, security and features, than would be
177 possible with cifs. Note that smb2 mount options also are simpler
178 (compared to cifs) due to protocol improvements.
179
180 Unless you are a developer or tester, say N.
diff --git a/fs/cifs/Makefile b/fs/cifs/Makefile
index 005d524c3a4a..4b4127544349 100644
--- a/fs/cifs/Makefile
+++ b/fs/cifs/Makefile
@@ -6,7 +6,7 @@ obj-$(CONFIG_CIFS) += cifs.o
6cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \ 6cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \
7 link.o misc.o netmisc.o smbencrypt.o transport.o asn1.o \ 7 link.o misc.o netmisc.o smbencrypt.o transport.o asn1.o \
8 cifs_unicode.o nterr.o xattr.o cifsencrypt.o \ 8 cifs_unicode.o nterr.o xattr.o cifsencrypt.o \
9 readdir.o ioctl.o sess.o export.o 9 readdir.o ioctl.o sess.o export.o smb1ops.o
10 10
11cifs-$(CONFIG_CIFS_ACL) += cifsacl.o 11cifs-$(CONFIG_CIFS_ACL) += cifsacl.o
12 12
@@ -15,3 +15,5 @@ cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o
15cifs-$(CONFIG_CIFS_DFS_UPCALL) += dns_resolve.o cifs_dfs_ref.o 15cifs-$(CONFIG_CIFS_DFS_UPCALL) += dns_resolve.o cifs_dfs_ref.o
16 16
17cifs-$(CONFIG_CIFS_FSCACHE) += fscache.o cache.o 17cifs-$(CONFIG_CIFS_FSCACHE) += fscache.o cache.o
18
19cifs-$(CONFIG_CIFS_SMB2) += smb2ops.o
diff --git a/fs/cifs/README b/fs/cifs/README
index b7d782bab797..22ab7b5b8da7 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -608,11 +608,6 @@ Stats Lists summary resource usage information as well as per
608 in the kernel configuration. 608 in the kernel configuration.
609 609
610Configuration pseudo-files: 610Configuration pseudo-files:
611MultiuserMount If set to one, more than one CIFS session to
612 the same server ip address can be established
613 if more than one uid accesses the same mount
614 point and if the uids user/password mapping
615 information is available. (default is 0)
616PacketSigningEnabled If set to one, cifs packet signing is enabled 611PacketSigningEnabled If set to one, cifs packet signing is enabled
617 and will be used if the server requires 612 and will be used if the server requires
618 it. If set to two, cifs packet signing is 613 it. If set to two, cifs packet signing is
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
index 270464629416..e8140528ca5c 100644
--- a/fs/cifs/cifs_debug.c
+++ b/fs/cifs/cifs_debug.c
@@ -57,19 +57,21 @@ cifs_dump_mem(char *label, void *data, int length)
57 } 57 }
58} 58}
59 59
60#ifdef CONFIG_CIFS_DEBUG2
61void cifs_dump_detail(void *buf) 60void cifs_dump_detail(void *buf)
62{ 61{
62#ifdef CONFIG_CIFS_DEBUG2
63 struct smb_hdr *smb = (struct smb_hdr *)buf; 63 struct smb_hdr *smb = (struct smb_hdr *)buf;
64 64
65 cERROR(1, "Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d", 65 cERROR(1, "Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d",
66 smb->Command, smb->Status.CifsError, 66 smb->Command, smb->Status.CifsError,
67 smb->Flags, smb->Flags2, smb->Mid, smb->Pid); 67 smb->Flags, smb->Flags2, smb->Mid, smb->Pid);
68 cERROR(1, "smb buf %p len %d", smb, smbCalcSize(smb)); 68 cERROR(1, "smb buf %p len %d", smb, smbCalcSize(smb));
69#endif /* CONFIG_CIFS_DEBUG2 */
69} 70}
70 71
71void cifs_dump_mids(struct TCP_Server_Info *server) 72void cifs_dump_mids(struct TCP_Server_Info *server)
72{ 73{
74#ifdef CONFIG_CIFS_DEBUG2
73 struct list_head *tmp; 75 struct list_head *tmp;
74 struct mid_q_entry *mid_entry; 76 struct mid_q_entry *mid_entry;
75 77
@@ -102,8 +104,8 @@ void cifs_dump_mids(struct TCP_Server_Info *server)
102 } 104 }
103 } 105 }
104 spin_unlock(&GlobalMid_Lock); 106 spin_unlock(&GlobalMid_Lock);
105}
106#endif /* CONFIG_CIFS_DEBUG2 */ 107#endif /* CONFIG_CIFS_DEBUG2 */
108}
107 109
108#ifdef CONFIG_PROC_FS 110#ifdef CONFIG_PROC_FS
109static int cifs_debug_data_proc_show(struct seq_file *m, void *v) 111static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
@@ -420,7 +422,6 @@ static struct proc_dir_entry *proc_fs_cifs;
420static const struct file_operations cifsFYI_proc_fops; 422static const struct file_operations cifsFYI_proc_fops;
421static const struct file_operations cifs_lookup_cache_proc_fops; 423static const struct file_operations cifs_lookup_cache_proc_fops;
422static const struct file_operations traceSMB_proc_fops; 424static const struct file_operations traceSMB_proc_fops;
423static const struct file_operations cifs_multiuser_mount_proc_fops;
424static const struct file_operations cifs_security_flags_proc_fops; 425static const struct file_operations cifs_security_flags_proc_fops;
425static const struct file_operations cifs_linux_ext_proc_fops; 426static const struct file_operations cifs_linux_ext_proc_fops;
426 427
@@ -440,8 +441,6 @@ cifs_proc_init(void)
440 proc_create("traceSMB", 0, proc_fs_cifs, &traceSMB_proc_fops); 441 proc_create("traceSMB", 0, proc_fs_cifs, &traceSMB_proc_fops);
441 proc_create("LinuxExtensionsEnabled", 0, proc_fs_cifs, 442 proc_create("LinuxExtensionsEnabled", 0, proc_fs_cifs,
442 &cifs_linux_ext_proc_fops); 443 &cifs_linux_ext_proc_fops);
443 proc_create("MultiuserMount", 0, proc_fs_cifs,
444 &cifs_multiuser_mount_proc_fops);
445 proc_create("SecurityFlags", 0, proc_fs_cifs, 444 proc_create("SecurityFlags", 0, proc_fs_cifs,
446 &cifs_security_flags_proc_fops); 445 &cifs_security_flags_proc_fops);
447 proc_create("LookupCacheEnabled", 0, proc_fs_cifs, 446 proc_create("LookupCacheEnabled", 0, proc_fs_cifs,
@@ -460,7 +459,6 @@ cifs_proc_clean(void)
460#ifdef CONFIG_CIFS_STATS 459#ifdef CONFIG_CIFS_STATS
461 remove_proc_entry("Stats", proc_fs_cifs); 460 remove_proc_entry("Stats", proc_fs_cifs);
462#endif 461#endif
463 remove_proc_entry("MultiuserMount", proc_fs_cifs);
464 remove_proc_entry("SecurityFlags", proc_fs_cifs); 462 remove_proc_entry("SecurityFlags", proc_fs_cifs);
465 remove_proc_entry("LinuxExtensionsEnabled", proc_fs_cifs); 463 remove_proc_entry("LinuxExtensionsEnabled", proc_fs_cifs);
466 remove_proc_entry("LookupCacheEnabled", proc_fs_cifs); 464 remove_proc_entry("LookupCacheEnabled", proc_fs_cifs);
@@ -617,52 +615,6 @@ static const struct file_operations traceSMB_proc_fops = {
617 .write = traceSMB_proc_write, 615 .write = traceSMB_proc_write,
618}; 616};
619 617
620static int cifs_multiuser_mount_proc_show(struct seq_file *m, void *v)
621{
622 seq_printf(m, "%d\n", multiuser_mount);
623 return 0;
624}
625
626static int cifs_multiuser_mount_proc_open(struct inode *inode, struct file *fh)
627{
628 return single_open(fh, cifs_multiuser_mount_proc_show, NULL);
629}
630
631static ssize_t cifs_multiuser_mount_proc_write(struct file *file,
632 const char __user *buffer, size_t count, loff_t *ppos)
633{
634 char c;
635 int rc;
636 static bool warned;
637
638 rc = get_user(c, buffer);
639 if (rc)
640 return rc;
641 if (c == '0' || c == 'n' || c == 'N')
642 multiuser_mount = 0;
643 else if (c == '1' || c == 'y' || c == 'Y') {
644 multiuser_mount = 1;
645 if (!warned) {
646 warned = true;
647 printk(KERN_WARNING "CIFS VFS: The legacy multiuser "
648 "mount code is scheduled to be deprecated in "
649 "3.5. Please switch to using the multiuser "
650 "mount option.");
651 }
652 }
653
654 return count;
655}
656
657static const struct file_operations cifs_multiuser_mount_proc_fops = {
658 .owner = THIS_MODULE,
659 .open = cifs_multiuser_mount_proc_open,
660 .read = seq_read,
661 .llseek = seq_lseek,
662 .release = single_release,
663 .write = cifs_multiuser_mount_proc_write,
664};
665
666static int cifs_security_flags_proc_show(struct seq_file *m, void *v) 618static int cifs_security_flags_proc_show(struct seq_file *m, void *v)
667{ 619{
668 seq_printf(m, "0x%x\n", global_secflags); 620 seq_printf(m, "0x%x\n", global_secflags);
diff --git a/fs/cifs/cifs_debug.h b/fs/cifs/cifs_debug.h
index 566e0ae8dc2c..c0c68bb492d7 100644
--- a/fs/cifs/cifs_debug.h
+++ b/fs/cifs/cifs_debug.h
@@ -24,10 +24,10 @@
24#define _H_CIFS_DEBUG 24#define _H_CIFS_DEBUG
25 25
26void cifs_dump_mem(char *label, void *data, int length); 26void cifs_dump_mem(char *label, void *data, int length);
27#ifdef CONFIG_CIFS_DEBUG2
28#define DBG2 2
29void cifs_dump_detail(void *); 27void cifs_dump_detail(void *);
30void cifs_dump_mids(struct TCP_Server_Info *); 28void cifs_dump_mids(struct TCP_Server_Info *);
29#ifdef CONFIG_CIFS_DEBUG2
30#define DBG2 2
31#else 31#else
32#define DBG2 0 32#define DBG2 0
33#endif 33#endif
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 541ef81f6ae8..8b6e344eb0ba 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -56,7 +56,6 @@ int traceSMB = 0;
56bool enable_oplocks = true; 56bool enable_oplocks = true;
57unsigned int linuxExtEnabled = 1; 57unsigned int linuxExtEnabled = 1;
58unsigned int lookupCacheEnabled = 1; 58unsigned int lookupCacheEnabled = 1;
59unsigned int multiuser_mount = 0;
60unsigned int global_secflags = CIFSSEC_DEF; 59unsigned int global_secflags = CIFSSEC_DEF;
61/* unsigned int ntlmv2_support = 0; */ 60/* unsigned int ntlmv2_support = 0; */
62unsigned int sign_CIFS_PDUs = 1; 61unsigned int sign_CIFS_PDUs = 1;
@@ -125,7 +124,7 @@ cifs_read_super(struct super_block *sb)
125 goto out_no_root; 124 goto out_no_root;
126 } 125 }
127 126
128 /* do that *after* d_alloc_root() - we want NULL ->d_op for root here */ 127 /* do that *after* d_make_root() - we want NULL ->d_op for root here */
129 if (cifs_sb_master_tcon(cifs_sb)->nocase) 128 if (cifs_sb_master_tcon(cifs_sb)->nocase)
130 sb->s_d_op = &cifs_ci_dentry_ops; 129 sb->s_d_op = &cifs_ci_dentry_ops;
131 else 130 else
@@ -272,7 +271,7 @@ static void
272cifs_evict_inode(struct inode *inode) 271cifs_evict_inode(struct inode *inode)
273{ 272{
274 truncate_inode_pages(&inode->i_data, 0); 273 truncate_inode_pages(&inode->i_data, 0);
275 end_writeback(inode); 274 clear_inode(inode);
276 cifs_fscache_release_inode_cookie(inode); 275 cifs_fscache_release_inode_cookie(inode);
277} 276}
278 277
@@ -329,6 +328,19 @@ cifs_show_security(struct seq_file *s, struct TCP_Server_Info *server)
329 seq_printf(s, "i"); 328 seq_printf(s, "i");
330} 329}
331 330
331static void
332cifs_show_cache_flavor(struct seq_file *s, struct cifs_sb_info *cifs_sb)
333{
334 seq_printf(s, ",cache=");
335
336 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO)
337 seq_printf(s, "strict");
338 else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
339 seq_printf(s, "none");
340 else
341 seq_printf(s, "loose");
342}
343
332/* 344/*
333 * cifs_show_options() is for displaying mount options in /proc/mounts. 345 * cifs_show_options() is for displaying mount options in /proc/mounts.
334 * Not all settable options are displayed but most of the important 346 * Not all settable options are displayed but most of the important
@@ -342,7 +354,9 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
342 struct sockaddr *srcaddr; 354 struct sockaddr *srcaddr;
343 srcaddr = (struct sockaddr *)&tcon->ses->server->srcaddr; 355 srcaddr = (struct sockaddr *)&tcon->ses->server->srcaddr;
344 356
357 seq_printf(s, ",vers=%s", tcon->ses->server->vals->version_string);
345 cifs_show_security(s, tcon->ses->server); 358 cifs_show_security(s, tcon->ses->server);
359 cifs_show_cache_flavor(s, cifs_sb);
346 360
347 seq_printf(s, ",unc=%s", tcon->treeName); 361 seq_printf(s, ",unc=%s", tcon->treeName);
348 362
@@ -408,8 +422,6 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
408 seq_printf(s, ",rwpidforward"); 422 seq_printf(s, ",rwpidforward");
409 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) 423 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL)
410 seq_printf(s, ",forcemand"); 424 seq_printf(s, ",forcemand");
411 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
412 seq_printf(s, ",directio");
413 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) 425 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
414 seq_printf(s, ",nouser_xattr"); 426 seq_printf(s, ",nouser_xattr");
415 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR) 427 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR)
@@ -432,8 +444,6 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
432 seq_printf(s, ",nostrictsync"); 444 seq_printf(s, ",nostrictsync");
433 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) 445 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
434 seq_printf(s, ",noperm"); 446 seq_printf(s, ",noperm");
435 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO)
436 seq_printf(s, ",strictcache");
437 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPUID) 447 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPUID)
438 seq_printf(s, ",backupuid=%u", cifs_sb->mnt_backupuid); 448 seq_printf(s, ",backupuid=%u", cifs_sb->mnt_backupuid);
439 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPGID) 449 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPGID)
@@ -945,7 +955,6 @@ cifs_init_once(void *inode)
945 struct cifsInodeInfo *cifsi = inode; 955 struct cifsInodeInfo *cifsi = inode;
946 956
947 inode_init_once(&cifsi->vfs_inode); 957 inode_init_once(&cifsi->vfs_inode);
948 INIT_LIST_HEAD(&cifsi->llist);
949 mutex_init(&cifsi->lock_mutex); 958 mutex_init(&cifsi->lock_mutex);
950} 959}
951 960
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 4ff6313f0a91..6df0cbe1cbc9 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -43,6 +43,7 @@
43 43
44#define CIFS_MIN_RCV_POOL 4 44#define CIFS_MIN_RCV_POOL 4
45 45
46#define MAX_REOPEN_ATT 5 /* these many maximum attempts to reopen a file */
46/* 47/*
47 * default attribute cache timeout (jiffies) 48 * default attribute cache timeout (jiffies)
48 */ 49 */
@@ -150,6 +151,58 @@ struct cifs_cred {
150 ***************************************************************** 151 *****************************************************************
151 */ 152 */
152 153
154enum smb_version {
155 Smb_1 = 1,
156 Smb_21,
157};
158
159struct mid_q_entry;
160struct TCP_Server_Info;
161struct cifsFileInfo;
162struct cifs_ses;
163
164struct smb_version_operations {
165 int (*send_cancel)(struct TCP_Server_Info *, void *,
166 struct mid_q_entry *);
167 bool (*compare_fids)(struct cifsFileInfo *, struct cifsFileInfo *);
168 /* setup request: allocate mid, sign message */
169 int (*setup_request)(struct cifs_ses *, struct kvec *, unsigned int,
170 struct mid_q_entry **);
171 /* check response: verify signature, map error */
172 int (*check_receive)(struct mid_q_entry *, struct TCP_Server_Info *,
173 bool);
174 void (*add_credits)(struct TCP_Server_Info *, const unsigned int);
175 void (*set_credits)(struct TCP_Server_Info *, const int);
176 int * (*get_credits_field)(struct TCP_Server_Info *);
177 __u64 (*get_next_mid)(struct TCP_Server_Info *);
178 /* data offset from read response message */
179 unsigned int (*read_data_offset)(char *);
180 /* data length from read response message */
181 unsigned int (*read_data_length)(char *);
182 /* map smb to linux error */
183 int (*map_error)(char *, bool);
184 /* find mid corresponding to the response message */
185 struct mid_q_entry * (*find_mid)(struct TCP_Server_Info *, char *);
186 void (*dump_detail)(void *);
187 /* verify the message */
188 int (*check_message)(char *, unsigned int);
189 bool (*is_oplock_break)(char *, struct TCP_Server_Info *);
190};
191
192struct smb_version_values {
193 char *version_string;
194 __u32 large_lock_type;
195 __u32 exclusive_lock_type;
196 __u32 shared_lock_type;
197 __u32 unlock_lock_type;
198 size_t header_size;
199 size_t max_header_size;
200 size_t read_rsp_size;
201};
202
203#define HEADER_SIZE(server) (server->vals->header_size)
204#define MAX_HEADER_SIZE(server) (server->vals->max_header_size)
205
153struct smb_vol { 206struct smb_vol {
154 char *username; 207 char *username;
155 char *password; 208 char *password;
@@ -205,6 +258,8 @@ struct smb_vol {
205 bool sockopt_tcp_nodelay:1; 258 bool sockopt_tcp_nodelay:1;
206 unsigned short int port; 259 unsigned short int port;
207 unsigned long actimeo; /* attribute cache timeout (jiffies) */ 260 unsigned long actimeo; /* attribute cache timeout (jiffies) */
261 struct smb_version_operations *ops;
262 struct smb_version_values *vals;
208 char *prepath; 263 char *prepath;
209 struct sockaddr_storage srcaddr; /* allow binding to a local IP */ 264 struct sockaddr_storage srcaddr; /* allow binding to a local IP */
210 struct nls_table *local_nls; 265 struct nls_table *local_nls;
@@ -242,6 +297,8 @@ struct TCP_Server_Info {
242 int srv_count; /* reference counter */ 297 int srv_count; /* reference counter */
243 /* 15 character server name + 0x20 16th byte indicating type = srv */ 298 /* 15 character server name + 0x20 16th byte indicating type = srv */
244 char server_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL]; 299 char server_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL];
300 struct smb_version_operations *ops;
301 struct smb_version_values *vals;
245 enum statusEnum tcpStatus; /* what we think the status is */ 302 enum statusEnum tcpStatus; /* what we think the status is */
246 char *hostname; /* hostname portion of UNC string */ 303 char *hostname; /* hostname portion of UNC string */
247 struct socket *ssocket; 304 struct socket *ssocket;
@@ -321,16 +378,6 @@ in_flight(struct TCP_Server_Info *server)
321 return num; 378 return num;
322} 379}
323 380
324static inline int*
325get_credits_field(struct TCP_Server_Info *server)
326{
327 /*
328 * This will change to switch statement when we reserve slots for echos
329 * and oplock breaks.
330 */
331 return &server->credits;
332}
333
334static inline bool 381static inline bool
335has_credits(struct TCP_Server_Info *server, int *credits) 382has_credits(struct TCP_Server_Info *server, int *credits)
336{ 383{
@@ -341,16 +388,22 @@ has_credits(struct TCP_Server_Info *server, int *credits)
341 return num > 0; 388 return num > 0;
342} 389}
343 390
344static inline size_t 391static inline void
345header_size(void) 392add_credits(struct TCP_Server_Info *server, const unsigned int add)
346{ 393{
347 return sizeof(struct smb_hdr); 394 server->ops->add_credits(server, add);
348} 395}
349 396
350static inline size_t 397static inline void
351max_header_size(void) 398set_credits(struct TCP_Server_Info *server, const int val)
352{ 399{
353 return MAX_CIFS_HDR_SIZE; 400 server->ops->set_credits(server, val);
401}
402
403static inline __u64
404get_next_mid(struct TCP_Server_Info *server)
405{
406 return server->ops->get_next_mid(server);
354} 407}
355 408
356/* 409/*
@@ -547,8 +600,7 @@ struct cifsLockInfo {
547 __u64 offset; 600 __u64 offset;
548 __u64 length; 601 __u64 length;
549 __u32 pid; 602 __u32 pid;
550 __u8 type; 603 __u32 type;
551 __u16 netfid;
552}; 604};
553 605
554/* 606/*
@@ -573,6 +625,10 @@ struct cifs_search_info {
573struct cifsFileInfo { 625struct cifsFileInfo {
574 struct list_head tlist; /* pointer to next fid owned by tcon */ 626 struct list_head tlist; /* pointer to next fid owned by tcon */
575 struct list_head flist; /* next fid (file instance) for this inode */ 627 struct list_head flist; /* next fid (file instance) for this inode */
628 struct list_head llist; /*
629 * brlocks held by this fid, protected by
630 * lock_mutex from cifsInodeInfo structure
631 */
576 unsigned int uid; /* allows finding which FileInfo structure */ 632 unsigned int uid; /* allows finding which FileInfo structure */
577 __u32 pid; /* process id who opened file */ 633 __u32 pid; /* process id who opened file */
578 __u16 netfid; /* file id from remote */ 634 __u16 netfid; /* file id from remote */
@@ -615,9 +671,12 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file);
615 */ 671 */
616 672
617struct cifsInodeInfo { 673struct cifsInodeInfo {
618 struct list_head llist; /* brlocks for this inode */
619 bool can_cache_brlcks; 674 bool can_cache_brlcks;
620 struct mutex lock_mutex; /* protect two fields above */ 675 struct mutex lock_mutex; /*
676 * protect the field above and llist
677 * from every cifsFileInfo structure
678 * from openFileList
679 */
621 /* BB add in lists for dirty pages i.e. write caching info for oplock */ 680 /* BB add in lists for dirty pages i.e. write caching info for oplock */
622 struct list_head openFileList; 681 struct list_head openFileList;
623 __u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */ 682 __u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */
@@ -703,7 +762,6 @@ static inline void cifs_stats_bytes_read(struct cifs_tcon *tcon,
703 762
704#endif 763#endif
705 764
706struct mid_q_entry;
707 765
708/* 766/*
709 * This is the prototype for the mid receive function. This function is for 767 * This is the prototype for the mid receive function. This function is for
@@ -1042,12 +1100,7 @@ GLOBAL_EXTERN atomic_t smBufAllocCount;
1042GLOBAL_EXTERN atomic_t midCount; 1100GLOBAL_EXTERN atomic_t midCount;
1043 1101
1044/* Misc globals */ 1102/* Misc globals */
1045GLOBAL_EXTERN unsigned int multiuser_mount; /* if enabled allows new sessions 1103GLOBAL_EXTERN bool enable_oplocks; /* enable or disable oplocks */
1046 to be established on existing mount if we
1047 have the uid/password or Kerberos credential
1048 or equivalent for current user */
1049/* enable or disable oplocks */
1050GLOBAL_EXTERN bool enable_oplocks;
1051GLOBAL_EXTERN unsigned int lookupCacheEnabled; 1104GLOBAL_EXTERN unsigned int lookupCacheEnabled;
1052GLOBAL_EXTERN unsigned int global_secflags; /* if on, session setup sent 1105GLOBAL_EXTERN unsigned int global_secflags; /* if on, session setup sent
1053 with more secure ntlmssp2 challenge/resp */ 1106 with more secure ntlmssp2 challenge/resp */
@@ -1074,4 +1127,11 @@ void cifs_oplock_break(struct work_struct *work);
1074extern const struct slow_work_ops cifs_oplock_break_ops; 1127extern const struct slow_work_ops cifs_oplock_break_ops;
1075extern struct workqueue_struct *cifsiod_wq; 1128extern struct workqueue_struct *cifsiod_wq;
1076 1129
1130/* Operations for different SMB versions */
1131#define SMB1_VERSION_STRING "1.0"
1132extern struct smb_version_operations smb1_operations;
1133extern struct smb_version_values smb1_values;
1134#define SMB21_VERSION_STRING "2.1"
1135extern struct smb_version_operations smb21_operations;
1136extern struct smb_version_values smb21_values;
1077#endif /* _CIFS_GLOB_H */ 1137#endif /* _CIFS_GLOB_H */
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 96192c1e380a..0a6cbfe2761e 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -78,6 +78,8 @@ extern int SendReceive(const unsigned int /* xid */ , struct cifs_ses *,
78 int * /* bytes returned */ , const int long_op); 78 int * /* bytes returned */ , const int long_op);
79extern int SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses, 79extern int SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses,
80 char *in_buf, int flags); 80 char *in_buf, int flags);
81extern int cifs_setup_request(struct cifs_ses *, struct kvec *, unsigned int,
82 struct mid_q_entry **);
81extern int cifs_check_receive(struct mid_q_entry *mid, 83extern int cifs_check_receive(struct mid_q_entry *mid,
82 struct TCP_Server_Info *server, bool log_error); 84 struct TCP_Server_Info *server, bool log_error);
83extern int SendReceive2(const unsigned int /* xid */ , struct cifs_ses *, 85extern int SendReceive2(const unsigned int /* xid */ , struct cifs_ses *,
@@ -88,9 +90,6 @@ extern int SendReceiveBlockingLock(const unsigned int xid,
88 struct smb_hdr *in_buf , 90 struct smb_hdr *in_buf ,
89 struct smb_hdr *out_buf, 91 struct smb_hdr *out_buf,
90 int *bytes_returned); 92 int *bytes_returned);
91extern void cifs_add_credits(struct TCP_Server_Info *server,
92 const unsigned int add);
93extern void cifs_set_credits(struct TCP_Server_Info *server, const int val);
94extern int checkSMB(char *buf, unsigned int length); 93extern int checkSMB(char *buf, unsigned int length);
95extern bool is_valid_oplock_break(char *, struct TCP_Server_Info *); 94extern bool is_valid_oplock_break(char *, struct TCP_Server_Info *);
96extern bool backup_cred(struct cifs_sb_info *); 95extern bool backup_cred(struct cifs_sb_info *);
@@ -115,7 +114,6 @@ extern int small_smb_init_no_tc(const int smb_cmd, const int wct,
115 void **request_buf); 114 void **request_buf);
116extern int CIFS_SessSetup(unsigned int xid, struct cifs_ses *ses, 115extern int CIFS_SessSetup(unsigned int xid, struct cifs_ses *ses,
117 const struct nls_table *nls_cp); 116 const struct nls_table *nls_cp);
118extern __u64 GetNextMid(struct TCP_Server_Info *server);
119extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601); 117extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601);
120extern u64 cifs_UnixTimeToNT(struct timespec); 118extern u64 cifs_UnixTimeToNT(struct timespec);
121extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, 119extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time,
@@ -192,11 +190,13 @@ extern int CIFSTCon(unsigned int xid, struct cifs_ses *ses,
192 190
193extern int CIFSFindFirst(const int xid, struct cifs_tcon *tcon, 191extern int CIFSFindFirst(const int xid, struct cifs_tcon *tcon,
194 const char *searchName, const struct nls_table *nls_codepage, 192 const char *searchName, const struct nls_table *nls_codepage,
195 __u16 *searchHandle, struct cifs_search_info *psrch_inf, 193 __u16 *searchHandle, __u16 search_flags,
194 struct cifs_search_info *psrch_inf,
196 int map, const char dirsep); 195 int map, const char dirsep);
197 196
198extern int CIFSFindNext(const int xid, struct cifs_tcon *tcon, 197extern int CIFSFindNext(const int xid, struct cifs_tcon *tcon,
199 __u16 searchHandle, struct cifs_search_info *psrch_inf); 198 __u16 searchHandle, __u16 search_flags,
199 struct cifs_search_info *psrch_inf);
200 200
201extern int CIFSFindClose(const int, struct cifs_tcon *tcon, 201extern int CIFSFindClose(const int, struct cifs_tcon *tcon,
202 const __u16 search_handle); 202 const __u16 search_handle);
@@ -464,6 +464,9 @@ extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8,
464 464
465/* asynchronous read support */ 465/* asynchronous read support */
466struct cifs_readdata { 466struct cifs_readdata {
467 struct kref refcount;
468 struct list_head list;
469 struct completion done;
467 struct cifsFileInfo *cfile; 470 struct cifsFileInfo *cfile;
468 struct address_space *mapping; 471 struct address_space *mapping;
469 __u64 offset; 472 __u64 offset;
@@ -472,12 +475,13 @@ struct cifs_readdata {
472 int result; 475 int result;
473 struct list_head pages; 476 struct list_head pages;
474 struct work_struct work; 477 struct work_struct work;
478 int (*marshal_iov) (struct cifs_readdata *rdata,
479 unsigned int remaining);
475 unsigned int nr_iov; 480 unsigned int nr_iov;
476 struct kvec iov[1]; 481 struct kvec iov[1];
477}; 482};
478 483
479struct cifs_readdata *cifs_readdata_alloc(unsigned int nr_pages); 484void cifs_readdata_release(struct kref *refcount);
480void cifs_readdata_free(struct cifs_readdata *rdata);
481int cifs_async_readv(struct cifs_readdata *rdata); 485int cifs_async_readv(struct cifs_readdata *rdata);
482 486
483/* asynchronous write support */ 487/* asynchronous write support */
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index da2f5446fa7a..5b400730c213 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -87,7 +87,6 @@ static struct {
87#endif /* CIFS_POSIX */ 87#endif /* CIFS_POSIX */
88 88
89/* Forward declarations */ 89/* Forward declarations */
90static void cifs_readv_complete(struct work_struct *work);
91 90
92/* Mark as invalid, all open files on tree connections since they 91/* Mark as invalid, all open files on tree connections since they
93 were closed when session to server was lost */ 92 were closed when session to server was lost */
@@ -269,7 +268,7 @@ small_smb_init_no_tc(const int smb_command, const int wct,
269 return rc; 268 return rc;
270 269
271 buffer = (struct smb_hdr *)*request_buf; 270 buffer = (struct smb_hdr *)*request_buf;
272 buffer->Mid = GetNextMid(ses->server); 271 buffer->Mid = get_next_mid(ses->server);
273 if (ses->capabilities & CAP_UNICODE) 272 if (ses->capabilities & CAP_UNICODE)
274 buffer->Flags2 |= SMBFLG2_UNICODE; 273 buffer->Flags2 |= SMBFLG2_UNICODE;
275 if (ses->capabilities & CAP_STATUS32) 274 if (ses->capabilities & CAP_STATUS32)
@@ -403,7 +402,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifs_ses *ses)
403 402
404 cFYI(1, "secFlags 0x%x", secFlags); 403 cFYI(1, "secFlags 0x%x", secFlags);
405 404
406 pSMB->hdr.Mid = GetNextMid(server); 405 pSMB->hdr.Mid = get_next_mid(server);
407 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS); 406 pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
408 407
409 if ((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5) 408 if ((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5)
@@ -461,7 +460,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifs_ses *ses)
461 server->maxReq = min_t(unsigned int, 460 server->maxReq = min_t(unsigned int,
462 le16_to_cpu(rsp->MaxMpxCount), 461 le16_to_cpu(rsp->MaxMpxCount),
463 cifs_max_pending); 462 cifs_max_pending);
464 cifs_set_credits(server, server->maxReq); 463 set_credits(server, server->maxReq);
465 server->maxBuf = le16_to_cpu(rsp->MaxBufSize); 464 server->maxBuf = le16_to_cpu(rsp->MaxBufSize);
466 server->max_vcs = le16_to_cpu(rsp->MaxNumberVcs); 465 server->max_vcs = le16_to_cpu(rsp->MaxNumberVcs);
467 /* even though we do not use raw we might as well set this 466 /* even though we do not use raw we might as well set this
@@ -569,7 +568,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifs_ses *ses)
569 little endian */ 568 little endian */
570 server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount), 569 server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
571 cifs_max_pending); 570 cifs_max_pending);
572 cifs_set_credits(server, server->maxReq); 571 set_credits(server, server->maxReq);
573 /* probably no need to store and check maxvcs */ 572 /* probably no need to store and check maxvcs */
574 server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize); 573 server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
575 server->max_rw = le32_to_cpu(pSMBr->MaxRawSize); 574 server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
@@ -721,7 +720,7 @@ cifs_echo_callback(struct mid_q_entry *mid)
721 struct TCP_Server_Info *server = mid->callback_data; 720 struct TCP_Server_Info *server = mid->callback_data;
722 721
723 DeleteMidQEntry(mid); 722 DeleteMidQEntry(mid);
724 cifs_add_credits(server, 1); 723 add_credits(server, 1);
725} 724}
726 725
727int 726int
@@ -783,7 +782,7 @@ CIFSSMBLogoff(const int xid, struct cifs_ses *ses)
783 return rc; 782 return rc;
784 } 783 }
785 784
786 pSMB->hdr.Mid = GetNextMid(ses->server); 785 pSMB->hdr.Mid = get_next_mid(ses->server);
787 786
788 if (ses->server->sec_mode & 787 if (ses->server->sec_mode &
789 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 788 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
@@ -1385,28 +1384,6 @@ openRetry:
1385 return rc; 1384 return rc;
1386} 1385}
1387 1386
1388struct cifs_readdata *
1389cifs_readdata_alloc(unsigned int nr_pages)
1390{
1391 struct cifs_readdata *rdata;
1392
1393 /* readdata + 1 kvec for each page */
1394 rdata = kzalloc(sizeof(*rdata) +
1395 sizeof(struct kvec) * nr_pages, GFP_KERNEL);
1396 if (rdata != NULL) {
1397 INIT_WORK(&rdata->work, cifs_readv_complete);
1398 INIT_LIST_HEAD(&rdata->pages);
1399 }
1400 return rdata;
1401}
1402
1403void
1404cifs_readdata_free(struct cifs_readdata *rdata)
1405{
1406 cifsFileInfo_put(rdata->cfile);
1407 kfree(rdata);
1408}
1409
1410/* 1387/*
1411 * Discard any remaining data in the current SMB. To do this, we borrow the 1388 * Discard any remaining data in the current SMB. To do this, we borrow the
1412 * current bigbuf. 1389 * current bigbuf.
@@ -1423,7 +1400,7 @@ cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1423 1400
1424 length = cifs_read_from_socket(server, server->bigbuf, 1401 length = cifs_read_from_socket(server, server->bigbuf,
1425 min_t(unsigned int, remaining, 1402 min_t(unsigned int, remaining,
1426 CIFSMaxBufSize + max_header_size())); 1403 CIFSMaxBufSize + MAX_HEADER_SIZE(server)));
1427 if (length < 0) 1404 if (length < 0)
1428 return length; 1405 return length;
1429 server->total_read += length; 1406 server->total_read += length;
@@ -1434,38 +1411,14 @@ cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1434 return 0; 1411 return 0;
1435} 1412}
1436 1413
1437static inline size_t
1438read_rsp_size(void)
1439{
1440 return sizeof(READ_RSP);
1441}
1442
1443static inline unsigned int
1444read_data_offset(char *buf)
1445{
1446 READ_RSP *rsp = (READ_RSP *)buf;
1447 return le16_to_cpu(rsp->DataOffset);
1448}
1449
1450static inline unsigned int
1451read_data_length(char *buf)
1452{
1453 READ_RSP *rsp = (READ_RSP *)buf;
1454 return (le16_to_cpu(rsp->DataLengthHigh) << 16) +
1455 le16_to_cpu(rsp->DataLength);
1456}
1457
1458static int 1414static int
1459cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) 1415cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1460{ 1416{
1461 int length, len; 1417 int length, len;
1462 unsigned int data_offset, remaining, data_len; 1418 unsigned int data_offset, data_len;
1463 struct cifs_readdata *rdata = mid->callback_data; 1419 struct cifs_readdata *rdata = mid->callback_data;
1464 char *buf = server->smallbuf; 1420 char *buf = server->smallbuf;
1465 unsigned int buflen = get_rfc1002_length(buf) + 4; 1421 unsigned int buflen = get_rfc1002_length(buf) + 4;
1466 u64 eof;
1467 pgoff_t eof_index;
1468 struct page *page, *tpage;
1469 1422
1470 cFYI(1, "%s: mid=%llu offset=%llu bytes=%u", __func__, 1423 cFYI(1, "%s: mid=%llu offset=%llu bytes=%u", __func__,
1471 mid->mid, rdata->offset, rdata->bytes); 1424 mid->mid, rdata->offset, rdata->bytes);
@@ -1475,9 +1428,10 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1475 * can if there's not enough data. At this point, we've read down to 1428 * can if there's not enough data. At this point, we've read down to
1476 * the Mid. 1429 * the Mid.
1477 */ 1430 */
1478 len = min_t(unsigned int, buflen, read_rsp_size()) - header_size() + 1; 1431 len = min_t(unsigned int, buflen, server->vals->read_rsp_size) -
1432 HEADER_SIZE(server) + 1;
1479 1433
1480 rdata->iov[0].iov_base = buf + header_size() - 1; 1434 rdata->iov[0].iov_base = buf + HEADER_SIZE(server) - 1;
1481 rdata->iov[0].iov_len = len; 1435 rdata->iov[0].iov_len = len;
1482 1436
1483 length = cifs_readv_from_socket(server, rdata->iov, 1, len); 1437 length = cifs_readv_from_socket(server, rdata->iov, 1, len);
@@ -1486,7 +1440,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1486 server->total_read += length; 1440 server->total_read += length;
1487 1441
1488 /* Was the SMB read successful? */ 1442 /* Was the SMB read successful? */
1489 rdata->result = map_smb_to_linux_error(buf, false); 1443 rdata->result = server->ops->map_error(buf, false);
1490 if (rdata->result != 0) { 1444 if (rdata->result != 0) {
1491 cFYI(1, "%s: server returned error %d", __func__, 1445 cFYI(1, "%s: server returned error %d", __func__,
1492 rdata->result); 1446 rdata->result);
@@ -1494,14 +1448,15 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1494 } 1448 }
1495 1449
1496 /* Is there enough to get to the rest of the READ_RSP header? */ 1450 /* Is there enough to get to the rest of the READ_RSP header? */
1497 if (server->total_read < read_rsp_size()) { 1451 if (server->total_read < server->vals->read_rsp_size) {
1498 cFYI(1, "%s: server returned short header. got=%u expected=%zu", 1452 cFYI(1, "%s: server returned short header. got=%u expected=%zu",
1499 __func__, server->total_read, read_rsp_size()); 1453 __func__, server->total_read,
1454 server->vals->read_rsp_size);
1500 rdata->result = -EIO; 1455 rdata->result = -EIO;
1501 return cifs_readv_discard(server, mid); 1456 return cifs_readv_discard(server, mid);
1502 } 1457 }
1503 1458
1504 data_offset = read_data_offset(buf) + 4; 1459 data_offset = server->ops->read_data_offset(buf) + 4;
1505 if (data_offset < server->total_read) { 1460 if (data_offset < server->total_read) {
1506 /* 1461 /*
1507 * win2k8 sometimes sends an offset of 0 when the read 1462 * win2k8 sometimes sends an offset of 0 when the read
@@ -1540,7 +1495,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1540 rdata->iov[0].iov_base, rdata->iov[0].iov_len); 1495 rdata->iov[0].iov_base, rdata->iov[0].iov_len);
1541 1496
1542 /* how much data is in the response? */ 1497 /* how much data is in the response? */
1543 data_len = read_data_length(buf); 1498 data_len = server->ops->read_data_length(buf);
1544 if (data_offset + data_len > buflen) { 1499 if (data_offset + data_len > buflen) {
1545 /* data_len is corrupt -- discard frame */ 1500 /* data_len is corrupt -- discard frame */
1546 rdata->result = -EIO; 1501 rdata->result = -EIO;
@@ -1548,64 +1503,8 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1548 } 1503 }
1549 1504
1550 /* marshal up the page array */ 1505 /* marshal up the page array */
1551 len = 0; 1506 len = rdata->marshal_iov(rdata, data_len);
1552 remaining = data_len; 1507 data_len -= len;
1553 rdata->nr_iov = 1;
1554
1555 /* determine the eof that the server (probably) has */
1556 eof = CIFS_I(rdata->mapping->host)->server_eof;
1557 eof_index = eof ? (eof - 1) >> PAGE_CACHE_SHIFT : 0;
1558 cFYI(1, "eof=%llu eof_index=%lu", eof, eof_index);
1559
1560 list_for_each_entry_safe(page, tpage, &rdata->pages, lru) {
1561 if (remaining >= PAGE_CACHE_SIZE) {
1562 /* enough data to fill the page */
1563 rdata->iov[rdata->nr_iov].iov_base = kmap(page);
1564 rdata->iov[rdata->nr_iov].iov_len = PAGE_CACHE_SIZE;
1565 cFYI(1, "%u: idx=%lu iov_base=%p iov_len=%zu",
1566 rdata->nr_iov, page->index,
1567 rdata->iov[rdata->nr_iov].iov_base,
1568 rdata->iov[rdata->nr_iov].iov_len);
1569 ++rdata->nr_iov;
1570 len += PAGE_CACHE_SIZE;
1571 remaining -= PAGE_CACHE_SIZE;
1572 } else if (remaining > 0) {
1573 /* enough for partial page, fill and zero the rest */
1574 rdata->iov[rdata->nr_iov].iov_base = kmap(page);
1575 rdata->iov[rdata->nr_iov].iov_len = remaining;
1576 cFYI(1, "%u: idx=%lu iov_base=%p iov_len=%zu",
1577 rdata->nr_iov, page->index,
1578 rdata->iov[rdata->nr_iov].iov_base,
1579 rdata->iov[rdata->nr_iov].iov_len);
1580 memset(rdata->iov[rdata->nr_iov].iov_base + remaining,
1581 '\0', PAGE_CACHE_SIZE - remaining);
1582 ++rdata->nr_iov;
1583 len += remaining;
1584 remaining = 0;
1585 } else if (page->index > eof_index) {
1586 /*
1587 * The VFS will not try to do readahead past the
1588 * i_size, but it's possible that we have outstanding
1589 * writes with gaps in the middle and the i_size hasn't
1590 * caught up yet. Populate those with zeroed out pages
1591 * to prevent the VFS from repeatedly attempting to
1592 * fill them until the writes are flushed.
1593 */
1594 zero_user(page, 0, PAGE_CACHE_SIZE);
1595 list_del(&page->lru);
1596 lru_cache_add_file(page);
1597 flush_dcache_page(page);
1598 SetPageUptodate(page);
1599 unlock_page(page);
1600 page_cache_release(page);
1601 } else {
1602 /* no need to hold page hostage */
1603 list_del(&page->lru);
1604 lru_cache_add_file(page);
1605 unlock_page(page);
1606 page_cache_release(page);
1607 }
1608 }
1609 1508
1610 /* issue the read if we have any iovecs left to fill */ 1509 /* issue the read if we have any iovecs left to fill */
1611 if (rdata->nr_iov > 1) { 1510 if (rdata->nr_iov > 1) {
@@ -1621,7 +1520,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1621 rdata->bytes = length; 1520 rdata->bytes = length;
1622 1521
1623 cFYI(1, "total_read=%u buflen=%u remaining=%u", server->total_read, 1522 cFYI(1, "total_read=%u buflen=%u remaining=%u", server->total_read,
1624 buflen, remaining); 1523 buflen, data_len);
1625 1524
1626 /* discard anything left over */ 1525 /* discard anything left over */
1627 if (server->total_read < buflen) 1526 if (server->total_read < buflen)
@@ -1632,33 +1531,6 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
1632} 1531}
1633 1532
1634static void 1533static void
1635cifs_readv_complete(struct work_struct *work)
1636{
1637 struct cifs_readdata *rdata = container_of(work,
1638 struct cifs_readdata, work);
1639 struct page *page, *tpage;
1640
1641 list_for_each_entry_safe(page, tpage, &rdata->pages, lru) {
1642 list_del(&page->lru);
1643 lru_cache_add_file(page);
1644
1645 if (rdata->result == 0) {
1646 kunmap(page);
1647 flush_dcache_page(page);
1648 SetPageUptodate(page);
1649 }
1650
1651 unlock_page(page);
1652
1653 if (rdata->result == 0)
1654 cifs_readpage_to_fscache(rdata->mapping->host, page);
1655
1656 page_cache_release(page);
1657 }
1658 cifs_readdata_free(rdata);
1659}
1660
1661static void
1662cifs_readv_callback(struct mid_q_entry *mid) 1534cifs_readv_callback(struct mid_q_entry *mid)
1663{ 1535{
1664 struct cifs_readdata *rdata = mid->callback_data; 1536 struct cifs_readdata *rdata = mid->callback_data;
@@ -1691,7 +1563,7 @@ cifs_readv_callback(struct mid_q_entry *mid)
1691 1563
1692 queue_work(cifsiod_wq, &rdata->work); 1564 queue_work(cifsiod_wq, &rdata->work);
1693 DeleteMidQEntry(mid); 1565 DeleteMidQEntry(mid);
1694 cifs_add_credits(server, 1); 1566 add_credits(server, 1);
1695} 1567}
1696 1568
1697/* cifs_async_readv - send an async write, and set up mid to handle result */ 1569/* cifs_async_readv - send an async write, and set up mid to handle result */
@@ -1744,12 +1616,15 @@ cifs_async_readv(struct cifs_readdata *rdata)
1744 rdata->iov[0].iov_base = smb; 1616 rdata->iov[0].iov_base = smb;
1745 rdata->iov[0].iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4; 1617 rdata->iov[0].iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4;
1746 1618
1619 kref_get(&rdata->refcount);
1747 rc = cifs_call_async(tcon->ses->server, rdata->iov, 1, 1620 rc = cifs_call_async(tcon->ses->server, rdata->iov, 1,
1748 cifs_readv_receive, cifs_readv_callback, 1621 cifs_readv_receive, cifs_readv_callback,
1749 rdata, false); 1622 rdata, false);
1750 1623
1751 if (rc == 0) 1624 if (rc == 0)
1752 cifs_stats_inc(&tcon->num_reads); 1625 cifs_stats_inc(&tcon->num_reads);
1626 else
1627 kref_put(&rdata->refcount, cifs_readdata_release);
1753 1628
1754 cifs_small_buf_release(smb); 1629 cifs_small_buf_release(smb);
1755 return rc; 1630 return rc;
@@ -2135,7 +2010,7 @@ cifs_writev_callback(struct mid_q_entry *mid)
2135 2010
2136 queue_work(cifsiod_wq, &wdata->work); 2011 queue_work(cifsiod_wq, &wdata->work);
2137 DeleteMidQEntry(mid); 2012 DeleteMidQEntry(mid);
2138 cifs_add_credits(tcon->ses->server, 1); 2013 add_credits(tcon->ses->server, 1);
2139} 2014}
2140 2015
2141/* cifs_async_writev - send an async write, and set up mid to handle result */ 2016/* cifs_async_writev - send an async write, and set up mid to handle result */
@@ -4344,7 +4219,7 @@ int
4344CIFSFindFirst(const int xid, struct cifs_tcon *tcon, 4219CIFSFindFirst(const int xid, struct cifs_tcon *tcon,
4345 const char *searchName, 4220 const char *searchName,
4346 const struct nls_table *nls_codepage, 4221 const struct nls_table *nls_codepage,
4347 __u16 *pnetfid, 4222 __u16 *pnetfid, __u16 search_flags,
4348 struct cifs_search_info *psrch_inf, int remap, const char dirsep) 4223 struct cifs_search_info *psrch_inf, int remap, const char dirsep)
4349{ 4224{
4350/* level 257 SMB_ */ 4225/* level 257 SMB_ */
@@ -4416,8 +4291,7 @@ findFirstRetry:
4416 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | 4291 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
4417 ATTR_DIRECTORY); 4292 ATTR_DIRECTORY);
4418 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO)); 4293 pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
4419 pSMB->SearchFlags = cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END | 4294 pSMB->SearchFlags = cpu_to_le16(search_flags);
4420 CIFS_SEARCH_RETURN_RESUME);
4421 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level); 4295 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4422 4296
4423 /* BB what should we set StorageType to? Does it matter? BB */ 4297 /* BB what should we set StorageType to? Does it matter? BB */
@@ -4487,8 +4361,8 @@ findFirstRetry:
4487 return rc; 4361 return rc;
4488} 4362}
4489 4363
4490int CIFSFindNext(const int xid, struct cifs_tcon *tcon, 4364int CIFSFindNext(const int xid, struct cifs_tcon *tcon, __u16 searchHandle,
4491 __u16 searchHandle, struct cifs_search_info *psrch_inf) 4365 __u16 search_flags, struct cifs_search_info *psrch_inf)
4492{ 4366{
4493 TRANSACTION2_FNEXT_REQ *pSMB = NULL; 4367 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
4494 TRANSACTION2_FNEXT_RSP *pSMBr = NULL; 4368 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
@@ -4531,8 +4405,7 @@ int CIFSFindNext(const int xid, struct cifs_tcon *tcon,
4531 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO)); 4405 cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
4532 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level); 4406 pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
4533 pSMB->ResumeKey = psrch_inf->resume_key; 4407 pSMB->ResumeKey = psrch_inf->resume_key;
4534 pSMB->SearchFlags = 4408 pSMB->SearchFlags = cpu_to_le16(search_flags);
4535 cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME);
4536 4409
4537 name_len = psrch_inf->resume_name_len; 4410 name_len = psrch_inf->resume_name_len;
4538 params += name_len; 4411 params += name_len;
@@ -4889,7 +4762,7 @@ getDFSRetry:
4889 4762
4890 /* server pointer checked in called function, 4763 /* server pointer checked in called function,
4891 but should never be null here anyway */ 4764 but should never be null here anyway */
4892 pSMB->hdr.Mid = GetNextMid(ses->server); 4765 pSMB->hdr.Mid = get_next_mid(ses->server);
4893 pSMB->hdr.Tid = ses->ipc_tid; 4766 pSMB->hdr.Tid = ses->ipc_tid;
4894 pSMB->hdr.Uid = ses->Suid; 4767 pSMB->hdr.Uid = ses->Suid;
4895 if (ses->capabilities & CAP_STATUS32) 4768 if (ses->capabilities & CAP_STATUS32)
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index e0b56d7a19c5..78db68a5cf44 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/connect.c 2 * fs/cifs/connect.c
3 * 3 *
4 * Copyright (C) International Business Machines Corp., 2002,2009 4 * Copyright (C) International Business Machines Corp., 2002,2011
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This library is free software; you can redistribute it and/or modify 7 * This library is free software; you can redistribute it and/or modify
@@ -102,7 +102,7 @@ enum {
102 Opt_srcaddr, Opt_prefixpath, 102 Opt_srcaddr, Opt_prefixpath,
103 Opt_iocharset, Opt_sockopt, 103 Opt_iocharset, Opt_sockopt,
104 Opt_netbiosname, Opt_servern, 104 Opt_netbiosname, Opt_servern,
105 Opt_ver, Opt_sec, 105 Opt_ver, Opt_vers, Opt_sec, Opt_cache,
106 106
107 /* Mount options to be ignored */ 107 /* Mount options to be ignored */
108 Opt_ignore, 108 Opt_ignore,
@@ -210,9 +210,9 @@ static const match_table_t cifs_mount_option_tokens = {
210 { Opt_netbiosname, "netbiosname=%s" }, 210 { Opt_netbiosname, "netbiosname=%s" },
211 { Opt_servern, "servern=%s" }, 211 { Opt_servern, "servern=%s" },
212 { Opt_ver, "ver=%s" }, 212 { Opt_ver, "ver=%s" },
213 { Opt_ver, "vers=%s" }, 213 { Opt_vers, "vers=%s" },
214 { Opt_ver, "version=%s" },
215 { Opt_sec, "sec=%s" }, 214 { Opt_sec, "sec=%s" },
215 { Opt_cache, "cache=%s" },
216 216
217 { Opt_ignore, "cred" }, 217 { Opt_ignore, "cred" },
218 { Opt_ignore, "credentials" }, 218 { Opt_ignore, "credentials" },
@@ -261,6 +261,26 @@ static const match_table_t cifs_secflavor_tokens = {
261 { Opt_sec_err, NULL } 261 { Opt_sec_err, NULL }
262}; 262};
263 263
264/* cache flavors */
265enum {
266 Opt_cache_loose,
267 Opt_cache_strict,
268 Opt_cache_none,
269 Opt_cache_err
270};
271
272static const match_table_t cifs_cacheflavor_tokens = {
273 { Opt_cache_loose, "loose" },
274 { Opt_cache_strict, "strict" },
275 { Opt_cache_none, "none" },
276 { Opt_cache_err, NULL }
277};
278
279static const match_table_t cifs_smb_version_tokens = {
280 { Smb_1, SMB1_VERSION_STRING },
281 { Smb_21, SMB21_VERSION_STRING },
282};
283
264static int ip_connect(struct TCP_Server_Info *server); 284static int ip_connect(struct TCP_Server_Info *server);
265static int generic_ip_connect(struct TCP_Server_Info *server); 285static int generic_ip_connect(struct TCP_Server_Info *server);
266static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink); 286static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink);
@@ -549,7 +569,7 @@ allocate_buffers(struct TCP_Server_Info *server)
549 } 569 }
550 } else if (server->large_buf) { 570 } else if (server->large_buf) {
551 /* we are reusing a dirty large buf, clear its start */ 571 /* we are reusing a dirty large buf, clear its start */
552 memset(server->bigbuf, 0, header_size()); 572 memset(server->bigbuf, 0, HEADER_SIZE(server));
553 } 573 }
554 574
555 if (!server->smallbuf) { 575 if (!server->smallbuf) {
@@ -563,7 +583,7 @@ allocate_buffers(struct TCP_Server_Info *server)
563 /* beginning of smb buffer is cleared in our buf_get */ 583 /* beginning of smb buffer is cleared in our buf_get */
564 } else { 584 } else {
565 /* if existing small buf clear beginning */ 585 /* if existing small buf clear beginning */
566 memset(server->smallbuf, 0, header_size()); 586 memset(server->smallbuf, 0, HEADER_SIZE(server));
567 } 587 }
568 588
569 return true; 589 return true;
@@ -764,25 +784,6 @@ is_smb_response(struct TCP_Server_Info *server, unsigned char type)
764 return false; 784 return false;
765} 785}
766 786
767static struct mid_q_entry *
768find_mid(struct TCP_Server_Info *server, char *buffer)
769{
770 struct smb_hdr *buf = (struct smb_hdr *)buffer;
771 struct mid_q_entry *mid;
772
773 spin_lock(&GlobalMid_Lock);
774 list_for_each_entry(mid, &server->pending_mid_q, qhead) {
775 if (mid->mid == buf->Mid &&
776 mid->mid_state == MID_REQUEST_SUBMITTED &&
777 le16_to_cpu(mid->command) == buf->Command) {
778 spin_unlock(&GlobalMid_Lock);
779 return mid;
780 }
781 }
782 spin_unlock(&GlobalMid_Lock);
783 return NULL;
784}
785
786void 787void
787dequeue_mid(struct mid_q_entry *mid, bool malformed) 788dequeue_mid(struct mid_q_entry *mid, bool malformed)
788{ 789{
@@ -934,7 +935,7 @@ standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid)
934 unsigned int pdu_length = get_rfc1002_length(buf); 935 unsigned int pdu_length = get_rfc1002_length(buf);
935 936
936 /* make sure this will fit in a large buffer */ 937 /* make sure this will fit in a large buffer */
937 if (pdu_length > CIFSMaxBufSize + max_header_size() - 4) { 938 if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE(server) - 4) {
938 cERROR(1, "SMB response too long (%u bytes)", 939 cERROR(1, "SMB response too long (%u bytes)",
939 pdu_length); 940 pdu_length);
940 cifs_reconnect(server); 941 cifs_reconnect(server);
@@ -950,8 +951,8 @@ standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid)
950 } 951 }
951 952
952 /* now read the rest */ 953 /* now read the rest */
953 length = cifs_read_from_socket(server, buf + header_size() - 1, 954 length = cifs_read_from_socket(server, buf + HEADER_SIZE(server) - 1,
954 pdu_length - header_size() + 1 + 4); 955 pdu_length - HEADER_SIZE(server) + 1 + 4);
955 if (length < 0) 956 if (length < 0)
956 return length; 957 return length;
957 server->total_read += length; 958 server->total_read += length;
@@ -967,7 +968,7 @@ standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid)
967 * 48 bytes is enough to display the header and a little bit 968 * 48 bytes is enough to display the header and a little bit
968 * into the payload for debugging purposes. 969 * into the payload for debugging purposes.
969 */ 970 */
970 length = checkSMB(buf, server->total_read); 971 length = server->ops->check_message(buf, server->total_read);
971 if (length != 0) 972 if (length != 0)
972 cifs_dump_mem("Bad SMB: ", buf, 973 cifs_dump_mem("Bad SMB: ", buf,
973 min_t(unsigned int, server->total_read, 48)); 974 min_t(unsigned int, server->total_read, 48));
@@ -1025,7 +1026,7 @@ cifs_demultiplex_thread(void *p)
1025 continue; 1026 continue;
1026 1027
1027 /* make sure we have enough to get to the MID */ 1028 /* make sure we have enough to get to the MID */
1028 if (pdu_length < header_size() - 1 - 4) { 1029 if (pdu_length < HEADER_SIZE(server) - 1 - 4) {
1029 cERROR(1, "SMB response too short (%u bytes)", 1030 cERROR(1, "SMB response too short (%u bytes)",
1030 pdu_length); 1031 pdu_length);
1031 cifs_reconnect(server); 1032 cifs_reconnect(server);
@@ -1035,12 +1036,12 @@ cifs_demultiplex_thread(void *p)
1035 1036
1036 /* read down to the MID */ 1037 /* read down to the MID */
1037 length = cifs_read_from_socket(server, buf + 4, 1038 length = cifs_read_from_socket(server, buf + 4,
1038 header_size() - 1 - 4); 1039 HEADER_SIZE(server) - 1 - 4);
1039 if (length < 0) 1040 if (length < 0)
1040 continue; 1041 continue;
1041 server->total_read += length; 1042 server->total_read += length;
1042 1043
1043 mid_entry = find_mid(server, buf); 1044 mid_entry = server->ops->find_mid(server, buf);
1044 1045
1045 if (!mid_entry || !mid_entry->receive) 1046 if (!mid_entry || !mid_entry->receive)
1046 length = standard_receive3(server, mid_entry); 1047 length = standard_receive3(server, mid_entry);
@@ -1057,12 +1058,15 @@ cifs_demultiplex_thread(void *p)
1057 if (mid_entry != NULL) { 1058 if (mid_entry != NULL) {
1058 if (!mid_entry->multiRsp || mid_entry->multiEnd) 1059 if (!mid_entry->multiRsp || mid_entry->multiEnd)
1059 mid_entry->callback(mid_entry); 1060 mid_entry->callback(mid_entry);
1060 } else if (!is_valid_oplock_break(buf, server)) { 1061 } else if (!server->ops->is_oplock_break ||
1062 !server->ops->is_oplock_break(buf, server)) {
1061 cERROR(1, "No task to wake, unknown frame received! " 1063 cERROR(1, "No task to wake, unknown frame received! "
1062 "NumMids %d", atomic_read(&midCount)); 1064 "NumMids %d", atomic_read(&midCount));
1063 cifs_dump_mem("Received Data is: ", buf, header_size()); 1065 cifs_dump_mem("Received Data is: ", buf,
1066 HEADER_SIZE(server));
1064#ifdef CONFIG_CIFS_DEBUG2 1067#ifdef CONFIG_CIFS_DEBUG2
1065 cifs_dump_detail(buf); 1068 if (server->ops->dump_detail)
1069 server->ops->dump_detail(buf);
1066 cifs_dump_mids(server); 1070 cifs_dump_mids(server);
1067#endif /* CIFS_DEBUG2 */ 1071#endif /* CIFS_DEBUG2 */
1068 1072
@@ -1186,6 +1190,54 @@ static int cifs_parse_security_flavors(char *value,
1186} 1190}
1187 1191
1188static int 1192static int
1193cifs_parse_cache_flavor(char *value, struct smb_vol *vol)
1194{
1195 substring_t args[MAX_OPT_ARGS];
1196
1197 switch (match_token(value, cifs_cacheflavor_tokens, args)) {
1198 case Opt_cache_loose:
1199 vol->direct_io = false;
1200 vol->strict_io = false;
1201 break;
1202 case Opt_cache_strict:
1203 vol->direct_io = false;
1204 vol->strict_io = true;
1205 break;
1206 case Opt_cache_none:
1207 vol->direct_io = true;
1208 vol->strict_io = false;
1209 break;
1210 default:
1211 cERROR(1, "bad cache= option: %s", value);
1212 return 1;
1213 }
1214 return 0;
1215}
1216
1217static int
1218cifs_parse_smb_version(char *value, struct smb_vol *vol)
1219{
1220 substring_t args[MAX_OPT_ARGS];
1221
1222 switch (match_token(value, cifs_smb_version_tokens, args)) {
1223 case Smb_1:
1224 vol->ops = &smb1_operations;
1225 vol->vals = &smb1_values;
1226 break;
1227#ifdef CONFIG_CIFS_SMB2
1228 case Smb_21:
1229 vol->ops = &smb21_operations;
1230 vol->vals = &smb21_values;
1231 break;
1232#endif
1233 default:
1234 cERROR(1, "Unknown vers= option specified: %s", value);
1235 return 1;
1236 }
1237 return 0;
1238}
1239
1240static int
1189cifs_parse_mount_options(const char *mountdata, const char *devname, 1241cifs_parse_mount_options(const char *mountdata, const char *devname,
1190 struct smb_vol *vol) 1242 struct smb_vol *vol)
1191{ 1243{
@@ -1203,6 +1255,8 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1203 char *string = NULL; 1255 char *string = NULL;
1204 char *tmp_end, *value; 1256 char *tmp_end, *value;
1205 char delim; 1257 char delim;
1258 bool cache_specified = false;
1259 static bool cache_warned = false;
1206 1260
1207 separator[0] = ','; 1261 separator[0] = ',';
1208 separator[1] = 0; 1262 separator[1] = 0;
@@ -1236,6 +1290,10 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1236 1290
1237 vol->actimeo = CIFS_DEF_ACTIMEO; 1291 vol->actimeo = CIFS_DEF_ACTIMEO;
1238 1292
1293 /* FIXME: add autonegotiation -- for now, SMB1 is default */
1294 vol->ops = &smb1_operations;
1295 vol->vals = &smb1_values;
1296
1239 if (!mountdata) 1297 if (!mountdata)
1240 goto cifs_parse_mount_err; 1298 goto cifs_parse_mount_err;
1241 1299
@@ -1414,10 +1472,20 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1414 vol->seal = 1; 1472 vol->seal = 1;
1415 break; 1473 break;
1416 case Opt_direct: 1474 case Opt_direct:
1417 vol->direct_io = 1; 1475 cache_specified = true;
1476 vol->direct_io = true;
1477 vol->strict_io = false;
1478 cERROR(1, "The \"directio\" option will be removed in "
1479 "3.7. Please switch to the \"cache=none\" "
1480 "option.");
1418 break; 1481 break;
1419 case Opt_strictcache: 1482 case Opt_strictcache:
1420 vol->strict_io = 1; 1483 cache_specified = true;
1484 vol->direct_io = false;
1485 vol->strict_io = true;
1486 cERROR(1, "The \"strictcache\" option will be removed "
1487 "in 3.7. Please switch to the \"cache=strict\" "
1488 "option.");
1421 break; 1489 break;
1422 case Opt_noac: 1490 case Opt_noac:
1423 printk(KERN_WARNING "CIFS: Mount option noac not " 1491 printk(KERN_WARNING "CIFS: Mount option noac not "
@@ -1821,8 +1889,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1821 if (string == NULL) 1889 if (string == NULL)
1822 goto out_nomem; 1890 goto out_nomem;
1823 1891
1824 if (strnicmp(string, "cifs", 4) == 0 || 1892 if (strnicmp(string, "1", 1) == 0) {
1825 strnicmp(string, "1", 1) == 0) {
1826 /* This is the default */ 1893 /* This is the default */
1827 break; 1894 break;
1828 } 1895 }
@@ -1830,6 +1897,14 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1830 printk(KERN_WARNING "CIFS: Invalid version" 1897 printk(KERN_WARNING "CIFS: Invalid version"
1831 " specified\n"); 1898 " specified\n");
1832 goto cifs_parse_mount_err; 1899 goto cifs_parse_mount_err;
1900 case Opt_vers:
1901 string = match_strdup(args);
1902 if (string == NULL)
1903 goto out_nomem;
1904
1905 if (cifs_parse_smb_version(string, vol) != 0)
1906 goto cifs_parse_mount_err;
1907 break;
1833 case Opt_sec: 1908 case Opt_sec:
1834 string = match_strdup(args); 1909 string = match_strdup(args);
1835 if (string == NULL) 1910 if (string == NULL)
@@ -1838,6 +1913,15 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1838 if (cifs_parse_security_flavors(string, vol) != 0) 1913 if (cifs_parse_security_flavors(string, vol) != 0)
1839 goto cifs_parse_mount_err; 1914 goto cifs_parse_mount_err;
1840 break; 1915 break;
1916 case Opt_cache:
1917 cache_specified = true;
1918 string = match_strdup(args);
1919 if (string == NULL)
1920 goto out_nomem;
1921
1922 if (cifs_parse_cache_flavor(string, vol) != 0)
1923 goto cifs_parse_mount_err;
1924 break;
1841 default: 1925 default:
1842 /* 1926 /*
1843 * An option we don't recognize. Save it off for later 1927 * An option we don't recognize. Save it off for later
@@ -1881,6 +1965,14 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1881 printk(KERN_NOTICE "CIFS: ignoring forcegid mount option " 1965 printk(KERN_NOTICE "CIFS: ignoring forcegid mount option "
1882 "specified with no gid= option.\n"); 1966 "specified with no gid= option.\n");
1883 1967
1968 /* FIXME: remove this block in 3.7 */
1969 if (!cache_specified && !cache_warned) {
1970 cache_warned = true;
1971 printk(KERN_NOTICE "CIFS: no cache= option specified, using "
1972 "\"cache=loose\". This default will change "
1973 "to \"cache=strict\" in 3.7.\n");
1974 }
1975
1884 kfree(mountdata_copy); 1976 kfree(mountdata_copy);
1885 return 0; 1977 return 0;
1886 1978
@@ -2041,6 +2133,9 @@ match_security(struct TCP_Server_Info *server, struct smb_vol *vol)
2041static int match_server(struct TCP_Server_Info *server, struct sockaddr *addr, 2133static int match_server(struct TCP_Server_Info *server, struct sockaddr *addr,
2042 struct smb_vol *vol) 2134 struct smb_vol *vol)
2043{ 2135{
2136 if ((server->vals != vol->vals) || (server->ops != vol->ops))
2137 return 0;
2138
2044 if (!net_eq(cifs_net_ns(server), current->nsproxy->net_ns)) 2139 if (!net_eq(cifs_net_ns(server), current->nsproxy->net_ns))
2045 return 0; 2140 return 0;
2046 2141
@@ -2163,6 +2258,8 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
2163 goto out_err; 2258 goto out_err;
2164 } 2259 }
2165 2260
2261 tcp_ses->ops = volume_info->ops;
2262 tcp_ses->vals = volume_info->vals;
2166 cifs_set_net_ns(tcp_ses, get_net(current->nsproxy->net_ns)); 2263 cifs_set_net_ns(tcp_ses, get_net(current->nsproxy->net_ns));
2167 tcp_ses->hostname = extract_hostname(volume_info->UNC); 2264 tcp_ses->hostname = extract_hostname(volume_info->UNC);
2168 if (IS_ERR(tcp_ses->hostname)) { 2265 if (IS_ERR(tcp_ses->hostname)) {
@@ -3569,6 +3666,7 @@ cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data,
3569 if (cifs_parse_mount_options(mount_data, devname, volume_info)) 3666 if (cifs_parse_mount_options(mount_data, devname, volume_info))
3570 return -EINVAL; 3667 return -EINVAL;
3571 3668
3669
3572 if (volume_info->nullauth) { 3670 if (volume_info->nullauth) {
3573 cFYI(1, "Anonymous login"); 3671 cFYI(1, "Anonymous login");
3574 kfree(volume_info->username); 3672 kfree(volume_info->username);
@@ -3842,7 +3940,7 @@ CIFSTCon(unsigned int xid, struct cifs_ses *ses,
3842 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX, 3940 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
3843 NULL /*no tid */ , 4 /*wct */ ); 3941 NULL /*no tid */ , 4 /*wct */ );
3844 3942
3845 smb_buffer->Mid = GetNextMid(ses->server); 3943 smb_buffer->Mid = get_next_mid(ses->server);
3846 smb_buffer->Uid = ses->Suid; 3944 smb_buffer->Uid = ses->Suid;
3847 pSMB = (TCONX_REQ *) smb_buffer; 3945 pSMB = (TCONX_REQ *) smb_buffer;
3848 pSMBr = (TCONX_RSP *) smb_buffer_response; 3946 pSMBr = (TCONX_RSP *) smb_buffer_response;
@@ -4010,11 +4108,11 @@ int cifs_negotiate_protocol(unsigned int xid, struct cifs_ses *ses)
4010 if (server->maxBuf != 0) 4108 if (server->maxBuf != 0)
4011 return 0; 4109 return 0;
4012 4110
4013 cifs_set_credits(server, 1); 4111 set_credits(server, 1);
4014 rc = CIFSSMBNegotiate(xid, ses); 4112 rc = CIFSSMBNegotiate(xid, ses);
4015 if (rc == -EAGAIN) { 4113 if (rc == -EAGAIN) {
4016 /* retry only once on 1st time connection */ 4114 /* retry only once on 1st time connection */
4017 cifs_set_credits(server, 1); 4115 set_credits(server, 1);
4018 rc = CIFSSMBNegotiate(xid, ses); 4116 rc = CIFSSMBNegotiate(xid, ses);
4019 if (rc == -EAGAIN) 4117 if (rc == -EAGAIN)
4020 rc = -EHOSTDOWN; 4118 rc = -EHOSTDOWN;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 81725e9286e9..513adbc211d7 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -264,6 +264,7 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file,
264 pCifsFile->tlink = cifs_get_tlink(tlink); 264 pCifsFile->tlink = cifs_get_tlink(tlink);
265 mutex_init(&pCifsFile->fh_mutex); 265 mutex_init(&pCifsFile->fh_mutex);
266 INIT_WORK(&pCifsFile->oplock_break, cifs_oplock_break); 266 INIT_WORK(&pCifsFile->oplock_break, cifs_oplock_break);
267 INIT_LIST_HEAD(&pCifsFile->llist);
267 268
268 spin_lock(&cifs_file_list_lock); 269 spin_lock(&cifs_file_list_lock);
269 list_add(&pCifsFile->tlist, &(tlink_tcon(tlink)->openFileList)); 270 list_add(&pCifsFile->tlist, &(tlink_tcon(tlink)->openFileList));
@@ -334,9 +335,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
334 * is closed anyway. 335 * is closed anyway.
335 */ 336 */
336 mutex_lock(&cifsi->lock_mutex); 337 mutex_lock(&cifsi->lock_mutex);
337 list_for_each_entry_safe(li, tmp, &cifsi->llist, llist) { 338 list_for_each_entry_safe(li, tmp, &cifs_file->llist, llist) {
338 if (li->netfid != cifs_file->netfid)
339 continue;
340 list_del(&li->llist); 339 list_del(&li->llist);
341 cifs_del_lock_waiters(li); 340 cifs_del_lock_waiters(li);
342 kfree(li); 341 kfree(li);
@@ -645,7 +644,7 @@ int cifs_closedir(struct inode *inode, struct file *file)
645} 644}
646 645
647static struct cifsLockInfo * 646static struct cifsLockInfo *
648cifs_lock_init(__u64 offset, __u64 length, __u8 type, __u16 netfid) 647cifs_lock_init(__u64 offset, __u64 length, __u8 type)
649{ 648{
650 struct cifsLockInfo *lock = 649 struct cifsLockInfo *lock =
651 kmalloc(sizeof(struct cifsLockInfo), GFP_KERNEL); 650 kmalloc(sizeof(struct cifsLockInfo), GFP_KERNEL);
@@ -654,7 +653,6 @@ cifs_lock_init(__u64 offset, __u64 length, __u8 type, __u16 netfid)
654 lock->offset = offset; 653 lock->offset = offset;
655 lock->length = length; 654 lock->length = length;
656 lock->type = type; 655 lock->type = type;
657 lock->netfid = netfid;
658 lock->pid = current->tgid; 656 lock->pid = current->tgid;
659 INIT_LIST_HEAD(&lock->blist); 657 INIT_LIST_HEAD(&lock->blist);
660 init_waitqueue_head(&lock->block_q); 658 init_waitqueue_head(&lock->block_q);
@@ -672,19 +670,20 @@ cifs_del_lock_waiters(struct cifsLockInfo *lock)
672} 670}
673 671
674static bool 672static bool
675__cifs_find_lock_conflict(struct cifsInodeInfo *cinode, __u64 offset, 673cifs_find_fid_lock_conflict(struct cifsFileInfo *cfile, __u64 offset,
676 __u64 length, __u8 type, __u16 netfid, 674 __u64 length, __u8 type, struct cifsFileInfo *cur,
677 struct cifsLockInfo **conf_lock) 675 struct cifsLockInfo **conf_lock)
678{ 676{
679 struct cifsLockInfo *li, *tmp; 677 struct cifsLockInfo *li;
678 struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server;
680 679
681 list_for_each_entry_safe(li, tmp, &cinode->llist, llist) { 680 list_for_each_entry(li, &cfile->llist, llist) {
682 if (offset + length <= li->offset || 681 if (offset + length <= li->offset ||
683 offset >= li->offset + li->length) 682 offset >= li->offset + li->length)
684 continue; 683 continue;
685 else if ((type & LOCKING_ANDX_SHARED_LOCK) && 684 else if ((type & server->vals->shared_lock_type) &&
686 ((netfid == li->netfid && current->tgid == li->pid) || 685 ((server->ops->compare_fids(cur, cfile) &&
687 type == li->type)) 686 current->tgid == li->pid) || type == li->type))
688 continue; 687 continue;
689 else { 688 else {
690 *conf_lock = li; 689 *conf_lock = li;
@@ -695,11 +694,23 @@ __cifs_find_lock_conflict(struct cifsInodeInfo *cinode, __u64 offset,
695} 694}
696 695
697static bool 696static bool
698cifs_find_lock_conflict(struct cifsInodeInfo *cinode, struct cifsLockInfo *lock, 697cifs_find_lock_conflict(struct cifsFileInfo *cfile, __u64 offset, __u64 length,
699 struct cifsLockInfo **conf_lock) 698 __u8 type, struct cifsLockInfo **conf_lock)
700{ 699{
701 return __cifs_find_lock_conflict(cinode, lock->offset, lock->length, 700 bool rc = false;
702 lock->type, lock->netfid, conf_lock); 701 struct cifsFileInfo *fid, *tmp;
702 struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
703
704 spin_lock(&cifs_file_list_lock);
705 list_for_each_entry_safe(fid, tmp, &cinode->openFileList, flist) {
706 rc = cifs_find_fid_lock_conflict(fid, offset, length, type,
707 cfile, conf_lock);
708 if (rc)
709 break;
710 }
711 spin_unlock(&cifs_file_list_lock);
712
713 return rc;
703} 714}
704 715
705/* 716/*
@@ -710,22 +721,24 @@ cifs_find_lock_conflict(struct cifsInodeInfo *cinode, struct cifsLockInfo *lock,
710 * the server or 1 otherwise. 721 * the server or 1 otherwise.
711 */ 722 */
712static int 723static int
713cifs_lock_test(struct cifsInodeInfo *cinode, __u64 offset, __u64 length, 724cifs_lock_test(struct cifsFileInfo *cfile, __u64 offset, __u64 length,
714 __u8 type, __u16 netfid, struct file_lock *flock) 725 __u8 type, struct file_lock *flock)
715{ 726{
716 int rc = 0; 727 int rc = 0;
717 struct cifsLockInfo *conf_lock; 728 struct cifsLockInfo *conf_lock;
729 struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
730 struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server;
718 bool exist; 731 bool exist;
719 732
720 mutex_lock(&cinode->lock_mutex); 733 mutex_lock(&cinode->lock_mutex);
721 734
722 exist = __cifs_find_lock_conflict(cinode, offset, length, type, netfid, 735 exist = cifs_find_lock_conflict(cfile, offset, length, type,
723 &conf_lock); 736 &conf_lock);
724 if (exist) { 737 if (exist) {
725 flock->fl_start = conf_lock->offset; 738 flock->fl_start = conf_lock->offset;
726 flock->fl_end = conf_lock->offset + conf_lock->length - 1; 739 flock->fl_end = conf_lock->offset + conf_lock->length - 1;
727 flock->fl_pid = conf_lock->pid; 740 flock->fl_pid = conf_lock->pid;
728 if (conf_lock->type & LOCKING_ANDX_SHARED_LOCK) 741 if (conf_lock->type & server->vals->shared_lock_type)
729 flock->fl_type = F_RDLCK; 742 flock->fl_type = F_RDLCK;
730 else 743 else
731 flock->fl_type = F_WRLCK; 744 flock->fl_type = F_WRLCK;
@@ -739,10 +752,11 @@ cifs_lock_test(struct cifsInodeInfo *cinode, __u64 offset, __u64 length,
739} 752}
740 753
741static void 754static void
742cifs_lock_add(struct cifsInodeInfo *cinode, struct cifsLockInfo *lock) 755cifs_lock_add(struct cifsFileInfo *cfile, struct cifsLockInfo *lock)
743{ 756{
757 struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
744 mutex_lock(&cinode->lock_mutex); 758 mutex_lock(&cinode->lock_mutex);
745 list_add_tail(&lock->llist, &cinode->llist); 759 list_add_tail(&lock->llist, &cfile->llist);
746 mutex_unlock(&cinode->lock_mutex); 760 mutex_unlock(&cinode->lock_mutex);
747} 761}
748 762
@@ -753,10 +767,11 @@ cifs_lock_add(struct cifsInodeInfo *cinode, struct cifsLockInfo *lock)
753 * 3) -EACCESS, if there is a lock that prevents us and wait is false. 767 * 3) -EACCESS, if there is a lock that prevents us and wait is false.
754 */ 768 */
755static int 769static int
756cifs_lock_add_if(struct cifsInodeInfo *cinode, struct cifsLockInfo *lock, 770cifs_lock_add_if(struct cifsFileInfo *cfile, struct cifsLockInfo *lock,
757 bool wait) 771 bool wait)
758{ 772{
759 struct cifsLockInfo *conf_lock; 773 struct cifsLockInfo *conf_lock;
774 struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
760 bool exist; 775 bool exist;
761 int rc = 0; 776 int rc = 0;
762 777
@@ -764,9 +779,10 @@ try_again:
764 exist = false; 779 exist = false;
765 mutex_lock(&cinode->lock_mutex); 780 mutex_lock(&cinode->lock_mutex);
766 781
767 exist = cifs_find_lock_conflict(cinode, lock, &conf_lock); 782 exist = cifs_find_lock_conflict(cfile, lock->offset, lock->length,
783 lock->type, &conf_lock);
768 if (!exist && cinode->can_cache_brlcks) { 784 if (!exist && cinode->can_cache_brlcks) {
769 list_add_tail(&lock->llist, &cinode->llist); 785 list_add_tail(&lock->llist, &cfile->llist);
770 mutex_unlock(&cinode->lock_mutex); 786 mutex_unlock(&cinode->lock_mutex);
771 return rc; 787 return rc;
772 } 788 }
@@ -860,7 +876,7 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile)
860 struct cifsLockInfo *li, *tmp; 876 struct cifsLockInfo *li, *tmp;
861 struct cifs_tcon *tcon; 877 struct cifs_tcon *tcon;
862 struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode); 878 struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
863 unsigned int num, max_num; 879 unsigned int num, max_num, max_buf;
864 LOCKING_ANDX_RANGE *buf, *cur; 880 LOCKING_ANDX_RANGE *buf, *cur;
865 int types[] = {LOCKING_ANDX_LARGE_FILES, 881 int types[] = {LOCKING_ANDX_LARGE_FILES,
866 LOCKING_ANDX_SHARED_LOCK | LOCKING_ANDX_LARGE_FILES}; 882 LOCKING_ANDX_SHARED_LOCK | LOCKING_ANDX_LARGE_FILES};
@@ -876,8 +892,19 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile)
876 return rc; 892 return rc;
877 } 893 }
878 894
879 max_num = (tcon->ses->server->maxBuf - sizeof(struct smb_hdr)) / 895 /*
880 sizeof(LOCKING_ANDX_RANGE); 896 * Accessing maxBuf is racy with cifs_reconnect - need to store value
897 * and check it for zero before using.
898 */
899 max_buf = tcon->ses->server->maxBuf;
900 if (!max_buf) {
901 mutex_unlock(&cinode->lock_mutex);
902 FreeXid(xid);
903 return -EINVAL;
904 }
905
906 max_num = (max_buf - sizeof(struct smb_hdr)) /
907 sizeof(LOCKING_ANDX_RANGE);
881 buf = kzalloc(max_num * sizeof(LOCKING_ANDX_RANGE), GFP_KERNEL); 908 buf = kzalloc(max_num * sizeof(LOCKING_ANDX_RANGE), GFP_KERNEL);
882 if (!buf) { 909 if (!buf) {
883 mutex_unlock(&cinode->lock_mutex); 910 mutex_unlock(&cinode->lock_mutex);
@@ -888,7 +915,7 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile)
888 for (i = 0; i < 2; i++) { 915 for (i = 0; i < 2; i++) {
889 cur = buf; 916 cur = buf;
890 num = 0; 917 num = 0;
891 list_for_each_entry_safe(li, tmp, &cinode->llist, llist) { 918 list_for_each_entry_safe(li, tmp, &cfile->llist, llist) {
892 if (li->type != types[i]) 919 if (li->type != types[i])
893 continue; 920 continue;
894 cur->Pid = cpu_to_le16(li->pid); 921 cur->Pid = cpu_to_le16(li->pid);
@@ -898,7 +925,8 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile)
898 cur->OffsetHigh = cpu_to_le32((u32)(li->offset>>32)); 925 cur->OffsetHigh = cpu_to_le32((u32)(li->offset>>32));
899 if (++num == max_num) { 926 if (++num == max_num) {
900 stored_rc = cifs_lockv(xid, tcon, cfile->netfid, 927 stored_rc = cifs_lockv(xid, tcon, cfile->netfid,
901 li->type, 0, num, buf); 928 (__u8)li->type, 0, num,
929 buf);
902 if (stored_rc) 930 if (stored_rc)
903 rc = stored_rc; 931 rc = stored_rc;
904 cur = buf; 932 cur = buf;
@@ -909,7 +937,7 @@ cifs_push_mandatory_locks(struct cifsFileInfo *cfile)
909 937
910 if (num) { 938 if (num) {
911 stored_rc = cifs_lockv(xid, tcon, cfile->netfid, 939 stored_rc = cifs_lockv(xid, tcon, cfile->netfid,
912 types[i], 0, num, buf); 940 (__u8)types[i], 0, num, buf);
913 if (stored_rc) 941 if (stored_rc)
914 rc = stored_rc; 942 rc = stored_rc;
915 } 943 }
@@ -1053,8 +1081,8 @@ cifs_push_locks(struct cifsFileInfo *cfile)
1053} 1081}
1054 1082
1055static void 1083static void
1056cifs_read_flock(struct file_lock *flock, __u8 *type, int *lock, int *unlock, 1084cifs_read_flock(struct file_lock *flock, __u32 *type, int *lock, int *unlock,
1057 bool *wait_flag) 1085 bool *wait_flag, struct TCP_Server_Info *server)
1058{ 1086{
1059 if (flock->fl_flags & FL_POSIX) 1087 if (flock->fl_flags & FL_POSIX)
1060 cFYI(1, "Posix"); 1088 cFYI(1, "Posix");
@@ -1073,38 +1101,50 @@ cifs_read_flock(struct file_lock *flock, __u8 *type, int *lock, int *unlock,
1073 (~(FL_POSIX | FL_FLOCK | FL_SLEEP | FL_ACCESS | FL_LEASE))) 1101 (~(FL_POSIX | FL_FLOCK | FL_SLEEP | FL_ACCESS | FL_LEASE)))
1074 cFYI(1, "Unknown lock flags 0x%x", flock->fl_flags); 1102 cFYI(1, "Unknown lock flags 0x%x", flock->fl_flags);
1075 1103
1076 *type = LOCKING_ANDX_LARGE_FILES; 1104 *type = server->vals->large_lock_type;
1077 if (flock->fl_type == F_WRLCK) { 1105 if (flock->fl_type == F_WRLCK) {
1078 cFYI(1, "F_WRLCK "); 1106 cFYI(1, "F_WRLCK ");
1107 *type |= server->vals->exclusive_lock_type;
1079 *lock = 1; 1108 *lock = 1;
1080 } else if (flock->fl_type == F_UNLCK) { 1109 } else if (flock->fl_type == F_UNLCK) {
1081 cFYI(1, "F_UNLCK"); 1110 cFYI(1, "F_UNLCK");
1111 *type |= server->vals->unlock_lock_type;
1082 *unlock = 1; 1112 *unlock = 1;
1083 /* Check if unlock includes more than one lock range */ 1113 /* Check if unlock includes more than one lock range */
1084 } else if (flock->fl_type == F_RDLCK) { 1114 } else if (flock->fl_type == F_RDLCK) {
1085 cFYI(1, "F_RDLCK"); 1115 cFYI(1, "F_RDLCK");
1086 *type |= LOCKING_ANDX_SHARED_LOCK; 1116 *type |= server->vals->shared_lock_type;
1087 *lock = 1; 1117 *lock = 1;
1088 } else if (flock->fl_type == F_EXLCK) { 1118 } else if (flock->fl_type == F_EXLCK) {
1089 cFYI(1, "F_EXLCK"); 1119 cFYI(1, "F_EXLCK");
1120 *type |= server->vals->exclusive_lock_type;
1090 *lock = 1; 1121 *lock = 1;
1091 } else if (flock->fl_type == F_SHLCK) { 1122 } else if (flock->fl_type == F_SHLCK) {
1092 cFYI(1, "F_SHLCK"); 1123 cFYI(1, "F_SHLCK");
1093 *type |= LOCKING_ANDX_SHARED_LOCK; 1124 *type |= server->vals->shared_lock_type;
1094 *lock = 1; 1125 *lock = 1;
1095 } else 1126 } else
1096 cFYI(1, "Unknown type of lock"); 1127 cFYI(1, "Unknown type of lock");
1097} 1128}
1098 1129
1099static int 1130static int
1100cifs_getlk(struct file *file, struct file_lock *flock, __u8 type, 1131cifs_mandatory_lock(int xid, struct cifsFileInfo *cfile, __u64 offset,
1132 __u64 length, __u32 type, int lock, int unlock, bool wait)
1133{
1134 return CIFSSMBLock(xid, tlink_tcon(cfile->tlink), cfile->netfid,
1135 current->tgid, length, offset, unlock, lock,
1136 (__u8)type, wait, 0);
1137}
1138
1139static int
1140cifs_getlk(struct file *file, struct file_lock *flock, __u32 type,
1101 bool wait_flag, bool posix_lck, int xid) 1141 bool wait_flag, bool posix_lck, int xid)
1102{ 1142{
1103 int rc = 0; 1143 int rc = 0;
1104 __u64 length = 1 + flock->fl_end - flock->fl_start; 1144 __u64 length = 1 + flock->fl_end - flock->fl_start;
1105 struct cifsFileInfo *cfile = (struct cifsFileInfo *)file->private_data; 1145 struct cifsFileInfo *cfile = (struct cifsFileInfo *)file->private_data;
1106 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); 1146 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
1107 struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode); 1147 struct TCP_Server_Info *server = tcon->ses->server;
1108 __u16 netfid = cfile->netfid; 1148 __u16 netfid = cfile->netfid;
1109 1149
1110 if (posix_lck) { 1150 if (posix_lck) {
@@ -1114,7 +1154,7 @@ cifs_getlk(struct file *file, struct file_lock *flock, __u8 type,
1114 if (!rc) 1154 if (!rc)
1115 return rc; 1155 return rc;
1116 1156
1117 if (type & LOCKING_ANDX_SHARED_LOCK) 1157 if (type & server->vals->shared_lock_type)
1118 posix_lock_type = CIFS_RDLCK; 1158 posix_lock_type = CIFS_RDLCK;
1119 else 1159 else
1120 posix_lock_type = CIFS_WRLCK; 1160 posix_lock_type = CIFS_WRLCK;
@@ -1124,38 +1164,35 @@ cifs_getlk(struct file *file, struct file_lock *flock, __u8 type,
1124 return rc; 1164 return rc;
1125 } 1165 }
1126 1166
1127 rc = cifs_lock_test(cinode, flock->fl_start, length, type, netfid, 1167 rc = cifs_lock_test(cfile, flock->fl_start, length, type, flock);
1128 flock);
1129 if (!rc) 1168 if (!rc)
1130 return rc; 1169 return rc;
1131 1170
1132 /* BB we could chain these into one lock request BB */ 1171 /* BB we could chain these into one lock request BB */
1133 rc = CIFSSMBLock(xid, tcon, netfid, current->tgid, length, 1172 rc = cifs_mandatory_lock(xid, cfile, flock->fl_start, length, type,
1134 flock->fl_start, 0, 1, type, 0, 0); 1173 1, 0, false);
1135 if (rc == 0) { 1174 if (rc == 0) {
1136 rc = CIFSSMBLock(xid, tcon, netfid, current->tgid, 1175 rc = cifs_mandatory_lock(xid, cfile, flock->fl_start, length,
1137 length, flock->fl_start, 1, 0, 1176 type, 0, 1, false);
1138 type, 0, 0);
1139 flock->fl_type = F_UNLCK; 1177 flock->fl_type = F_UNLCK;
1140 if (rc != 0) 1178 if (rc != 0)
1141 cERROR(1, "Error unlocking previously locked " 1179 cERROR(1, "Error unlocking previously locked "
1142 "range %d during test of lock", rc); 1180 "range %d during test of lock", rc);
1143 return 0; 1181 return 0;
1144 } 1182 }
1145 1183
1146 if (type & LOCKING_ANDX_SHARED_LOCK) { 1184 if (type & server->vals->shared_lock_type) {
1147 flock->fl_type = F_WRLCK; 1185 flock->fl_type = F_WRLCK;
1148 return 0; 1186 return 0;
1149 } 1187 }
1150 1188
1151 rc = CIFSSMBLock(xid, tcon, netfid, current->tgid, length, 1189 rc = cifs_mandatory_lock(xid, cfile, flock->fl_start, length,
1152 flock->fl_start, 0, 1, 1190 type | server->vals->shared_lock_type, 1, 0,
1153 type | LOCKING_ANDX_SHARED_LOCK, 0, 0); 1191 false);
1154 if (rc == 0) { 1192 if (rc == 0) {
1155 rc = CIFSSMBLock(xid, tcon, netfid, current->tgid, 1193 rc = cifs_mandatory_lock(xid, cfile, flock->fl_start, length,
1156 length, flock->fl_start, 1, 0, 1194 type | server->vals->shared_lock_type,
1157 type | LOCKING_ANDX_SHARED_LOCK, 1195 0, 1, false);
1158 0, 0);
1159 flock->fl_type = F_RDLCK; 1196 flock->fl_type = F_RDLCK;
1160 if (rc != 0) 1197 if (rc != 0)
1161 cERROR(1, "Error unlocking previously locked " 1198 cERROR(1, "Error unlocking previously locked "
@@ -1192,7 +1229,7 @@ cifs_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock, int xid)
1192 int types[] = {LOCKING_ANDX_LARGE_FILES, 1229 int types[] = {LOCKING_ANDX_LARGE_FILES,
1193 LOCKING_ANDX_SHARED_LOCK | LOCKING_ANDX_LARGE_FILES}; 1230 LOCKING_ANDX_SHARED_LOCK | LOCKING_ANDX_LARGE_FILES};
1194 unsigned int i; 1231 unsigned int i;
1195 unsigned int max_num, num; 1232 unsigned int max_num, num, max_buf;
1196 LOCKING_ANDX_RANGE *buf, *cur; 1233 LOCKING_ANDX_RANGE *buf, *cur;
1197 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); 1234 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
1198 struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode); 1235 struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
@@ -1202,8 +1239,16 @@ cifs_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock, int xid)
1202 1239
1203 INIT_LIST_HEAD(&tmp_llist); 1240 INIT_LIST_HEAD(&tmp_llist);
1204 1241
1205 max_num = (tcon->ses->server->maxBuf - sizeof(struct smb_hdr)) / 1242 /*
1206 sizeof(LOCKING_ANDX_RANGE); 1243 * Accessing maxBuf is racy with cifs_reconnect - need to store value
1244 * and check it for zero before using.
1245 */
1246 max_buf = tcon->ses->server->maxBuf;
1247 if (!max_buf)
1248 return -EINVAL;
1249
1250 max_num = (max_buf - sizeof(struct smb_hdr)) /
1251 sizeof(LOCKING_ANDX_RANGE);
1207 buf = kzalloc(max_num * sizeof(LOCKING_ANDX_RANGE), GFP_KERNEL); 1252 buf = kzalloc(max_num * sizeof(LOCKING_ANDX_RANGE), GFP_KERNEL);
1208 if (!buf) 1253 if (!buf)
1209 return -ENOMEM; 1254 return -ENOMEM;
@@ -1212,71 +1257,64 @@ cifs_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock, int xid)
1212 for (i = 0; i < 2; i++) { 1257 for (i = 0; i < 2; i++) {
1213 cur = buf; 1258 cur = buf;
1214 num = 0; 1259 num = 0;
1215 list_for_each_entry_safe(li, tmp, &cinode->llist, llist) { 1260 list_for_each_entry_safe(li, tmp, &cfile->llist, llist) {
1216 if (flock->fl_start > li->offset || 1261 if (flock->fl_start > li->offset ||
1217 (flock->fl_start + length) < 1262 (flock->fl_start + length) <
1218 (li->offset + li->length)) 1263 (li->offset + li->length))
1219 continue; 1264 continue;
1220 if (current->tgid != li->pid) 1265 if (current->tgid != li->pid)
1221 continue; 1266 continue;
1222 if (cfile->netfid != li->netfid)
1223 continue;
1224 if (types[i] != li->type) 1267 if (types[i] != li->type)
1225 continue; 1268 continue;
1226 if (!cinode->can_cache_brlcks) { 1269 if (cinode->can_cache_brlcks) {
1227 cur->Pid = cpu_to_le16(li->pid);
1228 cur->LengthLow = cpu_to_le32((u32)li->length);
1229 cur->LengthHigh =
1230 cpu_to_le32((u32)(li->length>>32));
1231 cur->OffsetLow = cpu_to_le32((u32)li->offset);
1232 cur->OffsetHigh =
1233 cpu_to_le32((u32)(li->offset>>32));
1234 /*
1235 * We need to save a lock here to let us add
1236 * it again to the inode list if the unlock
1237 * range request fails on the server.
1238 */
1239 list_move(&li->llist, &tmp_llist);
1240 if (++num == max_num) {
1241 stored_rc = cifs_lockv(xid, tcon,
1242 cfile->netfid,
1243 li->type, num,
1244 0, buf);
1245 if (stored_rc) {
1246 /*
1247 * We failed on the unlock range
1248 * request - add all locks from
1249 * the tmp list to the head of
1250 * the inode list.
1251 */
1252 cifs_move_llist(&tmp_llist,
1253 &cinode->llist);
1254 rc = stored_rc;
1255 } else
1256 /*
1257 * The unlock range request
1258 * succeed - free the tmp list.
1259 */
1260 cifs_free_llist(&tmp_llist);
1261 cur = buf;
1262 num = 0;
1263 } else
1264 cur++;
1265 } else {
1266 /* 1270 /*
1267 * We can cache brlock requests - simply remove 1271 * We can cache brlock requests - simply remove
1268 * a lock from the inode list. 1272 * a lock from the file's list.
1269 */ 1273 */
1270 list_del(&li->llist); 1274 list_del(&li->llist);
1271 cifs_del_lock_waiters(li); 1275 cifs_del_lock_waiters(li);
1272 kfree(li); 1276 kfree(li);
1277 continue;
1273 } 1278 }
1279 cur->Pid = cpu_to_le16(li->pid);
1280 cur->LengthLow = cpu_to_le32((u32)li->length);
1281 cur->LengthHigh = cpu_to_le32((u32)(li->length>>32));
1282 cur->OffsetLow = cpu_to_le32((u32)li->offset);
1283 cur->OffsetHigh = cpu_to_le32((u32)(li->offset>>32));
1284 /*
1285 * We need to save a lock here to let us add it again to
1286 * the file's list if the unlock range request fails on
1287 * the server.
1288 */
1289 list_move(&li->llist, &tmp_llist);
1290 if (++num == max_num) {
1291 stored_rc = cifs_lockv(xid, tcon, cfile->netfid,
1292 li->type, num, 0, buf);
1293 if (stored_rc) {
1294 /*
1295 * We failed on the unlock range
1296 * request - add all locks from the tmp
1297 * list to the head of the file's list.
1298 */
1299 cifs_move_llist(&tmp_llist,
1300 &cfile->llist);
1301 rc = stored_rc;
1302 } else
1303 /*
1304 * The unlock range request succeed -
1305 * free the tmp list.
1306 */
1307 cifs_free_llist(&tmp_llist);
1308 cur = buf;
1309 num = 0;
1310 } else
1311 cur++;
1274 } 1312 }
1275 if (num) { 1313 if (num) {
1276 stored_rc = cifs_lockv(xid, tcon, cfile->netfid, 1314 stored_rc = cifs_lockv(xid, tcon, cfile->netfid,
1277 types[i], num, 0, buf); 1315 types[i], num, 0, buf);
1278 if (stored_rc) { 1316 if (stored_rc) {
1279 cifs_move_llist(&tmp_llist, &cinode->llist); 1317 cifs_move_llist(&tmp_llist, &cfile->llist);
1280 rc = stored_rc; 1318 rc = stored_rc;
1281 } else 1319 } else
1282 cifs_free_llist(&tmp_llist); 1320 cifs_free_llist(&tmp_llist);
@@ -1289,14 +1327,14 @@ cifs_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock, int xid)
1289} 1327}
1290 1328
1291static int 1329static int
1292cifs_setlk(struct file *file, struct file_lock *flock, __u8 type, 1330cifs_setlk(struct file *file, struct file_lock *flock, __u32 type,
1293 bool wait_flag, bool posix_lck, int lock, int unlock, int xid) 1331 bool wait_flag, bool posix_lck, int lock, int unlock, int xid)
1294{ 1332{
1295 int rc = 0; 1333 int rc = 0;
1296 __u64 length = 1 + flock->fl_end - flock->fl_start; 1334 __u64 length = 1 + flock->fl_end - flock->fl_start;
1297 struct cifsFileInfo *cfile = (struct cifsFileInfo *)file->private_data; 1335 struct cifsFileInfo *cfile = (struct cifsFileInfo *)file->private_data;
1298 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); 1336 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
1299 struct cifsInodeInfo *cinode = CIFS_I(file->f_path.dentry->d_inode); 1337 struct TCP_Server_Info *server = tcon->ses->server;
1300 __u16 netfid = cfile->netfid; 1338 __u16 netfid = cfile->netfid;
1301 1339
1302 if (posix_lck) { 1340 if (posix_lck) {
@@ -1306,7 +1344,7 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u8 type,
1306 if (!rc || rc < 0) 1344 if (!rc || rc < 0)
1307 return rc; 1345 return rc;
1308 1346
1309 if (type & LOCKING_ANDX_SHARED_LOCK) 1347 if (type & server->vals->shared_lock_type)
1310 posix_lock_type = CIFS_RDLCK; 1348 posix_lock_type = CIFS_RDLCK;
1311 else 1349 else
1312 posix_lock_type = CIFS_WRLCK; 1350 posix_lock_type = CIFS_WRLCK;
@@ -1323,24 +1361,24 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u8 type,
1323 if (lock) { 1361 if (lock) {
1324 struct cifsLockInfo *lock; 1362 struct cifsLockInfo *lock;
1325 1363
1326 lock = cifs_lock_init(flock->fl_start, length, type, netfid); 1364 lock = cifs_lock_init(flock->fl_start, length, type);
1327 if (!lock) 1365 if (!lock)
1328 return -ENOMEM; 1366 return -ENOMEM;
1329 1367
1330 rc = cifs_lock_add_if(cinode, lock, wait_flag); 1368 rc = cifs_lock_add_if(cfile, lock, wait_flag);
1331 if (rc < 0) 1369 if (rc < 0)
1332 kfree(lock); 1370 kfree(lock);
1333 if (rc <= 0) 1371 if (rc <= 0)
1334 goto out; 1372 goto out;
1335 1373
1336 rc = CIFSSMBLock(xid, tcon, netfid, current->tgid, length, 1374 rc = cifs_mandatory_lock(xid, cfile, flock->fl_start, length,
1337 flock->fl_start, 0, 1, type, wait_flag, 0); 1375 type, 1, 0, wait_flag);
1338 if (rc) { 1376 if (rc) {
1339 kfree(lock); 1377 kfree(lock);
1340 goto out; 1378 goto out;
1341 } 1379 }
1342 1380
1343 cifs_lock_add(cinode, lock); 1381 cifs_lock_add(cfile, lock);
1344 } else if (unlock) 1382 } else if (unlock)
1345 rc = cifs_unlock_range(cfile, flock, xid); 1383 rc = cifs_unlock_range(cfile, flock, xid);
1346 1384
@@ -1361,7 +1399,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *flock)
1361 struct cifsInodeInfo *cinode; 1399 struct cifsInodeInfo *cinode;
1362 struct cifsFileInfo *cfile; 1400 struct cifsFileInfo *cfile;
1363 __u16 netfid; 1401 __u16 netfid;
1364 __u8 type; 1402 __u32 type;
1365 1403
1366 rc = -EACCES; 1404 rc = -EACCES;
1367 xid = GetXid(); 1405 xid = GetXid();
@@ -1370,11 +1408,13 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *flock)
1370 "end: %lld", cmd, flock->fl_flags, flock->fl_type, 1408 "end: %lld", cmd, flock->fl_flags, flock->fl_type,
1371 flock->fl_start, flock->fl_end); 1409 flock->fl_start, flock->fl_end);
1372 1410
1373 cifs_read_flock(flock, &type, &lock, &unlock, &wait_flag);
1374
1375 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
1376 cfile = (struct cifsFileInfo *)file->private_data; 1411 cfile = (struct cifsFileInfo *)file->private_data;
1377 tcon = tlink_tcon(cfile->tlink); 1412 tcon = tlink_tcon(cfile->tlink);
1413
1414 cifs_read_flock(flock, &type, &lock, &unlock, &wait_flag,
1415 tcon->ses->server);
1416
1417 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
1378 netfid = cfile->netfid; 1418 netfid = cfile->netfid;
1379 cinode = CIFS_I(file->f_path.dentry->d_inode); 1419 cinode = CIFS_I(file->f_path.dentry->d_inode);
1380 1420
@@ -1539,10 +1579,11 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
1539struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, 1579struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode,
1540 bool fsuid_only) 1580 bool fsuid_only)
1541{ 1581{
1542 struct cifsFileInfo *open_file; 1582 struct cifsFileInfo *open_file, *inv_file = NULL;
1543 struct cifs_sb_info *cifs_sb; 1583 struct cifs_sb_info *cifs_sb;
1544 bool any_available = false; 1584 bool any_available = false;
1545 int rc; 1585 int rc;
1586 unsigned int refind = 0;
1546 1587
1547 /* Having a null inode here (because mapping->host was set to zero by 1588 /* Having a null inode here (because mapping->host was set to zero by
1548 the VFS or MM) should not happen but we had reports of on oops (due to 1589 the VFS or MM) should not happen but we had reports of on oops (due to
@@ -1562,40 +1603,25 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode,
1562 1603
1563 spin_lock(&cifs_file_list_lock); 1604 spin_lock(&cifs_file_list_lock);
1564refind_writable: 1605refind_writable:
1606 if (refind > MAX_REOPEN_ATT) {
1607 spin_unlock(&cifs_file_list_lock);
1608 return NULL;
1609 }
1565 list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { 1610 list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
1566 if (!any_available && open_file->pid != current->tgid) 1611 if (!any_available && open_file->pid != current->tgid)
1567 continue; 1612 continue;
1568 if (fsuid_only && open_file->uid != current_fsuid()) 1613 if (fsuid_only && open_file->uid != current_fsuid())
1569 continue; 1614 continue;
1570 if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) { 1615 if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) {
1571 cifsFileInfo_get(open_file);
1572
1573 if (!open_file->invalidHandle) { 1616 if (!open_file->invalidHandle) {
1574 /* found a good writable file */ 1617 /* found a good writable file */
1618 cifsFileInfo_get(open_file);
1575 spin_unlock(&cifs_file_list_lock); 1619 spin_unlock(&cifs_file_list_lock);
1576 return open_file; 1620 return open_file;
1621 } else {
1622 if (!inv_file)
1623 inv_file = open_file;
1577 } 1624 }
1578
1579 spin_unlock(&cifs_file_list_lock);
1580
1581 /* Had to unlock since following call can block */
1582 rc = cifs_reopen_file(open_file, false);
1583 if (!rc)
1584 return open_file;
1585
1586 /* if it fails, try another handle if possible */
1587 cFYI(1, "wp failed on reopen file");
1588 cifsFileInfo_put(open_file);
1589
1590 spin_lock(&cifs_file_list_lock);
1591
1592 /* else we simply continue to the next entry. Thus
1593 we do not loop on reopen errors. If we
1594 can not reopen the file, for example if we
1595 reconnected to a server with another client
1596 racing to delete or lock the file we would not
1597 make progress if we restarted before the beginning
1598 of the loop here. */
1599 } 1625 }
1600 } 1626 }
1601 /* couldn't find useable FH with same pid, try any available */ 1627 /* couldn't find useable FH with same pid, try any available */
@@ -1603,7 +1629,30 @@ refind_writable:
1603 any_available = true; 1629 any_available = true;
1604 goto refind_writable; 1630 goto refind_writable;
1605 } 1631 }
1632
1633 if (inv_file) {
1634 any_available = false;
1635 cifsFileInfo_get(inv_file);
1636 }
1637
1606 spin_unlock(&cifs_file_list_lock); 1638 spin_unlock(&cifs_file_list_lock);
1639
1640 if (inv_file) {
1641 rc = cifs_reopen_file(inv_file, false);
1642 if (!rc)
1643 return inv_file;
1644 else {
1645 spin_lock(&cifs_file_list_lock);
1646 list_move_tail(&inv_file->flist,
1647 &cifs_inode->openFileList);
1648 spin_unlock(&cifs_file_list_lock);
1649 cifsFileInfo_put(inv_file);
1650 spin_lock(&cifs_file_list_lock);
1651 ++refind;
1652 goto refind_writable;
1653 }
1654 }
1655
1607 return NULL; 1656 return NULL;
1608} 1657}
1609 1658
@@ -2339,24 +2388,224 @@ ssize_t cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov,
2339 return cifs_user_writev(iocb, iov, nr_segs, pos); 2388 return cifs_user_writev(iocb, iov, nr_segs, pos);
2340} 2389}
2341 2390
2391static struct cifs_readdata *
2392cifs_readdata_alloc(unsigned int nr_vecs, work_func_t complete)
2393{
2394 struct cifs_readdata *rdata;
2395
2396 rdata = kzalloc(sizeof(*rdata) +
2397 sizeof(struct kvec) * nr_vecs, GFP_KERNEL);
2398 if (rdata != NULL) {
2399 kref_init(&rdata->refcount);
2400 INIT_LIST_HEAD(&rdata->list);
2401 init_completion(&rdata->done);
2402 INIT_WORK(&rdata->work, complete);
2403 INIT_LIST_HEAD(&rdata->pages);
2404 }
2405 return rdata;
2406}
2407
2408void
2409cifs_readdata_release(struct kref *refcount)
2410{
2411 struct cifs_readdata *rdata = container_of(refcount,
2412 struct cifs_readdata, refcount);
2413
2414 if (rdata->cfile)
2415 cifsFileInfo_put(rdata->cfile);
2416
2417 kfree(rdata);
2418}
2419
2420static int
2421cifs_read_allocate_pages(struct list_head *list, unsigned int npages)
2422{
2423 int rc = 0;
2424 struct page *page, *tpage;
2425 unsigned int i;
2426
2427 for (i = 0; i < npages; i++) {
2428 page = alloc_page(GFP_KERNEL|__GFP_HIGHMEM);
2429 if (!page) {
2430 rc = -ENOMEM;
2431 break;
2432 }
2433 list_add(&page->lru, list);
2434 }
2435
2436 if (rc) {
2437 list_for_each_entry_safe(page, tpage, list, lru) {
2438 list_del(&page->lru);
2439 put_page(page);
2440 }
2441 }
2442 return rc;
2443}
2444
2445static void
2446cifs_uncached_readdata_release(struct kref *refcount)
2447{
2448 struct page *page, *tpage;
2449 struct cifs_readdata *rdata = container_of(refcount,
2450 struct cifs_readdata, refcount);
2451
2452 list_for_each_entry_safe(page, tpage, &rdata->pages, lru) {
2453 list_del(&page->lru);
2454 put_page(page);
2455 }
2456 cifs_readdata_release(refcount);
2457}
2458
2459static int
2460cifs_retry_async_readv(struct cifs_readdata *rdata)
2461{
2462 int rc;
2463
2464 do {
2465 if (rdata->cfile->invalidHandle) {
2466 rc = cifs_reopen_file(rdata->cfile, true);
2467 if (rc != 0)
2468 continue;
2469 }
2470 rc = cifs_async_readv(rdata);
2471 } while (rc == -EAGAIN);
2472
2473 return rc;
2474}
2475
2476/**
2477 * cifs_readdata_to_iov - copy data from pages in response to an iovec
2478 * @rdata: the readdata response with list of pages holding data
2479 * @iov: vector in which we should copy the data
2480 * @nr_segs: number of segments in vector
2481 * @offset: offset into file of the first iovec
2482 * @copied: used to return the amount of data copied to the iov
2483 *
2484 * This function copies data from a list of pages in a readdata response into
2485 * an array of iovecs. It will first calculate where the data should go
2486 * based on the info in the readdata and then copy the data into that spot.
2487 */
2488static ssize_t
2489cifs_readdata_to_iov(struct cifs_readdata *rdata, const struct iovec *iov,
2490 unsigned long nr_segs, loff_t offset, ssize_t *copied)
2491{
2492 int rc = 0;
2493 struct iov_iter ii;
2494 size_t pos = rdata->offset - offset;
2495 struct page *page, *tpage;
2496 ssize_t remaining = rdata->bytes;
2497 unsigned char *pdata;
2498
2499 /* set up iov_iter and advance to the correct offset */
2500 iov_iter_init(&ii, iov, nr_segs, iov_length(iov, nr_segs), 0);
2501 iov_iter_advance(&ii, pos);
2502
2503 *copied = 0;
2504 list_for_each_entry_safe(page, tpage, &rdata->pages, lru) {
2505 ssize_t copy;
2506
2507 /* copy a whole page or whatever's left */
2508 copy = min_t(ssize_t, remaining, PAGE_SIZE);
2509
2510 /* ...but limit it to whatever space is left in the iov */
2511 copy = min_t(ssize_t, copy, iov_iter_count(&ii));
2512
2513 /* go while there's data to be copied and no errors */
2514 if (copy && !rc) {
2515 pdata = kmap(page);
2516 rc = memcpy_toiovecend(ii.iov, pdata, ii.iov_offset,
2517 (int)copy);
2518 kunmap(page);
2519 if (!rc) {
2520 *copied += copy;
2521 remaining -= copy;
2522 iov_iter_advance(&ii, copy);
2523 }
2524 }
2525
2526 list_del(&page->lru);
2527 put_page(page);
2528 }
2529
2530 return rc;
2531}
2532
2533static void
2534cifs_uncached_readv_complete(struct work_struct *work)
2535{
2536 struct cifs_readdata *rdata = container_of(work,
2537 struct cifs_readdata, work);
2538
2539 /* if the result is non-zero then the pages weren't kmapped */
2540 if (rdata->result == 0) {
2541 struct page *page;
2542
2543 list_for_each_entry(page, &rdata->pages, lru)
2544 kunmap(page);
2545 }
2546
2547 complete(&rdata->done);
2548 kref_put(&rdata->refcount, cifs_uncached_readdata_release);
2549}
2550
2551static int
2552cifs_uncached_read_marshal_iov(struct cifs_readdata *rdata,
2553 unsigned int remaining)
2554{
2555 int len = 0;
2556 struct page *page, *tpage;
2557
2558 rdata->nr_iov = 1;
2559 list_for_each_entry_safe(page, tpage, &rdata->pages, lru) {
2560 if (remaining >= PAGE_SIZE) {
2561 /* enough data to fill the page */
2562 rdata->iov[rdata->nr_iov].iov_base = kmap(page);
2563 rdata->iov[rdata->nr_iov].iov_len = PAGE_SIZE;
2564 cFYI(1, "%u: idx=%lu iov_base=%p iov_len=%zu",
2565 rdata->nr_iov, page->index,
2566 rdata->iov[rdata->nr_iov].iov_base,
2567 rdata->iov[rdata->nr_iov].iov_len);
2568 ++rdata->nr_iov;
2569 len += PAGE_SIZE;
2570 remaining -= PAGE_SIZE;
2571 } else if (remaining > 0) {
2572 /* enough for partial page, fill and zero the rest */
2573 rdata->iov[rdata->nr_iov].iov_base = kmap(page);
2574 rdata->iov[rdata->nr_iov].iov_len = remaining;
2575 cFYI(1, "%u: idx=%lu iov_base=%p iov_len=%zu",
2576 rdata->nr_iov, page->index,
2577 rdata->iov[rdata->nr_iov].iov_base,
2578 rdata->iov[rdata->nr_iov].iov_len);
2579 memset(rdata->iov[rdata->nr_iov].iov_base + remaining,
2580 '\0', PAGE_SIZE - remaining);
2581 ++rdata->nr_iov;
2582 len += remaining;
2583 remaining = 0;
2584 } else {
2585 /* no need to hold page hostage */
2586 list_del(&page->lru);
2587 put_page(page);
2588 }
2589 }
2590
2591 return len;
2592}
2593
2342static ssize_t 2594static ssize_t
2343cifs_iovec_read(struct file *file, const struct iovec *iov, 2595cifs_iovec_read(struct file *file, const struct iovec *iov,
2344 unsigned long nr_segs, loff_t *poffset) 2596 unsigned long nr_segs, loff_t *poffset)
2345{ 2597{
2346 int rc; 2598 ssize_t rc;
2347 int xid;
2348 ssize_t total_read;
2349 unsigned int bytes_read = 0;
2350 size_t len, cur_len; 2599 size_t len, cur_len;
2351 int iov_offset = 0; 2600 ssize_t total_read = 0;
2601 loff_t offset = *poffset;
2602 unsigned int npages;
2352 struct cifs_sb_info *cifs_sb; 2603 struct cifs_sb_info *cifs_sb;
2353 struct cifs_tcon *pTcon; 2604 struct cifs_tcon *tcon;
2354 struct cifsFileInfo *open_file; 2605 struct cifsFileInfo *open_file;
2355 struct smb_com_read_rsp *pSMBr; 2606 struct cifs_readdata *rdata, *tmp;
2356 struct cifs_io_parms io_parms; 2607 struct list_head rdata_list;
2357 char *read_data; 2608 pid_t pid;
2358 unsigned int rsize;
2359 __u32 pid;
2360 2609
2361 if (!nr_segs) 2610 if (!nr_segs)
2362 return 0; 2611 return 0;
@@ -2365,14 +2614,10 @@ cifs_iovec_read(struct file *file, const struct iovec *iov,
2365 if (!len) 2614 if (!len)
2366 return 0; 2615 return 0;
2367 2616
2368 xid = GetXid(); 2617 INIT_LIST_HEAD(&rdata_list);
2369 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 2618 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
2370
2371 /* FIXME: set up handlers for larger reads and/or convert to async */
2372 rsize = min_t(unsigned int, cifs_sb->rsize, CIFSMaxBufSize);
2373
2374 open_file = file->private_data; 2619 open_file = file->private_data;
2375 pTcon = tlink_tcon(open_file->tlink); 2620 tcon = tlink_tcon(open_file->tlink);
2376 2621
2377 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD) 2622 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
2378 pid = open_file->pid; 2623 pid = open_file->pid;
@@ -2382,56 +2627,78 @@ cifs_iovec_read(struct file *file, const struct iovec *iov,
2382 if ((file->f_flags & O_ACCMODE) == O_WRONLY) 2627 if ((file->f_flags & O_ACCMODE) == O_WRONLY)
2383 cFYI(1, "attempting read on write only file instance"); 2628 cFYI(1, "attempting read on write only file instance");
2384 2629
2385 for (total_read = 0; total_read < len; total_read += bytes_read) { 2630 do {
2386 cur_len = min_t(const size_t, len - total_read, rsize); 2631 cur_len = min_t(const size_t, len - total_read, cifs_sb->rsize);
2387 rc = -EAGAIN; 2632 npages = DIV_ROUND_UP(cur_len, PAGE_SIZE);
2388 read_data = NULL;
2389 2633
2390 while (rc == -EAGAIN) { 2634 /* allocate a readdata struct */
2391 int buf_type = CIFS_NO_BUFFER; 2635 rdata = cifs_readdata_alloc(npages,
2392 if (open_file->invalidHandle) { 2636 cifs_uncached_readv_complete);
2393 rc = cifs_reopen_file(open_file, true); 2637 if (!rdata) {
2394 if (rc != 0) 2638 rc = -ENOMEM;
2395 break; 2639 goto error;
2396 }
2397 io_parms.netfid = open_file->netfid;
2398 io_parms.pid = pid;
2399 io_parms.tcon = pTcon;
2400 io_parms.offset = *poffset;
2401 io_parms.length = cur_len;
2402 rc = CIFSSMBRead(xid, &io_parms, &bytes_read,
2403 &read_data, &buf_type);
2404 pSMBr = (struct smb_com_read_rsp *)read_data;
2405 if (read_data) {
2406 char *data_offset = read_data + 4 +
2407 le16_to_cpu(pSMBr->DataOffset);
2408 if (memcpy_toiovecend(iov, data_offset,
2409 iov_offset, bytes_read))
2410 rc = -EFAULT;
2411 if (buf_type == CIFS_SMALL_BUFFER)
2412 cifs_small_buf_release(read_data);
2413 else if (buf_type == CIFS_LARGE_BUFFER)
2414 cifs_buf_release(read_data);
2415 read_data = NULL;
2416 iov_offset += bytes_read;
2417 }
2418 } 2640 }
2419 2641
2420 if (rc || (bytes_read == 0)) { 2642 rc = cifs_read_allocate_pages(&rdata->pages, npages);
2421 if (total_read) { 2643 if (rc)
2422 break; 2644 goto error;
2423 } else { 2645
2424 FreeXid(xid); 2646 rdata->cfile = cifsFileInfo_get(open_file);
2425 return rc; 2647 rdata->offset = offset;
2648 rdata->bytes = cur_len;
2649 rdata->pid = pid;
2650 rdata->marshal_iov = cifs_uncached_read_marshal_iov;
2651
2652 rc = cifs_retry_async_readv(rdata);
2653error:
2654 if (rc) {
2655 kref_put(&rdata->refcount,
2656 cifs_uncached_readdata_release);
2657 break;
2658 }
2659
2660 list_add_tail(&rdata->list, &rdata_list);
2661 offset += cur_len;
2662 len -= cur_len;
2663 } while (len > 0);
2664
2665 /* if at least one read request send succeeded, then reset rc */
2666 if (!list_empty(&rdata_list))
2667 rc = 0;
2668
2669 /* the loop below should proceed in the order of increasing offsets */
2670restart_loop:
2671 list_for_each_entry_safe(rdata, tmp, &rdata_list, list) {
2672 if (!rc) {
2673 ssize_t copied;
2674
2675 /* FIXME: freezable sleep too? */
2676 rc = wait_for_completion_killable(&rdata->done);
2677 if (rc)
2678 rc = -EINTR;
2679 else if (rdata->result)
2680 rc = rdata->result;
2681 else {
2682 rc = cifs_readdata_to_iov(rdata, iov,
2683 nr_segs, *poffset,
2684 &copied);
2685 total_read += copied;
2686 }
2687
2688 /* resend call if it's a retryable error */
2689 if (rc == -EAGAIN) {
2690 rc = cifs_retry_async_readv(rdata);
2691 goto restart_loop;
2426 } 2692 }
2427 } else {
2428 cifs_stats_bytes_read(pTcon, bytes_read);
2429 *poffset += bytes_read;
2430 } 2693 }
2694 list_del_init(&rdata->list);
2695 kref_put(&rdata->refcount, cifs_uncached_readdata_release);
2431 } 2696 }
2432 2697
2433 FreeXid(xid); 2698 cifs_stats_bytes_read(tcon, total_read);
2434 return total_read; 2699 *poffset += total_read;
2700
2701 return total_read ? total_read : rc;
2435} 2702}
2436 2703
2437ssize_t cifs_user_readv(struct kiocb *iocb, const struct iovec *iov, 2704ssize_t cifs_user_readv(struct kiocb *iocb, const struct iovec *iov,
@@ -2606,6 +2873,100 @@ int cifs_file_mmap(struct file *file, struct vm_area_struct *vma)
2606 return rc; 2873 return rc;
2607} 2874}
2608 2875
2876static void
2877cifs_readv_complete(struct work_struct *work)
2878{
2879 struct cifs_readdata *rdata = container_of(work,
2880 struct cifs_readdata, work);
2881 struct page *page, *tpage;
2882
2883 list_for_each_entry_safe(page, tpage, &rdata->pages, lru) {
2884 list_del(&page->lru);
2885 lru_cache_add_file(page);
2886
2887 if (rdata->result == 0) {
2888 kunmap(page);
2889 flush_dcache_page(page);
2890 SetPageUptodate(page);
2891 }
2892
2893 unlock_page(page);
2894
2895 if (rdata->result == 0)
2896 cifs_readpage_to_fscache(rdata->mapping->host, page);
2897
2898 page_cache_release(page);
2899 }
2900 kref_put(&rdata->refcount, cifs_readdata_release);
2901}
2902
2903static int
2904cifs_readpages_marshal_iov(struct cifs_readdata *rdata, unsigned int remaining)
2905{
2906 int len = 0;
2907 struct page *page, *tpage;
2908 u64 eof;
2909 pgoff_t eof_index;
2910
2911 /* determine the eof that the server (probably) has */
2912 eof = CIFS_I(rdata->mapping->host)->server_eof;
2913 eof_index = eof ? (eof - 1) >> PAGE_CACHE_SHIFT : 0;
2914 cFYI(1, "eof=%llu eof_index=%lu", eof, eof_index);
2915
2916 rdata->nr_iov = 1;
2917 list_for_each_entry_safe(page, tpage, &rdata->pages, lru) {
2918 if (remaining >= PAGE_CACHE_SIZE) {
2919 /* enough data to fill the page */
2920 rdata->iov[rdata->nr_iov].iov_base = kmap(page);
2921 rdata->iov[rdata->nr_iov].iov_len = PAGE_CACHE_SIZE;
2922 cFYI(1, "%u: idx=%lu iov_base=%p iov_len=%zu",
2923 rdata->nr_iov, page->index,
2924 rdata->iov[rdata->nr_iov].iov_base,
2925 rdata->iov[rdata->nr_iov].iov_len);
2926 ++rdata->nr_iov;
2927 len += PAGE_CACHE_SIZE;
2928 remaining -= PAGE_CACHE_SIZE;
2929 } else if (remaining > 0) {
2930 /* enough for partial page, fill and zero the rest */
2931 rdata->iov[rdata->nr_iov].iov_base = kmap(page);
2932 rdata->iov[rdata->nr_iov].iov_len = remaining;
2933 cFYI(1, "%u: idx=%lu iov_base=%p iov_len=%zu",
2934 rdata->nr_iov, page->index,
2935 rdata->iov[rdata->nr_iov].iov_base,
2936 rdata->iov[rdata->nr_iov].iov_len);
2937 memset(rdata->iov[rdata->nr_iov].iov_base + remaining,
2938 '\0', PAGE_CACHE_SIZE - remaining);
2939 ++rdata->nr_iov;
2940 len += remaining;
2941 remaining = 0;
2942 } else if (page->index > eof_index) {
2943 /*
2944 * The VFS will not try to do readahead past the
2945 * i_size, but it's possible that we have outstanding
2946 * writes with gaps in the middle and the i_size hasn't
2947 * caught up yet. Populate those with zeroed out pages
2948 * to prevent the VFS from repeatedly attempting to
2949 * fill them until the writes are flushed.
2950 */
2951 zero_user(page, 0, PAGE_CACHE_SIZE);
2952 list_del(&page->lru);
2953 lru_cache_add_file(page);
2954 flush_dcache_page(page);
2955 SetPageUptodate(page);
2956 unlock_page(page);
2957 page_cache_release(page);
2958 } else {
2959 /* no need to hold page hostage */
2960 list_del(&page->lru);
2961 lru_cache_add_file(page);
2962 unlock_page(page);
2963 page_cache_release(page);
2964 }
2965 }
2966
2967 return len;
2968}
2969
2609static int cifs_readpages(struct file *file, struct address_space *mapping, 2970static int cifs_readpages(struct file *file, struct address_space *mapping,
2610 struct list_head *page_list, unsigned num_pages) 2971 struct list_head *page_list, unsigned num_pages)
2611{ 2972{
@@ -2708,7 +3069,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
2708 nr_pages++; 3069 nr_pages++;
2709 } 3070 }
2710 3071
2711 rdata = cifs_readdata_alloc(nr_pages); 3072 rdata = cifs_readdata_alloc(nr_pages, cifs_readv_complete);
2712 if (!rdata) { 3073 if (!rdata) {
2713 /* best to give up if we're out of mem */ 3074 /* best to give up if we're out of mem */
2714 list_for_each_entry_safe(page, tpage, &tmplist, lru) { 3075 list_for_each_entry_safe(page, tpage, &tmplist, lru) {
@@ -2722,24 +3083,16 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
2722 } 3083 }
2723 3084
2724 spin_lock(&cifs_file_list_lock); 3085 spin_lock(&cifs_file_list_lock);
2725 cifsFileInfo_get(open_file);
2726 spin_unlock(&cifs_file_list_lock); 3086 spin_unlock(&cifs_file_list_lock);
2727 rdata->cfile = open_file; 3087 rdata->cfile = cifsFileInfo_get(open_file);
2728 rdata->mapping = mapping; 3088 rdata->mapping = mapping;
2729 rdata->offset = offset; 3089 rdata->offset = offset;
2730 rdata->bytes = bytes; 3090 rdata->bytes = bytes;
2731 rdata->pid = pid; 3091 rdata->pid = pid;
3092 rdata->marshal_iov = cifs_readpages_marshal_iov;
2732 list_splice_init(&tmplist, &rdata->pages); 3093 list_splice_init(&tmplist, &rdata->pages);
2733 3094
2734 do { 3095 rc = cifs_retry_async_readv(rdata);
2735 if (open_file->invalidHandle) {
2736 rc = cifs_reopen_file(open_file, true);
2737 if (rc != 0)
2738 continue;
2739 }
2740 rc = cifs_async_readv(rdata);
2741 } while (rc == -EAGAIN);
2742
2743 if (rc != 0) { 3096 if (rc != 0) {
2744 list_for_each_entry_safe(page, tpage, &rdata->pages, 3097 list_for_each_entry_safe(page, tpage, &rdata->pages,
2745 lru) { 3098 lru) {
@@ -2748,9 +3101,11 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
2748 unlock_page(page); 3101 unlock_page(page);
2749 page_cache_release(page); 3102 page_cache_release(page);
2750 } 3103 }
2751 cifs_readdata_free(rdata); 3104 kref_put(&rdata->refcount, cifs_readdata_release);
2752 break; 3105 break;
2753 } 3106 }
3107
3108 kref_put(&rdata->refcount, cifs_readdata_release);
2754 } 3109 }
2755 3110
2756 return rc; 3111 return rc;
diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c
index 4221b5e48a42..6d2667f0c98c 100644
--- a/fs/cifs/ioctl.c
+++ b/fs/cifs/ioctl.c
@@ -51,7 +51,15 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
51 cifs_sb = CIFS_SB(inode->i_sb); 51 cifs_sb = CIFS_SB(inode->i_sb);
52 52
53 switch (command) { 53 switch (command) {
54 static bool warned = false;
54 case CIFS_IOC_CHECKUMOUNT: 55 case CIFS_IOC_CHECKUMOUNT:
56 if (!warned) {
57 warned = true;
58 cERROR(1, "the CIFS_IOC_CHECKMOUNT ioctl will "
59 "be deprecated in 3.7. Please "
60 "migrate away from the use of "
61 "umount.cifs");
62 }
55 cFYI(1, "User unmount attempted"); 63 cFYI(1, "User unmount attempted");
56 if (cifs_sb->mnt_uid == current_uid()) 64 if (cifs_sb->mnt_uid == current_uid())
57 rc = 0; 65 rc = 0;
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index c29d1aa2c54f..557506ae1e2a 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -212,93 +212,6 @@ cifs_small_buf_release(void *buf_to_free)
212 return; 212 return;
213} 213}
214 214
215/*
216 * Find a free multiplex id (SMB mid). Otherwise there could be
217 * mid collisions which might cause problems, demultiplexing the
218 * wrong response to this request. Multiplex ids could collide if
219 * one of a series requests takes much longer than the others, or
220 * if a very large number of long lived requests (byte range
221 * locks or FindNotify requests) are pending. No more than
222 * 64K-1 requests can be outstanding at one time. If no
223 * mids are available, return zero. A future optimization
224 * could make the combination of mids and uid the key we use
225 * to demultiplex on (rather than mid alone).
226 * In addition to the above check, the cifs demultiplex
227 * code already used the command code as a secondary
228 * check of the frame and if signing is negotiated the
229 * response would be discarded if the mid were the same
230 * but the signature was wrong. Since the mid is not put in the
231 * pending queue until later (when it is about to be dispatched)
232 * we do have to limit the number of outstanding requests
233 * to somewhat less than 64K-1 although it is hard to imagine
234 * so many threads being in the vfs at one time.
235 */
236__u64 GetNextMid(struct TCP_Server_Info *server)
237{
238 __u64 mid = 0;
239 __u16 last_mid, cur_mid;
240 bool collision;
241
242 spin_lock(&GlobalMid_Lock);
243
244 /* mid is 16 bit only for CIFS/SMB */
245 cur_mid = (__u16)((server->CurrentMid) & 0xffff);
246 /* we do not want to loop forever */
247 last_mid = cur_mid;
248 cur_mid++;
249
250 /*
251 * This nested loop looks more expensive than it is.
252 * In practice the list of pending requests is short,
253 * fewer than 50, and the mids are likely to be unique
254 * on the first pass through the loop unless some request
255 * takes longer than the 64 thousand requests before it
256 * (and it would also have to have been a request that
257 * did not time out).
258 */
259 while (cur_mid != last_mid) {
260 struct mid_q_entry *mid_entry;
261 unsigned int num_mids;
262
263 collision = false;
264 if (cur_mid == 0)
265 cur_mid++;
266
267 num_mids = 0;
268 list_for_each_entry(mid_entry, &server->pending_mid_q, qhead) {
269 ++num_mids;
270 if (mid_entry->mid == cur_mid &&
271 mid_entry->mid_state == MID_REQUEST_SUBMITTED) {
272 /* This mid is in use, try a different one */
273 collision = true;
274 break;
275 }
276 }
277
278 /*
279 * if we have more than 32k mids in the list, then something
280 * is very wrong. Possibly a local user is trying to DoS the
281 * box by issuing long-running calls and SIGKILL'ing them. If
282 * we get to 2^16 mids then we're in big trouble as this
283 * function could loop forever.
284 *
285 * Go ahead and assign out the mid in this situation, but force
286 * an eventual reconnect to clean out the pending_mid_q.
287 */
288 if (num_mids > 32768)
289 server->tcpStatus = CifsNeedReconnect;
290
291 if (!collision) {
292 mid = (__u64)cur_mid;
293 server->CurrentMid = mid;
294 break;
295 }
296 cur_mid++;
297 }
298 spin_unlock(&GlobalMid_Lock);
299 return mid;
300}
301
302/* NB: MID can not be set if treeCon not passed in, in that 215/* NB: MID can not be set if treeCon not passed in, in that
303 case it is responsbility of caller to set the mid */ 216 case it is responsbility of caller to set the mid */
304void 217void
@@ -306,8 +219,6 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
306 const struct cifs_tcon *treeCon, int word_count 219 const struct cifs_tcon *treeCon, int word_count
307 /* length of fixed section (word count) in two byte units */) 220 /* length of fixed section (word count) in two byte units */)
308{ 221{
309 struct list_head *temp_item;
310 struct cifs_ses *ses;
311 char *temp = (char *) buffer; 222 char *temp = (char *) buffer;
312 223
313 memset(temp, 0, 256); /* bigger than MAX_CIFS_HDR_SIZE */ 224 memset(temp, 0, 256); /* bigger than MAX_CIFS_HDR_SIZE */
@@ -336,52 +247,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
336 247
337 /* Uid is not converted */ 248 /* Uid is not converted */
338 buffer->Uid = treeCon->ses->Suid; 249 buffer->Uid = treeCon->ses->Suid;
339 buffer->Mid = GetNextMid(treeCon->ses->server); 250 buffer->Mid = get_next_mid(treeCon->ses->server);
340 if (multiuser_mount != 0) {
341 /* For the multiuser case, there are few obvious technically */
342 /* possible mechanisms to match the local linux user (uid) */
343 /* to a valid remote smb user (smb_uid): */
344 /* 1) Query Winbind (or other local pam/nss daemon */
345 /* for userid/password/logon_domain or credential */
346 /* 2) Query Winbind for uid to sid to username mapping */
347 /* and see if we have a matching password for existing*/
348 /* session for that user perhas getting password by */
349 /* adding a new pam_cifs module that stores passwords */
350 /* so that the cifs vfs can get at that for all logged*/
351 /* on users */
352 /* 3) (Which is the mechanism we have chosen) */
353 /* Search through sessions to the same server for a */
354 /* a match on the uid that was passed in on mount */
355 /* with the current processes uid (or euid?) and use */
356 /* that smb uid. If no existing smb session for */
357 /* that uid found, use the default smb session ie */
358 /* the smb session for the volume mounted which is */
359 /* the same as would be used if the multiuser mount */
360 /* flag were disabled. */
361
362 /* BB Add support for establishing new tCon and SMB Session */
363 /* with userid/password pairs found on the smb session */
364 /* for other target tcp/ip addresses BB */
365 if (current_fsuid() != treeCon->ses->linux_uid) {
366 cFYI(1, "Multiuser mode and UID "
367 "did not match tcon uid");
368 spin_lock(&cifs_tcp_ses_lock);
369 list_for_each(temp_item, &treeCon->ses->server->smb_ses_list) {
370 ses = list_entry(temp_item, struct cifs_ses, smb_ses_list);
371 if (ses->linux_uid == current_fsuid()) {
372 if (ses->server == treeCon->ses->server) {
373 cFYI(1, "found matching uid substitute right smb_uid");
374 buffer->Uid = ses->Suid;
375 break;
376 } else {
377 /* BB eventually call cifs_setup_session here */
378 cFYI(1, "local UID found but no smb sess with this server exists");
379 }
380 }
381 }
382 spin_unlock(&cifs_tcp_ses_lock);
383 }
384 }
385 } 251 }
386 if (treeCon->Flags & SMB_SHARE_IS_IN_DFS) 252 if (treeCon->Flags & SMB_SHARE_IS_IN_DFS)
387 buffer->Flags2 |= SMBFLG2_DFS; 253 buffer->Flags2 |= SMBFLG2_DFS;
@@ -700,22 +566,3 @@ backup_cred(struct cifs_sb_info *cifs_sb)
700 566
701 return false; 567 return false;
702} 568}
703
704void
705cifs_add_credits(struct TCP_Server_Info *server, const unsigned int add)
706{
707 spin_lock(&server->req_lock);
708 server->credits += add;
709 server->in_flight--;
710 spin_unlock(&server->req_lock);
711 wake_up(&server->request_q);
712}
713
714void
715cifs_set_credits(struct TCP_Server_Info *server, const int val)
716{
717 spin_lock(&server->req_lock);
718 server->credits = val;
719 server->oplocks = val > 1 ? enable_oplocks : false;
720 spin_unlock(&server->req_lock);
721}
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index e2bbc683e018..0a8224d1c4c5 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -219,6 +219,7 @@ int get_symlink_reparse_path(char *full_path, struct cifs_sb_info *cifs_sb,
219 219
220static int initiate_cifs_search(const int xid, struct file *file) 220static int initiate_cifs_search(const int xid, struct file *file)
221{ 221{
222 __u16 search_flags;
222 int rc = 0; 223 int rc = 0;
223 char *full_path = NULL; 224 char *full_path = NULL;
224 struct cifsFileInfo *cifsFile; 225 struct cifsFileInfo *cifsFile;
@@ -270,8 +271,12 @@ ffirst_retry:
270 cifsFile->srch_inf.info_level = SMB_FIND_FILE_DIRECTORY_INFO; 271 cifsFile->srch_inf.info_level = SMB_FIND_FILE_DIRECTORY_INFO;
271 } 272 }
272 273
274 search_flags = CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME;
275 if (backup_cred(cifs_sb))
276 search_flags |= CIFS_SEARCH_BACKUP_SEARCH;
277
273 rc = CIFSFindFirst(xid, pTcon, full_path, cifs_sb->local_nls, 278 rc = CIFSFindFirst(xid, pTcon, full_path, cifs_sb->local_nls,
274 &cifsFile->netfid, &cifsFile->srch_inf, 279 &cifsFile->netfid, search_flags, &cifsFile->srch_inf,
275 cifs_sb->mnt_cifs_flags & 280 cifs_sb->mnt_cifs_flags &
276 CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb)); 281 CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb));
277 if (rc == 0) 282 if (rc == 0)
@@ -502,11 +507,13 @@ static int cifs_save_resume_key(const char *current_entry,
502static int find_cifs_entry(const int xid, struct cifs_tcon *pTcon, 507static int find_cifs_entry(const int xid, struct cifs_tcon *pTcon,
503 struct file *file, char **ppCurrentEntry, int *num_to_ret) 508 struct file *file, char **ppCurrentEntry, int *num_to_ret)
504{ 509{
510 __u16 search_flags;
505 int rc = 0; 511 int rc = 0;
506 int pos_in_buf = 0; 512 int pos_in_buf = 0;
507 loff_t first_entry_in_buffer; 513 loff_t first_entry_in_buffer;
508 loff_t index_to_find = file->f_pos; 514 loff_t index_to_find = file->f_pos;
509 struct cifsFileInfo *cifsFile = file->private_data; 515 struct cifsFileInfo *cifsFile = file->private_data;
516 struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
510 /* check if index in the buffer */ 517 /* check if index in the buffer */
511 518
512 if ((cifsFile == NULL) || (ppCurrentEntry == NULL) || 519 if ((cifsFile == NULL) || (ppCurrentEntry == NULL) ||
@@ -560,10 +567,14 @@ static int find_cifs_entry(const int xid, struct cifs_tcon *pTcon,
560 cifsFile); 567 cifsFile);
561 } 568 }
562 569
570 search_flags = CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME;
571 if (backup_cred(cifs_sb))
572 search_flags |= CIFS_SEARCH_BACKUP_SEARCH;
573
563 while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) && 574 while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) &&
564 (rc == 0) && !cifsFile->srch_inf.endOfSearch) { 575 (rc == 0) && !cifsFile->srch_inf.endOfSearch) {
565 cFYI(1, "calling findnext2"); 576 cFYI(1, "calling findnext2");
566 rc = CIFSFindNext(xid, pTcon, cifsFile->netfid, 577 rc = CIFSFindNext(xid, pTcon, cifsFile->netfid, search_flags,
567 &cifsFile->srch_inf); 578 &cifsFile->srch_inf);
568 /* FindFirst/Next set last_entry to NULL on malformed reply */ 579 /* FindFirst/Next set last_entry to NULL on malformed reply */
569 if (cifsFile->srch_inf.last_entry) 580 if (cifsFile->srch_inf.last_entry)
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c
new file mode 100644
index 000000000000..6dec38f5522d
--- /dev/null
+++ b/fs/cifs/smb1ops.c
@@ -0,0 +1,243 @@
1/*
2 * SMB1 (CIFS) version specific operations
3 *
4 * Copyright (c) 2012, Jeff Layton <jlayton@redhat.com>
5 *
6 * This library is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License v2 as published
8 * by the Free Software Foundation.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include "cifsglob.h"
21#include "cifsproto.h"
22#include "cifs_debug.h"
23#include "cifspdu.h"
24
25/*
26 * An NT cancel request header looks just like the original request except:
27 *
28 * The Command is SMB_COM_NT_CANCEL
29 * The WordCount is zeroed out
30 * The ByteCount is zeroed out
31 *
32 * This function mangles an existing request buffer into a
33 * SMB_COM_NT_CANCEL request and then sends it.
34 */
35static int
36send_nt_cancel(struct TCP_Server_Info *server, void *buf,
37 struct mid_q_entry *mid)
38{
39 int rc = 0;
40 struct smb_hdr *in_buf = (struct smb_hdr *)buf;
41
42 /* -4 for RFC1001 length and +2 for BCC field */
43 in_buf->smb_buf_length = cpu_to_be32(sizeof(struct smb_hdr) - 4 + 2);
44 in_buf->Command = SMB_COM_NT_CANCEL;
45 in_buf->WordCount = 0;
46 put_bcc(0, in_buf);
47
48 mutex_lock(&server->srv_mutex);
49 rc = cifs_sign_smb(in_buf, server, &mid->sequence_number);
50 if (rc) {
51 mutex_unlock(&server->srv_mutex);
52 return rc;
53 }
54 rc = smb_send(server, in_buf, be32_to_cpu(in_buf->smb_buf_length));
55 mutex_unlock(&server->srv_mutex);
56
57 cFYI(1, "issued NT_CANCEL for mid %u, rc = %d",
58 in_buf->Mid, rc);
59
60 return rc;
61}
62
63static bool
64cifs_compare_fids(struct cifsFileInfo *ob1, struct cifsFileInfo *ob2)
65{
66 return ob1->netfid == ob2->netfid;
67}
68
69static unsigned int
70cifs_read_data_offset(char *buf)
71{
72 READ_RSP *rsp = (READ_RSP *)buf;
73 return le16_to_cpu(rsp->DataOffset);
74}
75
76static unsigned int
77cifs_read_data_length(char *buf)
78{
79 READ_RSP *rsp = (READ_RSP *)buf;
80 return (le16_to_cpu(rsp->DataLengthHigh) << 16) +
81 le16_to_cpu(rsp->DataLength);
82}
83
84static struct mid_q_entry *
85cifs_find_mid(struct TCP_Server_Info *server, char *buffer)
86{
87 struct smb_hdr *buf = (struct smb_hdr *)buffer;
88 struct mid_q_entry *mid;
89
90 spin_lock(&GlobalMid_Lock);
91 list_for_each_entry(mid, &server->pending_mid_q, qhead) {
92 if (mid->mid == buf->Mid &&
93 mid->mid_state == MID_REQUEST_SUBMITTED &&
94 le16_to_cpu(mid->command) == buf->Command) {
95 spin_unlock(&GlobalMid_Lock);
96 return mid;
97 }
98 }
99 spin_unlock(&GlobalMid_Lock);
100 return NULL;
101}
102
103static void
104cifs_add_credits(struct TCP_Server_Info *server, const unsigned int add)
105{
106 spin_lock(&server->req_lock);
107 server->credits += add;
108 server->in_flight--;
109 spin_unlock(&server->req_lock);
110 wake_up(&server->request_q);
111}
112
113static void
114cifs_set_credits(struct TCP_Server_Info *server, const int val)
115{
116 spin_lock(&server->req_lock);
117 server->credits = val;
118 server->oplocks = val > 1 ? enable_oplocks : false;
119 spin_unlock(&server->req_lock);
120}
121
122static int *
123cifs_get_credits_field(struct TCP_Server_Info *server)
124{
125 return &server->credits;
126}
127
128/*
129 * Find a free multiplex id (SMB mid). Otherwise there could be
130 * mid collisions which might cause problems, demultiplexing the
131 * wrong response to this request. Multiplex ids could collide if
132 * one of a series requests takes much longer than the others, or
133 * if a very large number of long lived requests (byte range
134 * locks or FindNotify requests) are pending. No more than
135 * 64K-1 requests can be outstanding at one time. If no
136 * mids are available, return zero. A future optimization
137 * could make the combination of mids and uid the key we use
138 * to demultiplex on (rather than mid alone).
139 * In addition to the above check, the cifs demultiplex
140 * code already used the command code as a secondary
141 * check of the frame and if signing is negotiated the
142 * response would be discarded if the mid were the same
143 * but the signature was wrong. Since the mid is not put in the
144 * pending queue until later (when it is about to be dispatched)
145 * we do have to limit the number of outstanding requests
146 * to somewhat less than 64K-1 although it is hard to imagine
147 * so many threads being in the vfs at one time.
148 */
149static __u64
150cifs_get_next_mid(struct TCP_Server_Info *server)
151{
152 __u64 mid = 0;
153 __u16 last_mid, cur_mid;
154 bool collision;
155
156 spin_lock(&GlobalMid_Lock);
157
158 /* mid is 16 bit only for CIFS/SMB */
159 cur_mid = (__u16)((server->CurrentMid) & 0xffff);
160 /* we do not want to loop forever */
161 last_mid = cur_mid;
162 cur_mid++;
163
164 /*
165 * This nested loop looks more expensive than it is.
166 * In practice the list of pending requests is short,
167 * fewer than 50, and the mids are likely to be unique
168 * on the first pass through the loop unless some request
169 * takes longer than the 64 thousand requests before it
170 * (and it would also have to have been a request that
171 * did not time out).
172 */
173 while (cur_mid != last_mid) {
174 struct mid_q_entry *mid_entry;
175 unsigned int num_mids;
176
177 collision = false;
178 if (cur_mid == 0)
179 cur_mid++;
180
181 num_mids = 0;
182 list_for_each_entry(mid_entry, &server->pending_mid_q, qhead) {
183 ++num_mids;
184 if (mid_entry->mid == cur_mid &&
185 mid_entry->mid_state == MID_REQUEST_SUBMITTED) {
186 /* This mid is in use, try a different one */
187 collision = true;
188 break;
189 }
190 }
191
192 /*
193 * if we have more than 32k mids in the list, then something
194 * is very wrong. Possibly a local user is trying to DoS the
195 * box by issuing long-running calls and SIGKILL'ing them. If
196 * we get to 2^16 mids then we're in big trouble as this
197 * function could loop forever.
198 *
199 * Go ahead and assign out the mid in this situation, but force
200 * an eventual reconnect to clean out the pending_mid_q.
201 */
202 if (num_mids > 32768)
203 server->tcpStatus = CifsNeedReconnect;
204
205 if (!collision) {
206 mid = (__u64)cur_mid;
207 server->CurrentMid = mid;
208 break;
209 }
210 cur_mid++;
211 }
212 spin_unlock(&GlobalMid_Lock);
213 return mid;
214}
215
216struct smb_version_operations smb1_operations = {
217 .send_cancel = send_nt_cancel,
218 .compare_fids = cifs_compare_fids,
219 .setup_request = cifs_setup_request,
220 .check_receive = cifs_check_receive,
221 .add_credits = cifs_add_credits,
222 .set_credits = cifs_set_credits,
223 .get_credits_field = cifs_get_credits_field,
224 .get_next_mid = cifs_get_next_mid,
225 .read_data_offset = cifs_read_data_offset,
226 .read_data_length = cifs_read_data_length,
227 .map_error = map_smb_to_linux_error,
228 .find_mid = cifs_find_mid,
229 .check_message = checkSMB,
230 .dump_detail = cifs_dump_detail,
231 .is_oplock_break = is_valid_oplock_break,
232};
233
234struct smb_version_values smb1_values = {
235 .version_string = SMB1_VERSION_STRING,
236 .large_lock_type = LOCKING_ANDX_LARGE_FILES,
237 .exclusive_lock_type = 0,
238 .shared_lock_type = LOCKING_ANDX_SHARED_LOCK,
239 .unlock_lock_type = 0,
240 .header_size = sizeof(struct smb_hdr),
241 .max_header_size = MAX_CIFS_HDR_SIZE,
242 .read_rsp_size = sizeof(READ_RSP),
243};
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
new file mode 100644
index 000000000000..f065e89756a1
--- /dev/null
+++ b/fs/cifs/smb2ops.c
@@ -0,0 +1,27 @@
1/*
2 * SMB2 version specific operations
3 *
4 * Copyright (c) 2012, Jeff Layton <jlayton@redhat.com>
5 *
6 * This library is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License v2 as published
8 * by the Free Software Foundation.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include "cifsglob.h"
21
22struct smb_version_operations smb21_operations = {
23};
24
25struct smb_version_values smb21_values = {
26 .version_string = SMB21_VERSION_STRING,
27};
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 0961336513d5..3097ee58fd7d 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -304,7 +304,8 @@ wait_for_free_credits(struct TCP_Server_Info *server, const int optype,
304static int 304static int
305wait_for_free_request(struct TCP_Server_Info *server, const int optype) 305wait_for_free_request(struct TCP_Server_Info *server, const int optype)
306{ 306{
307 return wait_for_free_credits(server, optype, get_credits_field(server)); 307 return wait_for_free_credits(server, optype,
308 server->ops->get_credits_field(server));
308} 309}
309 310
310static int allocate_mid(struct cifs_ses *ses, struct smb_hdr *in_buf, 311static int allocate_mid(struct cifs_ses *ses, struct smb_hdr *in_buf,
@@ -396,7 +397,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov,
396 rc = cifs_setup_async_request(server, iov, nvec, &mid); 397 rc = cifs_setup_async_request(server, iov, nvec, &mid);
397 if (rc) { 398 if (rc) {
398 mutex_unlock(&server->srv_mutex); 399 mutex_unlock(&server->srv_mutex);
399 cifs_add_credits(server, 1); 400 add_credits(server, 1);
400 wake_up(&server->request_q); 401 wake_up(&server->request_q);
401 return rc; 402 return rc;
402 } 403 }
@@ -418,7 +419,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov,
418 return rc; 419 return rc;
419out_err: 420out_err:
420 delete_mid(mid); 421 delete_mid(mid);
421 cifs_add_credits(server, 1); 422 add_credits(server, 1);
422 wake_up(&server->request_q); 423 wake_up(&server->request_q);
423 return rc; 424 return rc;
424} 425}
@@ -483,41 +484,11 @@ cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)
483 return rc; 484 return rc;
484} 485}
485 486
486/* 487static inline int
487 * An NT cancel request header looks just like the original request except: 488send_cancel(struct TCP_Server_Info *server, void *buf, struct mid_q_entry *mid)
488 *
489 * The Command is SMB_COM_NT_CANCEL
490 * The WordCount is zeroed out
491 * The ByteCount is zeroed out
492 *
493 * This function mangles an existing request buffer into a
494 * SMB_COM_NT_CANCEL request and then sends it.
495 */
496static int
497send_nt_cancel(struct TCP_Server_Info *server, struct smb_hdr *in_buf,
498 struct mid_q_entry *mid)
499{ 489{
500 int rc = 0; 490 return server->ops->send_cancel ?
501 491 server->ops->send_cancel(server, buf, mid) : 0;
502 /* -4 for RFC1001 length and +2 for BCC field */
503 in_buf->smb_buf_length = cpu_to_be32(sizeof(struct smb_hdr) - 4 + 2);
504 in_buf->Command = SMB_COM_NT_CANCEL;
505 in_buf->WordCount = 0;
506 put_bcc(0, in_buf);
507
508 mutex_lock(&server->srv_mutex);
509 rc = cifs_sign_smb(in_buf, server, &mid->sequence_number);
510 if (rc) {
511 mutex_unlock(&server->srv_mutex);
512 return rc;
513 }
514 rc = smb_send(server, in_buf, be32_to_cpu(in_buf->smb_buf_length));
515 mutex_unlock(&server->srv_mutex);
516
517 cFYI(1, "issued NT_CANCEL for mid %u, rc = %d",
518 in_buf->Mid, rc);
519
520 return rc;
521} 492}
522 493
523int 494int
@@ -544,7 +515,7 @@ cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
544 return map_smb_to_linux_error(mid->resp_buf, log_error); 515 return map_smb_to_linux_error(mid->resp_buf, log_error);
545} 516}
546 517
547static int 518int
548cifs_setup_request(struct cifs_ses *ses, struct kvec *iov, 519cifs_setup_request(struct cifs_ses *ses, struct kvec *iov,
549 unsigned int nvec, struct mid_q_entry **ret_mid) 520 unsigned int nvec, struct mid_q_entry **ret_mid)
550{ 521{
@@ -607,12 +578,12 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses,
607 578
608 mutex_lock(&ses->server->srv_mutex); 579 mutex_lock(&ses->server->srv_mutex);
609 580
610 rc = cifs_setup_request(ses, iov, n_vec, &midQ); 581 rc = ses->server->ops->setup_request(ses, iov, n_vec, &midQ);
611 if (rc) { 582 if (rc) {
612 mutex_unlock(&ses->server->srv_mutex); 583 mutex_unlock(&ses->server->srv_mutex);
613 cifs_small_buf_release(buf); 584 cifs_small_buf_release(buf);
614 /* Update # of requests on wire to server */ 585 /* Update # of requests on wire to server */
615 cifs_add_credits(ses->server, 1); 586 add_credits(ses->server, 1);
616 return rc; 587 return rc;
617 } 588 }
618 589
@@ -636,13 +607,13 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses,
636 607
637 rc = wait_for_response(ses->server, midQ); 608 rc = wait_for_response(ses->server, midQ);
638 if (rc != 0) { 609 if (rc != 0) {
639 send_nt_cancel(ses->server, (struct smb_hdr *)buf, midQ); 610 send_cancel(ses->server, buf, midQ);
640 spin_lock(&GlobalMid_Lock); 611 spin_lock(&GlobalMid_Lock);
641 if (midQ->mid_state == MID_REQUEST_SUBMITTED) { 612 if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
642 midQ->callback = DeleteMidQEntry; 613 midQ->callback = DeleteMidQEntry;
643 spin_unlock(&GlobalMid_Lock); 614 spin_unlock(&GlobalMid_Lock);
644 cifs_small_buf_release(buf); 615 cifs_small_buf_release(buf);
645 cifs_add_credits(ses->server, 1); 616 add_credits(ses->server, 1);
646 return rc; 617 return rc;
647 } 618 }
648 spin_unlock(&GlobalMid_Lock); 619 spin_unlock(&GlobalMid_Lock);
@@ -652,7 +623,7 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses,
652 623
653 rc = cifs_sync_mid_result(midQ, ses->server); 624 rc = cifs_sync_mid_result(midQ, ses->server);
654 if (rc != 0) { 625 if (rc != 0) {
655 cifs_add_credits(ses->server, 1); 626 add_credits(ses->server, 1);
656 return rc; 627 return rc;
657 } 628 }
658 629
@@ -670,14 +641,15 @@ SendReceive2(const unsigned int xid, struct cifs_ses *ses,
670 else 641 else
671 *pRespBufType = CIFS_SMALL_BUFFER; 642 *pRespBufType = CIFS_SMALL_BUFFER;
672 643
673 rc = cifs_check_receive(midQ, ses->server, flags & CIFS_LOG_ERROR); 644 rc = ses->server->ops->check_receive(midQ, ses->server,
645 flags & CIFS_LOG_ERROR);
674 646
675 /* mark it so buf will not be freed by delete_mid */ 647 /* mark it so buf will not be freed by delete_mid */
676 if ((flags & CIFS_NO_RESP) == 0) 648 if ((flags & CIFS_NO_RESP) == 0)
677 midQ->resp_buf = NULL; 649 midQ->resp_buf = NULL;
678out: 650out:
679 delete_mid(midQ); 651 delete_mid(midQ);
680 cifs_add_credits(ses->server, 1); 652 add_credits(ses->server, 1);
681 653
682 return rc; 654 return rc;
683} 655}
@@ -727,7 +699,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
727 if (rc) { 699 if (rc) {
728 mutex_unlock(&ses->server->srv_mutex); 700 mutex_unlock(&ses->server->srv_mutex);
729 /* Update # of requests on wire to server */ 701 /* Update # of requests on wire to server */
730 cifs_add_credits(ses->server, 1); 702 add_credits(ses->server, 1);
731 return rc; 703 return rc;
732 } 704 }
733 705
@@ -753,13 +725,13 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
753 725
754 rc = wait_for_response(ses->server, midQ); 726 rc = wait_for_response(ses->server, midQ);
755 if (rc != 0) { 727 if (rc != 0) {
756 send_nt_cancel(ses->server, in_buf, midQ); 728 send_cancel(ses->server, in_buf, midQ);
757 spin_lock(&GlobalMid_Lock); 729 spin_lock(&GlobalMid_Lock);
758 if (midQ->mid_state == MID_REQUEST_SUBMITTED) { 730 if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
759 /* no longer considered to be "in-flight" */ 731 /* no longer considered to be "in-flight" */
760 midQ->callback = DeleteMidQEntry; 732 midQ->callback = DeleteMidQEntry;
761 spin_unlock(&GlobalMid_Lock); 733 spin_unlock(&GlobalMid_Lock);
762 cifs_add_credits(ses->server, 1); 734 add_credits(ses->server, 1);
763 return rc; 735 return rc;
764 } 736 }
765 spin_unlock(&GlobalMid_Lock); 737 spin_unlock(&GlobalMid_Lock);
@@ -767,7 +739,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
767 739
768 rc = cifs_sync_mid_result(midQ, ses->server); 740 rc = cifs_sync_mid_result(midQ, ses->server);
769 if (rc != 0) { 741 if (rc != 0) {
770 cifs_add_credits(ses->server, 1); 742 add_credits(ses->server, 1);
771 return rc; 743 return rc;
772 } 744 }
773 745
@@ -783,7 +755,7 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses,
783 rc = cifs_check_receive(midQ, ses->server, 0); 755 rc = cifs_check_receive(midQ, ses->server, 0);
784out: 756out:
785 delete_mid(midQ); 757 delete_mid(midQ);
786 cifs_add_credits(ses->server, 1); 758 add_credits(ses->server, 1);
787 759
788 return rc; 760 return rc;
789} 761}
@@ -807,7 +779,7 @@ send_lock_cancel(const unsigned int xid, struct cifs_tcon *tcon,
807 779
808 pSMB->LockType = LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES; 780 pSMB->LockType = LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES;
809 pSMB->Timeout = 0; 781 pSMB->Timeout = 0;
810 pSMB->hdr.Mid = GetNextMid(ses->server); 782 pSMB->hdr.Mid = get_next_mid(ses->server);
811 783
812 return SendReceive(xid, ses, in_buf, out_buf, 784 return SendReceive(xid, ses, in_buf, out_buf,
813 &bytes_returned, 0); 785 &bytes_returned, 0);
@@ -898,7 +870,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
898 if (in_buf->Command == SMB_COM_TRANSACTION2) { 870 if (in_buf->Command == SMB_COM_TRANSACTION2) {
899 /* POSIX lock. We send a NT_CANCEL SMB to cause the 871 /* POSIX lock. We send a NT_CANCEL SMB to cause the
900 blocking lock to return. */ 872 blocking lock to return. */
901 rc = send_nt_cancel(ses->server, in_buf, midQ); 873 rc = send_cancel(ses->server, in_buf, midQ);
902 if (rc) { 874 if (rc) {
903 delete_mid(midQ); 875 delete_mid(midQ);
904 return rc; 876 return rc;
@@ -919,7 +891,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
919 891
920 rc = wait_for_response(ses->server, midQ); 892 rc = wait_for_response(ses->server, midQ);
921 if (rc) { 893 if (rc) {
922 send_nt_cancel(ses->server, in_buf, midQ); 894 send_cancel(ses->server, in_buf, midQ);
923 spin_lock(&GlobalMid_Lock); 895 spin_lock(&GlobalMid_Lock);
924 if (midQ->mid_state == MID_REQUEST_SUBMITTED) { 896 if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
925 /* no longer considered to be "in-flight" */ 897 /* no longer considered to be "in-flight" */