aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/cache.c16
-rw-r--r--fs/cifs/cifs_debug.c22
-rw-r--r--fs/cifs/cifs_spnego.c10
-rw-r--r--fs/cifs/cifsencrypt.c6
-rw-r--r--fs/cifs/cifsfs.c39
-rw-r--r--fs/cifs/cifsglob.h9
-rw-r--r--fs/cifs/cifssmb.c5
-rw-r--r--fs/cifs/connect.c462
-rw-r--r--fs/cifs/dir.c92
-rw-r--r--fs/cifs/file.c233
-rw-r--r--fs/cifs/inode.c20
-rw-r--r--fs/cifs/link.c4
-rw-r--r--fs/cifs/readdir.c8
-rw-r--r--fs/cifs/sess.c135
-rw-r--r--fs/cifs/transport.c2
15 files changed, 477 insertions, 586 deletions
diff --git a/fs/cifs/cache.c b/fs/cifs/cache.c
index 224d7bbd1fcc..e654dfd092c3 100644
--- a/fs/cifs/cache.c
+++ b/fs/cifs/cache.c
@@ -64,7 +64,9 @@ static uint16_t cifs_server_get_key(const void *cookie_netfs_data,
64 void *buffer, uint16_t maxbuf) 64 void *buffer, uint16_t maxbuf)
65{ 65{
66 const struct TCP_Server_Info *server = cookie_netfs_data; 66 const struct TCP_Server_Info *server = cookie_netfs_data;
67 const struct sockaddr *sa = (struct sockaddr *) &server->addr.sockAddr; 67 const struct sockaddr *sa = (struct sockaddr *) &server->dstaddr;
68 const struct sockaddr_in *addr = (struct sockaddr_in *) sa;
69 const struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) sa;
68 struct cifs_server_key *key = buffer; 70 struct cifs_server_key *key = buffer;
69 uint16_t key_len = sizeof(struct cifs_server_key); 71 uint16_t key_len = sizeof(struct cifs_server_key);
70 72
@@ -76,16 +78,16 @@ static uint16_t cifs_server_get_key(const void *cookie_netfs_data,
76 */ 78 */
77 switch (sa->sa_family) { 79 switch (sa->sa_family) {
78 case AF_INET: 80 case AF_INET:
79 key->family = server->addr.sockAddr.sin_family; 81 key->family = sa->sa_family;
80 key->port = server->addr.sockAddr.sin_port; 82 key->port = addr->sin_port;
81 key->addr[0].ipv4_addr = server->addr.sockAddr.sin_addr; 83 key->addr[0].ipv4_addr = addr->sin_addr;
82 key_len += sizeof(key->addr[0].ipv4_addr); 84 key_len += sizeof(key->addr[0].ipv4_addr);
83 break; 85 break;
84 86
85 case AF_INET6: 87 case AF_INET6:
86 key->family = server->addr.sockAddr6.sin6_family; 88 key->family = sa->sa_family;
87 key->port = server->addr.sockAddr6.sin6_port; 89 key->port = addr6->sin6_port;
88 key->addr[0].ipv6_addr = server->addr.sockAddr6.sin6_addr; 90 key->addr[0].ipv6_addr = addr6->sin6_addr;
89 key_len += sizeof(key->addr[0].ipv6_addr); 91 key_len += sizeof(key->addr[0].ipv6_addr);
90 break; 92 break;
91 93
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
index 103ab8b605b0..ede98300a8cd 100644
--- a/fs/cifs/cifs_debug.c
+++ b/fs/cifs/cifs_debug.c
@@ -119,29 +119,27 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
119 "Display Internal CIFS Data Structures for Debugging\n" 119 "Display Internal CIFS Data Structures for Debugging\n"
120 "---------------------------------------------------\n"); 120 "---------------------------------------------------\n");
121 seq_printf(m, "CIFS Version %s\n", CIFS_VERSION); 121 seq_printf(m, "CIFS Version %s\n", CIFS_VERSION);
122 seq_printf(m, "Features: "); 122 seq_printf(m, "Features:");
123#ifdef CONFIG_CIFS_DFS_UPCALL 123#ifdef CONFIG_CIFS_DFS_UPCALL
124 seq_printf(m, "dfs"); 124 seq_printf(m, " dfs");
125 seq_putc(m, ' ');
126#endif 125#endif
127#ifdef CONFIG_CIFS_FSCACHE 126#ifdef CONFIG_CIFS_FSCACHE
128 seq_printf(m, "fscache"); 127 seq_printf(m, " fscache");
129 seq_putc(m, ' ');
130#endif 128#endif
131#ifdef CONFIG_CIFS_WEAK_PW_HASH 129#ifdef CONFIG_CIFS_WEAK_PW_HASH
132 seq_printf(m, "lanman"); 130 seq_printf(m, " lanman");
133 seq_putc(m, ' ');
134#endif 131#endif
135#ifdef CONFIG_CIFS_POSIX 132#ifdef CONFIG_CIFS_POSIX
136 seq_printf(m, "posix"); 133 seq_printf(m, " posix");
137 seq_putc(m, ' ');
138#endif 134#endif
139#ifdef CONFIG_CIFS_UPCALL 135#ifdef CONFIG_CIFS_UPCALL
140 seq_printf(m, "spnego"); 136 seq_printf(m, " spnego");
141 seq_putc(m, ' ');
142#endif 137#endif
143#ifdef CONFIG_CIFS_XATTR 138#ifdef CONFIG_CIFS_XATTR
144 seq_printf(m, "xattr"); 139 seq_printf(m, " xattr");
140#endif
141#ifdef CONFIG_CIFS_ACL
142 seq_printf(m, " acl");
145#endif 143#endif
146 seq_putc(m, '\n'); 144 seq_putc(m, '\n');
147 seq_printf(m, "Active VFS Requests: %d\n", GlobalTotalActiveXid); 145 seq_printf(m, "Active VFS Requests: %d\n", GlobalTotalActiveXid);
diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c
index 87044906cd1f..4dfba8283165 100644
--- a/fs/cifs/cifs_spnego.c
+++ b/fs/cifs/cifs_spnego.c
@@ -98,6 +98,8 @@ struct key *
98cifs_get_spnego_key(struct cifsSesInfo *sesInfo) 98cifs_get_spnego_key(struct cifsSesInfo *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;
102 struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) &server->dstaddr;
101 char *description, *dp; 103 char *description, *dp;
102 size_t desc_len; 104 size_t desc_len;
103 struct key *spnego_key; 105 struct key *spnego_key;
@@ -127,10 +129,10 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
127 dp = description + strlen(description); 129 dp = description + strlen(description);
128 130
129 /* add the server address */ 131 /* add the server address */
130 if (server->addr.sockAddr.sin_family == AF_INET) 132 if (server->dstaddr.ss_family == AF_INET)
131 sprintf(dp, "ip4=%pI4", &server->addr.sockAddr.sin_addr); 133 sprintf(dp, "ip4=%pI4", &sa->sin_addr);
132 else if (server->addr.sockAddr.sin_family == AF_INET6) 134 else if (server->dstaddr.ss_family == AF_INET6)
133 sprintf(dp, "ip6=%pI6", &server->addr.sockAddr6.sin6_addr); 135 sprintf(dp, "ip6=%pI6", &sa6->sin6_addr);
134 else 136 else
135 goto out; 137 goto out;
136 138
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index f856732161ab..66f3d50d0676 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -72,6 +72,7 @@ static int cifs_calculate_signature(const struct smb_hdr *cifs_pdu,
72 return 0; 72 return 0;
73} 73}
74 74
75/* must be called with server->srv_mutex held */
75int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server, 76int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
76 __u32 *pexpected_response_sequence_number) 77 __u32 *pexpected_response_sequence_number)
77{ 78{
@@ -84,14 +85,12 @@ int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
84 if ((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0) 85 if ((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0)
85 return rc; 86 return rc;
86 87
87 spin_lock(&GlobalMid_Lock);
88 cifs_pdu->Signature.Sequence.SequenceNumber = 88 cifs_pdu->Signature.Sequence.SequenceNumber =
89 cpu_to_le32(server->sequence_number); 89 cpu_to_le32(server->sequence_number);
90 cifs_pdu->Signature.Sequence.Reserved = 0; 90 cifs_pdu->Signature.Sequence.Reserved = 0;
91 91
92 *pexpected_response_sequence_number = server->sequence_number++; 92 *pexpected_response_sequence_number = server->sequence_number++;
93 server->sequence_number++; 93 server->sequence_number++;
94 spin_unlock(&GlobalMid_Lock);
95 94
96 rc = cifs_calculate_signature(cifs_pdu, server, smb_signature); 95 rc = cifs_calculate_signature(cifs_pdu, server, smb_signature);
97 if (rc) 96 if (rc)
@@ -149,6 +148,7 @@ static int cifs_calc_signature2(const struct kvec *iov, int n_vec,
149 return rc; 148 return rc;
150} 149}
151 150
151/* must be called with server->srv_mutex held */
152int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server, 152int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
153 __u32 *pexpected_response_sequence_number) 153 __u32 *pexpected_response_sequence_number)
154{ 154{
@@ -162,14 +162,12 @@ int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
162 if ((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0) 162 if ((cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) == 0)
163 return rc; 163 return rc;
164 164
165 spin_lock(&GlobalMid_Lock);
166 cifs_pdu->Signature.Sequence.SequenceNumber = 165 cifs_pdu->Signature.Sequence.SequenceNumber =
167 cpu_to_le32(server->sequence_number); 166 cpu_to_le32(server->sequence_number);
168 cifs_pdu->Signature.Sequence.Reserved = 0; 167 cifs_pdu->Signature.Sequence.Reserved = 0;
169 168
170 *pexpected_response_sequence_number = server->sequence_number++; 169 *pexpected_response_sequence_number = server->sequence_number++;
171 server->sequence_number++; 170 server->sequence_number++;
172 spin_unlock(&GlobalMid_Lock);
173 171
174 rc = cifs_calc_signature2(iov, n_vec, server, smb_signature); 172 rc = cifs_calc_signature2(iov, n_vec, server, smb_signature);
175 if (rc) 173 if (rc)
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 3936aa7f2c22..d9f652a522a6 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -174,6 +174,12 @@ cifs_read_super(struct super_block *sb, void *data,
174 goto out_no_root; 174 goto out_no_root;
175 } 175 }
176 176
177 /* do that *after* d_alloc_root() - we want NULL ->d_op for root here */
178 if (cifs_sb_master_tcon(cifs_sb)->nocase)
179 sb->s_d_op = &cifs_ci_dentry_ops;
180 else
181 sb->s_d_op = &cifs_dentry_ops;
182
177#ifdef CONFIG_CIFS_EXPERIMENTAL 183#ifdef CONFIG_CIFS_EXPERIMENTAL
178 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { 184 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
179 cFYI(1, "export ops supported"); 185 cFYI(1, "export ops supported");
@@ -283,10 +289,13 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
283 return 0; 289 return 0;
284} 290}
285 291
286static int cifs_permission(struct inode *inode, int mask) 292static int cifs_permission(struct inode *inode, int mask, unsigned int flags)
287{ 293{
288 struct cifs_sb_info *cifs_sb; 294 struct cifs_sb_info *cifs_sb;
289 295
296 if (flags & IPERM_FLAG_RCU)
297 return -ECHILD;
298
290 cifs_sb = CIFS_SB(inode->i_sb); 299 cifs_sb = CIFS_SB(inode->i_sb);
291 300
292 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) { 301 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) {
@@ -298,7 +307,7 @@ static int cifs_permission(struct inode *inode, int mask)
298 on the client (above and beyond ACL on servers) for 307 on the client (above and beyond ACL on servers) for
299 servers which do not support setting and viewing mode bits, 308 servers which do not support setting and viewing mode bits,
300 so allowing client to check permissions is useful */ 309 so allowing client to check permissions is useful */
301 return generic_permission(inode, mask, NULL); 310 return generic_permission(inode, mask, flags, NULL);
302} 311}
303 312
304static struct kmem_cache *cifs_inode_cachep; 313static struct kmem_cache *cifs_inode_cachep;
@@ -326,6 +335,8 @@ cifs_alloc_inode(struct super_block *sb)
326 cifs_inode->invalid_mapping = false; 335 cifs_inode->invalid_mapping = false;
327 cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ 336 cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */
328 cifs_inode->server_eof = 0; 337 cifs_inode->server_eof = 0;
338 cifs_inode->uniqueid = 0;
339 cifs_inode->createtime = 0;
329 340
330 /* Can not set i_flags here - they get immediately overwritten 341 /* Can not set i_flags here - they get immediately overwritten
331 to zero by the VFS */ 342 to zero by the VFS */
@@ -334,10 +345,17 @@ cifs_alloc_inode(struct super_block *sb)
334 return &cifs_inode->vfs_inode; 345 return &cifs_inode->vfs_inode;
335} 346}
336 347
348static void cifs_i_callback(struct rcu_head *head)
349{
350 struct inode *inode = container_of(head, struct inode, i_rcu);
351 INIT_LIST_HEAD(&inode->i_dentry);
352 kmem_cache_free(cifs_inode_cachep, CIFS_I(inode));
353}
354
337static void 355static void
338cifs_destroy_inode(struct inode *inode) 356cifs_destroy_inode(struct inode *inode)
339{ 357{
340 kmem_cache_free(cifs_inode_cachep, CIFS_I(inode)); 358 call_rcu(&inode->i_rcu, cifs_i_callback);
341} 359}
342 360
343static void 361static void
@@ -351,18 +369,19 @@ cifs_evict_inode(struct inode *inode)
351static void 369static void
352cifs_show_address(struct seq_file *s, struct TCP_Server_Info *server) 370cifs_show_address(struct seq_file *s, struct TCP_Server_Info *server)
353{ 371{
372 struct sockaddr_in *sa = (struct sockaddr_in *) &server->dstaddr;
373 struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) &server->dstaddr;
374
354 seq_printf(s, ",addr="); 375 seq_printf(s, ",addr=");
355 376
356 switch (server->addr.sockAddr.sin_family) { 377 switch (server->dstaddr.ss_family) {
357 case AF_INET: 378 case AF_INET:
358 seq_printf(s, "%pI4", &server->addr.sockAddr.sin_addr.s_addr); 379 seq_printf(s, "%pI4", &sa->sin_addr.s_addr);
359 break; 380 break;
360 case AF_INET6: 381 case AF_INET6:
361 seq_printf(s, "%pI6", 382 seq_printf(s, "%pI6", &sa6->sin6_addr.s6_addr);
362 &server->addr.sockAddr6.sin6_addr.s6_addr); 383 if (sa6->sin6_scope_id)
363 if (server->addr.sockAddr6.sin6_scope_id) 384 seq_printf(s, "%%%u", sa6->sin6_scope_id);
364 seq_printf(s, "%%%u",
365 server->addr.sockAddr6.sin6_scope_id);
366 break; 385 break;
367 default: 386 default:
368 seq_printf(s, "(unknown)"); 387 seq_printf(s, "(unknown)");
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 7136c0c3e2f9..606ca8bb7102 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -163,10 +163,7 @@ struct TCP_Server_Info {
163 char server_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL]; 163 char server_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL];
164 char *hostname; /* hostname portion of UNC string */ 164 char *hostname; /* hostname portion of UNC string */
165 struct socket *ssocket; 165 struct socket *ssocket;
166 union { 166 struct sockaddr_storage dstaddr;
167 struct sockaddr_in sockAddr;
168 struct sockaddr_in6 sockAddr6;
169 } addr;
170 struct sockaddr_storage srcaddr; /* locally bind to this IP */ 167 struct sockaddr_storage srcaddr; /* locally bind to this IP */
171 wait_queue_head_t response_q; 168 wait_queue_head_t response_q;
172 wait_queue_head_t request_q; /* if more than maxmpx to srvr must block*/ 169 wait_queue_head_t request_q; /* if more than maxmpx to srvr must block*/
@@ -210,7 +207,7 @@ struct TCP_Server_Info {
210 char cryptkey[CIFS_CRYPTO_KEY_SIZE]; /* used by ntlm, ntlmv2 etc */ 207 char cryptkey[CIFS_CRYPTO_KEY_SIZE]; /* used by ntlm, ntlmv2 etc */
211 /* 16th byte of RFC1001 workstation name is always null */ 208 /* 16th byte of RFC1001 workstation name is always null */
212 char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL]; 209 char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL];
213 __u32 sequence_number; /* needed for CIFS PDU signature */ 210 __u32 sequence_number; /* for signing, protected by srv_mutex */
214 struct session_key session_key; 211 struct session_key session_key;
215 unsigned long lstrp; /* when we got last response from this server */ 212 unsigned long lstrp; /* when we got last response from this server */
216 u16 dialect; /* dialect index that server chose */ 213 u16 dialect; /* dialect index that server chose */
@@ -456,6 +453,7 @@ struct cifsInodeInfo {
456 bool invalid_mapping:1; /* pagecache is invalid */ 453 bool invalid_mapping:1; /* pagecache is invalid */
457 u64 server_eof; /* current file size on server */ 454 u64 server_eof; /* current file size on server */
458 u64 uniqueid; /* server inode number */ 455 u64 uniqueid; /* server inode number */
456 u64 createtime; /* creation time on server */
459#ifdef CONFIG_CIFS_FSCACHE 457#ifdef CONFIG_CIFS_FSCACHE
460 struct fscache_cookie *fscache; 458 struct fscache_cookie *fscache;
461#endif 459#endif
@@ -576,6 +574,7 @@ struct cifs_fattr {
576 u64 cf_uniqueid; 574 u64 cf_uniqueid;
577 u64 cf_eof; 575 u64 cf_eof;
578 u64 cf_bytes; 576 u64 cf_bytes;
577 u64 cf_createtime;
579 uid_t cf_uid; 578 uid_t cf_uid;
580 gid_t cf_gid; 579 gid_t cf_gid;
581 umode_t cf_mode; 580 umode_t cf_mode;
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 67acfb3acad2..2f6795e524d3 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -401,15 +401,12 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
401 else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_KRB5) { 401 else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_KRB5) {
402 cFYI(1, "Kerberos only mechanism, enable extended security"); 402 cFYI(1, "Kerberos only mechanism, enable extended security");
403 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; 403 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
404 } 404 } else if ((secFlags & CIFSSEC_MUST_NTLMSSP) == CIFSSEC_MUST_NTLMSSP)
405#ifdef CONFIG_CIFS_EXPERIMENTAL
406 else if ((secFlags & CIFSSEC_MUST_NTLMSSP) == CIFSSEC_MUST_NTLMSSP)
407 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; 405 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
408 else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_NTLMSSP) { 406 else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_NTLMSSP) {
409 cFYI(1, "NTLMSSP only mechanism, enable extended security"); 407 cFYI(1, "NTLMSSP only mechanism, enable extended security");
410 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; 408 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
411 } 409 }
412#endif
413 410
414 count = 0; 411 count = 0;
415 for (i = 0; i < CIFS_NUM_PROT; i++) { 412 for (i = 0; i < CIFS_NUM_PROT; i++) {
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index cc1a8604a790..a65d311d163a 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -64,8 +64,8 @@ struct smb_vol {
64 char *UNC; 64 char *UNC;
65 char *UNCip; 65 char *UNCip;
66 char *iocharset; /* local code page for mapping to and from Unicode */ 66 char *iocharset; /* local code page for mapping to and from Unicode */
67 char source_rfc1001_name[16]; /* netbios name of client */ 67 char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */
68 char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */ 68 char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */
69 uid_t cred_uid; 69 uid_t cred_uid;
70 uid_t linux_uid; 70 uid_t linux_uid;
71 gid_t linux_gid; 71 gid_t linux_gid;
@@ -115,8 +115,8 @@ struct smb_vol {
115#define TLINK_ERROR_EXPIRE (1 * HZ) 115#define TLINK_ERROR_EXPIRE (1 * HZ)
116#define TLINK_IDLE_EXPIRE (600 * HZ) 116#define TLINK_IDLE_EXPIRE (600 * HZ)
117 117
118static int ipv4_connect(struct TCP_Server_Info *server); 118static int ip_connect(struct TCP_Server_Info *server);
119static int ipv6_connect(struct TCP_Server_Info *server); 119static int generic_ip_connect(struct TCP_Server_Info *server);
120static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink); 120static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink);
121static void cifs_prune_tlinks(struct work_struct *work); 121static void cifs_prune_tlinks(struct work_struct *work);
122 122
@@ -200,10 +200,9 @@ cifs_reconnect(struct TCP_Server_Info *server)
200 while ((server->tcpStatus != CifsExiting) && 200 while ((server->tcpStatus != CifsExiting) &&
201 (server->tcpStatus != CifsGood)) { 201 (server->tcpStatus != CifsGood)) {
202 try_to_freeze(); 202 try_to_freeze();
203 if (server->addr.sockAddr6.sin6_family == AF_INET6) 203
204 rc = ipv6_connect(server); 204 /* we should try only the port we connected to before */
205 else 205 rc = generic_ip_connect(server);
206 rc = ipv4_connect(server);
207 if (rc) { 206 if (rc) {
208 cFYI(1, "reconnect error %d", rc); 207 cFYI(1, "reconnect error %d", rc);
209 msleep(3000); 208 msleep(3000);
@@ -477,7 +476,7 @@ incomplete_rcv:
477 * initialize frame) 476 * initialize frame)
478 */ 477 */
479 cifs_set_port((struct sockaddr *) 478 cifs_set_port((struct sockaddr *)
480 &server->addr.sockAddr, CIFS_PORT); 479 &server->dstaddr, CIFS_PORT);
481 cifs_reconnect(server); 480 cifs_reconnect(server);
482 csocket = server->ssocket; 481 csocket = server->ssocket;
483 wake_up(&server->response_q); 482 wake_up(&server->response_q);
@@ -817,11 +816,11 @@ cifs_parse_mount_options(char *options, const char *devname,
817 * informational, only used for servers that do not support 816 * informational, only used for servers that do not support
818 * port 445 and it can be overridden at mount time 817 * port 445 and it can be overridden at mount time
819 */ 818 */
820 memset(vol->source_rfc1001_name, 0x20, 15); 819 memset(vol->source_rfc1001_name, 0x20, RFC1001_NAME_LEN);
821 for (i = 0; i < strnlen(nodename, 15); i++) 820 for (i = 0; i < strnlen(nodename, RFC1001_NAME_LEN); i++)
822 vol->source_rfc1001_name[i] = toupper(nodename[i]); 821 vol->source_rfc1001_name[i] = toupper(nodename[i]);
823 822
824 vol->source_rfc1001_name[15] = 0; 823 vol->source_rfc1001_name[RFC1001_NAME_LEN] = 0;
825 /* null target name indicates to use *SMBSERVR default called name 824 /* null target name indicates to use *SMBSERVR default called name
826 if we end up sending RFC1001 session initialize */ 825 if we end up sending RFC1001 session initialize */
827 vol->target_rfc1001_name[0] = 0; 826 vol->target_rfc1001_name[0] = 0;
@@ -985,13 +984,11 @@ cifs_parse_mount_options(char *options, const char *devname,
985 return 1; 984 return 1;
986 } else if (strnicmp(value, "krb5", 4) == 0) { 985 } else if (strnicmp(value, "krb5", 4) == 0) {
987 vol->secFlg |= CIFSSEC_MAY_KRB5; 986 vol->secFlg |= CIFSSEC_MAY_KRB5;
988#ifdef CONFIG_CIFS_EXPERIMENTAL
989 } else if (strnicmp(value, "ntlmsspi", 8) == 0) { 987 } else if (strnicmp(value, "ntlmsspi", 8) == 0) {
990 vol->secFlg |= CIFSSEC_MAY_NTLMSSP | 988 vol->secFlg |= CIFSSEC_MAY_NTLMSSP |
991 CIFSSEC_MUST_SIGN; 989 CIFSSEC_MUST_SIGN;
992 } else if (strnicmp(value, "ntlmssp", 7) == 0) { 990 } else if (strnicmp(value, "ntlmssp", 7) == 0) {
993 vol->secFlg |= CIFSSEC_MAY_NTLMSSP; 991 vol->secFlg |= CIFSSEC_MAY_NTLMSSP;
994#endif
995 } else if (strnicmp(value, "ntlmv2i", 7) == 0) { 992 } else if (strnicmp(value, "ntlmv2i", 7) == 0) {
996 vol->secFlg |= CIFSSEC_MAY_NTLMV2 | 993 vol->secFlg |= CIFSSEC_MAY_NTLMV2 |
997 CIFSSEC_MUST_SIGN; 994 CIFSSEC_MUST_SIGN;
@@ -1168,22 +1165,22 @@ cifs_parse_mount_options(char *options, const char *devname,
1168 if (!value || !*value || (*value == ' ')) { 1165 if (!value || !*value || (*value == ' ')) {
1169 cFYI(1, "invalid (empty) netbiosname"); 1166 cFYI(1, "invalid (empty) netbiosname");
1170 } else { 1167 } else {
1171 memset(vol->source_rfc1001_name, 0x20, 15); 1168 memset(vol->source_rfc1001_name, 0x20,
1172 for (i = 0; i < 15; i++) { 1169 RFC1001_NAME_LEN);
1173 /* BB are there cases in which a comma can be 1170 /*
1174 valid in this workstation netbios name (and need 1171 * FIXME: are there cases in which a comma can
1175 special handling)? */ 1172 * be valid in workstation netbios name (and
1176 1173 * need special handling)?
1177 /* We do not uppercase netbiosname for user */ 1174 */
1175 for (i = 0; i < RFC1001_NAME_LEN; i++) {
1176 /* don't ucase netbiosname for user */
1178 if (value[i] == 0) 1177 if (value[i] == 0)
1179 break; 1178 break;
1180 else 1179 vol->source_rfc1001_name[i] = value[i];
1181 vol->source_rfc1001_name[i] =
1182 value[i];
1183 } 1180 }
1184 /* The string has 16th byte zero still from 1181 /* The string has 16th byte zero still from
1185 set at top of the function */ 1182 set at top of the function */
1186 if ((i == 15) && (value[i] != 0)) 1183 if (i == RFC1001_NAME_LEN && value[i] != 0)
1187 printk(KERN_WARNING "CIFS: netbiosname" 1184 printk(KERN_WARNING "CIFS: netbiosname"
1188 " longer than 15 truncated.\n"); 1185 " longer than 15 truncated.\n");
1189 } 1186 }
@@ -1193,7 +1190,8 @@ cifs_parse_mount_options(char *options, const char *devname,
1193 cFYI(1, "empty server netbiosname specified"); 1190 cFYI(1, "empty server netbiosname specified");
1194 } else { 1191 } else {
1195 /* last byte, type, is 0x20 for servr type */ 1192 /* last byte, type, is 0x20 for servr type */
1196 memset(vol->target_rfc1001_name, 0x20, 16); 1193 memset(vol->target_rfc1001_name, 0x20,
1194 RFC1001_NAME_LEN_WITH_NULL);
1197 1195
1198 for (i = 0; i < 15; i++) { 1196 for (i = 0; i < 15; i++) {
1199 /* BB are there cases in which a comma can be 1197 /* BB are there cases in which a comma can be
@@ -1210,7 +1208,7 @@ cifs_parse_mount_options(char *options, const char *devname,
1210 } 1208 }
1211 /* The string has 16th byte zero still from 1209 /* The string has 16th byte zero still from
1212 set at top of the function */ 1210 set at top of the function */
1213 if ((i == 15) && (value[i] != 0)) 1211 if (i == RFC1001_NAME_LEN && value[i] != 0)
1214 printk(KERN_WARNING "CIFS: server net" 1212 printk(KERN_WARNING "CIFS: server net"
1215 "biosname longer than 15 truncated.\n"); 1213 "biosname longer than 15 truncated.\n");
1216 } 1214 }
@@ -1341,10 +1339,8 @@ cifs_parse_mount_options(char *options, const char *devname,
1341 vol->no_psx_acl = 0; 1339 vol->no_psx_acl = 0;
1342 } else if (strnicmp(data, "noacl", 5) == 0) { 1340 } else if (strnicmp(data, "noacl", 5) == 0) {
1343 vol->no_psx_acl = 1; 1341 vol->no_psx_acl = 1;
1344#ifdef CONFIG_CIFS_EXPERIMENTAL
1345 } else if (strnicmp(data, "locallease", 6) == 0) { 1342 } else if (strnicmp(data, "locallease", 6) == 0) {
1346 vol->local_lease = 1; 1343 vol->local_lease = 1;
1347#endif
1348 } else if (strnicmp(data, "sign", 4) == 0) { 1344 } else if (strnicmp(data, "sign", 4) == 0) {
1349 vol->secFlg |= CIFSSEC_MUST_SIGN; 1345 vol->secFlg |= CIFSSEC_MUST_SIGN;
1350 } else if (strnicmp(data, "seal", 4) == 0) { 1346 } else if (strnicmp(data, "seal", 4) == 0) {
@@ -1454,35 +1450,71 @@ srcip_matches(struct sockaddr *srcaddr, struct sockaddr *rhs)
1454 } 1450 }
1455} 1451}
1456 1452
1453/*
1454 * If no port is specified in addr structure, we try to match with 445 port
1455 * and if it fails - with 139 ports. It should be called only if address
1456 * families of server and addr are equal.
1457 */
1458static bool
1459match_port(struct TCP_Server_Info *server, struct sockaddr *addr)
1460{
1461 unsigned short int port, *sport;
1462
1463 switch (addr->sa_family) {
1464 case AF_INET:
1465 sport = &((struct sockaddr_in *) &server->dstaddr)->sin_port;
1466 port = ((struct sockaddr_in *) addr)->sin_port;
1467 break;
1468 case AF_INET6:
1469 sport = &((struct sockaddr_in6 *) &server->dstaddr)->sin6_port;
1470 port = ((struct sockaddr_in6 *) addr)->sin6_port;
1471 break;
1472 default:
1473 WARN_ON(1);
1474 return false;
1475 }
1476
1477 if (!port) {
1478 port = htons(CIFS_PORT);
1479 if (port == *sport)
1480 return true;
1481
1482 port = htons(RFC1001_PORT);
1483 }
1484
1485 return port == *sport;
1486}
1457 1487
1458static bool 1488static bool
1459match_address(struct TCP_Server_Info *server, struct sockaddr *addr, 1489match_address(struct TCP_Server_Info *server, struct sockaddr *addr,
1460 struct sockaddr *srcaddr) 1490 struct sockaddr *srcaddr)
1461{ 1491{
1462 struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
1463 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
1464
1465 switch (addr->sa_family) { 1492 switch (addr->sa_family) {
1466 case AF_INET: 1493 case AF_INET: {
1467 if (addr4->sin_addr.s_addr != 1494 struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
1468 server->addr.sockAddr.sin_addr.s_addr) 1495 struct sockaddr_in *srv_addr4 =
1469 return false; 1496 (struct sockaddr_in *)&server->dstaddr;
1470 if (addr4->sin_port && 1497
1471 addr4->sin_port != server->addr.sockAddr.sin_port) 1498 if (addr4->sin_addr.s_addr != srv_addr4->sin_addr.s_addr)
1472 return false; 1499 return false;
1473 break; 1500 break;
1474 case AF_INET6: 1501 }
1502 case AF_INET6: {
1503 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
1504 struct sockaddr_in6 *srv_addr6 =
1505 (struct sockaddr_in6 *)&server->dstaddr;
1506
1475 if (!ipv6_addr_equal(&addr6->sin6_addr, 1507 if (!ipv6_addr_equal(&addr6->sin6_addr,
1476 &server->addr.sockAddr6.sin6_addr)) 1508 &srv_addr6->sin6_addr))
1477 return false; 1509 return false;
1478 if (addr6->sin6_scope_id != 1510 if (addr6->sin6_scope_id != srv_addr6->sin6_scope_id)
1479 server->addr.sockAddr6.sin6_scope_id)
1480 return false;
1481 if (addr6->sin6_port &&
1482 addr6->sin6_port != server->addr.sockAddr6.sin6_port)
1483 return false; 1511 return false;
1484 break; 1512 break;
1485 } 1513 }
1514 default:
1515 WARN_ON(1);
1516 return false; /* don't expect to be here */
1517 }
1486 1518
1487 if (!srcip_matches(srcaddr, (struct sockaddr *)&server->srcaddr)) 1519 if (!srcip_matches(srcaddr, (struct sockaddr *)&server->srcaddr))
1488 return false; 1520 return false;
@@ -1549,6 +1581,9 @@ cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol)
1549 (struct sockaddr *)&vol->srcaddr)) 1581 (struct sockaddr *)&vol->srcaddr))
1550 continue; 1582 continue;
1551 1583
1584 if (!match_port(server, addr))
1585 continue;
1586
1552 if (!match_security(server, vol)) 1587 if (!match_security(server, vol))
1553 continue; 1588 continue;
1554 1589
@@ -1681,14 +1716,13 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
1681 cFYI(1, "attempting ipv6 connect"); 1716 cFYI(1, "attempting ipv6 connect");
1682 /* BB should we allow ipv6 on port 139? */ 1717 /* BB should we allow ipv6 on port 139? */
1683 /* other OS never observed in Wild doing 139 with v6 */ 1718 /* other OS never observed in Wild doing 139 with v6 */
1684 memcpy(&tcp_ses->addr.sockAddr6, sin_server6, 1719 memcpy(&tcp_ses->dstaddr, sin_server6,
1685 sizeof(struct sockaddr_in6)); 1720 sizeof(struct sockaddr_in6));
1686 rc = ipv6_connect(tcp_ses); 1721 } else
1687 } else { 1722 memcpy(&tcp_ses->dstaddr, sin_server,
1688 memcpy(&tcp_ses->addr.sockAddr, sin_server, 1723 sizeof(struct sockaddr_in));
1689 sizeof(struct sockaddr_in)); 1724
1690 rc = ipv4_connect(tcp_ses); 1725 rc = ip_connect(tcp_ses);
1691 }
1692 if (rc < 0) { 1726 if (rc < 0) {
1693 cERROR(1, "Error connecting to socket. Aborting operation"); 1727 cERROR(1, "Error connecting to socket. Aborting operation");
1694 goto out_err_crypto_release; 1728 goto out_err_crypto_release;
@@ -1793,6 +1827,8 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
1793{ 1827{
1794 int rc = -ENOMEM, xid; 1828 int rc = -ENOMEM, xid;
1795 struct cifsSesInfo *ses; 1829 struct cifsSesInfo *ses;
1830 struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
1831 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr;
1796 1832
1797 xid = GetXid(); 1833 xid = GetXid();
1798 1834
@@ -1836,12 +1872,10 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
1836 1872
1837 /* new SMB session uses our server ref */ 1873 /* new SMB session uses our server ref */
1838 ses->server = server; 1874 ses->server = server;
1839 if (server->addr.sockAddr6.sin6_family == AF_INET6) 1875 if (server->dstaddr.ss_family == AF_INET6)
1840 sprintf(ses->serverName, "%pI6", 1876 sprintf(ses->serverName, "%pI6", &addr6->sin6_addr);
1841 &server->addr.sockAddr6.sin6_addr);
1842 else 1877 else
1843 sprintf(ses->serverName, "%pI4", 1878 sprintf(ses->serverName, "%pI4", &addr->sin_addr);
1844 &server->addr.sockAddr.sin_addr.s_addr);
1845 1879
1846 if (volume_info->username) 1880 if (volume_info->username)
1847 strncpy(ses->userName, volume_info->username, 1881 strncpy(ses->userName, volume_info->username,
@@ -2136,19 +2170,106 @@ bind_socket(struct TCP_Server_Info *server)
2136} 2170}
2137 2171
2138static int 2172static int
2139ipv4_connect(struct TCP_Server_Info *server) 2173ip_rfc1001_connect(struct TCP_Server_Info *server)
2174{
2175 int rc = 0;
2176 /*
2177 * some servers require RFC1001 sessinit before sending
2178 * negprot - BB check reconnection in case where second
2179 * sessinit is sent but no second negprot
2180 */
2181 struct rfc1002_session_packet *ses_init_buf;
2182 struct smb_hdr *smb_buf;
2183 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
2184 GFP_KERNEL);
2185 if (ses_init_buf) {
2186 ses_init_buf->trailer.session_req.called_len = 32;
2187
2188 if (server->server_RFC1001_name &&
2189 server->server_RFC1001_name[0] != 0)
2190 rfc1002mangle(ses_init_buf->trailer.
2191 session_req.called_name,
2192 server->server_RFC1001_name,
2193 RFC1001_NAME_LEN_WITH_NULL);
2194 else
2195 rfc1002mangle(ses_init_buf->trailer.
2196 session_req.called_name,
2197 DEFAULT_CIFS_CALLED_NAME,
2198 RFC1001_NAME_LEN_WITH_NULL);
2199
2200 ses_init_buf->trailer.session_req.calling_len = 32;
2201
2202 /*
2203 * calling name ends in null (byte 16) from old smb
2204 * convention.
2205 */
2206 if (server->workstation_RFC1001_name &&
2207 server->workstation_RFC1001_name[0] != 0)
2208 rfc1002mangle(ses_init_buf->trailer.
2209 session_req.calling_name,
2210 server->workstation_RFC1001_name,
2211 RFC1001_NAME_LEN_WITH_NULL);
2212 else
2213 rfc1002mangle(ses_init_buf->trailer.
2214 session_req.calling_name,
2215 "LINUX_CIFS_CLNT",
2216 RFC1001_NAME_LEN_WITH_NULL);
2217
2218 ses_init_buf->trailer.session_req.scope1 = 0;
2219 ses_init_buf->trailer.session_req.scope2 = 0;
2220 smb_buf = (struct smb_hdr *)ses_init_buf;
2221
2222 /* sizeof RFC1002_SESSION_REQUEST with no scope */
2223 smb_buf->smb_buf_length = 0x81000044;
2224 rc = smb_send(server, smb_buf, 0x44);
2225 kfree(ses_init_buf);
2226 /*
2227 * RFC1001 layer in at least one server
2228 * requires very short break before negprot
2229 * presumably because not expecting negprot
2230 * to follow so fast. This is a simple
2231 * solution that works without
2232 * complicating the code and causes no
2233 * significant slowing down on mount
2234 * for everyone else
2235 */
2236 usleep_range(1000, 2000);
2237 }
2238 /*
2239 * else the negprot may still work without this
2240 * even though malloc failed
2241 */
2242
2243 return rc;
2244}
2245
2246static int
2247generic_ip_connect(struct TCP_Server_Info *server)
2140{ 2248{
2141 int rc = 0; 2249 int rc = 0;
2142 int val; 2250 unsigned short int sport;
2143 bool connected = false; 2251 int slen, sfamily;
2144 __be16 orig_port = 0;
2145 struct socket *socket = server->ssocket; 2252 struct socket *socket = server->ssocket;
2253 struct sockaddr *saddr;
2254
2255 saddr = (struct sockaddr *) &server->dstaddr;
2256
2257 if (server->dstaddr.ss_family == AF_INET6) {
2258 sport = ((struct sockaddr_in6 *) saddr)->sin6_port;
2259 slen = sizeof(struct sockaddr_in6);
2260 sfamily = AF_INET6;
2261 } else {
2262 sport = ((struct sockaddr_in *) saddr)->sin_port;
2263 slen = sizeof(struct sockaddr_in);
2264 sfamily = AF_INET;
2265 }
2146 2266
2147 if (socket == NULL) { 2267 if (socket == NULL) {
2148 rc = sock_create_kern(PF_INET, SOCK_STREAM, 2268 rc = sock_create_kern(sfamily, SOCK_STREAM,
2149 IPPROTO_TCP, &socket); 2269 IPPROTO_TCP, &socket);
2150 if (rc < 0) { 2270 if (rc < 0) {
2151 cERROR(1, "Error %d creating socket", rc); 2271 cERROR(1, "Error %d creating socket", rc);
2272 server->ssocket = NULL;
2152 return rc; 2273 return rc;
2153 } 2274 }
2154 2275
@@ -2156,63 +2277,28 @@ ipv4_connect(struct TCP_Server_Info *server)
2156 cFYI(1, "Socket created"); 2277 cFYI(1, "Socket created");
2157 server->ssocket = socket; 2278 server->ssocket = socket;
2158 socket->sk->sk_allocation = GFP_NOFS; 2279 socket->sk->sk_allocation = GFP_NOFS;
2159 cifs_reclassify_socket4(socket); 2280 if (sfamily == AF_INET6)
2281 cifs_reclassify_socket6(socket);
2282 else
2283 cifs_reclassify_socket4(socket);
2160 } 2284 }
2161 2285
2162 rc = bind_socket(server); 2286 rc = bind_socket(server);
2163 if (rc < 0) 2287 if (rc < 0)
2164 return rc; 2288 return rc;
2165 2289
2166 /* user overrode default port */ 2290 rc = socket->ops->connect(socket, saddr, slen, 0);
2167 if (server->addr.sockAddr.sin_port) { 2291 if (rc < 0) {
2168 rc = socket->ops->connect(socket, (struct sockaddr *) 2292 cFYI(1, "Error %d connecting to server", rc);
2169 &server->addr.sockAddr,
2170 sizeof(struct sockaddr_in), 0);
2171 if (rc >= 0)
2172 connected = true;
2173 }
2174
2175 if (!connected) {
2176 /* save original port so we can retry user specified port
2177 later if fall back ports fail this time */
2178 orig_port = server->addr.sockAddr.sin_port;
2179
2180 /* do not retry on the same port we just failed on */
2181 if (server->addr.sockAddr.sin_port != htons(CIFS_PORT)) {
2182 server->addr.sockAddr.sin_port = htons(CIFS_PORT);
2183 rc = socket->ops->connect(socket,
2184 (struct sockaddr *)
2185 &server->addr.sockAddr,
2186 sizeof(struct sockaddr_in), 0);
2187 if (rc >= 0)
2188 connected = true;
2189 }
2190 }
2191 if (!connected) {
2192 server->addr.sockAddr.sin_port = htons(RFC1001_PORT);
2193 rc = socket->ops->connect(socket, (struct sockaddr *)
2194 &server->addr.sockAddr,
2195 sizeof(struct sockaddr_in), 0);
2196 if (rc >= 0)
2197 connected = true;
2198 }
2199
2200 /* give up here - unless we want to retry on different
2201 protocol families some day */
2202 if (!connected) {
2203 if (orig_port)
2204 server->addr.sockAddr.sin_port = orig_port;
2205 cFYI(1, "Error %d connecting to server via ipv4", rc);
2206 sock_release(socket); 2293 sock_release(socket);
2207 server->ssocket = NULL; 2294 server->ssocket = NULL;
2208 return rc; 2295 return rc;
2209 } 2296 }
2210 2297
2211
2212 /* 2298 /*
2213 * Eventually check for other socket options to change from 2299 * Eventually check for other socket options to change from
2214 * the default. sock_setsockopt not used because it expects 2300 * the default. sock_setsockopt not used because it expects
2215 * user space buffer 2301 * user space buffer
2216 */ 2302 */
2217 socket->sk->sk_rcvtimeo = 7 * HZ; 2303 socket->sk->sk_rcvtimeo = 7 * HZ;
2218 socket->sk->sk_sndtimeo = 5 * HZ; 2304 socket->sk->sk_sndtimeo = 5 * HZ;
@@ -2226,7 +2312,7 @@ ipv4_connect(struct TCP_Server_Info *server)
2226 } 2312 }
2227 2313
2228 if (server->tcp_nodelay) { 2314 if (server->tcp_nodelay) {
2229 val = 1; 2315 int val = 1;
2230 rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY, 2316 rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
2231 (char *)&val, sizeof(val)); 2317 (char *)&val, sizeof(val));
2232 if (rc) 2318 if (rc)
@@ -2237,161 +2323,39 @@ ipv4_connect(struct TCP_Server_Info *server)
2237 socket->sk->sk_sndbuf, 2323 socket->sk->sk_sndbuf,
2238 socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo); 2324 socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo);
2239 2325
2240 /* send RFC1001 sessinit */ 2326 if (sport == htons(RFC1001_PORT))
2241 if (server->addr.sockAddr.sin_port == htons(RFC1001_PORT)) { 2327 rc = ip_rfc1001_connect(server);
2242 /* some servers require RFC1001 sessinit before sending
2243 negprot - BB check reconnection in case where second
2244 sessinit is sent but no second negprot */
2245 struct rfc1002_session_packet *ses_init_buf;
2246 struct smb_hdr *smb_buf;
2247 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
2248 GFP_KERNEL);
2249 if (ses_init_buf) {
2250 ses_init_buf->trailer.session_req.called_len = 32;
2251 if (server->server_RFC1001_name &&
2252 server->server_RFC1001_name[0] != 0)
2253 rfc1002mangle(ses_init_buf->trailer.
2254 session_req.called_name,
2255 server->server_RFC1001_name,
2256 RFC1001_NAME_LEN_WITH_NULL);
2257 else
2258 rfc1002mangle(ses_init_buf->trailer.
2259 session_req.called_name,
2260 DEFAULT_CIFS_CALLED_NAME,
2261 RFC1001_NAME_LEN_WITH_NULL);
2262
2263 ses_init_buf->trailer.session_req.calling_len = 32;
2264
2265 /* calling name ends in null (byte 16) from old smb
2266 convention. */
2267 if (server->workstation_RFC1001_name &&
2268 server->workstation_RFC1001_name[0] != 0)
2269 rfc1002mangle(ses_init_buf->trailer.
2270 session_req.calling_name,
2271 server->workstation_RFC1001_name,
2272 RFC1001_NAME_LEN_WITH_NULL);
2273 else
2274 rfc1002mangle(ses_init_buf->trailer.
2275 session_req.calling_name,
2276 "LINUX_CIFS_CLNT",
2277 RFC1001_NAME_LEN_WITH_NULL);
2278
2279 ses_init_buf->trailer.session_req.scope1 = 0;
2280 ses_init_buf->trailer.session_req.scope2 = 0;
2281 smb_buf = (struct smb_hdr *)ses_init_buf;
2282 /* sizeof RFC1002_SESSION_REQUEST with no scope */
2283 smb_buf->smb_buf_length = 0x81000044;
2284 rc = smb_send(server, smb_buf, 0x44);
2285 kfree(ses_init_buf);
2286 msleep(1); /* RFC1001 layer in at least one server
2287 requires very short break before negprot
2288 presumably because not expecting negprot
2289 to follow so fast. This is a simple
2290 solution that works without
2291 complicating the code and causes no
2292 significant slowing down on mount
2293 for everyone else */
2294 }
2295 /* else the negprot may still work without this
2296 even though malloc failed */
2297
2298 }
2299 2328
2300 return rc; 2329 return rc;
2301} 2330}
2302 2331
2303static int 2332static int
2304ipv6_connect(struct TCP_Server_Info *server) 2333ip_connect(struct TCP_Server_Info *server)
2305{ 2334{
2306 int rc = 0; 2335 unsigned short int *sport;
2307 int val; 2336 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr;
2308 bool connected = false; 2337 struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
2309 __be16 orig_port = 0;
2310 struct socket *socket = server->ssocket;
2311 2338
2312 if (socket == NULL) { 2339 if (server->dstaddr.ss_family == AF_INET6)
2313 rc = sock_create_kern(PF_INET6, SOCK_STREAM, 2340 sport = &addr6->sin6_port;
2314 IPPROTO_TCP, &socket); 2341 else
2315 if (rc < 0) { 2342 sport = &addr->sin_port;
2316 cERROR(1, "Error %d creating ipv6 socket", rc);
2317 socket = NULL;
2318 return rc;
2319 }
2320 2343
2321 /* BB other socket options to set KEEPALIVE, NODELAY? */ 2344 if (*sport == 0) {
2322 cFYI(1, "ipv6 Socket created"); 2345 int rc;
2323 server->ssocket = socket;
2324 socket->sk->sk_allocation = GFP_NOFS;
2325 cifs_reclassify_socket6(socket);
2326 }
2327 2346
2328 rc = bind_socket(server); 2347 /* try with 445 port at first */
2329 if (rc < 0) 2348 *sport = htons(CIFS_PORT);
2330 return rc;
2331 2349
2332 /* user overrode default port */ 2350 rc = generic_ip_connect(server);
2333 if (server->addr.sockAddr6.sin6_port) {
2334 rc = socket->ops->connect(socket,
2335 (struct sockaddr *) &server->addr.sockAddr6,
2336 sizeof(struct sockaddr_in6), 0);
2337 if (rc >= 0)
2338 connected = true;
2339 }
2340
2341 if (!connected) {
2342 /* save original port so we can retry user specified port
2343 later if fall back ports fail this time */
2344
2345 orig_port = server->addr.sockAddr6.sin6_port;
2346 /* do not retry on the same port we just failed on */
2347 if (server->addr.sockAddr6.sin6_port != htons(CIFS_PORT)) {
2348 server->addr.sockAddr6.sin6_port = htons(CIFS_PORT);
2349 rc = socket->ops->connect(socket, (struct sockaddr *)
2350 &server->addr.sockAddr6,
2351 sizeof(struct sockaddr_in6), 0);
2352 if (rc >= 0)
2353 connected = true;
2354 }
2355 }
2356 if (!connected) {
2357 server->addr.sockAddr6.sin6_port = htons(RFC1001_PORT);
2358 rc = socket->ops->connect(socket, (struct sockaddr *)
2359 &server->addr.sockAddr6,
2360 sizeof(struct sockaddr_in6), 0);
2361 if (rc >= 0) 2351 if (rc >= 0)
2362 connected = true; 2352 return rc;
2363 }
2364
2365 /* give up here - unless we want to retry on different
2366 protocol families some day */
2367 if (!connected) {
2368 if (orig_port)
2369 server->addr.sockAddr6.sin6_port = orig_port;
2370 cFYI(1, "Error %d connecting to server via ipv6", rc);
2371 sock_release(socket);
2372 server->ssocket = NULL;
2373 return rc;
2374 }
2375
2376 /*
2377 * Eventually check for other socket options to change from
2378 * the default. sock_setsockopt not used because it expects
2379 * user space buffer
2380 */
2381 socket->sk->sk_rcvtimeo = 7 * HZ;
2382 socket->sk->sk_sndtimeo = 5 * HZ;
2383 2353
2384 if (server->tcp_nodelay) { 2354 /* if it failed, try with 139 port */
2385 val = 1; 2355 *sport = htons(RFC1001_PORT);
2386 rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
2387 (char *)&val, sizeof(val));
2388 if (rc)
2389 cFYI(1, "set TCP_NODELAY socket option error %d", rc);
2390 } 2356 }
2391 2357
2392 server->ssocket = socket; 2358 return generic_ip_connect(server);
2393
2394 return rc;
2395} 2359}
2396 2360
2397void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, 2361void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 3840eddbfb7a..1e95dd635632 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -130,17 +130,6 @@ cifs_bp_rename_retry:
130 return full_path; 130 return full_path;
131} 131}
132 132
133static void setup_cifs_dentry(struct cifsTconInfo *tcon,
134 struct dentry *direntry,
135 struct inode *newinode)
136{
137 if (tcon->nocase)
138 direntry->d_op = &cifs_ci_dentry_ops;
139 else
140 direntry->d_op = &cifs_dentry_ops;
141 d_instantiate(direntry, newinode);
142}
143
144/* Inode operations in similar order to how they appear in Linux file fs.h */ 133/* Inode operations in similar order to how they appear in Linux file fs.h */
145 134
146int 135int
@@ -293,10 +282,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
293 args.uid = NO_CHANGE_64; 282 args.uid = NO_CHANGE_64;
294 args.gid = NO_CHANGE_64; 283 args.gid = NO_CHANGE_64;
295 } 284 }
296 CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args, 285 CIFSSMBUnixSetFileInfo(xid, tcon, &args, fileHandle,
297 cifs_sb->local_nls, 286 current->tgid);
298 cifs_sb->mnt_cifs_flags &
299 CIFS_MOUNT_MAP_SPECIAL_CHR);
300 } else { 287 } else {
301 /* BB implement mode setting via Windows security 288 /* BB implement mode setting via Windows security
302 descriptors e.g. */ 289 descriptors e.g. */
@@ -329,7 +316,7 @@ cifs_create_get_file_info:
329 316
330cifs_create_set_dentry: 317cifs_create_set_dentry:
331 if (rc == 0) 318 if (rc == 0)
332 setup_cifs_dentry(tcon, direntry, newinode); 319 d_instantiate(direntry, newinode);
333 else 320 else
334 cFYI(1, "Create worked, get_inode_info failed rc = %d", rc); 321 cFYI(1, "Create worked, get_inode_info failed rc = %d", rc);
335 322
@@ -420,10 +407,6 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
420 407
421 rc = cifs_get_inode_info_unix(&newinode, full_path, 408 rc = cifs_get_inode_info_unix(&newinode, full_path,
422 inode->i_sb, xid); 409 inode->i_sb, xid);
423 if (pTcon->nocase)
424 direntry->d_op = &cifs_ci_dentry_ops;
425 else
426 direntry->d_op = &cifs_dentry_ops;
427 410
428 if (rc == 0) 411 if (rc == 0)
429 d_instantiate(direntry, newinode); 412 d_instantiate(direntry, newinode);
@@ -603,10 +586,6 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
603 parent_dir_inode->i_sb, xid, NULL); 586 parent_dir_inode->i_sb, xid, NULL);
604 587
605 if ((rc == 0) && (newInode != NULL)) { 588 if ((rc == 0) && (newInode != NULL)) {
606 if (pTcon->nocase)
607 direntry->d_op = &cifs_ci_dentry_ops;
608 else
609 direntry->d_op = &cifs_dentry_ops;
610 d_add(direntry, newInode); 589 d_add(direntry, newInode);
611 if (posix_open) { 590 if (posix_open) {
612 filp = lookup_instantiate_filp(nd, direntry, 591 filp = lookup_instantiate_filp(nd, direntry,
@@ -633,10 +612,6 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
633 } else if (rc == -ENOENT) { 612 } else if (rc == -ENOENT) {
634 rc = 0; 613 rc = 0;
635 direntry->d_time = jiffies; 614 direntry->d_time = jiffies;
636 if (pTcon->nocase)
637 direntry->d_op = &cifs_ci_dentry_ops;
638 else
639 direntry->d_op = &cifs_dentry_ops;
640 d_add(direntry, NULL); 615 d_add(direntry, NULL);
641 /* if it was once a directory (but how can we tell?) we could do 616 /* if it was once a directory (but how can we tell?) we could do
642 shrink_dcache_parent(direntry); */ 617 shrink_dcache_parent(direntry); */
@@ -656,22 +631,37 @@ lookup_out:
656static int 631static int
657cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd) 632cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
658{ 633{
659 int isValid = 1; 634 if (nd->flags & LOOKUP_RCU)
635 return -ECHILD;
660 636
661 if (direntry->d_inode) { 637 if (direntry->d_inode) {
662 if (cifs_revalidate_dentry(direntry)) 638 if (cifs_revalidate_dentry(direntry))
663 return 0; 639 return 0;
664 } else { 640 else
665 cFYI(1, "neg dentry 0x%p name = %s", 641 return 1;
666 direntry, direntry->d_name.name);
667 if (time_after(jiffies, direntry->d_time + HZ) ||
668 !lookupCacheEnabled) {
669 d_drop(direntry);
670 isValid = 0;
671 }
672 } 642 }
673 643
674 return isValid; 644 /*
645 * This may be nfsd (or something), anyway, we can't see the
646 * intent of this. So, since this can be for creation, drop it.
647 */
648 if (!nd)
649 return 0;
650
651 /*
652 * Drop the negative dentry, in order to make sure to use the
653 * case sensitive name which is specified by user if this is
654 * for creation.
655 */
656 if (!(nd->flags & (LOOKUP_CONTINUE | LOOKUP_PARENT))) {
657 if (nd->flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET))
658 return 0;
659 }
660
661 if (time_after(jiffies, direntry->d_time + HZ) || !lookupCacheEnabled)
662 return 0;
663
664 return 1;
675} 665}
676 666
677/* static int cifs_d_delete(struct dentry *direntry) 667/* static int cifs_d_delete(struct dentry *direntry)
@@ -688,9 +678,10 @@ const struct dentry_operations cifs_dentry_ops = {
688/* d_delete: cifs_d_delete, */ /* not needed except for debugging */ 678/* d_delete: cifs_d_delete, */ /* not needed except for debugging */
689}; 679};
690 680
691static int cifs_ci_hash(struct dentry *dentry, struct qstr *q) 681static int cifs_ci_hash(const struct dentry *dentry, const struct inode *inode,
682 struct qstr *q)
692{ 683{
693 struct nls_table *codepage = CIFS_SB(dentry->d_inode->i_sb)->local_nls; 684 struct nls_table *codepage = CIFS_SB(dentry->d_sb)->local_nls;
694 unsigned long hash; 685 unsigned long hash;
695 int i; 686 int i;
696 687
@@ -703,21 +694,16 @@ static int cifs_ci_hash(struct dentry *dentry, struct qstr *q)
703 return 0; 694 return 0;
704} 695}
705 696
706static int cifs_ci_compare(struct dentry *dentry, struct qstr *a, 697static int cifs_ci_compare(const struct dentry *parent,
707 struct qstr *b) 698 const struct inode *pinode,
699 const struct dentry *dentry, const struct inode *inode,
700 unsigned int len, const char *str, const struct qstr *name)
708{ 701{
709 struct nls_table *codepage = CIFS_SB(dentry->d_inode->i_sb)->local_nls; 702 struct nls_table *codepage = CIFS_SB(pinode->i_sb)->local_nls;
710 703
711 if ((a->len == b->len) && 704 if ((name->len == len) &&
712 (nls_strnicmp(codepage, a->name, b->name, a->len) == 0)) { 705 (nls_strnicmp(codepage, name->name, str, len) == 0))
713 /*
714 * To preserve case, don't let an existing negative dentry's
715 * case take precedence. If a is not a negative dentry, this
716 * should have no side effects
717 */
718 memcpy((void *)a->name, b->name, a->len);
719 return 0; 706 return 0;
720 }
721 return 1; 707 return 1;
722} 708}
723 709
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 5a28660ca2b5..d843631c028d 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -104,53 +104,6 @@ static inline int cifs_get_disposition(unsigned int flags)
104 return FILE_OPEN; 104 return FILE_OPEN;
105} 105}
106 106
107static inline int cifs_open_inode_helper(struct inode *inode,
108 struct cifsTconInfo *pTcon, __u32 oplock, FILE_ALL_INFO *buf,
109 char *full_path, int xid)
110{
111 struct cifsInodeInfo *pCifsInode = CIFS_I(inode);
112 struct timespec temp;
113 int rc;
114
115 if (pCifsInode->clientCanCacheRead) {
116 /* we have the inode open somewhere else
117 no need to discard cache data */
118 goto client_can_cache;
119 }
120
121 /* BB need same check in cifs_create too? */
122 /* if not oplocked, invalidate inode pages if mtime or file
123 size changed */
124 temp = cifs_NTtimeToUnix(buf->LastWriteTime);
125 if (timespec_equal(&inode->i_mtime, &temp) &&
126 (inode->i_size ==
127 (loff_t)le64_to_cpu(buf->EndOfFile))) {
128 cFYI(1, "inode unchanged on server");
129 } else {
130 if (inode->i_mapping) {
131 /* BB no need to lock inode until after invalidate
132 since namei code should already have it locked? */
133 rc = filemap_write_and_wait(inode->i_mapping);
134 mapping_set_error(inode->i_mapping, rc);
135 }
136 cFYI(1, "invalidating remote inode since open detected it "
137 "changed");
138 invalidate_remote_inode(inode);
139 }
140
141client_can_cache:
142 if (pTcon->unix_ext)
143 rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb,
144 xid);
145 else
146 rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb,
147 xid, NULL);
148
149 cifs_set_oplock_level(pCifsInode, oplock);
150
151 return rc;
152}
153
154int cifs_posix_open(char *full_path, struct inode **pinode, 107int cifs_posix_open(char *full_path, struct inode **pinode,
155 struct super_block *sb, int mode, unsigned int f_flags, 108 struct super_block *sb, int mode, unsigned int f_flags,
156 __u32 *poplock, __u16 *pnetfid, int xid) 109 __u32 *poplock, __u16 *pnetfid, int xid)
@@ -213,6 +166,76 @@ posix_open_ret:
213 return rc; 166 return rc;
214} 167}
215 168
169static int
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,
172 __u16 *pnetfid, int xid)
173{
174 int rc;
175 int desiredAccess;
176 int disposition;
177 FILE_ALL_INFO *buf;
178
179 desiredAccess = cifs_convert_flags(f_flags);
180
181/*********************************************************************
182 * open flag mapping table:
183 *
184 * POSIX Flag CIFS Disposition
185 * ---------- ----------------
186 * O_CREAT FILE_OPEN_IF
187 * O_CREAT | O_EXCL FILE_CREATE
188 * O_CREAT | O_TRUNC FILE_OVERWRITE_IF
189 * O_TRUNC FILE_OVERWRITE
190 * none of the above FILE_OPEN
191 *
192 * Note that there is not a direct match between disposition
193 * FILE_SUPERSEDE (ie create whether or not file exists although
194 * O_CREAT | O_TRUNC is similar but truncates the existing
195 * file rather than creating a new file as FILE_SUPERSEDE does
196 * (which uses the attributes / metadata passed in on open call)
197 *?
198 *? O_SYNC is a reasonable match to CIFS writethrough flag
199 *? and the read write flags match reasonably. O_LARGEFILE
200 *? is irrelevant because largefile support is always used
201 *? by this client. Flags O_APPEND, O_DIRECT, O_DIRECTORY,
202 * O_FASYNC, O_NOFOLLOW, O_NONBLOCK need further investigation
203 *********************************************************************/
204
205 disposition = cifs_get_disposition(f_flags);
206
207 /* BB pass O_SYNC flag through on file attributes .. BB */
208
209 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
210 if (!buf)
211 return -ENOMEM;
212
213 if (tcon->ses->capabilities & CAP_NT_SMBS)
214 rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
215 desiredAccess, CREATE_NOT_DIR, pnetfid, poplock, buf,
216 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
217 & CIFS_MOUNT_MAP_SPECIAL_CHR);
218 else
219 rc = SMBLegacyOpen(xid, tcon, full_path, disposition,
220 desiredAccess, CREATE_NOT_DIR, pnetfid, poplock, buf,
221 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
222 & CIFS_MOUNT_MAP_SPECIAL_CHR);
223
224 if (rc)
225 goto out;
226
227 if (tcon->unix_ext)
228 rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb,
229 xid);
230 else
231 rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb,
232 xid, pnetfid);
233
234out:
235 kfree(buf);
236 return rc;
237}
238
216struct cifsFileInfo * 239struct cifsFileInfo *
217cifs_new_fileinfo(__u16 fileHandle, struct file *file, 240cifs_new_fileinfo(__u16 fileHandle, struct file *file,
218 struct tcon_link *tlink, __u32 oplock) 241 struct tcon_link *tlink, __u32 oplock)
@@ -317,10 +340,8 @@ int cifs_open(struct inode *inode, struct file *file)
317 struct cifsFileInfo *pCifsFile = NULL; 340 struct cifsFileInfo *pCifsFile = NULL;
318 struct cifsInodeInfo *pCifsInode; 341 struct cifsInodeInfo *pCifsInode;
319 char *full_path = NULL; 342 char *full_path = NULL;
320 int desiredAccess; 343 bool posix_open_ok = false;
321 int disposition;
322 __u16 netfid; 344 __u16 netfid;
323 FILE_ALL_INFO *buf = NULL;
324 345
325 xid = GetXid(); 346 xid = GetXid();
326 347
@@ -358,17 +379,7 @@ int cifs_open(struct inode *inode, struct file *file)
358 file->f_flags, &oplock, &netfid, xid); 379 file->f_flags, &oplock, &netfid, xid);
359 if (rc == 0) { 380 if (rc == 0) {
360 cFYI(1, "posix open succeeded"); 381 cFYI(1, "posix open succeeded");
361 382 posix_open_ok = true;
362 pCifsFile = cifs_new_fileinfo(netfid, file, tlink,
363 oplock);
364 if (pCifsFile == NULL) {
365 CIFSSMBClose(xid, tcon, netfid);
366 rc = -ENOMEM;
367 }
368
369 cifs_fscache_set_inode_cookie(inode, file);
370
371 goto out;
372 } else if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { 383 } else if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
373 if (tcon->ses->serverNOS) 384 if (tcon->ses->serverNOS)
374 cERROR(1, "server %s of type %s returned" 385 cERROR(1, "server %s of type %s returned"
@@ -385,103 +396,39 @@ int cifs_open(struct inode *inode, struct file *file)
385 or DFS errors */ 396 or DFS errors */
386 } 397 }
387 398
388 desiredAccess = cifs_convert_flags(file->f_flags); 399 if (!posix_open_ok) {
389 400 rc = cifs_nt_open(full_path, inode, cifs_sb, tcon,
390/********************************************************************* 401 file->f_flags, &oplock, &netfid, xid);
391 * open flag mapping table: 402 if (rc)
392 * 403 goto out;
393 * POSIX Flag CIFS Disposition
394 * ---------- ----------------
395 * O_CREAT FILE_OPEN_IF
396 * O_CREAT | O_EXCL FILE_CREATE
397 * O_CREAT | O_TRUNC FILE_OVERWRITE_IF
398 * O_TRUNC FILE_OVERWRITE
399 * none of the above FILE_OPEN
400 *
401 * Note that there is not a direct match between disposition
402 * FILE_SUPERSEDE (ie create whether or not file exists although
403 * O_CREAT | O_TRUNC is similar but truncates the existing
404 * file rather than creating a new file as FILE_SUPERSEDE does
405 * (which uses the attributes / metadata passed in on open call)
406 *?
407 *? O_SYNC is a reasonable match to CIFS writethrough flag
408 *? and the read write flags match reasonably. O_LARGEFILE
409 *? is irrelevant because largefile support is always used
410 *? by this client. Flags O_APPEND, O_DIRECT, O_DIRECTORY,
411 * O_FASYNC, O_NOFOLLOW, O_NONBLOCK need further investigation
412 *********************************************************************/
413
414 disposition = cifs_get_disposition(file->f_flags);
415
416 /* BB pass O_SYNC flag through on file attributes .. BB */
417
418 /* Also refresh inode by passing in file_info buf returned by SMBOpen
419 and calling get_inode_info with returned buf (at least helps
420 non-Unix server case) */
421
422 /* BB we can not do this if this is the second open of a file
423 and the first handle has writebehind data, we might be
424 able to simply do a filemap_fdatawrite/filemap_fdatawait first */
425 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
426 if (!buf) {
427 rc = -ENOMEM;
428 goto out;
429 }
430
431 if (tcon->ses->capabilities & CAP_NT_SMBS)
432 rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
433 desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf,
434 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
435 & CIFS_MOUNT_MAP_SPECIAL_CHR);
436 else
437 rc = -EIO; /* no NT SMB support fall into legacy open below */
438
439 if (rc == -EIO) {
440 /* Old server, try legacy style OpenX */
441 rc = SMBLegacyOpen(xid, tcon, full_path, disposition,
442 desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf,
443 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
444 & CIFS_MOUNT_MAP_SPECIAL_CHR);
445 }
446 if (rc) {
447 cFYI(1, "cifs_open returned 0x%x", rc);
448 goto out;
449 } 404 }
450 405
451 rc = cifs_open_inode_helper(inode, tcon, oplock, buf, full_path, xid);
452 if (rc != 0)
453 goto out;
454
455 pCifsFile = cifs_new_fileinfo(netfid, file, tlink, oplock); 406 pCifsFile = cifs_new_fileinfo(netfid, file, tlink, oplock);
456 if (pCifsFile == NULL) { 407 if (pCifsFile == NULL) {
408 CIFSSMBClose(xid, tcon, netfid);
457 rc = -ENOMEM; 409 rc = -ENOMEM;
458 goto out; 410 goto out;
459 } 411 }
460 412
461 cifs_fscache_set_inode_cookie(inode, file); 413 cifs_fscache_set_inode_cookie(inode, file);
462 414
463 if (oplock & CIFS_CREATE_ACTION) { 415 if ((oplock & CIFS_CREATE_ACTION) && !posix_open_ok && tcon->unix_ext) {
464 /* time to set mode which we can not set earlier due to 416 /* time to set mode which we can not set earlier due to
465 problems creating new read-only files */ 417 problems creating new read-only files */
466 if (tcon->unix_ext) { 418 struct cifs_unix_set_info_args args = {
467 struct cifs_unix_set_info_args args = { 419 .mode = inode->i_mode,
468 .mode = inode->i_mode, 420 .uid = NO_CHANGE_64,
469 .uid = NO_CHANGE_64, 421 .gid = NO_CHANGE_64,
470 .gid = NO_CHANGE_64, 422 .ctime = NO_CHANGE_64,
471 .ctime = NO_CHANGE_64, 423 .atime = NO_CHANGE_64,
472 .atime = NO_CHANGE_64, 424 .mtime = NO_CHANGE_64,
473 .mtime = NO_CHANGE_64, 425 .device = 0,
474 .device = 0, 426 };
475 }; 427 CIFSSMBUnixSetFileInfo(xid, tcon, &args, netfid,
476 CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args, 428 pCifsFile->pid);
477 cifs_sb->local_nls,
478 cifs_sb->mnt_cifs_flags &
479 CIFS_MOUNT_MAP_SPECIAL_CHR);
480 }
481 } 429 }
482 430
483out: 431out:
484 kfree(buf);
485 kfree(full_path); 432 kfree(full_path);
486 FreeXid(xid); 433 FreeXid(xid);
487 cifs_put_tlink(tlink); 434 cifs_put_tlink(tlink);
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 589f3e3f6e00..b06b60620240 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -518,6 +518,7 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
518 518
519 fattr->cf_eof = le64_to_cpu(info->EndOfFile); 519 fattr->cf_eof = le64_to_cpu(info->EndOfFile);
520 fattr->cf_bytes = le64_to_cpu(info->AllocationSize); 520 fattr->cf_bytes = le64_to_cpu(info->AllocationSize);
521 fattr->cf_createtime = le64_to_cpu(info->CreationTime);
521 522
522 if (fattr->cf_cifsattrs & ATTR_DIRECTORY) { 523 if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
523 fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode; 524 fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode;
@@ -779,6 +780,10 @@ cifs_find_inode(struct inode *inode, void *opaque)
779 if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid) 780 if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid)
780 return 0; 781 return 0;
781 782
783 /* use createtime like an i_generation field */
784 if (CIFS_I(inode)->createtime != fattr->cf_createtime)
785 return 0;
786
782 /* don't match inode of different type */ 787 /* don't match inode of different type */
783 if ((inode->i_mode & S_IFMT) != (fattr->cf_mode & S_IFMT)) 788 if ((inode->i_mode & S_IFMT) != (fattr->cf_mode & S_IFMT))
784 return 0; 789 return 0;
@@ -796,6 +801,7 @@ cifs_init_inode(struct inode *inode, void *opaque)
796 struct cifs_fattr *fattr = (struct cifs_fattr *) opaque; 801 struct cifs_fattr *fattr = (struct cifs_fattr *) opaque;
797 802
798 CIFS_I(inode)->uniqueid = fattr->cf_uniqueid; 803 CIFS_I(inode)->uniqueid = fattr->cf_uniqueid;
804 CIFS_I(inode)->createtime = fattr->cf_createtime;
799 return 0; 805 return 0;
800} 806}
801 807
@@ -809,14 +815,14 @@ inode_has_hashed_dentries(struct inode *inode)
809{ 815{
810 struct dentry *dentry; 816 struct dentry *dentry;
811 817
812 spin_lock(&dcache_lock); 818 spin_lock(&inode->i_lock);
813 list_for_each_entry(dentry, &inode->i_dentry, d_alias) { 819 list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
814 if (!d_unhashed(dentry) || IS_ROOT(dentry)) { 820 if (!d_unhashed(dentry) || IS_ROOT(dentry)) {
815 spin_unlock(&dcache_lock); 821 spin_unlock(&inode->i_lock);
816 return true; 822 return true;
817 } 823 }
818 } 824 }
819 spin_unlock(&dcache_lock); 825 spin_unlock(&inode->i_lock);
820 return false; 826 return false;
821} 827}
822 828
@@ -1318,10 +1324,6 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
1318/*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need 1324/*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need
1319 to set uid/gid */ 1325 to set uid/gid */
1320 inc_nlink(inode); 1326 inc_nlink(inode);
1321 if (pTcon->nocase)
1322 direntry->d_op = &cifs_ci_dentry_ops;
1323 else
1324 direntry->d_op = &cifs_dentry_ops;
1325 1327
1326 cifs_unix_basic_to_fattr(&fattr, pInfo, cifs_sb); 1328 cifs_unix_basic_to_fattr(&fattr, pInfo, cifs_sb);
1327 cifs_fill_uniqueid(inode->i_sb, &fattr); 1329 cifs_fill_uniqueid(inode->i_sb, &fattr);
@@ -1362,10 +1364,6 @@ mkdir_get_info:
1362 rc = cifs_get_inode_info(&newinode, full_path, NULL, 1364 rc = cifs_get_inode_info(&newinode, full_path, NULL,
1363 inode->i_sb, xid, NULL); 1365 inode->i_sb, xid, NULL);
1364 1366
1365 if (pTcon->nocase)
1366 direntry->d_op = &cifs_ci_dentry_ops;
1367 else
1368 direntry->d_op = &cifs_dentry_ops;
1369 d_instantiate(direntry, newinode); 1367 d_instantiate(direntry, newinode);
1370 /* setting nlink not necessary except in cases where we 1368 /* setting nlink not necessary except in cases where we
1371 * failed to get it from the server or was set bogus */ 1369 * failed to get it from the server or was set bogus */
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 85cdbf831e7b..306769de2fb5 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -524,10 +524,6 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
524 cFYI(1, "Create symlink ok, getinodeinfo fail rc = %d", 524 cFYI(1, "Create symlink ok, getinodeinfo fail rc = %d",
525 rc); 525 rc);
526 } else { 526 } else {
527 if (pTcon->nocase)
528 direntry->d_op = &cifs_ci_dentry_ops;
529 else
530 direntry->d_op = &cifs_dentry_ops;
531 d_instantiate(direntry, newinode); 527 d_instantiate(direntry, newinode);
532 } 528 }
533 } 529 }
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index a73eb9f4bdaf..7f25cc3d2256 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -79,7 +79,7 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
79 cFYI(1, "For %s", name->name); 79 cFYI(1, "For %s", name->name);
80 80
81 if (parent->d_op && parent->d_op->d_hash) 81 if (parent->d_op && parent->d_op->d_hash)
82 parent->d_op->d_hash(parent, name); 82 parent->d_op->d_hash(parent, parent->d_inode, name);
83 else 83 else
84 name->hash = full_name_hash(name->name, name->len); 84 name->hash = full_name_hash(name->name, name->len);
85 85
@@ -102,11 +102,6 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
102 return NULL; 102 return NULL;
103 } 103 }
104 104
105 if (cifs_sb_master_tcon(CIFS_SB(sb))->nocase)
106 dentry->d_op = &cifs_ci_dentry_ops;
107 else
108 dentry->d_op = &cifs_dentry_ops;
109
110 alias = d_materialise_unique(dentry, inode); 105 alias = d_materialise_unique(dentry, inode);
111 if (alias != NULL) { 106 if (alias != NULL) {
112 dput(dentry); 107 dput(dentry);
@@ -160,6 +155,7 @@ cifs_dir_info_to_fattr(struct cifs_fattr *fattr, FILE_DIRECTORY_INFO *info,
160 fattr->cf_cifsattrs = le32_to_cpu(info->ExtFileAttributes); 155 fattr->cf_cifsattrs = le32_to_cpu(info->ExtFileAttributes);
161 fattr->cf_eof = le64_to_cpu(info->EndOfFile); 156 fattr->cf_eof = le64_to_cpu(info->EndOfFile);
162 fattr->cf_bytes = le64_to_cpu(info->AllocationSize); 157 fattr->cf_bytes = le64_to_cpu(info->AllocationSize);
158 fattr->cf_createtime = le64_to_cpu(info->CreationTime);
163 fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime); 159 fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);
164 fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime); 160 fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime);
165 fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime); 161 fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime);
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index 7b01d3f6eed6..eb746486e49e 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -420,7 +420,6 @@ static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
420 return 0; 420 return 0;
421} 421}
422 422
423#ifdef CONFIG_CIFS_EXPERIMENTAL
424/* BB Move to ntlmssp.c eventually */ 423/* BB Move to ntlmssp.c eventually */
425 424
426/* We do not malloc the blob, it is passed in pbuffer, because 425/* We do not malloc the blob, it is passed in pbuffer, because
@@ -431,13 +430,14 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
431 NEGOTIATE_MESSAGE *sec_blob = (NEGOTIATE_MESSAGE *)pbuffer; 430 NEGOTIATE_MESSAGE *sec_blob = (NEGOTIATE_MESSAGE *)pbuffer;
432 __u32 flags; 431 __u32 flags;
433 432
433 memset(pbuffer, 0, sizeof(NEGOTIATE_MESSAGE));
434 memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8); 434 memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
435 sec_blob->MessageType = NtLmNegotiate; 435 sec_blob->MessageType = NtLmNegotiate;
436 436
437 /* BB is NTLMV2 session security format easier to use here? */ 437 /* BB is NTLMV2 session security format easier to use here? */
438 flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET | 438 flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET |
439 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | 439 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
440 NTLMSSP_NEGOTIATE_NTLM; 440 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
441 if (ses->server->secMode & 441 if (ses->server->secMode &
442 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { 442 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
443 flags |= NTLMSSP_NEGOTIATE_SIGN; 443 flags |= NTLMSSP_NEGOTIATE_SIGN;
@@ -446,7 +446,7 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
446 NTLMSSP_NEGOTIATE_EXTENDED_SEC; 446 NTLMSSP_NEGOTIATE_EXTENDED_SEC;
447 } 447 }
448 448
449 sec_blob->NegotiateFlags |= cpu_to_le32(flags); 449 sec_blob->NegotiateFlags = cpu_to_le32(flags);
450 450
451 sec_blob->WorkstationName.BufferOffset = 0; 451 sec_blob->WorkstationName.BufferOffset = 0;
452 sec_blob->WorkstationName.Length = 0; 452 sec_blob->WorkstationName.Length = 0;
@@ -477,7 +477,7 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
477 flags = NTLMSSP_NEGOTIATE_56 | 477 flags = NTLMSSP_NEGOTIATE_56 |
478 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO | 478 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO |
479 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | 479 NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
480 NTLMSSP_NEGOTIATE_NTLM; 480 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
481 if (ses->server->secMode & 481 if (ses->server->secMode &
482 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) 482 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
483 flags |= NTLMSSP_NEGOTIATE_SIGN; 483 flags |= NTLMSSP_NEGOTIATE_SIGN;
@@ -485,7 +485,7 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
485 flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; 485 flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
486 486
487 tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE); 487 tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE);
488 sec_blob->NegotiateFlags |= cpu_to_le32(flags); 488 sec_blob->NegotiateFlags = cpu_to_le32(flags);
489 489
490 sec_blob->LmChallengeResponse.BufferOffset = 490 sec_blob->LmChallengeResponse.BufferOffset =
491 cpu_to_le32(sizeof(AUTHENTICATE_MESSAGE)); 491 cpu_to_le32(sizeof(AUTHENTICATE_MESSAGE));
@@ -544,8 +544,9 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
544 sec_blob->WorkstationName.MaximumLength = 0; 544 sec_blob->WorkstationName.MaximumLength = 0;
545 tmp += 2; 545 tmp += 2;
546 546
547 if ((ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) && 547 if (((ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) ||
548 !calc_seckey(ses)) { 548 (ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
549 && !calc_seckey(ses)) {
549 memcpy(tmp, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE); 550 memcpy(tmp, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
550 sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer); 551 sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
551 sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE); 552 sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE);
@@ -563,17 +564,6 @@ setup_ntlmv2_ret:
563 return rc; 564 return rc;
564} 565}
565 566
566
567static void setup_ntlmssp_neg_req(SESSION_SETUP_ANDX *pSMB,
568 struct cifsSesInfo *ses)
569{
570 build_ntlmssp_negotiate_blob(&pSMB->req.SecurityBlob[0], ses);
571 pSMB->req.SecurityBlobLength = cpu_to_le16(sizeof(NEGOTIATE_MESSAGE));
572
573 return;
574}
575#endif
576
577int 567int
578CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, 568CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
579 const struct nls_table *nls_cp) 569 const struct nls_table *nls_cp)
@@ -814,71 +804,70 @@ ssetup_ntlmssp_authenticate:
814 rc = -ENOSYS; 804 rc = -ENOSYS;
815 goto ssetup_exit; 805 goto ssetup_exit;
816#endif /* CONFIG_CIFS_UPCALL */ 806#endif /* CONFIG_CIFS_UPCALL */
817 } else { 807 } else if (type == RawNTLMSSP) {
818#ifdef CONFIG_CIFS_EXPERIMENTAL 808 if ((pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) == 0) {
819 if (type == RawNTLMSSP) { 809 cERROR(1, "NTLMSSP requires Unicode support");
820 if ((pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) == 0) { 810 rc = -ENOSYS;
821 cERROR(1, "NTLMSSP requires Unicode support"); 811 goto ssetup_exit;
822 rc = -ENOSYS; 812 }
813
814 cFYI(1, "ntlmssp session setup phase %d", phase);
815 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
816 capabilities |= CAP_EXTENDED_SECURITY;
817 pSMB->req.Capabilities |= cpu_to_le32(capabilities);
818 switch(phase) {
819 case NtLmNegotiate:
820 build_ntlmssp_negotiate_blob(
821 pSMB->req.SecurityBlob, ses);
822 iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE);
823 iov[1].iov_base = pSMB->req.SecurityBlob;
824 pSMB->req.SecurityBlobLength =
825 cpu_to_le16(sizeof(NEGOTIATE_MESSAGE));
826 break;
827 case NtLmAuthenticate:
828 /*
829 * 5 is an empirical value, large enough to hold
830 * authenticate message plus max 10 of av paris,
831 * domain, user, workstation names, flags, etc.
832 */
833 ntlmsspblob = kzalloc(
834 5*sizeof(struct _AUTHENTICATE_MESSAGE),
835 GFP_KERNEL);
836 if (!ntlmsspblob) {
837 cERROR(1, "Can't allocate NTLMSSP blob");
838 rc = -ENOMEM;
823 goto ssetup_exit; 839 goto ssetup_exit;
824 } 840 }
825 841
826 cFYI(1, "ntlmssp session setup phase %d", phase); 842 rc = build_ntlmssp_auth_blob(ntlmsspblob,
827 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; 843 &blob_len, ses, nls_cp);
828 capabilities |= CAP_EXTENDED_SECURITY; 844 if (rc)
829 pSMB->req.Capabilities |= cpu_to_le32(capabilities);
830 if (phase == NtLmNegotiate) {
831 setup_ntlmssp_neg_req(pSMB, ses);
832 iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE);
833 iov[1].iov_base = &pSMB->req.SecurityBlob[0];
834 } else if (phase == NtLmAuthenticate) {
835 /* 5 is an empirical value, large enought to
836 * hold authenticate message, max 10 of
837 * av paris, doamin,user,workstation mames,
838 * flags etc..
839 */
840 ntlmsspblob = kmalloc(
841 5*sizeof(struct _AUTHENTICATE_MESSAGE),
842 GFP_KERNEL);
843 if (!ntlmsspblob) {
844 cERROR(1, "Can't allocate NTLMSSP");
845 rc = -ENOMEM;
846 goto ssetup_exit;
847 }
848
849 rc = build_ntlmssp_auth_blob(ntlmsspblob,
850 &blob_len, ses, nls_cp);
851 if (rc)
852 goto ssetup_exit;
853 iov[1].iov_len = blob_len;
854 iov[1].iov_base = ntlmsspblob;
855 pSMB->req.SecurityBlobLength =
856 cpu_to_le16(blob_len);
857 /* Make sure that we tell the server that we
858 are using the uid that it just gave us back
859 on the response (challenge) */
860 smb_buf->Uid = ses->Suid;
861 } else {
862 cERROR(1, "invalid phase %d", phase);
863 rc = -ENOSYS;
864 goto ssetup_exit; 845 goto ssetup_exit;
865 } 846 iov[1].iov_len = blob_len;
866 /* unicode strings must be word aligned */ 847 iov[1].iov_base = ntlmsspblob;
867 if ((iov[0].iov_len + iov[1].iov_len) % 2) { 848 pSMB->req.SecurityBlobLength = cpu_to_le16(blob_len);
868 *bcc_ptr = 0; 849 /*
869 bcc_ptr++; 850 * Make sure that we tell the server that we are using
870 } 851 * the uid that it just gave us back on the response
871 unicode_oslm_strings(&bcc_ptr, nls_cp); 852 * (challenge)
872 } else { 853 */
873 cERROR(1, "secType %d not supported!", type); 854 smb_buf->Uid = ses->Suid;
855 break;
856 default:
857 cERROR(1, "invalid phase %d", phase);
874 rc = -ENOSYS; 858 rc = -ENOSYS;
875 goto ssetup_exit; 859 goto ssetup_exit;
876 } 860 }
877#else 861 /* unicode strings must be word aligned */
862 if ((iov[0].iov_len + iov[1].iov_len) % 2) {
863 *bcc_ptr = 0;
864 bcc_ptr++;
865 }
866 unicode_oslm_strings(&bcc_ptr, nls_cp);
867 } else {
878 cERROR(1, "secType %d not supported!", type); 868 cERROR(1, "secType %d not supported!", type);
879 rc = -ENOSYS; 869 rc = -ENOSYS;
880 goto ssetup_exit; 870 goto ssetup_exit;
881#endif
882 } 871 }
883 872
884 iov[2].iov_base = str_area; 873 iov[2].iov_base = str_area;
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index e0588cdf4cc5..59ca81b16919 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -119,7 +119,7 @@ smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
119 if (ssocket == NULL) 119 if (ssocket == NULL)
120 return -ENOTSOCK; /* BB eventually add reconnect code here */ 120 return -ENOTSOCK; /* BB eventually add reconnect code here */
121 121
122 smb_msg.msg_name = (struct sockaddr *) &server->addr.sockAddr; 122 smb_msg.msg_name = (struct sockaddr *) &server->dstaddr;
123 smb_msg.msg_namelen = sizeof(struct sockaddr); 123 smb_msg.msg_namelen = sizeof(struct sockaddr);
124 smb_msg.msg_control = NULL; 124 smb_msg.msg_control = NULL;
125 smb_msg.msg_controllen = 0; 125 smb_msg.msg_controllen = 0;