aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-27 13:23:51 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-27 13:23:51 -0400
commit40efeb4d0bb1993c3c10baff9b7d86839f99171e (patch)
tree1f43ddf76f584273c4d7df4d1b469390619e4d25
parent81faae7f9c245a17f585d6edb7d4683cc6336b11 (diff)
parent383c55350fb4ab6bd08abfab82038ae0364f1f48 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6: [CIFS] Fix endian error comparing authusers when cifsacl enabled [CIFS] Rename three structures to avoid camel case Fix extended security auth failure CIFS: Add rwpidforward mount option CIFS: Migrate to shared superblock model [CIFS] Migrate from prefixpath logic CIFS: Fix memory leak in cifs_do_mount [CIFS] When mandatory encryption on share, fail mount CIFS: Use pid saved from cifsFileInfo in writepages and set_file_size cifs: add cifs_async_writev cifs: clean up wsize negotiation and allow for larger wsize cifs: convert cifs_writepages to use async writes CIFS: Fix undefined behavior when mount fails cifs: don't call mid_q_entry->callback under the Global_MidLock (try #5) CIFS: Simplify mount code for further shared sb capability CIFS: Simplify connection structure search calls cifs: remove unused SMB2 config and mount options cifs: add ignore_pend flag to cifs_call_async cifs: make cifs_send_async take a kvec array cifs: consolidate SendReceive response checks
-rw-r--r--fs/cifs/Kconfig20
-rw-r--r--fs/cifs/README3
-rw-r--r--fs/cifs/cache.c6
-rw-r--r--fs/cifs/cifs_debug.c26
-rw-r--r--fs/cifs/cifs_dfs_ref.c2
-rw-r--r--fs/cifs/cifs_fs_sb.h3
-rw-r--r--fs/cifs/cifs_spnego.c2
-rw-r--r--fs/cifs/cifs_spnego.h2
-rw-r--r--fs/cifs/cifsacl.c9
-rw-r--r--fs/cifs/cifsencrypt.c14
-rw-r--r--fs/cifs/cifsfs.c233
-rw-r--r--fs/cifs/cifsglob.h129
-rw-r--r--fs/cifs/cifsproto.h209
-rw-r--r--fs/cifs/cifssmb.c463
-rw-r--r--fs/cifs/connect.c625
-rw-r--r--fs/cifs/dir.c33
-rw-r--r--fs/cifs/file.c376
-rw-r--r--fs/cifs/fscache.c6
-rw-r--r--fs/cifs/fscache.h8
-rw-r--r--fs/cifs/inode.c92
-rw-r--r--fs/cifs/ioctl.c2
-rw-r--r--fs/cifs/link.c46
-rw-r--r--fs/cifs/misc.c32
-rw-r--r--fs/cifs/netmisc.c2
-rw-r--r--fs/cifs/readdir.c8
-rw-r--r--fs/cifs/sess.c42
-rw-r--r--fs/cifs/transport.c214
-rw-r--r--fs/cifs/xattr.c8
28 files changed, 1571 insertions, 1044 deletions
diff --git a/fs/cifs/Kconfig b/fs/cifs/Kconfig
index 75c47cd8d086..1cd4c3a1862d 100644
--- a/fs/cifs/Kconfig
+++ b/fs/cifs/Kconfig
@@ -153,26 +153,6 @@ config CIFS_ACL
153 Allows to fetch CIFS/NTFS ACL from the server. The DACL blob 153 Allows to fetch CIFS/NTFS ACL from the server. The DACL blob
154 is handed over to the application/caller. 154 is handed over to the application/caller.
155 155
156config CIFS_SMB2
157 bool "SMB2 network file system support (EXPERIMENTAL)"
158 depends on EXPERIMENTAL && INET && BROKEN
159 select NLS
160 select KEYS
161 select FSCACHE
162 select DNS_RESOLVER
163
164 help
165 This enables experimental support for the SMB2 (Server Message Block
166 version 2) protocol. The SMB2 protocol is the successor to the
167 popular CIFS and SMB network file sharing protocols. SMB2 is the
168 native file sharing mechanism for recent versions of Windows
169 operating systems (since Vista). SMB2 enablement will eventually
170 allow users better performance, security and features, than would be
171 possible with cifs. Note that smb2 mount options also are simpler
172 (compared to cifs) due to protocol improvements.
173
174 Unless you are a developer or tester, say N.
175
176config CIFS_NFSD_EXPORT 156config CIFS_NFSD_EXPORT
177 bool "Allow nfsd to export CIFS file system (EXPERIMENTAL)" 157 bool "Allow nfsd to export CIFS file system (EXPERIMENTAL)"
178 depends on CIFS && EXPERIMENTAL 158 depends on CIFS && EXPERIMENTAL
diff --git a/fs/cifs/README b/fs/cifs/README
index 4a3ca0e5ca24..c5c2c5e5f0f2 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -457,6 +457,9 @@ A partial list of the supported mount options follows:
457 otherwise - read from the server. All written data are stored 457 otherwise - read from the server. All written data are stored
458 in the cache, but if the client doesn't have Exclusive Oplock, 458 in the cache, but if the client doesn't have Exclusive Oplock,
459 it writes the data to the server. 459 it writes the data to the server.
460 rwpidforward Forward pid of a process who opened a file to any read or write
461 operation on that file. This prevent applications like WINE
462 from failing on read and write if we use mandatory brlock style.
460 acl Allow setfacl and getfacl to manage posix ACLs if server 463 acl Allow setfacl and getfacl to manage posix ACLs if server
461 supports them. (default) 464 supports them. (default)
462 noacl Do not allow setfacl and getfacl calls on this mount 465 noacl Do not allow setfacl and getfacl calls on this mount
diff --git a/fs/cifs/cache.c b/fs/cifs/cache.c
index 53d57a3fe427..dd8584d35a14 100644
--- a/fs/cifs/cache.c
+++ b/fs/cifs/cache.c
@@ -146,7 +146,7 @@ static char *extract_sharename(const char *treename)
146static uint16_t cifs_super_get_key(const void *cookie_netfs_data, void *buffer, 146static uint16_t cifs_super_get_key(const void *cookie_netfs_data, void *buffer,
147 uint16_t maxbuf) 147 uint16_t maxbuf)
148{ 148{
149 const struct cifsTconInfo *tcon = cookie_netfs_data; 149 const struct cifs_tcon *tcon = cookie_netfs_data;
150 char *sharename; 150 char *sharename;
151 uint16_t len; 151 uint16_t len;
152 152
@@ -173,7 +173,7 @@ cifs_fscache_super_get_aux(const void *cookie_netfs_data, void *buffer,
173 uint16_t maxbuf) 173 uint16_t maxbuf)
174{ 174{
175 struct cifs_fscache_super_auxdata auxdata; 175 struct cifs_fscache_super_auxdata auxdata;
176 const struct cifsTconInfo *tcon = cookie_netfs_data; 176 const struct cifs_tcon *tcon = cookie_netfs_data;
177 177
178 memset(&auxdata, 0, sizeof(auxdata)); 178 memset(&auxdata, 0, sizeof(auxdata));
179 auxdata.resource_id = tcon->resource_id; 179 auxdata.resource_id = tcon->resource_id;
@@ -192,7 +192,7 @@ fscache_checkaux cifs_fscache_super_check_aux(void *cookie_netfs_data,
192 uint16_t datalen) 192 uint16_t datalen)
193{ 193{
194 struct cifs_fscache_super_auxdata auxdata; 194 struct cifs_fscache_super_auxdata auxdata;
195 const struct cifsTconInfo *tcon = cookie_netfs_data; 195 const struct cifs_tcon *tcon = cookie_netfs_data;
196 196
197 if (datalen != sizeof(auxdata)) 197 if (datalen != sizeof(auxdata))
198 return FSCACHE_CHECKAUX_OBSOLETE; 198 return FSCACHE_CHECKAUX_OBSOLETE;
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
index 18f4272d9047..2fe3cf13b2e9 100644
--- a/fs/cifs/cifs_debug.c
+++ b/fs/cifs/cifs_debug.c
@@ -110,8 +110,8 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
110 struct list_head *tmp1, *tmp2, *tmp3; 110 struct list_head *tmp1, *tmp2, *tmp3;
111 struct mid_q_entry *mid_entry; 111 struct mid_q_entry *mid_entry;
112 struct TCP_Server_Info *server; 112 struct TCP_Server_Info *server;
113 struct cifsSesInfo *ses; 113 struct cifs_ses *ses;
114 struct cifsTconInfo *tcon; 114 struct cifs_tcon *tcon;
115 int i, j; 115 int i, j;
116 __u32 dev_type; 116 __u32 dev_type;
117 117
@@ -152,7 +152,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
152 tcp_ses_list); 152 tcp_ses_list);
153 i++; 153 i++;
154 list_for_each(tmp2, &server->smb_ses_list) { 154 list_for_each(tmp2, &server->smb_ses_list) {
155 ses = list_entry(tmp2, struct cifsSesInfo, 155 ses = list_entry(tmp2, struct cifs_ses,
156 smb_ses_list); 156 smb_ses_list);
157 if ((ses->serverDomain == NULL) || 157 if ((ses->serverDomain == NULL) ||
158 (ses->serverOS == NULL) || 158 (ses->serverOS == NULL) ||
@@ -171,7 +171,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
171 seq_printf(m, "TCP status: %d\n\tLocal Users To " 171 seq_printf(m, "TCP status: %d\n\tLocal Users To "
172 "Server: %d SecMode: 0x%x Req On Wire: %d", 172 "Server: %d SecMode: 0x%x Req On Wire: %d",
173 server->tcpStatus, server->srv_count, 173 server->tcpStatus, server->srv_count,
174 server->secMode, 174 server->sec_mode,
175 atomic_read(&server->inFlight)); 175 atomic_read(&server->inFlight));
176 176
177#ifdef CONFIG_CIFS_STATS2 177#ifdef CONFIG_CIFS_STATS2
@@ -183,7 +183,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
183 seq_puts(m, "\n\tShares:"); 183 seq_puts(m, "\n\tShares:");
184 j = 0; 184 j = 0;
185 list_for_each(tmp3, &ses->tcon_list) { 185 list_for_each(tmp3, &ses->tcon_list) {
186 tcon = list_entry(tmp3, struct cifsTconInfo, 186 tcon = list_entry(tmp3, struct cifs_tcon,
187 tcon_list); 187 tcon_list);
188 ++j; 188 ++j;
189 dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType); 189 dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType);
@@ -256,8 +256,8 @@ static ssize_t cifs_stats_proc_write(struct file *file,
256 int rc; 256 int rc;
257 struct list_head *tmp1, *tmp2, *tmp3; 257 struct list_head *tmp1, *tmp2, *tmp3;
258 struct TCP_Server_Info *server; 258 struct TCP_Server_Info *server;
259 struct cifsSesInfo *ses; 259 struct cifs_ses *ses;
260 struct cifsTconInfo *tcon; 260 struct cifs_tcon *tcon;
261 261
262 rc = get_user(c, buffer); 262 rc = get_user(c, buffer);
263 if (rc) 263 if (rc)
@@ -273,11 +273,11 @@ static ssize_t cifs_stats_proc_write(struct file *file,
273 server = list_entry(tmp1, struct TCP_Server_Info, 273 server = list_entry(tmp1, struct TCP_Server_Info,
274 tcp_ses_list); 274 tcp_ses_list);
275 list_for_each(tmp2, &server->smb_ses_list) { 275 list_for_each(tmp2, &server->smb_ses_list) {
276 ses = list_entry(tmp2, struct cifsSesInfo, 276 ses = list_entry(tmp2, struct cifs_ses,
277 smb_ses_list); 277 smb_ses_list);
278 list_for_each(tmp3, &ses->tcon_list) { 278 list_for_each(tmp3, &ses->tcon_list) {
279 tcon = list_entry(tmp3, 279 tcon = list_entry(tmp3,
280 struct cifsTconInfo, 280 struct cifs_tcon,
281 tcon_list); 281 tcon_list);
282 atomic_set(&tcon->num_smbs_sent, 0); 282 atomic_set(&tcon->num_smbs_sent, 0);
283 atomic_set(&tcon->num_writes, 0); 283 atomic_set(&tcon->num_writes, 0);
@@ -312,8 +312,8 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v)
312 int i; 312 int i;
313 struct list_head *tmp1, *tmp2, *tmp3; 313 struct list_head *tmp1, *tmp2, *tmp3;
314 struct TCP_Server_Info *server; 314 struct TCP_Server_Info *server;
315 struct cifsSesInfo *ses; 315 struct cifs_ses *ses;
316 struct cifsTconInfo *tcon; 316 struct cifs_tcon *tcon;
317 317
318 seq_printf(m, 318 seq_printf(m,
319 "Resources in use\nCIFS Session: %d\n", 319 "Resources in use\nCIFS Session: %d\n",
@@ -346,11 +346,11 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v)
346 server = list_entry(tmp1, struct TCP_Server_Info, 346 server = list_entry(tmp1, struct TCP_Server_Info,
347 tcp_ses_list); 347 tcp_ses_list);
348 list_for_each(tmp2, &server->smb_ses_list) { 348 list_for_each(tmp2, &server->smb_ses_list) {
349 ses = list_entry(tmp2, struct cifsSesInfo, 349 ses = list_entry(tmp2, struct cifs_ses,
350 smb_ses_list); 350 smb_ses_list);
351 list_for_each(tmp3, &ses->tcon_list) { 351 list_for_each(tmp3, &ses->tcon_list) {
352 tcon = list_entry(tmp3, 352 tcon = list_entry(tmp3,
353 struct cifsTconInfo, 353 struct cifs_tcon,
354 tcon_list); 354 tcon_list);
355 i++; 355 i++;
356 seq_printf(m, "\n%d) %s", i, tcon->treeName); 356 seq_printf(m, "\n%d) %s", i, tcon->treeName);
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c
index 2b68ac57d97d..8d8f28c94c0f 100644
--- a/fs/cifs/cifs_dfs_ref.c
+++ b/fs/cifs/cifs_dfs_ref.c
@@ -272,7 +272,7 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt)
272 struct dfs_info3_param *referrals = NULL; 272 struct dfs_info3_param *referrals = NULL;
273 unsigned int num_referrals = 0; 273 unsigned int num_referrals = 0;
274 struct cifs_sb_info *cifs_sb; 274 struct cifs_sb_info *cifs_sb;
275 struct cifsSesInfo *ses; 275 struct cifs_ses *ses;
276 char *full_path; 276 char *full_path;
277 int xid, i; 277 int xid, i;
278 int rc; 278 int rc;
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index a9d5692e0c20..ffb1459dc6ec 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -41,6 +41,7 @@
41#define CIFS_MOUNT_MF_SYMLINKS 0x10000 /* Minshall+French Symlinks enabled */ 41#define CIFS_MOUNT_MF_SYMLINKS 0x10000 /* Minshall+French Symlinks enabled */
42#define CIFS_MOUNT_MULTIUSER 0x20000 /* multiuser mount */ 42#define CIFS_MOUNT_MULTIUSER 0x20000 /* multiuser mount */
43#define CIFS_MOUNT_STRICT_IO 0x40000 /* strict cache mode */ 43#define CIFS_MOUNT_STRICT_IO 0x40000 /* strict cache mode */
44#define CIFS_MOUNT_RWPIDFORWARD 0x80000 /* use pid forwarding for rw */
44 45
45struct cifs_sb_info { 46struct cifs_sb_info {
46 struct rb_root tlink_tree; 47 struct rb_root tlink_tree;
@@ -56,8 +57,6 @@ struct cifs_sb_info {
56 mode_t mnt_file_mode; 57 mode_t mnt_file_mode;
57 mode_t mnt_dir_mode; 58 mode_t mnt_dir_mode;
58 unsigned int mnt_cifs_flags; 59 unsigned int mnt_cifs_flags;
59 int prepathlen;
60 char *prepath; /* relative path under the share to mount to */
61 char *mountdata; /* options received at mount time or via DFS refs */ 60 char *mountdata; /* options received at mount time or via DFS refs */
62 struct backing_dev_info bdi; 61 struct backing_dev_info bdi;
63 struct delayed_work prune_tlinks; 62 struct delayed_work prune_tlinks;
diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c
index 33d221394aca..2272fd5fe5b7 100644
--- a/fs/cifs/cifs_spnego.c
+++ b/fs/cifs/cifs_spnego.c
@@ -95,7 +95,7 @@ struct key_type cifs_spnego_key_type = {
95 95
96/* get a key struct with a SPNEGO security blob, suitable for session setup */ 96/* get a key struct with a SPNEGO security blob, suitable for session setup */
97struct key * 97struct key *
98cifs_get_spnego_key(struct cifsSesInfo *sesInfo) 98cifs_get_spnego_key(struct cifs_ses *sesInfo)
99{ 99{
100 struct TCP_Server_Info *server = sesInfo->server; 100 struct TCP_Server_Info *server = sesInfo->server;
101 struct sockaddr_in *sa = (struct sockaddr_in *) &server->dstaddr; 101 struct sockaddr_in *sa = (struct sockaddr_in *) &server->dstaddr;
diff --git a/fs/cifs/cifs_spnego.h b/fs/cifs/cifs_spnego.h
index e4041ec4d712..31bef9ee078b 100644
--- a/fs/cifs/cifs_spnego.h
+++ b/fs/cifs/cifs_spnego.h
@@ -41,7 +41,7 @@ struct cifs_spnego_msg {
41 41
42#ifdef __KERNEL__ 42#ifdef __KERNEL__
43extern struct key_type cifs_spnego_key_type; 43extern struct key_type cifs_spnego_key_type;
44extern struct key *cifs_get_spnego_key(struct cifsSesInfo *sesInfo); 44extern struct key *cifs_get_spnego_key(struct cifs_ses *sesInfo);
45#endif /* KERNEL */ 45#endif /* KERNEL */
46 46
47#endif /* _CIFS_SPNEGO_H */ 47#endif /* _CIFS_SPNEGO_H */
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index f3c6fb9942ac..5f02b4ee9a03 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -38,7 +38,7 @@ static const struct cifs_sid sid_everyone = {
38 1, 1, {0, 0, 0, 0, 0, 1}, {0} }; 38 1, 1, {0, 0, 0, 0, 0, 1}, {0} };
39/* security id for Authenticated Users system group */ 39/* security id for Authenticated Users system group */
40static const struct cifs_sid sid_authusers = { 40static const struct cifs_sid sid_authusers = {
41 1, 1, {0, 0, 0, 0, 0, 5}, {11} }; 41 1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11)} };
42/* group users */ 42/* group users */
43static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} }; 43static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} };
44 44
@@ -458,7 +458,8 @@ int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
458 if (num_subauth) { 458 if (num_subauth) {
459 for (i = 0; i < num_subauth; ++i) { 459 for (i = 0; i < num_subauth; ++i) {
460 if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) { 460 if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
461 if (ctsid->sub_auth[i] > cwsid->sub_auth[i]) 461 if (le32_to_cpu(ctsid->sub_auth[i]) >
462 le32_to_cpu(cwsid->sub_auth[i]))
462 return 1; 463 return 1;
463 else 464 else
464 return -1; 465 return -1;
@@ -945,7 +946,7 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
945 int oplock = 0; 946 int oplock = 0;
946 int xid, rc; 947 int xid, rc;
947 __u16 fid; 948 __u16 fid;
948 struct cifsTconInfo *tcon; 949 struct cifs_tcon *tcon;
949 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); 950 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
950 951
951 if (IS_ERR(tlink)) 952 if (IS_ERR(tlink))
@@ -1013,7 +1014,7 @@ static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path,
1013 int oplock = 0; 1014 int oplock = 0;
1014 int xid, rc; 1015 int xid, rc;
1015 __u16 fid; 1016 __u16 fid;
1016 struct cifsTconInfo *tcon; 1017 struct cifs_tcon *tcon;
1017 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); 1018 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
1018 1019
1019 if (IS_ERR(tlink)) 1020 if (IS_ERR(tlink))
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index 45c3f78c8f81..dfbd9f1f373d 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -229,7 +229,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu,
229} 229}
230 230
231/* first calculate 24 bytes ntlm response and then 16 byte session key */ 231/* first calculate 24 bytes ntlm response and then 16 byte session key */
232int setup_ntlm_response(struct cifsSesInfo *ses) 232int setup_ntlm_response(struct cifs_ses *ses)
233{ 233{
234 int rc = 0; 234 int rc = 0;
235 unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE; 235 unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE;
@@ -312,7 +312,7 @@ int calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
312 * Allocate domain name which gets freed when session struct is deallocated. 312 * Allocate domain name which gets freed when session struct is deallocated.
313 */ 313 */
314static int 314static int
315build_avpair_blob(struct cifsSesInfo *ses, const struct nls_table *nls_cp) 315build_avpair_blob(struct cifs_ses *ses, const struct nls_table *nls_cp)
316{ 316{
317 unsigned int dlen; 317 unsigned int dlen;
318 unsigned int wlen; 318 unsigned int wlen;
@@ -400,7 +400,7 @@ build_avpair_blob(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
400 * about target string i.e. for some, just user name might suffice. 400 * about target string i.e. for some, just user name might suffice.
401 */ 401 */
402static int 402static int
403find_domain_name(struct cifsSesInfo *ses, const struct nls_table *nls_cp) 403find_domain_name(struct cifs_ses *ses, const struct nls_table *nls_cp)
404{ 404{
405 unsigned int attrsize; 405 unsigned int attrsize;
406 unsigned int type; 406 unsigned int type;
@@ -445,7 +445,7 @@ find_domain_name(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
445 return 0; 445 return 0;
446} 446}
447 447
448static int calc_ntlmv2_hash(struct cifsSesInfo *ses, char *ntlmv2_hash, 448static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
449 const struct nls_table *nls_cp) 449 const struct nls_table *nls_cp)
450{ 450{
451 int rc = 0; 451 int rc = 0;
@@ -527,7 +527,7 @@ calc_exit_2:
527} 527}
528 528
529static int 529static int
530CalcNTLMv2_response(const struct cifsSesInfo *ses, char *ntlmv2_hash) 530CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash)
531{ 531{
532 int rc; 532 int rc;
533 unsigned int offset = CIFS_SESS_KEY_SIZE + 8; 533 unsigned int offset = CIFS_SESS_KEY_SIZE + 8;
@@ -563,7 +563,7 @@ CalcNTLMv2_response(const struct cifsSesInfo *ses, char *ntlmv2_hash)
563 563
564 564
565int 565int
566setup_ntlmv2_rsp(struct cifsSesInfo *ses, const struct nls_table *nls_cp) 566setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
567{ 567{
568 int rc; 568 int rc;
569 int baselen; 569 int baselen;
@@ -649,7 +649,7 @@ setup_ntlmv2_rsp_ret:
649} 649}
650 650
651int 651int
652calc_seckey(struct cifsSesInfo *ses) 652calc_seckey(struct cifs_ses *ses)
653{ 653{
654 int rc; 654 int rc;
655 struct crypto_blkcipher *tfm_arc4; 655 struct crypto_blkcipher *tfm_arc4;
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 493b74ca5648..989442dcfb45 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -104,46 +104,25 @@ cifs_sb_deactive(struct super_block *sb)
104} 104}
105 105
106static int 106static int
107cifs_read_super(struct super_block *sb, void *data, 107cifs_read_super(struct super_block *sb, struct smb_vol *volume_info,
108 const char *devname, int silent) 108 const char *devname, int silent)
109{ 109{
110 struct inode *inode; 110 struct inode *inode;
111 struct cifs_sb_info *cifs_sb; 111 struct cifs_sb_info *cifs_sb;
112 int rc = 0; 112 int rc = 0;
113 113
114 /* BB should we make this contingent on mount parm? */
115 sb->s_flags |= MS_NODIRATIME | MS_NOATIME;
116 sb->s_fs_info = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL);
117 cifs_sb = CIFS_SB(sb); 114 cifs_sb = CIFS_SB(sb);
118 if (cifs_sb == NULL)
119 return -ENOMEM;
120 115
121 spin_lock_init(&cifs_sb->tlink_tree_lock); 116 spin_lock_init(&cifs_sb->tlink_tree_lock);
122 cifs_sb->tlink_tree = RB_ROOT; 117 cifs_sb->tlink_tree = RB_ROOT;
123 118
124 rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY); 119 rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY);
125 if (rc) { 120 if (rc)
126 kfree(cifs_sb);
127 return rc; 121 return rc;
128 }
129 cifs_sb->bdi.ra_pages = default_backing_dev_info.ra_pages;
130 122
131 /* 123 cifs_sb->bdi.ra_pages = default_backing_dev_info.ra_pages;
132 * Copy mount params to sb for use in submounts. Better to do
133 * the copy here and deal with the error before cleanup gets
134 * complicated post-mount.
135 */
136 if (data) {
137 cifs_sb->mountdata = kstrndup(data, PAGE_SIZE, GFP_KERNEL);
138 if (cifs_sb->mountdata == NULL) {
139 bdi_destroy(&cifs_sb->bdi);
140 kfree(sb->s_fs_info);
141 sb->s_fs_info = NULL;
142 return -ENOMEM;
143 }
144 }
145 124
146 rc = cifs_mount(sb, cifs_sb, devname); 125 rc = cifs_mount(sb, cifs_sb, volume_info, devname);
147 126
148 if (rc) { 127 if (rc) {
149 if (!silent) 128 if (!silent)
@@ -194,15 +173,7 @@ out_no_root:
194 cifs_umount(sb, cifs_sb); 173 cifs_umount(sb, cifs_sb);
195 174
196out_mount_failed: 175out_mount_failed:
197 if (cifs_sb) { 176 bdi_destroy(&cifs_sb->bdi);
198 if (cifs_sb->mountdata) {
199 kfree(cifs_sb->mountdata);
200 cifs_sb->mountdata = NULL;
201 }
202 unload_nls(cifs_sb->local_nls);
203 bdi_destroy(&cifs_sb->bdi);
204 kfree(cifs_sb);
205 }
206 return rc; 177 return rc;
207} 178}
208 179
@@ -237,7 +208,7 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
237{ 208{
238 struct super_block *sb = dentry->d_sb; 209 struct super_block *sb = dentry->d_sb;
239 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 210 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
240 struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); 211 struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
241 int rc = -EOPNOTSUPP; 212 int rc = -EOPNOTSUPP;
242 int xid; 213 int xid;
243 214
@@ -390,7 +361,7 @@ static int
390cifs_show_options(struct seq_file *s, struct vfsmount *m) 361cifs_show_options(struct seq_file *s, struct vfsmount *m)
391{ 362{
392 struct cifs_sb_info *cifs_sb = CIFS_SB(m->mnt_sb); 363 struct cifs_sb_info *cifs_sb = CIFS_SB(m->mnt_sb);
393 struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); 364 struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
394 struct sockaddr *srcaddr; 365 struct sockaddr *srcaddr;
395 srcaddr = (struct sockaddr *)&tcon->ses->server->srcaddr; 366 srcaddr = (struct sockaddr *)&tcon->ses->server->srcaddr;
396 367
@@ -444,14 +415,20 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
444 seq_printf(s, ",nocase"); 415 seq_printf(s, ",nocase");
445 if (tcon->retry) 416 if (tcon->retry)
446 seq_printf(s, ",hard"); 417 seq_printf(s, ",hard");
447 if (cifs_sb->prepath) 418 if (tcon->unix_ext)
448 seq_printf(s, ",prepath=%s", cifs_sb->prepath); 419 seq_printf(s, ",unix");
420 else
421 seq_printf(s, ",nounix");
449 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) 422 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
450 seq_printf(s, ",posixpaths"); 423 seq_printf(s, ",posixpaths");
451 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) 424 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)
452 seq_printf(s, ",setuids"); 425 seq_printf(s, ",setuids");
453 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) 426 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
454 seq_printf(s, ",serverino"); 427 seq_printf(s, ",serverino");
428 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
429 seq_printf(s, ",rwpidforward");
430 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL)
431 seq_printf(s, ",forcemand");
455 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) 432 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
456 seq_printf(s, ",directio"); 433 seq_printf(s, ",directio");
457 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) 434 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
@@ -484,7 +461,7 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
484static void cifs_umount_begin(struct super_block *sb) 461static void cifs_umount_begin(struct super_block *sb)
485{ 462{
486 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 463 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
487 struct cifsTconInfo *tcon; 464 struct cifs_tcon *tcon;
488 465
489 if (cifs_sb == NULL) 466 if (cifs_sb == NULL)
490 return; 467 return;
@@ -559,29 +536,189 @@ static const struct super_operations cifs_super_ops = {
559#endif 536#endif
560}; 537};
561 538
539/*
540 * Get root dentry from superblock according to prefix path mount option.
541 * Return dentry with refcount + 1 on success and NULL otherwise.
542 */
543static struct dentry *
544cifs_get_root(struct smb_vol *vol, struct super_block *sb)
545{
546 int xid, rc;
547 struct inode *inode;
548 struct qstr name;
549 struct dentry *dparent = NULL, *dchild = NULL, *alias;
550 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
551 unsigned int i, full_len, len;
552 char *full_path = NULL, *pstart;
553 char sep;
554
555 full_path = cifs_build_path_to_root(vol, cifs_sb,
556 cifs_sb_master_tcon(cifs_sb));
557 if (full_path == NULL)
558 return NULL;
559
560 cFYI(1, "Get root dentry for %s", full_path);
561
562 xid = GetXid();
563 sep = CIFS_DIR_SEP(cifs_sb);
564 dparent = dget(sb->s_root);
565 full_len = strlen(full_path);
566 full_path[full_len] = sep;
567 pstart = full_path + 1;
568
569 for (i = 1, len = 0; i <= full_len; i++) {
570 if (full_path[i] != sep || !len) {
571 len++;
572 continue;
573 }
574
575 full_path[i] = 0;
576 cFYI(1, "get dentry for %s", pstart);
577
578 name.name = pstart;
579 name.len = len;
580 name.hash = full_name_hash(pstart, len);
581 dchild = d_lookup(dparent, &name);
582 if (dchild == NULL) {
583 cFYI(1, "not exists");
584 dchild = d_alloc(dparent, &name);
585 if (dchild == NULL) {
586 dput(dparent);
587 dparent = NULL;
588 goto out;
589 }
590 }
591
592 cFYI(1, "get inode");
593 if (dchild->d_inode == NULL) {
594 cFYI(1, "not exists");
595 inode = NULL;
596 if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext)
597 rc = cifs_get_inode_info_unix(&inode, full_path,
598 sb, xid);
599 else
600 rc = cifs_get_inode_info(&inode, full_path,
601 NULL, sb, xid, NULL);
602 if (rc) {
603 dput(dchild);
604 dput(dparent);
605 dparent = NULL;
606 goto out;
607 }
608 alias = d_materialise_unique(dchild, inode);
609 if (alias != NULL) {
610 dput(dchild);
611 if (IS_ERR(alias)) {
612 dput(dparent);
613 dparent = NULL;
614 goto out;
615 }
616 dchild = alias;
617 }
618 }
619 cFYI(1, "parent %p, child %p", dparent, dchild);
620
621 dput(dparent);
622 dparent = dchild;
623 len = 0;
624 pstart = full_path + i + 1;
625 full_path[i] = sep;
626 }
627out:
628 _FreeXid(xid);
629 kfree(full_path);
630 return dparent;
631}
632
562static struct dentry * 633static struct dentry *
563cifs_do_mount(struct file_system_type *fs_type, 634cifs_do_mount(struct file_system_type *fs_type,
564 int flags, const char *dev_name, void *data) 635 int flags, const char *dev_name, void *data)
565{ 636{
566 int rc; 637 int rc;
567 struct super_block *sb; 638 struct super_block *sb;
568 639 struct cifs_sb_info *cifs_sb;
569 sb = sget(fs_type, NULL, set_anon_super, NULL); 640 struct smb_vol *volume_info;
641 struct cifs_mnt_data mnt_data;
642 struct dentry *root;
570 643
571 cFYI(1, "Devname: %s flags: %d ", dev_name, flags); 644 cFYI(1, "Devname: %s flags: %d ", dev_name, flags);
572 645
573 if (IS_ERR(sb)) 646 rc = cifs_setup_volume_info(&volume_info, (char *)data, dev_name);
574 return ERR_CAST(sb); 647 if (rc)
648 return ERR_PTR(rc);
649
650 cifs_sb = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL);
651 if (cifs_sb == NULL) {
652 root = ERR_PTR(-ENOMEM);
653 goto out;
654 }
655
656 cifs_setup_cifs_sb(volume_info, cifs_sb);
657
658 mnt_data.vol = volume_info;
659 mnt_data.cifs_sb = cifs_sb;
660 mnt_data.flags = flags;
661
662 sb = sget(fs_type, cifs_match_super, set_anon_super, &mnt_data);
663 if (IS_ERR(sb)) {
664 root = ERR_CAST(sb);
665 goto out_cifs_sb;
666 }
667
668 if (sb->s_fs_info) {
669 cFYI(1, "Use existing superblock");
670 goto out_shared;
671 }
672
673 /*
674 * Copy mount params for use in submounts. Better to do
675 * the copy here and deal with the error before cleanup gets
676 * complicated post-mount.
677 */
678 cifs_sb->mountdata = kstrndup(data, PAGE_SIZE, GFP_KERNEL);
679 if (cifs_sb->mountdata == NULL) {
680 root = ERR_PTR(-ENOMEM);
681 goto out_super;
682 }
575 683
576 sb->s_flags = flags; 684 sb->s_flags = flags;
685 /* BB should we make this contingent on mount parm? */
686 sb->s_flags |= MS_NODIRATIME | MS_NOATIME;
687 sb->s_fs_info = cifs_sb;
577 688
578 rc = cifs_read_super(sb, data, dev_name, flags & MS_SILENT ? 1 : 0); 689 rc = cifs_read_super(sb, volume_info, dev_name,
690 flags & MS_SILENT ? 1 : 0);
579 if (rc) { 691 if (rc) {
580 deactivate_locked_super(sb); 692 root = ERR_PTR(rc);
581 return ERR_PTR(rc); 693 goto out_super;
582 } 694 }
695
583 sb->s_flags |= MS_ACTIVE; 696 sb->s_flags |= MS_ACTIVE;
584 return dget(sb->s_root); 697
698 root = cifs_get_root(volume_info, sb);
699 if (root == NULL)
700 goto out_super;
701
702 cFYI(1, "dentry root is: %p", root);
703 goto out;
704
705out_shared:
706 root = cifs_get_root(volume_info, sb);
707 if (root)
708 cFYI(1, "dentry root is: %p", root);
709 goto out;
710
711out_super:
712 kfree(cifs_sb->mountdata);
713 deactivate_locked_super(sb);
714
715out_cifs_sb:
716 unload_nls(cifs_sb->local_nls);
717 kfree(cifs_sb);
718
719out:
720 cifs_cleanup_volume_info(&volume_info);
721 return root;
585} 722}
586 723
587static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, 724static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 76b4517e74b0..6255fa812c7a 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -155,6 +155,81 @@ struct cifs_cred {
155 ***************************************************************** 155 *****************************************************************
156 */ 156 */
157 157
158struct smb_vol {
159 char *username;
160 char *password;
161 char *domainname;
162 char *UNC;
163 char *UNCip;
164 char *iocharset; /* local code page for mapping to and from Unicode */
165 char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */
166 char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */
167 uid_t cred_uid;
168 uid_t linux_uid;
169 gid_t linux_gid;
170 mode_t file_mode;
171 mode_t dir_mode;
172 unsigned secFlg;
173 bool retry:1;
174 bool intr:1;
175 bool setuids:1;
176 bool override_uid:1;
177 bool override_gid:1;
178 bool dynperm:1;
179 bool noperm:1;
180 bool no_psx_acl:1; /* set if posix acl support should be disabled */
181 bool cifs_acl:1;
182 bool no_xattr:1; /* set if xattr (EA) support should be disabled*/
183 bool server_ino:1; /* use inode numbers from server ie UniqueId */
184 bool direct_io:1;
185 bool strict_io:1; /* strict cache behavior */
186 bool remap:1; /* set to remap seven reserved chars in filenames */
187 bool posix_paths:1; /* unset to not ask for posix pathnames. */
188 bool no_linux_ext:1;
189 bool sfu_emul:1;
190 bool nullauth:1; /* attempt to authenticate with null user */
191 bool nocase:1; /* request case insensitive filenames */
192 bool nobrl:1; /* disable sending byte range locks to srv */
193 bool mand_lock:1; /* send mandatory not posix byte range lock reqs */
194 bool seal:1; /* request transport encryption on share */
195 bool nodfs:1; /* Do not request DFS, even if available */
196 bool local_lease:1; /* check leases only on local system, not remote */
197 bool noblocksnd:1;
198 bool noautotune:1;
199 bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
200 bool fsc:1; /* enable fscache */
201 bool mfsymlinks:1; /* use Minshall+French Symlinks */
202 bool multiuser:1;
203 bool rwpidforward:1; /* pid forward for read/write operations */
204 unsigned int rsize;
205 unsigned int wsize;
206 bool sockopt_tcp_nodelay:1;
207 unsigned short int port;
208 unsigned long actimeo; /* attribute cache timeout (jiffies) */
209 char *prepath;
210 struct sockaddr_storage srcaddr; /* allow binding to a local IP */
211 struct nls_table *local_nls;
212};
213
214#define CIFS_MOUNT_MASK (CIFS_MOUNT_NO_PERM | CIFS_MOUNT_SET_UID | \
215 CIFS_MOUNT_SERVER_INUM | CIFS_MOUNT_DIRECT_IO | \
216 CIFS_MOUNT_NO_XATTR | CIFS_MOUNT_MAP_SPECIAL_CHR | \
217 CIFS_MOUNT_UNX_EMUL | CIFS_MOUNT_NO_BRL | \
218 CIFS_MOUNT_CIFS_ACL | CIFS_MOUNT_OVERR_UID | \
219 CIFS_MOUNT_OVERR_GID | CIFS_MOUNT_DYNPERM | \
220 CIFS_MOUNT_NOPOSIXBRL | CIFS_MOUNT_NOSSYNC | \
221 CIFS_MOUNT_FSCACHE | CIFS_MOUNT_MF_SYMLINKS | \
222 CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_STRICT_IO)
223
224#define CIFS_MS_MASK (MS_RDONLY | MS_MANDLOCK | MS_NOEXEC | MS_NOSUID | \
225 MS_NODEV | MS_SYNCHRONOUS)
226
227struct cifs_mnt_data {
228 struct cifs_sb_info *cifs_sb;
229 struct smb_vol *vol;
230 int flags;
231};
232
158struct TCP_Server_Info { 233struct TCP_Server_Info {
159 struct list_head tcp_ses_list; 234 struct list_head tcp_ses_list;
160 struct list_head smb_ses_list; 235 struct list_head smb_ses_list;
@@ -179,7 +254,7 @@ struct TCP_Server_Info {
179 struct mutex srv_mutex; 254 struct mutex srv_mutex;
180 struct task_struct *tsk; 255 struct task_struct *tsk;
181 char server_GUID[16]; 256 char server_GUID[16];
182 char secMode; 257 char sec_mode;
183 bool session_estab; /* mark when very first sess is established */ 258 bool session_estab; /* mark when very first sess is established */
184 u16 dialect; /* dialect index that server chose */ 259 u16 dialect; /* dialect index that server chose */
185 enum securityEnum secType; 260 enum securityEnum secType;
@@ -254,7 +329,7 @@ static inline void cifs_set_net_ns(struct TCP_Server_Info *srv, struct net *net)
254/* 329/*
255 * Session structure. One of these for each uid session with a particular host 330 * Session structure. One of these for each uid session with a particular host
256 */ 331 */
257struct cifsSesInfo { 332struct cifs_ses {
258 struct list_head smb_ses_list; 333 struct list_head smb_ses_list;
259 struct list_head tcon_list; 334 struct list_head tcon_list;
260 struct mutex session_mutex; 335 struct mutex session_mutex;
@@ -294,11 +369,11 @@ struct cifsSesInfo {
294 * there is one of these for each connection to a resource on a particular 369 * there is one of these for each connection to a resource on a particular
295 * session 370 * session
296 */ 371 */
297struct cifsTconInfo { 372struct cifs_tcon {
298 struct list_head tcon_list; 373 struct list_head tcon_list;
299 int tc_count; 374 int tc_count;
300 struct list_head openFileList; 375 struct list_head openFileList;
301 struct cifsSesInfo *ses; /* pointer to session associated with */ 376 struct cifs_ses *ses; /* pointer to session associated with */
302 char treeName[MAX_TREE_SIZE + 1]; /* UNC name of resource in ASCII */ 377 char treeName[MAX_TREE_SIZE + 1]; /* UNC name of resource in ASCII */
303 char *nativeFileSystem; 378 char *nativeFileSystem;
304 char *password; /* for share-level security */ 379 char *password; /* for share-level security */
@@ -380,12 +455,12 @@ struct tcon_link {
380#define TCON_LINK_IN_TREE 2 455#define TCON_LINK_IN_TREE 2
381 unsigned long tl_time; 456 unsigned long tl_time;
382 atomic_t tl_count; 457 atomic_t tl_count;
383 struct cifsTconInfo *tl_tcon; 458 struct cifs_tcon *tl_tcon;
384}; 459};
385 460
386extern struct tcon_link *cifs_sb_tlink(struct cifs_sb_info *cifs_sb); 461extern struct tcon_link *cifs_sb_tlink(struct cifs_sb_info *cifs_sb);
387 462
388static inline struct cifsTconInfo * 463static inline struct cifs_tcon *
389tlink_tcon(struct tcon_link *tlink) 464tlink_tcon(struct tcon_link *tlink)
390{ 465{
391 return tlink->tl_tcon; 466 return tlink->tl_tcon;
@@ -402,7 +477,7 @@ cifs_get_tlink(struct tcon_link *tlink)
402} 477}
403 478
404/* This function is always expected to succeed */ 479/* This function is always expected to succeed */
405extern struct cifsTconInfo *cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb); 480extern struct cifs_tcon *cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb);
406 481
407/* 482/*
408 * This info hangs off the cifsFileInfo structure, pointed to by llist. 483 * This info hangs off the cifsFileInfo structure, pointed to by llist.
@@ -455,6 +530,14 @@ struct cifsFileInfo {
455 struct work_struct oplock_break; /* work for oplock breaks */ 530 struct work_struct oplock_break; /* work for oplock breaks */
456}; 531};
457 532
533struct cifs_io_parms {
534 __u16 netfid;
535 __u32 pid;
536 __u64 offset;
537 unsigned int length;
538 struct cifs_tcon *tcon;
539};
540
458/* 541/*
459 * Take a reference on the file private data. Must be called with 542 * Take a reference on the file private data. Must be called with
460 * cifs_file_list_lock held. 543 * cifs_file_list_lock held.
@@ -509,10 +592,30 @@ static inline char CIFS_DIR_SEP(const struct cifs_sb_info *cifs_sb)
509 return '\\'; 592 return '\\';
510} 593}
511 594
595static inline void
596convert_delimiter(char *path, char delim)
597{
598 int i;
599 char old_delim;
600
601 if (path == NULL)
602 return;
603
604 if (delim == '/')
605 old_delim = '\\';
606 else
607 old_delim = '/';
608
609 for (i = 0; path[i] != '\0'; i++) {
610 if (path[i] == old_delim)
611 path[i] = delim;
612 }
613}
614
512#ifdef CONFIG_CIFS_STATS 615#ifdef CONFIG_CIFS_STATS
513#define cifs_stats_inc atomic_inc 616#define cifs_stats_inc atomic_inc
514 617
515static inline void cifs_stats_bytes_written(struct cifsTconInfo *tcon, 618static inline void cifs_stats_bytes_written(struct cifs_tcon *tcon,
516 unsigned int bytes) 619 unsigned int bytes)
517{ 620{
518 if (bytes) { 621 if (bytes) {
@@ -522,7 +625,7 @@ static inline void cifs_stats_bytes_written(struct cifsTconInfo *tcon,
522 } 625 }
523} 626}
524 627
525static inline void cifs_stats_bytes_read(struct cifsTconInfo *tcon, 628static inline void cifs_stats_bytes_read(struct cifs_tcon *tcon,
526 unsigned int bytes) 629 unsigned int bytes)
527{ 630{
528 spin_lock(&tcon->stat_lock); 631 spin_lock(&tcon->stat_lock);
@@ -543,9 +646,8 @@ struct mid_q_entry;
543 * This is the prototype for the mid callback function. When creating one, 646 * This is the prototype for the mid callback function. When creating one,
544 * take special care to avoid deadlocks. Things to bear in mind: 647 * take special care to avoid deadlocks. Things to bear in mind:
545 * 648 *
546 * - it will be called by cifsd 649 * - it will be called by cifsd, with no locks held
547 * - the GlobalMid_Lock will be held 650 * - the mid will be removed from any lists
548 * - the mid will be removed from the pending_mid_q list
549 */ 651 */
550typedef void (mid_callback_t)(struct mid_q_entry *mid); 652typedef void (mid_callback_t)(struct mid_q_entry *mid);
551 653
@@ -573,7 +675,7 @@ struct mid_q_entry {
573struct oplock_q_entry { 675struct oplock_q_entry {
574 struct list_head qhead; 676 struct list_head qhead;
575 struct inode *pinode; 677 struct inode *pinode;
576 struct cifsTconInfo *tcon; 678 struct cifs_tcon *tcon;
577 __u16 netfid; 679 __u16 netfid;
578}; 680};
579 681
@@ -656,6 +758,7 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param,
656#define MID_RESPONSE_RECEIVED 4 758#define MID_RESPONSE_RECEIVED 4
657#define MID_RETRY_NEEDED 8 /* session closed while this request out */ 759#define MID_RETRY_NEEDED 8 /* session closed while this request out */
658#define MID_RESPONSE_MALFORMED 0x10 760#define MID_RESPONSE_MALFORMED 0x10
761#define MID_SHUTDOWN 0x20
659 762
660/* Types of response buffer returned from SendReceive2 */ 763/* Types of response buffer returned from SendReceive2 */
661#define CIFS_NO_BUFFER 0 /* Response buffer not returned */ 764#define CIFS_NO_BUFFER 0 /* Response buffer not returned */
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 6e69e06a30b3..953f84413c77 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -57,8 +57,9 @@ extern int init_cifs_idmap(void);
57extern void exit_cifs_idmap(void); 57extern void exit_cifs_idmap(void);
58extern void cifs_destroy_idmaptrees(void); 58extern void cifs_destroy_idmaptrees(void);
59extern char *build_path_from_dentry(struct dentry *); 59extern char *build_path_from_dentry(struct dentry *);
60extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb, 60extern char *cifs_build_path_to_root(struct smb_vol *vol,
61 struct cifsTconInfo *tcon); 61 struct cifs_sb_info *cifs_sb,
62 struct cifs_tcon *tcon);
62extern char *build_wildcard_path_from_dentry(struct dentry *direntry); 63extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
63extern char *cifs_compose_mount_options(const char *sb_mountdata, 64extern char *cifs_compose_mount_options(const char *sb_mountdata,
64 const char *fullpath, const struct dfs_info3_param *ref, 65 const char *fullpath, const struct dfs_info3_param *ref,
@@ -67,20 +68,22 @@ extern char *cifs_compose_mount_options(const char *sb_mountdata,
67extern struct mid_q_entry *AllocMidQEntry(const struct smb_hdr *smb_buffer, 68extern struct mid_q_entry *AllocMidQEntry(const struct smb_hdr *smb_buffer,
68 struct TCP_Server_Info *server); 69 struct TCP_Server_Info *server);
69extern void DeleteMidQEntry(struct mid_q_entry *midEntry); 70extern void DeleteMidQEntry(struct mid_q_entry *midEntry);
70extern int cifs_call_async(struct TCP_Server_Info *server, 71extern int cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov,
71 struct smb_hdr *in_buf, mid_callback_t *callback, 72 unsigned int nvec, mid_callback_t *callback,
72 void *cbdata); 73 void *cbdata, bool ignore_pend);
73extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *, 74extern int SendReceive(const unsigned int /* xid */ , struct cifs_ses *,
74 struct smb_hdr * /* input */ , 75 struct smb_hdr * /* input */ ,
75 struct smb_hdr * /* out */ , 76 struct smb_hdr * /* out */ ,
76 int * /* bytes returned */ , const int long_op); 77 int * /* bytes returned */ , const int long_op);
77extern int SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses, 78extern int SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses,
78 struct smb_hdr *in_buf, int flags); 79 struct smb_hdr *in_buf, int flags);
79extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *, 80extern int cifs_check_receive(struct mid_q_entry *mid,
81 struct TCP_Server_Info *server, bool log_error);
82extern int SendReceive2(const unsigned int /* xid */ , struct cifs_ses *,
80 struct kvec *, int /* nvec to send */, 83 struct kvec *, int /* nvec to send */,
81 int * /* type of buf returned */ , const int flags); 84 int * /* type of buf returned */ , const int flags);
82extern int SendReceiveBlockingLock(const unsigned int xid, 85extern int SendReceiveBlockingLock(const unsigned int xid,
83 struct cifsTconInfo *ptcon, 86 struct cifs_tcon *ptcon,
84 struct smb_hdr *in_buf , 87 struct smb_hdr *in_buf ,
85 struct smb_hdr *out_buf, 88 struct smb_hdr *out_buf,
86 int *bytes_returned); 89 int *bytes_returned);
@@ -99,14 +102,14 @@ extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len);
99extern int cifs_set_port(struct sockaddr *addr, const unsigned short int port); 102extern int cifs_set_port(struct sockaddr *addr, const unsigned short int port);
100extern int cifs_fill_sockaddr(struct sockaddr *dst, const char *src, int len, 103extern int cifs_fill_sockaddr(struct sockaddr *dst, const char *src, int len,
101 const unsigned short int port); 104 const unsigned short int port);
102extern int map_smb_to_linux_error(struct smb_hdr *smb, int logErr); 105extern int map_smb_to_linux_error(struct smb_hdr *smb, bool logErr);
103extern void header_assemble(struct smb_hdr *, char /* command */ , 106extern void header_assemble(struct smb_hdr *, char /* command */ ,
104 const struct cifsTconInfo *, int /* length of 107 const struct cifs_tcon *, int /* length of
105 fixed section (word count) in two byte units */); 108 fixed section (word count) in two byte units */);
106extern int small_smb_init_no_tc(const int smb_cmd, const int wct, 109extern int small_smb_init_no_tc(const int smb_cmd, const int wct,
107 struct cifsSesInfo *ses, 110 struct cifs_ses *ses,
108 void **request_buf); 111 void **request_buf);
109extern int CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, 112extern int CIFS_SessSetup(unsigned int xid, struct cifs_ses *ses,
110 const struct nls_table *nls_cp); 113 const struct nls_table *nls_cp);
111extern __u16 GetNextMid(struct TCP_Server_Info *server); 114extern __u16 GetNextMid(struct TCP_Server_Info *server);
112extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601); 115extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601);
@@ -148,102 +151,108 @@ extern struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *, struct inode *,
148extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *, 151extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *,
149 const char *); 152 const char *);
150 153
154extern void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
155 struct cifs_sb_info *cifs_sb);
156extern int cifs_match_super(struct super_block *, void *);
157extern void cifs_cleanup_volume_info(struct smb_vol **pvolume_info);
158extern int cifs_setup_volume_info(struct smb_vol **pvolume_info,
159 char *mount_data, const char *devname);
151extern int cifs_mount(struct super_block *, struct cifs_sb_info *, 160extern int cifs_mount(struct super_block *, struct cifs_sb_info *,
152 const char *); 161 struct smb_vol *, const char *);
153extern int cifs_umount(struct super_block *, struct cifs_sb_info *); 162extern int cifs_umount(struct super_block *, struct cifs_sb_info *);
154extern void cifs_dfs_release_automount_timer(void); 163extern void cifs_dfs_release_automount_timer(void);
155void cifs_proc_init(void); 164void cifs_proc_init(void);
156void cifs_proc_clean(void); 165void cifs_proc_clean(void);
157 166
158extern int cifs_negotiate_protocol(unsigned int xid, 167extern int cifs_negotiate_protocol(unsigned int xid,
159 struct cifsSesInfo *ses); 168 struct cifs_ses *ses);
160extern int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses, 169extern int cifs_setup_session(unsigned int xid, struct cifs_ses *ses,
161 struct nls_table *nls_info); 170 struct nls_table *nls_info);
162extern int CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses); 171extern int CIFSSMBNegotiate(unsigned int xid, struct cifs_ses *ses);
163 172
164extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, 173extern int CIFSTCon(unsigned int xid, struct cifs_ses *ses,
165 const char *tree, struct cifsTconInfo *tcon, 174 const char *tree, struct cifs_tcon *tcon,
166 const struct nls_table *); 175 const struct nls_table *);
167 176
168extern int CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, 177extern int CIFSFindFirst(const int xid, struct cifs_tcon *tcon,
169 const char *searchName, const struct nls_table *nls_codepage, 178 const char *searchName, const struct nls_table *nls_codepage,
170 __u16 *searchHandle, struct cifs_search_info *psrch_inf, 179 __u16 *searchHandle, struct cifs_search_info *psrch_inf,
171 int map, const char dirsep); 180 int map, const char dirsep);
172 181
173extern int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, 182extern int CIFSFindNext(const int xid, struct cifs_tcon *tcon,
174 __u16 searchHandle, struct cifs_search_info *psrch_inf); 183 __u16 searchHandle, struct cifs_search_info *psrch_inf);
175 184
176extern int CIFSFindClose(const int, struct cifsTconInfo *tcon, 185extern int CIFSFindClose(const int, struct cifs_tcon *tcon,
177 const __u16 search_handle); 186 const __u16 search_handle);
178 187
179extern int CIFSSMBQFileInfo(const int xid, struct cifsTconInfo *tcon, 188extern int CIFSSMBQFileInfo(const int xid, struct cifs_tcon *tcon,
180 u16 netfid, FILE_ALL_INFO *pFindData); 189 u16 netfid, FILE_ALL_INFO *pFindData);
181extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, 190extern int CIFSSMBQPathInfo(const int xid, struct cifs_tcon *tcon,
182 const unsigned char *searchName, 191 const unsigned char *searchName,
183 FILE_ALL_INFO *findData, 192 FILE_ALL_INFO *findData,
184 int legacy /* whether to use old info level */, 193 int legacy /* whether to use old info level */,
185 const struct nls_table *nls_codepage, int remap); 194 const struct nls_table *nls_codepage, int remap);
186extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, 195extern int SMBQueryInformation(const int xid, struct cifs_tcon *tcon,
187 const unsigned char *searchName, 196 const unsigned char *searchName,
188 FILE_ALL_INFO *findData, 197 FILE_ALL_INFO *findData,
189 const struct nls_table *nls_codepage, int remap); 198 const struct nls_table *nls_codepage, int remap);
190 199
191extern int CIFSSMBUnixQFileInfo(const int xid, struct cifsTconInfo *tcon, 200extern int CIFSSMBUnixQFileInfo(const int xid, struct cifs_tcon *tcon,
192 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData); 201 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData);
193extern int CIFSSMBUnixQPathInfo(const int xid, 202extern int CIFSSMBUnixQPathInfo(const int xid,
194 struct cifsTconInfo *tcon, 203 struct cifs_tcon *tcon,
195 const unsigned char *searchName, 204 const unsigned char *searchName,
196 FILE_UNIX_BASIC_INFO *pFindData, 205 FILE_UNIX_BASIC_INFO *pFindData,
197 const struct nls_table *nls_codepage, int remap); 206 const struct nls_table *nls_codepage, int remap);
198 207
199extern int CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, 208extern int CIFSGetDFSRefer(const int xid, struct cifs_ses *ses,
200 const unsigned char *searchName, 209 const unsigned char *searchName,
201 struct dfs_info3_param **target_nodes, 210 struct dfs_info3_param **target_nodes,
202 unsigned int *number_of_nodes_in_array, 211 unsigned int *number_of_nodes_in_array,
203 const struct nls_table *nls_codepage, int remap); 212 const struct nls_table *nls_codepage, int remap);
204 213
205extern int get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, 214extern int get_dfs_path(int xid, struct cifs_ses *pSesInfo,
206 const char *old_path, 215 const char *old_path,
207 const struct nls_table *nls_codepage, 216 const struct nls_table *nls_codepage,
208 unsigned int *pnum_referrals, 217 unsigned int *pnum_referrals,
209 struct dfs_info3_param **preferrals, 218 struct dfs_info3_param **preferrals,
210 int remap); 219 int remap);
211extern void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, 220extern void reset_cifs_unix_caps(int xid, struct cifs_tcon *tcon,
212 struct super_block *sb, struct smb_vol *vol); 221 struct super_block *sb, struct smb_vol *vol);
213extern int CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, 222extern int CIFSSMBQFSInfo(const int xid, struct cifs_tcon *tcon,
214 struct kstatfs *FSData); 223 struct kstatfs *FSData);
215extern int SMBOldQFSInfo(const int xid, struct cifsTconInfo *tcon, 224extern int SMBOldQFSInfo(const int xid, struct cifs_tcon *tcon,
216 struct kstatfs *FSData); 225 struct kstatfs *FSData);
217extern int CIFSSMBSetFSUnixInfo(const int xid, struct cifsTconInfo *tcon, 226extern int CIFSSMBSetFSUnixInfo(const int xid, struct cifs_tcon *tcon,
218 __u64 cap); 227 __u64 cap);
219 228
220extern int CIFSSMBQFSAttributeInfo(const int xid, 229extern int CIFSSMBQFSAttributeInfo(const int xid,
221 struct cifsTconInfo *tcon); 230 struct cifs_tcon *tcon);
222extern int CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon); 231extern int CIFSSMBQFSDeviceInfo(const int xid, struct cifs_tcon *tcon);
223extern int CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon); 232extern int CIFSSMBQFSUnixInfo(const int xid, struct cifs_tcon *tcon);
224extern int CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon, 233extern int CIFSSMBQFSPosixInfo(const int xid, struct cifs_tcon *tcon,
225 struct kstatfs *FSData); 234 struct kstatfs *FSData);
226 235
227extern int CIFSSMBSetPathInfo(const int xid, struct cifsTconInfo *tcon, 236extern int CIFSSMBSetPathInfo(const int xid, struct cifs_tcon *tcon,
228 const char *fileName, const FILE_BASIC_INFO *data, 237 const char *fileName, const FILE_BASIC_INFO *data,
229 const struct nls_table *nls_codepage, 238 const struct nls_table *nls_codepage,
230 int remap_special_chars); 239 int remap_special_chars);
231extern int CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon, 240extern int CIFSSMBSetFileInfo(const int xid, struct cifs_tcon *tcon,
232 const FILE_BASIC_INFO *data, __u16 fid, 241 const FILE_BASIC_INFO *data, __u16 fid,
233 __u32 pid_of_opener); 242 __u32 pid_of_opener);
234extern int CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon, 243extern int CIFSSMBSetFileDisposition(const int xid, struct cifs_tcon *tcon,
235 bool delete_file, __u16 fid, __u32 pid_of_opener); 244 bool delete_file, __u16 fid, __u32 pid_of_opener);
236#if 0 245#if 0
237extern int CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon, 246extern int CIFSSMBSetAttrLegacy(int xid, struct cifs_tcon *tcon,
238 char *fileName, __u16 dos_attributes, 247 char *fileName, __u16 dos_attributes,
239 const struct nls_table *nls_codepage); 248 const struct nls_table *nls_codepage);
240#endif /* possibly unneeded function */ 249#endif /* possibly unneeded function */
241extern int CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, 250extern int CIFSSMBSetEOF(const int xid, struct cifs_tcon *tcon,
242 const char *fileName, __u64 size, 251 const char *fileName, __u64 size,
243 bool setAllocationSizeFlag, 252 bool setAllocationSizeFlag,
244 const struct nls_table *nls_codepage, 253 const struct nls_table *nls_codepage,
245 int remap_special_chars); 254 int remap_special_chars);
246extern int CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, 255extern int CIFSSMBSetFileSize(const int xid, struct cifs_tcon *tcon,
247 __u64 size, __u16 fileHandle, __u32 opener_pid, 256 __u64 size, __u16 fileHandle, __u32 opener_pid,
248 bool AllocSizeFlag); 257 bool AllocSizeFlag);
249 258
@@ -257,120 +266,116 @@ struct cifs_unix_set_info_args {
257 dev_t device; 266 dev_t device;
258}; 267};
259 268
260extern int CIFSSMBUnixSetFileInfo(const int xid, struct cifsTconInfo *tcon, 269extern int CIFSSMBUnixSetFileInfo(const int xid, struct cifs_tcon *tcon,
261 const struct cifs_unix_set_info_args *args, 270 const struct cifs_unix_set_info_args *args,
262 u16 fid, u32 pid_of_opener); 271 u16 fid, u32 pid_of_opener);
263 272
264extern int CIFSSMBUnixSetPathInfo(const int xid, struct cifsTconInfo *pTcon, 273extern int CIFSSMBUnixSetPathInfo(const int xid, struct cifs_tcon *pTcon,
265 char *fileName, 274 char *fileName,
266 const struct cifs_unix_set_info_args *args, 275 const struct cifs_unix_set_info_args *args,
267 const struct nls_table *nls_codepage, 276 const struct nls_table *nls_codepage,
268 int remap_special_chars); 277 int remap_special_chars);
269 278
270extern int CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon, 279extern int CIFSSMBMkDir(const int xid, struct cifs_tcon *tcon,
271 const char *newName, 280 const char *newName,
272 const struct nls_table *nls_codepage, 281 const struct nls_table *nls_codepage,
273 int remap_special_chars); 282 int remap_special_chars);
274extern int CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon, 283extern int CIFSSMBRmDir(const int xid, struct cifs_tcon *tcon,
275 const char *name, const struct nls_table *nls_codepage, 284 const char *name, const struct nls_table *nls_codepage,
276 int remap_special_chars); 285 int remap_special_chars);
277extern int CIFSPOSIXDelFile(const int xid, struct cifsTconInfo *tcon, 286extern int CIFSPOSIXDelFile(const int xid, struct cifs_tcon *tcon,
278 const char *name, __u16 type, 287 const char *name, __u16 type,
279 const struct nls_table *nls_codepage, 288 const struct nls_table *nls_codepage,
280 int remap_special_chars); 289 int remap_special_chars);
281extern int CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon, 290extern int CIFSSMBDelFile(const int xid, struct cifs_tcon *tcon,
282 const char *name, 291 const char *name,
283 const struct nls_table *nls_codepage, 292 const struct nls_table *nls_codepage,
284 int remap_special_chars); 293 int remap_special_chars);
285extern int CIFSSMBRename(const int xid, struct cifsTconInfo *tcon, 294extern int CIFSSMBRename(const int xid, struct cifs_tcon *tcon,
286 const char *fromName, const char *toName, 295 const char *fromName, const char *toName,
287 const struct nls_table *nls_codepage, 296 const struct nls_table *nls_codepage,
288 int remap_special_chars); 297 int remap_special_chars);
289extern int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon, 298extern int CIFSSMBRenameOpenFile(const int xid, struct cifs_tcon *pTcon,
290 int netfid, const char *target_name, 299 int netfid, const char *target_name,
291 const struct nls_table *nls_codepage, 300 const struct nls_table *nls_codepage,
292 int remap_special_chars); 301 int remap_special_chars);
293extern int CIFSCreateHardLink(const int xid, 302extern int CIFSCreateHardLink(const int xid,
294 struct cifsTconInfo *tcon, 303 struct cifs_tcon *tcon,
295 const char *fromName, const char *toName, 304 const char *fromName, const char *toName,
296 const struct nls_table *nls_codepage, 305 const struct nls_table *nls_codepage,
297 int remap_special_chars); 306 int remap_special_chars);
298extern int CIFSUnixCreateHardLink(const int xid, 307extern int CIFSUnixCreateHardLink(const int xid,
299 struct cifsTconInfo *tcon, 308 struct cifs_tcon *tcon,
300 const char *fromName, const char *toName, 309 const char *fromName, const char *toName,
301 const struct nls_table *nls_codepage, 310 const struct nls_table *nls_codepage,
302 int remap_special_chars); 311 int remap_special_chars);
303extern int CIFSUnixCreateSymLink(const int xid, 312extern int CIFSUnixCreateSymLink(const int xid,
304 struct cifsTconInfo *tcon, 313 struct cifs_tcon *tcon,
305 const char *fromName, const char *toName, 314 const char *fromName, const char *toName,
306 const struct nls_table *nls_codepage); 315 const struct nls_table *nls_codepage);
307extern int CIFSSMBUnixQuerySymLink(const int xid, 316extern int CIFSSMBUnixQuerySymLink(const int xid,
308 struct cifsTconInfo *tcon, 317 struct cifs_tcon *tcon,
309 const unsigned char *searchName, char **syminfo, 318 const unsigned char *searchName, char **syminfo,
310 const struct nls_table *nls_codepage); 319 const struct nls_table *nls_codepage);
311#ifdef CONFIG_CIFS_SYMLINK_EXPERIMENTAL 320#ifdef CONFIG_CIFS_SYMLINK_EXPERIMENTAL
312extern int CIFSSMBQueryReparseLinkInfo(const int xid, 321extern int CIFSSMBQueryReparseLinkInfo(const int xid,
313 struct cifsTconInfo *tcon, 322 struct cifs_tcon *tcon,
314 const unsigned char *searchName, 323 const unsigned char *searchName,
315 char *symlinkinfo, const int buflen, __u16 fid, 324 char *symlinkinfo, const int buflen, __u16 fid,
316 const struct nls_table *nls_codepage); 325 const struct nls_table *nls_codepage);
317#endif /* temporarily unused until cifs_symlink fixed */ 326#endif /* temporarily unused until cifs_symlink fixed */
318extern int CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon, 327extern int CIFSSMBOpen(const int xid, struct cifs_tcon *tcon,
319 const char *fileName, const int disposition, 328 const char *fileName, const int disposition,
320 const int access_flags, const int omode, 329 const int access_flags, const int omode,
321 __u16 *netfid, int *pOplock, FILE_ALL_INFO *, 330 __u16 *netfid, int *pOplock, FILE_ALL_INFO *,
322 const struct nls_table *nls_codepage, int remap); 331 const struct nls_table *nls_codepage, int remap);
323extern int SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon, 332extern int SMBLegacyOpen(const int xid, struct cifs_tcon *tcon,
324 const char *fileName, const int disposition, 333 const char *fileName, const int disposition,
325 const int access_flags, const int omode, 334 const int access_flags, const int omode,
326 __u16 *netfid, int *pOplock, FILE_ALL_INFO *, 335 __u16 *netfid, int *pOplock, FILE_ALL_INFO *,
327 const struct nls_table *nls_codepage, int remap); 336 const struct nls_table *nls_codepage, int remap);
328extern int CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, 337extern int CIFSPOSIXCreate(const int xid, struct cifs_tcon *tcon,
329 u32 posix_flags, __u64 mode, __u16 *netfid, 338 u32 posix_flags, __u64 mode, __u16 *netfid,
330 FILE_UNIX_BASIC_INFO *pRetData, 339 FILE_UNIX_BASIC_INFO *pRetData,
331 __u32 *pOplock, const char *name, 340 __u32 *pOplock, const char *name,
332 const struct nls_table *nls_codepage, int remap); 341 const struct nls_table *nls_codepage, int remap);
333extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, 342extern int CIFSSMBClose(const int xid, struct cifs_tcon *tcon,
334 const int smb_file_id); 343 const int smb_file_id);
335 344
336extern int CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon, 345extern int CIFSSMBFlush(const int xid, struct cifs_tcon *tcon,
337 const int smb_file_id); 346 const int smb_file_id);
338 347
339extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, 348extern int CIFSSMBRead(const int xid, struct cifs_io_parms *io_parms,
340 const int netfid, unsigned int count, 349 unsigned int *nbytes, char **buf,
341 const __u64 lseek, unsigned int *nbytes, char **buf,
342 int *return_buf_type); 350 int *return_buf_type);
343extern int CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, 351extern int CIFSSMBWrite(const int xid, struct cifs_io_parms *io_parms,
344 const int netfid, const unsigned int count, 352 unsigned int *nbytes, const char *buf,
345 const __u64 lseek, unsigned int *nbytes, 353 const char __user *ubuf, const int long_op);
346 const char *buf, const char __user *ubuf, 354extern int CIFSSMBWrite2(const int xid, struct cifs_io_parms *io_parms,
355 unsigned int *nbytes, struct kvec *iov, const int nvec,
347 const int long_op); 356 const int long_op);
348extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, 357extern int CIFSGetSrvInodeNumber(const int xid, struct cifs_tcon *tcon,
349 const int netfid, const unsigned int count,
350 const __u64 offset, unsigned int *nbytes,
351 struct kvec *iov, const int nvec, const int long_op);
352extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
353 const unsigned char *searchName, __u64 *inode_number, 358 const unsigned char *searchName, __u64 *inode_number,
354 const struct nls_table *nls_codepage, 359 const struct nls_table *nls_codepage,
355 int remap_special_chars); 360 int remap_special_chars);
356 361
357extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, 362extern int CIFSSMBLock(const int xid, struct cifs_tcon *tcon,
358 const __u16 netfid, const __u64 len, 363 const __u16 netfid, const __u64 len,
359 const __u64 offset, const __u32 numUnlock, 364 const __u64 offset, const __u32 numUnlock,
360 const __u32 numLock, const __u8 lockType, 365 const __u32 numLock, const __u8 lockType,
361 const bool waitFlag, const __u8 oplock_level); 366 const bool waitFlag, const __u8 oplock_level);
362extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, 367extern int CIFSSMBPosixLock(const int xid, struct cifs_tcon *tcon,
363 const __u16 smb_file_id, const int get_flag, 368 const __u16 smb_file_id, const int get_flag,
364 const __u64 len, struct file_lock *, 369 const __u64 len, struct file_lock *,
365 const __u16 lock_type, const bool waitFlag); 370 const __u16 lock_type, const bool waitFlag);
366extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon); 371extern int CIFSSMBTDis(const int xid, struct cifs_tcon *tcon);
367extern int CIFSSMBEcho(struct TCP_Server_Info *server); 372extern int CIFSSMBEcho(struct TCP_Server_Info *server);
368extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses); 373extern int CIFSSMBLogoff(const int xid, struct cifs_ses *ses);
369 374
370extern struct cifsSesInfo *sesInfoAlloc(void); 375extern struct cifs_ses *sesInfoAlloc(void);
371extern void sesInfoFree(struct cifsSesInfo *); 376extern void sesInfoFree(struct cifs_ses *);
372extern struct cifsTconInfo *tconInfoAlloc(void); 377extern struct cifs_tcon *tconInfoAlloc(void);
373extern void tconInfoFree(struct cifsTconInfo *); 378extern void tconInfoFree(struct cifs_tcon *);
374 379
375extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *, __u32 *); 380extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *, __u32 *);
376extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *, 381extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,
@@ -379,51 +384,51 @@ extern int cifs_verify_signature(struct smb_hdr *,
379 struct TCP_Server_Info *server, 384 struct TCP_Server_Info *server,
380 __u32 expected_sequence_number); 385 __u32 expected_sequence_number);
381extern int SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *); 386extern int SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *);
382extern int setup_ntlm_response(struct cifsSesInfo *); 387extern int setup_ntlm_response(struct cifs_ses *);
383extern int setup_ntlmv2_rsp(struct cifsSesInfo *, const struct nls_table *); 388extern int setup_ntlmv2_rsp(struct cifs_ses *, const struct nls_table *);
384extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *); 389extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *);
385extern void cifs_crypto_shash_release(struct TCP_Server_Info *); 390extern void cifs_crypto_shash_release(struct TCP_Server_Info *);
386extern int calc_seckey(struct cifsSesInfo *); 391extern int calc_seckey(struct cifs_ses *);
387 392
388#ifdef CONFIG_CIFS_WEAK_PW_HASH 393#ifdef CONFIG_CIFS_WEAK_PW_HASH
389extern int calc_lanman_hash(const char *password, const char *cryptkey, 394extern int calc_lanman_hash(const char *password, const char *cryptkey,
390 bool encrypt, char *lnm_session_key); 395 bool encrypt, char *lnm_session_key);
391#endif /* CIFS_WEAK_PW_HASH */ 396#endif /* CIFS_WEAK_PW_HASH */
392#ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* unused temporarily */ 397#ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* unused temporarily */
393extern int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, 398extern int CIFSSMBNotify(const int xid, struct cifs_tcon *tcon,
394 const int notify_subdirs, const __u16 netfid, 399 const int notify_subdirs, const __u16 netfid,
395 __u32 filter, struct file *file, int multishot, 400 __u32 filter, struct file *file, int multishot,
396 const struct nls_table *nls_codepage); 401 const struct nls_table *nls_codepage);
397#endif /* was needed for dnotify, and will be needed for inotify when VFS fix */ 402#endif /* was needed for dnotify, and will be needed for inotify when VFS fix */
398extern int CIFSSMBCopy(int xid, 403extern int CIFSSMBCopy(int xid,
399 struct cifsTconInfo *source_tcon, 404 struct cifs_tcon *source_tcon,
400 const char *fromName, 405 const char *fromName,
401 const __u16 target_tid, 406 const __u16 target_tid,
402 const char *toName, const int flags, 407 const char *toName, const int flags,
403 const struct nls_table *nls_codepage, 408 const struct nls_table *nls_codepage,
404 int remap_special_chars); 409 int remap_special_chars);
405extern ssize_t CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, 410extern ssize_t CIFSSMBQAllEAs(const int xid, struct cifs_tcon *tcon,
406 const unsigned char *searchName, 411 const unsigned char *searchName,
407 const unsigned char *ea_name, char *EAData, 412 const unsigned char *ea_name, char *EAData,
408 size_t bufsize, const struct nls_table *nls_codepage, 413 size_t bufsize, const struct nls_table *nls_codepage,
409 int remap_special_chars); 414 int remap_special_chars);
410extern int CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, 415extern int CIFSSMBSetEA(const int xid, struct cifs_tcon *tcon,
411 const char *fileName, const char *ea_name, 416 const char *fileName, const char *ea_name,
412 const void *ea_value, const __u16 ea_value_len, 417 const void *ea_value, const __u16 ea_value_len,
413 const struct nls_table *nls_codepage, int remap_special_chars); 418 const struct nls_table *nls_codepage, int remap_special_chars);
414extern int CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, 419extern int CIFSSMBGetCIFSACL(const int xid, struct cifs_tcon *tcon,
415 __u16 fid, struct cifs_ntsd **acl_inf, __u32 *buflen); 420 __u16 fid, struct cifs_ntsd **acl_inf, __u32 *buflen);
416extern int CIFSSMBSetCIFSACL(const int, struct cifsTconInfo *, __u16, 421extern int CIFSSMBSetCIFSACL(const int, struct cifs_tcon *, __u16,
417 struct cifs_ntsd *, __u32); 422 struct cifs_ntsd *, __u32);
418extern int CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon, 423extern int CIFSSMBGetPosixACL(const int xid, struct cifs_tcon *tcon,
419 const unsigned char *searchName, 424 const unsigned char *searchName,
420 char *acl_inf, const int buflen, const int acl_type, 425 char *acl_inf, const int buflen, const int acl_type,
421 const struct nls_table *nls_codepage, int remap_special_chars); 426 const struct nls_table *nls_codepage, int remap_special_chars);
422extern int CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon, 427extern int CIFSSMBSetPosixACL(const int xid, struct cifs_tcon *tcon,
423 const unsigned char *fileName, 428 const unsigned char *fileName,
424 const char *local_acl, const int buflen, const int acl_type, 429 const char *local_acl, const int buflen, const int acl_type,
425 const struct nls_table *nls_codepage, int remap_special_chars); 430 const struct nls_table *nls_codepage, int remap_special_chars);
426extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon, 431extern int CIFSGetExtAttr(const int xid, struct cifs_tcon *tcon,
427 const int netfid, __u64 *pExtAttrBits, __u64 *pMask); 432 const int netfid, __u64 *pExtAttrBits, __u64 *pMask);
428extern void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb); 433extern void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb);
429extern bool CIFSCouldBeMFSymlink(const struct cifs_fattr *fattr); 434extern bool CIFSCouldBeMFSymlink(const struct cifs_fattr *fattr);
@@ -434,4 +439,22 @@ extern int mdfour(unsigned char *, unsigned char *, int);
434extern int E_md4hash(const unsigned char *passwd, unsigned char *p16); 439extern int E_md4hash(const unsigned char *passwd, unsigned char *p16);
435extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8, 440extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8,
436 unsigned char *p24); 441 unsigned char *p24);
442
443/* asynchronous write support */
444struct cifs_writedata {
445 struct kref refcount;
446 enum writeback_sync_modes sync_mode;
447 struct work_struct work;
448 struct cifsFileInfo *cfile;
449 __u64 offset;
450 unsigned int bytes;
451 int result;
452 unsigned int nr_pages;
453 struct page *pages[1];
454};
455
456int cifs_async_writev(struct cifs_writedata *wdata);
457struct cifs_writedata *cifs_writedata_alloc(unsigned int nr_pages);
458void cifs_writedata_release(struct kref *refcount);
459
437#endif /* _CIFSPROTO_H */ 460#endif /* _CIFSPROTO_H */
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 83df937b814e..1a9fe7f816d1 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -32,6 +32,7 @@
32#include <linux/vfs.h> 32#include <linux/vfs.h>
33#include <linux/slab.h> 33#include <linux/slab.h>
34#include <linux/posix_acl_xattr.h> 34#include <linux/posix_acl_xattr.h>
35#include <linux/pagemap.h>
35#include <asm/uaccess.h> 36#include <asm/uaccess.h>
36#include "cifspdu.h" 37#include "cifspdu.h"
37#include "cifsglob.h" 38#include "cifsglob.h"
@@ -84,7 +85,7 @@ static struct {
84 85
85/* Mark as invalid, all open files on tree connections since they 86/* Mark as invalid, all open files on tree connections since they
86 were closed when session to server was lost */ 87 were closed when session to server was lost */
87static void mark_open_files_invalid(struct cifsTconInfo *pTcon) 88static void mark_open_files_invalid(struct cifs_tcon *pTcon)
88{ 89{
89 struct cifsFileInfo *open_file = NULL; 90 struct cifsFileInfo *open_file = NULL;
90 struct list_head *tmp; 91 struct list_head *tmp;
@@ -104,10 +105,10 @@ static void mark_open_files_invalid(struct cifsTconInfo *pTcon)
104 105
105/* reconnect the socket, tcon, and smb session if needed */ 106/* reconnect the socket, tcon, and smb session if needed */
106static int 107static int
107cifs_reconnect_tcon(struct cifsTconInfo *tcon, int smb_command) 108cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
108{ 109{
109 int rc = 0; 110 int rc = 0;
110 struct cifsSesInfo *ses; 111 struct cifs_ses *ses;
111 struct TCP_Server_Info *server; 112 struct TCP_Server_Info *server;
112 struct nls_table *nls_codepage; 113 struct nls_table *nls_codepage;
113 114
@@ -226,7 +227,7 @@ out:
226 SMB information in the SMB header. If the return code is zero, this 227 SMB information in the SMB header. If the return code is zero, this
227 function must have filled in request_buf pointer */ 228 function must have filled in request_buf pointer */
228static int 229static int
229small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, 230small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
230 void **request_buf) 231 void **request_buf)
231{ 232{
232 int rc; 233 int rc;
@@ -252,7 +253,7 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
252 253
253int 254int
254small_smb_init_no_tc(const int smb_command, const int wct, 255small_smb_init_no_tc(const int smb_command, const int wct,
255 struct cifsSesInfo *ses, void **request_buf) 256 struct cifs_ses *ses, void **request_buf)
256{ 257{
257 int rc; 258 int rc;
258 struct smb_hdr *buffer; 259 struct smb_hdr *buffer;
@@ -278,7 +279,7 @@ small_smb_init_no_tc(const int smb_command, const int wct,
278 279
279/* If the return code is zero, this function must fill in request_buf pointer */ 280/* If the return code is zero, this function must fill in request_buf pointer */
280static int 281static int
281__smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, 282__smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
282 void **request_buf, void **response_buf) 283 void **request_buf, void **response_buf)
283{ 284{
284 *request_buf = cifs_buf_get(); 285 *request_buf = cifs_buf_get();
@@ -304,7 +305,7 @@ __smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
304 305
305/* If the return code is zero, this function must fill in request_buf pointer */ 306/* If the return code is zero, this function must fill in request_buf pointer */
306static int 307static int
307smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, 308smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
308 void **request_buf, void **response_buf) 309 void **request_buf, void **response_buf)
309{ 310{
310 int rc; 311 int rc;
@@ -317,7 +318,7 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
317} 318}
318 319
319static int 320static int
320smb_init_no_reconnect(int smb_command, int wct, struct cifsTconInfo *tcon, 321smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
321 void **request_buf, void **response_buf) 322 void **request_buf, void **response_buf)
322{ 323{
323 if (tcon->ses->need_reconnect || tcon->need_reconnect) 324 if (tcon->ses->need_reconnect || tcon->need_reconnect)
@@ -366,7 +367,7 @@ static inline void inc_rfc1001_len(void *pSMB, int count)
366} 367}
367 368
368int 369int
369CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) 370CIFSSMBNegotiate(unsigned int xid, struct cifs_ses *ses)
370{ 371{
371 NEGOTIATE_REQ *pSMB; 372 NEGOTIATE_REQ *pSMB;
372 NEGOTIATE_RSP *pSMBr; 373 NEGOTIATE_RSP *pSMBr;
@@ -450,7 +451,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
450 rc = -EOPNOTSUPP; 451 rc = -EOPNOTSUPP;
451 goto neg_err_exit; 452 goto neg_err_exit;
452 } 453 }
453 server->secMode = (__u8)le16_to_cpu(rsp->SecurityMode); 454 server->sec_mode = (__u8)le16_to_cpu(rsp->SecurityMode);
454 server->maxReq = le16_to_cpu(rsp->MaxMpxCount); 455 server->maxReq = le16_to_cpu(rsp->MaxMpxCount);
455 server->maxBuf = min((__u32)le16_to_cpu(rsp->MaxBufSize), 456 server->maxBuf = min((__u32)le16_to_cpu(rsp->MaxBufSize),
456 (__u32)CIFSMaxBufSize + MAX_CIFS_HDR_SIZE); 457 (__u32)CIFSMaxBufSize + MAX_CIFS_HDR_SIZE);
@@ -504,7 +505,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
504 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) { 505 cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
505 memcpy(ses->server->cryptkey, rsp->EncryptionKey, 506 memcpy(ses->server->cryptkey, rsp->EncryptionKey,
506 CIFS_CRYPTO_KEY_SIZE); 507 CIFS_CRYPTO_KEY_SIZE);
507 } else if (server->secMode & SECMODE_PW_ENCRYPT) { 508 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
508 rc = -EIO; /* need cryptkey unless plain text */ 509 rc = -EIO; /* need cryptkey unless plain text */
509 goto neg_err_exit; 510 goto neg_err_exit;
510 } 511 }
@@ -526,11 +527,11 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
526 goto neg_err_exit; 527 goto neg_err_exit;
527 } 528 }
528 /* else wct == 17 NTLM */ 529 /* else wct == 17 NTLM */
529 server->secMode = pSMBr->SecurityMode; 530 server->sec_mode = pSMBr->SecurityMode;
530 if ((server->secMode & SECMODE_USER) == 0) 531 if ((server->sec_mode & SECMODE_USER) == 0)
531 cFYI(1, "share mode security"); 532 cFYI(1, "share mode security");
532 533
533 if ((server->secMode & SECMODE_PW_ENCRYPT) == 0) 534 if ((server->sec_mode & SECMODE_PW_ENCRYPT) == 0)
534#ifdef CONFIG_CIFS_WEAK_PW_HASH 535#ifdef CONFIG_CIFS_WEAK_PW_HASH
535 if ((secFlags & CIFSSEC_MAY_PLNTXT) == 0) 536 if ((secFlags & CIFSSEC_MAY_PLNTXT) == 0)
536#endif /* CIFS_WEAK_PW_HASH */ 537#endif /* CIFS_WEAK_PW_HASH */
@@ -570,18 +571,10 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
570 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) { 571 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
571 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey, 572 memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
572 CIFS_CRYPTO_KEY_SIZE); 573 CIFS_CRYPTO_KEY_SIZE);
573 } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) 574 } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
574 && (pSMBr->EncryptionKeyLength == 0)) { 575 server->capabilities & CAP_EXTENDED_SECURITY) &&
576 (pSMBr->EncryptionKeyLength == 0)) {
575 /* decode security blob */ 577 /* decode security blob */
576 } else if (server->secMode & SECMODE_PW_ENCRYPT) {
577 rc = -EIO; /* no crypt key only if plain text pwd */
578 goto neg_err_exit;
579 }
580
581 /* BB might be helpful to save off the domain of server here */
582
583 if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) &&
584 (server->capabilities & CAP_EXTENDED_SECURITY)) {
585 count = get_bcc(&pSMBr->hdr); 578 count = get_bcc(&pSMBr->hdr);
586 if (count < 16) { 579 if (count < 16) {
587 rc = -EIO; 580 rc = -EIO;
@@ -624,6 +617,9 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
624 } else 617 } else
625 rc = -EOPNOTSUPP; 618 rc = -EOPNOTSUPP;
626 } 619 }
620 } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
621 rc = -EIO; /* no crypt key only if plain text pwd */
622 goto neg_err_exit;
627 } else 623 } else
628 server->capabilities &= ~CAP_EXTENDED_SECURITY; 624 server->capabilities &= ~CAP_EXTENDED_SECURITY;
629 625
@@ -634,27 +630,27 @@ signing_check:
634 /* MUST_SIGN already includes the MAY_SIGN FLAG 630 /* MUST_SIGN already includes the MAY_SIGN FLAG
635 so if this is zero it means that signing is disabled */ 631 so if this is zero it means that signing is disabled */
636 cFYI(1, "Signing disabled"); 632 cFYI(1, "Signing disabled");
637 if (server->secMode & SECMODE_SIGN_REQUIRED) { 633 if (server->sec_mode & SECMODE_SIGN_REQUIRED) {
638 cERROR(1, "Server requires " 634 cERROR(1, "Server requires "
639 "packet signing to be enabled in " 635 "packet signing to be enabled in "
640 "/proc/fs/cifs/SecurityFlags."); 636 "/proc/fs/cifs/SecurityFlags.");
641 rc = -EOPNOTSUPP; 637 rc = -EOPNOTSUPP;
642 } 638 }
643 server->secMode &= 639 server->sec_mode &=
644 ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); 640 ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
645 } else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) { 641 } else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) {
646 /* signing required */ 642 /* signing required */
647 cFYI(1, "Must sign - secFlags 0x%x", secFlags); 643 cFYI(1, "Must sign - secFlags 0x%x", secFlags);
648 if ((server->secMode & 644 if ((server->sec_mode &
649 (SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED)) == 0) { 645 (SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED)) == 0) {
650 cERROR(1, "signing required but server lacks support"); 646 cERROR(1, "signing required but server lacks support");
651 rc = -EOPNOTSUPP; 647 rc = -EOPNOTSUPP;
652 } else 648 } else
653 server->secMode |= SECMODE_SIGN_REQUIRED; 649 server->sec_mode |= SECMODE_SIGN_REQUIRED;
654 } else { 650 } else {
655 /* signing optional ie CIFSSEC_MAY_SIGN */ 651 /* signing optional ie CIFSSEC_MAY_SIGN */
656 if ((server->secMode & SECMODE_SIGN_REQUIRED) == 0) 652 if ((server->sec_mode & SECMODE_SIGN_REQUIRED) == 0)
657 server->secMode &= 653 server->sec_mode &=
658 ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); 654 ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
659 } 655 }
660 656
@@ -666,7 +662,7 @@ neg_err_exit:
666} 662}
667 663
668int 664int
669CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon) 665CIFSSMBTDis(const int xid, struct cifs_tcon *tcon)
670{ 666{
671 struct smb_hdr *smb_buffer; 667 struct smb_hdr *smb_buffer;
672 int rc = 0; 668 int rc = 0;
@@ -725,6 +721,7 @@ CIFSSMBEcho(struct TCP_Server_Info *server)
725{ 721{
726 ECHO_REQ *smb; 722 ECHO_REQ *smb;
727 int rc = 0; 723 int rc = 0;
724 struct kvec iov;
728 725
729 cFYI(1, "In echo request"); 726 cFYI(1, "In echo request");
730 727
@@ -739,9 +736,10 @@ CIFSSMBEcho(struct TCP_Server_Info *server)
739 put_bcc(1, &smb->hdr); 736 put_bcc(1, &smb->hdr);
740 smb->Data[0] = 'a'; 737 smb->Data[0] = 'a';
741 inc_rfc1001_len(smb, 3); 738 inc_rfc1001_len(smb, 3);
739 iov.iov_base = smb;
740 iov.iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4;
742 741
743 rc = cifs_call_async(server, (struct smb_hdr *)smb, 742 rc = cifs_call_async(server, &iov, 1, cifs_echo_callback, server, true);
744 cifs_echo_callback, server);
745 if (rc) 743 if (rc)
746 cFYI(1, "Echo request failed: %d", rc); 744 cFYI(1, "Echo request failed: %d", rc);
747 745
@@ -751,7 +749,7 @@ CIFSSMBEcho(struct TCP_Server_Info *server)
751} 749}
752 750
753int 751int
754CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses) 752CIFSSMBLogoff(const int xid, struct cifs_ses *ses)
755{ 753{
756 LOGOFF_ANDX_REQ *pSMB; 754 LOGOFF_ANDX_REQ *pSMB;
757 int rc = 0; 755 int rc = 0;
@@ -778,7 +776,7 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
778 776
779 pSMB->hdr.Mid = GetNextMid(ses->server); 777 pSMB->hdr.Mid = GetNextMid(ses->server);
780 778
781 if (ses->server->secMode & 779 if (ses->server->sec_mode &
782 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 780 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
783 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 781 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
784 782
@@ -798,7 +796,7 @@ session_already_dead:
798} 796}
799 797
800int 798int
801CIFSPOSIXDelFile(const int xid, struct cifsTconInfo *tcon, const char *fileName, 799CIFSPOSIXDelFile(const int xid, struct cifs_tcon *tcon, const char *fileName,
802 __u16 type, const struct nls_table *nls_codepage, int remap) 800 __u16 type, const struct nls_table *nls_codepage, int remap)
803{ 801{
804 TRANSACTION2_SPI_REQ *pSMB = NULL; 802 TRANSACTION2_SPI_REQ *pSMB = NULL;
@@ -873,7 +871,7 @@ PsxDelete:
873} 871}
874 872
875int 873int
876CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon, const char *fileName, 874CIFSSMBDelFile(const int xid, struct cifs_tcon *tcon, const char *fileName,
877 const struct nls_table *nls_codepage, int remap) 875 const struct nls_table *nls_codepage, int remap)
878{ 876{
879 DELETE_FILE_REQ *pSMB = NULL; 877 DELETE_FILE_REQ *pSMB = NULL;
@@ -918,7 +916,7 @@ DelFileRetry:
918} 916}
919 917
920int 918int
921CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon, const char *dirName, 919CIFSSMBRmDir(const int xid, struct cifs_tcon *tcon, const char *dirName,
922 const struct nls_table *nls_codepage, int remap) 920 const struct nls_table *nls_codepage, int remap)
923{ 921{
924 DELETE_DIRECTORY_REQ *pSMB = NULL; 922 DELETE_DIRECTORY_REQ *pSMB = NULL;
@@ -961,7 +959,7 @@ RmDirRetry:
961} 959}
962 960
963int 961int
964CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon, 962CIFSSMBMkDir(const int xid, struct cifs_tcon *tcon,
965 const char *name, const struct nls_table *nls_codepage, int remap) 963 const char *name, const struct nls_table *nls_codepage, int remap)
966{ 964{
967 int rc = 0; 965 int rc = 0;
@@ -1004,7 +1002,7 @@ MkDirRetry:
1004} 1002}
1005 1003
1006int 1004int
1007CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, __u32 posix_flags, 1005CIFSPOSIXCreate(const int xid, struct cifs_tcon *tcon, __u32 posix_flags,
1008 __u64 mode, __u16 *netfid, FILE_UNIX_BASIC_INFO *pRetData, 1006 __u64 mode, __u16 *netfid, FILE_UNIX_BASIC_INFO *pRetData,
1009 __u32 *pOplock, const char *name, 1007 __u32 *pOplock, const char *name,
1010 const struct nls_table *nls_codepage, int remap) 1008 const struct nls_table *nls_codepage, int remap)
@@ -1170,7 +1168,7 @@ access_flags_to_smbopen_mode(const int access_flags)
1170} 1168}
1171 1169
1172int 1170int
1173SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon, 1171SMBLegacyOpen(const int xid, struct cifs_tcon *tcon,
1174 const char *fileName, const int openDisposition, 1172 const char *fileName, const int openDisposition,
1175 const int access_flags, const int create_options, __u16 *netfid, 1173 const int access_flags, const int create_options, __u16 *netfid,
1176 int *pOplock, FILE_ALL_INFO *pfile_info, 1174 int *pOplock, FILE_ALL_INFO *pfile_info,
@@ -1277,7 +1275,7 @@ OldOpenRetry:
1277} 1275}
1278 1276
1279int 1277int
1280CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon, 1278CIFSSMBOpen(const int xid, struct cifs_tcon *tcon,
1281 const char *fileName, const int openDisposition, 1279 const char *fileName, const int openDisposition,
1282 const int access_flags, const int create_options, __u16 *netfid, 1280 const int access_flags, const int create_options, __u16 *netfid,
1283 int *pOplock, FILE_ALL_INFO *pfile_info, 1281 int *pOplock, FILE_ALL_INFO *pfile_info,
@@ -1379,8 +1377,7 @@ openRetry:
1379} 1377}
1380 1378
1381int 1379int
1382CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid, 1380CIFSSMBRead(const int xid, struct cifs_io_parms *io_parms, unsigned int *nbytes,
1383 const unsigned int count, const __u64 lseek, unsigned int *nbytes,
1384 char **buf, int *pbuf_type) 1381 char **buf, int *pbuf_type)
1385{ 1382{
1386 int rc = -EACCES; 1383 int rc = -EACCES;
@@ -1390,13 +1387,18 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
1390 int wct; 1387 int wct;
1391 int resp_buf_type = 0; 1388 int resp_buf_type = 0;
1392 struct kvec iov[1]; 1389 struct kvec iov[1];
1390 __u32 pid = io_parms->pid;
1391 __u16 netfid = io_parms->netfid;
1392 __u64 offset = io_parms->offset;
1393 struct cifs_tcon *tcon = io_parms->tcon;
1394 unsigned int count = io_parms->length;
1393 1395
1394 cFYI(1, "Reading %d bytes on fid %d", count, netfid); 1396 cFYI(1, "Reading %d bytes on fid %d", count, netfid);
1395 if (tcon->ses->capabilities & CAP_LARGE_FILES) 1397 if (tcon->ses->capabilities & CAP_LARGE_FILES)
1396 wct = 12; 1398 wct = 12;
1397 else { 1399 else {
1398 wct = 10; /* old style read */ 1400 wct = 10; /* old style read */
1399 if ((lseek >> 32) > 0) { 1401 if ((offset >> 32) > 0) {
1400 /* can not handle this big offset for old */ 1402 /* can not handle this big offset for old */
1401 return -EIO; 1403 return -EIO;
1402 } 1404 }
@@ -1407,15 +1409,18 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
1407 if (rc) 1409 if (rc)
1408 return rc; 1410 return rc;
1409 1411
1412 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1413 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1414
1410 /* tcon and ses pointer are checked in smb_init */ 1415 /* tcon and ses pointer are checked in smb_init */
1411 if (tcon->ses->server == NULL) 1416 if (tcon->ses->server == NULL)
1412 return -ECONNABORTED; 1417 return -ECONNABORTED;
1413 1418
1414 pSMB->AndXCommand = 0xFF; /* none */ 1419 pSMB->AndXCommand = 0xFF; /* none */
1415 pSMB->Fid = netfid; 1420 pSMB->Fid = netfid;
1416 pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF); 1421 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
1417 if (wct == 12) 1422 if (wct == 12)
1418 pSMB->OffsetHigh = cpu_to_le32(lseek >> 32); 1423 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
1419 1424
1420 pSMB->Remaining = 0; 1425 pSMB->Remaining = 0;
1421 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF); 1426 pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
@@ -1484,9 +1489,8 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
1484 1489
1485 1490
1486int 1491int
1487CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, 1492CIFSSMBWrite(const int xid, struct cifs_io_parms *io_parms,
1488 const int netfid, const unsigned int count, 1493 unsigned int *nbytes, const char *buf,
1489 const __u64 offset, unsigned int *nbytes, const char *buf,
1490 const char __user *ubuf, const int long_op) 1494 const char __user *ubuf, const int long_op)
1491{ 1495{
1492 int rc = -EACCES; 1496 int rc = -EACCES;
@@ -1495,6 +1499,11 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
1495 int bytes_returned, wct; 1499 int bytes_returned, wct;
1496 __u32 bytes_sent; 1500 __u32 bytes_sent;
1497 __u16 byte_count; 1501 __u16 byte_count;
1502 __u32 pid = io_parms->pid;
1503 __u16 netfid = io_parms->netfid;
1504 __u64 offset = io_parms->offset;
1505 struct cifs_tcon *tcon = io_parms->tcon;
1506 unsigned int count = io_parms->length;
1498 1507
1499 *nbytes = 0; 1508 *nbytes = 0;
1500 1509
@@ -1516,6 +1525,10 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
1516 (void **) &pSMBr); 1525 (void **) &pSMBr);
1517 if (rc) 1526 if (rc)
1518 return rc; 1527 return rc;
1528
1529 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1530 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1531
1519 /* tcon and ses pointer are checked in smb_init */ 1532 /* tcon and ses pointer are checked in smb_init */
1520 if (tcon->ses->server == NULL) 1533 if (tcon->ses->server == NULL)
1521 return -ECONNABORTED; 1534 return -ECONNABORTED;
@@ -1602,17 +1615,259 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
1602 return rc; 1615 return rc;
1603} 1616}
1604 1617
1618void
1619cifs_writedata_release(struct kref *refcount)
1620{
1621 struct cifs_writedata *wdata = container_of(refcount,
1622 struct cifs_writedata, refcount);
1623
1624 if (wdata->cfile)
1625 cifsFileInfo_put(wdata->cfile);
1626
1627 kfree(wdata);
1628}
1629
1630/*
1631 * Write failed with a retryable error. Resend the write request. It's also
1632 * possible that the page was redirtied so re-clean the page.
1633 */
1634static void
1635cifs_writev_requeue(struct cifs_writedata *wdata)
1636{
1637 int i, rc;
1638 struct inode *inode = wdata->cfile->dentry->d_inode;
1639
1640 for (i = 0; i < wdata->nr_pages; i++) {
1641 lock_page(wdata->pages[i]);
1642 clear_page_dirty_for_io(wdata->pages[i]);
1643 }
1644
1645 do {
1646 rc = cifs_async_writev(wdata);
1647 } while (rc == -EAGAIN);
1648
1649 for (i = 0; i < wdata->nr_pages; i++) {
1650 if (rc != 0)
1651 SetPageError(wdata->pages[i]);
1652 unlock_page(wdata->pages[i]);
1653 }
1654
1655 mapping_set_error(inode->i_mapping, rc);
1656 kref_put(&wdata->refcount, cifs_writedata_release);
1657}
1658
1659static void
1660cifs_writev_complete(struct work_struct *work)
1661{
1662 struct cifs_writedata *wdata = container_of(work,
1663 struct cifs_writedata, work);
1664 struct inode *inode = wdata->cfile->dentry->d_inode;
1665 int i = 0;
1666
1667 if (wdata->result == 0) {
1668 cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
1669 cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
1670 wdata->bytes);
1671 } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
1672 return cifs_writev_requeue(wdata);
1673
1674 for (i = 0; i < wdata->nr_pages; i++) {
1675 struct page *page = wdata->pages[i];
1676 if (wdata->result == -EAGAIN)
1677 __set_page_dirty_nobuffers(page);
1678 else if (wdata->result < 0)
1679 SetPageError(page);
1680 end_page_writeback(page);
1681 page_cache_release(page);
1682 }
1683 if (wdata->result != -EAGAIN)
1684 mapping_set_error(inode->i_mapping, wdata->result);
1685 kref_put(&wdata->refcount, cifs_writedata_release);
1686}
1687
1688struct cifs_writedata *
1689cifs_writedata_alloc(unsigned int nr_pages)
1690{
1691 struct cifs_writedata *wdata;
1692
1693 /* this would overflow */
1694 if (nr_pages == 0) {
1695 cERROR(1, "%s: called with nr_pages == 0!", __func__);
1696 return NULL;
1697 }
1698
1699 /* writedata + number of page pointers */
1700 wdata = kzalloc(sizeof(*wdata) +
1701 sizeof(struct page *) * (nr_pages - 1), GFP_NOFS);
1702 if (wdata != NULL) {
1703 INIT_WORK(&wdata->work, cifs_writev_complete);
1704 kref_init(&wdata->refcount);
1705 }
1706 return wdata;
1707}
1708
1709/*
1710 * Check the midState and signature on received buffer (if any), and queue the
1711 * workqueue completion task.
1712 */
1713static void
1714cifs_writev_callback(struct mid_q_entry *mid)
1715{
1716 struct cifs_writedata *wdata = mid->callback_data;
1717 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
1718 unsigned int written;
1719 WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
1720
1721 switch (mid->midState) {
1722 case MID_RESPONSE_RECEIVED:
1723 wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
1724 if (wdata->result != 0)
1725 break;
1726
1727 written = le16_to_cpu(smb->CountHigh);
1728 written <<= 16;
1729 written += le16_to_cpu(smb->Count);
1730 /*
1731 * Mask off high 16 bits when bytes written as returned
1732 * by the server is greater than bytes requested by the
1733 * client. OS/2 servers are known to set incorrect
1734 * CountHigh values.
1735 */
1736 if (written > wdata->bytes)
1737 written &= 0xFFFF;
1738
1739 if (written < wdata->bytes)
1740 wdata->result = -ENOSPC;
1741 else
1742 wdata->bytes = written;
1743 break;
1744 case MID_REQUEST_SUBMITTED:
1745 case MID_RETRY_NEEDED:
1746 wdata->result = -EAGAIN;
1747 break;
1748 default:
1749 wdata->result = -EIO;
1750 break;
1751 }
1752
1753 queue_work(system_nrt_wq, &wdata->work);
1754 DeleteMidQEntry(mid);
1755 atomic_dec(&tcon->ses->server->inFlight);
1756 wake_up(&tcon->ses->server->request_q);
1757}
1758
1759/* cifs_async_writev - send an async write, and set up mid to handle result */
1760int
1761cifs_async_writev(struct cifs_writedata *wdata)
1762{
1763 int i, rc = -EACCES;
1764 WRITE_REQ *smb = NULL;
1765 int wct;
1766 struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
1767 struct inode *inode = wdata->cfile->dentry->d_inode;
1768 struct kvec *iov = NULL;
1769
1770 if (tcon->ses->capabilities & CAP_LARGE_FILES) {
1771 wct = 14;
1772 } else {
1773 wct = 12;
1774 if (wdata->offset >> 32 > 0) {
1775 /* can not handle big offset for old srv */
1776 return -EIO;
1777 }
1778 }
1779
1780 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
1781 if (rc)
1782 goto async_writev_out;
1783
1784 /* 1 iov per page + 1 for header */
1785 iov = kzalloc((wdata->nr_pages + 1) * sizeof(*iov), GFP_NOFS);
1786 if (iov == NULL) {
1787 rc = -ENOMEM;
1788 goto async_writev_out;
1789 }
1790
1791 smb->hdr.Pid = cpu_to_le16((__u16)wdata->cfile->pid);
1792 smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->cfile->pid >> 16));
1793
1794 smb->AndXCommand = 0xFF; /* none */
1795 smb->Fid = wdata->cfile->netfid;
1796 smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
1797 if (wct == 14)
1798 smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
1799 smb->Reserved = 0xFFFFFFFF;
1800 smb->WriteMode = 0;
1801 smb->Remaining = 0;
1802
1803 smb->DataOffset =
1804 cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
1805
1806 /* 4 for RFC1001 length + 1 for BCC */
1807 iov[0].iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4 + 1;
1808 iov[0].iov_base = smb;
1809
1810 /* marshal up the pages into iov array */
1811 wdata->bytes = 0;
1812 for (i = 0; i < wdata->nr_pages; i++) {
1813 iov[i + 1].iov_len = min(inode->i_size -
1814 page_offset(wdata->pages[i]),
1815 (loff_t)PAGE_CACHE_SIZE);
1816 iov[i + 1].iov_base = kmap(wdata->pages[i]);
1817 wdata->bytes += iov[i + 1].iov_len;
1818 }
1819
1820 cFYI(1, "async write at %llu %u bytes", wdata->offset, wdata->bytes);
1821
1822 smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
1823 smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
1824
1825 if (wct == 14) {
1826 inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
1827 put_bcc(wdata->bytes + 1, &smb->hdr);
1828 } else {
1829 /* wct == 12 */
1830 struct smb_com_writex_req *smbw =
1831 (struct smb_com_writex_req *)smb;
1832 inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
1833 put_bcc(wdata->bytes + 5, &smbw->hdr);
1834 iov[0].iov_len += 4; /* pad bigger by four bytes */
1835 }
1836
1837 kref_get(&wdata->refcount);
1838 rc = cifs_call_async(tcon->ses->server, iov, wdata->nr_pages + 1,
1839 cifs_writev_callback, wdata, false);
1840
1841 if (rc == 0)
1842 cifs_stats_inc(&tcon->num_writes);
1843 else
1844 kref_put(&wdata->refcount, cifs_writedata_release);
1845
1846 /* send is done, unmap pages */
1847 for (i = 0; i < wdata->nr_pages; i++)
1848 kunmap(wdata->pages[i]);
1849
1850async_writev_out:
1851 cifs_small_buf_release(smb);
1852 kfree(iov);
1853 return rc;
1854}
1855
1605int 1856int
1606CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, 1857CIFSSMBWrite2(const int xid, struct cifs_io_parms *io_parms,
1607 const int netfid, const unsigned int count, 1858 unsigned int *nbytes, struct kvec *iov, int n_vec,
1608 const __u64 offset, unsigned int *nbytes, struct kvec *iov, 1859 const int long_op)
1609 int n_vec, const int long_op)
1610{ 1860{
1611 int rc = -EACCES; 1861 int rc = -EACCES;
1612 WRITE_REQ *pSMB = NULL; 1862 WRITE_REQ *pSMB = NULL;
1613 int wct; 1863 int wct;
1614 int smb_hdr_len; 1864 int smb_hdr_len;
1615 int resp_buf_type = 0; 1865 int resp_buf_type = 0;
1866 __u32 pid = io_parms->pid;
1867 __u16 netfid = io_parms->netfid;
1868 __u64 offset = io_parms->offset;
1869 struct cifs_tcon *tcon = io_parms->tcon;
1870 unsigned int count = io_parms->length;
1616 1871
1617 *nbytes = 0; 1872 *nbytes = 0;
1618 1873
@@ -1630,6 +1885,10 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
1630 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB); 1885 rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
1631 if (rc) 1886 if (rc)
1632 return rc; 1887 return rc;
1888
1889 pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
1890 pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
1891
1633 /* tcon and ses pointer are checked in smb_init */ 1892 /* tcon and ses pointer are checked in smb_init */
1634 if (tcon->ses->server == NULL) 1893 if (tcon->ses->server == NULL)
1635 return -ECONNABORTED; 1894 return -ECONNABORTED;
@@ -1705,7 +1964,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
1705 1964
1706 1965
1707int 1966int
1708CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, 1967CIFSSMBLock(const int xid, struct cifs_tcon *tcon,
1709 const __u16 smb_file_id, const __u64 len, 1968 const __u16 smb_file_id, const __u64 len,
1710 const __u64 offset, const __u32 numUnlock, 1969 const __u64 offset, const __u32 numUnlock,
1711 const __u32 numLock, const __u8 lockType, 1970 const __u32 numLock, const __u8 lockType,
@@ -1775,7 +2034,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1775} 2034}
1776 2035
1777int 2036int
1778CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, 2037CIFSSMBPosixLock(const int xid, struct cifs_tcon *tcon,
1779 const __u16 smb_file_id, const int get_flag, const __u64 len, 2038 const __u16 smb_file_id, const int get_flag, const __u64 len,
1780 struct file_lock *pLockData, const __u16 lock_type, 2039 struct file_lock *pLockData, const __u16 lock_type,
1781 const bool waitFlag) 2040 const bool waitFlag)
@@ -1913,7 +2172,7 @@ plk_err_exit:
1913 2172
1914 2173
1915int 2174int
1916CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id) 2175CIFSSMBClose(const int xid, struct cifs_tcon *tcon, int smb_file_id)
1917{ 2176{
1918 int rc = 0; 2177 int rc = 0;
1919 CLOSE_REQ *pSMB = NULL; 2178 CLOSE_REQ *pSMB = NULL;
@@ -1946,7 +2205,7 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
1946} 2205}
1947 2206
1948int 2207int
1949CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon, int smb_file_id) 2208CIFSSMBFlush(const int xid, struct cifs_tcon *tcon, int smb_file_id)
1950{ 2209{
1951 int rc = 0; 2210 int rc = 0;
1952 FLUSH_REQ *pSMB = NULL; 2211 FLUSH_REQ *pSMB = NULL;
@@ -1967,7 +2226,7 @@ CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
1967} 2226}
1968 2227
1969int 2228int
1970CIFSSMBRename(const int xid, struct cifsTconInfo *tcon, 2229CIFSSMBRename(const int xid, struct cifs_tcon *tcon,
1971 const char *fromName, const char *toName, 2230 const char *fromName, const char *toName,
1972 const struct nls_table *nls_codepage, int remap) 2231 const struct nls_table *nls_codepage, int remap)
1973{ 2232{
@@ -2034,7 +2293,7 @@ renameRetry:
2034 return rc; 2293 return rc;
2035} 2294}
2036 2295
2037int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon, 2296int CIFSSMBRenameOpenFile(const int xid, struct cifs_tcon *pTcon,
2038 int netfid, const char *target_name, 2297 int netfid, const char *target_name,
2039 const struct nls_table *nls_codepage, int remap) 2298 const struct nls_table *nls_codepage, int remap)
2040{ 2299{
@@ -2114,7 +2373,7 @@ int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon,
2114} 2373}
2115 2374
2116int 2375int
2117CIFSSMBCopy(const int xid, struct cifsTconInfo *tcon, const char *fromName, 2376CIFSSMBCopy(const int xid, struct cifs_tcon *tcon, const char *fromName,
2118 const __u16 target_tid, const char *toName, const int flags, 2377 const __u16 target_tid, const char *toName, const int flags,
2119 const struct nls_table *nls_codepage, int remap) 2378 const struct nls_table *nls_codepage, int remap)
2120{ 2379{
@@ -2182,7 +2441,7 @@ copyRetry:
2182} 2441}
2183 2442
2184int 2443int
2185CIFSUnixCreateSymLink(const int xid, struct cifsTconInfo *tcon, 2444CIFSUnixCreateSymLink(const int xid, struct cifs_tcon *tcon,
2186 const char *fromName, const char *toName, 2445 const char *fromName, const char *toName,
2187 const struct nls_table *nls_codepage) 2446 const struct nls_table *nls_codepage)
2188{ 2447{
@@ -2271,7 +2530,7 @@ createSymLinkRetry:
2271} 2530}
2272 2531
2273int 2532int
2274CIFSUnixCreateHardLink(const int xid, struct cifsTconInfo *tcon, 2533CIFSUnixCreateHardLink(const int xid, struct cifs_tcon *tcon,
2275 const char *fromName, const char *toName, 2534 const char *fromName, const char *toName,
2276 const struct nls_table *nls_codepage, int remap) 2535 const struct nls_table *nls_codepage, int remap)
2277{ 2536{
@@ -2356,7 +2615,7 @@ createHardLinkRetry:
2356} 2615}
2357 2616
2358int 2617int
2359CIFSCreateHardLink(const int xid, struct cifsTconInfo *tcon, 2618CIFSCreateHardLink(const int xid, struct cifs_tcon *tcon,
2360 const char *fromName, const char *toName, 2619 const char *fromName, const char *toName,
2361 const struct nls_table *nls_codepage, int remap) 2620 const struct nls_table *nls_codepage, int remap)
2362{ 2621{
@@ -2428,7 +2687,7 @@ winCreateHardLinkRetry:
2428} 2687}
2429 2688
2430int 2689int
2431CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon, 2690CIFSSMBUnixQuerySymLink(const int xid, struct cifs_tcon *tcon,
2432 const unsigned char *searchName, char **symlinkinfo, 2691 const unsigned char *searchName, char **symlinkinfo,
2433 const struct nls_table *nls_codepage) 2692 const struct nls_table *nls_codepage)
2434{ 2693{
@@ -2533,7 +2792,7 @@ querySymLinkRetry:
2533 * it is not compiled in by default until callers fixed up and more tested. 2792 * it is not compiled in by default until callers fixed up and more tested.
2534 */ 2793 */
2535int 2794int
2536CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, 2795CIFSSMBQueryReparseLinkInfo(const int xid, struct cifs_tcon *tcon,
2537 const unsigned char *searchName, 2796 const unsigned char *searchName,
2538 char *symlinkinfo, const int buflen, __u16 fid, 2797 char *symlinkinfo, const int buflen, __u16 fid,
2539 const struct nls_table *nls_codepage) 2798 const struct nls_table *nls_codepage)
@@ -2771,7 +3030,7 @@ static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
2771} 3030}
2772 3031
2773int 3032int
2774CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon, 3033CIFSSMBGetPosixACL(const int xid, struct cifs_tcon *tcon,
2775 const unsigned char *searchName, 3034 const unsigned char *searchName,
2776 char *acl_inf, const int buflen, const int acl_type, 3035 char *acl_inf, const int buflen, const int acl_type,
2777 const struct nls_table *nls_codepage, int remap) 3036 const struct nls_table *nls_codepage, int remap)
@@ -2859,7 +3118,7 @@ queryAclRetry:
2859} 3118}
2860 3119
2861int 3120int
2862CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon, 3121CIFSSMBSetPosixACL(const int xid, struct cifs_tcon *tcon,
2863 const unsigned char *fileName, 3122 const unsigned char *fileName,
2864 const char *local_acl, const int buflen, 3123 const char *local_acl, const int buflen,
2865 const int acl_type, 3124 const int acl_type,
@@ -2939,7 +3198,7 @@ setACLerrorExit:
2939 3198
2940/* BB fix tabs in this function FIXME BB */ 3199/* BB fix tabs in this function FIXME BB */
2941int 3200int
2942CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon, 3201CIFSGetExtAttr(const int xid, struct cifs_tcon *tcon,
2943 const int netfid, __u64 *pExtAttrBits, __u64 *pMask) 3202 const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
2944{ 3203{
2945 int rc = 0; 3204 int rc = 0;
@@ -3032,7 +3291,7 @@ GetExtAttrOut:
3032 */ 3291 */
3033static int 3292static int
3034smb_init_nttransact(const __u16 sub_command, const int setup_count, 3293smb_init_nttransact(const __u16 sub_command, const int setup_count,
3035 const int parm_len, struct cifsTconInfo *tcon, 3294 const int parm_len, struct cifs_tcon *tcon,
3036 void **ret_buf) 3295 void **ret_buf)
3037{ 3296{
3038 int rc; 3297 int rc;
@@ -3115,7 +3374,7 @@ validate_ntransact(char *buf, char **ppparm, char **ppdata,
3115 3374
3116/* Get Security Descriptor (by handle) from remote server for a file or dir */ 3375/* Get Security Descriptor (by handle) from remote server for a file or dir */
3117int 3376int
3118CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, 3377CIFSSMBGetCIFSACL(const int xid, struct cifs_tcon *tcon, __u16 fid,
3119 struct cifs_ntsd **acl_inf, __u32 *pbuflen) 3378 struct cifs_ntsd **acl_inf, __u32 *pbuflen)
3120{ 3379{
3121 int rc = 0; 3380 int rc = 0;
@@ -3207,7 +3466,7 @@ qsec_out:
3207} 3466}
3208 3467
3209int 3468int
3210CIFSSMBSetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, 3469CIFSSMBSetCIFSACL(const int xid, struct cifs_tcon *tcon, __u16 fid,
3211 struct cifs_ntsd *pntsd, __u32 acllen) 3470 struct cifs_ntsd *pntsd, __u32 acllen)
3212{ 3471{
3213 __u16 byte_count, param_count, data_count, param_offset, data_offset; 3472 __u16 byte_count, param_count, data_count, param_offset, data_offset;
@@ -3273,7 +3532,7 @@ setCifsAclRetry:
3273 3532
3274/* Legacy Query Path Information call for lookup to old servers such 3533/* Legacy Query Path Information call for lookup to old servers such
3275 as Win9x/WinME */ 3534 as Win9x/WinME */
3276int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, 3535int SMBQueryInformation(const int xid, struct cifs_tcon *tcon,
3277 const unsigned char *searchName, 3536 const unsigned char *searchName,
3278 FILE_ALL_INFO *pFinfo, 3537 FILE_ALL_INFO *pFinfo,
3279 const struct nls_table *nls_codepage, int remap) 3538 const struct nls_table *nls_codepage, int remap)
@@ -3341,7 +3600,7 @@ QInfRetry:
3341} 3600}
3342 3601
3343int 3602int
3344CIFSSMBQFileInfo(const int xid, struct cifsTconInfo *tcon, 3603CIFSSMBQFileInfo(const int xid, struct cifs_tcon *tcon,
3345 u16 netfid, FILE_ALL_INFO *pFindData) 3604 u16 netfid, FILE_ALL_INFO *pFindData)
3346{ 3605{
3347 struct smb_t2_qfi_req *pSMB = NULL; 3606 struct smb_t2_qfi_req *pSMB = NULL;
@@ -3408,7 +3667,7 @@ QFileInfoRetry:
3408} 3667}
3409 3668
3410int 3669int
3411CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, 3670CIFSSMBQPathInfo(const int xid, struct cifs_tcon *tcon,
3412 const unsigned char *searchName, 3671 const unsigned char *searchName,
3413 FILE_ALL_INFO *pFindData, 3672 FILE_ALL_INFO *pFindData,
3414 int legacy /* old style infolevel */, 3673 int legacy /* old style infolevel */,
@@ -3509,7 +3768,7 @@ QPathInfoRetry:
3509} 3768}
3510 3769
3511int 3770int
3512CIFSSMBUnixQFileInfo(const int xid, struct cifsTconInfo *tcon, 3771CIFSSMBUnixQFileInfo(const int xid, struct cifs_tcon *tcon,
3513 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData) 3772 u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
3514{ 3773{
3515 struct smb_t2_qfi_req *pSMB = NULL; 3774 struct smb_t2_qfi_req *pSMB = NULL;
@@ -3578,7 +3837,7 @@ UnixQFileInfoRetry:
3578} 3837}
3579 3838
3580int 3839int
3581CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon, 3840CIFSSMBUnixQPathInfo(const int xid, struct cifs_tcon *tcon,
3582 const unsigned char *searchName, 3841 const unsigned char *searchName,
3583 FILE_UNIX_BASIC_INFO *pFindData, 3842 FILE_UNIX_BASIC_INFO *pFindData,
3584 const struct nls_table *nls_codepage, int remap) 3843 const struct nls_table *nls_codepage, int remap)
@@ -3664,7 +3923,7 @@ UnixQPathInfoRetry:
3664 3923
3665/* xid, tcon, searchName and codepage are input parms, rest are returned */ 3924/* xid, tcon, searchName and codepage are input parms, rest are returned */
3666int 3925int
3667CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, 3926CIFSFindFirst(const int xid, struct cifs_tcon *tcon,
3668 const char *searchName, 3927 const char *searchName,
3669 const struct nls_table *nls_codepage, 3928 const struct nls_table *nls_codepage,
3670 __u16 *pnetfid, 3929 __u16 *pnetfid,
@@ -3812,7 +4071,7 @@ findFirstRetry:
3812 return rc; 4071 return rc;
3813} 4072}
3814 4073
3815int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, 4074int CIFSFindNext(const int xid, struct cifs_tcon *tcon,
3816 __u16 searchHandle, struct cifs_search_info *psrch_inf) 4075 __u16 searchHandle, struct cifs_search_info *psrch_inf)
3817{ 4076{
3818 TRANSACTION2_FNEXT_REQ *pSMB = NULL; 4077 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
@@ -3950,7 +4209,7 @@ FNext2_err_exit:
3950} 4209}
3951 4210
3952int 4211int
3953CIFSFindClose(const int xid, struct cifsTconInfo *tcon, 4212CIFSFindClose(const int xid, struct cifs_tcon *tcon,
3954 const __u16 searchHandle) 4213 const __u16 searchHandle)
3955{ 4214{
3956 int rc = 0; 4215 int rc = 0;
@@ -3982,7 +4241,7 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon,
3982} 4241}
3983 4242
3984int 4243int
3985CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon, 4244CIFSGetSrvInodeNumber(const int xid, struct cifs_tcon *tcon,
3986 const unsigned char *searchName, 4245 const unsigned char *searchName,
3987 __u64 *inode_number, 4246 __u64 *inode_number,
3988 const struct nls_table *nls_codepage, int remap) 4247 const struct nls_table *nls_codepage, int remap)
@@ -4184,7 +4443,7 @@ parse_DFS_referrals_exit:
4184} 4443}
4185 4444
4186int 4445int
4187CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, 4446CIFSGetDFSRefer(const int xid, struct cifs_ses *ses,
4188 const unsigned char *searchName, 4447 const unsigned char *searchName,
4189 struct dfs_info3_param **target_nodes, 4448 struct dfs_info3_param **target_nodes,
4190 unsigned int *num_of_nodes, 4449 unsigned int *num_of_nodes,
@@ -4233,7 +4492,7 @@ getDFSRetry:
4233 } 4492 }
4234 4493
4235 if (ses->server) { 4494 if (ses->server) {
4236 if (ses->server->secMode & 4495 if (ses->server->sec_mode &
4237 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 4496 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
4238 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 4497 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
4239 } 4498 }
@@ -4298,7 +4557,7 @@ GetDFSRefExit:
4298 4557
4299/* Query File System Info such as free space to old servers such as Win 9x */ 4558/* Query File System Info such as free space to old servers such as Win 9x */
4300int 4559int
4301SMBOldQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData) 4560SMBOldQFSInfo(const int xid, struct cifs_tcon *tcon, struct kstatfs *FSData)
4302{ 4561{
4303/* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */ 4562/* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
4304 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4563 TRANSACTION2_QFSI_REQ *pSMB = NULL;
@@ -4377,7 +4636,7 @@ oldQFSInfoRetry:
4377} 4636}
4378 4637
4379int 4638int
4380CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData) 4639CIFSSMBQFSInfo(const int xid, struct cifs_tcon *tcon, struct kstatfs *FSData)
4381{ 4640{
4382/* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */ 4641/* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
4383 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4642 TRANSACTION2_QFSI_REQ *pSMB = NULL;
@@ -4456,7 +4715,7 @@ QFSInfoRetry:
4456} 4715}
4457 4716
4458int 4717int
4459CIFSSMBQFSAttributeInfo(const int xid, struct cifsTconInfo *tcon) 4718CIFSSMBQFSAttributeInfo(const int xid, struct cifs_tcon *tcon)
4460{ 4719{
4461/* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */ 4720/* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
4462 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4721 TRANSACTION2_QFSI_REQ *pSMB = NULL;
@@ -4526,7 +4785,7 @@ QFSAttributeRetry:
4526} 4785}
4527 4786
4528int 4787int
4529CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon) 4788CIFSSMBQFSDeviceInfo(const int xid, struct cifs_tcon *tcon)
4530{ 4789{
4531/* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */ 4790/* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
4532 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4791 TRANSACTION2_QFSI_REQ *pSMB = NULL;
@@ -4597,7 +4856,7 @@ QFSDeviceRetry:
4597} 4856}
4598 4857
4599int 4858int
4600CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon) 4859CIFSSMBQFSUnixInfo(const int xid, struct cifs_tcon *tcon)
4601{ 4860{
4602/* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */ 4861/* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
4603 TRANSACTION2_QFSI_REQ *pSMB = NULL; 4862 TRANSACTION2_QFSI_REQ *pSMB = NULL;
@@ -4667,7 +4926,7 @@ QFSUnixRetry:
4667} 4926}
4668 4927
4669int 4928int
4670CIFSSMBSetFSUnixInfo(const int xid, struct cifsTconInfo *tcon, __u64 cap) 4929CIFSSMBSetFSUnixInfo(const int xid, struct cifs_tcon *tcon, __u64 cap)
4671{ 4930{
4672/* level 0x200 SMB_SET_CIFS_UNIX_INFO */ 4931/* level 0x200 SMB_SET_CIFS_UNIX_INFO */
4673 TRANSACTION2_SETFSI_REQ *pSMB = NULL; 4932 TRANSACTION2_SETFSI_REQ *pSMB = NULL;
@@ -4741,7 +5000,7 @@ SETFSUnixRetry:
4741 5000
4742 5001
4743int 5002int
4744CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon, 5003CIFSSMBQFSPosixInfo(const int xid, struct cifs_tcon *tcon,
4745 struct kstatfs *FSData) 5004 struct kstatfs *FSData)
4746{ 5005{
4747/* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */ 5006/* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
@@ -4834,7 +5093,7 @@ QFSPosixRetry:
4834 in Samba which this routine can run into */ 5093 in Samba which this routine can run into */
4835 5094
4836int 5095int
4837CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, const char *fileName, 5096CIFSSMBSetEOF(const int xid, struct cifs_tcon *tcon, const char *fileName,
4838 __u64 size, bool SetAllocation, 5097 __u64 size, bool SetAllocation,
4839 const struct nls_table *nls_codepage, int remap) 5098 const struct nls_table *nls_codepage, int remap)
4840{ 5099{
@@ -4923,7 +5182,7 @@ SetEOFRetry:
4923} 5182}
4924 5183
4925int 5184int
4926CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size, 5185CIFSSMBSetFileSize(const int xid, struct cifs_tcon *tcon, __u64 size,
4927 __u16 fid, __u32 pid_of_opener, bool SetAllocation) 5186 __u16 fid, __u32 pid_of_opener, bool SetAllocation)
4928{ 5187{
4929 struct smb_com_transaction2_sfi_req *pSMB = NULL; 5188 struct smb_com_transaction2_sfi_req *pSMB = NULL;
@@ -5005,7 +5264,7 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
5005 time and resort to the original setpathinfo level which takes the ancient 5264 time and resort to the original setpathinfo level which takes the ancient
5006 DOS time format with 2 second granularity */ 5265 DOS time format with 2 second granularity */
5007int 5266int
5008CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon, 5267CIFSSMBSetFileInfo(const int xid, struct cifs_tcon *tcon,
5009 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener) 5268 const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
5010{ 5269{
5011 struct smb_com_transaction2_sfi_req *pSMB = NULL; 5270 struct smb_com_transaction2_sfi_req *pSMB = NULL;
@@ -5067,7 +5326,7 @@ CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon,
5067} 5326}
5068 5327
5069int 5328int
5070CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon, 5329CIFSSMBSetFileDisposition(const int xid, struct cifs_tcon *tcon,
5071 bool delete_file, __u16 fid, __u32 pid_of_opener) 5330 bool delete_file, __u16 fid, __u32 pid_of_opener)
5072{ 5331{
5073 struct smb_com_transaction2_sfi_req *pSMB = NULL; 5332 struct smb_com_transaction2_sfi_req *pSMB = NULL;
@@ -5123,7 +5382,7 @@ CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon,
5123} 5382}
5124 5383
5125int 5384int
5126CIFSSMBSetPathInfo(const int xid, struct cifsTconInfo *tcon, 5385CIFSSMBSetPathInfo(const int xid, struct cifs_tcon *tcon,
5127 const char *fileName, const FILE_BASIC_INFO *data, 5386 const char *fileName, const FILE_BASIC_INFO *data,
5128 const struct nls_table *nls_codepage, int remap) 5387 const struct nls_table *nls_codepage, int remap)
5129{ 5388{
@@ -5207,7 +5466,7 @@ SetTimesRetry:
5207 handling it anyway and NT4 was what we thought it would be needed for 5466 handling it anyway and NT4 was what we thought it would be needed for
5208 Do not delete it until we prove whether needed for Win9x though */ 5467 Do not delete it until we prove whether needed for Win9x though */
5209int 5468int
5210CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon, char *fileName, 5469CIFSSMBSetAttrLegacy(int xid, struct cifs_tcon *tcon, char *fileName,
5211 __u16 dos_attrs, const struct nls_table *nls_codepage) 5470 __u16 dos_attrs, const struct nls_table *nls_codepage)
5212{ 5471{
5213 SETATTR_REQ *pSMB = NULL; 5472 SETATTR_REQ *pSMB = NULL;
@@ -5295,7 +5554,7 @@ cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
5295} 5554}
5296 5555
5297int 5556int
5298CIFSSMBUnixSetFileInfo(const int xid, struct cifsTconInfo *tcon, 5557CIFSSMBUnixSetFileInfo(const int xid, struct cifs_tcon *tcon,
5299 const struct cifs_unix_set_info_args *args, 5558 const struct cifs_unix_set_info_args *args,
5300 u16 fid, u32 pid_of_opener) 5559 u16 fid, u32 pid_of_opener)
5301{ 5560{
@@ -5358,7 +5617,7 @@ CIFSSMBUnixSetFileInfo(const int xid, struct cifsTconInfo *tcon,
5358} 5617}
5359 5618
5360int 5619int
5361CIFSSMBUnixSetPathInfo(const int xid, struct cifsTconInfo *tcon, char *fileName, 5620CIFSSMBUnixSetPathInfo(const int xid, struct cifs_tcon *tcon, char *fileName,
5362 const struct cifs_unix_set_info_args *args, 5621 const struct cifs_unix_set_info_args *args,
5363 const struct nls_table *nls_codepage, int remap) 5622 const struct nls_table *nls_codepage, int remap)
5364{ 5623{
@@ -5445,7 +5704,7 @@ setPermsRetry:
5445 * the data isn't copied to it, but the length is returned. 5704 * the data isn't copied to it, but the length is returned.
5446 */ 5705 */
5447ssize_t 5706ssize_t
5448CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, 5707CIFSSMBQAllEAs(const int xid, struct cifs_tcon *tcon,
5449 const unsigned char *searchName, const unsigned char *ea_name, 5708 const unsigned char *searchName, const unsigned char *ea_name,
5450 char *EAData, size_t buf_size, 5709 char *EAData, size_t buf_size,
5451 const struct nls_table *nls_codepage, int remap) 5710 const struct nls_table *nls_codepage, int remap)
@@ -5626,7 +5885,7 @@ QAllEAsOut:
5626} 5885}
5627 5886
5628int 5887int
5629CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, const char *fileName, 5888CIFSSMBSetEA(const int xid, struct cifs_tcon *tcon, const char *fileName,
5630 const char *ea_name, const void *ea_value, 5889 const char *ea_name, const void *ea_value,
5631 const __u16 ea_value_len, const struct nls_table *nls_codepage, 5890 const __u16 ea_value_len, const struct nls_table *nls_codepage,
5632 int remap) 5891 int remap)
@@ -5753,7 +6012,7 @@ SetEARetry:
5753 * incompatible for network fs clients, we could instead simply 6012 * incompatible for network fs clients, we could instead simply
5754 * expose this config flag by adding a future cifs (and smb2) notify ioctl. 6013 * expose this config flag by adding a future cifs (and smb2) notify ioctl.
5755 */ 6014 */
5756int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, 6015int CIFSSMBNotify(const int xid, struct cifs_tcon *tcon,
5757 const int notify_subdirs, const __u16 netfid, 6016 const int notify_subdirs, const __u16 netfid,
5758 __u32 filter, struct file *pfile, int multishot, 6017 __u32 filter, struct file *pfile, int multishot,
5759 const struct nls_table *nls_codepage) 6018 const struct nls_table *nls_codepage)
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index da284e3cb653..6d88b82537c3 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -57,62 +57,6 @@
57 57
58extern mempool_t *cifs_req_poolp; 58extern mempool_t *cifs_req_poolp;
59 59
60struct smb_vol {
61 char *username;
62 char *password;
63 char *domainname;
64 char *UNC;
65 char *UNCip;
66 char *iocharset; /* local code page for mapping to and from Unicode */
67 char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */
68 char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */
69 uid_t cred_uid;
70 uid_t linux_uid;
71 gid_t linux_gid;
72 mode_t file_mode;
73 mode_t dir_mode;
74 unsigned secFlg;
75 bool retry:1;
76 bool intr:1;
77 bool setuids:1;
78 bool override_uid:1;
79 bool override_gid:1;
80 bool dynperm:1;
81 bool noperm:1;
82 bool no_psx_acl:1; /* set if posix acl support should be disabled */
83 bool cifs_acl:1;
84 bool no_xattr:1; /* set if xattr (EA) support should be disabled*/
85 bool server_ino:1; /* use inode numbers from server ie UniqueId */
86 bool direct_io:1;
87 bool strict_io:1; /* strict cache behavior */
88 bool remap:1; /* set to remap seven reserved chars in filenames */
89 bool posix_paths:1; /* unset to not ask for posix pathnames. */
90 bool no_linux_ext:1;
91 bool sfu_emul:1;
92 bool nullauth:1; /* attempt to authenticate with null user */
93 bool nocase:1; /* request case insensitive filenames */
94 bool nobrl:1; /* disable sending byte range locks to srv */
95 bool mand_lock:1; /* send mandatory not posix byte range lock reqs */
96 bool seal:1; /* request transport encryption on share */
97 bool nodfs:1; /* Do not request DFS, even if available */
98 bool local_lease:1; /* check leases only on local system, not remote */
99 bool noblocksnd:1;
100 bool noautotune:1;
101 bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
102 bool fsc:1; /* enable fscache */
103 bool mfsymlinks:1; /* use Minshall+French Symlinks */
104 bool multiuser:1;
105 bool use_smb2:1; /* force smb2 use on mount instead of cifs */
106 unsigned int rsize;
107 unsigned int wsize;
108 bool sockopt_tcp_nodelay:1;
109 unsigned short int port;
110 unsigned long actimeo; /* attribute cache timeout (jiffies) */
111 char *prepath;
112 struct sockaddr_storage srcaddr; /* allow binding to a local IP */
113 struct nls_table *local_nls;
114};
115
116/* FIXME: should these be tunable? */ 60/* FIXME: should these be tunable? */
117#define TLINK_ERROR_EXPIRE (1 * HZ) 61#define TLINK_ERROR_EXPIRE (1 * HZ)
118#define TLINK_IDLE_EXPIRE (600 * HZ) 62#define TLINK_IDLE_EXPIRE (600 * HZ)
@@ -135,9 +79,10 @@ cifs_reconnect(struct TCP_Server_Info *server)
135{ 79{
136 int rc = 0; 80 int rc = 0;
137 struct list_head *tmp, *tmp2; 81 struct list_head *tmp, *tmp2;
138 struct cifsSesInfo *ses; 82 struct cifs_ses *ses;
139 struct cifsTconInfo *tcon; 83 struct cifs_tcon *tcon;
140 struct mid_q_entry *mid_entry; 84 struct mid_q_entry *mid_entry;
85 struct list_head retry_list;
141 86
142 spin_lock(&GlobalMid_Lock); 87 spin_lock(&GlobalMid_Lock);
143 if (server->tcpStatus == CifsExiting) { 88 if (server->tcpStatus == CifsExiting) {
@@ -157,11 +102,11 @@ cifs_reconnect(struct TCP_Server_Info *server)
157 cFYI(1, "%s: marking sessions and tcons for reconnect", __func__); 102 cFYI(1, "%s: marking sessions and tcons for reconnect", __func__);
158 spin_lock(&cifs_tcp_ses_lock); 103 spin_lock(&cifs_tcp_ses_lock);
159 list_for_each(tmp, &server->smb_ses_list) { 104 list_for_each(tmp, &server->smb_ses_list) {
160 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list); 105 ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
161 ses->need_reconnect = true; 106 ses->need_reconnect = true;
162 ses->ipc_tid = 0; 107 ses->ipc_tid = 0;
163 list_for_each(tmp2, &ses->tcon_list) { 108 list_for_each(tmp2, &ses->tcon_list) {
164 tcon = list_entry(tmp2, struct cifsTconInfo, tcon_list); 109 tcon = list_entry(tmp2, struct cifs_tcon, tcon_list);
165 tcon->need_reconnect = true; 110 tcon->need_reconnect = true;
166 } 111 }
167 } 112 }
@@ -189,16 +134,23 @@ cifs_reconnect(struct TCP_Server_Info *server)
189 mutex_unlock(&server->srv_mutex); 134 mutex_unlock(&server->srv_mutex);
190 135
191 /* mark submitted MIDs for retry and issue callback */ 136 /* mark submitted MIDs for retry and issue callback */
192 cFYI(1, "%s: issuing mid callbacks", __func__); 137 INIT_LIST_HEAD(&retry_list);
138 cFYI(1, "%s: moving mids to private list", __func__);
193 spin_lock(&GlobalMid_Lock); 139 spin_lock(&GlobalMid_Lock);
194 list_for_each_safe(tmp, tmp2, &server->pending_mid_q) { 140 list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {
195 mid_entry = list_entry(tmp, struct mid_q_entry, qhead); 141 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
196 if (mid_entry->midState == MID_REQUEST_SUBMITTED) 142 if (mid_entry->midState == MID_REQUEST_SUBMITTED)
197 mid_entry->midState = MID_RETRY_NEEDED; 143 mid_entry->midState = MID_RETRY_NEEDED;
144 list_move(&mid_entry->qhead, &retry_list);
145 }
146 spin_unlock(&GlobalMid_Lock);
147
148 cFYI(1, "%s: issuing mid callbacks", __func__);
149 list_for_each_safe(tmp, tmp2, &retry_list) {
150 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
198 list_del_init(&mid_entry->qhead); 151 list_del_init(&mid_entry->qhead);
199 mid_entry->callback(mid_entry); 152 mid_entry->callback(mid_entry);
200 } 153 }
201 spin_unlock(&GlobalMid_Lock);
202 154
203 while (server->tcpStatus == CifsNeedReconnect) { 155 while (server->tcpStatus == CifsNeedReconnect) {
204 try_to_freeze(); 156 try_to_freeze();
@@ -672,12 +624,12 @@ multi_t2_fnd:
672 mid_entry->when_received = jiffies; 624 mid_entry->when_received = jiffies;
673#endif 625#endif
674 list_del_init(&mid_entry->qhead); 626 list_del_init(&mid_entry->qhead);
675 mid_entry->callback(mid_entry);
676 break; 627 break;
677 } 628 }
678 spin_unlock(&GlobalMid_Lock); 629 spin_unlock(&GlobalMid_Lock);
679 630
680 if (mid_entry != NULL) { 631 if (mid_entry != NULL) {
632 mid_entry->callback(mid_entry);
681 /* Was previous buf put in mpx struct for multi-rsp? */ 633 /* Was previous buf put in mpx struct for multi-rsp? */
682 if (!isMultiRsp) { 634 if (!isMultiRsp) {
683 /* smb buffer will be freed by user thread */ 635 /* smb buffer will be freed by user thread */
@@ -741,15 +693,25 @@ multi_t2_fnd:
741 cifs_small_buf_release(smallbuf); 693 cifs_small_buf_release(smallbuf);
742 694
743 if (!list_empty(&server->pending_mid_q)) { 695 if (!list_empty(&server->pending_mid_q)) {
696 struct list_head dispose_list;
697
698 INIT_LIST_HEAD(&dispose_list);
744 spin_lock(&GlobalMid_Lock); 699 spin_lock(&GlobalMid_Lock);
745 list_for_each_safe(tmp, tmp2, &server->pending_mid_q) { 700 list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {
746 mid_entry = list_entry(tmp, struct mid_q_entry, qhead); 701 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
747 cFYI(1, "Clearing Mid 0x%x - issuing callback", 702 cFYI(1, "Clearing mid 0x%x", mid_entry->mid);
748 mid_entry->mid); 703 mid_entry->midState = MID_SHUTDOWN;
704 list_move(&mid_entry->qhead, &dispose_list);
705 }
706 spin_unlock(&GlobalMid_Lock);
707
708 /* now walk dispose list and issue callbacks */
709 list_for_each_safe(tmp, tmp2, &dispose_list) {
710 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
711 cFYI(1, "Callback mid 0x%x", mid_entry->mid);
749 list_del_init(&mid_entry->qhead); 712 list_del_init(&mid_entry->qhead);
750 mid_entry->callback(mid_entry); 713 mid_entry->callback(mid_entry);
751 } 714 }
752 spin_unlock(&GlobalMid_Lock);
753 /* 1/8th of sec is more than enough time for them to exit */ 715 /* 1/8th of sec is more than enough time for them to exit */
754 msleep(125); 716 msleep(125);
755 } 717 }
@@ -1062,13 +1024,6 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1062 (strnicmp(value, "1", 1) == 0)) { 1024 (strnicmp(value, "1", 1) == 0)) {
1063 /* this is the default */ 1025 /* this is the default */
1064 continue; 1026 continue;
1065 } else if ((strnicmp(value, "smb2", 4) == 0) ||
1066 (strnicmp(value, "2", 1) == 0)) {
1067#ifdef CONFIG_CIFS_SMB2
1068 vol->use_smb2 = true;
1069#else
1070 cERROR(1, "smb2 support not enabled");
1071#endif /* CONFIG_CIFS_SMB2 */
1072 } 1027 }
1073 } else if ((strnicmp(data, "unc", 3) == 0) 1028 } else if ((strnicmp(data, "unc", 3) == 0)
1074 || (strnicmp(data, "target", 6) == 0) 1029 || (strnicmp(data, "target", 6) == 0)
@@ -1404,6 +1359,8 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1404 vol->server_ino = 1; 1359 vol->server_ino = 1;
1405 } else if (strnicmp(data, "noserverino", 9) == 0) { 1360 } else if (strnicmp(data, "noserverino", 9) == 0) {
1406 vol->server_ino = 0; 1361 vol->server_ino = 0;
1362 } else if (strnicmp(data, "rwpidforward", 4) == 0) {
1363 vol->rwpidforward = 1;
1407 } else if (strnicmp(data, "cifsacl", 7) == 0) { 1364 } else if (strnicmp(data, "cifsacl", 7) == 0) {
1408 vol->cifs_acl = 1; 1365 vol->cifs_acl = 1;
1409 } else if (strnicmp(data, "nocifsacl", 9) == 0) { 1366 } else if (strnicmp(data, "nocifsacl", 9) == 0) {
@@ -1640,16 +1597,35 @@ match_security(struct TCP_Server_Info *server, struct smb_vol *vol)
1640 1597
1641 /* now check if signing mode is acceptable */ 1598 /* now check if signing mode is acceptable */
1642 if ((secFlags & CIFSSEC_MAY_SIGN) == 0 && 1599 if ((secFlags & CIFSSEC_MAY_SIGN) == 0 &&
1643 (server->secMode & SECMODE_SIGN_REQUIRED)) 1600 (server->sec_mode & SECMODE_SIGN_REQUIRED))
1644 return false; 1601 return false;
1645 else if (((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) && 1602 else if (((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) &&
1646 (server->secMode & 1603 (server->sec_mode &
1647 (SECMODE_SIGN_ENABLED|SECMODE_SIGN_REQUIRED)) == 0) 1604 (SECMODE_SIGN_ENABLED|SECMODE_SIGN_REQUIRED)) == 0)
1648 return false; 1605 return false;
1649 1606
1650 return true; 1607 return true;
1651} 1608}
1652 1609
1610static int match_server(struct TCP_Server_Info *server, struct sockaddr *addr,
1611 struct smb_vol *vol)
1612{
1613 if (!net_eq(cifs_net_ns(server), current->nsproxy->net_ns))
1614 return 0;
1615
1616 if (!match_address(server, addr,
1617 (struct sockaddr *)&vol->srcaddr))
1618 return 0;
1619
1620 if (!match_port(server, addr))
1621 return 0;
1622
1623 if (!match_security(server, vol))
1624 return 0;
1625
1626 return 1;
1627}
1628
1653static struct TCP_Server_Info * 1629static struct TCP_Server_Info *
1654cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol) 1630cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol)
1655{ 1631{
@@ -1657,17 +1633,7 @@ cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol)
1657 1633
1658 spin_lock(&cifs_tcp_ses_lock); 1634 spin_lock(&cifs_tcp_ses_lock);
1659 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) { 1635 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
1660 if (!net_eq(cifs_net_ns(server), current->nsproxy->net_ns)) 1636 if (!match_server(server, addr, vol))
1661 continue;
1662
1663 if (!match_address(server, addr,
1664 (struct sockaddr *)&vol->srcaddr))
1665 continue;
1666
1667 if (!match_port(server, addr))
1668 continue;
1669
1670 if (!match_security(server, vol))
1671 continue; 1637 continue;
1672 1638
1673 ++server->srv_count; 1639 ++server->srv_count;
@@ -1861,32 +1827,39 @@ out_err:
1861 return ERR_PTR(rc); 1827 return ERR_PTR(rc);
1862} 1828}
1863 1829
1864static struct cifsSesInfo * 1830static int match_session(struct cifs_ses *ses, struct smb_vol *vol)
1831{
1832 switch (ses->server->secType) {
1833 case Kerberos:
1834 if (vol->cred_uid != ses->cred_uid)
1835 return 0;
1836 break;
1837 default:
1838 /* anything else takes username/password */
1839 if (ses->user_name == NULL)
1840 return 0;
1841 if (strncmp(ses->user_name, vol->username,
1842 MAX_USERNAME_SIZE))
1843 return 0;
1844 if (strlen(vol->username) != 0 &&
1845 ses->password != NULL &&
1846 strncmp(ses->password,
1847 vol->password ? vol->password : "",
1848 MAX_PASSWORD_SIZE))
1849 return 0;
1850 }
1851 return 1;
1852}
1853
1854static struct cifs_ses *
1865cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol) 1855cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol)
1866{ 1856{
1867 struct cifsSesInfo *ses; 1857 struct cifs_ses *ses;
1868 1858
1869 spin_lock(&cifs_tcp_ses_lock); 1859 spin_lock(&cifs_tcp_ses_lock);
1870 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { 1860 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
1871 switch (server->secType) { 1861 if (!match_session(ses, vol))
1872 case Kerberos: 1862 continue;
1873 if (vol->cred_uid != ses->cred_uid)
1874 continue;
1875 break;
1876 default:
1877 /* anything else takes username/password */
1878 if (ses->user_name == NULL)
1879 continue;
1880 if (strncmp(ses->user_name, vol->username,
1881 MAX_USERNAME_SIZE))
1882 continue;
1883 if (strlen(vol->username) != 0 &&
1884 ses->password != NULL &&
1885 strncmp(ses->password,
1886 vol->password ? vol->password : "",
1887 MAX_PASSWORD_SIZE))
1888 continue;
1889 }
1890 ++ses->ses_count; 1863 ++ses->ses_count;
1891 spin_unlock(&cifs_tcp_ses_lock); 1864 spin_unlock(&cifs_tcp_ses_lock);
1892 return ses; 1865 return ses;
@@ -1896,7 +1869,7 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol)
1896} 1869}
1897 1870
1898static void 1871static void
1899cifs_put_smb_ses(struct cifsSesInfo *ses) 1872cifs_put_smb_ses(struct cifs_ses *ses)
1900{ 1873{
1901 int xid; 1874 int xid;
1902 struct TCP_Server_Info *server = ses->server; 1875 struct TCP_Server_Info *server = ses->server;
@@ -1922,11 +1895,11 @@ cifs_put_smb_ses(struct cifsSesInfo *ses)
1922 1895
1923static bool warned_on_ntlm; /* globals init to false automatically */ 1896static bool warned_on_ntlm; /* globals init to false automatically */
1924 1897
1925static struct cifsSesInfo * 1898static struct cifs_ses *
1926cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) 1899cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
1927{ 1900{
1928 int rc = -ENOMEM, xid; 1901 int rc = -ENOMEM, xid;
1929 struct cifsSesInfo *ses; 1902 struct cifs_ses *ses;
1930 struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr; 1903 struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
1931 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr; 1904 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr;
1932 1905
@@ -2029,20 +2002,26 @@ get_ses_fail:
2029 return ERR_PTR(rc); 2002 return ERR_PTR(rc);
2030} 2003}
2031 2004
2032static struct cifsTconInfo * 2005static int match_tcon(struct cifs_tcon *tcon, const char *unc)
2033cifs_find_tcon(struct cifsSesInfo *ses, const char *unc) 2006{
2007 if (tcon->tidStatus == CifsExiting)
2008 return 0;
2009 if (strncmp(tcon->treeName, unc, MAX_TREE_SIZE))
2010 return 0;
2011 return 1;
2012}
2013
2014static struct cifs_tcon *
2015cifs_find_tcon(struct cifs_ses *ses, const char *unc)
2034{ 2016{
2035 struct list_head *tmp; 2017 struct list_head *tmp;
2036 struct cifsTconInfo *tcon; 2018 struct cifs_tcon *tcon;
2037 2019
2038 spin_lock(&cifs_tcp_ses_lock); 2020 spin_lock(&cifs_tcp_ses_lock);
2039 list_for_each(tmp, &ses->tcon_list) { 2021 list_for_each(tmp, &ses->tcon_list) {
2040 tcon = list_entry(tmp, struct cifsTconInfo, tcon_list); 2022 tcon = list_entry(tmp, struct cifs_tcon, tcon_list);
2041 if (tcon->tidStatus == CifsExiting) 2023 if (!match_tcon(tcon, unc))
2042 continue;
2043 if (strncmp(tcon->treeName, unc, MAX_TREE_SIZE))
2044 continue; 2024 continue;
2045
2046 ++tcon->tc_count; 2025 ++tcon->tc_count;
2047 spin_unlock(&cifs_tcp_ses_lock); 2026 spin_unlock(&cifs_tcp_ses_lock);
2048 return tcon; 2027 return tcon;
@@ -2052,10 +2031,10 @@ cifs_find_tcon(struct cifsSesInfo *ses, const char *unc)
2052} 2031}
2053 2032
2054static void 2033static void
2055cifs_put_tcon(struct cifsTconInfo *tcon) 2034cifs_put_tcon(struct cifs_tcon *tcon)
2056{ 2035{
2057 int xid; 2036 int xid;
2058 struct cifsSesInfo *ses = tcon->ses; 2037 struct cifs_ses *ses = tcon->ses;
2059 2038
2060 cFYI(1, "%s: tc_count=%d\n", __func__, tcon->tc_count); 2039 cFYI(1, "%s: tc_count=%d\n", __func__, tcon->tc_count);
2061 spin_lock(&cifs_tcp_ses_lock); 2040 spin_lock(&cifs_tcp_ses_lock);
@@ -2076,11 +2055,11 @@ cifs_put_tcon(struct cifsTconInfo *tcon)
2076 cifs_put_smb_ses(ses); 2055 cifs_put_smb_ses(ses);
2077} 2056}
2078 2057
2079static struct cifsTconInfo * 2058static struct cifs_tcon *
2080cifs_get_tcon(struct cifsSesInfo *ses, struct smb_vol *volume_info) 2059cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
2081{ 2060{
2082 int rc, xid; 2061 int rc, xid;
2083 struct cifsTconInfo *tcon; 2062 struct cifs_tcon *tcon;
2084 2063
2085 tcon = cifs_find_tcon(ses, volume_info->UNC); 2064 tcon = cifs_find_tcon(ses, volume_info->UNC);
2086 if (tcon) { 2065 if (tcon) {
@@ -2169,8 +2148,102 @@ cifs_put_tlink(struct tcon_link *tlink)
2169 return; 2148 return;
2170} 2149}
2171 2150
2151static inline struct tcon_link *
2152cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb);
2153
2154static int
2155compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data)
2156{
2157 struct cifs_sb_info *old = CIFS_SB(sb);
2158 struct cifs_sb_info *new = mnt_data->cifs_sb;
2159
2160 if ((sb->s_flags & CIFS_MS_MASK) != (mnt_data->flags & CIFS_MS_MASK))
2161 return 0;
2162
2163 if ((old->mnt_cifs_flags & CIFS_MOUNT_MASK) !=
2164 (new->mnt_cifs_flags & CIFS_MOUNT_MASK))
2165 return 0;
2166
2167 if (old->rsize != new->rsize)
2168 return 0;
2169
2170 /*
2171 * We want to share sb only if we don't specify wsize or specified wsize
2172 * is greater or equal than existing one.
2173 */
2174 if (new->wsize && new->wsize < old->wsize)
2175 return 0;
2176
2177 if (old->mnt_uid != new->mnt_uid || old->mnt_gid != new->mnt_gid)
2178 return 0;
2179
2180 if (old->mnt_file_mode != new->mnt_file_mode ||
2181 old->mnt_dir_mode != new->mnt_dir_mode)
2182 return 0;
2183
2184 if (strcmp(old->local_nls->charset, new->local_nls->charset))
2185 return 0;
2186
2187 if (old->actimeo != new->actimeo)
2188 return 0;
2189
2190 return 1;
2191}
2192
2172int 2193int
2173get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path, 2194cifs_match_super(struct super_block *sb, void *data)
2195{
2196 struct cifs_mnt_data *mnt_data = (struct cifs_mnt_data *)data;
2197 struct smb_vol *volume_info;
2198 struct cifs_sb_info *cifs_sb;
2199 struct TCP_Server_Info *tcp_srv;
2200 struct cifs_ses *ses;
2201 struct cifs_tcon *tcon;
2202 struct tcon_link *tlink;
2203 struct sockaddr_storage addr;
2204 int rc = 0;
2205
2206 memset(&addr, 0, sizeof(struct sockaddr_storage));
2207
2208 spin_lock(&cifs_tcp_ses_lock);
2209 cifs_sb = CIFS_SB(sb);
2210 tlink = cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));
2211 if (IS_ERR(tlink)) {
2212 spin_unlock(&cifs_tcp_ses_lock);
2213 return rc;
2214 }
2215 tcon = tlink_tcon(tlink);
2216 ses = tcon->ses;
2217 tcp_srv = ses->server;
2218
2219 volume_info = mnt_data->vol;
2220
2221 if (!volume_info->UNCip || !volume_info->UNC)
2222 goto out;
2223
2224 rc = cifs_fill_sockaddr((struct sockaddr *)&addr,
2225 volume_info->UNCip,
2226 strlen(volume_info->UNCip),
2227 volume_info->port);
2228 if (!rc)
2229 goto out;
2230
2231 if (!match_server(tcp_srv, (struct sockaddr *)&addr, volume_info) ||
2232 !match_session(ses, volume_info) ||
2233 !match_tcon(tcon, volume_info->UNC)) {
2234 rc = 0;
2235 goto out;
2236 }
2237
2238 rc = compare_mount_options(sb, mnt_data);
2239out:
2240 cifs_put_tlink(tlink);
2241 spin_unlock(&cifs_tcp_ses_lock);
2242 return rc;
2243}
2244
2245int
2246get_dfs_path(int xid, struct cifs_ses *pSesInfo, const char *old_path,
2174 const struct nls_table *nls_codepage, unsigned int *pnum_referrals, 2247 const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
2175 struct dfs_info3_param **preferrals, int remap) 2248 struct dfs_info3_param **preferrals, int remap)
2176{ 2249{
@@ -2469,7 +2542,7 @@ ip_connect(struct TCP_Server_Info *server)
2469 return generic_ip_connect(server); 2542 return generic_ip_connect(server);
2470} 2543}
2471 2544
2472void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, 2545void reset_cifs_unix_caps(int xid, struct cifs_tcon *tcon,
2473 struct super_block *sb, struct smb_vol *vol_info) 2546 struct super_block *sb, struct smb_vol *vol_info)
2474{ 2547{
2475 /* if we are reconnecting then should we check to see if 2548 /* if we are reconnecting then should we check to see if
@@ -2498,7 +2571,7 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
2498 2571
2499 if (!CIFSSMBQFSUnixInfo(xid, tcon)) { 2572 if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
2500 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability); 2573 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
2501 2574 cFYI(1, "unix caps which server supports %lld", cap);
2502 /* check for reconnect case in which we do not 2575 /* check for reconnect case in which we do not
2503 want to change the mount behavior if we can avoid it */ 2576 want to change the mount behavior if we can avoid it */
2504 if (vol_info == NULL) { 2577 if (vol_info == NULL) {
@@ -2516,6 +2589,9 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
2516 } 2589 }
2517 } 2590 }
2518 2591
2592 if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)
2593 cERROR(1, "per-share encryption not supported yet");
2594
2519 cap &= CIFS_UNIX_CAP_MASK; 2595 cap &= CIFS_UNIX_CAP_MASK;
2520 if (vol_info && vol_info->no_psx_acl) 2596 if (vol_info && vol_info->no_psx_acl)
2521 cap &= ~CIFS_UNIX_POSIX_ACL_CAP; 2597 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
@@ -2534,12 +2610,6 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
2534 CIFS_MOUNT_POSIX_PATHS; 2610 CIFS_MOUNT_POSIX_PATHS;
2535 } 2611 }
2536 2612
2537 /* We might be setting the path sep back to a different
2538 form if we are reconnecting and the server switched its
2539 posix path capability for this share */
2540 if (sb && (CIFS_SB(sb)->prepathlen > 0))
2541 CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb));
2542
2543 if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) { 2613 if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) {
2544 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) { 2614 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
2545 CIFS_SB(sb)->rsize = 127 * 1024; 2615 CIFS_SB(sb)->rsize = 127 * 1024;
@@ -2564,6 +2634,10 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
2564 cFYI(1, "very large read cap"); 2634 cFYI(1, "very large read cap");
2565 if (cap & CIFS_UNIX_LARGE_WRITE_CAP) 2635 if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
2566 cFYI(1, "very large write cap"); 2636 cFYI(1, "very large write cap");
2637 if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)
2638 cFYI(1, "transport encryption cap");
2639 if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)
2640 cFYI(1, "mandatory transport encryption cap");
2567#endif /* CIFS_DEBUG2 */ 2641#endif /* CIFS_DEBUG2 */
2568 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) { 2642 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
2569 if (vol_info == NULL) { 2643 if (vol_info == NULL) {
@@ -2580,28 +2654,8 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
2580 } 2654 }
2581} 2655}
2582 2656
2583static void 2657void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
2584convert_delimiter(char *path, char delim) 2658 struct cifs_sb_info *cifs_sb)
2585{
2586 int i;
2587 char old_delim;
2588
2589 if (path == NULL)
2590 return;
2591
2592 if (delim == '/')
2593 old_delim = '\\';
2594 else
2595 old_delim = '/';
2596
2597 for (i = 0; path[i] != '\0'; i++) {
2598 if (path[i] == old_delim)
2599 path[i] = delim;
2600 }
2601}
2602
2603static void setup_cifs_sb(struct smb_vol *pvolume_info,
2604 struct cifs_sb_info *cifs_sb)
2605{ 2659{
2606 INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks); 2660 INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks);
2607 2661
@@ -2615,40 +2669,19 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
2615 else /* default */ 2669 else /* default */
2616 cifs_sb->rsize = CIFSMaxBufSize; 2670 cifs_sb->rsize = CIFSMaxBufSize;
2617 2671
2618 if (pvolume_info->wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
2619 cERROR(1, "wsize %d too large, using 4096 instead",
2620 pvolume_info->wsize);
2621 cifs_sb->wsize = 4096;
2622 } else if (pvolume_info->wsize)
2623 cifs_sb->wsize = pvolume_info->wsize;
2624 else
2625 cifs_sb->wsize = min_t(const int,
2626 PAGEVEC_SIZE * PAGE_CACHE_SIZE,
2627 127*1024);
2628 /* old default of CIFSMaxBufSize was too small now
2629 that SMB Write2 can send multiple pages in kvec.
2630 RFC1001 does not describe what happens when frame
2631 bigger than 128K is sent so use that as max in
2632 conjunction with 52K kvec constraint on arch with 4K
2633 page size */
2634
2635 if (cifs_sb->rsize < 2048) { 2672 if (cifs_sb->rsize < 2048) {
2636 cifs_sb->rsize = 2048; 2673 cifs_sb->rsize = 2048;
2637 /* Windows ME may prefer this */ 2674 /* Windows ME may prefer this */
2638 cFYI(1, "readsize set to minimum: 2048"); 2675 cFYI(1, "readsize set to minimum: 2048");
2639 } 2676 }
2640 /* calculate prepath */ 2677
2641 cifs_sb->prepath = pvolume_info->prepath; 2678 /*
2642 if (cifs_sb->prepath) { 2679 * Temporarily set wsize for matching superblock. If we end up using
2643 cifs_sb->prepathlen = strlen(cifs_sb->prepath); 2680 * new sb then cifs_negotiate_wsize will later negotiate it downward
2644 /* we can not convert the / to \ in the path 2681 * if needed.
2645 separators in the prefixpath yet because we do not 2682 */
2646 know (until reset_cifs_unix_caps is called later) 2683 cifs_sb->wsize = pvolume_info->wsize;
2647 whether POSIX PATH CAP is available. We normalize 2684
2648 the / to \ after reset_cifs_unix_caps is called */
2649 pvolume_info->prepath = NULL;
2650 } else
2651 cifs_sb->prepathlen = 0;
2652 cifs_sb->mnt_uid = pvolume_info->linux_uid; 2685 cifs_sb->mnt_uid = pvolume_info->linux_uid;
2653 cifs_sb->mnt_gid = pvolume_info->linux_gid; 2686 cifs_sb->mnt_gid = pvolume_info->linux_gid;
2654 cifs_sb->mnt_file_mode = pvolume_info->file_mode; 2687 cifs_sb->mnt_file_mode = pvolume_info->file_mode;
@@ -2657,6 +2690,7 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
2657 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode); 2690 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode);
2658 2691
2659 cifs_sb->actimeo = pvolume_info->actimeo; 2692 cifs_sb->actimeo = pvolume_info->actimeo;
2693 cifs_sb->local_nls = pvolume_info->local_nls;
2660 2694
2661 if (pvolume_info->noperm) 2695 if (pvolume_info->noperm)
2662 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM; 2696 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
@@ -2676,6 +2710,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
2676 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOSSYNC; 2710 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOSSYNC;
2677 if (pvolume_info->mand_lock) 2711 if (pvolume_info->mand_lock)
2678 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL; 2712 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL;
2713 if (pvolume_info->rwpidforward)
2714 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RWPIDFORWARD;
2679 if (pvolume_info->cifs_acl) 2715 if (pvolume_info->cifs_acl)
2680 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL; 2716 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
2681 if (pvolume_info->override_uid) 2717 if (pvolume_info->override_uid)
@@ -2709,8 +2745,55 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
2709 "mount option supported"); 2745 "mount option supported");
2710} 2746}
2711 2747
2748/*
2749 * When the server supports very large writes via POSIX extensions, we can
2750 * allow up to 2^24 - PAGE_CACHE_SIZE.
2751 *
2752 * Note that this might make for "interesting" allocation problems during
2753 * writeback however (as we have to allocate an array of pointers for the
2754 * pages). A 16M write means ~32kb page array with PAGE_CACHE_SIZE == 4096.
2755 */
2756#define CIFS_MAX_WSIZE ((1<<24) - PAGE_CACHE_SIZE)
2757
2758/*
2759 * When the server doesn't allow large posix writes, default to a wsize of
2760 * 128k - PAGE_CACHE_SIZE -- one page less than the largest frame size
2761 * described in RFC1001. This allows space for the header without going over
2762 * that by default.
2763 */
2764#define CIFS_MAX_RFC1001_WSIZE (128 * 1024 - PAGE_CACHE_SIZE)
2765
2766/*
2767 * The default wsize is 1M. find_get_pages seems to return a maximum of 256
2768 * pages in a single call. With PAGE_CACHE_SIZE == 4k, this means we can fill
2769 * a single wsize request with a single call.
2770 */
2771#define CIFS_DEFAULT_WSIZE (1024 * 1024)
2772
2773static unsigned int
2774cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info)
2775{
2776 __u64 unix_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
2777 struct TCP_Server_Info *server = tcon->ses->server;
2778 unsigned int wsize = pvolume_info->wsize ? pvolume_info->wsize :
2779 CIFS_DEFAULT_WSIZE;
2780
2781 /* can server support 24-bit write sizes? (via UNIX extensions) */
2782 if (!tcon->unix_ext || !(unix_cap & CIFS_UNIX_LARGE_WRITE_CAP))
2783 wsize = min_t(unsigned int, wsize, CIFS_MAX_RFC1001_WSIZE);
2784
2785 /* no CAP_LARGE_WRITE_X? Limit it to 16 bits */
2786 if (!(server->capabilities & CAP_LARGE_WRITE_X))
2787 wsize = min_t(unsigned int, wsize, USHRT_MAX);
2788
2789 /* hard limit of CIFS_MAX_WSIZE */
2790 wsize = min_t(unsigned int, wsize, CIFS_MAX_WSIZE);
2791
2792 return wsize;
2793}
2794
2712static int 2795static int
2713is_path_accessible(int xid, struct cifsTconInfo *tcon, 2796is_path_accessible(int xid, struct cifs_tcon *tcon,
2714 struct cifs_sb_info *cifs_sb, const char *full_path) 2797 struct cifs_sb_info *cifs_sb, const char *full_path)
2715{ 2798{
2716 int rc; 2799 int rc;
@@ -2733,8 +2816,8 @@ is_path_accessible(int xid, struct cifsTconInfo *tcon,
2733 return rc; 2816 return rc;
2734} 2817}
2735 2818
2736static void 2819void
2737cleanup_volume_info(struct smb_vol **pvolume_info) 2820cifs_cleanup_volume_info(struct smb_vol **pvolume_info)
2738{ 2821{
2739 struct smb_vol *volume_info; 2822 struct smb_vol *volume_info;
2740 2823
@@ -2764,24 +2847,13 @@ build_unc_path_to_root(const struct smb_vol *volume_info,
2764 char *full_path; 2847 char *full_path;
2765 2848
2766 int unc_len = strnlen(volume_info->UNC, MAX_TREE_SIZE + 1); 2849 int unc_len = strnlen(volume_info->UNC, MAX_TREE_SIZE + 1);
2767 full_path = kmalloc(unc_len + cifs_sb->prepathlen + 1, GFP_KERNEL); 2850 full_path = kmalloc(unc_len + 1, GFP_KERNEL);
2768 if (full_path == NULL) 2851 if (full_path == NULL)
2769 return ERR_PTR(-ENOMEM); 2852 return ERR_PTR(-ENOMEM);
2770 2853
2771 strncpy(full_path, volume_info->UNC, unc_len); 2854 strncpy(full_path, volume_info->UNC, unc_len);
2772 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) { 2855 full_path[unc_len] = 0; /* add trailing null */
2773 int i; 2856 convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb));
2774 for (i = 0; i < unc_len; i++) {
2775 if (full_path[i] == '\\')
2776 full_path[i] = '/';
2777 }
2778 }
2779
2780 if (cifs_sb->prepathlen)
2781 strncpy(full_path + unc_len, cifs_sb->prepath,
2782 cifs_sb->prepathlen);
2783
2784 full_path[unc_len + cifs_sb->prepathlen] = 0; /* add trailing null */
2785 return full_path; 2857 return full_path;
2786} 2858}
2787 2859
@@ -2796,7 +2868,7 @@ build_unc_path_to_root(const struct smb_vol *volume_info,
2796 * determine whether there were referrals. 2868 * determine whether there were referrals.
2797 */ 2869 */
2798static int 2870static int
2799expand_dfs_referral(int xid, struct cifsSesInfo *pSesInfo, 2871expand_dfs_referral(int xid, struct cifs_ses *pSesInfo,
2800 struct smb_vol *volume_info, struct cifs_sb_info *cifs_sb, 2872 struct smb_vol *volume_info, struct cifs_sb_info *cifs_sb,
2801 int check_prefix) 2873 int check_prefix)
2802{ 2874{
@@ -2840,40 +2912,13 @@ expand_dfs_referral(int xid, struct cifsSesInfo *pSesInfo,
2840} 2912}
2841#endif 2913#endif
2842 2914
2843int 2915int cifs_setup_volume_info(struct smb_vol **pvolume_info, char *mount_data,
2844cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, 2916 const char *devname)
2845 const char *devname)
2846{ 2917{
2847 int rc;
2848 int xid;
2849 struct smb_vol *volume_info; 2918 struct smb_vol *volume_info;
2850 struct cifsSesInfo *pSesInfo; 2919 int rc = 0;
2851 struct cifsTconInfo *tcon;
2852 struct TCP_Server_Info *srvTcp;
2853 char *full_path;
2854 struct tcon_link *tlink;
2855#ifdef CONFIG_CIFS_DFS_UPCALL
2856 int referral_walks_count = 0;
2857try_mount_again:
2858 /* cleanup activities if we're chasing a referral */
2859 if (referral_walks_count) {
2860 if (tcon)
2861 cifs_put_tcon(tcon);
2862 else if (pSesInfo)
2863 cifs_put_smb_ses(pSesInfo);
2864
2865 cleanup_volume_info(&volume_info);
2866 FreeXid(xid);
2867 }
2868#endif
2869 rc = 0;
2870 tcon = NULL;
2871 pSesInfo = NULL;
2872 srvTcp = NULL;
2873 full_path = NULL;
2874 tlink = NULL;
2875 2920
2876 xid = GetXid(); 2921 *pvolume_info = NULL;
2877 2922
2878 volume_info = kzalloc(sizeof(struct smb_vol), GFP_KERNEL); 2923 volume_info = kzalloc(sizeof(struct smb_vol), GFP_KERNEL);
2879 if (!volume_info) { 2924 if (!volume_info) {
@@ -2881,7 +2926,7 @@ try_mount_again:
2881 goto out; 2926 goto out;
2882 } 2927 }
2883 2928
2884 if (cifs_parse_mount_options(cifs_sb->mountdata, devname, 2929 if (cifs_parse_mount_options(mount_data, devname,
2885 volume_info)) { 2930 volume_info)) {
2886 rc = -EINVAL; 2931 rc = -EINVAL;
2887 goto out; 2932 goto out;
@@ -2914,7 +2959,46 @@ try_mount_again:
2914 goto out; 2959 goto out;
2915 } 2960 }
2916 } 2961 }
2917 cifs_sb->local_nls = volume_info->local_nls; 2962
2963 *pvolume_info = volume_info;
2964 return rc;
2965out:
2966 cifs_cleanup_volume_info(&volume_info);
2967 return rc;
2968}
2969
2970int
2971cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2972 struct smb_vol *volume_info, const char *devname)
2973{
2974 int rc = 0;
2975 int xid;
2976 struct cifs_ses *pSesInfo;
2977 struct cifs_tcon *tcon;
2978 struct TCP_Server_Info *srvTcp;
2979 char *full_path;
2980 struct tcon_link *tlink;
2981#ifdef CONFIG_CIFS_DFS_UPCALL
2982 int referral_walks_count = 0;
2983try_mount_again:
2984 /* cleanup activities if we're chasing a referral */
2985 if (referral_walks_count) {
2986 if (tcon)
2987 cifs_put_tcon(tcon);
2988 else if (pSesInfo)
2989 cifs_put_smb_ses(pSesInfo);
2990
2991 cifs_cleanup_volume_info(&volume_info);
2992 FreeXid(xid);
2993 }
2994#endif
2995 tcon = NULL;
2996 pSesInfo = NULL;
2997 srvTcp = NULL;
2998 full_path = NULL;
2999 tlink = NULL;
3000
3001 xid = GetXid();
2918 3002
2919 /* get a reference to a tcp session */ 3003 /* get a reference to a tcp session */
2920 srvTcp = cifs_get_tcp_session(volume_info); 3004 srvTcp = cifs_get_tcp_session(volume_info);
@@ -2931,7 +3015,6 @@ try_mount_again:
2931 goto mount_fail_check; 3015 goto mount_fail_check;
2932 } 3016 }
2933 3017
2934 setup_cifs_sb(volume_info, cifs_sb);
2935 if (pSesInfo->capabilities & CAP_LARGE_FILES) 3018 if (pSesInfo->capabilities & CAP_LARGE_FILES)
2936 sb->s_maxbytes = MAX_LFS_FILESIZE; 3019 sb->s_maxbytes = MAX_LFS_FILESIZE;
2937 else 3020 else
@@ -2948,35 +3031,36 @@ try_mount_again:
2948 goto remote_path_check; 3031 goto remote_path_check;
2949 } 3032 }
2950 3033
2951 /* do not care if following two calls succeed - informational */
2952 if (!tcon->ipc) {
2953 CIFSSMBQFSDeviceInfo(xid, tcon);
2954 CIFSSMBQFSAttributeInfo(xid, tcon);
2955 }
2956
2957 /* tell server which Unix caps we support */ 3034 /* tell server which Unix caps we support */
2958 if (tcon->ses->capabilities & CAP_UNIX) 3035 if (tcon->ses->capabilities & CAP_UNIX) {
2959 /* reset of caps checks mount to see if unix extensions 3036 /* reset of caps checks mount to see if unix extensions
2960 disabled for just this mount */ 3037 disabled for just this mount */
2961 reset_cifs_unix_caps(xid, tcon, sb, volume_info); 3038 reset_cifs_unix_caps(xid, tcon, sb, volume_info);
2962 else 3039 if ((tcon->ses->server->tcpStatus == CifsNeedReconnect) &&
3040 (le64_to_cpu(tcon->fsUnixInfo.Capability) &
3041 CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)) {
3042 rc = -EACCES;
3043 goto mount_fail_check;
3044 }
3045 } else
2963 tcon->unix_ext = 0; /* server does not support them */ 3046 tcon->unix_ext = 0; /* server does not support them */
2964 3047
2965 /* convert forward to back slashes in prepath here if needed */ 3048 /* do not care if following two calls succeed - informational */
2966 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0) 3049 if (!tcon->ipc) {
2967 convert_delimiter(cifs_sb->prepath, CIFS_DIR_SEP(cifs_sb)); 3050 CIFSSMBQFSDeviceInfo(xid, tcon);
3051 CIFSSMBQFSAttributeInfo(xid, tcon);
3052 }
2968 3053
2969 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) { 3054 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
2970 cifs_sb->rsize = 1024 * 127; 3055 cifs_sb->rsize = 1024 * 127;
2971 cFYI(DBG2, "no very large read support, rsize now 127K"); 3056 cFYI(DBG2, "no very large read support, rsize now 127K");
2972 } 3057 }
2973 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
2974 cifs_sb->wsize = min(cifs_sb->wsize,
2975 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
2976 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X)) 3058 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
2977 cifs_sb->rsize = min(cifs_sb->rsize, 3059 cifs_sb->rsize = min(cifs_sb->rsize,
2978 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)); 3060 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
2979 3061
3062 cifs_sb->wsize = cifs_negotiate_wsize(tcon, volume_info);
3063
2980remote_path_check: 3064remote_path_check:
2981#ifdef CONFIG_CIFS_DFS_UPCALL 3065#ifdef CONFIG_CIFS_DFS_UPCALL
2982 /* 3066 /*
@@ -2996,10 +3080,10 @@ remote_path_check:
2996 } 3080 }
2997#endif 3081#endif
2998 3082
2999 /* check if a whole path (including prepath) is not remote */ 3083 /* check if a whole path is not remote */
3000 if (!rc && tcon) { 3084 if (!rc && tcon) {
3001 /* build_path_to_root works only when we have a valid tcon */ 3085 /* build_path_to_root works only when we have a valid tcon */
3002 full_path = cifs_build_path_to_root(cifs_sb, tcon); 3086 full_path = cifs_build_path_to_root(volume_info, cifs_sb, tcon);
3003 if (full_path == NULL) { 3087 if (full_path == NULL) {
3004 rc = -ENOMEM; 3088 rc = -ENOMEM;
3005 goto mount_fail_check; 3089 goto mount_fail_check;
@@ -3025,10 +3109,6 @@ remote_path_check:
3025 rc = -ELOOP; 3109 rc = -ELOOP;
3026 goto mount_fail_check; 3110 goto mount_fail_check;
3027 } 3111 }
3028 /* convert forward to back slashes in prepath here if needed */
3029 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
3030 convert_delimiter(cifs_sb->prepath,
3031 CIFS_DIR_SEP(cifs_sb));
3032 3112
3033 rc = expand_dfs_referral(xid, pSesInfo, volume_info, cifs_sb, 3113 rc = expand_dfs_referral(xid, pSesInfo, volume_info, cifs_sb,
3034 true); 3114 true);
@@ -3087,14 +3167,13 @@ mount_fail_check:
3087 password will be freed at unmount time) */ 3167 password will be freed at unmount time) */
3088out: 3168out:
3089 /* zero out password before freeing */ 3169 /* zero out password before freeing */
3090 cleanup_volume_info(&volume_info);
3091 FreeXid(xid); 3170 FreeXid(xid);
3092 return rc; 3171 return rc;
3093} 3172}
3094 3173
3095int 3174int
3096CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, 3175CIFSTCon(unsigned int xid, struct cifs_ses *ses,
3097 const char *tree, struct cifsTconInfo *tcon, 3176 const char *tree, struct cifs_tcon *tcon,
3098 const struct nls_table *nls_codepage) 3177 const struct nls_table *nls_codepage)
3099{ 3178{
3100 struct smb_hdr *smb_buffer; 3179 struct smb_hdr *smb_buffer;
@@ -3126,7 +3205,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3126 pSMB->AndXCommand = 0xFF; 3205 pSMB->AndXCommand = 0xFF;
3127 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO); 3206 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
3128 bcc_ptr = &pSMB->Password[0]; 3207 bcc_ptr = &pSMB->Password[0];
3129 if ((ses->server->secMode) & SECMODE_USER) { 3208 if ((ses->server->sec_mode) & SECMODE_USER) {
3130 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */ 3209 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
3131 *bcc_ptr = 0; /* password is null byte */ 3210 *bcc_ptr = 0; /* password is null byte */
3132 bcc_ptr++; /* skip password */ 3211 bcc_ptr++; /* skip password */
@@ -3143,7 +3222,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3143 if ((global_secflags & CIFSSEC_MAY_LANMAN) && 3222 if ((global_secflags & CIFSSEC_MAY_LANMAN) &&
3144 (ses->server->secType == LANMAN)) 3223 (ses->server->secType == LANMAN))
3145 calc_lanman_hash(tcon->password, ses->server->cryptkey, 3224 calc_lanman_hash(tcon->password, ses->server->cryptkey,
3146 ses->server->secMode & 3225 ses->server->sec_mode &
3147 SECMODE_PW_ENCRYPT ? true : false, 3226 SECMODE_PW_ENCRYPT ? true : false,
3148 bcc_ptr); 3227 bcc_ptr);
3149 else 3228 else
@@ -3159,7 +3238,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3159 } 3238 }
3160 } 3239 }
3161 3240
3162 if (ses->server->secMode & 3241 if (ses->server->sec_mode &
3163 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 3242 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3164 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 3243 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3165 3244
@@ -3255,7 +3334,6 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3255 struct rb_root *root = &cifs_sb->tlink_tree; 3334 struct rb_root *root = &cifs_sb->tlink_tree;
3256 struct rb_node *node; 3335 struct rb_node *node;
3257 struct tcon_link *tlink; 3336 struct tcon_link *tlink;
3258 char *tmp;
3259 3337
3260 cancel_delayed_work_sync(&cifs_sb->prune_tlinks); 3338 cancel_delayed_work_sync(&cifs_sb->prune_tlinks);
3261 3339
@@ -3272,15 +3350,10 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3272 } 3350 }
3273 spin_unlock(&cifs_sb->tlink_tree_lock); 3351 spin_unlock(&cifs_sb->tlink_tree_lock);
3274 3352
3275 tmp = cifs_sb->prepath;
3276 cifs_sb->prepathlen = 0;
3277 cifs_sb->prepath = NULL;
3278 kfree(tmp);
3279
3280 return 0; 3353 return 0;
3281} 3354}
3282 3355
3283int cifs_negotiate_protocol(unsigned int xid, struct cifsSesInfo *ses) 3356int cifs_negotiate_protocol(unsigned int xid, struct cifs_ses *ses)
3284{ 3357{
3285 int rc = 0; 3358 int rc = 0;
3286 struct TCP_Server_Info *server = ses->server; 3359 struct TCP_Server_Info *server = ses->server;
@@ -3310,7 +3383,7 @@ int cifs_negotiate_protocol(unsigned int xid, struct cifsSesInfo *ses)
3310} 3383}
3311 3384
3312 3385
3313int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses, 3386int cifs_setup_session(unsigned int xid, struct cifs_ses *ses,
3314 struct nls_table *nls_info) 3387 struct nls_table *nls_info)
3315{ 3388{
3316 int rc = 0; 3389 int rc = 0;
@@ -3322,7 +3395,7 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
3322 ses->capabilities &= (~CAP_UNIX); 3395 ses->capabilities &= (~CAP_UNIX);
3323 3396
3324 cFYI(1, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d", 3397 cFYI(1, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
3325 server->secMode, server->capabilities, server->timeAdj); 3398 server->sec_mode, server->capabilities, server->timeAdj);
3326 3399
3327 rc = CIFS_SessSetup(xid, ses, nls_info); 3400 rc = CIFS_SessSetup(xid, ses, nls_info);
3328 if (rc) { 3401 if (rc) {
@@ -3354,12 +3427,12 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
3354 return rc; 3427 return rc;
3355} 3428}
3356 3429
3357static struct cifsTconInfo * 3430static struct cifs_tcon *
3358cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid) 3431cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid)
3359{ 3432{
3360 struct cifsTconInfo *master_tcon = cifs_sb_master_tcon(cifs_sb); 3433 struct cifs_tcon *master_tcon = cifs_sb_master_tcon(cifs_sb);
3361 struct cifsSesInfo *ses; 3434 struct cifs_ses *ses;
3362 struct cifsTconInfo *tcon = NULL; 3435 struct cifs_tcon *tcon = NULL;
3363 struct smb_vol *vol_info; 3436 struct smb_vol *vol_info;
3364 char username[28]; /* big enough for "krb50x" + hex of ULONG_MAX 6+16 */ 3437 char username[28]; /* big enough for "krb50x" + hex of ULONG_MAX 6+16 */
3365 /* We used to have this as MAX_USERNAME which is */ 3438 /* We used to have this as MAX_USERNAME which is */
@@ -3392,7 +3465,7 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid)
3392 3465
3393 ses = cifs_get_smb_ses(master_tcon->ses->server, vol_info); 3466 ses = cifs_get_smb_ses(master_tcon->ses->server, vol_info);
3394 if (IS_ERR(ses)) { 3467 if (IS_ERR(ses)) {
3395 tcon = (struct cifsTconInfo *)ses; 3468 tcon = (struct cifs_tcon *)ses;
3396 cifs_put_tcp_session(master_tcon->ses->server); 3469 cifs_put_tcp_session(master_tcon->ses->server);
3397 goto out; 3470 goto out;
3398 } 3471 }
@@ -3417,7 +3490,7 @@ cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb)
3417 return cifs_sb->master_tlink; 3490 return cifs_sb->master_tlink;
3418} 3491}
3419 3492
3420struct cifsTconInfo * 3493struct cifs_tcon *
3421cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb) 3494cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb)
3422{ 3495{
3423 return tlink_tcon(cifs_sb_master_tlink(cifs_sb)); 3496 return tlink_tcon(cifs_sb_master_tlink(cifs_sb));
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 9ea65cf36714..81914df47ef1 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -50,12 +50,11 @@ build_path_from_dentry(struct dentry *direntry)
50{ 50{
51 struct dentry *temp; 51 struct dentry *temp;
52 int namelen; 52 int namelen;
53 int pplen;
54 int dfsplen; 53 int dfsplen;
55 char *full_path; 54 char *full_path;
56 char dirsep; 55 char dirsep;
57 struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb); 56 struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
58 struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); 57 struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
59 58
60 if (direntry == NULL) 59 if (direntry == NULL)
61 return NULL; /* not much we can do if dentry is freed and 60 return NULL; /* not much we can do if dentry is freed and
@@ -63,13 +62,12 @@ build_path_from_dentry(struct dentry *direntry)
63 when the server crashed */ 62 when the server crashed */
64 63
65 dirsep = CIFS_DIR_SEP(cifs_sb); 64 dirsep = CIFS_DIR_SEP(cifs_sb);
66 pplen = cifs_sb->prepathlen;
67 if (tcon->Flags & SMB_SHARE_IS_IN_DFS) 65 if (tcon->Flags & SMB_SHARE_IS_IN_DFS)
68 dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1); 66 dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
69 else 67 else
70 dfsplen = 0; 68 dfsplen = 0;
71cifs_bp_rename_retry: 69cifs_bp_rename_retry:
72 namelen = pplen + dfsplen; 70 namelen = dfsplen;
73 for (temp = direntry; !IS_ROOT(temp);) { 71 for (temp = direntry; !IS_ROOT(temp);) {
74 namelen += (1 + temp->d_name.len); 72 namelen += (1 + temp->d_name.len);
75 temp = temp->d_parent; 73 temp = temp->d_parent;
@@ -100,7 +98,7 @@ cifs_bp_rename_retry:
100 return NULL; 98 return NULL;
101 } 99 }
102 } 100 }
103 if (namelen != pplen + dfsplen) { 101 if (namelen != dfsplen) {
104 cERROR(1, "did not end path lookup where expected namelen is %d", 102 cERROR(1, "did not end path lookup where expected namelen is %d",
105 namelen); 103 namelen);
106 /* presumably this is only possible if racing with a rename 104 /* presumably this is only possible if racing with a rename
@@ -126,7 +124,6 @@ cifs_bp_rename_retry:
126 } 124 }
127 } 125 }
128 } 126 }
129 strncpy(full_path + dfsplen, CIFS_SB(direntry->d_sb)->prepath, pplen);
130 return full_path; 127 return full_path;
131} 128}
132 129
@@ -152,7 +149,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
152 __u16 fileHandle; 149 __u16 fileHandle;
153 struct cifs_sb_info *cifs_sb; 150 struct cifs_sb_info *cifs_sb;
154 struct tcon_link *tlink; 151 struct tcon_link *tlink;
155 struct cifsTconInfo *tcon; 152 struct cifs_tcon *tcon;
156 char *full_path = NULL; 153 char *full_path = NULL;
157 FILE_ALL_INFO *buf = NULL; 154 FILE_ALL_INFO *buf = NULL;
158 struct inode *newinode = NULL; 155 struct inode *newinode = NULL;
@@ -356,7 +353,8 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
356 int xid; 353 int xid;
357 struct cifs_sb_info *cifs_sb; 354 struct cifs_sb_info *cifs_sb;
358 struct tcon_link *tlink; 355 struct tcon_link *tlink;
359 struct cifsTconInfo *pTcon; 356 struct cifs_tcon *pTcon;
357 struct cifs_io_parms io_parms;
360 char *full_path = NULL; 358 char *full_path = NULL;
361 struct inode *newinode = NULL; 359 struct inode *newinode = NULL;
362 int oplock = 0; 360 int oplock = 0;
@@ -439,16 +437,19 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
439 * timestamps in, but we can reuse it safely */ 437 * timestamps in, but we can reuse it safely */
440 438
441 pdev = (struct win_dev *)buf; 439 pdev = (struct win_dev *)buf;
440 io_parms.netfid = fileHandle;
441 io_parms.pid = current->tgid;
442 io_parms.tcon = pTcon;
443 io_parms.offset = 0;
444 io_parms.length = sizeof(struct win_dev);
442 if (S_ISCHR(mode)) { 445 if (S_ISCHR(mode)) {
443 memcpy(pdev->type, "IntxCHR", 8); 446 memcpy(pdev->type, "IntxCHR", 8);
444 pdev->major = 447 pdev->major =
445 cpu_to_le64(MAJOR(device_number)); 448 cpu_to_le64(MAJOR(device_number));
446 pdev->minor = 449 pdev->minor =
447 cpu_to_le64(MINOR(device_number)); 450 cpu_to_le64(MINOR(device_number));
448 rc = CIFSSMBWrite(xid, pTcon, 451 rc = CIFSSMBWrite(xid, &io_parms,
449 fileHandle, 452 &bytes_written, (char *)pdev,
450 sizeof(struct win_dev),
451 0, &bytes_written, (char *)pdev,
452 NULL, 0); 453 NULL, 0);
453 } else if (S_ISBLK(mode)) { 454 } else if (S_ISBLK(mode)) {
454 memcpy(pdev->type, "IntxBLK", 8); 455 memcpy(pdev->type, "IntxBLK", 8);
@@ -456,10 +457,8 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
456 cpu_to_le64(MAJOR(device_number)); 457 cpu_to_le64(MAJOR(device_number));
457 pdev->minor = 458 pdev->minor =
458 cpu_to_le64(MINOR(device_number)); 459 cpu_to_le64(MINOR(device_number));
459 rc = CIFSSMBWrite(xid, pTcon, 460 rc = CIFSSMBWrite(xid, &io_parms,
460 fileHandle, 461 &bytes_written, (char *)pdev,
461 sizeof(struct win_dev),
462 0, &bytes_written, (char *)pdev,
463 NULL, 0); 462 NULL, 0);
464 } /* else if (S_ISFIFO) */ 463 } /* else if (S_ISFIFO) */
465 CIFSSMBClose(xid, pTcon, fileHandle); 464 CIFSSMBClose(xid, pTcon, fileHandle);
@@ -486,7 +485,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
486 bool posix_open = false; 485 bool posix_open = false;
487 struct cifs_sb_info *cifs_sb; 486 struct cifs_sb_info *cifs_sb;
488 struct tcon_link *tlink; 487 struct tcon_link *tlink;
489 struct cifsTconInfo *pTcon; 488 struct cifs_tcon *pTcon;
490 struct cifsFileInfo *cfile; 489 struct cifsFileInfo *cfile;
491 struct inode *newInode = NULL; 490 struct inode *newInode = NULL;
492 char *full_path = NULL; 491 char *full_path = NULL;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index c672afef0c09..bb71471a4d9d 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -114,7 +114,7 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
114 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 114 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
115 struct cifs_fattr fattr; 115 struct cifs_fattr fattr;
116 struct tcon_link *tlink; 116 struct tcon_link *tlink;
117 struct cifsTconInfo *tcon; 117 struct cifs_tcon *tcon;
118 118
119 cFYI(1, "posix open %s", full_path); 119 cFYI(1, "posix open %s", full_path);
120 120
@@ -168,7 +168,7 @@ posix_open_ret:
168 168
169static int 169static int
170cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb, 170cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
171 struct cifsTconInfo *tcon, unsigned int f_flags, __u32 *poplock, 171 struct cifs_tcon *tcon, unsigned int f_flags, __u32 *poplock,
172 __u16 *pnetfid, int xid) 172 __u16 *pnetfid, int xid)
173{ 173{
174 int rc; 174 int rc;
@@ -285,7 +285,7 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file,
285void cifsFileInfo_put(struct cifsFileInfo *cifs_file) 285void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
286{ 286{
287 struct inode *inode = cifs_file->dentry->d_inode; 287 struct inode *inode = cifs_file->dentry->d_inode;
288 struct cifsTconInfo *tcon = tlink_tcon(cifs_file->tlink); 288 struct cifs_tcon *tcon = tlink_tcon(cifs_file->tlink);
289 struct cifsInodeInfo *cifsi = CIFS_I(inode); 289 struct cifsInodeInfo *cifsi = CIFS_I(inode);
290 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 290 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
291 struct cifsLockInfo *li, *tmp; 291 struct cifsLockInfo *li, *tmp;
@@ -343,7 +343,7 @@ int cifs_open(struct inode *inode, struct file *file)
343 int xid; 343 int xid;
344 __u32 oplock; 344 __u32 oplock;
345 struct cifs_sb_info *cifs_sb; 345 struct cifs_sb_info *cifs_sb;
346 struct cifsTconInfo *tcon; 346 struct cifs_tcon *tcon;
347 struct tcon_link *tlink; 347 struct tcon_link *tlink;
348 struct cifsFileInfo *pCifsFile = NULL; 348 struct cifsFileInfo *pCifsFile = NULL;
349 char *full_path = NULL; 349 char *full_path = NULL;
@@ -457,7 +457,7 @@ static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush)
457 int xid; 457 int xid;
458 __u32 oplock; 458 __u32 oplock;
459 struct cifs_sb_info *cifs_sb; 459 struct cifs_sb_info *cifs_sb;
460 struct cifsTconInfo *tcon; 460 struct cifs_tcon *tcon;
461 struct cifsInodeInfo *pCifsInode; 461 struct cifsInodeInfo *pCifsInode;
462 struct inode *inode; 462 struct inode *inode;
463 char *full_path = NULL; 463 char *full_path = NULL;
@@ -596,7 +596,7 @@ int cifs_closedir(struct inode *inode, struct file *file)
596 xid = GetXid(); 596 xid = GetXid();
597 597
598 if (pCFileStruct) { 598 if (pCFileStruct) {
599 struct cifsTconInfo *pTcon = tlink_tcon(pCFileStruct->tlink); 599 struct cifs_tcon *pTcon = tlink_tcon(pCFileStruct->tlink);
600 600
601 cFYI(1, "Freeing private data in close dir"); 601 cFYI(1, "Freeing private data in close dir");
602 spin_lock(&cifs_file_list_lock); 602 spin_lock(&cifs_file_list_lock);
@@ -653,7 +653,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
653 __u64 length; 653 __u64 length;
654 bool wait_flag = false; 654 bool wait_flag = false;
655 struct cifs_sb_info *cifs_sb; 655 struct cifs_sb_info *cifs_sb;
656 struct cifsTconInfo *tcon; 656 struct cifs_tcon *tcon;
657 __u16 netfid; 657 __u16 netfid;
658 __u8 lockType = LOCKING_ANDX_LARGE_FILES; 658 __u8 lockType = LOCKING_ANDX_LARGE_FILES;
659 bool posix_locking = 0; 659 bool posix_locking = 0;
@@ -725,8 +725,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
725 else 725 else
726 posix_lock_type = CIFS_WRLCK; 726 posix_lock_type = CIFS_WRLCK;
727 rc = CIFSSMBPosixLock(xid, tcon, netfid, 1 /* get */, 727 rc = CIFSSMBPosixLock(xid, tcon, netfid, 1 /* get */,
728 length, pfLock, 728 length, pfLock, posix_lock_type,
729 posix_lock_type, wait_flag); 729 wait_flag);
730 FreeXid(xid); 730 FreeXid(xid);
731 return rc; 731 return rc;
732 } 732 }
@@ -797,8 +797,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
797 posix_lock_type = CIFS_UNLCK; 797 posix_lock_type = CIFS_UNLCK;
798 798
799 rc = CIFSSMBPosixLock(xid, tcon, netfid, 0 /* set */, 799 rc = CIFSSMBPosixLock(xid, tcon, netfid, 0 /* set */,
800 length, pfLock, 800 length, pfLock, posix_lock_type,
801 posix_lock_type, wait_flag); 801 wait_flag);
802 } else { 802 } else {
803 struct cifsFileInfo *fid = file->private_data; 803 struct cifsFileInfo *fid = file->private_data;
804 804
@@ -857,7 +857,7 @@ cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
857 cifsi->server_eof = end_of_write; 857 cifsi->server_eof = end_of_write;
858} 858}
859 859
860static ssize_t cifs_write(struct cifsFileInfo *open_file, 860static ssize_t cifs_write(struct cifsFileInfo *open_file, __u32 pid,
861 const char *write_data, size_t write_size, 861 const char *write_data, size_t write_size,
862 loff_t *poffset) 862 loff_t *poffset)
863{ 863{
@@ -865,10 +865,11 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file,
865 unsigned int bytes_written = 0; 865 unsigned int bytes_written = 0;
866 unsigned int total_written; 866 unsigned int total_written;
867 struct cifs_sb_info *cifs_sb; 867 struct cifs_sb_info *cifs_sb;
868 struct cifsTconInfo *pTcon; 868 struct cifs_tcon *pTcon;
869 int xid; 869 int xid;
870 struct dentry *dentry = open_file->dentry; 870 struct dentry *dentry = open_file->dentry;
871 struct cifsInodeInfo *cifsi = CIFS_I(dentry->d_inode); 871 struct cifsInodeInfo *cifsi = CIFS_I(dentry->d_inode);
872 struct cifs_io_parms io_parms;
872 873
873 cifs_sb = CIFS_SB(dentry->d_sb); 874 cifs_sb = CIFS_SB(dentry->d_sb);
874 875
@@ -901,8 +902,13 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file,
901 /* iov[0] is reserved for smb header */ 902 /* iov[0] is reserved for smb header */
902 iov[1].iov_base = (char *)write_data + total_written; 903 iov[1].iov_base = (char *)write_data + total_written;
903 iov[1].iov_len = len; 904 iov[1].iov_len = len;
904 rc = CIFSSMBWrite2(xid, pTcon, open_file->netfid, len, 905 io_parms.netfid = open_file->netfid;
905 *poffset, &bytes_written, iov, 1, 0); 906 io_parms.pid = pid;
907 io_parms.tcon = pTcon;
908 io_parms.offset = *poffset;
909 io_parms.length = len;
910 rc = CIFSSMBWrite2(xid, &io_parms, &bytes_written, iov,
911 1, 0);
906 } 912 }
907 if (rc || (bytes_written == 0)) { 913 if (rc || (bytes_written == 0)) {
908 if (total_written) 914 if (total_written)
@@ -1071,8 +1077,8 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
1071 1077
1072 open_file = find_writable_file(CIFS_I(mapping->host), false); 1078 open_file = find_writable_file(CIFS_I(mapping->host), false);
1073 if (open_file) { 1079 if (open_file) {
1074 bytes_written = cifs_write(open_file, write_data, 1080 bytes_written = cifs_write(open_file, open_file->pid,
1075 to - from, &offset); 1081 write_data, to - from, &offset);
1076 cifsFileInfo_put(open_file); 1082 cifsFileInfo_put(open_file);
1077 /* Does mm or vfs already set times? */ 1083 /* Does mm or vfs already set times? */
1078 inode->i_atime = inode->i_mtime = current_fs_time(inode->i_sb); 1084 inode->i_atime = inode->i_mtime = current_fs_time(inode->i_sb);
@@ -1092,58 +1098,20 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
1092static int cifs_writepages(struct address_space *mapping, 1098static int cifs_writepages(struct address_space *mapping,
1093 struct writeback_control *wbc) 1099 struct writeback_control *wbc)
1094{ 1100{
1095 unsigned int bytes_to_write; 1101 struct cifs_sb_info *cifs_sb = CIFS_SB(mapping->host->i_sb);
1096 unsigned int bytes_written; 1102 bool done = false, scanned = false, range_whole = false;
1097 struct cifs_sb_info *cifs_sb; 1103 pgoff_t end, index;
1098 int done = 0; 1104 struct cifs_writedata *wdata;
1099 pgoff_t end;
1100 pgoff_t index;
1101 int range_whole = 0;
1102 struct kvec *iov;
1103 int len;
1104 int n_iov = 0;
1105 pgoff_t next;
1106 int nr_pages;
1107 __u64 offset = 0;
1108 struct cifsFileInfo *open_file;
1109 struct cifsTconInfo *tcon;
1110 struct cifsInodeInfo *cifsi = CIFS_I(mapping->host);
1111 struct page *page; 1105 struct page *page;
1112 struct pagevec pvec;
1113 int rc = 0; 1106 int rc = 0;
1114 int scanned = 0;
1115 int xid;
1116
1117 cifs_sb = CIFS_SB(mapping->host->i_sb);
1118 1107
1119 /* 1108 /*
1120 * If wsize is smaller that the page cache size, default to writing 1109 * If wsize is smaller than the page cache size, default to writing
1121 * one page at a time via cifs_writepage 1110 * one page at a time via cifs_writepage
1122 */ 1111 */
1123 if (cifs_sb->wsize < PAGE_CACHE_SIZE) 1112 if (cifs_sb->wsize < PAGE_CACHE_SIZE)
1124 return generic_writepages(mapping, wbc); 1113 return generic_writepages(mapping, wbc);
1125 1114
1126 iov = kmalloc(32 * sizeof(struct kvec), GFP_KERNEL);
1127 if (iov == NULL)
1128 return generic_writepages(mapping, wbc);
1129
1130 /*
1131 * if there's no open file, then this is likely to fail too,
1132 * but it'll at least handle the return. Maybe it should be
1133 * a BUG() instead?
1134 */
1135 open_file = find_writable_file(CIFS_I(mapping->host), false);
1136 if (!open_file) {
1137 kfree(iov);
1138 return generic_writepages(mapping, wbc);
1139 }
1140
1141 tcon = tlink_tcon(open_file->tlink);
1142 cifsFileInfo_put(open_file);
1143
1144 xid = GetXid();
1145
1146 pagevec_init(&pvec, 0);
1147 if (wbc->range_cyclic) { 1115 if (wbc->range_cyclic) {
1148 index = mapping->writeback_index; /* Start from prev offset */ 1116 index = mapping->writeback_index; /* Start from prev offset */
1149 end = -1; 1117 end = -1;
@@ -1151,24 +1119,49 @@ static int cifs_writepages(struct address_space *mapping,
1151 index = wbc->range_start >> PAGE_CACHE_SHIFT; 1119 index = wbc->range_start >> PAGE_CACHE_SHIFT;
1152 end = wbc->range_end >> PAGE_CACHE_SHIFT; 1120 end = wbc->range_end >> PAGE_CACHE_SHIFT;
1153 if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX) 1121 if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
1154 range_whole = 1; 1122 range_whole = true;
1155 scanned = 1; 1123 scanned = true;
1156 } 1124 }
1157retry: 1125retry:
1158 while (!done && (index <= end) && 1126 while (!done && index <= end) {
1159 (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, 1127 unsigned int i, nr_pages, found_pages;
1160 PAGECACHE_TAG_DIRTY, 1128 pgoff_t next = 0, tofind;
1161 min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1))) { 1129 struct page **pages;
1162 int first; 1130
1163 unsigned int i; 1131 tofind = min((cifs_sb->wsize / PAGE_CACHE_SIZE) - 1,
1164 1132 end - index) + 1;
1165 first = -1; 1133
1166 next = 0; 1134 wdata = cifs_writedata_alloc((unsigned int)tofind);
1167 n_iov = 0; 1135 if (!wdata) {
1168 bytes_to_write = 0; 1136 rc = -ENOMEM;
1169 1137 break;
1170 for (i = 0; i < nr_pages; i++) { 1138 }
1171 page = pvec.pages[i]; 1139
1140 /*
1141 * find_get_pages_tag seems to return a max of 256 on each
1142 * iteration, so we must call it several times in order to
1143 * fill the array or the wsize is effectively limited to
1144 * 256 * PAGE_CACHE_SIZE.
1145 */
1146 found_pages = 0;
1147 pages = wdata->pages;
1148 do {
1149 nr_pages = find_get_pages_tag(mapping, &index,
1150 PAGECACHE_TAG_DIRTY,
1151 tofind, pages);
1152 found_pages += nr_pages;
1153 tofind -= nr_pages;
1154 pages += nr_pages;
1155 } while (nr_pages && tofind && index <= end);
1156
1157 if (found_pages == 0) {
1158 kref_put(&wdata->refcount, cifs_writedata_release);
1159 break;
1160 }
1161
1162 nr_pages = 0;
1163 for (i = 0; i < found_pages; i++) {
1164 page = wdata->pages[i];
1172 /* 1165 /*
1173 * At this point we hold neither mapping->tree_lock nor 1166 * At this point we hold neither mapping->tree_lock nor
1174 * lock on the page itself: the page may be truncated or 1167 * lock on the page itself: the page may be truncated or
@@ -1177,7 +1170,7 @@ retry:
1177 * mapping 1170 * mapping
1178 */ 1171 */
1179 1172
1180 if (first < 0) 1173 if (nr_pages == 0)
1181 lock_page(page); 1174 lock_page(page);
1182 else if (!trylock_page(page)) 1175 else if (!trylock_page(page))
1183 break; 1176 break;
@@ -1188,7 +1181,7 @@ retry:
1188 } 1181 }
1189 1182
1190 if (!wbc->range_cyclic && page->index > end) { 1183 if (!wbc->range_cyclic && page->index > end) {
1191 done = 1; 1184 done = true;
1192 unlock_page(page); 1185 unlock_page(page);
1193 break; 1186 break;
1194 } 1187 }
@@ -1215,119 +1208,89 @@ retry:
1215 set_page_writeback(page); 1208 set_page_writeback(page);
1216 1209
1217 if (page_offset(page) >= mapping->host->i_size) { 1210 if (page_offset(page) >= mapping->host->i_size) {
1218 done = 1; 1211 done = true;
1219 unlock_page(page); 1212 unlock_page(page);
1220 end_page_writeback(page); 1213 end_page_writeback(page);
1221 break; 1214 break;
1222 } 1215 }
1223 1216
1224 /* 1217 wdata->pages[i] = page;
1225 * BB can we get rid of this? pages are held by pvec 1218 next = page->index + 1;
1226 */ 1219 ++nr_pages;
1227 page_cache_get(page); 1220 }
1228 1221
1229 len = min(mapping->host->i_size - page_offset(page), 1222 /* reset index to refind any pages skipped */
1230 (loff_t)PAGE_CACHE_SIZE); 1223 if (nr_pages == 0)
1224 index = wdata->pages[0]->index + 1;
1231 1225
1232 /* reserve iov[0] for the smb header */ 1226 /* put any pages we aren't going to use */
1233 n_iov++; 1227 for (i = nr_pages; i < found_pages; i++) {
1234 iov[n_iov].iov_base = kmap(page); 1228 page_cache_release(wdata->pages[i]);
1235 iov[n_iov].iov_len = len; 1229 wdata->pages[i] = NULL;
1236 bytes_to_write += len; 1230 }
1237 1231
1238 if (first < 0) { 1232 /* nothing to write? */
1239 first = i; 1233 if (nr_pages == 0) {
1240 offset = page_offset(page); 1234 kref_put(&wdata->refcount, cifs_writedata_release);
1241 } 1235 continue;
1242 next = page->index + 1;
1243 if (bytes_to_write + PAGE_CACHE_SIZE > cifs_sb->wsize)
1244 break;
1245 } 1236 }
1246 if (n_iov) {
1247retry_write:
1248 open_file = find_writable_file(CIFS_I(mapping->host),
1249 false);
1250 if (!open_file) {
1251 cERROR(1, "No writable handles for inode");
1252 rc = -EBADF;
1253 } else {
1254 rc = CIFSSMBWrite2(xid, tcon, open_file->netfid,
1255 bytes_to_write, offset,
1256 &bytes_written, iov, n_iov,
1257 0);
1258 cifsFileInfo_put(open_file);
1259 }
1260 1237
1261 cFYI(1, "Write2 rc=%d, wrote=%u", rc, bytes_written); 1238 wdata->sync_mode = wbc->sync_mode;
1239 wdata->nr_pages = nr_pages;
1240 wdata->offset = page_offset(wdata->pages[0]);
1262 1241
1263 /* 1242 do {
1264 * For now, treat a short write as if nothing got 1243 if (wdata->cfile != NULL)
1265 * written. A zero length write however indicates 1244 cifsFileInfo_put(wdata->cfile);
1266 * ENOSPC or EFBIG. We have no way to know which 1245 wdata->cfile = find_writable_file(CIFS_I(mapping->host),
1267 * though, so call it ENOSPC for now. EFBIG would 1246 false);
1268 * get translated to AS_EIO anyway. 1247 if (!wdata->cfile) {
1269 * 1248 cERROR(1, "No writable handles for inode");
1270 * FIXME: make it take into account the data that did 1249 rc = -EBADF;
1271 * get written 1250 break;
1272 */
1273 if (rc == 0) {
1274 if (bytes_written == 0)
1275 rc = -ENOSPC;
1276 else if (bytes_written < bytes_to_write)
1277 rc = -EAGAIN;
1278 } 1251 }
1252 rc = cifs_async_writev(wdata);
1253 } while (wbc->sync_mode == WB_SYNC_ALL && rc == -EAGAIN);
1279 1254
1280 /* retry on data-integrity flush */ 1255 for (i = 0; i < nr_pages; ++i)
1281 if (wbc->sync_mode == WB_SYNC_ALL && rc == -EAGAIN) 1256 unlock_page(wdata->pages[i]);
1282 goto retry_write;
1283
1284 /* fix the stats and EOF */
1285 if (bytes_written > 0) {
1286 cifs_stats_bytes_written(tcon, bytes_written);
1287 cifs_update_eof(cifsi, offset, bytes_written);
1288 }
1289 1257
1290 for (i = 0; i < n_iov; i++) { 1258 /* send failure -- clean up the mess */
1291 page = pvec.pages[first + i]; 1259 if (rc != 0) {
1292 /* on retryable write error, redirty page */ 1260 for (i = 0; i < nr_pages; ++i) {
1293 if (rc == -EAGAIN) 1261 if (rc == -EAGAIN)
1294 redirty_page_for_writepage(wbc, page); 1262 redirty_page_for_writepage(wbc,
1295 else if (rc != 0) 1263 wdata->pages[i]);
1296 SetPageError(page); 1264 else
1297 kunmap(page); 1265 SetPageError(wdata->pages[i]);
1298 unlock_page(page); 1266 end_page_writeback(wdata->pages[i]);
1299 end_page_writeback(page); 1267 page_cache_release(wdata->pages[i]);
1300 page_cache_release(page);
1301 } 1268 }
1302
1303 if (rc != -EAGAIN) 1269 if (rc != -EAGAIN)
1304 mapping_set_error(mapping, rc); 1270 mapping_set_error(mapping, rc);
1305 else 1271 }
1306 rc = 0; 1272 kref_put(&wdata->refcount, cifs_writedata_release);
1307 1273
1308 if ((wbc->nr_to_write -= n_iov) <= 0) 1274 wbc->nr_to_write -= nr_pages;
1309 done = 1; 1275 if (wbc->nr_to_write <= 0)
1310 index = next; 1276 done = true;
1311 } else
1312 /* Need to re-find the pages we skipped */
1313 index = pvec.pages[0]->index + 1;
1314 1277
1315 pagevec_release(&pvec); 1278 index = next;
1316 } 1279 }
1280
1317 if (!scanned && !done) { 1281 if (!scanned && !done) {
1318 /* 1282 /*
1319 * We hit the last page and there is more work to be done: wrap 1283 * We hit the last page and there is more work to be done: wrap
1320 * back to the start of the file 1284 * back to the start of the file
1321 */ 1285 */
1322 scanned = 1; 1286 scanned = true;
1323 index = 0; 1287 index = 0;
1324 goto retry; 1288 goto retry;
1325 } 1289 }
1290
1326 if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) 1291 if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
1327 mapping->writeback_index = index; 1292 mapping->writeback_index = index;
1328 1293
1329 FreeXid(xid);
1330 kfree(iov);
1331 return rc; 1294 return rc;
1332} 1295}
1333 1296
@@ -1383,6 +1346,14 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
1383{ 1346{
1384 int rc; 1347 int rc;
1385 struct inode *inode = mapping->host; 1348 struct inode *inode = mapping->host;
1349 struct cifsFileInfo *cfile = file->private_data;
1350 struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb);
1351 __u32 pid;
1352
1353 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
1354 pid = cfile->pid;
1355 else
1356 pid = current->tgid;
1386 1357
1387 cFYI(1, "write_end for page %p from pos %lld with %d bytes", 1358 cFYI(1, "write_end for page %p from pos %lld with %d bytes",
1388 page, pos, copied); 1359 page, pos, copied);
@@ -1406,8 +1377,7 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
1406 /* BB check if anything else missing out of ppw 1377 /* BB check if anything else missing out of ppw
1407 such as updating last write time */ 1378 such as updating last write time */
1408 page_data = kmap(page); 1379 page_data = kmap(page);
1409 rc = cifs_write(file->private_data, page_data + offset, 1380 rc = cifs_write(cfile, pid, page_data + offset, copied, &pos);
1410 copied, &pos);
1411 /* if (rc < 0) should we set writebehind rc? */ 1381 /* if (rc < 0) should we set writebehind rc? */
1412 kunmap(page); 1382 kunmap(page);
1413 1383
@@ -1435,7 +1405,7 @@ int cifs_strict_fsync(struct file *file, int datasync)
1435{ 1405{
1436 int xid; 1406 int xid;
1437 int rc = 0; 1407 int rc = 0;
1438 struct cifsTconInfo *tcon; 1408 struct cifs_tcon *tcon;
1439 struct cifsFileInfo *smbfile = file->private_data; 1409 struct cifsFileInfo *smbfile = file->private_data;
1440 struct inode *inode = file->f_path.dentry->d_inode; 1410 struct inode *inode = file->f_path.dentry->d_inode;
1441 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 1411 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
@@ -1465,7 +1435,7 @@ int cifs_fsync(struct file *file, int datasync)
1465{ 1435{
1466 int xid; 1436 int xid;
1467 int rc = 0; 1437 int rc = 0;
1468 struct cifsTconInfo *tcon; 1438 struct cifs_tcon *tcon;
1469 struct cifsFileInfo *smbfile = file->private_data; 1439 struct cifsFileInfo *smbfile = file->private_data;
1470 struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 1440 struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
1471 1441
@@ -1556,9 +1526,11 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,
1556 struct iov_iter it; 1526 struct iov_iter it;
1557 struct inode *inode; 1527 struct inode *inode;
1558 struct cifsFileInfo *open_file; 1528 struct cifsFileInfo *open_file;
1559 struct cifsTconInfo *pTcon; 1529 struct cifs_tcon *pTcon;
1560 struct cifs_sb_info *cifs_sb; 1530 struct cifs_sb_info *cifs_sb;
1531 struct cifs_io_parms io_parms;
1561 int xid, rc; 1532 int xid, rc;
1533 __u32 pid;
1562 1534
1563 len = iov_length(iov, nr_segs); 1535 len = iov_length(iov, nr_segs);
1564 if (!len) 1536 if (!len)
@@ -1590,6 +1562,12 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,
1590 1562
1591 xid = GetXid(); 1563 xid = GetXid();
1592 open_file = file->private_data; 1564 open_file = file->private_data;
1565
1566 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
1567 pid = open_file->pid;
1568 else
1569 pid = current->tgid;
1570
1593 pTcon = tlink_tcon(open_file->tlink); 1571 pTcon = tlink_tcon(open_file->tlink);
1594 inode = file->f_path.dentry->d_inode; 1572 inode = file->f_path.dentry->d_inode;
1595 1573
@@ -1616,9 +1594,13 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,
1616 if (rc != 0) 1594 if (rc != 0)
1617 break; 1595 break;
1618 } 1596 }
1619 rc = CIFSSMBWrite2(xid, pTcon, open_file->netfid, 1597 io_parms.netfid = open_file->netfid;
1620 cur_len, *poffset, &written, 1598 io_parms.pid = pid;
1621 to_send, npages, 0); 1599 io_parms.tcon = pTcon;
1600 io_parms.offset = *poffset;
1601 io_parms.length = cur_len;
1602 rc = CIFSSMBWrite2(xid, &io_parms, &written, to_send,
1603 npages, 0);
1622 } while (rc == -EAGAIN); 1604 } while (rc == -EAGAIN);
1623 1605
1624 for (i = 0; i < npages; i++) 1606 for (i = 0; i < npages; i++)
@@ -1711,10 +1693,12 @@ cifs_iovec_read(struct file *file, const struct iovec *iov,
1711 size_t len, cur_len; 1693 size_t len, cur_len;
1712 int iov_offset = 0; 1694 int iov_offset = 0;
1713 struct cifs_sb_info *cifs_sb; 1695 struct cifs_sb_info *cifs_sb;
1714 struct cifsTconInfo *pTcon; 1696 struct cifs_tcon *pTcon;
1715 struct cifsFileInfo *open_file; 1697 struct cifsFileInfo *open_file;
1716 struct smb_com_read_rsp *pSMBr; 1698 struct smb_com_read_rsp *pSMBr;
1699 struct cifs_io_parms io_parms;
1717 char *read_data; 1700 char *read_data;
1701 __u32 pid;
1718 1702
1719 if (!nr_segs) 1703 if (!nr_segs)
1720 return 0; 1704 return 0;
@@ -1729,6 +1713,11 @@ cifs_iovec_read(struct file *file, const struct iovec *iov,
1729 open_file = file->private_data; 1713 open_file = file->private_data;
1730 pTcon = tlink_tcon(open_file->tlink); 1714 pTcon = tlink_tcon(open_file->tlink);
1731 1715
1716 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
1717 pid = open_file->pid;
1718 else
1719 pid = current->tgid;
1720
1732 if ((file->f_flags & O_ACCMODE) == O_WRONLY) 1721 if ((file->f_flags & O_ACCMODE) == O_WRONLY)
1733 cFYI(1, "attempting read on write only file instance"); 1722 cFYI(1, "attempting read on write only file instance");
1734 1723
@@ -1744,8 +1733,12 @@ cifs_iovec_read(struct file *file, const struct iovec *iov,
1744 if (rc != 0) 1733 if (rc != 0)
1745 break; 1734 break;
1746 } 1735 }
1747 rc = CIFSSMBRead(xid, pTcon, open_file->netfid, 1736 io_parms.netfid = open_file->netfid;
1748 cur_len, *poffset, &bytes_read, 1737 io_parms.pid = pid;
1738 io_parms.tcon = pTcon;
1739 io_parms.offset = *poffset;
1740 io_parms.length = len;
1741 rc = CIFSSMBRead(xid, &io_parms, &bytes_read,
1749 &read_data, &buf_type); 1742 &read_data, &buf_type);
1750 pSMBr = (struct smb_com_read_rsp *)read_data; 1743 pSMBr = (struct smb_com_read_rsp *)read_data;
1751 if (read_data) { 1744 if (read_data) {
@@ -1822,11 +1815,13 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
1822 unsigned int total_read; 1815 unsigned int total_read;
1823 unsigned int current_read_size; 1816 unsigned int current_read_size;
1824 struct cifs_sb_info *cifs_sb; 1817 struct cifs_sb_info *cifs_sb;
1825 struct cifsTconInfo *pTcon; 1818 struct cifs_tcon *pTcon;
1826 int xid; 1819 int xid;
1827 char *current_offset; 1820 char *current_offset;
1828 struct cifsFileInfo *open_file; 1821 struct cifsFileInfo *open_file;
1822 struct cifs_io_parms io_parms;
1829 int buf_type = CIFS_NO_BUFFER; 1823 int buf_type = CIFS_NO_BUFFER;
1824 __u32 pid;
1830 1825
1831 xid = GetXid(); 1826 xid = GetXid();
1832 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 1827 cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
@@ -1839,6 +1834,11 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
1839 open_file = file->private_data; 1834 open_file = file->private_data;
1840 pTcon = tlink_tcon(open_file->tlink); 1835 pTcon = tlink_tcon(open_file->tlink);
1841 1836
1837 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
1838 pid = open_file->pid;
1839 else
1840 pid = current->tgid;
1841
1842 if ((file->f_flags & O_ACCMODE) == O_WRONLY) 1842 if ((file->f_flags & O_ACCMODE) == O_WRONLY)
1843 cFYI(1, "attempting read on write only file instance"); 1843 cFYI(1, "attempting read on write only file instance");
1844 1844
@@ -1861,11 +1861,13 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
1861 if (rc != 0) 1861 if (rc != 0)
1862 break; 1862 break;
1863 } 1863 }
1864 rc = CIFSSMBRead(xid, pTcon, 1864 io_parms.netfid = open_file->netfid;
1865 open_file->netfid, 1865 io_parms.pid = pid;
1866 current_read_size, *poffset, 1866 io_parms.tcon = pTcon;
1867 &bytes_read, &current_offset, 1867 io_parms.offset = *poffset;
1868 &buf_type); 1868 io_parms.length = current_read_size;
1869 rc = CIFSSMBRead(xid, &io_parms, &bytes_read,
1870 &current_offset, &buf_type);
1869 } 1871 }
1870 if (rc || (bytes_read == 0)) { 1872 if (rc || (bytes_read == 0)) {
1871 if (total_read) { 1873 if (total_read) {
@@ -1996,13 +1998,15 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
1996 loff_t offset; 1998 loff_t offset;
1997 struct page *page; 1999 struct page *page;
1998 struct cifs_sb_info *cifs_sb; 2000 struct cifs_sb_info *cifs_sb;
1999 struct cifsTconInfo *pTcon; 2001 struct cifs_tcon *pTcon;
2000 unsigned int bytes_read = 0; 2002 unsigned int bytes_read = 0;
2001 unsigned int read_size, i; 2003 unsigned int read_size, i;
2002 char *smb_read_data = NULL; 2004 char *smb_read_data = NULL;
2003 struct smb_com_read_rsp *pSMBr; 2005 struct smb_com_read_rsp *pSMBr;
2004 struct cifsFileInfo *open_file; 2006 struct cifsFileInfo *open_file;
2007 struct cifs_io_parms io_parms;
2005 int buf_type = CIFS_NO_BUFFER; 2008 int buf_type = CIFS_NO_BUFFER;
2009 __u32 pid;
2006 2010
2007 xid = GetXid(); 2011 xid = GetXid();
2008 if (file->private_data == NULL) { 2012 if (file->private_data == NULL) {
@@ -2024,6 +2028,11 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
2024 goto read_complete; 2028 goto read_complete;
2025 2029
2026 cFYI(DBG2, "rpages: num pages %d", num_pages); 2030 cFYI(DBG2, "rpages: num pages %d", num_pages);
2031 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
2032 pid = open_file->pid;
2033 else
2034 pid = current->tgid;
2035
2027 for (i = 0; i < num_pages; ) { 2036 for (i = 0; i < num_pages; ) {
2028 unsigned contig_pages; 2037 unsigned contig_pages;
2029 struct page *tmp_page; 2038 struct page *tmp_page;
@@ -2065,12 +2074,13 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
2065 if (rc != 0) 2074 if (rc != 0)
2066 break; 2075 break;
2067 } 2076 }
2068 2077 io_parms.netfid = open_file->netfid;
2069 rc = CIFSSMBRead(xid, pTcon, 2078 io_parms.pid = pid;
2070 open_file->netfid, 2079 io_parms.tcon = pTcon;
2071 read_size, offset, 2080 io_parms.offset = offset;
2072 &bytes_read, &smb_read_data, 2081 io_parms.length = read_size;
2073 &buf_type); 2082 rc = CIFSSMBRead(xid, &io_parms, &bytes_read,
2083 &smb_read_data, &buf_type);
2074 /* BB more RC checks ? */ 2084 /* BB more RC checks ? */
2075 if (rc == -EAGAIN) { 2085 if (rc == -EAGAIN) {
2076 if (smb_read_data) { 2086 if (smb_read_data) {
diff --git a/fs/cifs/fscache.c b/fs/cifs/fscache.c
index 297a43d0ff7f..d368a47ba5eb 100644
--- a/fs/cifs/fscache.c
+++ b/fs/cifs/fscache.c
@@ -40,7 +40,7 @@ void cifs_fscache_release_client_cookie(struct TCP_Server_Info *server)
40 server->fscache = NULL; 40 server->fscache = NULL;
41} 41}
42 42
43void cifs_fscache_get_super_cookie(struct cifsTconInfo *tcon) 43void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon)
44{ 44{
45 struct TCP_Server_Info *server = tcon->ses->server; 45 struct TCP_Server_Info *server = tcon->ses->server;
46 46
@@ -51,7 +51,7 @@ void cifs_fscache_get_super_cookie(struct cifsTconInfo *tcon)
51 server->fscache, tcon->fscache); 51 server->fscache, tcon->fscache);
52} 52}
53 53
54void cifs_fscache_release_super_cookie(struct cifsTconInfo *tcon) 54void cifs_fscache_release_super_cookie(struct cifs_tcon *tcon)
55{ 55{
56 cFYI(1, "CIFS: releasing superblock cookie (0x%p)", tcon->fscache); 56 cFYI(1, "CIFS: releasing superblock cookie (0x%p)", tcon->fscache);
57 fscache_relinquish_cookie(tcon->fscache, 0); 57 fscache_relinquish_cookie(tcon->fscache, 0);
@@ -62,7 +62,7 @@ static void cifs_fscache_enable_inode_cookie(struct inode *inode)
62{ 62{
63 struct cifsInodeInfo *cifsi = CIFS_I(inode); 63 struct cifsInodeInfo *cifsi = CIFS_I(inode);
64 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 64 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
65 struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); 65 struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
66 66
67 if (cifsi->fscache) 67 if (cifsi->fscache)
68 return; 68 return;
diff --git a/fs/cifs/fscache.h b/fs/cifs/fscache.h
index 31b88ec2341e..63539323e0b9 100644
--- a/fs/cifs/fscache.h
+++ b/fs/cifs/fscache.h
@@ -40,8 +40,8 @@ extern void cifs_fscache_unregister(void);
40 */ 40 */
41extern void cifs_fscache_get_client_cookie(struct TCP_Server_Info *); 41extern void cifs_fscache_get_client_cookie(struct TCP_Server_Info *);
42extern void cifs_fscache_release_client_cookie(struct TCP_Server_Info *); 42extern void cifs_fscache_release_client_cookie(struct TCP_Server_Info *);
43extern void cifs_fscache_get_super_cookie(struct cifsTconInfo *); 43extern void cifs_fscache_get_super_cookie(struct cifs_tcon *);
44extern void cifs_fscache_release_super_cookie(struct cifsTconInfo *); 44extern void cifs_fscache_release_super_cookie(struct cifs_tcon *);
45 45
46extern void cifs_fscache_release_inode_cookie(struct inode *); 46extern void cifs_fscache_release_inode_cookie(struct inode *);
47extern void cifs_fscache_set_inode_cookie(struct inode *, struct file *); 47extern void cifs_fscache_set_inode_cookie(struct inode *, struct file *);
@@ -99,9 +99,9 @@ static inline void
99cifs_fscache_get_client_cookie(struct TCP_Server_Info *server) {} 99cifs_fscache_get_client_cookie(struct TCP_Server_Info *server) {}
100static inline void 100static inline void
101cifs_fscache_release_client_cookie(struct TCP_Server_Info *server) {} 101cifs_fscache_release_client_cookie(struct TCP_Server_Info *server) {}
102static inline void cifs_fscache_get_super_cookie(struct cifsTconInfo *tcon) {} 102static inline void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon) {}
103static inline void 103static inline void
104cifs_fscache_release_super_cookie(struct cifsTconInfo *tcon) {} 104cifs_fscache_release_super_cookie(struct cifs_tcon *tcon) {}
105 105
106static inline void cifs_fscache_release_inode_cookie(struct inode *inode) {} 106static inline void cifs_fscache_release_inode_cookie(struct inode *inode) {}
107static inline void cifs_fscache_set_inode_cookie(struct inode *inode, 107static inline void cifs_fscache_set_inode_cookie(struct inode *inode,
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index de02ed5e25c2..9b018c8334fa 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -295,7 +295,7 @@ int cifs_get_file_info_unix(struct file *filp)
295 struct inode *inode = filp->f_path.dentry->d_inode; 295 struct inode *inode = filp->f_path.dentry->d_inode;
296 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 296 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
297 struct cifsFileInfo *cfile = filp->private_data; 297 struct cifsFileInfo *cfile = filp->private_data;
298 struct cifsTconInfo *tcon = tlink_tcon(cfile->tlink); 298 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
299 299
300 xid = GetXid(); 300 xid = GetXid();
301 rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->netfid, &find_data); 301 rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->netfid, &find_data);
@@ -318,7 +318,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
318 int rc; 318 int rc;
319 FILE_UNIX_BASIC_INFO find_data; 319 FILE_UNIX_BASIC_INFO find_data;
320 struct cifs_fattr fattr; 320 struct cifs_fattr fattr;
321 struct cifsTconInfo *tcon; 321 struct cifs_tcon *tcon;
322 struct tcon_link *tlink; 322 struct tcon_link *tlink;
323 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 323 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
324 324
@@ -373,7 +373,8 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
373 int oplock = 0; 373 int oplock = 0;
374 __u16 netfid; 374 __u16 netfid;
375 struct tcon_link *tlink; 375 struct tcon_link *tlink;
376 struct cifsTconInfo *tcon; 376 struct cifs_tcon *tcon;
377 struct cifs_io_parms io_parms;
377 char buf[24]; 378 char buf[24];
378 unsigned int bytes_read; 379 unsigned int bytes_read;
379 char *pbuf; 380 char *pbuf;
@@ -405,9 +406,13 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
405 if (rc == 0) { 406 if (rc == 0) {
406 int buf_type = CIFS_NO_BUFFER; 407 int buf_type = CIFS_NO_BUFFER;
407 /* Read header */ 408 /* Read header */
408 rc = CIFSSMBRead(xid, tcon, netfid, 409 io_parms.netfid = netfid;
409 24 /* length */, 0 /* offset */, 410 io_parms.pid = current->tgid;
410 &bytes_read, &pbuf, &buf_type); 411 io_parms.tcon = tcon;
412 io_parms.offset = 0;
413 io_parms.length = 24;
414 rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf,
415 &buf_type);
411 if ((rc == 0) && (bytes_read >= 8)) { 416 if ((rc == 0) && (bytes_read >= 8)) {
412 if (memcmp("IntxBLK", pbuf, 8) == 0) { 417 if (memcmp("IntxBLK", pbuf, 8) == 0) {
413 cFYI(1, "Block device"); 418 cFYI(1, "Block device");
@@ -468,7 +473,7 @@ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,
468 char ea_value[4]; 473 char ea_value[4];
469 __u32 mode; 474 __u32 mode;
470 struct tcon_link *tlink; 475 struct tcon_link *tlink;
471 struct cifsTconInfo *tcon; 476 struct cifs_tcon *tcon;
472 477
473 tlink = cifs_sb_tlink(cifs_sb); 478 tlink = cifs_sb_tlink(cifs_sb);
474 if (IS_ERR(tlink)) 479 if (IS_ERR(tlink))
@@ -502,7 +507,7 @@ static void
502cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info, 507cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
503 struct cifs_sb_info *cifs_sb, bool adjust_tz) 508 struct cifs_sb_info *cifs_sb, bool adjust_tz)
504{ 509{
505 struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); 510 struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
506 511
507 memset(fattr, 0, sizeof(*fattr)); 512 memset(fattr, 0, sizeof(*fattr));
508 fattr->cf_cifsattrs = le32_to_cpu(info->Attributes); 513 fattr->cf_cifsattrs = le32_to_cpu(info->Attributes);
@@ -553,7 +558,7 @@ int cifs_get_file_info(struct file *filp)
553 struct inode *inode = filp->f_path.dentry->d_inode; 558 struct inode *inode = filp->f_path.dentry->d_inode;
554 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 559 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
555 struct cifsFileInfo *cfile = filp->private_data; 560 struct cifsFileInfo *cfile = filp->private_data;
556 struct cifsTconInfo *tcon = tlink_tcon(cfile->tlink); 561 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
557 562
558 xid = GetXid(); 563 xid = GetXid();
559 rc = CIFSSMBQFileInfo(xid, tcon, cfile->netfid, &find_data); 564 rc = CIFSSMBQFileInfo(xid, tcon, cfile->netfid, &find_data);
@@ -590,7 +595,7 @@ int cifs_get_inode_info(struct inode **pinode,
590 struct super_block *sb, int xid, const __u16 *pfid) 595 struct super_block *sb, int xid, const __u16 *pfid)
591{ 596{
592 int rc = 0, tmprc; 597 int rc = 0, tmprc;
593 struct cifsTconInfo *pTcon; 598 struct cifs_tcon *pTcon;
594 struct tcon_link *tlink; 599 struct tcon_link *tlink;
595 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 600 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
596 char *buf = NULL; 601 char *buf = NULL;
@@ -735,10 +740,10 @@ static const struct inode_operations cifs_ipc_inode_ops = {
735 .lookup = cifs_lookup, 740 .lookup = cifs_lookup,
736}; 741};
737 742
738char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb, 743char *cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
739 struct cifsTconInfo *tcon) 744 struct cifs_tcon *tcon)
740{ 745{
741 int pplen = cifs_sb->prepathlen; 746 int pplen = vol->prepath ? strlen(vol->prepath) : 0;
742 int dfsplen; 747 int dfsplen;
743 char *full_path = NULL; 748 char *full_path = NULL;
744 749
@@ -772,7 +777,7 @@ char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb,
772 } 777 }
773 } 778 }
774 } 779 }
775 strncpy(full_path + dfsplen, cifs_sb->prepath, pplen); 780 strncpy(full_path + dfsplen, vol->prepath, pplen);
776 full_path[dfsplen + pplen] = 0; /* add trailing null */ 781 full_path[dfsplen + pplen] = 0; /* add trailing null */
777 return full_path; 782 return full_path;
778} 783}
@@ -884,19 +889,13 @@ struct inode *cifs_root_iget(struct super_block *sb)
884 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 889 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
885 struct inode *inode = NULL; 890 struct inode *inode = NULL;
886 long rc; 891 long rc;
887 char *full_path; 892 struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
888 struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
889
890 full_path = cifs_build_path_to_root(cifs_sb, tcon);
891 if (full_path == NULL)
892 return ERR_PTR(-ENOMEM);
893 893
894 xid = GetXid(); 894 xid = GetXid();
895 if (tcon->unix_ext) 895 if (tcon->unix_ext)
896 rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid); 896 rc = cifs_get_inode_info_unix(&inode, "", sb, xid);
897 else 897 else
898 rc = cifs_get_inode_info(&inode, full_path, NULL, sb, 898 rc = cifs_get_inode_info(&inode, "", NULL, sb, xid, NULL);
899 xid, NULL);
900 899
901 if (!inode) { 900 if (!inode) {
902 inode = ERR_PTR(rc); 901 inode = ERR_PTR(rc);
@@ -922,7 +921,6 @@ struct inode *cifs_root_iget(struct super_block *sb)
922 } 921 }
923 922
924out: 923out:
925 kfree(full_path);
926 /* can not call macro FreeXid here since in a void func 924 /* can not call macro FreeXid here since in a void func
927 * TODO: This is no longer true 925 * TODO: This is no longer true
928 */ 926 */
@@ -943,7 +941,7 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid,
943 struct cifsInodeInfo *cifsInode = CIFS_I(inode); 941 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
944 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 942 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
945 struct tcon_link *tlink = NULL; 943 struct tcon_link *tlink = NULL;
946 struct cifsTconInfo *pTcon; 944 struct cifs_tcon *pTcon;
947 FILE_BASIC_INFO info_buf; 945 FILE_BASIC_INFO info_buf;
948 946
949 if (attrs == NULL) 947 if (attrs == NULL)
@@ -1061,7 +1059,7 @@ cifs_rename_pending_delete(char *full_path, struct dentry *dentry, int xid)
1061 struct cifsInodeInfo *cifsInode = CIFS_I(inode); 1059 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1062 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 1060 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1063 struct tcon_link *tlink; 1061 struct tcon_link *tlink;
1064 struct cifsTconInfo *tcon; 1062 struct cifs_tcon *tcon;
1065 __u32 dosattr, origattr; 1063 __u32 dosattr, origattr;
1066 FILE_BASIC_INFO *info_buf = NULL; 1064 FILE_BASIC_INFO *info_buf = NULL;
1067 1065
@@ -1179,7 +1177,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
1179 struct super_block *sb = dir->i_sb; 1177 struct super_block *sb = dir->i_sb;
1180 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 1178 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
1181 struct tcon_link *tlink; 1179 struct tcon_link *tlink;
1182 struct cifsTconInfo *tcon; 1180 struct cifs_tcon *tcon;
1183 struct iattr *attrs = NULL; 1181 struct iattr *attrs = NULL;
1184 __u32 dosattr = 0, origattr = 0; 1182 __u32 dosattr = 0, origattr = 0;
1185 1183
@@ -1277,7 +1275,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
1277 int xid; 1275 int xid;
1278 struct cifs_sb_info *cifs_sb; 1276 struct cifs_sb_info *cifs_sb;
1279 struct tcon_link *tlink; 1277 struct tcon_link *tlink;
1280 struct cifsTconInfo *pTcon; 1278 struct cifs_tcon *pTcon;
1281 char *full_path = NULL; 1279 char *full_path = NULL;
1282 struct inode *newinode = NULL; 1280 struct inode *newinode = NULL;
1283 struct cifs_fattr fattr; 1281 struct cifs_fattr fattr;
@@ -1455,7 +1453,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
1455 int xid; 1453 int xid;
1456 struct cifs_sb_info *cifs_sb; 1454 struct cifs_sb_info *cifs_sb;
1457 struct tcon_link *tlink; 1455 struct tcon_link *tlink;
1458 struct cifsTconInfo *pTcon; 1456 struct cifs_tcon *pTcon;
1459 char *full_path = NULL; 1457 char *full_path = NULL;
1460 struct cifsInodeInfo *cifsInode; 1458 struct cifsInodeInfo *cifsInode;
1461 1459
@@ -1512,7 +1510,7 @@ cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath,
1512{ 1510{
1513 struct cifs_sb_info *cifs_sb = CIFS_SB(from_dentry->d_sb); 1511 struct cifs_sb_info *cifs_sb = CIFS_SB(from_dentry->d_sb);
1514 struct tcon_link *tlink; 1512 struct tcon_link *tlink;
1515 struct cifsTconInfo *pTcon; 1513 struct cifs_tcon *pTcon;
1516 __u16 srcfid; 1514 __u16 srcfid;
1517 int oplock, rc; 1515 int oplock, rc;
1518 1516
@@ -1564,7 +1562,7 @@ int cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
1564 char *toName = NULL; 1562 char *toName = NULL;
1565 struct cifs_sb_info *cifs_sb; 1563 struct cifs_sb_info *cifs_sb;
1566 struct tcon_link *tlink; 1564 struct tcon_link *tlink;
1567 struct cifsTconInfo *tcon; 1565 struct cifs_tcon *tcon;
1568 FILE_UNIX_BASIC_INFO *info_buf_source = NULL; 1566 FILE_UNIX_BASIC_INFO *info_buf_source = NULL;
1569 FILE_UNIX_BASIC_INFO *info_buf_target; 1567 FILE_UNIX_BASIC_INFO *info_buf_target;
1570 int xid, rc, tmprc; 1568 int xid, rc, tmprc;
@@ -1794,7 +1792,7 @@ int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
1794 struct kstat *stat) 1792 struct kstat *stat)
1795{ 1793{
1796 struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb); 1794 struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb);
1797 struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); 1795 struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
1798 struct inode *inode = dentry->d_inode; 1796 struct inode *inode = dentry->d_inode;
1799 int rc; 1797 int rc;
1800 1798
@@ -1872,7 +1870,8 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
1872 struct cifsInodeInfo *cifsInode = CIFS_I(inode); 1870 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1873 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 1871 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1874 struct tcon_link *tlink = NULL; 1872 struct tcon_link *tlink = NULL;
1875 struct cifsTconInfo *pTcon = NULL; 1873 struct cifs_tcon *pTcon = NULL;
1874 struct cifs_io_parms io_parms;
1876 1875
1877 /* 1876 /*
1878 * To avoid spurious oplock breaks from server, in the case of 1877 * To avoid spurious oplock breaks from server, in the case of
@@ -1894,8 +1893,14 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
1894 cFYI(1, "SetFSize for attrs rc = %d", rc); 1893 cFYI(1, "SetFSize for attrs rc = %d", rc);
1895 if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { 1894 if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1896 unsigned int bytes_written; 1895 unsigned int bytes_written;
1897 rc = CIFSSMBWrite(xid, pTcon, nfid, 0, attrs->ia_size, 1896
1898 &bytes_written, NULL, NULL, 1); 1897 io_parms.netfid = nfid;
1898 io_parms.pid = npid;
1899 io_parms.tcon = pTcon;
1900 io_parms.offset = 0;
1901 io_parms.length = attrs->ia_size;
1902 rc = CIFSSMBWrite(xid, &io_parms, &bytes_written,
1903 NULL, NULL, 1);
1899 cFYI(1, "Wrt seteof rc %d", rc); 1904 cFYI(1, "Wrt seteof rc %d", rc);
1900 } 1905 }
1901 } else 1906 } else
@@ -1930,10 +1935,15 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
1930 CIFS_MOUNT_MAP_SPECIAL_CHR); 1935 CIFS_MOUNT_MAP_SPECIAL_CHR);
1931 if (rc == 0) { 1936 if (rc == 0) {
1932 unsigned int bytes_written; 1937 unsigned int bytes_written;
1933 rc = CIFSSMBWrite(xid, pTcon, netfid, 0, 1938
1934 attrs->ia_size, 1939 io_parms.netfid = netfid;
1935 &bytes_written, NULL, 1940 io_parms.pid = current->tgid;
1936 NULL, 1); 1941 io_parms.tcon = pTcon;
1942 io_parms.offset = 0;
1943 io_parms.length = attrs->ia_size;
1944 rc = CIFSSMBWrite(xid, &io_parms,
1945 &bytes_written,
1946 NULL, NULL, 1);
1937 cFYI(1, "wrt seteof rc %d", rc); 1947 cFYI(1, "wrt seteof rc %d", rc);
1938 CIFSSMBClose(xid, pTcon, netfid); 1948 CIFSSMBClose(xid, pTcon, netfid);
1939 } 1949 }
@@ -1961,7 +1971,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
1961 struct cifsInodeInfo *cifsInode = CIFS_I(inode); 1971 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1962 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 1972 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1963 struct tcon_link *tlink; 1973 struct tcon_link *tlink;
1964 struct cifsTconInfo *pTcon; 1974 struct cifs_tcon *pTcon;
1965 struct cifs_unix_set_info_args *args = NULL; 1975 struct cifs_unix_set_info_args *args = NULL;
1966 struct cifsFileInfo *open_file; 1976 struct cifsFileInfo *open_file;
1967 1977
@@ -2247,7 +2257,7 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs)
2247{ 2257{
2248 struct inode *inode = direntry->d_inode; 2258 struct inode *inode = direntry->d_inode;
2249 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 2259 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
2250 struct cifsTconInfo *pTcon = cifs_sb_master_tcon(cifs_sb); 2260 struct cifs_tcon *pTcon = cifs_sb_master_tcon(cifs_sb);
2251 2261
2252 if (pTcon->unix_ext) 2262 if (pTcon->unix_ext)
2253 return cifs_setattr_unix(direntry, attrs); 2263 return cifs_setattr_unix(direntry, attrs);
diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c
index 0c98672d0122..4221b5e48a42 100644
--- a/fs/cifs/ioctl.c
+++ b/fs/cifs/ioctl.c
@@ -38,7 +38,7 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
38 struct cifs_sb_info *cifs_sb; 38 struct cifs_sb_info *cifs_sb;
39#ifdef CONFIG_CIFS_POSIX 39#ifdef CONFIG_CIFS_POSIX
40 struct cifsFileInfo *pSMBFile = filep->private_data; 40 struct cifsFileInfo *pSMBFile = filep->private_data;
41 struct cifsTconInfo *tcon; 41 struct cifs_tcon *tcon;
42 __u64 ExtAttrBits = 0; 42 __u64 ExtAttrBits = 0;
43 __u64 ExtAttrMask = 0; 43 __u64 ExtAttrMask = 0;
44 __u64 caps; 44 __u64 caps;
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index ce417a9764a3..556b1a0b54de 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -175,7 +175,7 @@ CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str)
175} 175}
176 176
177static int 177static int
178CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon, 178CIFSCreateMFSymLink(const int xid, struct cifs_tcon *tcon,
179 const char *fromName, const char *toName, 179 const char *fromName, const char *toName,
180 const struct nls_table *nls_codepage, int remap) 180 const struct nls_table *nls_codepage, int remap)
181{ 181{
@@ -184,6 +184,7 @@ CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
184 __u16 netfid = 0; 184 __u16 netfid = 0;
185 u8 *buf; 185 u8 *buf;
186 unsigned int bytes_written = 0; 186 unsigned int bytes_written = 0;
187 struct cifs_io_parms io_parms;
187 188
188 buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL); 189 buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
189 if (!buf) 190 if (!buf)
@@ -203,10 +204,13 @@ CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
203 return rc; 204 return rc;
204 } 205 }
205 206
206 rc = CIFSSMBWrite(xid, tcon, netfid, 207 io_parms.netfid = netfid;
207 CIFS_MF_SYMLINK_FILE_SIZE /* length */, 208 io_parms.pid = current->tgid;
208 0 /* offset */, 209 io_parms.tcon = tcon;
209 &bytes_written, buf, NULL, 0); 210 io_parms.offset = 0;
211 io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
212
213 rc = CIFSSMBWrite(xid, &io_parms, &bytes_written, buf, NULL, 0);
210 CIFSSMBClose(xid, tcon, netfid); 214 CIFSSMBClose(xid, tcon, netfid);
211 kfree(buf); 215 kfree(buf);
212 if (rc != 0) 216 if (rc != 0)
@@ -219,7 +223,7 @@ CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
219} 223}
220 224
221static int 225static int
222CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon, 226CIFSQueryMFSymLink(const int xid, struct cifs_tcon *tcon,
223 const unsigned char *searchName, char **symlinkinfo, 227 const unsigned char *searchName, char **symlinkinfo,
224 const struct nls_table *nls_codepage, int remap) 228 const struct nls_table *nls_codepage, int remap)
225{ 229{
@@ -231,6 +235,7 @@ CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon,
231 unsigned int bytes_read = 0; 235 unsigned int bytes_read = 0;
232 int buf_type = CIFS_NO_BUFFER; 236 int buf_type = CIFS_NO_BUFFER;
233 unsigned int link_len = 0; 237 unsigned int link_len = 0;
238 struct cifs_io_parms io_parms;
234 FILE_ALL_INFO file_info; 239 FILE_ALL_INFO file_info;
235 240
236 rc = CIFSSMBOpen(xid, tcon, searchName, FILE_OPEN, GENERIC_READ, 241 rc = CIFSSMBOpen(xid, tcon, searchName, FILE_OPEN, GENERIC_READ,
@@ -249,11 +254,13 @@ CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon,
249 if (!buf) 254 if (!buf)
250 return -ENOMEM; 255 return -ENOMEM;
251 pbuf = buf; 256 pbuf = buf;
257 io_parms.netfid = netfid;
258 io_parms.pid = current->tgid;
259 io_parms.tcon = tcon;
260 io_parms.offset = 0;
261 io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
252 262
253 rc = CIFSSMBRead(xid, tcon, netfid, 263 rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf, &buf_type);
254 CIFS_MF_SYMLINK_FILE_SIZE /* length */,
255 0 /* offset */,
256 &bytes_read, &pbuf, &buf_type);
257 CIFSSMBClose(xid, tcon, netfid); 264 CIFSSMBClose(xid, tcon, netfid);
258 if (rc != 0) { 265 if (rc != 0) {
259 kfree(buf); 266 kfree(buf);
@@ -291,7 +298,8 @@ CIFSCheckMFSymlink(struct cifs_fattr *fattr,
291 int oplock = 0; 298 int oplock = 0;
292 __u16 netfid = 0; 299 __u16 netfid = 0;
293 struct tcon_link *tlink; 300 struct tcon_link *tlink;
294 struct cifsTconInfo *pTcon; 301 struct cifs_tcon *pTcon;
302 struct cifs_io_parms io_parms;
295 u8 *buf; 303 u8 *buf;
296 char *pbuf; 304 char *pbuf;
297 unsigned int bytes_read = 0; 305 unsigned int bytes_read = 0;
@@ -328,11 +336,13 @@ CIFSCheckMFSymlink(struct cifs_fattr *fattr,
328 goto out; 336 goto out;
329 } 337 }
330 pbuf = buf; 338 pbuf = buf;
339 io_parms.netfid = netfid;
340 io_parms.pid = current->tgid;
341 io_parms.tcon = pTcon;
342 io_parms.offset = 0;
343 io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
331 344
332 rc = CIFSSMBRead(xid, pTcon, netfid, 345 rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf, &buf_type);
333 CIFS_MF_SYMLINK_FILE_SIZE /* length */,
334 0 /* offset */,
335 &bytes_read, &pbuf, &buf_type);
336 CIFSSMBClose(xid, pTcon, netfid); 346 CIFSSMBClose(xid, pTcon, netfid);
337 if (rc != 0) { 347 if (rc != 0) {
338 kfree(buf); 348 kfree(buf);
@@ -370,7 +380,7 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
370 char *toName = NULL; 380 char *toName = NULL;
371 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 381 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
372 struct tcon_link *tlink; 382 struct tcon_link *tlink;
373 struct cifsTconInfo *pTcon; 383 struct cifs_tcon *pTcon;
374 struct cifsInodeInfo *cifsInode; 384 struct cifsInodeInfo *cifsInode;
375 385
376 tlink = cifs_sb_tlink(cifs_sb); 386 tlink = cifs_sb_tlink(cifs_sb);
@@ -445,7 +455,7 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
445 char *target_path = NULL; 455 char *target_path = NULL;
446 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 456 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
447 struct tcon_link *tlink = NULL; 457 struct tcon_link *tlink = NULL;
448 struct cifsTconInfo *tcon; 458 struct cifs_tcon *tcon;
449 459
450 xid = GetXid(); 460 xid = GetXid();
451 461
@@ -518,7 +528,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
518 int xid; 528 int xid;
519 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 529 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
520 struct tcon_link *tlink; 530 struct tcon_link *tlink;
521 struct cifsTconInfo *pTcon; 531 struct cifs_tcon *pTcon;
522 char *full_path = NULL; 532 char *full_path = NULL;
523 struct inode *newinode = NULL; 533 struct inode *newinode = NULL;
524 534
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 907531ac5888..03a1f491d39b 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -67,12 +67,12 @@ _FreeXid(unsigned int xid)
67 spin_unlock(&GlobalMid_Lock); 67 spin_unlock(&GlobalMid_Lock);
68} 68}
69 69
70struct cifsSesInfo * 70struct cifs_ses *
71sesInfoAlloc(void) 71sesInfoAlloc(void)
72{ 72{
73 struct cifsSesInfo *ret_buf; 73 struct cifs_ses *ret_buf;
74 74
75 ret_buf = kzalloc(sizeof(struct cifsSesInfo), GFP_KERNEL); 75 ret_buf = kzalloc(sizeof(struct cifs_ses), GFP_KERNEL);
76 if (ret_buf) { 76 if (ret_buf) {
77 atomic_inc(&sesInfoAllocCount); 77 atomic_inc(&sesInfoAllocCount);
78 ret_buf->status = CifsNew; 78 ret_buf->status = CifsNew;
@@ -85,7 +85,7 @@ sesInfoAlloc(void)
85} 85}
86 86
87void 87void
88sesInfoFree(struct cifsSesInfo *buf_to_free) 88sesInfoFree(struct cifs_ses *buf_to_free)
89{ 89{
90 if (buf_to_free == NULL) { 90 if (buf_to_free == NULL) {
91 cFYI(1, "Null buffer passed to sesInfoFree"); 91 cFYI(1, "Null buffer passed to sesInfoFree");
@@ -105,11 +105,11 @@ sesInfoFree(struct cifsSesInfo *buf_to_free)
105 kfree(buf_to_free); 105 kfree(buf_to_free);
106} 106}
107 107
108struct cifsTconInfo * 108struct cifs_tcon *
109tconInfoAlloc(void) 109tconInfoAlloc(void)
110{ 110{
111 struct cifsTconInfo *ret_buf; 111 struct cifs_tcon *ret_buf;
112 ret_buf = kzalloc(sizeof(struct cifsTconInfo), GFP_KERNEL); 112 ret_buf = kzalloc(sizeof(struct cifs_tcon), GFP_KERNEL);
113 if (ret_buf) { 113 if (ret_buf) {
114 atomic_inc(&tconInfoAllocCount); 114 atomic_inc(&tconInfoAllocCount);
115 ret_buf->tidStatus = CifsNew; 115 ret_buf->tidStatus = CifsNew;
@@ -124,7 +124,7 @@ tconInfoAlloc(void)
124} 124}
125 125
126void 126void
127tconInfoFree(struct cifsTconInfo *buf_to_free) 127tconInfoFree(struct cifs_tcon *buf_to_free)
128{ 128{
129 if (buf_to_free == NULL) { 129 if (buf_to_free == NULL) {
130 cFYI(1, "Null buffer passed to tconInfoFree"); 130 cFYI(1, "Null buffer passed to tconInfoFree");
@@ -295,11 +295,11 @@ __u16 GetNextMid(struct TCP_Server_Info *server)
295 case it is responsbility of caller to set the mid */ 295 case it is responsbility of caller to set the mid */
296void 296void
297header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , 297header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
298 const struct cifsTconInfo *treeCon, int word_count 298 const struct cifs_tcon *treeCon, int word_count
299 /* length of fixed section (word count) in two byte units */) 299 /* length of fixed section (word count) in two byte units */)
300{ 300{
301 struct list_head *temp_item; 301 struct list_head *temp_item;
302 struct cifsSesInfo *ses; 302 struct cifs_ses *ses;
303 char *temp = (char *) buffer; 303 char *temp = (char *) buffer;
304 304
305 memset(temp, 0, 256); /* bigger than MAX_CIFS_HDR_SIZE */ 305 memset(temp, 0, 256); /* bigger than MAX_CIFS_HDR_SIZE */
@@ -359,7 +359,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
359 "did not match tcon uid"); 359 "did not match tcon uid");
360 spin_lock(&cifs_tcp_ses_lock); 360 spin_lock(&cifs_tcp_ses_lock);
361 list_for_each(temp_item, &treeCon->ses->server->smb_ses_list) { 361 list_for_each(temp_item, &treeCon->ses->server->smb_ses_list) {
362 ses = list_entry(temp_item, struct cifsSesInfo, smb_ses_list); 362 ses = list_entry(temp_item, struct cifs_ses, smb_ses_list);
363 if (ses->linux_uid == current_fsuid()) { 363 if (ses->linux_uid == current_fsuid()) {
364 if (ses->server == treeCon->ses->server) { 364 if (ses->server == treeCon->ses->server) {
365 cFYI(1, "found matching uid substitute right smb_uid"); 365 cFYI(1, "found matching uid substitute right smb_uid");
@@ -380,7 +380,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
380 if (treeCon->nocase) 380 if (treeCon->nocase)
381 buffer->Flags |= SMBFLG_CASELESS; 381 buffer->Flags |= SMBFLG_CASELESS;
382 if ((treeCon->ses) && (treeCon->ses->server)) 382 if ((treeCon->ses) && (treeCon->ses->server))
383 if (treeCon->ses->server->secMode & 383 if (treeCon->ses->server->sec_mode &
384 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 384 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
385 buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 385 buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
386 } 386 }
@@ -507,8 +507,8 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
507{ 507{
508 struct smb_com_lock_req *pSMB = (struct smb_com_lock_req *)buf; 508 struct smb_com_lock_req *pSMB = (struct smb_com_lock_req *)buf;
509 struct list_head *tmp, *tmp1, *tmp2; 509 struct list_head *tmp, *tmp1, *tmp2;
510 struct cifsSesInfo *ses; 510 struct cifs_ses *ses;
511 struct cifsTconInfo *tcon; 511 struct cifs_tcon *tcon;
512 struct cifsInodeInfo *pCifsInode; 512 struct cifsInodeInfo *pCifsInode;
513 struct cifsFileInfo *netfile; 513 struct cifsFileInfo *netfile;
514 514
@@ -566,9 +566,9 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
566 /* look up tcon based on tid & uid */ 566 /* look up tcon based on tid & uid */
567 spin_lock(&cifs_tcp_ses_lock); 567 spin_lock(&cifs_tcp_ses_lock);
568 list_for_each(tmp, &srv->smb_ses_list) { 568 list_for_each(tmp, &srv->smb_ses_list) {
569 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list); 569 ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
570 list_for_each(tmp1, &ses->tcon_list) { 570 list_for_each(tmp1, &ses->tcon_list) {
571 tcon = list_entry(tmp1, struct cifsTconInfo, tcon_list); 571 tcon = list_entry(tmp1, struct cifs_tcon, tcon_list);
572 if (tcon->tid != buf->Tid) 572 if (tcon->tid != buf->Tid)
573 continue; 573 continue;
574 574
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
index 79b71c2c7c9d..73e47e84b61a 100644
--- a/fs/cifs/netmisc.c
+++ b/fs/cifs/netmisc.c
@@ -836,7 +836,7 @@ ntstatus_to_dos(__u32 ntstatus, __u8 *eclass, __u16 *ecode)
836} 836}
837 837
838int 838int
839map_smb_to_linux_error(struct smb_hdr *smb, int logErr) 839map_smb_to_linux_error(struct smb_hdr *smb, bool logErr)
840{ 840{
841 unsigned int i; 841 unsigned int i;
842 int rc = -EIO; /* if transport error smb error may not be set */ 842 int rc = -EIO; /* if transport error smb error may not be set */
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index f8e4cd2a7912..6751e745bbc6 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -195,7 +195,7 @@ int get_symlink_reparse_path(char *full_path, struct cifs_sb_info *cifs_sb,
195 int len; 195 int len;
196 int oplock = 0; 196 int oplock = 0;
197 int rc; 197 int rc;
198 struct cifsTconInfo *ptcon = cifs_sb_tcon(cifs_sb); 198 struct cifs_tcon *ptcon = cifs_sb_tcon(cifs_sb);
199 char *tmpbuffer; 199 char *tmpbuffer;
200 200
201 rc = CIFSSMBOpen(xid, ptcon, full_path, FILE_OPEN, GENERIC_READ, 201 rc = CIFSSMBOpen(xid, ptcon, full_path, FILE_OPEN, GENERIC_READ,
@@ -223,7 +223,7 @@ static int initiate_cifs_search(const int xid, struct file *file)
223 struct cifsFileInfo *cifsFile; 223 struct cifsFileInfo *cifsFile;
224 struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); 224 struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
225 struct tcon_link *tlink = NULL; 225 struct tcon_link *tlink = NULL;
226 struct cifsTconInfo *pTcon; 226 struct cifs_tcon *pTcon;
227 227
228 if (file->private_data == NULL) { 228 if (file->private_data == NULL) {
229 tlink = cifs_sb_tlink(cifs_sb); 229 tlink = cifs_sb_tlink(cifs_sb);
@@ -496,7 +496,7 @@ static int cifs_save_resume_key(const char *current_entry,
496 assume that they are located in the findfirst return buffer.*/ 496 assume that they are located in the findfirst return buffer.*/
497/* We start counting in the buffer with entry 2 and increment for every 497/* We start counting in the buffer with entry 2 and increment for every
498 entry (do not increment for . or .. entry) */ 498 entry (do not increment for . or .. entry) */
499static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, 499static int find_cifs_entry(const int xid, struct cifs_tcon *pTcon,
500 struct file *file, char **ppCurrentEntry, int *num_to_ret) 500 struct file *file, char **ppCurrentEntry, int *num_to_ret)
501{ 501{
502 int rc = 0; 502 int rc = 0;
@@ -764,7 +764,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
764{ 764{
765 int rc = 0; 765 int rc = 0;
766 int xid, i; 766 int xid, i;
767 struct cifsTconInfo *pTcon; 767 struct cifs_tcon *pTcon;
768 struct cifsFileInfo *cifsFile = NULL; 768 struct cifsFileInfo *cifsFile = NULL;
769 char *current_entry; 769 char *current_entry;
770 int num_to_fill = 0; 770 int num_to_fill = 0;
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index 7dd462100378..3892ab817a36 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -37,13 +37,13 @@
37 * the socket has been reestablished (so we know whether to use vc 0). 37 * the socket has been reestablished (so we know whether to use vc 0).
38 * Called while holding the cifs_tcp_ses_lock, so do not block 38 * Called while holding the cifs_tcp_ses_lock, so do not block
39 */ 39 */
40static bool is_first_ses_reconnect(struct cifsSesInfo *ses) 40static bool is_first_ses_reconnect(struct cifs_ses *ses)
41{ 41{
42 struct list_head *tmp; 42 struct list_head *tmp;
43 struct cifsSesInfo *tmp_ses; 43 struct cifs_ses *tmp_ses;
44 44
45 list_for_each(tmp, &ses->server->smb_ses_list) { 45 list_for_each(tmp, &ses->server->smb_ses_list) {
46 tmp_ses = list_entry(tmp, struct cifsSesInfo, 46 tmp_ses = list_entry(tmp, struct cifs_ses,
47 smb_ses_list); 47 smb_ses_list);
48 if (tmp_ses->need_reconnect == false) 48 if (tmp_ses->need_reconnect == false)
49 return false; 49 return false;
@@ -61,11 +61,11 @@ static bool is_first_ses_reconnect(struct cifsSesInfo *ses)
61 * any vc but zero (some servers reset the connection on vcnum zero) 61 * any vc but zero (some servers reset the connection on vcnum zero)
62 * 62 *
63 */ 63 */
64static __le16 get_next_vcnum(struct cifsSesInfo *ses) 64static __le16 get_next_vcnum(struct cifs_ses *ses)
65{ 65{
66 __u16 vcnum = 0; 66 __u16 vcnum = 0;
67 struct list_head *tmp; 67 struct list_head *tmp;
68 struct cifsSesInfo *tmp_ses; 68 struct cifs_ses *tmp_ses;
69 __u16 max_vcs = ses->server->max_vcs; 69 __u16 max_vcs = ses->server->max_vcs;
70 __u16 i; 70 __u16 i;
71 int free_vc_found = 0; 71 int free_vc_found = 0;
@@ -87,7 +87,7 @@ static __le16 get_next_vcnum(struct cifsSesInfo *ses)
87 free_vc_found = 1; 87 free_vc_found = 1;
88 88
89 list_for_each(tmp, &ses->server->smb_ses_list) { 89 list_for_each(tmp, &ses->server->smb_ses_list) {
90 tmp_ses = list_entry(tmp, struct cifsSesInfo, 90 tmp_ses = list_entry(tmp, struct cifs_ses,
91 smb_ses_list); 91 smb_ses_list);
92 if (tmp_ses->vcnum == i) { 92 if (tmp_ses->vcnum == i) {
93 free_vc_found = 0; 93 free_vc_found = 0;
@@ -114,7 +114,7 @@ get_vc_num_exit:
114 return cpu_to_le16(vcnum); 114 return cpu_to_le16(vcnum);
115} 115}
116 116
117static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB) 117static __u32 cifs_ssetup_hdr(struct cifs_ses *ses, SESSION_SETUP_ANDX *pSMB)
118{ 118{
119 __u32 capabilities = 0; 119 __u32 capabilities = 0;
120 120
@@ -136,7 +136,7 @@ static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)
136 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS | 136 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
137 CAP_LARGE_WRITE_X | CAP_LARGE_READ_X; 137 CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
138 138
139 if (ses->server->secMode & 139 if (ses->server->sec_mode &
140 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 140 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
141 pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 141 pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
142 142
@@ -181,7 +181,7 @@ unicode_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp)
181 *pbcc_area = bcc_ptr; 181 *pbcc_area = bcc_ptr;
182} 182}
183 183
184static void unicode_domain_string(char **pbcc_area, struct cifsSesInfo *ses, 184static void unicode_domain_string(char **pbcc_area, struct cifs_ses *ses,
185 const struct nls_table *nls_cp) 185 const struct nls_table *nls_cp)
186{ 186{
187 char *bcc_ptr = *pbcc_area; 187 char *bcc_ptr = *pbcc_area;
@@ -204,7 +204,7 @@ static void unicode_domain_string(char **pbcc_area, struct cifsSesInfo *ses,
204} 204}
205 205
206 206
207static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses, 207static void unicode_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
208 const struct nls_table *nls_cp) 208 const struct nls_table *nls_cp)
209{ 209{
210 char *bcc_ptr = *pbcc_area; 210 char *bcc_ptr = *pbcc_area;
@@ -236,7 +236,7 @@ static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
236 *pbcc_area = bcc_ptr; 236 *pbcc_area = bcc_ptr;
237} 237}
238 238
239static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses, 239static void ascii_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
240 const struct nls_table *nls_cp) 240 const struct nls_table *nls_cp)
241{ 241{
242 char *bcc_ptr = *pbcc_area; 242 char *bcc_ptr = *pbcc_area;
@@ -276,7 +276,7 @@ static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
276} 276}
277 277
278static void 278static void
279decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses, 279decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifs_ses *ses,
280 const struct nls_table *nls_cp) 280 const struct nls_table *nls_cp)
281{ 281{
282 int len; 282 int len;
@@ -310,7 +310,7 @@ decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses,
310} 310}
311 311
312static int decode_ascii_ssetup(char **pbcc_area, __u16 bleft, 312static int decode_ascii_ssetup(char **pbcc_area, __u16 bleft,
313 struct cifsSesInfo *ses, 313 struct cifs_ses *ses,
314 const struct nls_table *nls_cp) 314 const struct nls_table *nls_cp)
315{ 315{
316 int rc = 0; 316 int rc = 0;
@@ -364,7 +364,7 @@ static int decode_ascii_ssetup(char **pbcc_area, __u16 bleft,
364} 364}
365 365
366static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, 366static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
367 struct cifsSesInfo *ses) 367 struct cifs_ses *ses)
368{ 368{
369 unsigned int tioffset; /* challenge message target info area */ 369 unsigned int tioffset; /* challenge message target info area */
370 unsigned int tilen; /* challenge message target info area length */ 370 unsigned int tilen; /* challenge message target info area length */
@@ -411,7 +411,7 @@ static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
411/* We do not malloc the blob, it is passed in pbuffer, because 411/* We do not malloc the blob, it is passed in pbuffer, because
412 it is fixed size, and small, making this approach cleaner */ 412 it is fixed size, and small, making this approach cleaner */
413static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer, 413static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
414 struct cifsSesInfo *ses) 414 struct cifs_ses *ses)
415{ 415{
416 NEGOTIATE_MESSAGE *sec_blob = (NEGOTIATE_MESSAGE *)pbuffer; 416 NEGOTIATE_MESSAGE *sec_blob = (NEGOTIATE_MESSAGE *)pbuffer;
417 __u32 flags; 417 __u32 flags;
@@ -424,7 +424,7 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
424 flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET | 424 flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET |
425 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | 425 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
426 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC; 426 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
427 if (ses->server->secMode & 427 if (ses->server->sec_mode &
428 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { 428 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
429 flags |= NTLMSSP_NEGOTIATE_SIGN; 429 flags |= NTLMSSP_NEGOTIATE_SIGN;
430 if (!ses->server->session_estab) 430 if (!ses->server->session_estab)
@@ -449,7 +449,7 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
449 This function returns the length of the data in the blob */ 449 This function returns the length of the data in the blob */
450static int build_ntlmssp_auth_blob(unsigned char *pbuffer, 450static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
451 u16 *buflen, 451 u16 *buflen,
452 struct cifsSesInfo *ses, 452 struct cifs_ses *ses,
453 const struct nls_table *nls_cp) 453 const struct nls_table *nls_cp)
454{ 454{
455 int rc; 455 int rc;
@@ -464,10 +464,10 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
464 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO | 464 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO |
465 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | 465 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
466 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC; 466 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
467 if (ses->server->secMode & 467 if (ses->server->sec_mode &
468 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 468 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
469 flags |= NTLMSSP_NEGOTIATE_SIGN; 469 flags |= NTLMSSP_NEGOTIATE_SIGN;
470 if (ses->server->secMode & SECMODE_SIGN_REQUIRED) 470 if (ses->server->sec_mode & SECMODE_SIGN_REQUIRED)
471 flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; 471 flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
472 472
473 tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE); 473 tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE);
@@ -551,7 +551,7 @@ setup_ntlmv2_ret:
551} 551}
552 552
553int 553int
554CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, 554CIFS_SessSetup(unsigned int xid, struct cifs_ses *ses,
555 const struct nls_table *nls_cp) 555 const struct nls_table *nls_cp)
556{ 556{
557 int rc = 0; 557 int rc = 0;
@@ -657,7 +657,7 @@ ssetup_ntlmssp_authenticate:
657 */ 657 */
658 658
659 rc = calc_lanman_hash(ses->password, ses->server->cryptkey, 659 rc = calc_lanman_hash(ses->password, ses->server->cryptkey,
660 ses->server->secMode & SECMODE_PW_ENCRYPT ? 660 ses->server->sec_mode & SECMODE_PW_ENCRYPT ?
661 true : false, lnm_session_key); 661 true : false, lnm_session_key);
662 662
663 ses->flags |= CIFS_SES_LANMAN; 663 ses->flags |= CIFS_SES_LANMAN;
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index f2513fb8c391..147aa22c3c3a 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -295,7 +295,7 @@ static int wait_for_free_request(struct TCP_Server_Info *server,
295 return 0; 295 return 0;
296} 296}
297 297
298static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf, 298static int allocate_mid(struct cifs_ses *ses, struct smb_hdr *in_buf,
299 struct mid_q_entry **ppmidQ) 299 struct mid_q_entry **ppmidQ)
300{ 300{
301 if (ses->server->tcpStatus == CifsExiting) { 301 if (ses->server->tcpStatus == CifsExiting) {
@@ -342,22 +342,24 @@ wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ)
342 * the result. Caller is responsible for dealing with timeouts. 342 * the result. Caller is responsible for dealing with timeouts.
343 */ 343 */
344int 344int
345cifs_call_async(struct TCP_Server_Info *server, struct smb_hdr *in_buf, 345cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov,
346 mid_callback_t *callback, void *cbdata) 346 unsigned int nvec, mid_callback_t *callback, void *cbdata,
347 bool ignore_pend)
347{ 348{
348 int rc; 349 int rc;
349 struct mid_q_entry *mid; 350 struct mid_q_entry *mid;
351 struct smb_hdr *hdr = (struct smb_hdr *)iov[0].iov_base;
350 352
351 rc = wait_for_free_request(server, CIFS_ASYNC_OP); 353 rc = wait_for_free_request(server, ignore_pend ? CIFS_ASYNC_OP : 0);
352 if (rc) 354 if (rc)
353 return rc; 355 return rc;
354 356
355 /* enable signing if server requires it */ 357 /* enable signing if server requires it */
356 if (server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 358 if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
357 in_buf->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; 359 hdr->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
358 360
359 mutex_lock(&server->srv_mutex); 361 mutex_lock(&server->srv_mutex);
360 mid = AllocMidQEntry(in_buf, server); 362 mid = AllocMidQEntry(hdr, server);
361 if (mid == NULL) { 363 if (mid == NULL) {
362 mutex_unlock(&server->srv_mutex); 364 mutex_unlock(&server->srv_mutex);
363 return -ENOMEM; 365 return -ENOMEM;
@@ -368,7 +370,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_hdr *in_buf,
368 list_add_tail(&mid->qhead, &server->pending_mid_q); 370 list_add_tail(&mid->qhead, &server->pending_mid_q);
369 spin_unlock(&GlobalMid_Lock); 371 spin_unlock(&GlobalMid_Lock);
370 372
371 rc = cifs_sign_smb(in_buf, server, &mid->sequence_number); 373 rc = cifs_sign_smb2(iov, nvec, server, &mid->sequence_number);
372 if (rc) { 374 if (rc) {
373 mutex_unlock(&server->srv_mutex); 375 mutex_unlock(&server->srv_mutex);
374 goto out_err; 376 goto out_err;
@@ -380,7 +382,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_hdr *in_buf,
380#ifdef CONFIG_CIFS_STATS2 382#ifdef CONFIG_CIFS_STATS2
381 atomic_inc(&server->inSend); 383 atomic_inc(&server->inSend);
382#endif 384#endif
383 rc = smb_send(server, in_buf, be32_to_cpu(in_buf->smb_buf_length)); 385 rc = smb_sendv(server, iov, nvec);
384#ifdef CONFIG_CIFS_STATS2 386#ifdef CONFIG_CIFS_STATS2
385 atomic_dec(&server->inSend); 387 atomic_dec(&server->inSend);
386 mid->when_sent = jiffies; 388 mid->when_sent = jiffies;
@@ -407,7 +409,7 @@ out_err:
407 * 409 *
408 */ 410 */
409int 411int
410SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses, 412SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses,
411 struct smb_hdr *in_buf, int flags) 413 struct smb_hdr *in_buf, int flags)
412{ 414{
413 int rc; 415 int rc;
@@ -424,7 +426,7 @@ SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses,
424} 426}
425 427
426static int 428static int
427sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server) 429cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)
428{ 430{
429 int rc = 0; 431 int rc = 0;
430 432
@@ -432,28 +434,21 @@ sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)
432 mid->mid, mid->midState); 434 mid->mid, mid->midState);
433 435
434 spin_lock(&GlobalMid_Lock); 436 spin_lock(&GlobalMid_Lock);
435 /* ensure that it's no longer on the pending_mid_q */
436 list_del_init(&mid->qhead);
437
438 switch (mid->midState) { 437 switch (mid->midState) {
439 case MID_RESPONSE_RECEIVED: 438 case MID_RESPONSE_RECEIVED:
440 spin_unlock(&GlobalMid_Lock); 439 spin_unlock(&GlobalMid_Lock);
441 return rc; 440 return rc;
442 case MID_REQUEST_SUBMITTED:
443 /* socket is going down, reject all calls */
444 if (server->tcpStatus == CifsExiting) {
445 cERROR(1, "%s: canceling mid=%d cmd=0x%x state=%d",
446 __func__, mid->mid, mid->command, mid->midState);
447 rc = -EHOSTDOWN;
448 break;
449 }
450 case MID_RETRY_NEEDED: 441 case MID_RETRY_NEEDED:
451 rc = -EAGAIN; 442 rc = -EAGAIN;
452 break; 443 break;
453 case MID_RESPONSE_MALFORMED: 444 case MID_RESPONSE_MALFORMED:
454 rc = -EIO; 445 rc = -EIO;
455 break; 446 break;
447 case MID_SHUTDOWN:
448 rc = -EHOSTDOWN;
449 break;
456 default: 450 default:
451 list_del_init(&mid->qhead);
457 cERROR(1, "%s: invalid mid state mid=%d state=%d", __func__, 452 cERROR(1, "%s: invalid mid state mid=%d state=%d", __func__,
458 mid->mid, mid->midState); 453 mid->mid, mid->midState);
459 rc = -EIO; 454 rc = -EIO;
@@ -502,13 +497,31 @@ send_nt_cancel(struct TCP_Server_Info *server, struct smb_hdr *in_buf,
502} 497}
503 498
504int 499int
505SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, 500cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
501 bool log_error)
502{
503 dump_smb(mid->resp_buf,
504 min_t(u32, 92, be32_to_cpu(mid->resp_buf->smb_buf_length)));
505
506 /* convert the length into a more usable form */
507 if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
508 /* FIXME: add code to kill session */
509 if (cifs_verify_signature(mid->resp_buf, server,
510 mid->sequence_number + 1) != 0)
511 cERROR(1, "Unexpected SMB signature");
512 }
513
514 /* BB special case reconnect tid and uid here? */
515 return map_smb_to_linux_error(mid->resp_buf, log_error);
516}
517
518int
519SendReceive2(const unsigned int xid, struct cifs_ses *ses,
506 struct kvec *iov, int n_vec, int *pRespBufType /* ret */, 520 struct kvec *iov, int n_vec, int *pRespBufType /* ret */,
507 const int flags) 521 const int flags)
508{ 522{
509 int rc = 0; 523 int rc = 0;
510 int long_op; 524 int long_op;
511 unsigned int receive_len;
512 struct mid_q_entry *midQ; 525 struct mid_q_entry *midQ;
513 struct smb_hdr *in_buf = iov[0].iov_base; 526 struct smb_hdr *in_buf = iov[0].iov_base;
514 527
@@ -598,61 +611,31 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
598 611
599 cifs_small_buf_release(in_buf); 612 cifs_small_buf_release(in_buf);
600 613
601 rc = sync_mid_result(midQ, ses->server); 614 rc = cifs_sync_mid_result(midQ, ses->server);
602 if (rc != 0) { 615 if (rc != 0) {
603 atomic_dec(&ses->server->inFlight); 616 atomic_dec(&ses->server->inFlight);
604 wake_up(&ses->server->request_q); 617 wake_up(&ses->server->request_q);
605 return rc; 618 return rc;
606 } 619 }
607 620
608 receive_len = be32_to_cpu(midQ->resp_buf->smb_buf_length); 621 if (!midQ->resp_buf || midQ->midState != MID_RESPONSE_RECEIVED) {
609
610 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
611 cERROR(1, "Frame too large received. Length: %d Xid: %d",
612 receive_len, xid);
613 rc = -EIO; 622 rc = -EIO;
623 cFYI(1, "Bad MID state?");
614 goto out; 624 goto out;
615 } 625 }
616 626
617 /* rcvd frame is ok */ 627 iov[0].iov_base = (char *)midQ->resp_buf;
618 628 iov[0].iov_len = be32_to_cpu(midQ->resp_buf->smb_buf_length) + 4;
619 if (midQ->resp_buf && 629 if (midQ->largeBuf)
620 (midQ->midState == MID_RESPONSE_RECEIVED)) { 630 *pRespBufType = CIFS_LARGE_BUFFER;
621 631 else
622 iov[0].iov_base = (char *)midQ->resp_buf; 632 *pRespBufType = CIFS_SMALL_BUFFER;
623 if (midQ->largeBuf)
624 *pRespBufType = CIFS_LARGE_BUFFER;
625 else
626 *pRespBufType = CIFS_SMALL_BUFFER;
627 iov[0].iov_len = receive_len + 4;
628
629 dump_smb(midQ->resp_buf, 80);
630 /* convert the length into a more usable form */
631 if ((receive_len > 24) &&
632 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
633 SECMODE_SIGN_ENABLED))) {
634 rc = cifs_verify_signature(midQ->resp_buf,
635 ses->server,
636 midQ->sequence_number+1);
637 if (rc) {
638 cERROR(1, "Unexpected SMB signature");
639 /* BB FIXME add code to kill session */
640 }
641 }
642
643 /* BB special case reconnect tid and uid here? */
644 rc = map_smb_to_linux_error(midQ->resp_buf,
645 flags & CIFS_LOG_ERROR);
646 633
647 if ((flags & CIFS_NO_RESP) == 0) 634 rc = cifs_check_receive(midQ, ses->server, flags & CIFS_LOG_ERROR);
648 midQ->resp_buf = NULL; /* mark it so buf will
649 not be freed by
650 delete_mid */
651 } else {
652 rc = -EIO;
653 cFYI(1, "Bad MID state?");
654 }
655 635
636 /* mark it so buf will not be freed by delete_mid */
637 if ((flags & CIFS_NO_RESP) == 0)
638 midQ->resp_buf = NULL;
656out: 639out:
657 delete_mid(midQ); 640 delete_mid(midQ);
658 atomic_dec(&ses->server->inFlight); 641 atomic_dec(&ses->server->inFlight);
@@ -662,12 +645,11 @@ out:
662} 645}
663 646
664int 647int
665SendReceive(const unsigned int xid, struct cifsSesInfo *ses, 648SendReceive(const unsigned int xid, struct cifs_ses *ses,
666 struct smb_hdr *in_buf, struct smb_hdr *out_buf, 649 struct smb_hdr *in_buf, struct smb_hdr *out_buf,
667 int *pbytes_returned, const int long_op) 650 int *pbytes_returned, const int long_op)
668{ 651{
669 int rc = 0; 652 int rc = 0;
670 unsigned int receive_len;
671 struct mid_q_entry *midQ; 653 struct mid_q_entry *midQ;
672 654
673 if (ses == NULL) { 655 if (ses == NULL) {
@@ -750,54 +732,23 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
750 spin_unlock(&GlobalMid_Lock); 732 spin_unlock(&GlobalMid_Lock);
751 } 733 }
752 734
753 rc = sync_mid_result(midQ, ses->server); 735 rc = cifs_sync_mid_result(midQ, ses->server);
754 if (rc != 0) { 736 if (rc != 0) {
755 atomic_dec(&ses->server->inFlight); 737 atomic_dec(&ses->server->inFlight);
756 wake_up(&ses->server->request_q); 738 wake_up(&ses->server->request_q);
757 return rc; 739 return rc;
758 } 740 }
759 741
760 receive_len = be32_to_cpu(midQ->resp_buf->smb_buf_length); 742 if (!midQ->resp_buf || !out_buf ||
761 743 midQ->midState != MID_RESPONSE_RECEIVED) {
762 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
763 cERROR(1, "Frame too large received. Length: %d Xid: %d",
764 receive_len, xid);
765 rc = -EIO;
766 goto out;
767 }
768
769 /* rcvd frame is ok */
770
771 if (midQ->resp_buf && out_buf
772 && (midQ->midState == MID_RESPONSE_RECEIVED)) {
773 out_buf->smb_buf_length = cpu_to_be32(receive_len);
774 memcpy((char *)out_buf + 4,
775 (char *)midQ->resp_buf + 4,
776 receive_len);
777
778 dump_smb(out_buf, 92);
779 /* convert the length into a more usable form */
780 if ((receive_len > 24) &&
781 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
782 SECMODE_SIGN_ENABLED))) {
783 rc = cifs_verify_signature(out_buf,
784 ses->server,
785 midQ->sequence_number+1);
786 if (rc) {
787 cERROR(1, "Unexpected SMB signature");
788 /* BB FIXME add code to kill session */
789 }
790 }
791
792 *pbytes_returned = be32_to_cpu(out_buf->smb_buf_length);
793
794 /* BB special case reconnect tid and uid here? */
795 rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );
796 } else {
797 rc = -EIO; 744 rc = -EIO;
798 cERROR(1, "Bad MID state?"); 745 cERROR(1, "Bad MID state?");
746 goto out;
799 } 747 }
800 748
749 *pbytes_returned = be32_to_cpu(midQ->resp_buf->smb_buf_length);
750 memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
751 rc = cifs_check_receive(midQ, ses->server, 0);
801out: 752out:
802 delete_mid(midQ); 753 delete_mid(midQ);
803 atomic_dec(&ses->server->inFlight); 754 atomic_dec(&ses->server->inFlight);
@@ -810,12 +761,12 @@ out:
810 blocking lock to return. */ 761 blocking lock to return. */
811 762
812static int 763static int
813send_lock_cancel(const unsigned int xid, struct cifsTconInfo *tcon, 764send_lock_cancel(const unsigned int xid, struct cifs_tcon *tcon,
814 struct smb_hdr *in_buf, 765 struct smb_hdr *in_buf,
815 struct smb_hdr *out_buf) 766 struct smb_hdr *out_buf)
816{ 767{
817 int bytes_returned; 768 int bytes_returned;
818 struct cifsSesInfo *ses = tcon->ses; 769 struct cifs_ses *ses = tcon->ses;
819 LOCK_REQ *pSMB = (LOCK_REQ *)in_buf; 770 LOCK_REQ *pSMB = (LOCK_REQ *)in_buf;
820 771
821 /* We just modify the current in_buf to change 772 /* We just modify the current in_buf to change
@@ -832,15 +783,14 @@ send_lock_cancel(const unsigned int xid, struct cifsTconInfo *tcon,
832} 783}
833 784
834int 785int
835SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, 786SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
836 struct smb_hdr *in_buf, struct smb_hdr *out_buf, 787 struct smb_hdr *in_buf, struct smb_hdr *out_buf,
837 int *pbytes_returned) 788 int *pbytes_returned)
838{ 789{
839 int rc = 0; 790 int rc = 0;
840 int rstart = 0; 791 int rstart = 0;
841 unsigned int receive_len;
842 struct mid_q_entry *midQ; 792 struct mid_q_entry *midQ;
843 struct cifsSesInfo *ses; 793 struct cifs_ses *ses;
844 794
845 if (tcon == NULL || tcon->ses == NULL) { 795 if (tcon == NULL || tcon->ses == NULL) {
846 cERROR(1, "Null smb session"); 796 cERROR(1, "Null smb session");
@@ -957,50 +907,20 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
957 rstart = 1; 907 rstart = 1;
958 } 908 }
959 909
960 rc = sync_mid_result(midQ, ses->server); 910 rc = cifs_sync_mid_result(midQ, ses->server);
961 if (rc != 0) 911 if (rc != 0)
962 return rc; 912 return rc;
963 913
964 receive_len = be32_to_cpu(midQ->resp_buf->smb_buf_length);
965 if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {
966 cERROR(1, "Frame too large received. Length: %d Xid: %d",
967 receive_len, xid);
968 rc = -EIO;
969 goto out;
970 }
971
972 /* rcvd frame is ok */ 914 /* rcvd frame is ok */
973 915 if (out_buf == NULL || midQ->midState != MID_RESPONSE_RECEIVED) {
974 if ((out_buf == NULL) || (midQ->midState != MID_RESPONSE_RECEIVED)) {
975 rc = -EIO; 916 rc = -EIO;
976 cERROR(1, "Bad MID state?"); 917 cERROR(1, "Bad MID state?");
977 goto out; 918 goto out;
978 } 919 }
979 920
980 out_buf->smb_buf_length = cpu_to_be32(receive_len); 921 *pbytes_returned = be32_to_cpu(midQ->resp_buf->smb_buf_length);
981 memcpy((char *)out_buf + 4, 922 memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
982 (char *)midQ->resp_buf + 4, 923 rc = cifs_check_receive(midQ, ses->server, 0);
983 receive_len);
984
985 dump_smb(out_buf, 92);
986 /* convert the length into a more usable form */
987 if ((receive_len > 24) &&
988 (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
989 SECMODE_SIGN_ENABLED))) {
990 rc = cifs_verify_signature(out_buf,
991 ses->server,
992 midQ->sequence_number+1);
993 if (rc) {
994 cERROR(1, "Unexpected SMB signature");
995 /* BB FIXME add code to kill session */
996 }
997 }
998
999 *pbytes_returned = be32_to_cpu(out_buf->smb_buf_length);
1000
1001 /* BB special case reconnect tid and uid here? */
1002 rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );
1003
1004out: 924out:
1005 delete_mid(midQ); 925 delete_mid(midQ);
1006 if (rstart && rc == -EACCES) 926 if (rstart && rc == -EACCES)
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c
index 912995e013ec..2a22fb2989e4 100644
--- a/fs/cifs/xattr.c
+++ b/fs/cifs/xattr.c
@@ -49,7 +49,7 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name)
49 int xid; 49 int xid;
50 struct cifs_sb_info *cifs_sb; 50 struct cifs_sb_info *cifs_sb;
51 struct tcon_link *tlink; 51 struct tcon_link *tlink;
52 struct cifsTconInfo *pTcon; 52 struct cifs_tcon *pTcon;
53 struct super_block *sb; 53 struct super_block *sb;
54 char *full_path = NULL; 54 char *full_path = NULL;
55 55
@@ -109,7 +109,7 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
109 int xid; 109 int xid;
110 struct cifs_sb_info *cifs_sb; 110 struct cifs_sb_info *cifs_sb;
111 struct tcon_link *tlink; 111 struct tcon_link *tlink;
112 struct cifsTconInfo *pTcon; 112 struct cifs_tcon *pTcon;
113 struct super_block *sb; 113 struct super_block *sb;
114 char *full_path; 114 char *full_path;
115 struct cifs_ntsd *pacl; 115 struct cifs_ntsd *pacl;
@@ -240,7 +240,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
240 int xid; 240 int xid;
241 struct cifs_sb_info *cifs_sb; 241 struct cifs_sb_info *cifs_sb;
242 struct tcon_link *tlink; 242 struct tcon_link *tlink;
243 struct cifsTconInfo *pTcon; 243 struct cifs_tcon *pTcon;
244 struct super_block *sb; 244 struct super_block *sb;
245 char *full_path; 245 char *full_path;
246 246
@@ -372,7 +372,7 @@ ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size)
372 int xid; 372 int xid;
373 struct cifs_sb_info *cifs_sb; 373 struct cifs_sb_info *cifs_sb;
374 struct tcon_link *tlink; 374 struct tcon_link *tlink;
375 struct cifsTconInfo *pTcon; 375 struct cifs_tcon *pTcon;
376 struct super_block *sb; 376 struct super_block *sb;
377 char *full_path; 377 char *full_path;
378 378