aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/connect.c
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2005-10-21 11:39:12 -0400
committerSteve French <sfrench@us.ibm.com>2005-10-21 11:39:12 -0400
commitd6d3f5bc68be3c4ab84e6f1f9db92291da671504 (patch)
tree76946c62cc7d1a18203fba50ea87fd567387f637 /fs/cifs/connect.c
parentac9b9c667c2e1194e22ebe0a441ae1c37aaa9b90 (diff)
parent23e7dd7d95f6fdc167a6d6ddea79ced0af33bbff (diff)
Merge with /pub/scm/linux/kernel/git/sfrench/cifs-2.6.git/
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r--fs/cifs/connect.c219
1 files changed, 182 insertions, 37 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 47360156cc54..d74367a08d51 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -29,6 +29,8 @@
29#include <linux/utsname.h> 29#include <linux/utsname.h>
30#include <linux/mempool.h> 30#include <linux/mempool.h>
31#include <linux/delay.h> 31#include <linux/delay.h>
32#include <linux/completion.h>
33#include <linux/pagevec.h>
32#include <asm/uaccess.h> 34#include <asm/uaccess.h>
33#include <asm/processor.h> 35#include <asm/processor.h>
34#include "cifspdu.h" 36#include "cifspdu.h"
@@ -44,6 +46,8 @@
44#define CIFS_PORT 445 46#define CIFS_PORT 445
45#define RFC1001_PORT 139 47#define RFC1001_PORT 139
46 48
49static DECLARE_COMPLETION(cifsd_complete);
50
47extern void SMBencrypt(unsigned char *passwd, unsigned char *c8, 51extern void SMBencrypt(unsigned char *passwd, unsigned char *c8,
48 unsigned char *p24); 52 unsigned char *p24);
49extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, 53extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
@@ -60,6 +64,7 @@ struct smb_vol {
60 char *in6_addr; /* ipv6 address as human readable form of in6_addr */ 64 char *in6_addr; /* ipv6 address as human readable form of in6_addr */
61 char *iocharset; /* local code page for mapping to and from Unicode */ 65 char *iocharset; /* local code page for mapping to and from Unicode */
62 char source_rfc1001_name[16]; /* netbios name of client */ 66 char source_rfc1001_name[16]; /* netbios name of client */
67 char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */
63 uid_t linux_uid; 68 uid_t linux_uid;
64 gid_t linux_gid; 69 gid_t linux_gid;
65 mode_t file_mode; 70 mode_t file_mode;
@@ -74,6 +79,10 @@ struct smb_vol {
74 unsigned server_ino:1; /* use inode numbers from server ie UniqueId */ 79 unsigned server_ino:1; /* use inode numbers from server ie UniqueId */
75 unsigned direct_io:1; 80 unsigned direct_io:1;
76 unsigned remap:1; /* set to remap seven reserved chars in filenames */ 81 unsigned remap:1; /* set to remap seven reserved chars in filenames */
82 unsigned posix_paths:1; /* unset to not ask for posix pathnames. */
83 unsigned sfu_emul:1;
84 unsigned nocase; /* request case insensitive filenames */
85 unsigned nobrl; /* disable sending byte range locks to srv */
77 unsigned int rsize; 86 unsigned int rsize;
78 unsigned int wsize; 87 unsigned int wsize;
79 unsigned int sockopt; 88 unsigned int sockopt;
@@ -82,7 +91,8 @@ struct smb_vol {
82 91
83static int ipv4_connect(struct sockaddr_in *psin_server, 92static int ipv4_connect(struct sockaddr_in *psin_server,
84 struct socket **csocket, 93 struct socket **csocket,
85 char * netb_name); 94 char * netb_name,
95 char * server_netb_name);
86static int ipv6_connect(struct sockaddr_in6 *psin_server, 96static int ipv6_connect(struct sockaddr_in6 *psin_server,
87 struct socket **csocket); 97 struct socket **csocket);
88 98
@@ -175,9 +185,11 @@ cifs_reconnect(struct TCP_Server_Info *server)
175 } else { 185 } else {
176 rc = ipv4_connect(&server->addr.sockAddr, 186 rc = ipv4_connect(&server->addr.sockAddr,
177 &server->ssocket, 187 &server->ssocket,
178 server->workstation_RFC1001_name); 188 server->workstation_RFC1001_name,
189 server->server_RFC1001_name);
179 } 190 }
180 if(rc) { 191 if(rc) {
192 cFYI(1,("reconnect error %d",rc));
181 msleep(3000); 193 msleep(3000);
182 } else { 194 } else {
183 atomic_inc(&tcpSesReconnectCount); 195 atomic_inc(&tcpSesReconnectCount);
@@ -293,12 +305,12 @@ static int coalesce_t2(struct smb_hdr * psecond, struct smb_hdr *pTargetSMB)
293 byte_count += total_in_buf2; 305 byte_count += total_in_buf2;
294 BCC_LE(pTargetSMB) = cpu_to_le16(byte_count); 306 BCC_LE(pTargetSMB) = cpu_to_le16(byte_count);
295 307
296 byte_count = be32_to_cpu(pTargetSMB->smb_buf_length); 308 byte_count = pTargetSMB->smb_buf_length;
297 byte_count += total_in_buf2; 309 byte_count += total_in_buf2;
298 310
299 /* BB also add check that we are not beyond maximum buffer size */ 311 /* BB also add check that we are not beyond maximum buffer size */
300 312
301 pTargetSMB->smb_buf_length = cpu_to_be32(byte_count); 313 pTargetSMB->smb_buf_length = byte_count;
302 314
303 if(remaining == total_in_buf2) { 315 if(remaining == total_in_buf2) {
304 cFYI(1,("found the last secondary response")); 316 cFYI(1,("found the last secondary response"));
@@ -323,7 +335,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
323 struct cifsSesInfo *ses; 335 struct cifsSesInfo *ses;
324 struct task_struct *task_to_wake = NULL; 336 struct task_struct *task_to_wake = NULL;
325 struct mid_q_entry *mid_entry; 337 struct mid_q_entry *mid_entry;
326 char *temp; 338 char temp;
327 int isLargeBuf = FALSE; 339 int isLargeBuf = FALSE;
328 int isMultiRsp; 340 int isMultiRsp;
329 int reconnect; 341 int reconnect;
@@ -337,6 +349,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
337 atomic_inc(&tcpSesAllocCount); 349 atomic_inc(&tcpSesAllocCount);
338 length = tcpSesAllocCount.counter; 350 length = tcpSesAllocCount.counter;
339 write_unlock(&GlobalSMBSeslock); 351 write_unlock(&GlobalSMBSeslock);
352 complete(&cifsd_complete);
340 if(length > 1) { 353 if(length > 1) {
341 mempool_resize(cifs_req_poolp, 354 mempool_resize(cifs_req_poolp,
342 length + cifs_min_rcv, 355 length + cifs_min_rcv,
@@ -424,22 +437,32 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
424 continue; 437 continue;
425 } 438 }
426 439
427 /* the right amount was read from socket - 4 bytes */ 440 /* The right amount was read from socket - 4 bytes */
441 /* so we can now interpret the length field */
442
443 /* the first byte big endian of the length field,
444 is actually not part of the length but the type
445 with the most common, zero, as regular data */
446 temp = *((char *) smb_buffer);
428 447
448 /* Note that FC 1001 length is big endian on the wire,
449 but we convert it here so it is always manipulated
450 as host byte order */
429 pdu_length = ntohl(smb_buffer->smb_buf_length); 451 pdu_length = ntohl(smb_buffer->smb_buf_length);
430 cFYI(1,("rfc1002 length(big endian)0x%x)", pdu_length+4)); 452 smb_buffer->smb_buf_length = pdu_length;
453
454 cFYI(1,("rfc1002 length 0x%x)", pdu_length+4));
431 455
432 temp = (char *) smb_buffer; 456 if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
433 if (temp[0] == (char) RFC1002_SESSION_KEEP_ALIVE) {
434 continue; 457 continue;
435 } else if (temp[0] == (char)RFC1002_POSITIVE_SESSION_RESPONSE) { 458 } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
436 cFYI(1,("Good RFC 1002 session rsp")); 459 cFYI(1,("Good RFC 1002 session rsp"));
437 continue; 460 continue;
438 } else if (temp[0] == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) { 461 } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
439 /* we get this from Windows 98 instead of 462 /* we get this from Windows 98 instead of
440 an error on SMB negprot response */ 463 an error on SMB negprot response */
441 cFYI(1,("Negative RFC1002 Session Response Error 0x%x)", 464 cFYI(1,("Negative RFC1002 Session Response Error 0x%x)",
442 temp[4])); 465 pdu_length));
443 if(server->tcpStatus == CifsNew) { 466 if(server->tcpStatus == CifsNew) {
444 /* if nack on negprot (rather than 467 /* if nack on negprot (rather than
445 ret of smb negprot error) reconnecting 468 ret of smb negprot error) reconnecting
@@ -461,9 +484,10 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
461 wake_up(&server->response_q); 484 wake_up(&server->response_q);
462 continue; 485 continue;
463 } 486 }
464 } else if (temp[0] != (char) 0) { 487 } else if (temp != (char) 0) {
465 cERROR(1,("Unknown RFC 1002 frame")); 488 cERROR(1,("Unknown RFC 1002 frame"));
466 cifs_dump_mem(" Received Data: ", temp, length); 489 cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
490 length);
467 cifs_reconnect(server); 491 cifs_reconnect(server);
468 csocket = server->ssocket; 492 csocket = server->ssocket;
469 continue; 493 continue;
@@ -533,7 +557,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
533 557
534 dump_smb(smb_buffer, length); 558 dump_smb(smb_buffer, length);
535 if (checkSMB (smb_buffer, smb_buffer->Mid, total_read+4)) { 559 if (checkSMB (smb_buffer, smb_buffer->Mid, total_read+4)) {
536 cERROR(1, ("Bad SMB Received ")); 560 cifs_dump_mem("Bad SMB: ", smb_buffer, 48);
537 continue; 561 continue;
538 } 562 }
539 563
@@ -581,6 +605,9 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
581multi_t2_fnd: 605multi_t2_fnd:
582 task_to_wake = mid_entry->tsk; 606 task_to_wake = mid_entry->tsk;
583 mid_entry->midState = MID_RESPONSE_RECEIVED; 607 mid_entry->midState = MID_RESPONSE_RECEIVED;
608#ifdef CONFIG_CIFS_STATS2
609 mid_entry->when_received = jiffies;
610#endif
584 break; 611 break;
585 } 612 }
586 } 613 }
@@ -598,7 +625,8 @@ multi_t2_fnd:
598 } else if ((is_valid_oplock_break(smb_buffer) == FALSE) 625 } else if ((is_valid_oplock_break(smb_buffer) == FALSE)
599 && (isMultiRsp == FALSE)) { 626 && (isMultiRsp == FALSE)) {
600 cERROR(1, ("No task to wake, unknown frame rcvd!")); 627 cERROR(1, ("No task to wake, unknown frame rcvd!"));
601 cifs_dump_mem("Received Data is: ",temp,sizeof(struct smb_hdr)); 628 cifs_dump_mem("Received Data is: ",(char *)smb_buffer,
629 sizeof(struct smb_hdr));
602 } 630 }
603 } /* end while !EXITING */ 631 } /* end while !EXITING */
604 632
@@ -676,7 +704,7 @@ multi_t2_fnd:
676 msleep(125); 704 msleep(125);
677 } 705 }
678 706
679 if (list_empty(&server->pending_mid_q)) { 707 if (!list_empty(&server->pending_mid_q)) {
680 /* mpx threads have not exited yet give them 708 /* mpx threads have not exited yet give them
681 at least the smb send timeout time for long ops */ 709 at least the smb send timeout time for long ops */
682 /* due to delays on oplock break requests, we need 710 /* due to delays on oplock break requests, we need
@@ -713,7 +741,7 @@ multi_t2_fnd:
713 GFP_KERNEL); 741 GFP_KERNEL);
714 } 742 }
715 743
716 msleep(250); 744 complete_and_exit(&cifsd_complete, 0);
717 return 0; 745 return 0;
718} 746}
719 747
@@ -737,7 +765,9 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
737 toupper(system_utsname.nodename[i]); 765 toupper(system_utsname.nodename[i]);
738 } 766 }
739 vol->source_rfc1001_name[15] = 0; 767 vol->source_rfc1001_name[15] = 0;
740 768 /* null target name indicates to use *SMBSERVR default called name
769 if we end up sending RFC1001 session initialize */
770 vol->target_rfc1001_name[0] = 0;
741 vol->linux_uid = current->uid; /* current->euid instead? */ 771 vol->linux_uid = current->uid; /* current->euid instead? */
742 vol->linux_gid = current->gid; 772 vol->linux_gid = current->gid;
743 vol->dir_mode = S_IRWXUGO; 773 vol->dir_mode = S_IRWXUGO;
@@ -747,6 +777,9 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
747 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */ 777 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
748 vol->rw = TRUE; 778 vol->rw = TRUE;
749 779
780 /* default is always to request posix paths. */
781 vol->posix_paths = 1;
782
750 if (!options) 783 if (!options)
751 return 1; 784 return 1;
752 785
@@ -987,7 +1020,31 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
987 /* The string has 16th byte zero still from 1020 /* The string has 16th byte zero still from
988 set at top of the function */ 1021 set at top of the function */
989 if((i==15) && (value[i] != 0)) 1022 if((i==15) && (value[i] != 0))
990 printk(KERN_WARNING "CIFS: netbiosname longer than 15 and was truncated.\n"); 1023 printk(KERN_WARNING "CIFS: netbiosname longer than 15 truncated.\n");
1024 }
1025 } else if (strnicmp(data, "servern", 7) == 0) {
1026 /* servernetbiosname specified override *SMBSERVER */
1027 if (!value || !*value || (*value == ' ')) {
1028 cFYI(1,("empty server netbiosname specified"));
1029 } else {
1030 /* last byte, type, is 0x20 for servr type */
1031 memset(vol->target_rfc1001_name,0x20,16);
1032
1033 for(i=0;i<15;i++) {
1034 /* BB are there cases in which a comma can be
1035 valid in this workstation netbios name (and need
1036 special handling)? */
1037
1038 /* user or mount helper must uppercase netbiosname */
1039 if (value[i]==0)
1040 break;
1041 else
1042 vol->target_rfc1001_name[i] = value[i];
1043 }
1044 /* The string has 16th byte zero still from
1045 set at top of the function */
1046 if((i==15) && (value[i] != 0))
1047 printk(KERN_WARNING "CIFS: server netbiosname longer than 15 truncated.\n");
991 } 1048 }
992 } else if (strnicmp(data, "credentials", 4) == 0) { 1049 } else if (strnicmp(data, "credentials", 4) == 0) {
993 /* ignore */ 1050 /* ignore */
@@ -1025,6 +1082,27 @@ cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
1025 vol->remap = 1; 1082 vol->remap = 1;
1026 } else if (strnicmp(data, "nomapchars", 10) == 0) { 1083 } else if (strnicmp(data, "nomapchars", 10) == 0) {
1027 vol->remap = 0; 1084 vol->remap = 0;
1085 } else if (strnicmp(data, "sfu", 3) == 0) {
1086 vol->sfu_emul = 1;
1087 } else if (strnicmp(data, "nosfu", 5) == 0) {
1088 vol->sfu_emul = 0;
1089 } else if (strnicmp(data, "posixpaths", 10) == 0) {
1090 vol->posix_paths = 1;
1091 } else if (strnicmp(data, "noposixpaths", 12) == 0) {
1092 vol->posix_paths = 0;
1093 } else if ((strnicmp(data, "nocase", 6) == 0) ||
1094 (strnicmp(data, "ignorecase", 10) == 0)) {
1095 vol->nocase = 1;
1096 } else if (strnicmp(data, "brl", 3) == 0) {
1097 vol->nobrl = 0;
1098 } else if ((strnicmp(data, "nobrl", 5) == 0) ||
1099 (strnicmp(data, "nolock", 6) == 0)) {
1100 vol->nobrl = 1;
1101 /* turn off mandatory locking in mode
1102 if remote locking is turned off since the
1103 local vfs will do advisory */
1104 if(vol->file_mode == (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
1105 vol->file_mode = S_IALLUGO;
1028 } else if (strnicmp(data, "setuids", 7) == 0) { 1106 } else if (strnicmp(data, "setuids", 7) == 0) {
1029 vol->setuids = 1; 1107 vol->setuids = 1;
1030 } else if (strnicmp(data, "nosetuids", 9) == 0) { 1108 } else if (strnicmp(data, "nosetuids", 9) == 0) {
@@ -1244,7 +1322,7 @@ static void rfc1002mangle(char * target,char * source, unsigned int length)
1244 1322
1245static int 1323static int
1246ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, 1324ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1247 char * netbios_name) 1325 char * netbios_name, char * target_name)
1248{ 1326{
1249 int rc = 0; 1327 int rc = 0;
1250 int connected = 0; 1328 int connected = 0;
@@ -1309,10 +1387,16 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1309 /* Eventually check for other socket options to change from 1387 /* Eventually check for other socket options to change from
1310 the default. sock_setsockopt not used because it expects 1388 the default. sock_setsockopt not used because it expects
1311 user space buffer */ 1389 user space buffer */
1390 cFYI(1,("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",(*csocket)->sk->sk_sndbuf,
1391 (*csocket)->sk->sk_rcvbuf, (*csocket)->sk->sk_rcvtimeo));
1312 (*csocket)->sk->sk_rcvtimeo = 7 * HZ; 1392 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1393 /* make the bufsizes depend on wsize/rsize and max requests */
1394 if((*csocket)->sk->sk_sndbuf < (200 * 1024))
1395 (*csocket)->sk->sk_sndbuf = 200 * 1024;
1396 if((*csocket)->sk->sk_rcvbuf < (140 * 1024))
1397 (*csocket)->sk->sk_rcvbuf = 140 * 1024;
1313 1398
1314 /* send RFC1001 sessinit */ 1399 /* send RFC1001 sessinit */
1315
1316 if(psin_server->sin_port == htons(RFC1001_PORT)) { 1400 if(psin_server->sin_port == htons(RFC1001_PORT)) {
1317 /* some servers require RFC1001 sessinit before sending 1401 /* some servers require RFC1001 sessinit before sending
1318 negprot - BB check reconnection in case where second 1402 negprot - BB check reconnection in case where second
@@ -1322,8 +1406,14 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1322 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet), GFP_KERNEL); 1406 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet), GFP_KERNEL);
1323 if(ses_init_buf) { 1407 if(ses_init_buf) {
1324 ses_init_buf->trailer.session_req.called_len = 32; 1408 ses_init_buf->trailer.session_req.called_len = 32;
1325 rfc1002mangle(ses_init_buf->trailer.session_req.called_name, 1409 if(target_name && (target_name[0] != 0)) {
1326 DEFAULT_CIFS_CALLED_NAME,16); 1410 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1411 target_name, 16);
1412 } else {
1413 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1414 DEFAULT_CIFS_CALLED_NAME,16);
1415 }
1416
1327 ses_init_buf->trailer.session_req.calling_len = 32; 1417 ses_init_buf->trailer.session_req.calling_len = 32;
1328 /* calling name ends in null (byte 16) from old smb 1418 /* calling name ends in null (byte 16) from old smb
1329 convention. */ 1419 convention. */
@@ -1556,7 +1646,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1556 sin_server.sin_port = htons(volume_info.port); 1646 sin_server.sin_port = htons(volume_info.port);
1557 else 1647 else
1558 sin_server.sin_port = 0; 1648 sin_server.sin_port = 0;
1559 rc = ipv4_connect(&sin_server,&csocket,volume_info.source_rfc1001_name); 1649 rc = ipv4_connect(&sin_server,&csocket,
1650 volume_info.source_rfc1001_name,
1651 volume_info.target_rfc1001_name);
1560 if (rc < 0) { 1652 if (rc < 0) {
1561 cERROR(1, 1653 cERROR(1,
1562 ("Error connecting to IPv4 socket. Aborting operation")); 1654 ("Error connecting to IPv4 socket. Aborting operation"));
@@ -1606,9 +1698,11 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1606 kfree(volume_info.password); 1698 kfree(volume_info.password);
1607 FreeXid(xid); 1699 FreeXid(xid);
1608 return rc; 1700 return rc;
1609 } else 1701 }
1610 rc = 0; 1702 wait_for_completion(&cifsd_complete);
1703 rc = 0;
1611 memcpy(srvTcp->workstation_RFC1001_name, volume_info.source_rfc1001_name,16); 1704 memcpy(srvTcp->workstation_RFC1001_name, volume_info.source_rfc1001_name,16);
1705 memcpy(srvTcp->server_RFC1001_name, volume_info.target_rfc1001_name,16);
1612 srvTcp->sequence_number = 0; 1706 srvTcp->sequence_number = 0;
1613 } 1707 }
1614 } 1708 }
@@ -1653,17 +1747,27 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1653 1747
1654 /* search for existing tcon to this server share */ 1748 /* search for existing tcon to this server share */
1655 if (!rc) { 1749 if (!rc) {
1656 if((volume_info.rsize) && (volume_info.rsize <= CIFSMaxBufSize)) 1750 if(volume_info.rsize > CIFSMaxBufSize) {
1751 cERROR(1,("rsize %d too large, using MaxBufSize",
1752 volume_info.rsize));
1753 cifs_sb->rsize = CIFSMaxBufSize;
1754 } else if((volume_info.rsize) && (volume_info.rsize <= CIFSMaxBufSize))
1657 cifs_sb->rsize = volume_info.rsize; 1755 cifs_sb->rsize = volume_info.rsize;
1658 else 1756 else /* default */
1659 cifs_sb->rsize = srvTcp->maxBuf - MAX_CIFS_HDR_SIZE; /* default */ 1757 cifs_sb->rsize = CIFSMaxBufSize;
1660 if((volume_info.wsize) && (volume_info.wsize <= CIFSMaxBufSize)) 1758
1759 if(volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
1760 cERROR(1,("wsize %d too large using 4096 instead",
1761 volume_info.wsize));
1762 cifs_sb->wsize = 4096;
1763 } else if(volume_info.wsize)
1661 cifs_sb->wsize = volume_info.wsize; 1764 cifs_sb->wsize = volume_info.wsize;
1662 else 1765 else
1663 cifs_sb->wsize = CIFSMaxBufSize; /* default */ 1766 cifs_sb->wsize = CIFSMaxBufSize; /* default */
1664 if(cifs_sb->rsize < PAGE_CACHE_SIZE) { 1767 if(cifs_sb->rsize < PAGE_CACHE_SIZE) {
1665 cifs_sb->rsize = PAGE_CACHE_SIZE; 1768 cifs_sb->rsize = PAGE_CACHE_SIZE;
1666 cERROR(1,("Attempt to set readsize for mount to less than one page (4096)")); 1769 /* Windows ME does this */
1770 cFYI(1,("Attempt to set readsize for mount to less than one page (4096)"));
1667 } 1771 }
1668 cifs_sb->mnt_uid = volume_info.linux_uid; 1772 cifs_sb->mnt_uid = volume_info.linux_uid;
1669 cifs_sb->mnt_gid = volume_info.linux_gid; 1773 cifs_sb->mnt_gid = volume_info.linux_gid;
@@ -1681,8 +1785,13 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1681 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR; 1785 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
1682 if(volume_info.no_xattr) 1786 if(volume_info.no_xattr)
1683 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR; 1787 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
1788 if(volume_info.sfu_emul)
1789 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
1790 if(volume_info.nobrl)
1791 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
1792
1684 if(volume_info.direct_io) { 1793 if(volume_info.direct_io) {
1685 cERROR(1,("mounting share using direct i/o")); 1794 cFYI(1,("mounting share using direct i/o"));
1686 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; 1795 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
1687 } 1796 }
1688 1797
@@ -1696,6 +1805,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1696 to the same server share the last value passed in 1805 to the same server share the last value passed in
1697 for the retry flag is used */ 1806 for the retry flag is used */
1698 tcon->retry = volume_info.retry; 1807 tcon->retry = volume_info.retry;
1808 tcon->nocase = volume_info.nocase;
1699 } else { 1809 } else {
1700 tcon = tconInfoAlloc(); 1810 tcon = tconInfoAlloc();
1701 if (tcon == NULL) 1811 if (tcon == NULL)
@@ -1724,6 +1834,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1724 if (!rc) { 1834 if (!rc) {
1725 atomic_inc(&pSesInfo->inUse); 1835 atomic_inc(&pSesInfo->inUse);
1726 tcon->retry = volume_info.retry; 1836 tcon->retry = volume_info.retry;
1837 tcon->nocase = volume_info.nocase;
1727 } 1838 }
1728 } 1839 }
1729 } 1840 }
@@ -1745,8 +1856,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1745 spin_lock(&GlobalMid_Lock); 1856 spin_lock(&GlobalMid_Lock);
1746 srvTcp->tcpStatus = CifsExiting; 1857 srvTcp->tcpStatus = CifsExiting;
1747 spin_unlock(&GlobalMid_Lock); 1858 spin_unlock(&GlobalMid_Lock);
1748 if(srvTcp->tsk) 1859 if(srvTcp->tsk) {
1749 send_sig(SIGKILL,srvTcp->tsk,1); 1860 send_sig(SIGKILL,srvTcp->tsk,1);
1861 wait_for_completion(&cifsd_complete);
1862 }
1750 } 1863 }
1751 /* If find_unc succeeded then rc == 0 so we can not end */ 1864 /* If find_unc succeeded then rc == 0 so we can not end */
1752 if (tcon) /* up accidently freeing someone elses tcon struct */ 1865 if (tcon) /* up accidently freeing someone elses tcon struct */
@@ -1759,8 +1872,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1759 temp_rc = CIFSSMBLogoff(xid, pSesInfo); 1872 temp_rc = CIFSSMBLogoff(xid, pSesInfo);
1760 /* if the socketUseCount is now zero */ 1873 /* if the socketUseCount is now zero */
1761 if((temp_rc == -ESHUTDOWN) && 1874 if((temp_rc == -ESHUTDOWN) &&
1762 (pSesInfo->server->tsk)) 1875 (pSesInfo->server->tsk)) {
1763 send_sig(SIGKILL,pSesInfo->server->tsk,1); 1876 send_sig(SIGKILL,pSesInfo->server->tsk,1);
1877 wait_for_completion(&cifsd_complete);
1878 }
1764 } else 1879 } else
1765 cFYI(1, ("No session or bad tcon")); 1880 cFYI(1, ("No session or bad tcon"));
1766 sesInfoFree(pSesInfo); 1881 sesInfoFree(pSesInfo);
@@ -1783,8 +1898,27 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1783 cFYI(1,("server negotiated posix acl support")); 1898 cFYI(1,("server negotiated posix acl support"));
1784 sb->s_flags |= MS_POSIXACL; 1899 sb->s_flags |= MS_POSIXACL;
1785 } 1900 }
1901
1902 /* Try and negotiate POSIX pathnames if we can. */
1903 if (volume_info.posix_paths && (CIFS_UNIX_POSIX_PATHNAMES_CAP &
1904 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
1905 if (!CIFSSMBSetFSUnixInfo(xid, tcon, CIFS_UNIX_POSIX_PATHNAMES_CAP)) {
1906 cFYI(1,("negotiated posix pathnames support"));
1907 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS;
1908 } else {
1909 cFYI(1,("posix pathnames support requested but not supported"));
1910 }
1911 }
1786 } 1912 }
1787 } 1913 }
1914 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
1915 cifs_sb->wsize = min(cifs_sb->wsize,
1916 (tcon->ses->server->maxBuf -
1917 MAX_CIFS_HDR_SIZE));
1918 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
1919 cifs_sb->rsize = min(cifs_sb->rsize,
1920 (tcon->ses->server->maxBuf -
1921 MAX_CIFS_HDR_SIZE));
1788 } 1922 }
1789 1923
1790 /* volume_info.password is freed above when existing session found 1924 /* volume_info.password is freed above when existing session found
@@ -1832,6 +1966,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
1832 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX, 1966 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
1833 NULL /* no tCon exists yet */ , 13 /* wct */ ); 1967 NULL /* no tCon exists yet */ , 13 /* wct */ );
1834 1968
1969 smb_buffer->Mid = GetNextMid(ses->server);
1835 pSMB->req_no_secext.AndXCommand = 0xFF; 1970 pSMB->req_no_secext.AndXCommand = 0xFF;
1836 pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); 1971 pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
1837 pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq); 1972 pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
@@ -2107,6 +2242,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2107 /* send SMBsessionSetup here */ 2242 /* send SMBsessionSetup here */
2108 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX, 2243 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2109 NULL /* no tCon exists yet */ , 12 /* wct */ ); 2244 NULL /* no tCon exists yet */ , 12 /* wct */ );
2245
2246 smb_buffer->Mid = GetNextMid(ses->server);
2110 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; 2247 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2111 pSMB->req.AndXCommand = 0xFF; 2248 pSMB->req.AndXCommand = 0xFF;
2112 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); 2249 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
@@ -2373,6 +2510,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2373 /* send SMBsessionSetup here */ 2510 /* send SMBsessionSetup here */
2374 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX, 2511 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2375 NULL /* no tCon exists yet */ , 12 /* wct */ ); 2512 NULL /* no tCon exists yet */ , 12 /* wct */ );
2513
2514 smb_buffer->Mid = GetNextMid(ses->server);
2376 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; 2515 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2377 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT); 2516 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2378 2517
@@ -2715,6 +2854,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2715 /* send SMBsessionSetup here */ 2854 /* send SMBsessionSetup here */
2716 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX, 2855 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2717 NULL /* no tCon exists yet */ , 12 /* wct */ ); 2856 NULL /* no tCon exists yet */ , 12 /* wct */ );
2857
2858 smb_buffer->Mid = GetNextMid(ses->server);
2718 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT); 2859 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2719 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; 2860 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2720 pSMB->req.AndXCommand = 0xFF; 2861 pSMB->req.AndXCommand = 0xFF;
@@ -3086,6 +3227,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3086 3227
3087 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX, 3228 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
3088 NULL /*no tid */ , 4 /*wct */ ); 3229 NULL /*no tid */ , 4 /*wct */ );
3230
3231 smb_buffer->Mid = GetNextMid(ses->server);
3089 smb_buffer->Uid = ses->Suid; 3232 smb_buffer->Uid = ses->Suid;
3090 pSMB = (TCONX_REQ *) smb_buffer; 3233 pSMB = (TCONX_REQ *) smb_buffer;
3091 pSMBr = (TCONX_RSP *) smb_buffer_response; 3234 pSMBr = (TCONX_RSP *) smb_buffer_response;
@@ -3207,8 +3350,10 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3207 return 0; 3350 return 0;
3208 } else if (rc == -ESHUTDOWN) { 3351 } else if (rc == -ESHUTDOWN) {
3209 cFYI(1,("Waking up socket by sending it signal")); 3352 cFYI(1,("Waking up socket by sending it signal"));
3210 if(cifsd_task) 3353 if(cifsd_task) {
3211 send_sig(SIGKILL,cifsd_task,1); 3354 send_sig(SIGKILL,cifsd_task,1);
3355 wait_for_completion(&cifsd_complete);
3356 }
3212 rc = 0; 3357 rc = 0;
3213 } /* else - we have an smb session 3358 } /* else - we have an smb session
3214 left on this socket do not kill cifsd */ 3359 left on this socket do not kill cifsd */