bk://cifs.bkbits.net/linux-2.5cifs cifs.adm@hostme.bitkeeper.com|ChangeSet|20040428010922|57825 cifs.adm # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/04/29 15:41:50-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-cifs # # fs/cifs/cifssmb.c # 2004/04/29 15:41:48-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/27 16:50:50-05:00 stevef@stevef95.austin.ibm.com # fix double entry typo # # fs/cifs/cifssmb.c # 2004/04/27 16:50:43-05:00 stevef@stevef95.austin.ibm.com +1 -1 # fix double entry typo # # ChangeSet # 2004/04/27 16:43:22-05:00 stevef@stevef95.austin.ibm.com # fixes for socket retry and error handling of misc. error paths # # fs/cifs/transport.c # 2004/04/27 16:43:14-05:00 stevef@stevef95.austin.ibm.com +39 -39 # fix partial socket write retry # # fs/cifs/file.c # 2004/04/27 16:43:13-05:00 stevef@stevef95.austin.ibm.com +5 -0 # log out of memory getting resume key # # fs/cifs/connect.c # 2004/04/27 16:43:13-05:00 stevef@stevef95.austin.ibm.com +4 -3 # on low memory do not prematurely exit demux thread # # fs/cifs/cifssmb.c # 2004/04/27 16:43:13-05:00 stevef@stevef95.austin.ibm.com +7 -3 # Improve UnixQPathInfo error handling # # fs/cifs/CHANGES # 2004/04/27 16:43:13-05:00 stevef@stevef95.austin.ibm.com +7 -2 # update cifs vfs change log for 1.12 # # ChangeSet # 2004/04/27 00:42:42-05:00 stevef@smfhome.smfsambadom # Merge bk://cifs.bkbits.net/linux-2.5cifs # into smfhome.smfsambadom:/suse/home/stevef/bk/linux-2.5cifs # # ChangeSet # 2004/04/26 18:11:55-07:00 akpm@bix.(none) # Merge bk://cifs.bkbits.net/linux-2.5cifs # into bix.(none):/usr/src/bk-cifs # # ChangeSet # 2004/04/27 00:56:04-05:00 stevef@steveft21.ltcsamba # rfc1001 session init name parsing fix # # fs/cifs/connect.c # 2004/04/27 00:42:28-05:00 stevef@smfhome.smfsambadom +0 -0 # Auto merged # # fs/cifs/connect.c # 2004/04/27 00:55:47-05:00 stevef@steveft21.ltcsamba +48 -17 # rfc1001 session init name parsing fix # # ChangeSet # 2004/04/27 00:33:08-05:00 stevef@smfhome.smfsambadom # do not block (writing back to the filesystem potentially) while allocating smb buffers # # fs/cifs/misc.c # 2004/04/27 00:33:01-05:00 stevef@smfhome.smfsambadom +1 -1 # do not block (writing back to the filesystem potentially) while allocating smb buffers # # fs/cifs/connect.c # 2004/04/27 00:33:01-05:00 stevef@smfhome.smfsambadom +2 -1 # do not block allocating memory in cifs daemon # # fs/cifs/cifsfs.c # 2004/04/26 18:11:52-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/26 17:32:50-05:00 stevef@stevef95.austin.ibm.com # update rfc1001 handling # # fs/cifs/cifsglob.h # 2004/04/26 17:32:42-05:00 stevef@stevef95.austin.ibm.com +1 -1 # move rfc1001 workstation name from per smb session struct to per tcp connection where it belongs # # fs/cifs/cifsfs.c # 2004/04/26 17:32:42-05:00 stevef@stevef95.austin.ibm.com +4 -2 # missing fdatawait in invalidate path # # fs/cifs/TODO # 2004/04/26 17:32:42-05:00 stevef@stevef95.austin.ibm.com +15 -2 # update cifs todo list # # fs/cifs/README # 2004/04/26 17:32:42-05:00 stevef@stevef95.austin.ibm.com +11 -2 # add updated cifs readme info on nt # # fs/cifs/CHANGES # 2004/04/26 17:32:42-05:00 stevef@stevef95.austin.ibm.com +1 -1 # Update CIFS VFS change log for 1.11a # # ChangeSet # 2004/04/26 14:12:28-05:00 stevef@stevef95.austin.ibm.com # fix memory allocation of rfc1002 sess init struct # # fs/cifs/connect.c # 2004/04/26 14:12:20-05:00 stevef@stevef95.austin.ibm.com +1 -1 # fix memory allocation of rfc1002 sess init struct # # ChangeSet # 2004/04/26 11:38:19-05:00 stevef@stevef95.austin.ibm.com # Merge bk://cifs.bkbits.net/linux-2.5cifs # into stevef95.austin.ibm.com:/usr/src/bk/linux-2.5cifs # # fs/cifs/file.c # 2004/04/26 11:38:08-05:00 stevef@stevef95.austin.ibm.com +0 -0 # Auto merged # # ChangeSet # 2004/04/26 11:34:15-05:00 stevef@stevef95.austin.ibm.com # Flush writebehind before invalidate in file open path # # fs/cifs/file.c # 2004/04/26 11:34:07-05:00 stevef@stevef95.austin.ibm.com +10 -4 # Flush writebehind before invalidate in file open path # # fs/cifs/CHANGES # 2004/04/26 11:34:04-05:00 stevef@stevef95.austin.ibm.com +5 -0 # Update CIFS VFS changelog for version 1.11 # # fs/cifs/AUTHORS # 2004/04/26 11:34:04-05:00 stevef@stevef95.austin.ibm.com +3 -1 # Update CIFS contributors # # ChangeSet # 2004/04/25 22:43:20-05:00 stevef@smfhome.smfsambadom # Remove unneeded debug statement # # fs/cifs/connect.c # 2004/04/25 22:42:58-05:00 stevef@smfhome.smfsambadom +0 -1 # Remove unneeded debug statement # # ChangeSet # 2004/04/25 22:41:35-05:00 stevef@smfhome.smfsambadom # Fix port 139 connections to Windows 2K adding missing RFC1002 session_init # # fs/cifs/rfc1002pdu.h # 2004/04/25 22:41:28-05:00 stevef@smfhome.smfsambadom +6 -2 # Fix port 139 connections to Windows 2K adding missing RFC1002 session_init # # fs/cifs/file.c # 2004/04/25 22:41:28-05:00 stevef@smfhome.smfsambadom +1 -1 # fix typo in comment # # fs/cifs/connect.c # 2004/04/25 22:41:28-05:00 stevef@smfhome.smfsambadom +74 -11 # Fix port 139 connections to Windows 2K adding missing RFC1002 session_init # # fs/cifs/cifsglob.h # 2004/04/25 22:41:28-05:00 stevef@smfhome.smfsambadom +1 -0 # Fix port 139 connections to Windows 2K adding missing RFC1002 session_init # # ChangeSet # 2004/04/23 12:36:52-07:00 akpm@bix.(none) # Merge bk://cifs.bkbits.net/linux-2.5cifs # into bix.(none):/usr/src/bk-cifs # # fs/cifs/cifsfs.c # 2004/04/23 12:36:49-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/19 19:23:58-07:00 akpm@bix.(none) # Merge bk://cifs.bkbits.net/linux-2.5cifs # into bix.(none):/usr/src/bk-cifs # # fs/cifs/cifsfs.c # 2004/04/19 19:23:56-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/16 20:19:53-07:00 akpm@bix.(none) # Merge bk://cifs.bkbits.net/linux-2.5cifs # into bix.(none):/usr/src/bk-cifs # # fs/cifs/cifsfs.c # 2004/04/16 20:19:51-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/16 20:18:59-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-cifs # # fs/cifs/cifsfs.c # 2004/04/16 20:18:56-07:00 akpm@bix.(none) +0 -0 # Auto merged # diff -Nru a/fs/cifs/AUTHORS b/fs/cifs/AUTHORS --- a/fs/cifs/AUTHORS Thu Apr 29 23:09:38 2004 +++ b/fs/cifs/AUTHORS Thu Apr 29 23:09:38 2004 @@ -21,11 +21,13 @@ Andi Kleen Amrut Joshi Shobhit Dayal +Sergey Vlasov Test case and Bug Report contributors ------------------------------------- Thanks to those in the community who have submitted detailed bug reports and debug of problems they have found: Jochen Dolze, David Blaine, Rene Scharfe, Martin Josefsson, Alexander Wild, Anthony Liguori, -Urban Widmark, Massimiliano Ferrero, Howard Owen and others. +Lars Muller, Urban Widmark, Massimiliano Ferrero, Howard Owen, +Kieron Briggs and others. diff -Nru a/fs/cifs/CHANGES b/fs/cifs/CHANGES --- a/fs/cifs/CHANGES Thu Apr 29 23:09:38 2004 +++ b/fs/cifs/CHANGES Thu Apr 29 23:09:38 2004 @@ -1,3 +1,13 @@ +Version 1.12 +------------ +Fixes for large file copy, signal handling, socket retry, buffer +allocation and low memory situations. + +Version 1.11 +------------ +Better port 139 support to Windows servers (RFC1001/RFC1002 Session_Initialize) +also now allowing support for specifying client netbiosname. NT4 support added. + Version 1.10 ------------ Fix reconnection (and certain failed mounts) to properly wake up the diff -Nru a/fs/cifs/README b/fs/cifs/README --- a/fs/cifs/README Thu Apr 29 23:09:38 2004 +++ b/fs/cifs/README Thu Apr 29 23:09:38 2004 @@ -148,8 +148,8 @@ Restrictions ============ Servers must support the NTLM SMB dialect (which is the most recent, supported -by Samba and Windows NT, 2000 and XP and many other SMB/CIFS servers) and -servers must support either "pure-TCP" (port 445 TCP/IP CIFS connections) or RFC +by Samba and Windows NT version 4, 2000 and XP and many other SMB/CIFS servers) +Servers must support either "pure-TCP" (port 445 TCP/IP CIFS connections) or RFC 1001/1002 support for "Netbios-Over-TCP/IP." Neither of these is likely to be a problem as most servers support this. IPv6 support is planned for the future. @@ -275,6 +275,15 @@ and for more extensive tracing including the start of smb requests and responses echo 1 > /proc/fs/cifs/traceSMB + +Three other experimental features are under development and to test +require enabling an ifdef (e.g. by adding "#define CIFS_FCNTL" in cifsglob.h) + + CIFS_QUOTA + + CIFS_XATTR + + CIFS_FCNTL (fcntl needed for support of directory change notification) Also note that "cat /proc/fs/cifs/DebugData" will display some information about the active sessions and the shares that are mounted. Note: NTLMv2 enablement diff -Nru a/fs/cifs/TODO b/fs/cifs/TODO --- a/fs/cifs/TODO Thu Apr 29 23:09:38 2004 +++ b/fs/cifs/TODO Thu Apr 29 23:09:38 2004 @@ -65,14 +65,27 @@ 3) create of new files to FAT partitions on Windows servers can succeed but still return access denied (appears to be Windows not client problem). NTFS partitions do not have this problem. +4) debug connectathon special test case nfs_idem (which does +some invalid symlink naming, or at least what Samba thinks +is an invalid symlink target). +5) debug connectation lock test case 10 which fails against +Samba (may be unmappable due to POSIX to Windows lock model +differences but worth investigating). Also debug Samba to +see why lock test case 7 takes longer to complete to Samba +than to Windows. Misc testing to do ================= 1) check out max path names and max path name components against various server types. -2) Run dbench. Modify file portion of ltp so it can run against a mounted network +2) Modify file portion of ltp so it can run against a mounted network share and run it against cifs vfs. -3) Additional performance testing and optimization using iozone and similar tools. +3) Additional performance testing and optimization using iozone and similar - +there are some easy changes that can be done to parallelize sequential writes, +and when signing is disabled to request larger read sizes (larger than +negotiated size) and send larger write sizes to modern servers. + +4) More exhaustively test the recently added NT4 support diff -Nru a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c --- a/fs/cifs/cifsfs.c Thu Apr 29 23:09:38 2004 +++ b/fs/cifs/cifsfs.c Thu Apr 29 23:09:38 2004 @@ -672,8 +672,10 @@ /* down(&inode->i_sem);*/ if (S_ISREG(inode->i_mode)) { rc = filemap_fdatawrite(inode->i_mapping); - if(CIFS_I(inode)->clientCanCacheRead == 0) + if(CIFS_I(inode)->clientCanCacheRead == 0) { + filemap_fdatawait(inode->i_mapping); invalidate_remote_inode(inode); + } } else rc = 0; /* up(&inode->i_sem);*/ @@ -772,6 +774,6 @@ MODULE_AUTHOR("Steve French "); MODULE_LICENSE("GPL"); /* combination of LGPL + GPL source behaves as GPL */ MODULE_DESCRIPTION - ("VFS to access servers complying with the SNIA CIFS Specification e.g. Samba and Windows"); + ("VFS to access servers complying with the SNIA CIFS Specification e.g. Samba and Windows Revision: 1.11"); module_init(init_cifs) module_exit(exit_cifs) diff -Nru a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h --- a/fs/cifs/cifsglob.h Thu Apr 29 23:09:38 2004 +++ b/fs/cifs/cifsglob.h Thu Apr 29 23:09:38 2004 @@ -139,6 +139,7 @@ int capabilities; /* allow selective disabling of caps by smb sess */ __u16 timeZone; char cryptKey[CIFS_CRYPTO_KEY_SIZE]; + char workstation_RFC1001_name[16]; /* 16th byte is always zero */ }; /* diff -Nru a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c --- a/fs/cifs/cifssmb.c Thu Apr 29 23:09:38 2004 +++ b/fs/cifs/cifssmb.c Thu Apr 29 23:09:38 2004 @@ -1509,7 +1509,7 @@ TRANSACTION2_QPI_REQ *pSMB = NULL; TRANSACTION2_QPI_RSP *pSMBr = NULL; int rc = 0; - int bytes_returned; + int bytes_returned = 0; int name_len; cFYI(1, ("In QPathInfo (Unix) the path %s", searchName)); @@ -1565,9 +1565,13 @@ } else { /* decode response */ pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset); /* BB also check if enough total bytes returned */ - if ((pSMBr->ByteCount < 40) || (pSMBr->DataOffset > 512)) + if ((pSMBr->ByteCount < sizeof(FILE_UNIX_BASIC_INFO)) || + (pSMBr->DataOffset > 512) || + (pSMBr->DataOffset < sizeof(struct smb_hdr))) { + cFYI(1,("UnixQPathinfo invalid data offset %d bytes returned %d", + (int)pSMBr->DataOffset,bytes_returned)); rc = -EIO; /* bad smb */ - else { + } else { memcpy((char *) pFindData, (char *) &pSMBr->hdr.Protocol + pSMBr->DataOffset, diff -Nru a/fs/cifs/connect.c b/fs/cifs/connect.c --- a/fs/cifs/connect.c Thu Apr 29 23:09:38 2004 +++ b/fs/cifs/connect.c Thu Apr 29 23:09:38 2004 @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include "cifspdu.h" @@ -54,7 +55,7 @@ char *UNC; char *UNCip; char *iocharset; /* local code page for mapping to and from Unicode */ - char *source_rfc1001_name; /* netbios name of client */ + char source_rfc1001_name[16]; /* netbios name of client */ uid_t linux_uid; gid_t linux_gid; mode_t file_mode; @@ -67,8 +68,11 @@ unsigned short int port; }; -int ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket); -int ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket); +static int ipv4_connect(struct sockaddr_in *psin_server, + struct socket **csocket, + char * netb_name); +static int ipv6_connect(struct sockaddr_in6 *psin_server, + struct socket **csocket); /* @@ -149,7 +153,9 @@ if(server->protocolType == IPV6) { rc = ipv6_connect(&server->addr.sockAddr6,&server->ssocket); } else { - rc = ipv4_connect(&server->addr.sockAddr, &server->ssocket); + rc = ipv4_connect(&server->addr.sockAddr, + &server->ssocket, + server->workstation_RFC1001_name); } if(rc) { set_current_state(TASK_INTERRUPTIBLE); @@ -160,7 +166,6 @@ wake_up(&server->response_q); } } - return rc; } @@ -182,7 +187,7 @@ daemonize("cifsd"); allow_signal(SIGKILL); - + current->flags |= PF_MEMALLOC; server->tsk = current; /* save process info to wake at shutdown */ cFYI(1, ("Demultiplex PID: %d", current->pid)); @@ -196,9 +201,10 @@ memset(smb_buffer, 0, sizeof (struct smb_hdr)); if (smb_buffer == NULL) { - cERROR(1, - ("Can not get mem for SMB response buffer ")); - return -ENOMEM; + cERROR(1,("Can not get memory for SMB response")); + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ * 3); /* give system time to free memory */ + continue; } iov.iov_base = smb_buffer; iov.iov_len = sizeof (struct smb_hdr) - 1; @@ -456,12 +462,21 @@ { char *value; char *data; - int temp_len, i, j; + unsigned int temp_len, i, j; char separator[2]; separator[0] = ','; separator[1] = 0; + memset(vol->source_rfc1001_name,0x20,15); + for(i=0;i < strnlen(system_utsname.nodename,15);i++) { + /* does not have to be a perfect mapping since the field is + informational, only used for servers that do not support + port 445 and it can be overridden at mount time */ + vol->source_rfc1001_name[i] = toupper(system_utsname.nodename[i]); + } + vol->source_rfc1001_name[15] = 0; + vol->linux_uid = current->uid; /* current->euid instead? */ vol->linux_gid = current->gid; vol->dir_mode = S_IRWXUGO; @@ -590,6 +605,8 @@ printk(KERN_WARNING "CIFS: invalid domain name\n"); return 1; /* needs_arg; */ } + /* BB are there cases in which a comma can be valid in + a domain name and need special handling? */ if (strnlen(value, 65) < 65) { vol->domainname = value; cFYI(1, ("Domain name set")); @@ -652,12 +669,25 @@ simple_strtoul(value, &value, 0); } } else if (strnicmp(data, "netbiosname", 4) == 0) { - if (!value || !*value) { - vol->source_rfc1001_name = NULL; - } else if (strnlen(value, 17) < 17) { - vol->source_rfc1001_name = value; + if (!value || !*value || (*value == ' ')) { + cFYI(1,("invalid (empty) netbiosname specified")); } else { - printk(KERN_WARNING "CIFS: netbiosname too long (more than 15)\n"); + memset(vol->source_rfc1001_name,0x20,15); + for(i=0;i<15;i++) { + /* BB are there cases in which a comma can be + valid in this workstation netbios name (and need + special handling)? */ + + /* We do not uppercase netbiosname for user */ + if (value[i]==0) + break; + else + vol->source_rfc1001_name[i] = value[i]; + } + /* The string has 16th byte zero still from + set at top of the function */ + if((i==15) && (value[i] != 0)) + printk(KERN_WARNING "CIFS: netbiosname longer than 15 and was truncated.\n"); } } else if (strnicmp(data, "version", 3) == 0) { /* ignore */ @@ -845,8 +875,24 @@ return rc; } -int -ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket) +/* See RFC1001 section 14 on representation of Netbios names */ +static void rfc1002mangle(char * target,char * source, unsigned int length) +{ + unsigned int i,j; + + for(i=0,j=0;i<(length);i++) { + /* mask a nibble at a time and encode */ + target[j] = 'A' + (0x0F & (source[i] >> 4)); + target[j+1] = 'A' + (0x0F & source[i]); + j+=2; + } + +} + + +static int +ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, + char * netbios_name) { int rc = 0; int connected = 0; @@ -861,11 +907,11 @@ } else { /* BB other socket options to set KEEPALIVE, NODELAY? */ cFYI(1,("Socket created")); + /* (*csocket)->sk->allocation = GFP_NOFS; */ /* BB is there equivalent in 2.6 */ } } psin_server->sin_family = AF_INET; - if(psin_server->sin_port) { /* user overrode default port */ rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *) psin_server, @@ -912,11 +958,47 @@ the default. sock_setsockopt not used because it expects user space buffer */ (*csocket)->sk->sk_rcvtimeo = 7 * HZ; + + /* send RFC1001 sessinit */ + + if(psin_server->sin_port == htons(139)) { + /* some servers require RFC1001 sessinit before sending + negprot - BB check reconnection in case where second + sessinit is sent but no second negprot */ + struct rfc1002_session_packet * ses_init_buf; + struct smb_hdr * smb_buf; + ses_init_buf = cifs_kcalloc(sizeof(struct rfc1002_session_packet), GFP_KERNEL); + if(ses_init_buf) { + ses_init_buf->trailer.session_req.called_len = 32; + rfc1002mangle(ses_init_buf->trailer.session_req.called_name, + DEFAULT_CIFS_CALLED_NAME,16); + ses_init_buf->trailer.session_req.calling_len = 32; + if(netbios_name && (netbios_name[0] !=0)) { + rfc1002mangle(ses_init_buf->trailer.session_req.calling_name, + netbios_name,16); + } else { + rfc1002mangle(ses_init_buf->trailer.session_req.calling_name, + "LINUX_CIFS_CLNT",16); + } + ses_init_buf->trailer.session_req.scope1 = 0; + ses_init_buf->trailer.session_req.scope2 = 0; + /* BB fixme ensure calling space padded w/null terminate*/ + smb_buf = (struct smb_hdr *)ses_init_buf; + /* sizeof RFC1002_SESSION_REQUEST with no scope */ + smb_buf->smb_buf_length = 0x81000044; + rc = smb_send(*csocket, smb_buf, 0x44, + (struct sockaddr *)psin_server); + kfree(ses_init_buf); + } + /* else the negprot may still work without this + even though malloc failed */ + + } return rc; } -int +static int ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket) { int rc = 0; @@ -1000,7 +1082,6 @@ /* cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); */ memset(&volume_info,0,sizeof(struct smb_vol)); - if (cifs_parse_mount_options(mount_data, devname, &volume_info)) { if(volume_info.UNC) kfree(volume_info.UNC); @@ -1049,6 +1130,12 @@ } else if (volume_info.UNCip){ /* BB using ip addr as server name connect to the DFS root below */ cERROR(1,("Connecting to DFS root not implemented yet")); + if(volume_info.UNC) + kfree(volume_info.UNC); + if(volume_info.password) + kfree(volume_info.password); + FreeXid(xid); + return -EINVAL; } else /* which servers DFS root would we conect to */ { cERROR(1, ("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified ")); @@ -1087,7 +1174,7 @@ sin_server.sin_port = htons(volume_info.port); else sin_server.sin_port = 0; - rc = ipv4_connect(&sin_server, &csocket); + rc = ipv4_connect(&sin_server,&csocket,volume_info.source_rfc1001_name); if (rc < 0) { cERROR(1, ("Error connecting to IPv4 socket. Aborting operation")); @@ -1123,6 +1210,7 @@ init_MUTEX(&srvTcp->tcpSem); kernel_thread((void *)(void *)cifs_demultiplex_thread, srvTcp, CLONE_FS | CLONE_FILES | CLONE_VM); + memcpy(srvTcp->workstation_RFC1001_name, volume_info.source_rfc1001_name,16); } } @@ -1131,6 +1219,7 @@ cFYI(1, ("Existing smb sess found ")); if(volume_info.password) kfree(volume_info.password); + /* volume_info.UNC freed at end of function */ } else if (!rc) { cFYI(1, ("Existing smb sess not found ")); pSesInfo = sesInfoAlloc(); @@ -1142,7 +1231,8 @@ NIPQUAD(sin_server.sin_addr.s_addr)); } - if (!rc){ + if (!rc){ + /* volume_info.password freed at unmount */ if (volume_info.password) pSesInfo->password = volume_info.password; if (volume_info.username) @@ -1263,6 +1353,11 @@ if (tcon->ses->capabilities & CAP_UNIX) CIFSSMBQFSUnixInfo(xid, tcon, cifs_sb->local_nls); } + + /* volume_info.password is freed above when existing session found + (in which case it is not needed anymore) but when new sesion is created + the password ptr is put in the new session structure (in which case the + password will be freed at unmount time) */ if(volume_info.UNC) kfree(volume_info.UNC); FreeXid(xid); diff -Nru a/fs/cifs/file.c b/fs/cifs/file.c --- a/fs/cifs/file.c Thu Apr 29 23:09:38 2004 +++ b/fs/cifs/file.c Thu Apr 29 23:09:38 2004 @@ -187,6 +187,12 @@ (file->f_dentry->d_inode->i_size == (loff_t)le64_to_cpu(buf->EndOfFile))) { cFYI(1,("inode unchanged on server")); } else { + if(file->f_dentry->d_inode->i_mapping) { + /* BB no need to lock inode until after invalidate*/ + /* since namei code should already have it locked?*/ + filemap_fdatawrite(file->f_dentry->d_inode->i_mapping); + filemap_fdatawait(file->f_dentry->d_inode->i_mapping); + } cFYI(1,("invalidating remote inode since open detected it changed")); invalidate_remote_inode(file->f_dentry->d_inode); } @@ -1049,7 +1055,7 @@ } else if (bytes_read > 0) { pSMBr = (struct smb_com_read_rsp *)smb_read_data; cifs_copy_cache_pages(mapping, page_list, bytes_read, - smb_read_data + 4 /* RFC1000 hdr */ + + smb_read_data + 4 /* RFC1001 hdr */ + le16_to_cpu(pSMBr->DataOffset), &lru_pvec); i += bytes_read >> PAGE_CACHE_SHIFT; @@ -1277,20 +1283,20 @@ (tmp_inode->i_blksize - 1 + pfindData->NumOfBytes) >> tmp_inode->i_blkbits; if (S_ISREG(tmp_inode->i_mode)) { - cFYI(1, (" File inode ")); + cFYI(1, ("File inode")); tmp_inode->i_op = &cifs_file_inode_ops; tmp_inode->i_fop = &cifs_file_ops; tmp_inode->i_data.a_ops = &cifs_addr_ops; } else if (S_ISDIR(tmp_inode->i_mode)) { - cFYI(1, (" Directory inode")); + cFYI(1, ("Directory inode")); tmp_inode->i_op = &cifs_dir_inode_ops; tmp_inode->i_fop = &cifs_dir_ops; } else if (S_ISLNK(tmp_inode->i_mode)) { - cFYI(1, (" Symbolic Link inode ")); + cFYI(1, ("Symbolic Link inode")); tmp_inode->i_op = &cifs_symlink_inode_ops; /* tmp_inode->i_fop = *//* do not need to set to anything */ } else { - cFYI(1, (" Init special inode ")); + cFYI(1, ("Special inode")); init_special_inode(tmp_inode, tmp_inode->i_mode, tmp_inode->i_rdev); } @@ -1356,6 +1362,11 @@ cifsFile->search_resume_name = kmalloc(cifsFile->resume_name_length, GFP_KERNEL); + if(cifsFile->search_resume_name == NULL) { + cERROR(1,("failed new resume key allocate, length %d", + cifsFile->resume_name_length)); + return; + } if(Unicode) cifs_strtoUCS((wchar_t *) cifsFile->search_resume_name, filename, len, nls_tab); diff -Nru a/fs/cifs/misc.c b/fs/cifs/misc.c --- a/fs/cifs/misc.c Thu Apr 29 23:09:38 2004 +++ b/fs/cifs/misc.c Thu Apr 29 23:09:38 2004 @@ -153,7 +153,7 @@ albeit slightly larger than necessary and maxbuffersize defaults to this and can not be bigger */ ret_buf = - (struct smb_hdr *) kmem_cache_alloc(cifs_req_cachep, SLAB_KERNEL); + (struct smb_hdr *) kmem_cache_alloc(cifs_req_cachep, SLAB_KERNEL | SLAB_NOFS); /* clear the first few header bytes */ if (ret_buf) { diff -Nru a/fs/cifs/rfc1002pdu.h b/fs/cifs/rfc1002pdu.h --- a/fs/cifs/rfc1002pdu.h Thu Apr 29 23:09:38 2004 +++ b/fs/cifs/rfc1002pdu.h Thu Apr 29 23:09:38 2004 @@ -42,8 +42,12 @@ __u16 length; union { struct { - __u8 called_name[16]; - __u8 calling_name[16]; + __u8 called_len; + __u8 called_name[32]; + __u8 scope1; /* null */ + __u8 calling_len; + __u8 calling_name[32]; + __u8 scope2; /* null */ } session_req; struct { __u32 retarget_ip_addr; diff -Nru a/fs/cifs/transport.c b/fs/cifs/transport.c --- a/fs/cifs/transport.c Thu Apr 29 23:09:38 2004 +++ b/fs/cifs/transport.c Thu Apr 29 23:09:38 2004 @@ -149,19 +149,25 @@ temp_fs = get_fs(); /* we must turn off socket api parm checking */ set_fs(get_ds()); - rc = sock_sendmsg(ssocket, &smb_msg, smb_buf_length + 4); - while((rc == -ENOSPC) || (rc == -EAGAIN)) { - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(HZ/2); + while(iov.iov_len > 0) { rc = sock_sendmsg(ssocket, &smb_msg, smb_buf_length + 4); + if ((rc == -ENOSPC) || (rc == -EAGAIN)) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(HZ/2); + continue; + } + if (rc < 0) + break; + iov.iov_base += rc; + iov.iov_len -= rc; } set_fs(temp_fs); if (rc < 0) { - cERROR(1, - ("Error %d sending data on socket to server.", rc)); - } else + cERROR(1,("Error %d sending data on socket to server.", rc)); + } else { rc = 0; + } return rc; } @@ -239,7 +245,7 @@ but we still give response a change to complete */ if(midQ->midState & MID_REQUEST_SUBMITTED) { set_current_state(TASK_UNINTERRUPTIBLE); - timeout = schedule_timeout(2 * HZ); + timeout = sleep_on_timeout(&ses->server->response_q,2 * HZ); } } else { /* using normal timeout */ /* timeout = wait_event_interruptible_timeout(ses->server->response_q, @@ -250,44 +256,38 @@ /* Can not allow user interrupts- wreaks havoc with performance */ if(midQ->midState & MID_REQUEST_SUBMITTED) { set_current_state(TASK_UNINTERRUPTIBLE); - timeout = schedule_timeout(timeout); + timeout = sleep_on_timeout(&ses->server->response_q,timeout); } } - if (signal_pending(current)) { - if (midQ->resp_buf == NULL) - rc = -EINTR; /* BB are we supposed to return -ERESTARTSYS ? */ - DeleteMidQEntry(midQ); - return rc; /* why bother returning an error if it succeeded */ - } else { /* BB spinlock protect this against races with demux thread */ - spin_lock(&GlobalMid_Lock); - if (midQ->resp_buf) { - spin_unlock(&GlobalMid_Lock); - receive_len = - be32_to_cpu(midQ->resp_buf->smb_buf_length); - } else { - cFYI(1,("No response buffer")); - if(midQ->midState == MID_REQUEST_SUBMITTED) { - if(ses->server->tcpStatus == CifsExiting) - rc = -EHOSTDOWN; - else { - ses->server->tcpStatus = CifsNeedReconnect; - midQ->midState = MID_RETRY_NEEDED; - } + + spin_lock(&GlobalMid_Lock); + if (midQ->resp_buf) { + spin_unlock(&GlobalMid_Lock); + receive_len = be32_to_cpu(midQ->resp_buf->smb_buf_length); + } else { + cERROR(1,("No response buffer")); + if(midQ->midState == MID_REQUEST_SUBMITTED) { + if(ses->server->tcpStatus == CifsExiting) + rc = -EHOSTDOWN; + else { + ses->server->tcpStatus = CifsNeedReconnect; + midQ->midState = MID_RETRY_NEEDED; } + } - if (rc != -EHOSTDOWN) { - if(midQ->midState == MID_RETRY_NEEDED) { - rc = -EAGAIN; - cFYI(1,("marking request for retry")); - } else { - rc = -EIO; - } + if (rc != -EHOSTDOWN) { + if(midQ->midState == MID_RETRY_NEEDED) { + rc = -EAGAIN; + cFYI(1,("marking request for retry")); + } else { + rc = -EIO; } - spin_unlock(&GlobalMid_Lock); - DeleteMidQEntry(midQ); - return rc; } + spin_unlock(&GlobalMid_Lock); + DeleteMidQEntry(midQ); + return rc; } + if (receive_len > CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE) { cERROR(1,