diff -Nau linux-2.5.59/fs/cifs/CHANGES linux-2.5.59new/fs/cifs/CHANGES --- linux-2.5.59/fs/cifs/CHANGES Thu Jan 16 20:22:41 2003 +++ linux-2.5.59new/fs/cifs/CHANGES Thu Feb 6 02:00:22 2003 @@ -1,3 +1,31 @@ +Version 0.63 +------------ +Fix memory leak in AllocMidQEntry. +Finish reconnection logic, so connection with server can be dropped +(or server rebooted) and the cifs client will reconnect. + +Version 0.62 +------------ +Fix temporary socket leak when bad userid or password specified +(or other SMBSessSetup failure). Increase maximum buffer size to slightly +over 16K to allow negotiation of up to Samba and Windows server default read +sizes. Add support for readpages + +Version 0.61 +------------ +Fix oops when user not passed in on mount. Extensive fixes and improvements to +error logging (strip redundant newlines, change debug macros to ensure newline +passed in and to be more consistent). Fix writepage wrong file handle problem, +a readonly file handle could be incorrectly used to attempt to write out +file updates through the page cache to multiply open files. This could cause +the iozone benchmark to fail on the fwrite test. Fix bug mounting two different +shares to the same Windows server when using different usernames +(doing this to Samba servers worked but Windows was rejecting it) - now it is +possible to use different userids when connecting to the same server from a +Linux client. Fix oops when treeDisconnect called during unmount on +previously freed socket. + + Version 0.60 ------------ Fix oops in readpages caused by not setting address space operations in inode in diff -Nau linux-2.5.59/fs/cifs/TODO linux-2.5.59new/fs/cifs/TODO --- linux-2.5.59/fs/cifs/TODO Thu Jan 16 20:22:45 2003 +++ linux-2.5.59new/fs/cifs/TODO Thu Feb 6 02:00:22 2003 @@ -1,4 +1,4 @@ -version 0.5.3 October 8th, 2002 +version 0.6.3 January 31, 2003 A Partial List of Known Problems and Missing Features ===================================================== @@ -7,7 +7,8 @@ for visible, important contributions to this module. Here is a partial list of the known problems and missing features: -a) Support for SecurityDescriptors for chmod/chgrp/chown +a) Support for SecurityDescriptors for chmod/chgrp/chown so +these can be supported for Windows servers b) Better pam/winbind integration @@ -16,7 +17,7 @@ d) Kerberos/SPNEGO session setup support - (started) -e)NTLMv2 authentication and MD5-HMAC signing of SMB PDUs - (mostly implemented) +e) NTLMv2 authentication and MD5-HMAC signing SMB PDUs - (mostly implemented) f) oplock support (ie safe CIFS distributed file caching) is not complete. In addition Directory entry caching relies on a 1 second timer, rather than @@ -28,18 +29,27 @@ h) quota support i) support for the Linux 2.5 kernel new feature get_xattr and set_xattr +which will allow us to expose dos attributes as well as real +ACLs j) finish off the mount helper, mount.cifs - (started) -KNOWN BUGS (updated October 8nd, 2002) +k) finish writepages support (multi-page write behind for improved +performance) and syncpage + +l) hook lower into the sockets api (as NFS/SunRPC does) to avoid the +extra copy in/out of the socket buffers in some cases. + +m) finish support for IPv6 + +KNOWN BUGS (updated January 31, 2003) ==================================== -1) symbolic links (Windows reparse points) are recognized but +1) existing symbolic links (Windows reparse points) are recognized but can not be created remotely. They are implemented for Samba and those that support the CIFS Unix extensions but Samba has a bug currently handling symlink text beginning with slash 2) delete of file with read-only attribute set will fail (may be ok) -3) autoreconnection logic is only partially complete. -4) there may be a problem with truncating a memmapped file to smaller than 4k with +3) there may be a problem with truncating a memmapped file to smaller than 4k with the size being reported as exactly 4k. Misc testing to do @@ -47,8 +57,8 @@ 1) check out max path names and max path name components against various server types. -2) Run POSIX bencharks against cifs +2) Run dbench -3) Run dbench +3) Finish FSX testing on SMP now that we workaround the Samba bug -4) Finish FSX testing on SMP now that we workaround the Samba bug +4) Additional performance testing and optimization diff -Nau linux-2.5.59/fs/cifs/asn1.c linux-2.5.59new/fs/cifs/asn1.c --- linux-2.5.59/fs/cifs/asn1.c Thu Jan 16 20:21:34 2003 +++ linux-2.5.59new/fs/cifs/asn1.c Thu Feb 6 02:00:22 2003 @@ -458,16 +458,18 @@ unsigned int cls, con, tag, oidlen, rc; int use_ntlmssp = FALSE; + *secType = NTLM; /* BB eventually make Kerberos or NLTMSSP the default */ + /* cifs_dump_mem(" Received SecBlob ", security_blob, length); */ asn1_open(&ctx, security_blob, length); if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { - cFYI(1, ("\nError decoding negTokenInit header ")); + cFYI(1, ("Error decoding negTokenInit header ")); return 0; } else if ((cls != ASN1_APL) || (con != ASN1_CON) || (tag != ASN1_EOC)) { - cFYI(1, ("\ncls = %d con = %d tag = %d", cls, con, tag)); + cFYI(1, ("cls = %d con = %d tag = %d", cls, con, tag)); return 0; } else { /* remember to free obj->oid */ @@ -486,51 +488,49 @@ } if (!rc) { - cFYI(1, ("\nError decoding negTokenInit header")); + cFYI(1, ("Error decoding negTokenInit header")); return 0; } if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { - cFYI(1, ("\nError decoding negTokenInit ")); + cFYI(1, ("Error decoding negTokenInit ")); return 0; } else if ((cls != ASN1_CTX) || (con != ASN1_CON) || (tag != ASN1_EOC)) { - cFYI(1, - ("\ncls = %d con = %d tag = %d end = %p (%d) exit 0", + cFYI(1,("cls = %d con = %d tag = %d end = %p (%d) exit 0", cls, con, tag, end, *end)); return 0; } if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { - cFYI(1, ("\nError decoding negTokenInit ")); + cFYI(1, ("Error decoding negTokenInit ")); return 0; } else if ((cls != ASN1_UNI) || (con != ASN1_CON) || (tag != ASN1_SEQ)) { - cFYI(1, - ("\ncls = %d con = %d tag = %d end = %p (%d) exit 1", + cFYI(1,("cls = %d con = %d tag = %d end = %p (%d) exit 1", cls, con, tag, end, *end)); return 0; } if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { - cFYI(1, ("\nError decoding 2nd part of negTokenInit ")); + cFYI(1, ("Error decoding 2nd part of negTokenInit ")); return 0; } else if ((cls != ASN1_CTX) || (con != ASN1_CON) || (tag != ASN1_EOC)) { cFYI(1, - ("\ncls = %d con = %d tag = %d end = %p (%d) exit 0", + ("cls = %d con = %d tag = %d end = %p (%d) exit 0", cls, con, tag, end, *end)); return 0; } if (asn1_header_decode (&ctx, &sequence_end, &cls, &con, &tag) == 0) { - cFYI(1, ("\nError decoding 2nd part of negTokenInit ")); + cFYI(1, ("Error decoding 2nd part of negTokenInit ")); return 0; } else if ((cls != ASN1_UNI) || (con != ASN1_CON) || (tag != ASN1_SEQ)) { cFYI(1, - ("\ncls = %d con = %d tag = %d end = %p (%d) exit 1", + ("cls = %d con = %d tag = %d end = %p (%d) exit 1", cls, con, tag, end, *end)); return 0; } @@ -539,13 +539,13 @@ rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag); if (!rc) { cFYI(1, - ("\nError 1 decoding negTokenInit header exit 2")); + ("Error 1 decoding negTokenInit header exit 2")); return 0; } if ((tag == ASN1_OJI) && (con == ASN1_PRI)) { asn1_oid_decode(&ctx, end, &oid, &oidlen); cFYI(1, - ("\nOID len = %d oid = 0x%lx 0x%lx 0x%lx 0x%lx", + ("OID len = %d oid = 0x%lx 0x%lx 0x%lx 0x%lx", oidlen, *oid, *(oid + 1), *(oid + 2), *(oid + 3))); rc = compare_oid(oid, oidlen, NTLMSSP_OID, @@ -554,54 +554,53 @@ if (rc) use_ntlmssp = TRUE; } else { - cFYI(1, - ("\nThis should be an oid what is going on? ")); + cFYI(1,("This should be an oid what is going on? ")); } } if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { cFYI(1, - ("\nError decoding last part of negTokenInit exit 3")); + ("Error decoding last part of negTokenInit exit 3")); return 0; } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) { /* tag = 3 indicating mechListMIC */ cFYI(1, - ("\nExit 4 cls = %d con = %d tag = %d end = %p (%d)", + ("Exit 4 cls = %d con = %d tag = %d end = %p (%d)", cls, con, tag, end, *end)); return 0; } if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { cFYI(1, - ("\nError decoding last part of negTokenInit exit 5")); + ("Error decoding last part of negTokenInit exit 5")); return 0; } else if ((cls != ASN1_UNI) || (con != ASN1_CON) || (tag != ASN1_SEQ)) { cFYI(1, - ("\nExit 6 cls = %d con = %d tag = %d end = %p (%d)", + ("Exit 6 cls = %d con = %d tag = %d end = %p (%d)", cls, con, tag, end, *end)); } if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { cFYI(1, - ("\nError decoding last part of negTokenInit exit 7")); + ("Error decoding last part of negTokenInit exit 7")); return 0; } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) { cFYI(1, - ("\nExit 8 cls = %d con = %d tag = %d end = %p (%d)", + ("Exit 8 cls = %d con = %d tag = %d end = %p (%d)", cls, con, tag, end, *end)); return 0; } if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { cFYI(1, - ("\nError decoding last part of negTokenInit exit 9")); + ("Error decoding last part of negTokenInit exit 9")); return 0; } else if ((cls != ASN1_UNI) || (con != ASN1_PRI) || (tag != ASN1_GENSTR)) { cFYI(1, - ("\nExit 10 cls = %d con = %d tag = %d end = %p (%d)", + ("Exit 10 cls = %d con = %d tag = %d end = %p (%d)", cls, con, tag, end, *end)); return 0; } - cFYI(1, ("\nNeed to call asn1_octets_decode() function for this %s", ctx.pointer)); /* is this UTF-8 or ASCII? */ + cFYI(1, ("Need to call asn1_octets_decode() function for this %s", ctx.pointer)); /* is this UTF-8 or ASCII? */ } /* if (use_kerberos) diff -Nau linux-2.5.59/fs/cifs/cifs_debug.c linux-2.5.59new/fs/cifs/cifs_debug.c --- linux-2.5.59/fs/cifs/cifs_debug.c Thu Jan 16 20:22:08 2003 +++ linux-2.5.59new/fs/cifs/cifs_debug.c Thu Feb 6 02:00:22 2003 @@ -39,7 +39,7 @@ char *charptr = data; char buf[10], line[80]; - printk("%s: dump of %d bytes of data at 0x%p\n\n", label, length, data); + printk(KERN_DEBUG "%s: dump of %d bytes of data at 0x%p\n\n", label, length, data); for (i = 0; i < length; i += 16) { line[0] = 0; for (j = 0; (j < 4) && (i + j * 4 < length); j++) { @@ -52,7 +52,7 @@ buf[1] = isprint(charptr[i + j]) ? charptr[i + j] : '.'; strcat(line, buf); } - printk("%s\n", line); + printk(KERN_DEBUG "%s\n", line); } } @@ -68,7 +68,6 @@ int length = 0; char *buf_start = buf; - printk("\n\nEntering cifs_debug_data_read: buf=0x%p, beginBuffer=0x%p, offset=%ld, count=%d, eof=%d, data=0x%p\n", buf, *beginBuffer, offset, count, *eof, data); /* BB remove */ length = sprintf(buf, "Display Internal CIFS Data Structures for Debugging\n" @@ -95,7 +94,6 @@ read_unlock(&GlobalSMBSeslock); sprintf(buf, "\n"); buf++; - printk("\nTotal Buffer so far: %s\n", buf_start); length = sprintf(buf, "\nShares: \n"); buf += length; diff -Nau linux-2.5.59/fs/cifs/cifs_debug.h linux-2.5.59new/fs/cifs/cifs_debug.h --- linux-2.5.59/fs/cifs/cifs_debug.h Thu Jan 16 20:22:17 2003 +++ linux-2.5.59new/fs/cifs/cifs_debug.h Thu Feb 6 02:00:22 2003 @@ -33,29 +33,35 @@ */ #ifdef CIFS_DEBUG + /* information message: e.g., configuration, major event */ extern int cifsFYI; -#define cFYI(button,prspec)\ -{ if (button && cifsFYI) printk prspec; } +#define cifsfyi(format,arg...) if (cifsFYI) printk(KERN_DEBUG " " __FILE__ ": " format "\n" "", ## arg) + +#define cFYI(button,prspec) if (button) cifsfyi prspec + +#define cifswarn(format, arg...) printk(KERN_WARNING ": " format "\n", ## arg) /* debug event message: */ -#define cEVENT(button,prspec)\ -{ if (button) printk prspec; } +extern int cifsERROR; + +#define cEVENT(format,arg...) if (cifsERROR) printk(KERN_EVENT __FILE__ ": " format "\n", ## arg) /* error event message: e.g., i/o error */ -extern int cifsERROR; -#define cERROR(button, prspec)\ -{ if (button && cifsERROR) { printk prspec; if (button > 1) BUG(); } } +#define cifserror(format,arg...) if (cifsERROR) printk(KERN_ERR " CIFS VFS: " format "\n" "", ## arg) + +#define cERROR(button, prspec) if (button) cifserror prspec /* * debug OFF * --------- */ -#else /* _CIFS_DEBUG */ +#else /* _CIFS_DEBUG */ #define cERROR(button,prspec) -#define cEVENT(button,prspec) +#define cEVENT(format,arg...) #define cFYI(button, prspec) -#endif /* _CIFS_DEBUG */ +#define cifserror(format,arg...) +#endif /* _CIFS_DEBUG */ /* * statistics diff -Nau linux-2.5.59/fs/cifs/cifs_unicode.c linux-2.5.59new/fs/cifs/cifs_unicode.c --- linux-2.5.59/fs/cifs/cifs_unicode.c Thu Jan 16 20:23:01 2003 +++ linux-2.5.59new/fs/cifs/cifs_unicode.c Thu Feb 6 02:00:22 2003 @@ -69,7 +69,6 @@ } } to[outlen] = 0; - cEVENT(0, ("cifs_strfromUCS returning %d - '%s'\n", outlen, to)); return outlen; } @@ -86,15 +85,13 @@ int charlen; int i; - cEVENT(0, ("cifs_strtoUCS - '%s'\n", from)); - for (i = 0; len && *from; i++, from += charlen, len -= charlen) { /* works for 2.4.0 kernel or later */ charlen = codepage->char2uni(from, len, &to[i]); if (charlen < 1) { cERROR(1, - ("cifs_strtoUCS: char2uni returned %d.\n", + ("cifs_strtoUCS: char2uni returned %d", charlen)); to[i] = cpu_to_le16(0x003f); /* a question mark */ charlen = 1; @@ -103,8 +100,6 @@ } - cEVENT(0, (" returning %d\n", i)); - to[i] = 0; return i; } diff -Nau linux-2.5.59/fs/cifs/cifsfs.c linux-2.5.59new/fs/cifs/cifsfs.c --- linux-2.5.59/fs/cifs/cifsfs.c Thu Jan 16 20:22:15 2003 +++ linux-2.5.59new/fs/cifs/cifsfs.c Thu Feb 6 02:00:22 2003 @@ -71,12 +71,13 @@ if(cifs_sb == NULL) return -ENOMEM; cifs_sb->local_nls = load_nls_default(); /* needed for ASCII cp to Unicode converts */ + rc = cifs_mount(sb, cifs_sb, data, devname); if (rc) { if (!silent) cERROR(1, - ("cifs_mount failed w/return code = %d\n", rc)); + ("cifs_mount failed w/return code = %d", rc)); goto out_mount_failed; } @@ -97,13 +98,10 @@ return 0; out_no_root: - cEVENT(1, ("cifs_read_super: get root inode failed\n")); + cERROR(1, ("cifs_read_super: get root inode failed")); if (inode) iput(inode); - if (rc) { - cERROR(1, ("cifs_mount failed with no root inode")); - } out_mount_failed: if(cifs_sb) kfree(cifs_sb); @@ -116,15 +114,15 @@ int rc = 0; struct cifs_sb_info *cifs_sb; - cFYI(1, ("In cifs_put_super\n")); + cFYI(1, ("In cifs_put_super")); cifs_sb = CIFS_SB(sb); if(cifs_sb == NULL) { - cFYI(1,("\nEmpty cifs superblock info passed to unmount")); + cFYI(1,("Empty cifs superblock info passed to unmount")); return; } rc = cifs_umount(sb, cifs_sb); if (rc) { - cERROR(1, ("cifs_umount failed with return code %d\n", rc)); + cERROR(1, ("cifs_umount failed with return code %d", rc)); } unload_nls(cifs_sb->local_nls); kfree(cifs_sb); @@ -236,7 +234,7 @@ int rc; struct super_block *sb = sget(fs_type, NULL, set_anon_super, NULL); - cFYI(1, ("\nDevname: %s flags: %d ", dev_name, flags)); + cFYI(1, ("Devname: %s flags: %d ", dev_name, flags)); if (IS_ERR(sb)) return sb; @@ -277,8 +275,15 @@ struct inode_operations cifs_file_inode_ops = { /* revalidate:cifs_revalidate, */ .setattr = cifs_setattr, - .getattr = cifs_getattr, + .getattr = cifs_getattr, /* do we need this anymore? */ .rename = cifs_rename, +#ifdef CIFS_XATTR + .setxattr = cifs_setxattr, + .getxattr = cifs_getxattr, + .listxattr = cifs_listxattr, + .removexattr = cifs_removexattr, + .permission = cifs_permission, +#endif }; struct inode_operations cifs_symlink_inode_ops = { @@ -287,6 +292,12 @@ /* BB add the following two eventually */ /* revalidate: cifs_revalidate, setattr: cifs_notify_change, *//* BB do we need notify change */ +#ifdef CIFS_XATTR + .setxattr = cifs_setxattr, + .getxattr = cifs_getxattr, + .listxattr = cifs_listxattr, + .removexattr = cifs_removexattr, +#endif }; struct file_operations cifs_file_ops = { @@ -333,7 +344,7 @@ cifs_destroy_inodecache(void) { if (kmem_cache_destroy(cifs_inode_cachep)) - printk(KERN_INFO "cifs_inode_cache: error freeing\n"); + printk(KERN_WARNING "cifs_inode_cache: error freeing\n"); } int @@ -353,7 +364,7 @@ cifs_destroy_request_bufs(void) { if (kmem_cache_destroy(cifs_req_cachep)) - printk(KERN_INFO + printk(KERN_WARNING "cifs_destroy_request_cache: error not all structures were freed\n"); } @@ -373,7 +384,7 @@ cifs_destroy_mids(void) { if (kmem_cache_destroy(cifs_mid_cachep)) - printk(KERN_INFO + printk(KERN_WARNING "cifs_destroy_mids: error not all structures were freed\n"); } @@ -426,7 +437,7 @@ static void __exit exit_cifs(void) { - cFYI(0, ("\nIn unregister ie exit_cifs")); + cFYI(0, ("In unregister ie exit_cifs")); #if CONFIG_PROC_FS cifs_proc_clean(); #endif diff -Nau linux-2.5.59/fs/cifs/cifsglob.h linux-2.5.59new/fs/cifs/cifsglob.h --- linux-2.5.59/fs/cifs/cifsglob.h Thu Jan 16 20:21:43 2003 +++ linux-2.5.59new/fs/cifs/cifsglob.h Thu Feb 6 02:00:22 2003 @@ -27,7 +27,7 @@ #define MAX_TREE_SIZE 2 + MAX_SERVER_SIZE + 1 + MAX_SHARE_SIZE + 1 #define MAX_SERVER_SIZE 15 #define MAX_SHARE_SIZE 64 /* used to be 20 - this should still be enough */ -#define MAX_USERNAME_SIZE 32 /* 22 is to allow for 15 char names + null +#define MAX_USERNAME_SIZE 32 /* 32 is to allow for 15 char names + null termination then *2 for unicode versions */ #define MAX_PASSWORD_SIZE 16 @@ -109,6 +109,21 @@ struct semaphore tcpSem; struct task_struct *tsk; char server_GUID[16]; + char secMode; + enum securityEnum secType; + unsigned int maxReq; /* Clients should submit no more */ + /* than maxReq distinct unanswered SMBs to the server when using */ + /* multiplexed reads or writes */ + unsigned int maxBuf; /* maxBuf specifies the maximum */ + /* message size the server can send or receive for non-raw SMBs */ + unsigned int maxRw; /* maxRw specifies the maximum */ + /* message size the server can send or receive for */ + /* SMB_COM_WRITE_RAW or SMB_COM_READ_RAW. */ + char sessid[4]; /* unique token id for this session */ + /* (returned on Negotiate */ + int capabilities; /* allow selective disabling of caps by smb sess */ + __u16 timeZone; + char cryptKey[CIFS_CRYPTO_KEY_SIZE]; }; /* @@ -117,12 +132,11 @@ * has changed. We also hang a list of sessions owned by this user off here. */ struct cifsUidInfo { - struct cifsUidInfo *next1; /* BB replace with list and atomicize */ - struct cifsSesInfo *ses; /* list of sessions *//* BB replace with list and atomicize */ - struct srSesInfo *sesSR; /* Save/Restore session list */ + struct list_head userList; + struct list_head sessionList; /* SMB sessions for this user */ uid_t linux_uid; char user[MAX_USERNAME_SIZE + 1]; /* ascii name of user */ - /* BB eventually need ptr into PAM or WinBind info */ + /* BB may need ptr or callback for PAM or WinBind info */ }; /* @@ -135,28 +149,16 @@ struct TCP_Server_Info *server; /* pointer to server info */ atomic_t inUse; /* # of CURRENT users of this ses */ enum statusEnum status; - int dialectIndex; /* the negotiated dialect index */ - char secMode; - enum securityEnum secType; - unsigned int maxReq; /* Clients should submit no more */ - /* than maxReq distinct unanswered SMBs to the server when using */ - /* multiplexed reads or writes */ - unsigned int maxBuf; /* maxBuf specifies the maximum */ - /* message size the server can send or receive for non-raw SMBs */ - unsigned int maxRw; /* maxRw specifies the maximum */ - /* message size the server can send or receive for */ - /* SMB_COM_WRITE_RAW or SMB_COM_READ_RAW. */ - char sessid[4]; /* unique token id for this session */ - /* (returned on Negotiate */ __u16 ipc_tid; /* special tid for connection to IPC share */ - int capabilities; - __u16 timeZone; char *serverOS; /* name of operating system underlying the server */ char *serverNOS; /* name of network operating system that the server is running */ char *serverDomain; /* security realm of server */ int Suid; /* needed for user level security */ + int capabilities; char serverName[SERVER_NAME_LEN_WITH_NULL * 2]; /* BB make bigger for tcp names - will ipv6 and sctp addresses fit here?? */ - char userName[MAX_USERNAME_SIZE + 1]; /* BB remove and replace with list of cifsUidInfo structures */ + char userName[MAX_USERNAME_SIZE + 1]; + char domainName[MAX_USERNAME_SIZE + 1]; + char password_with_pad[CIFS_ENCPWD_SIZE]; }; /* @@ -172,6 +174,7 @@ char *nativeFileSystem; __u16 tid; /* The 2 byte transaction id */ __u16 Flags; /* optional support bits */ + enum statusEnum tidStatus; atomic_t useCount; /* how many mounts (explicit or implicit refer to this share */ FILE_SYSTEM_DEVICE_INFO fsDevInfo; FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* note file system name may be truncated - but very unlikely */ diff -Nau linux-2.5.59/fs/cifs/cifspdu.h linux-2.5.59new/fs/cifs/cifspdu.h --- linux-2.5.59/fs/cifs/cifspdu.h Thu Jan 16 20:22:39 2003 +++ linux-2.5.59new/fs/cifs/cifspdu.h Thu Feb 6 02:00:22 2003 @@ -79,7 +79,7 @@ /* * Starting value for maximum SMB size negotiation */ -#define CIFS_MAX_MSGSIZE (4*1024) +#define CIFS_MAX_MSGSIZE (4*4096) /* * Size of encrypted user password in bytes diff -Nau linux-2.5.59/fs/cifs/cifsproto.h linux-2.5.59new/fs/cifs/cifsproto.h --- linux-2.5.59/fs/cifs/cifsproto.h Thu Jan 16 20:21:36 2003 +++ linux-2.5.59new/fs/cifs/cifsproto.h Thu Feb 6 02:00:22 2003 @@ -36,8 +36,8 @@ unsigned int /* length */ , struct sockaddr *); extern unsigned int _GetXid(void); extern void _FreeXid(unsigned int); -#define GetXid() (int)_GetXid(); cFYI(1,("\nCIFS VFS: in %s as Xid: %d with uid: %d",__FUNCTION__, xid,current->fsuid)); -#define FreeXid(curr_xid) {_FreeXid(curr_xid); cFYI(1,("\nCIFS VFS: leaving %s (xid = %d) rc = %d\n",__FUNCTION__,curr_xid,rc));} +#define GetXid() (int)_GetXid(); cFYI(1,("CIFS VFS: in %s as Xid: %d with uid: %d",__FUNCTION__, xid,current->fsuid)); +#define FreeXid(curr_xid) {_FreeXid(curr_xid); cFYI(1,("CIFS VFS: leaving %s (xid = %d) rc = %d",__FUNCTION__,curr_xid,rc));} extern char *build_path_from_dentry(struct dentry *); extern char *build_wildcard_path_from_dentry(struct dentry *direntry); extern void renew_parental_timestamps(struct dentry *direntry); @@ -72,28 +72,21 @@ const unsigned char *search_path, struct super_block *sb); -extern int CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses, - char cryptokey[CIFS_CRYPTO_KEY_SIZE]); +extern int setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, + struct nls_table * nls_info); +extern int CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses); extern int CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, - char *user, char *domain, char *session_key, char *ntlm_session_key, const struct nls_table *); extern int CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, - char *user, char *domain, - char *SecurityBlob, - int SecurityBlobLength, + char *SecurityBlob,int SecurityBlobLength, const struct nls_table *); extern int CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, - struct cifsSesInfo *ses, - char *domain, - char *ntlm_session_key, - int *ntlmv2_flag, + struct cifsSesInfo *ses, int *ntlmv2_flag, const struct nls_table *); extern int CIFSNTLMSSPAuthSessSetup(unsigned int xid, - struct cifsSesInfo *ses, char *user, - char *domain, char *ntlm_session_key, - char *lanman_session_key, - int ntlmv2_flag, + struct cifsSesInfo *ses, char *ntlm_session_key, + char *lanman_session_key,int ntlmv2_flag, const struct nls_table *); extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, @@ -202,7 +195,7 @@ extern int CIFSSMBRead(const int xid, const struct cifsTconInfo *tcon, const int netfid, unsigned int count, - const __u64 lseek, unsigned int *nbytes, char *buf); + const __u64 lseek, unsigned int *nbytes, char **buf); extern int CIFSSMBWrite(const int xid, const struct cifsTconInfo *tcon, const int netfid, const unsigned int count, const __u64 lseek, unsigned int *nbytes, diff -Nau linux-2.5.59/fs/cifs/cifssmb.c linux-2.5.59new/fs/cifs/cifssmb.c --- linux-2.5.59/fs/cifs/cifssmb.c Thu Jan 16 20:21:44 2003 +++ linux-2.5.59new/fs/cifs/cifssmb.c Thu Feb 6 02:00:22 2003 @@ -49,6 +49,11 @@ { int rc = 0; + if(tcon) + if(tcon->ses) + if(tcon->ses->status == CifsNeedReconnect) + setup_session(0, tcon->ses, load_nls_default()); + *request_buf = buf_get(); if (request_buf == 0) { return -ENOMEM; @@ -65,13 +70,20 @@ } int -CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses, - char cryptokey[CIFS_CRYPTO_KEY_SIZE]) +CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) { NEGOTIATE_REQ *pSMB; NEGOTIATE_RSP *pSMBr; int rc = 0; int bytes_returned; + struct TCP_Server_Info * server; + + if(ses->server) + server = ses->server; + else { + rc = -EIO; + return rc; + } rc = smb_init(SMB_COM_NEGOTIATE, 0, 0 /* no tcon yet */ , (void **) &pSMB, (void **) &pSMBr); @@ -81,9 +93,9 @@ pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; if (extended_security) pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; - if (sign_CIFS_PDUs) { - pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; - } + if (sign_CIFS_PDUs) { + pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; + } pSMB->ByteCount = strlen(protocols[0].name) + 1; strncpy(pSMB->DialectsArray, protocols[0].name, 30); @@ -95,22 +107,22 @@ rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc == 0) { - ses->dialectIndex = le16_to_cpu(pSMBr->DialectIndex); - ses->secMode = pSMBr->SecurityMode; + server->secMode = pSMBr->SecurityMode; + server->secType = NTLM; /* BB override default for NTLMv2 or krb*/ /* one byte - no need to convert this or EncryptionKeyLen from le,*/ - ses->maxReq = le16_to_cpu(pSMBr->MaxMpxCount); + server->maxReq = le16_to_cpu(pSMBr->MaxMpxCount); /* probably no need to store and check maxvcs */ - ses->maxBuf = + server->maxBuf = min(le32_to_cpu(pSMBr->MaxBufferSize), (__u32) CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE); - ses->maxRw = le32_to_cpu(pSMBr->MaxRawSize); - cFYI(1, ("\nMax buf = %d ", ses->maxBuf)); - GETU32(ses->sessid) = le32_to_cpu(pSMBr->SessionKey); - ses->capabilities = le32_to_cpu(pSMBr->Capabilities); - ses->timeZone = le16_to_cpu(pSMBr->ServerTimeZone); + server->maxRw = le32_to_cpu(pSMBr->MaxRawSize); + cFYI(0, ("Max buf = %d ", ses->server->maxBuf)); + GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey); + server->capabilities = le32_to_cpu(pSMBr->Capabilities); + server->timeZone = le16_to_cpu(pSMBr->ServerTimeZone); /* BB with UTC do we ever need to be using srvr timezone? */ if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) { - memcpy(cryptokey, pSMBr->u.EncryptionKey, + memcpy(server->cryptKey, pSMBr->u.EncryptionKey, CIFS_CRYPTO_KEY_SIZE); } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) && (pSMBr->EncryptionKeyLength == 0)) { @@ -124,22 +136,22 @@ if (pSMBr->ByteCount < 16) rc = -EIO; else if (pSMBr->ByteCount == 16) { - ses->secType = RawNTLMSSP; - if (ses->server->socketUseCount.counter > 1) { + server->secType = RawNTLMSSP; + if (server->socketUseCount.counter > 1) { if (memcmp - (ses->server->server_GUID, - pSMBr->u.extended_response. - GUID, 16) != 0) { + (server->server_GUID, + pSMBr->u.extended_response. + GUID, 16) != 0) { cFYI(1, - ("UID of server does not match that of previous connection to same ip address")); - memcpy(ses->server-> - server_GUID, - pSMBr->u. - extended_response. - GUID, 16); + ("UID of server does not match that of previous connection to same ip address")); + memcpy(server-> + server_GUID, + pSMBr->u. + extended_response. + GUID, 16); } } else - memcpy(ses->server->server_GUID, + memcpy(server->server_GUID, pSMBr->u.extended_response. GUID, 16); } else { @@ -147,16 +159,16 @@ extended_response. SecurityBlob, pSMBr->ByteCount - - 16, &ses->secType); + 16, &server->secType); } } else - ses->capabilities &= ~CAP_EXTENDED_SECURITY; - if(sign_CIFS_PDUs == FALSE) { - if(ses->secMode & SECMODE_SIGN_REQUIRED) - cERROR(1,("\nServer required CIFS packet signing - enable /proc/fs/cifs/PacketSigningEnabled")); - ses->secMode &= ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); - } + server->capabilities &= ~CAP_EXTENDED_SECURITY; + if(sign_CIFS_PDUs == FALSE) { + if(server->secMode & SECMODE_SIGN_REQUIRED) + cERROR(1,("Server required CIFS packet signing - enable /proc/fs/cifs/PacketSigningEnabled")); + server->secMode &= ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); + } } if (pSMB) buf_release(pSMB); @@ -171,7 +183,7 @@ int rc = 0; int length; - cFYI(1, ("\nIn tree disconnect")); + cFYI(1, ("In tree disconnect")); /* * If last user of the connection and * connection alive - disconnect it @@ -192,6 +204,10 @@ /* BB remove (from server) list of shares - but with smp safety BB */ /* BB is ses active - do we need to check here - but how? BB */ + if((tcon->ses == 0) || (tcon->ses->server == 0)) { + up(&tcon->tconSem); + return -EIO; + } rc = smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon, (void **) &smb_buffer, (void **) &smb_buffer_response); @@ -218,7 +234,7 @@ int rc = 0; int length; - cFYI(1, ("\nIn SMBLogoff for session disconnect")); + cFYI(1, ("In SMBLogoff for session disconnect")); if (ses) down(&ses->sesSem); /* need to add more places where this sem is checked */ @@ -230,7 +246,7 @@ up(&ses->sesSem); return -EBUSY; } - if(ses->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) + if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; rc = smb_init(SMB_COM_LOGOFF_ANDX, 2, 0 /* no tcon anymore */ , (void **) &pSMB, (void **) &smb_buffer_response); @@ -278,7 +294,6 @@ name_len++; /* trailing null */ name_len *= 2; } else { /* BB improve the check for buffer overruns BB */ - name_len = strnlen(fileName, 530); name_len++; /* trailing null */ strncpy(pSMB->fileName, fileName, name_len); @@ -292,7 +307,7 @@ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { - cERROR(1, ("\nSend error in RMFile = %d\n", rc)); + cERROR(1, ("Send error in RMFile = %d", rc)); } if (pSMB) buf_release(pSMB); @@ -309,7 +324,7 @@ int bytes_returned; int name_len; - cFYI(1, ("\nIn CIFSSMBRmDir")); + cFYI(1, ("In CIFSSMBRmDir")); rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB, (void **) &pSMBr); @@ -323,7 +338,6 @@ name_len++; /* trailing null */ name_len *= 2; } else { /* BB improve the check for buffer overruns BB */ - name_len = strnlen(dirName, 530); name_len++; /* trailing null */ strncpy(pSMB->DirName, dirName, name_len); @@ -336,7 +350,7 @@ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { - cERROR(1, ("\nSend error in RMDir = %d\n", rc)); + cERROR(1, ("Send error in RMDir = %d", rc)); } if (pSMB) buf_release(pSMB); @@ -353,7 +367,7 @@ int bytes_returned; int name_len; - cFYI(1, ("\nIn CIFSSMBMkDir")); + cFYI(1, ("In CIFSSMBMkDir")); rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB, (void **) &pSMBr); @@ -367,7 +381,6 @@ name_len++; /* trailing null */ name_len *= 2; } else { /* BB improve the check for buffer overruns BB */ - name_len = strnlen(name, 530); name_len++; /* trailing null */ strncpy(pSMB->DirName, name, name_len); @@ -380,7 +393,7 @@ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { - cERROR(1, ("\nSend error in RMDir = %d\n", rc)); + cERROR(1, ("Send error in RMDir = %d", rc)); } if (pSMB) buf_release(pSMB); @@ -418,15 +431,17 @@ name_len *= 2; pSMB->NameLength = cpu_to_le16(name_len); } else { /* BB improve the check for buffer overruns BB */ - pSMB->ByteCount = 0; /* no pad */ name_len = strnlen(fileName, 530); name_len++; /* trailing null */ pSMB->NameLength = cpu_to_le16(name_len); strncpy(pSMB->fileName, fileName, name_len); } - if (*pOplock) + if (*pOplock & REQ_OPLOCK) pSMB->OpenFlags = cpu_to_le32(REQ_OPLOCK); + else if (*pOplock & REQ_BATCHOPLOCK) { + pSMB->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK); + } pSMB->DesiredAccess = cpu_to_le32(access_flags); pSMB->AllocationSize = 0; pSMB->FileAttributes = ATTR_NORMAL; /* XP does not handle ATTR_POSIX_SEMANTICS */ @@ -449,7 +464,7 @@ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { - cERROR(1, ("\nSend error in Open = %d\n", rc)); + cERROR(1, ("Send error in Open = %d", rc)); } else { *pOplock = pSMBr->OplockLevel; /* one byte no need to le_to_cpu */ *netfid = pSMBr->Fid; /* cifs fid stays in le */ @@ -463,17 +478,23 @@ return rc; } +/* If no buffer passed in, then caller wants to do the copy + as in the case of readpages so the SMB buffer must be + freed by the caller */ + int CIFSSMBRead(const int xid, const struct cifsTconInfo *tcon, const int netfid, const unsigned int count, - const __u64 lseek, unsigned int *nbytes, char *buf) + const __u64 lseek, unsigned int *nbytes, char **buf) { int rc = -EACCES; READ_REQ *pSMB = NULL; READ_RSP *pSMBr = NULL; - char *pReadData; + char *pReadData = NULL; int bytes_returned; + *nbytes = 0; + rc = smb_init(SMB_COM_READ_ANDX, 12, tcon, (void **) &pSMB, (void **) &pSMBr); if (rc) @@ -485,7 +506,7 @@ pSMB->OffsetHigh = cpu_to_le32(lseek >> 32); pSMB->Remaining = 0; pSMB->MaxCount = cpu_to_le16(min(count, - (tcon->ses->maxBuf - + (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFF00)); pSMB->MaxCountHigh = 0; pSMB->ByteCount = 0; /* no need to do le conversion since it is 0 */ @@ -493,14 +514,14 @@ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { - cERROR(1, ("\nSend error in read = %d\n", rc)); - *nbytes = 0; + cERROR(1, ("Send error in read = %d", rc)); } else { pSMBr->DataLength = le16_to_cpu(pSMBr->DataLength); *nbytes = pSMBr->DataLength; /*check that DataLength would not go beyond end of SMB */ if ((pSMBr->DataLength > CIFS_MAX_MSGSIZE) || (pSMBr->DataLength > count)) { + cFYI(1,("bad length %d for count %d",pSMBr->DataLength,count)); rc = -EIO; *nbytes = 0; } else { @@ -508,16 +529,20 @@ (char *) (&pSMBr->hdr.Protocol) + le16_to_cpu(pSMBr->DataOffset); /* if(rc = copy_to_user(buf, pReadData, pSMBr->DataLength)) { - cERROR(1,("\nFaulting on read rc = %d",rc)); + cERROR(1,("Faulting on read rc = %d",rc)); rc = -EFAULT; }*/ /* can not use copy_to_user when using page cache*/ - memcpy(buf,pReadData,pSMBr->DataLength); + if(*buf) + memcpy(*buf,pReadData,pSMBr->DataLength); } } - if (pSMB) - buf_release(pSMB); - + if (pSMB) { + if(*buf) + buf_release(pSMB); + else + *buf = (char *)pSMB; + } return rc; } @@ -542,9 +567,9 @@ pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); pSMB->OffsetHigh = cpu_to_le32(offset >> 32); pSMB->Remaining = 0; - if (count > ((tcon->ses->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFF00)) + if (count > ((tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFF00)) pSMB->DataLengthLow = - (tcon->ses->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFF00; + (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFF00; else pSMB->DataLengthLow = count; pSMB->DataLengthHigh = 0; @@ -561,7 +586,7 @@ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, long_op); if (rc) { - cERROR(1, ("\nSend error in write = %d\n", rc)); + cERROR(1, ("Send error in write = %d", rc)); *nbytes = 0; } else *nbytes = le16_to_cpu(pSMBr->Count); @@ -583,7 +608,7 @@ LOCK_RSP *pSMBr = NULL; int bytes_returned; - cFYI(1, ("\nIn CIFSSMBLock")); + cFYI(1, ("In CIFSSMBLock")); rc = smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB, (void **) &pSMBr); @@ -607,7 +632,7 @@ (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { - cERROR(1, ("\nSend error in Lock = %d\n", rc)); + cERROR(1, ("Send error in Lock = %d", rc)); } if (pSMB) buf_release(pSMB); @@ -622,7 +647,7 @@ CLOSE_REQ *pSMB = NULL; CLOSE_RSP *pSMBr = NULL; int bytes_returned; - cFYI(1, ("\nIn CIFSSMBClose")); + cFYI(1, ("In CIFSSMBClose")); rc = smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB, (void **) &pSMBr); @@ -635,7 +660,7 @@ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { - cERROR(1, ("\nSend error in Close = %d\n", rc)); + cERROR(1, ("Send error in Close = %d", rc)); } if (pSMB) buf_release(pSMB); @@ -654,7 +679,7 @@ int bytes_returned; int name_len, name_len2; - cFYI(1, ("\nIn CIFSSMBRename")); + cFYI(1, ("In CIFSSMBRename")); rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB, (void **) &pSMBr); @@ -682,7 +707,6 @@ name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; name_len2 *= 2; /* convert to bytes */ } else { /* BB improve the check for buffer overruns BB */ - name_len = strnlen(fromName, 530); name_len++; /* trailing null */ strncpy(pSMB->OldFileName, fromName, name_len); @@ -702,7 +726,7 @@ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { - cFYI(1, ("\nSend error in RMDir = %d\n", rc)); + cFYI(1, ("Send error in RMDir = %d", rc)); } if (pSMB) buf_release(pSMB); @@ -723,7 +747,7 @@ int rc = 0; int bytes_returned = 0; - cFYI(1, ("\nIn Symlink Unix style")); + cFYI(1, ("In Symlink Unix style")); rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); @@ -788,7 +812,7 @@ (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { cFYI(1, - ("\nSend error in SetPathInfo (create symlink) = %d\n", + ("Send error in SetPathInfo (create symlink) = %d", rc)); } @@ -810,7 +834,7 @@ int rc = 0; int bytes_returned = 0; - cFYI(1, ("\nIn Create Hard link Unix style")); + cFYI(1, ("In Create Hard link Unix style")); rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); @@ -873,7 +897,7 @@ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { - cFYI(1, ("\nSend error in SetPathInfo (hard link) = %d\n", rc)); + cFYI(1, ("Send error in SetPathInfo (hard link) = %d", rc)); } if (pSMB) @@ -892,7 +916,7 @@ int bytes_returned; int name_len, name_len2; - cFYI(1, ("\nIn CIFSCreateHardLink")); + cFYI(1, ("In CIFSCreateHardLink")); rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB, (void **) &pSMBr); @@ -923,7 +947,6 @@ name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; name_len2 *= 2; /* convert to bytes */ } else { /* BB improve the check for buffer overruns BB */ - name_len = strnlen(fromName, 530); name_len++; /* trailing null */ strncpy(pSMB->OldFileName, fromName, name_len); @@ -942,7 +965,7 @@ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { - cFYI(1, ("\nSend error in hard link (NT rename) = %d\n", rc)); + cFYI(1, ("Send error in hard link (NT rename) = %d", rc)); } if (pSMB) buf_release(pSMB); @@ -963,7 +986,7 @@ int bytes_returned; int name_len; - cFYI(1, ("\nIn QPathSymLinkInfo (Unix) for path %s", searchName)); + cFYI(1, ("In QPathSymLinkInfo (Unix) for path %s", searchName)); rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); if (rc) @@ -977,7 +1000,6 @@ name_len++; /* trailing null */ name_len *= 2; } else { /* BB improve the check for buffer overruns BB */ - name_len = strnlen(searchName, 530); name_len++; /* trailing null */ strncpy(pSMB->FileName, searchName, name_len); @@ -1011,7 +1033,7 @@ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { - cFYI(1, ("\nSend error in QuerySymLinkInfo = %d\n", rc)); + cFYI(1, ("Send error in QuerySymLinkInfo = %d", rc)); } else { /* decode response */ pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset); pSMBr->DataCount = le16_to_cpu(pSMBr->DataCount); @@ -1066,7 +1088,7 @@ struct smb_com_transaction_ioctl_req * pSMB; struct smb_com_transaction_ioctl_rsp * pSMBr; - cFYI(1, ("\nIn Windows reparse style QueryLink info for path %s", searchName)); + cFYI(1, ("In Windows reparse style QueryLink info for path %s", searchName)); rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB, (void **) &pSMBr); if (rc) @@ -1093,7 +1115,7 @@ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { - cFYI(1, ("\nSend error in QueryReparseLinkInfo = %d\n", rc)); + cFYI(1, ("Send error in QueryReparseLinkInfo = %d", rc)); } else { /* decode response */ pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset); pSMBr->DataCount = le16_to_cpu(pSMBr->DataCount); @@ -1121,11 +1143,11 @@ } } else { rc = -EIO; - cFYI(1,("\nInvalid return data count on get reparse info ioctl")); + cFYI(1,("Invalid return data count on get reparse info ioctl")); } symlinkinfo[buflen] = 0; /* just in case so the caller does not go off the end of the buffer */ - cFYI(1,("\nreadlink result - %s ",symlinkinfo)); + cFYI(1,("readlink result - %s ",symlinkinfo)); } } if (pSMB) @@ -1146,7 +1168,7 @@ int bytes_returned; int name_len; - cFYI(1, ("\nIn QPathInfo path %s", searchName)); + cFYI(1, ("In QPathInfo path %s", searchName)); rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); if (rc) @@ -1160,7 +1182,6 @@ name_len++; /* trailing null */ name_len *= 2; } else { /* BB improve the check for buffer overruns BB */ - name_len = strnlen(searchName, 530); name_len++; /* trailing null */ strncpy(pSMB->FileName, searchName, name_len); @@ -1194,7 +1215,7 @@ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { - cFYI(1, ("\nSend error in QPathInfo = %d\n", rc)); + cFYI(1, ("Send error in QPathInfo = %d", rc)); } else { /* decode response */ pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset); if ((pSMBr->ByteCount < 40) || (pSMBr->DataOffset > 512)) /* BB also check enough total bytes returned */ @@ -1223,7 +1244,7 @@ int bytes_returned; int name_len; - cFYI(1, ("\nIn QPathInfo (Unix) the path %s", searchName)); + cFYI(1, ("In QPathInfo (Unix) the path %s", searchName)); rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); if (rc) @@ -1237,7 +1258,6 @@ name_len++; /* trailing null */ name_len *= 2; } else { /* BB improve the check for buffer overruns BB */ - name_len = strnlen(searchName, 530); name_len++; /* trailing null */ strncpy(pSMB->FileName, searchName, name_len); @@ -1271,7 +1291,7 @@ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { - cFYI(1, ("\nSend error in QPathInfo = %d\n", rc)); + cFYI(1, ("Send error in QPathInfo = %d", rc)); } else { /* decode response */ pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset); if ((pSMBr->ByteCount < 40) || (pSMBr->DataOffset > 512)) /* BB also check enough total bytes returned */ @@ -1300,7 +1320,7 @@ int bytes_returned; int name_len; - cFYI(1, ("\nIn FindUnique")); + cFYI(1, ("In FindUnique")); rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); if (rc) @@ -1314,7 +1334,6 @@ name_len++; /* trailing null */ name_len *= 2; } else { /* BB improve the check for buffer overruns BB */ - name_len = strnlen(searchName, 530); name_len++; /* trailing null */ strncpy(pSMB->FileName, searchName, name_len); @@ -1353,7 +1372,7 @@ (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { - cFYI(1, ("\nSend error in FindFileDirInfo = %d\n", rc)); + cFYI(1, ("Send error in FindFileDirInfo = %d", rc)); } else { /* decode response */ /* BB fill in */ @@ -1378,7 +1397,7 @@ int bytes_returned; int name_len; - cFYI(1, ("\nIn FindFirst")); + cFYI(1, ("In FindFirst")); rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); if (rc) @@ -1392,7 +1411,6 @@ name_len++; /* trailing null */ name_len *= 2; } else { /* BB improve the check for buffer overruns BB */ - name_len = strnlen(searchName, 530); name_len++; /* trailing null */ strncpy(pSMB->FileName, searchName, name_len); @@ -1401,7 +1419,7 @@ pSMB->TotalParameterCount = 12 + name_len /* includes null */ ; pSMB->TotalDataCount = 0; /* no EAs */ pSMB->MaxParameterCount = cpu_to_le16(10); - pSMB->MaxDataCount = cpu_to_le16((tcon->ses->maxBuf - + pSMB->MaxDataCount = cpu_to_le16((tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFF00); pSMB->MaxSetupCount = 0; pSMB->Reserved = 0; @@ -1441,7 +1459,7 @@ (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { /* BB add logic to retry regular search if Unix search rejected unexpectedly by server */ - cFYI(1, ("\nError in FindFirst = %d\n", rc)); + cFYI(1, ("Error in FindFirst = %d", rc)); } else { /* decode response */ /* BB add safety checks for these memcpys */ if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) @@ -1480,7 +1498,7 @@ int rc = 0; int bytes_returned; - cFYI(1, ("\nIn FindNext")); + cFYI(1, ("In FindNext")); rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); if (rc) @@ -1490,7 +1508,7 @@ pSMB->TotalDataCount = 0; /* no EAs */ pSMB->MaxParameterCount = cpu_to_le16(8); pSMB->MaxDataCount = - cpu_to_le16((tcon->ses->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFF00); + cpu_to_le16((tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFF00); pSMB->MaxSetupCount = 0; pSMB->Reserved = 0; pSMB->Flags = 0; @@ -1533,7 +1551,7 @@ if (rc == -EBADF) rc = 0; /* search probably was closed at end of search above */ else - cFYI(1, ("\nFindNext returned = %d\n", rc)); + cFYI(1, ("FindNext returned = %d", rc)); } else { /* decode response */ /* BB add safety checks for these memcpys */ if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) @@ -1574,7 +1592,7 @@ *number_of_UNC_in_array = 0; *targetUNCs = NULL; - cFYI(1, ("\nIn GetDFSRefer the path %s", searchName)); + cFYI(1, ("In GetDFSRefer the path %s", searchName)); if (ses == NULL) return -ENODEV; @@ -1591,7 +1609,7 @@ if (ses->capabilities & CAP_DFS) { pSMB->hdr.Flags2 |= SMBFLG2_DFS; } - if(ses->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) + if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; if (ses->capabilities & CAP_UNICODE) { @@ -1604,7 +1622,6 @@ name_len++; /* trailing null */ name_len *= 2; } else { /* BB improve the check for buffer overruns BB */ - name_len = strnlen(searchName, 530); name_len++; /* trailing null */ strncpy(pSMB->RequestFileName, searchName, name_len); @@ -1636,7 +1653,7 @@ rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { - cFYI(1, ("\nSend error in GetDFSRefer = %d\n", rc)); + cFYI(1, ("Send error in GetDFSRefer = %d", rc)); } else { /* decode response */ /* BB Add logic to parse referrals here */ } @@ -1656,7 +1673,7 @@ int rc = 0; int bytes_returned = 0; - cFYI(1, ("\nIn QFSInfo")); + cFYI(1, ("In QFSInfo")); rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); @@ -1689,11 +1706,11 @@ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { - cERROR(1, ("\nSend error in QFSInfo = %d\n", rc)); + cERROR(1, ("Send error in QFSInfo = %d", rc)); } else { /* decode response */ pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset); cFYI(1, - ("\nDecoding qfsinfo response. BCC: %d Offset %d\n", + ("Decoding qfsinfo response. BCC: %d Offset %d", pSMBr->ByteCount, pSMBr->DataOffset)); if ((pSMBr->ByteCount < 24) || (pSMBr->DataOffset > 512)) /* BB also check enough total bytes returned */ rc = -EIO; /* bad smb */ @@ -1711,7 +1728,7 @@ FSData->f_bfree = FSData->f_bavail = le64_to_cpu(response_data->FreeAllocationUnits); cFYI(1, - ("\nBlocks: %ld Free: %ld Block size %ld\n", + ("Blocks: %ld Free: %ld Block size %ld", FSData->f_blocks, FSData->f_bfree, FSData->f_bsize)); } @@ -1732,7 +1749,7 @@ int rc = 0; int bytes_returned = 0; - cFYI(1, ("\nIn QFSAttributeInfo")); + cFYI(1, ("In QFSAttributeInfo")); rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); if (rc) @@ -1764,7 +1781,7 @@ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { - cERROR(1, ("\nSend error in QFSAttributeInfo = %d\n", rc)); + cERROR(1, ("Send error in QFSAttributeInfo = %d", rc)); } else { /* decode response */ pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset); if ((pSMBr->ByteCount < 13) || (pSMBr->DataOffset > 512)) { /* BB also check enough bytes returned */ @@ -1794,7 +1811,7 @@ int rc = 0; int bytes_returned = 0; - cFYI(1, ("\nIn QFSDeviceInfo")); + cFYI(1, ("In QFSDeviceInfo")); rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); @@ -1828,7 +1845,7 @@ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { - cERROR(1, ("\nSend error in QFSDeviceInfo = %d\n", rc)); + cERROR(1, ("Send error in QFSDeviceInfo = %d", rc)); } else { /* decode response */ pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset); if ((pSMBr->ByteCount < sizeof (FILE_SYSTEM_DEVICE_INFO)) @@ -1859,7 +1876,7 @@ int rc = 0; int bytes_returned = 0; - cFYI(1, ("\nIn QFSUnixInfo")); + cFYI(1, ("In QFSUnixInfo")); rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); if (rc) @@ -1891,7 +1908,7 @@ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { - cERROR(1, ("\nSend error in QFSUnixInfo = %d\n", rc)); + cERROR(1, ("Send error in QFSUnixInfo = %d", rc)); } else { /* decode response */ pSMBr->DataOffset = cpu_to_le16(pSMBr->DataOffset); if ((pSMBr->ByteCount < 13) || (pSMBr->DataOffset > 512)) { @@ -1927,7 +1944,7 @@ int rc = 0; int bytes_returned = 0; - cFYI(1, ("\nIn SetEOF")); + cFYI(1, ("In SetEOF")); rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); @@ -1942,7 +1959,6 @@ name_len++; /* trailing null */ name_len *= 2; } else { /* BB improve the check for buffer overruns BB */ - name_len = strnlen(fileName, 530); name_len++; /* trailing null */ strncpy(pSMB->FileName, fileName, name_len); @@ -1995,7 +2011,7 @@ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { - cFYI(1, ("\nSetPathInfo (file size) returned %d\n", rc)); + cFYI(1, ("SetPathInfo (file size) returned %d", rc)); } if (pSMB) @@ -2015,7 +2031,7 @@ int bytes_returned = 0; __u32 tmp; - cFYI(1, ("\nSetFileSize (via SetFileInfo)")); + cFYI(1, ("SetFileSize (via SetFileInfo)")); rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); @@ -2080,7 +2096,7 @@ (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { cFYI(1, - ("\nSend error in SetFileInfo (SetFileSize) = %d\n", + ("Send error in SetFileInfo (SetFileSize) = %d", rc)); } @@ -2100,7 +2116,7 @@ int bytes_returned = 0; char *data_offset; - cFYI(1, ("\nIn SetTimes")); + cFYI(1, ("In SetTimes")); rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); @@ -2115,7 +2131,6 @@ name_len++; /* trailing null */ name_len *= 2; } else { /* BB improve the check for buffer overruns BB */ - name_len = strnlen(fileName, 530); name_len++; /* trailing null */ strncpy(pSMB->FileName, fileName, name_len); @@ -2156,7 +2171,7 @@ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { - cFYI(1, ("\nSetPathInfo (times) returned %d\n", rc)); + cFYI(1, ("SetPathInfo (times) returned %d", rc)); } if (pSMB) @@ -2176,7 +2191,7 @@ int bytes_returned = 0; FILE_UNIX_BASIC_INFO *data_offset; - cFYI(1, ("\nIn SetUID/GID/Mode")); + cFYI(1, ("In SetUID/GID/Mode")); rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); @@ -2191,7 +2206,6 @@ name_len++; /* trailing null */ name_len *= 2; } else { /* BB improve the check for buffer overruns BB */ - name_len = strnlen(fileName, 530); name_len++; /* trailing null */ strncpy(pSMB->FileName, fileName, name_len); @@ -2232,7 +2246,7 @@ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); if (rc) { - cFYI(1, ("\nSetPathInfo (perms) returned %d\n", rc)); + cFYI(1, ("SetPathInfo (perms) returned %d", rc)); } if (pSMB) diff -Nau linux-2.5.59/fs/cifs/connect.c linux-2.5.59new/fs/cifs/connect.c --- linux-2.5.59/fs/cifs/connect.c Thu Jan 16 20:22:43 2003 +++ linux-2.5.59new/fs/cifs/connect.c Thu Feb 6 02:00:22 2003 @@ -60,22 +60,61 @@ int ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket); + + /* + * cifs tcp session reconnection + * + * mark tcp session as reconnecting so temporarily locked + * mark all smb sessions as reconnecting for tcp session (TBD BB) + * reconnect tcp session + * wake up waiters on reconnection? - (not needed currently) + */ + int cifs_reconnect(struct TCP_Server_Info *server) { int rc = 0; + struct list_head *tmp; + struct cifsSesInfo *ses; - cFYI(1, ("\nReconnecting tcp session ")); + server->tcpStatus = CifsNeedReconnect; + server->maxBuf = 0; - /* lock tcp session */ - /* mark all smb sessions as reconnecting which use this tcp session */ - /* reconnect tcp session */ - /* wake up waiters on reconnection */ - cFYI(1, - ("\nState: 0x%x Flags: 0x%lx", server->ssocket->state, - server->ssocket->flags)); + cFYI(1, ("Reconnecting tcp session ")); + + read_lock(&GlobalSMBSeslock); + list_for_each(tmp, &GlobalSMBSessionList) { + ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList); + if (ses->server) { + if (ses->server == server) { + ses->status = CifsNeedReconnect; + } + } + /* else tcp and smb sessions need reconnection */ + } + read_unlock(&GlobalSMBSeslock); + + if(server->ssocket) { + cFYI(1,("State: 0x%x Flags: 0x%lx", server->ssocket->state, + server->ssocket->flags)); + server->ssocket->ops->shutdown(server->ssocket,SEND_SHUTDOWN);; + cFYI(1,("Post shutdown state: 0x%x Flags: 0x%lx", server->ssocket->state, + server->ssocket->flags)); + sock_release(server->ssocket); + server->ssocket = NULL; + } + + while ((server->tcpStatus != CifsExiting) && (server->tcpStatus != CifsGood)) + { + rc = ipv4_connect(&server->sockAddr, &server->ssocket); + if(rc) { + set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(3 * HZ); + } else { + server->tcpStatus = CifsGood; + } + } - ipv4_connect(&server->sockAddr, &server->ssocket); return rc; } @@ -98,7 +137,7 @@ daemonize(); server->tsk = current; /* save process info to wake at shutdown */ - cFYI(1, ("\nDemultiplex PID: %d", current->pid)); + cFYI(1, ("Demultiplex PID: %d", current->pid)); temp_fs = get_fs(); /* we must turn off socket api parm checking */ set_fs(get_ds()); @@ -111,7 +150,7 @@ if (smb_buffer == NULL) { cERROR(1, - ("\n Error - can not get mem for SMB response buffer ")); + ("Can not get mem for SMB response buffer ")); return -ENOMEM; } iov.iov_base = smb_buffer; @@ -129,25 +168,26 @@ MSG_PEEK /* flags see socket.h */ ); if (length < 0) { if (length == -ECONNRESET) { - cERROR(1, ("\nConnection reset by peer ")); - /* BB fix call below */ - /* cifs_reconnect(server); */ + cERROR(1, ("Connection reset by peer ")); + cifs_reconnect(server); + csocket = server->ssocket; + continue; } else { /* find define for the -512 returned at unmount time */ cFYI(1, - ("\nReceived error on sock_recvmsg( peek) with length = %d\n", + ("Received error on sock_recvmsg( peek) with length = %d", length)); } break; } if (length == 0) { cFYI(1, - ("\nZero length peek received - dead session?? ")); - /* schedule_timeout(HZ/4); - continue; */ - break; + ("Zero length peek received - dead session?")); + cifs_reconnect(server); + csocket = server->ssocket; + continue; } pdu_length = 4 + ntohl(smb_buffer->smb_buf_length); - cFYI(1, ("\nPeek length rcvd: %d with smb length: %d", length, pdu_length)); /* BB */ + cFYI(1, ("Peek length rcvd: %d with smb length: %d", length, pdu_length)); /* BB */ temp = (char *) smb_buffer; if (length > 3) { @@ -156,18 +196,18 @@ iov.iov_len = 4; length = sock_recvmsg(csocket, &smb_msg, 4, 0); cFYI(0, - ("\nReceived 4 byte keep alive packet ")); + ("Received 4 byte keep alive packet ")); } else if ((temp[0] == (char) 0x83) && (length == 5)) { /* we get this from Windows 98 instead of error on SMB negprot response */ cERROR(1, - ("\nNegative RFC 1002 Session response. Error = 0x%x", + ("Negative RFC 1002 Session response. Error = 0x%x", temp[4])); break; } else if (temp[0] != (char) 0) { cERROR(1, - ("\nUnknown RFC 1001 frame received not 0x00 nor 0x85")); + ("Unknown RFC 1001 frame received not 0x00 nor 0x85")); cifs_dump_mem(" Received Data is: ", temp, length); break; } else { @@ -181,7 +221,7 @@ (smb_buffer, smb_buffer->Mid))) { cERROR(1, (KERN_ERR - "\nInvalid size or format for SMB found with length %d and pdu_lenght %d\n", + "Invalid size or format for SMB found with length %d and pdu_lenght %d", length, pdu_length)); /* BB fix by finding next smb signature - and reading off data until next smb ? BB */ @@ -199,11 +239,11 @@ iov.iov_len = pdu_length-total_read; */ length = sock_recvmsg(csocket, &smb_msg, pdu_length - total_read, 0); - /* cERROR(1,("\nFor iovlen %d Length received: %d with total read %d", + /* cERROR(1,("For iovlen %d Length received: %d with total read %d", iov.iov_len, length,total_read)); */ if (length == 0) { cERROR(1, - ("\nZero length receive when expecting %d ", + ("Zero length receive when expecting %d ", pdu_length - total_read)); /* BB add reconnect here */ break; @@ -214,11 +254,11 @@ dump_smb(smb_buffer, length); if (checkSMB (smb_buffer, smb_buffer->Mid, total_read)) { - cERROR(1, ("\n Bad SMB Received ")); + cERROR(1, ("Bad SMB Received ")); continue; } - task_to_wake = NULL; + task_to_wake = NULL; read_lock(&GlobalMid_Lock); list_for_each(tmp, &server->pending_mid_q) { mid_entry = list_entry(tmp, struct @@ -227,7 +267,7 @@ if (mid_entry->mid == smb_buffer->Mid) { cFYI(1, - (" Mid 0x%x matched - waking up\n ",mid_entry->mid)); + (" Mid 0x%x matched - waking up ",mid_entry->mid)); task_to_wake = mid_entry->tsk; mid_entry->resp_buf = smb_buffer; @@ -240,17 +280,17 @@ smb_buffer = NULL; /* will be freed by users thread after he is done */ wake_up_process(task_to_wake); } else if (is_valid_oplock_break(smb_buffer) == FALSE) { - cERROR(1, ("\n No task to wake, unknown frame rcvd!\n")); - } + cERROR(1, ("No task to wake, unknown frame rcvd!")); + } } } else { cFYI(0, - ("\nFrame less than four bytes received %d bytes long.", + ("Frame less than four bytes received %d bytes long.", length)); if (length > 0) { length = sock_recvmsg(csocket, &smb_msg, length, 0); /* throw away junk frame */ cFYI(1, - (" with junk 0x%x in it\n", + (" with junk 0x%x in it ", *(__u32 *) smb_buffer)); } } @@ -279,13 +319,12 @@ kfree(server); } else /* BB need to more gracefully handle the rare negative session response case because response will be still outstanding */ - cERROR(1, ("\nThere are still active MIDs in queue and we are exiting but we can not delete mid_q_entries or TCP_Server_Info structure due to pending requests MEMORY LEAK!!\n ")); /* BB wake up waitors, and/or wait and/or free stale mids and try again? BB */ + cERROR(1, ("There are still active MIDs in queue and we are exiting but we can not delete mid_q_entries or TCP_Server_Info structure due to pending requests MEMORY LEAK!!")); /* BB wake up waitors, and/or wait and/or free stale mids and try again? BB */ /* BB Need to fix bug in error path above - perhaps wait until smb requests time out and then free the tcp per server struct BB */ read_unlock(&GlobalSMBSeslock); - - cFYI(1, ("\nAbout to exit from demultiplex thread\n")); + cFYI(1, ("About to exit from demultiplex thread")); return 0; } @@ -314,14 +353,14 @@ *value++ = '\0'; if (strnicmp(data, "user", 4) == 0) { if (!value || !*value) { - printk(KERN_ERR - "CIFS: invalid or missing username"); + printk(KERN_WARNING + "CIFS: invalid or missing username\n"); return 1; /* needs_arg; */ } if (strnlen(value, 200) < 200) { vol->username = value; } else { - printk(KERN_ERR "CIFS: username too long"); + printk(KERN_WARNING "CIFS: username too long\n"); return 1; } } else if (strnicmp(data, "pass", 4) == 0) { @@ -330,15 +369,15 @@ } else if (strnlen(value, 17) < 17) { vol->password = value; } else { - printk(KERN_ERR "CIFS: password too long"); + printk(KERN_WARNING "CIFS: password too long\n"); return 1; } } else if ((strnicmp(data, "unc", 3) == 0) || (strnicmp(data, "target", 6) == 0) || (strnicmp(data, "path", 4) == 0)) { if (!value || !*value) { - printk(KERN_ERR - "CIFS: invalid path to network resource"); + printk(KERN_WARNING + "CIFS: invalid path to network resource\n"); return 1; /* needs_arg; */ } if (strnlen(value, 300) < 300) { @@ -347,26 +386,26 @@ vol->UNC[0] = '\\'; vol->UNC[1] = '\\'; } else if (strncmp(vol->UNC, "\\\\", 2) != 0) { - printk(KERN_ERR - "CIFS: UNC Path does not begin with // or \\\\"); + printk(KERN_WARNING + "CIFS: UNC Path does not begin with // or \\\\ \n"); return 1; } vol->UNCip = &vol->UNC[2]; } else { - printk(KERN_ERR "CIFS: UNC name too long"); + printk(KERN_WARNING "CIFS: UNC name too long\n"); return 1; } } else if ((strnicmp(data, "domain", 3) == 0) || (strnicmp(data, "workgroup", 5) == 0)) { if (!value || !*value) { - printk(KERN_ERR "CIFS: invalid domain name"); + printk(KERN_WARNING "CIFS: invalid domain name\n"); return 1; /* needs_arg; */ } if (strnlen(value, 65) < 65) { vol->domainname = value; - cFYI(1, ("\nDomain name set")); + cFYI(1, ("Domain name set")); } else { - printk(KERN_ERR "CIFS: domain name too long"); + printk(KERN_WARNING "CIFS: domain name too long\n"); return 1; } } else if (strnicmp(data, "uid", 3) == 0) { @@ -394,9 +433,7 @@ } else if (strnicmp(data, "rw", 2) == 0) { vol->rw = TRUE; } else - printk(KERN_ERR - "CIFS: Unrecognized mount option %s = %s", - data, value); + printk(KERN_WARNING "CIFS: Unknown mount option %s\n",data); } if (vol->UNC == NULL) { if (strnlen(devname, 300) < 300) { @@ -405,13 +442,12 @@ vol->UNC[0] = '\\'; vol->UNC[1] = '\\'; } else if (strncmp(vol->UNC, "\\\\", 2) != 0) { - printk(KERN_ERR - "CIFS: UNC Path does not begin with // or \\\\"); + printk(KERN_WARNING "CIFS: UNC Path does not begin with // or \\\\ \n"); return 1; } vol->UNCip = &vol->UNC[2]; } else { - printk(KERN_ERR "CIFS: UNC name too long"); + printk(KERN_WARNING "CIFS: UNC name too long\n"); return 1; } } @@ -457,7 +493,7 @@ read_lock(&GlobalSMBSeslock); list_for_each(tmp, &GlobalTreeConnectionList) { - cFYI(1, ("\nNext tcon - ")); + cFYI(1, ("Next tcon - ")); tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); if (tcon->ses) { if (tcon->ses->server) { @@ -471,13 +507,13 @@ /* found a match on the TCP session */ /* BB check if reconnection needed */ cFYI(1, - ("\nMatched ip, old UNC: %s == new: %s ?", + ("Matched ip, old UNC: %s == new: %s ?", tcon->treeName, uncName)); if (strncmp (tcon->treeName, uncName, MAX_TREE_SIZE) == 0) { cFYI(1, - ("\nMatched UNC, old user: %s == new: %s ?", + ("Matched UNC, old user: %s == new: %s ?", tcon->treeName, uncName)); if (strncmp (tcon->ses->userName, @@ -521,45 +557,118 @@ SERVER_NAME_LEN_WITH_NULL * 2), "\\IPC$", 6); rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage); cFYI(1, - ("\nCIFS Tcon rc = %d ipc_tid = %d\n", rc, - pSesInfo->ipc_tid)); + ("CIFS Tcon rc = %d ipc_tid = %d", rc,pSesInfo->ipc_tid)); kfree(temp_unc); } if (rc == 0) rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, &referrals, &num_referrals, nls_codepage); - return -ENODEV; /* BB remove and add return rc; */ + return -ENODEV; /* BB remove and add return rc; */ } +int setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, struct nls_table * nls_info) +{ + int rc = 0; + char session_key[CIFS_SESSION_KEY_SIZE]; + char ntlm_session_key[CIFS_SESSION_KEY_SIZE]; + int ntlmv2_flag = FALSE; + + if(pSesInfo->server->maxBuf == 0) /* no need to send on reconnect */ + rc = CIFSSMBNegotiate(xid, pSesInfo); + pSesInfo->capabilities = pSesInfo->server->capabilities; + if (!rc) { + cFYI(1,("Security Mode: 0x%x Capabilities: 0x%x Time Zone: %d", + pSesInfo->server->secMode, + pSesInfo->server->capabilities, + pSesInfo->server->timeZone)); + if (extended_security + && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY) + && (pSesInfo->server->secType == NTLMSSP)) { + cFYI(1, ("New style sesssetup ")); + rc = CIFSSpnegoSessSetup(xid, pSesInfo, + NULL /* security blob */, + 0 /* blob length */, + nls_info); + } else if (extended_security + && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY) + && (pSesInfo->server->secType == RawNTLMSSP)) { + cFYI(1, ("NTLMSSP sesssetup ")); + rc = CIFSNTLMSSPNegotiateSessSetup(xid, + pSesInfo, + &ntlmv2_flag, + nls_info); + if (!rc) { + if(ntlmv2_flag) { + cFYI(1,("Able to use the more secure NTLM version 2 password hash")); + /* SMBNTv2encrypt( ...); */ /* BB fix this up - + and note that Samba client equivalent looks wrong */ + } else + SMBNTencrypt(pSesInfo->password_with_pad, + pSesInfo->server->cryptKey,ntlm_session_key); + + /* for better security the weaker lanman hash not sent + in AuthSessSetup so why bother calculating it */ + /* toUpper(nls_info, + password_with_pad); + SMBencrypt(password_with_pad, + pSesInfo->server->cryptKey, session_key); */ + + rc = CIFSNTLMSSPAuthSessSetup(xid, + pSesInfo, + ntlm_session_key, + session_key, + ntlmv2_flag, + nls_info); + } + } else { /* old style NTLM 0.12 session setup */ + SMBNTencrypt(pSesInfo->password_with_pad, + pSesInfo->server->cryptKey, + ntlm_session_key); + rc = CIFSSessSetup(xid, pSesInfo, + session_key, + ntlm_session_key, + nls_info); + } + if (rc) { + cERROR(1,("Send error in SessSetup = %d",rc)); + } else { + cFYI(1,("CIFS Session Established successfully")); + pSesInfo->status = CifsGood; + } + } + return rc; +} + int ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket) { int rc = 0; - rc = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, csocket); - if (rc < 0) { - cERROR(1, ("Error creating socket. Aborting operation\n")); - return rc; + if(*csocket == NULL) { + rc = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, csocket); + if (rc < 0) { + cERROR(1, ("Error %d creating socket",rc)); + *csocket = NULL; + return rc; + } else { + cFYI(1,("Socket created")); + } } psin_server->sin_family = AF_INET; psin_server->sin_port = htons(CIFS_PORT); rc = (*csocket)->ops->connect(*csocket, - (struct sockaddr *) psin_server, - sizeof (struct sockaddr_in), 0 - /* Is there a way to fix a polling timeout - - and find out what more of the flags really mean? */ - ); + (struct sockaddr *) psin_server, + sizeof (struct sockaddr_in),0); if (rc < 0) { psin_server->sin_port = htons(RFC1001_PORT); rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *) - psin_server, - sizeof (struct sockaddr_in), 0); + psin_server, sizeof (struct sockaddr_in),0); if (rc < 0) { - cFYI(1, ("Error connecting to socket. %d\n", rc)); + cFYI(1, ("Error connecting to socket. %d", rc)); sock_release(*csocket); *csocket = NULL; return rc; @@ -577,7 +686,7 @@ rc = sock_create(PF_INET6, SOCK_STREAM, IPPROTO_TCP /* IPPROTO_IPV6 ? */ , csocket); if (rc < 0) { - cERROR(1, ("Error creating socket. Aborting operation\n")); + cERROR(1, ("Error creating socket. Aborting operation")); return rc; } @@ -596,7 +705,7 @@ sizeof (struct sockaddr_in6), 0); if (rc < 0) { cFYI(1, - ("Error connecting to socket (via ipv6). %d\n", + ("Error connecting to socket (via ipv6). %d", rc)); sock_release(*csocket); *csocket = NULL; @@ -613,8 +722,7 @@ { int rc = 0; int xid; - int ntlmv2_flag = FALSE; - struct socket *csocket; + struct socket *csocket = NULL; struct sockaddr_in sin_server; /* struct sockaddr_in6 sin_server6; */ struct smb_vol volume_info; @@ -622,35 +730,33 @@ struct cifsSesInfo *existingCifsSes = NULL; struct cifsTconInfo *tcon = NULL; struct TCP_Server_Info *srvTcp = NULL; - char cryptKey[CIFS_CRYPTO_KEY_SIZE]; - char session_key[CIFS_SESSION_KEY_SIZE]; - char ntlm_session_key[CIFS_SESSION_KEY_SIZE]; - char password_with_pad[CIFS_ENCPWD_SIZE]; xid = GetXid(); - cFYI(0, ("\nEntering cifs_mount. Xid: %d with: %s\n", xid, mount_data)); + cFYI(0, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); if(parse_mount_options(mount_data, devname, &volume_info)) { FreeXid(xid); return -EINVAL; } - if (volume_info.username) { - cFYI(1, ("\nUsername: %s ", volume_info.username)); + cFYI(1, ("Username: %s ", volume_info.username)); } else { - cERROR(1, ("\nNo username specified ")); - /* Could add ways to allow getting user name from alternate locations */ + cifserror("No username specified "); + /* In userspace mount helper we can get user name from alternate + locations such as env variables and files on disk */ + FreeXid(xid); + return -EINVAL; } if (volume_info.UNC) { sin_server.sin_addr.s_addr = inet_addr(volume_info.UNCip); - cFYI(1, ("\nUNC: %s ", volume_info.UNC)); + cFYI(1, ("UNC: %s ", volume_info.UNC)); } else { /* BB we could connect to the DFS root? but which server do we ask? */ cERROR(1, - ("\nCIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified ")); + ("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified ")); FreeXid(xid); return -EINVAL; } @@ -659,12 +765,14 @@ find_tcp_session(sin_server.sin_addr.s_addr, volume_info.username, &srvTcp); if (srvTcp) { - cFYI(1, ("\nExisting tcp session with server found ")); + cFYI(1, ("Existing tcp session with server found ")); } else { /* create socket */ rc = ipv4_connect(&sin_server, &csocket); if (rc < 0) { cERROR(1, - ("Error connecting to IPv4 socket. Aborting operation\n")); + ("Error connecting to IPv4 socket. Aborting operation")); + if(csocket != NULL) + sock_release(csocket); FreeXid(xid); return rc; } @@ -682,6 +790,7 @@ srvTcp->ssocket = csocket; init_waitqueue_head(&srvTcp->response_q); INIT_LIST_HEAD(&srvTcp->pending_mid_q); + srvTcp->tcpStatus = CifsGood; kernel_thread((void *) (void *) cifs_demultiplex_thread, srvTcp, CLONE_FS | CLONE_FILES | CLONE_VM); @@ -690,113 +799,32 @@ if (existingCifsSes) { pSesInfo = existingCifsSes; - cFYI(1, ("\nExisting smb sess found ")); + cFYI(1, ("Existing smb sess found ")); } else if (!rc) { - cFYI(1, ("\nExisting smb sess not found ")); + cFYI(1, ("Existing smb sess not found ")); pSesInfo = sesInfoAlloc(); if (pSesInfo == NULL) rc = -ENOMEM; else { pSesInfo->server = srvTcp; - pSesInfo->status = CifsGood; sprintf(pSesInfo->serverName, "%u.%u.%u.%u", NIPQUAD(sin_server.sin_addr.s_addr)); } - /* send negotiate protocol smb */ - if (!rc) - rc = CIFSSMBNegotiate(xid, pSesInfo, cryptKey); - cFYI(0, ("\nNegotiate rc = %d ", rc)); - if (!rc) { - cFYI(1, ("\nSecurity Mode: %x", pSesInfo->secMode)); - cFYI(1, - (" Server Capabilities: %x", - pSesInfo->capabilities)); - cFYI(1, - (" Time Zone: 0x%x %d\n", pSesInfo->timeZone, - pSesInfo->timeZone)); - - memset(password_with_pad, 0, CIFS_ENCPWD_SIZE); + if (!rc){ if (volume_info.password) - strcpy(password_with_pad, volume_info.password); - - if (extended_security - && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY) - && (pSesInfo->secType == NTLMSSP)) { - cFYI(1, ("\nNew style sesssetup ")); - rc = CIFSSpnegoSessSetup(xid, pSesInfo, - volume_info. - username, - volume_info. - domainname, NULL - /* security blob */ - , 0 /* blob length */ - , cifs_sb->local_nls); - } else if (extended_security - && (pSesInfo-> - capabilities & CAP_EXTENDED_SECURITY) - && (pSesInfo->secType == RawNTLMSSP)) { - cFYI(1, ("\nNTLMSSP sesssetup ")); - rc = CIFSNTLMSSPNegotiateSessSetup(xid, - pSesInfo, - cryptKey, - volume_info.domainname, - &ntlmv2_flag, - cifs_sb->local_nls); - if (!rc) { - if(ntlmv2_flag) { - cFYI(1,("\nAble to use the more secure NTLM version 2 password hash")); - /* SMBNTv2encrypt( ...); */ /* BB fix this up - - and note that Samba client equivalent looks wrong */ - } else - SMBNTencrypt(password_with_pad,cryptKey,ntlm_session_key); - - /* for better security the weaker lanman hash not sent - in AuthSessSetup so why bother calculating it */ - - /* toUpper(cifs_sb->local_nls, - password_with_pad); - SMBencrypt(password_with_pad, - cryptKey, session_key); */ - - rc = CIFSNTLMSSPAuthSessSetup(xid, - pSesInfo, - volume_info. - username, - volume_info.domainname, - ntlm_session_key, - session_key, - ntlmv2_flag, - cifs_sb->local_nls); - } - } else { /* old style NTLM 0.12 session setup */ - SMBNTencrypt(password_with_pad, cryptKey, - ntlm_session_key); - /* Removed following few lines to not send old style password - hash ever - for better security */ - /* toUpper(cifs_sb->local_nls, password_with_pad); - SMBencrypt(password_with_pad, cryptKey,session_key); */ - - rc = CIFSSessSetup(xid, pSesInfo, - volume_info.username, - volume_info. - domainname, - session_key, - ntlm_session_key, - cifs_sb->local_nls); - } - if (rc) { - cERROR(1, - ("\nSend error in SessSetup = %d\n", - rc)); - } else { - cFYI(1, - ("CIFS Session Established successfully ")); + strncpy(pSesInfo->password_with_pad, + volume_info.password,CIFS_ENCPWD_SIZE); + if (volume_info.username) strncpy(pSesInfo->userName, - volume_info.username, - MAX_USERNAME_SIZE); + volume_info.username,MAX_USERNAME_SIZE); + if (volume_info.domainname) + strncpy(pSesInfo->domainName, + volume_info.domainname,MAX_USERNAME_SIZE); + + rc = setup_session(xid,pSesInfo, cifs_sb->local_nls); + if(!rc) atomic_inc(&srvTcp->socketUseCount); - } } } @@ -806,7 +834,7 @@ find_unc(sin_server.sin_addr.s_addr, volume_info.UNC, volume_info.username); if (tcon) { - cFYI(1, ("\nFound match on UNC path ")); + cFYI(1, ("Found match on UNC path ")); } else { tcon = tconInfoAlloc(); if (tcon == NULL) @@ -829,7 +857,7 @@ rc = CIFSTCon(xid, pSesInfo, volume_info.UNC, tcon, cifs_sb->local_nls); - cFYI(1, ("\nCIFS Tcon rc = %d\n", rc)); + cFYI(1, ("CIFS Tcon rc = %d", rc)); } if (!rc) atomic_inc(&pSesInfo->inUse); @@ -837,7 +865,7 @@ } } if (pSesInfo->capabilities & CAP_LARGE_FILES) { - cFYI(0, ("\nLarge files supported ")); + cFYI(0, ("Large files supported ")); sb->s_maxbytes = (u64) 1 << 63; } else sb->s_maxbytes = (u64) 1 << 31; /* 2 GB */ @@ -845,19 +873,21 @@ /* on error free sesinfo and tcon struct if needed */ if (rc) { /* If find_unc succeeded then rc == 0 so we can not end */ - if (tcon) /* up here accidently freeing someone elses tcon struct */ + if (tcon) /* up here accidently freeing someone elses tcon struct */ tconInfoFree(tcon); if (existingCifsSes == 0) { if (pSesInfo) { if (pSesInfo->server) { - cFYI(0, - ("\nAbout to check if we need to do SMBLogoff ")); if (pSesInfo->Suid) CIFSSMBLogoff(xid, pSesInfo); - wake_up_process(pSesInfo->server->tsk); + if(pSesInfo->server->tsk) + send_sig(SIGINT,pSesInfo->server->tsk,1); + else + cFYI(1,("Can not wake captive thread on cleanup of failed mount")); + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ / 4); /* give captive thread time to exit */ } else - cFYI(1, ("\nNo session or bad tcon")); + cFYI(1, ("No session or bad tcon")); sesInfoFree(pSesInfo); /* pSesInfo = NULL; */ } @@ -875,13 +905,12 @@ } FreeXid(xid); - return rc; } int -CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, char *user, - char *domain, char session_key[CIFS_SESSION_KEY_SIZE], +CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, + char session_key[CIFS_SESSION_KEY_SIZE], char session_key2[CIFS_SESSION_KEY_SIZE], const struct nls_table *nls_codepage) { @@ -890,12 +919,14 @@ SESSION_SETUP_ANDX *pSMB; SESSION_SETUP_ANDX *pSMBr; char *bcc_ptr; + char *user = ses->userName; + char *domain = ses->domainName; int rc = 0; int remaining_words = 0; int bytes_returned = 0; int len; - cFYI(1, ("\nIn sesssetup ")); + cFYI(1, ("In sesssetup ")); smb_buffer = buf_get(); if (smb_buffer == 0) { @@ -909,10 +940,10 @@ 0 /* no tCon exists yet */ , 13 /* wct */ ); pSMB->req_no_secext.AndXCommand = 0xFF; - pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->maxBuf); - pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->maxReq); + pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); + pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq); - if(ses->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) + if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; pSMB->req_no_secext.Capabilities = @@ -1135,21 +1166,22 @@ int CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, - char *user, char *domain, char *SecurityBlob, - int SecurityBlobLength, - const struct nls_table *nls_codepage) + char *SecurityBlob,int SecurityBlobLength, + const struct nls_table *nls_codepage) { struct smb_hdr *smb_buffer; struct smb_hdr *smb_buffer_response; SESSION_SETUP_ANDX *pSMB; SESSION_SETUP_ANDX *pSMBr; char *bcc_ptr; + char *user = ses->userName; + char *domain = ses->domainName; int rc = 0; int remaining_words = 0; int bytes_returned = 0; int len; - cFYI(1, ("\nIn v2 sesssetup ")); + cFYI(1, ("In v2 sesssetup ")); smb_buffer = buf_get(); if (smb_buffer == 0) { @@ -1163,10 +1195,10 @@ 0 /* no tCon exists yet */ , 12 /* wct */ ); pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; pSMB->req.AndXCommand = 0xFF; - pSMB->req.MaxBufferSize = cpu_to_le16(ses->maxBuf); - pSMB->req.MaxMpxCount = cpu_to_le16(ses->maxReq); + pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); + pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq); - if(ses->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) + if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; pSMB->req.Capabilities = @@ -1275,7 +1307,7 @@ bcc_ptr += pSMBr->resp.SecurityBlobLength; cFYI(1, - ("\nSecurity Blob Length %d ", + ("Security Blob Length %d ", pSMBr->resp.SecurityBlobLength)); } @@ -1393,9 +1425,7 @@ int CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, - struct cifsSesInfo *ses, - char *challenge_from_server, - char *domain, int * pNTLMv2_flag, + struct cifsSesInfo *ses, int * pNTLMv2_flag, const struct nls_table *nls_codepage) { struct smb_hdr *smb_buffer; @@ -1403,6 +1433,7 @@ SESSION_SETUP_ANDX *pSMB; SESSION_SETUP_ANDX *pSMBr; char *bcc_ptr; + char *domain = ses->domainName; int rc = 0; int remaining_words = 0; int bytes_returned = 0; @@ -1411,7 +1442,7 @@ PNEGOTIATE_MESSAGE SecurityBlob; PCHALLENGE_MESSAGE SecurityBlob2; - cFYI(1, ("\nIn NTLMSSP sesssetup (negotiate) ")); + cFYI(1, ("In NTLMSSP sesssetup (negotiate) ")); *pNTLMv2_flag = FALSE; smb_buffer = buf_get(); if (smb_buffer == 0) { @@ -1428,10 +1459,10 @@ pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT); pSMB->req.AndXCommand = 0xFF; - pSMB->req.MaxBufferSize = cpu_to_le16(ses->maxBuf); - pSMB->req.MaxMpxCount = cpu_to_le16(ses->maxReq); + pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); + pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq); - if(ses->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) + if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; pSMB->req.Capabilities = @@ -1554,7 +1585,7 @@ SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr; if (SecurityBlob2->MessageType != NtLmChallenge) { cFYI(1, - ("\nUnexpected NTLMSSP message type received %d", + ("Unexpected NTLMSSP message type received %d", SecurityBlob2->MessageType)); } else if (ses) { ses->Suid = smb_buffer_response->Uid; /* UID left in le format */ @@ -1567,13 +1598,13 @@ bcc_ptr += pSMBr->resp.SecurityBlobLength; cFYI(1, - ("\nSecurity Blob Length %d ", + ("Security Blob Length %d ", pSMBr->resp.SecurityBlobLength)); } - cFYI(1, ("\nNTLMSSP Challenge rcvd ")); + cFYI(1, ("NTLMSSP Challenge rcvd ")); - memcpy(challenge_from_server, + memcpy(ses->server->cryptKey, SecurityBlob2->Challenge, CIFS_CRYPTO_KEY_SIZE); if(SecurityBlob2->NegotiateFlags & NTLMSSP_NEGOTIATE_NTLMV2) @@ -1721,16 +1752,16 @@ int CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, - char *user, char *domain, - char *ntlm_session_key, - char *lanman_session_key, int ntlmv2_flag, - const struct nls_table *nls_codepage) + char *ntlm_session_key, char *lanman_session_key, int ntlmv2_flag, + const struct nls_table *nls_codepage) { struct smb_hdr *smb_buffer; struct smb_hdr *smb_buffer_response; SESSION_SETUP_ANDX *pSMB; SESSION_SETUP_ANDX *pSMBr; char *bcc_ptr; + char *user = ses->userName; + char *domain = ses->domainName; int rc = 0; int remaining_words = 0; int bytes_returned = 0; @@ -1738,7 +1769,7 @@ int SecurityBlobLength = sizeof (AUTHENTICATE_MESSAGE); PAUTHENTICATE_MESSAGE SecurityBlob; - cFYI(1, ("\nIn NTLMSSPSessSetup (Authenticate)")); + cFYI(1, ("In NTLMSSPSessSetup (Authenticate)")); smb_buffer = buf_get(); if (smb_buffer == 0) { @@ -1754,12 +1785,12 @@ pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT); pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; pSMB->req.AndXCommand = 0xFF; - pSMB->req.MaxBufferSize = cpu_to_le16(ses->maxBuf); - pSMB->req.MaxMpxCount = cpu_to_le16(ses->maxReq); + pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); + pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq); pSMB->req.hdr.Uid = ses->Suid; - if(ses->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) + if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; pSMB->req.Capabilities = @@ -1948,7 +1979,7 @@ if (pSMBr->resp.Action & GUEST_LOGIN) cFYI(1, (" Guest login")); /* BB do we want to set anything in SesInfo struct ? */ /* if(SecurityBlob2->MessageType != NtLm??){ - cFYI("\nUnexpected message type on auth response is %d ")); + cFYI("Unexpected message type on auth response is %d ")); } */ if (ses) { cFYI(1, @@ -1965,12 +1996,12 @@ bcc_ptr += pSMBr->resp.SecurityBlobLength; cFYI(1, - ("\nSecurity Blob Length %d ", + ("Security Blob Length %d ", pSMBr->resp.SecurityBlobLength)); } cFYI(1, - ("\nNTLMSSP response to Authenticate ")); + ("NTLMSSP response to Authenticate ")); if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) { if ((long) (bcc_ptr) % 2) { @@ -2132,7 +2163,7 @@ bcc_ptr = &(pSMB->Password[0]); bcc_ptr++; /* skip password */ - if(ses->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) + if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; if (ses->capabilities & CAP_STATUS32) { @@ -2162,7 +2193,7 @@ rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length, 0); /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */ - /* above now done in SendReceive */ + /* above now done in SendReceive */ if ((rc == 0) && (tcon != NULL)) { tcon->tid = smb_buffer_response->Tid; bcc_ptr = pByteArea(smb_buffer_response); @@ -2199,7 +2230,7 @@ /* else do not bother copying these informational fields */ } tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport); - cFYI(1, ("\nTcon flags: 0x%x ", tcon->Flags)); + cFYI(1, ("Tcon flags: 0x%x ", tcon->Flags)); } else if ((rc == 0) && tcon == NULL) { /* all we need to save for IPC$ connection */ ses->ipc_tid = smb_buffer_response->Tid; @@ -2228,27 +2259,28 @@ } tconInfoFree(cifs_sb->tcon); if ((ses) && (ses->server)) { - cFYI(1, ("\nAbout to do SMBLogoff ")); + cFYI(1, ("About to do SMBLogoff ")); rc = CIFSSMBLogoff(xid, ses); if (rc == -EBUSY) { - /* BB this looks wrong - why is this here? */ FreeXid(xid); return 0; } + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ / 4); /* give captive thread time to exit */ if((ses->server) && (ses->server->ssocket)) { - cFYI(1,("\nWaking up socket by sending it signal ")); + cFYI(1,("Waking up socket by sending it signal ")); send_sig(SIGINT,ses->server->tsk,1); } } else - cFYI(1, ("\nNo session or bad tcon")); + cFYI(1, ("No session or bad tcon")); } /* BB future check active count of tcon and then free if needed BB */ cifs_sb->tcon = NULL; if (ses) { + set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ / 2); /* if ((ses->server) && (ses->server->ssocket)) { - cFYI(1,("\nReleasing socket ")); + cFYI(1,("Releasing socket ")); sock_release(ses->server->ssocket); kfree(ses->server); } */ diff -Nau linux-2.5.59/fs/cifs/dir.c linux-2.5.59new/fs/cifs/dir.c --- linux-2.5.59/fs/cifs/dir.c Thu Jan 16 20:22:21 2003 +++ linux-2.5.59new/fs/cifs/dir.c Thu Feb 6 02:00:22 2003 @@ -72,7 +72,7 @@ } if (namelen != 0) cERROR(1, - ("\nWe did not end path lookup where we expected namelen is %d", + ("We did not end path lookup where we expected namelen is %d", namelen)); return full_path; @@ -111,7 +111,7 @@ } if (namelen != 0) cERROR(1, - ("\nWe did not end path lookup where we expected namelen is %d", + ("We did not end path lookup where we expected namelen is %d", namelen)); return full_path; @@ -124,7 +124,7 @@ { int rc = -ENOENT; int xid; - int oplock = FALSE; /* no need to oplock when we are not going to read from the file */ + int oplock = REQ_OPLOCK; __u16 fileHandle; struct cifs_sb_info *cifs_sb; struct cifsTconInfo *pTcon; @@ -144,7 +144,7 @@ /* 0x20197 was used previously */ , CREATE_NOT_DIR, &fileHandle, &oplock, cifs_sb->local_nls); if (rc) { - cFYI(1, ("\ncifs_create returned 0x%x ", rc)); + cFYI(1, ("cifs_create returned 0x%x ", rc)); } else { if (pTcon->ses->capabilities & CAP_UNIX) rc = cifs_get_inode_info_unix(&newinode, full_path, @@ -154,14 +154,17 @@ inode->i_sb); if (rc != 0) { - cFYI(1, - ("\nCreate worked but get_inode_info failed with rc = %d ", + cFYI(1,("Create worked but get_inode_info failed with rc = %d", rc)); /* close handle */ } else { direntry->d_op = &cifs_dentry_ops; d_instantiate(direntry, newinode); } + /* BB check oplock state before deciding to call following */ +/* if(*oplock) + save off handle in inode and dontdoclose */ + CIFSSMBClose(xid, pTcon, fileHandle); /* BB In the future chain close with the NTCreateX to narrow window */ @@ -204,7 +207,7 @@ cFYI(1, (" NULL inode in lookup")); } cFYI(1, - (" Full path: %s inode = 0x%p\n", full_path, direntry->d_inode)); + (" Full path: %s inode = 0x%p", full_path, direntry->d_inode)); if (pTcon->ses->capabilities & CAP_UNIX) rc = cifs_get_inode_info_unix(&newInode, full_path, parent_dir_inode->i_sb); @@ -224,7 +227,7 @@ d_add(direntry, NULL); } else { cERROR(1, - ("Error 0x%x or (%d decimal) on cifs_get_inode_info in lookup\n", + ("Error 0x%x or (%d decimal) on cifs_get_inode_info in lookup", rc, rc)); /* BB special case check for Access Denied - watch security exposure of returning dir info implicitly via different rc if file exists or not but no access BB */ } @@ -251,7 +254,7 @@ full_path = build_wildcard_path_from_dentry(file->f_dentry); - cFYI(1, (" inode = 0x%p and full path is %s\n", inode, full_path)); + cFYI(1, (" inode = 0x%p and full path is %s", inode, full_path)); if (full_path) kfree(full_path); @@ -273,7 +276,7 @@ } } else { cFYI(1, - ("In cifs_d_revalidate with no inode but name = %s and dentry 0x%p\n", + ("In cifs_d_revalidate with no inode but name = %s and dentry 0x%p", direntry->d_name.name, direntry)); } @@ -286,7 +289,7 @@ { int rc = 0; - cFYI(1, ("In cifs d_delete, name = %s\n", direntry->d_name.name)); + cFYI(1, ("In cifs d_delete, name = %s", direntry->d_name.name)); return rc; } */ diff -Nau linux-2.5.59/fs/cifs/file.c linux-2.5.59new/fs/cifs/file.c --- linux-2.5.59/fs/cifs/file.c Thu Jan 16 20:21:33 2003 +++ linux-2.5.59new/fs/cifs/file.c Thu Feb 6 02:00:22 2003 @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include "cifsfs.h" @@ -85,9 +86,11 @@ if (file->f_flags & O_CREAT) disposition = FILE_OVERWRITE; + /* BB first check if file has batch oplock (or oplock ?) */ + /* BB finish adding in oplock support BB */ if (oplockEnabled) - oplock = TRUE; + oplock = REQ_OPLOCK; else oplock = FALSE; @@ -95,8 +98,8 @@ rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, cifs_sb->local_nls); if (rc) { - cFYI(1, ("\ncifs_open returned 0x%x ", rc)); - cFYI(1, (" oplock: %d ", oplock)); + cFYI(1, ("cifs_open returned 0x%x ", rc)); + cFYI(1, ("oplock: %d ", oplock)); } else { file->private_data = kmalloc(sizeof (struct cifsFileInfo), GFP_KERNEL); @@ -142,9 +145,7 @@ struct cifs_sb_info *cifs_sb; struct cifsTconInfo *pTcon; struct cifsFileInfo *pSMBFile = - (struct cifsFileInfo *) file->private_data; - - cFYI(1, ("\n inode = 0x%p with ", inode)); + (struct cifsFileInfo *) file->private_data; xid = GetXid(); @@ -172,12 +173,12 @@ struct cifsFileInfo *pSMBFileStruct = (struct cifsFileInfo *) file->private_data; - cFYI(1, ("\nClosedir inode = 0x%p with ", inode)); + cFYI(1, ("Closedir inode = 0x%p with ", inode)); xid = GetXid(); if (pSMBFileStruct) { - cFYI(1, ("\nFreeing private data in close dir")); + cFYI(1, ("Freeing private data in close dir")); kfree(file->private_data); file->private_data = NULL; } @@ -202,42 +203,42 @@ xid = GetXid(); cFYI(1, - ("\nLock parm: 0x%x flockflags: 0x%x flocktype: 0x%x start: %lld end: %lld", + ("Lock parm: 0x%x flockflags: 0x%x flocktype: 0x%x start: %lld end: %lld", cmd, pfLock->fl_flags, pfLock->fl_type, pfLock->fl_start, pfLock->fl_end)); if (pfLock->fl_flags & FL_POSIX) - cFYI(1, ("\nPosix ")); + cFYI(1, ("Posix ")); if (pfLock->fl_flags & FL_FLOCK) - cFYI(1, ("\nFlock ")); + cFYI(1, ("Flock ")); if (pfLock->fl_flags & FL_SLEEP) - cFYI(1, ("\nBlocking lock ")); + cFYI(1, ("Blocking lock ")); if (pfLock->fl_flags & FL_ACCESS) - cFYI(1, ("\nProcess suspended by mandatory locking ")); + cFYI(1, ("Process suspended by mandatory locking ")); if (pfLock->fl_flags & FL_LEASE) - cFYI(1, ("\nLease on file ")); + cFYI(1, ("Lease on file ")); if (pfLock->fl_flags & 0xFFD0) - cFYI(1, ("\n Unknown lock flags ")); + cFYI(1, ("Unknown lock flags ")); if (pfLock->fl_type == F_WRLCK) { - cFYI(1, ("\nF_WRLCK ")); + cFYI(1, ("F_WRLCK ")); numLock = 1; } else if (pfLock->fl_type == F_UNLCK) { - cFYI(1, ("\nF_UNLCK ")); + cFYI(1, ("F_UNLCK ")); numUnlock = 1; } else if (pfLock->fl_type == F_RDLCK) { - cFYI(1, ("\nF_RDLCK ")); + cFYI(1, ("F_RDLCK ")); lockType |= LOCKING_ANDX_SHARED_LOCK; numLock = 1; } else if (pfLock->fl_type == F_EXLCK) { - cFYI(1, ("\nF_EXLCK ")); + cFYI(1, ("F_EXLCK ")); numLock = 1; } else if (pfLock->fl_type == F_SHLCK) { - cFYI(1, ("\nF_SHLCK ")); + cFYI(1, ("F_SHLCK ")); lockType |= LOCKING_ANDX_SHARED_LOCK; numLock = 1; } else - cFYI(1, ("\nUnknown type of lock ")); + cFYI(1, ("Unknown type of lock ")); cifs_sb = CIFS_SB(file->f_dentry->d_sb); pTcon = cifs_sb->tcon; @@ -265,7 +266,7 @@ pfLock->fl_type = F_UNLCK; if (rc != 0) cERROR(1, - ("\nError unlocking previously locked range %d during test of lock ", + ("Error unlocking previously locked range %d during test of lock ", rc)); rc = 0; @@ -304,7 +305,7 @@ pTcon = cifs_sb->tcon; /*cFYI(1, - (" write %d bytes to offset %lld of %s \n", write_size, + (" write %d bytes to offset %lld of %s", write_size, *poffset, file->f_dentry->d_name.name)); */ if (file->private_data == NULL) { @@ -360,6 +361,7 @@ struct inode *inode = page->mapping->host; struct cifsInodeInfo *cifsInode; struct cifsFileInfo *open_file = NULL; + struct list_head *tmp; int xid; xid = GetXid(); @@ -388,25 +390,28 @@ write_data += from; cifsInode = CIFS_I(mapping->host); - if(!list_empty(&(cifsInode->openFileList))) { - open_file = list_entry(cifsInode->openFileList.next, - struct cifsFileInfo, flist); + list_for_each(tmp, &cifsInode->openFileList) { + open_file = list_entry(tmp,struct cifsFileInfo, flist); /* We could check if file is open for writing first */ - if(open_file->pfile) + if((open_file->pfile) && + ((open_file->pfile->f_flags & O_RDWR) || + (open_file->pfile->f_flags & O_WRONLY))) { bytes_written = cifs_write(open_file->pfile, write_data, to-from, &offset); /* Does mm or vfs already set times? */ - inode->i_atime = inode->i_mtime = CURRENT_TIME; - if ((bytes_written > 0) && (offset)) { - rc = 0; - if (offset > inode->i_size) - inode->i_size = offset; - } else if(bytes_written < 0) { - rc = bytes_written; + inode->i_atime = inode->i_mtime = CURRENT_TIME; + if ((bytes_written > 0) && (offset)) { + rc = 0; + if (offset > inode->i_size) + inode->i_size = offset; + mark_inode_dirty_sync(inode); /* is this needed ? */ + } else if(bytes_written < 0) { + rc = bytes_written; + } } - mark_inode_dirty_sync(inode); - } else { - cFYI(1,("\nNo open files to get file handle from")); + } + if(open_file == NULL) { + cFYI(1,("No writeable filehandles for inode")); rc = -EIO; } @@ -415,6 +420,18 @@ } static int +cifs_writepages(struct address_space *mapping, struct writeback_control *wbc) +{ + int rc = -EFAULT; + int xid; + + xid = GetXid(); + + FreeXid(xid); + return rc; +} + +static int cifs_writepage(struct page* page, struct writeback_control *wbc) { int rc = -EFAULT; @@ -483,7 +500,7 @@ /* fill in rpages then result = cifs_pagein_inode(inode, index, rpages); *//* BB finish */ - cFYI(1, ("\nrpages is %d for sync page of Index %ld ", rpages, index)); + cFYI(1, ("rpages is %d for sync page of Index %ld ", rpages, index)); if (rc < 0) return rc; @@ -500,6 +517,7 @@ struct cifs_sb_info *cifs_sb; struct cifsTconInfo *pTcon; int xid; + char * current_offset; xid = GetXid(); cifs_sb = CIFS_SB(file->f_dentry->d_sb); @@ -510,12 +528,13 @@ return -EBADF; } - for (total_read = 0; read_size > total_read; total_read += bytes_read) { + for (total_read = 0,current_offset=read_data; read_size > total_read; + total_read += bytes_read,current_offset+=bytes_read) { rc = CIFSSMBRead(xid, pTcon, ((struct cifsFileInfo *) file-> private_data)->netfid, read_size - total_read, *poffset, - &bytes_read, read_data + total_read); + &bytes_read, ¤t_offset); if (rc || (bytes_read == 0)) { if (total_read) { break; @@ -540,7 +559,7 @@ xid = GetXid(); rc = cifs_revalidate(dentry); if (rc) { - cFYI(1,("Validation prior to mmap failed, error=%d\n", rc)); + cFYI(1,("Validation prior to mmap failed, error=%d", rc)); FreeXid(xid); return rc; } @@ -549,20 +568,129 @@ return rc; } +static void cifs_copy_cache_pages(struct address_space *mapping, struct list_head *pages, + int bytes_read, char *data) +{ + struct page *page; + struct pagevec lru_pvec; + char * target; + + pagevec_init(&lru_pvec, 0); + + while (bytes_read > 0) { + if(list_empty(pages)) + break; + page = list_entry(pages->prev, struct page, list); + + list_del(&page->list); + if (add_to_page_cache(page, mapping, page->index, GFP_KERNEL)) { + page_cache_release(page); + continue; + } + + page_cache_get(page); + target = kmap(page); + + if(PAGE_CACHE_SIZE > bytes_read) { + memcpy(target,data,bytes_read); + bytes_read = 0; + } else { + memcpy(target,data,PAGE_CACHE_SIZE); + bytes_read -= PAGE_CACHE_SIZE; + } + + if (!pagevec_add(&lru_pvec, page)) + __pagevec_lru_add(&lru_pvec); + flush_dcache_page(page); + SetPageUptodate(page); + kunmap(page); + unlock_page(page); + page_cache_release(page); + data += PAGE_CACHE_SIZE; + } + pagevec_lru_add(&lru_pvec); + return; +} + + static int -cifs_readpage(struct file *file, struct page *page) +cifs_readpages(struct file *file, struct address_space *mapping, + struct list_head *page_list, unsigned num_pages) { - loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT; - char * read_data; int rc = -EACCES; + int xid,i; + loff_t offset; + struct page * page; struct cifs_sb_info *cifs_sb; struct cifsTconInfo *pTcon; - int xid; + int bytes_read = 0; + unsigned int read_size; + char * smb_read_data = 0; + struct smb_com_read_rsp * pSMBr; xid = GetXid(); + if (file->private_data == NULL) { + FreeXid(xid); + return -EBADF; + } + cifs_sb = CIFS_SB(file->f_dentry->d_sb); pTcon = cifs_sb->tcon; + for(i = 0;iprev, struct page, list); + offset = (loff_t)page->index << PAGE_CACHE_SHIFT; + /* for reads over a certain size we could initiate async read ahead */ + + cFYI(1,("Read %d pages into cache at offset %ld ",num_pages-i, (unsigned long) offset)); + read_size = (num_pages - i) * PAGE_CACHE_SIZE; + rc = CIFSSMBRead(xid, pTcon, + ((struct cifsFileInfo *) file-> + private_data)->netfid, + read_size, offset, + &bytes_read, &smb_read_data); + + if ((rc < 0) || (smb_read_data == NULL)) { + cFYI(1,("Read error in readpages: %d",rc)); + break; + } 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 */ + + le16_to_cpu(pSMBr->DataOffset)); + i += bytes_read >> PAGE_CACHE_SHIFT; + if((bytes_read & PAGE_CACHE_MASK) != bytes_read) { + cFYI(1,("Partial page %d of %d read into cache",i++,num_pages)); + break; + } + } else { + cFYI(1,("No bytes read")); + break; + } + if(smb_read_data) { + buf_release(smb_read_data); + smb_read_data = 0; + } + bytes_read = 0; + } + FreeXid(xid); + return rc; +} + +static int +cifs_readpage(struct file *file, struct page *page) +{ + loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT; + char * read_data; + int rc = -EACCES; + int xid; + + xid = GetXid(); + if (file->private_data == NULL) { FreeXid(xid); return -EBADF; @@ -576,7 +704,7 @@ if (rc < 0) goto io_error; else { - cFYI(1,("\nBytes read %d ",rc)); + cFYI(1,("Bytes read %d ",rc)); } file->f_dentry->d_inode->i_atime = CURRENT_TIME; @@ -620,7 +748,7 @@ /* should we treat the dos attribute of read-only as read-only mode bit e.g. 555 */ tmp_inode->i_mode = S_IALLUGO & ~(S_ISUID | S_IXGRP); /* 2767 perms - indicate mandatory locking */ cFYI(0, - ("\nCIFS FFIRST: Attributes came in as 0x%x", + ("CIFS FFIRST: Attributes came in as 0x%x", pfindData->ExtFileAttributes)); if (pfindData->ExtFileAttributes & ATTR_REPARSE) { *pobject_type = DT_LNK; @@ -639,9 +767,9 @@ tmp_inode->i_blocks = do_div(pfindData->AllocationSize, tmp_inode->i_blksize); if (pfindData->AllocationSize < pfindData->EndOfFile) - cFYI(1, ("\nServer inconsistency Error: it says allocation size less than end of file ")); + cFYI(1, ("Possible sparse file: allocation size less than end of file ")); cFYI(1, - ("\nCIFS FFIRST: Size %ld and blocks %ld and blocksize %ld", + ("File Size %ld and blocks %ld and blocksize %ld", (unsigned long) tmp_inode->i_size, tmp_inode->i_blocks, tmp_inode->i_blksize)); if (S_ISREG(tmp_inode->i_mode)) { @@ -657,7 +785,7 @@ cFYI(1, (" Symbolic Link inode ")); tmp_inode->i_op = &cifs_symlink_inode_ops; } else { - cFYI(1, ("\nInit special inode ")); + cFYI(1, (" Init special inode ")); init_special_inode(tmp_inode, tmp_inode->i_mode, kdev_t_to_nr(tmp_inode->i_rdev)); } @@ -726,7 +854,7 @@ tmp_inode->i_op = &cifs_symlink_inode_ops; /* tmp_inode->i_fop = *//* do not need to set to anything */ } else { - cFYI(1, ("\nInit special inode ")); + cFYI(1, (" Init special inode ")); init_special_inode(tmp_inode, tmp_inode->i_mode, kdev_t_to_nr(tmp_inode->i_rdev)); } @@ -740,20 +868,20 @@ struct cifs_sb_info *cifs_sb; struct cifsTconInfo *pTcon; - cFYI(1, ("\nFor %s ", qstring->name)); + cFYI(1, ("For %s ", qstring->name)); cifs_sb = CIFS_SB(file->f_dentry->d_sb); pTcon = cifs_sb->tcon; qstring->hash = full_name_hash(qstring->name, qstring->len); tmp_dentry = d_lookup(file->f_dentry, qstring); if (tmp_dentry) { - cFYI(1, (" existing dentry with inode 0x%p ", tmp_dentry->d_inode)); /* BB remove */ + cFYI(1, (" existing dentry with inode 0x%p", tmp_dentry->d_inode)); /* BB remove */ *ptmp_inode = tmp_dentry->d_inode; /* BB overwrite the old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len ?? */ } else { tmp_dentry = d_alloc(file->f_dentry, qstring); *ptmp_inode = new_inode(file->f_dentry->d_sb); - cFYI(1, ("\nAlloc new inode %p ", *ptmp_inode)); + cFYI(1, ("Alloc new inode %p ", *ptmp_inode)); tmp_dentry->d_op = &cifs_dentry_ops; cFYI(1, (" instantiate dentry 0x%p with inode 0x%p ", tmp_dentry, *ptmp_inode)); @@ -763,8 +891,8 @@ tmp_dentry->d_time = jiffies; (*ptmp_inode)->i_blksize = - (pTcon->ses->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00; - cFYI(1, ("\ni_blksize = %ld", (*ptmp_inode)->i_blksize)); + (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00; + cFYI(1, ("i_blksize = %ld", (*ptmp_inode)->i_blksize)); *pnew_dentry = tmp_dentry; } @@ -836,14 +964,14 @@ full_path = build_wildcard_path_from_dentry(file->f_dentry); - cFYI(1, ("\nFull path: %s start at: %lld ", full_path, file->f_pos)); + cFYI(1, ("Full path: %s start at: %lld ", full_path, file->f_pos)); switch ((int) file->f_pos) { case 0: if (filldir (direntry, ".", 1, file->f_pos, file->f_dentry->d_inode->i_ino, DT_DIR) < 0) { - cERROR(1, ("\nFilldir for current dir failed ")); + cERROR(1, ("Filldir for current dir failed ")); break; } file->f_pos++; @@ -852,7 +980,7 @@ if (filldir (direntry, "..", 2, file->f_pos, file->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) { - cERROR(1, ("\nFilldir for parent dir failed ")); + cERROR(1, ("Filldir for parent dir failed ")); break; } file->f_pos++; @@ -957,13 +1085,13 @@ if (file->private_data == NULL) { rc = -EBADF; cFYI(1, - ("\nReaddir on closed srch, pos = %lld", + ("Readdir on closed srch, pos = %lld", file->f_pos)); } else { cifsFile = (struct cifsFileInfo *) file->private_data; if (cifsFile->endOfSearch) { rc = 0; - cFYI(1, ("\nEnd of search ")); + cFYI(1, ("End of search ")); break; } searchHandle = cifsFile->netfid; @@ -1077,6 +1205,7 @@ struct address_space_operations cifs_addr_ops = { .readpage = cifs_readpage, + .readpages = cifs_readpages, .writepage = cifs_writepage, .prepare_write = cifs_prepare_write, .commit_write = cifs_commit_write, @@ -1086,6 +1215,7 @@ /* change over to struct below when sync page tested and complete */ struct address_space_operations cifs_addr_ops2 = { .readpage = cifs_readpage, + .readpages = cifs_readpages, .writepage = cifs_writepage, .prepare_write = cifs_prepare_write, .commit_write = cifs_commit_write, diff -Nau linux-2.5.59/fs/cifs/inode.c linux-2.5.59new/fs/cifs/inode.c --- linux-2.5.59/fs/cifs/inode.c Thu Jan 16 20:21:34 2003 +++ linux-2.5.59new/fs/cifs/inode.c Thu Feb 6 02:00:22 2003 @@ -44,7 +44,7 @@ xid = GetXid(); pTcon = cifs_sb->tcon; - cFYI(1, ("\nGetting info on %s ", search_path)); + cFYI(1, (" Getting info on %s ", search_path)); /* we could have done a find first instead but this returns more info */ rc = CIFSSMBUnixQPathInfo(xid, pTcon, search_path, &findData, cifs_sb->local_nls); @@ -85,7 +85,7 @@ /* get new inode */ if (*pinode == NULL) { *pinode = new_inode(sb); - cFYI(1, ("\nAlloc new inode %p ", *pinode)); + cFYI(1, (" Alloc new inode %p ", *pinode)); } inode = *pinode; /* new_inode = iget(parent_dir_inode->i_sb, findData.IndexNumber); */ @@ -93,7 +93,7 @@ cifsInfo = CIFS_I(inode); - cFYI(1, ("\nOld time %ld ", cifsInfo->time)); + cFYI(1, (" Old time %ld ", cifsInfo->time)); cifsInfo->time = jiffies; cFYI(1, (" New time %ld ", cifsInfo->time)); atomic_inc(&cifsInfo->inUse); /* inc on every refresh of inode */ @@ -129,12 +129,12 @@ findData.EndOfFile = le64_to_cpu(findData.EndOfFile); inode->i_size = findData.EndOfFile; inode->i_blksize = - (pTcon->ses->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00; + (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00; inode->i_blocks = do_div(findData.NumOfBytes, inode->i_blksize); if (findData.NumOfBytes < findData.EndOfFile) - cFYI(1, ("\nServer inconsistency Error: it says allocation size less than end of file ")); + cFYI(1, ("Server inconsistency Error: it says allocation size less than end of file ")); cFYI(1, - ("\nCIFS FFIRST: Size %ld and blocks %ld ", + ("CIFS FFIRST: Size %ld and blocks %ld ", (unsigned long) inode->i_size, inode->i_blocks)); if (S_ISREG(inode->i_mode)) { cFYI(1, (" File inode ")); @@ -150,7 +150,7 @@ inode->i_op = &cifs_symlink_inode_ops; /* tmp_inode->i_fop = *//* do not need to set to anything */ } else { - cFYI(1, ("\nInit special inode ")); + cFYI(1, (" Init special inode ")); init_special_inode(inode, inode->i_mode, kdev_t_to_nr(inode->i_rdev)); } @@ -174,7 +174,7 @@ xid = GetXid(); pTcon = cifs_sb->tcon; - cFYI(1, ("\nGetting info on %s ", search_path)); + cFYI(1, (" Getting info on %s ", search_path)); /* we could have done a find first instead but this returns more info */ rc = CIFSSMBQPathInfo(xid, pTcon, search_path, &findData, cifs_sb->local_nls); @@ -214,20 +214,20 @@ /* get new inode */ if (*pinode == NULL) { *pinode = new_inode(sb); - cFYI(1, ("\nAlloc new inode %p ", *pinode)); + cFYI(1, (" Alloc new inode %p ", *pinode)); } inode = *pinode; cifsInfo = CIFS_I(inode); findData.Attributes = le32_to_cpu(findData.Attributes); cifsInfo->cifsAttrs = findData.Attributes; - cFYI(1, ("\nOld time %ld ", cifsInfo->time)); + cFYI(1, (" Old time %ld ", cifsInfo->time)); cifsInfo->time = jiffies; cFYI(1, (" New time %ld ", cifsInfo->time)); atomic_inc(&cifsInfo->inUse); /* inc on every refresh of inode */ inode->i_blksize = - (pTcon->ses->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00; + (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00; /* Linux can not store file creation time unfortunately so we ignore it */ inode->i_atime = cifs_NTtimeToUnix(le64_to_cpu(findData.LastAccessTime)); @@ -239,7 +239,7 @@ /* should we treat the dos attribute of read-only as read-only mode bit e.g. 555 */ inode->i_mode = S_IALLUGO & ~(S_ISUID | S_IXGRP); /* 2767 perms indicate mandatory locking - will override for dirs later */ cFYI(0, - ("\nAttributes came in as 0x%x\n", findData.Attributes)); + (" Attributes came in as 0x%x ", findData.Attributes)); if (findData.Attributes & ATTR_REPARSE) { /* Can IFLNK be set as it basically is on windows with IFREG or IFDIR? */ inode->i_mode |= S_IFLNK; @@ -256,7 +256,7 @@ inode->i_blocks = do_div(findData.AllocationSize, inode->i_blksize); cFYI(1, - ("\n Size %ld and blocks %ld ", + (" Size %ld and blocks %ld ", (unsigned long) inode->i_size, inode->i_blocks)); inode->i_nlink = le32_to_cpu(findData.NumberOfLinks); @@ -307,7 +307,7 @@ char *full_path = NULL; struct cifsInodeInfo *cifsInode; - cFYI(1, ("\n cifs_unlink, inode = 0x%p with ", inode)); + cFYI(1, (" cifs_unlink, inode = 0x%p with ", inode)); xid = GetXid(); @@ -356,7 +356,7 @@ char *full_path = NULL; struct inode *newinode = NULL; - cFYI(1, ("In cifs_mkdir, mode = 0x%x inode = 0x%p\n", mode, inode)); + cFYI(1, ("In cifs_mkdir, mode = 0x%x inode = 0x%p ", mode, inode)); xid = GetXid(); @@ -367,7 +367,7 @@ /* BB add setting the equivalent of mode via CreateX w/ACLs */ rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls); if (rc) { - cFYI(1, ("\ncifs_mkdir returned 0x%x ", rc)); + cFYI(1, ("cifs_mkdir returned 0x%x ", rc)); } else { inode->i_nlink++; if (pTcon->ses->capabilities & CAP_UNIX) @@ -407,7 +407,7 @@ char *full_path = NULL; struct cifsInodeInfo *cifsInode; - cFYI(1, ("\nn cifs_rmdir, inode = 0x%p with ", inode)); + cFYI(1, (" cifs_rmdir, inode = 0x%p with ", inode)); xid = GetXid(); @@ -493,7 +493,7 @@ full_path = build_path_from_dentry(direntry); cFYI(1, - (" full path: %s for inode 0x%p with count %d dentry: 0x%p d_time %ld at time %ld \n", + (" full path: %s for inode 0x%p with count %d dentry: 0x%p d_time %ld at time %ld ", full_path, direntry->d_inode, direntry->d_inode->i_count.counter, direntry, direntry->d_time, jiffies)); @@ -562,7 +562,7 @@ full_path = build_path_from_dentry(dirent); rc = CIFSSMBSetEOF(xid, pTcon, full_path, inode->i_size,FALSE, cifs_sb->local_nls); - cFYI(1,("\nSetEOF (truncate) rc = %d",rc)); + cFYI(1,(" SetEOF (truncate) rc = %d",rc)); if(rc == -ETXTBSY) { cifsInode = CIFS_I(inode); if(!list_empty(&(cifsInode->openFileList))) { @@ -572,7 +572,7 @@ rc = CIFSSMBSetFileSize(xid, pTcon, inode->i_size, open_file->netfid,open_file->pid,FALSE); } else { - cFYI(1,("\nNo open files to get file handle from")); + cFYI(1,(" No open files to get file handle from")); } } if (!rc) @@ -604,7 +604,7 @@ xid = GetXid(); cFYI(1, - ("\nIn cifs_setattr, name = %s attrs->iavalid 0x%x\n", + (" In cifs_setattr, name = %s attrs->iavalid 0x%x ", direntry->d_name.name, attrs->ia_valid)); cifs_sb = CIFS_SB(direntry->d_inode->i_sb); pTcon = cifs_sb->tcon; @@ -614,12 +614,12 @@ /* BB check if we need to refresh inode from server now ? BB */ - cFYI(1, ("\nChanging attributes 0x%x", attrs->ia_valid)); + cFYI(1, (" Changing attributes 0x%x", attrs->ia_valid)); if (attrs->ia_valid & ATTR_SIZE) { rc = CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size,FALSE, cifs_sb->local_nls); - cFYI(1,("\nSetEOF (setattrs) rc = %d",rc)); + cFYI(1,(" SetEOF (setattrs) rc = %d",rc)); if(rc == -ETXTBSY) { if(!list_empty(&(cifsInode->openFileList))) { @@ -629,7 +629,7 @@ rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, open_file->netfid,open_file->pid,FALSE); } else { - cFYI(1,("\nNo open files to get file handle from")); + cFYI(1,(" No open files to get file handle from")); } } /* Set Allocation Size of file - might not even need to call the @@ -641,17 +641,17 @@ by calling SetFileInfo to set the sizes */ } if (attrs->ia_valid & ATTR_UID) { - cFYI(1, ("\nCIFS - UID changed to %d", attrs->ia_uid)); + cFYI(1, (" CIFS - UID changed to %d", attrs->ia_uid)); uid = attrs->ia_uid; /* entry->uid = cpu_to_le16(attr->ia_uid); */ } if (attrs->ia_valid & ATTR_GID) { - cFYI(1, ("\nCIFS - GID changed to %d", attrs->ia_gid)); + cFYI(1, (" CIFS - GID changed to %d", attrs->ia_gid)); gid = attrs->ia_gid; /* entry->gid = cpu_to_le16(attr->ia_gid); */ } if (attrs->ia_valid & ATTR_MODE) { - cFYI(1, ("\nCIFS - Mode changed to 0x%x", attrs->ia_mode)); + cFYI(1, (" CIFS - Mode changed to 0x%x", attrs->ia_mode)); mode = attrs->ia_mode; /* entry->mode = cpu_to_le16(attr->ia_mode); */ } @@ -680,7 +680,7 @@ if (attrs->ia_valid & ATTR_CTIME) { set_time = TRUE; - cFYI(1, ("\nCIFS - CTIME changed ")); /* BB probably do not need */ + cFYI(1, (" CIFS - CTIME changed ")); /* BB probably do not need */ time_buf.ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime)); } else @@ -707,7 +707,7 @@ cifs_delete_inode(struct inode *inode) { /* Note: called without the big kernel filelock - remember spinlocks! */ - cFYI(1, ("In cifs_delete_inode, inode = 0x%p\n", inode)); + cFYI(1, ("In cifs_delete_inode, inode = 0x%p ", inode)); /* may have to add back in when safe distributed caching of directories via e.g. FindNotify added */ } diff -Nau linux-2.5.59/fs/cifs/link.c linux-2.5.59new/fs/cifs/link.c --- linux-2.5.59/fs/cifs/link.c Thu Jan 16 20:21:49 2003 +++ linux-2.5.59new/fs/cifs/link.c Thu Feb 6 02:00:22 2003 @@ -88,7 +88,7 @@ xid = GetXid(); full_path = build_path_from_dentry(direntry); - cFYI(1, ("\nFull path: %s inode = 0x%p\n", full_path, inode)); + cFYI(1, ("Full path: %s inode = 0x%p", full_path, inode)); cifs_sb = CIFS_SB(inode->i_sb); pTcon = cifs_sb->tcon; @@ -136,8 +136,8 @@ pTcon = cifs_sb->tcon; full_path = build_path_from_dentry(direntry); - cFYI(1, ("\nFull path: %s ", full_path)); - cFYI(1, (" symname is %s\n", symname)); + cFYI(1, ("Full path: %s ", full_path)); + cFYI(1, ("symname is %s", symname)); /* BB what if DFS and this volume is on different share? BB */ if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) @@ -156,7 +156,7 @@ if (rc != 0) { cFYI(1, - ("\nCreate symlink worked but get_inode_info failed with rc = %d ", + ("Create symlink worked but get_inode_info failed with rc = %d ", rc)); } else { direntry->d_op = &cifs_dentry_ops; @@ -188,7 +188,7 @@ pTcon = cifs_sb->tcon; full_path = build_path_from_dentry(direntry); cFYI(1, - ("\nFull path: %s inode = 0x%p pBuffer = 0x%p buflen = %d\n", + ("Full path: %s inode = 0x%p pBuffer = 0x%p buflen = %d", full_path, inode, pBuffer, buflen)); /* BB add read reparse point symlink code and Unix extensions symlink code here BB */ diff -Nau linux-2.5.59/fs/cifs/misc.c linux-2.5.59new/fs/cifs/misc.c --- linux-2.5.59/fs/cifs/misc.c Thu Jan 16 20:22:46 2003 +++ linux-2.5.59new/fs/cifs/misc.c Thu Feb 6 02:00:22 2003 @@ -81,7 +81,7 @@ sesInfoFree(struct cifsSesInfo *buf_to_free) { if (buf_to_free == NULL) { - cFYI(1, ("\nNull buffer passed to sesInfoFree")); + cFYI(1, ("Null buffer passed to sesInfoFree")); return; } @@ -122,7 +122,7 @@ tconInfoFree(struct cifsTconInfo *buf_to_free) { if (buf_to_free == NULL) { - cFYI(1, ("\nNull buffer passed to tconInfoFree")); + cFYI(1, ("Null buffer passed to tconInfoFree")); return; } write_lock(&GlobalSMBSeslock); @@ -169,7 +169,7 @@ { if (buf_to_free == NULL) { - cFYI(1, ("\nNull buffer passed to buf_release")); + cFYI(1, ("Null buffer passed to buf_release")); return; } kmem_cache_free(cifs_req_cachep, buf_to_free); @@ -225,8 +225,10 @@ } if (treeCon->Flags & SMB_SHARE_IS_IN_DFS) buffer->Flags2 |= SMBFLG2_DFS; - if(treeCon->ses->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) - buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; + if(treeCon->ses->server) + if(treeCon->ses->server->secMode & + (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) + buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; } /* endian conversion of flags is now done just before sending */ @@ -248,17 +250,17 @@ if(smb->Command == SMB_COM_LOCKING_ANDX) return 0; else - cERROR(1, ("\n Rcvd Request not response ")); + cERROR(1, ("Rcvd Request not response ")); } } else { /* bad signature or mid */ if (*(unsigned int *) smb->Protocol != cpu_to_le32(0x424d53ff)) cERROR(1, - ("\nBad protocol string signature header %x ", + ("Bad protocol string signature header %x ", *(unsigned int *) smb->Protocol)); if (mid != smb->Mid) - cERROR(1, ("\n Mids do not match \n")); + cERROR(1, ("Mids do not match")); } - cERROR(1, ("\nCIFS: bad smb detected. The Mid=%d\n", smb->Mid)); + cERROR(1, ("bad smb detected. The Mid=%d", smb->Mid)); return 1; } @@ -266,13 +268,13 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length) { cFYI(0, - ("\nEntering checkSMB with Length: %x, smb_buf_length: %x ", + ("Entering checkSMB with Length: %x, smb_buf_length: %x ", length, ntohl(smb->smb_buf_length))); if ((length < 2 + sizeof (struct smb_hdr)) || (4 + ntohl(smb->smb_buf_length) > CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE)) { if (length < 2 + sizeof (struct smb_hdr)) { - cERROR(1, ("\n Length less than 2 + sizeof smb_hdr ")); + cERROR(1, ("Length less than 2 + sizeof smb_hdr ")); if ((length >= sizeof (struct smb_hdr) - 1) && (smb->Status.CifsError != 0)) return 0; /* some error cases do not return wct and bcc */ @@ -281,9 +283,9 @@ if (4 + ntohl(smb->smb_buf_length) > CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE) cERROR(1, - ("\n smb_buf_length greater than CIFS_MAX_MSGSIZE ... ")); + ("smb_buf_length greater than CIFS_MAX_MSGSIZE ... ")); cERROR(1, - ("CIFS: bad smb detected. Illegal length. The mid=%d\n", + ("bad smb detected. Illegal length. The mid=%d", smb->Mid)); return 1; } @@ -295,51 +297,60 @@ || (4 + ntohl(smb->smb_buf_length) != length)) { return 0; } else { - cERROR(1, ("\nCIFS: smbCalcSize %x ", smbCalcSize(smb))); + cERROR(1, ("smbCalcSize %x ", smbCalcSize(smb))); cERROR(1, - ("CIFS: bad smb size detected. The Mid=%d\n", smb->Mid)); + ("bad smb size detected. The Mid=%d", smb->Mid)); return 1; } } int is_valid_oplock_break(struct smb_hdr *buf) { - struct smb_com_lock_req * pSMB = (struct smb_com_lock_req *)buf; - struct list_head *tmp; - struct cifsTconInfo *tcon; - - /* could add check for smb response flag 0x80 */ - cFYI(1,("\nChecking for oplock break")); - if(pSMB->hdr.Command != SMB_COM_LOCKING_ANDX) - return FALSE; - if(pSMB->hdr.Flags & SMBFLG_RESPONSE) - return FALSE; /* server sends us "request" here */ - if(pSMB->hdr.WordCount != 8) - return FALSE; - - cFYI(1,(" oplock type 0x%d level 0x%d",pSMB->LockType,pSMB->OplockLevel)); - if(!(pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE)) - return FALSE; - - /* look up tcon based on tid & uid */ - read_lock(&GlobalSMBSeslock); - list_for_each(tmp, &GlobalTreeConnectionList) { - tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); - if (tcon->tid == buf->Tid) - if(tcon->ses->Suid == buf->Uid) { - /* BB Add following logic: - 2) look up inode from tcon->openFileList->file->f_dentry->d_inode - 3) flush dirty pages and cached byte range locks and mark inode - 4) depending on break type change to r/o caching or no caching - 5) send oplock break response to server */ - read_unlock(&GlobalSMBSeslock); - cFYI(1,("\nFound matching connection, process oplock break")); - return TRUE; - } - } - read_unlock(&GlobalSMBSeslock); - cFYI(1,("\nProcessing oplock break for non-existent connection")); - return TRUE; + struct smb_com_lock_req * pSMB = (struct smb_com_lock_req *)buf; + struct list_head *tmp; + struct list_head *tmp1; + struct cifsTconInfo *tcon; + struct cifsFileInfo *netfile; + + /* could add check for smb response flag 0x80 */ + cFYI(1,("Checking for oplock break")); + if(pSMB->hdr.Command != SMB_COM_LOCKING_ANDX) + return FALSE; + if(pSMB->hdr.Flags & SMBFLG_RESPONSE) + return FALSE; /* server sends us "request" here */ + if(pSMB->hdr.WordCount != 8) + return FALSE; + + cFYI(1,(" oplock type 0x%d level 0x%d",pSMB->LockType,pSMB->OplockLevel)); + if(!(pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE)) + return FALSE; + + /* look up tcon based on tid & uid */ + read_lock(&GlobalSMBSeslock); + list_for_each(tmp, &GlobalTreeConnectionList) { + tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); + if (tcon->tid == buf->Tid) { + list_for_each(tmp1,&tcon->openFileList){ + netfile = list_entry(tmp1,struct cifsFileInfo,tlist); + if(pSMB->Fid == netfile->netfid) { + /* BB Add following logic: + 2) look up inode from tcon->openFileList->file->f_dentry->d_inode + 3) flush dirty pages and cached byte range locks and mark inode + 4) depending on break type change to r/o caching or no caching + 5) send oplock break response to server */ + read_unlock(&GlobalSMBSeslock); + cFYI(1,("Matching file id, processing oplock break")); + return TRUE; + } + } + read_unlock(&GlobalSMBSeslock); + cFYI(1,("No matching file for oplock break on connection")); + return TRUE; + } + } + read_unlock(&GlobalSMBSeslock); + cFYI(1,("Can not process oplock break for non-existent connection")); + return TRUE; } void @@ -355,7 +366,7 @@ buffer = (unsigned char *) smb_buf; for (i = 0, j = 0; i < smb_buf_length; i++, j++) { if (i % 8 == 0) { /* we have reached the beginning of line */ - printk("\n| "); + printk(KERN_DEBUG "| "); j = 0; } printk("%0#4x ", buffer[i]); @@ -367,7 +378,7 @@ if (i % 8 == 7) { /* we have reached end of line, time to print ascii */ debug_line[16] = 0; - printk(" | %s", debug_line); + printk(" | %s\n", debug_line); } } for (; j < 8; j++) { @@ -375,6 +386,6 @@ debug_line[2 * j] = ' '; debug_line[1 + (2 * j)] = ' '; } - printk(" | %s\n", debug_line); + printk( " | %s\n", debug_line); return; } diff -Nau linux-2.5.59/fs/cifs/netmisc.c linux-2.5.59new/fs/cifs/netmisc.c --- linux-2.5.59/fs/cifs/netmisc.c Thu Jan 16 20:22:42 2003 +++ linux-2.5.59new/fs/cifs/netmisc.c Thu Feb 6 02:00:22 2003 @@ -753,12 +753,11 @@ { int idx = 0; - printk("\nStatus code returned: 0x%08x ", status_code); - while (nt_errs[idx].nt_errstr != NULL) { if (((nt_errs[idx].nt_errcode) & 0xFFFFFF) == (status_code & 0xFFFFFF)) { - printk(nt_errs[idx].nt_errstr); + printk(KERN_NOTICE "Status code returned 0x%08x %s\n", + status_code,nt_errs[idx].nt_errstr); } idx++; } @@ -815,11 +814,8 @@ } /* old style errors */ - cFYI(1, (" !!Mapping smb error code %d ", smberrcode)); - /* DOS class smb error codes - map DOS */ - - /* BB special case reconnect tid and reconnect uid here? */ + /* DOS class smb error codes - map DOS */ if (smberrclass == ERRDOS) { /* one byte field no need to byte reverse */ for (i = 0; i < @@ -849,10 +845,7 @@ } /* else ERRHRD class errors or junk - return EIO */ - /* BB get smb->error_class and code lookup in table if ERR_STATUS is not - set in this frame else translate newer NT Status code - in both cases - change to equivalent posix error BB */ - cFYI(1, (" to POSIX err %d !!", rc)); + cFYI(1, (" !!Mapping smb error code %d to POSIX err %d !!", smberrcode,rc)); /* generic corrective action e.g. reconnect SMB session on ERRbaduid could be added */ diff -Nau linux-2.5.59/fs/cifs/smbencrypt.c linux-2.5.59new/fs/cifs/smbencrypt.c --- linux-2.5.59/fs/cifs/smbencrypt.c Thu Jan 16 20:22:09 2003 +++ linux-2.5.59new/fs/cifs/smbencrypt.c Thu Feb 6 02:00:22 2003 @@ -305,7 +305,7 @@ if (new_pw_len > 512) { cERROR(1, - ("CIFS make_oem_passwd_hash: new password is too long.\n")); + ("CIFS make_oem_passwd_hash: new password is too long.")); return FALSE; } diff -Nau linux-2.5.59/fs/cifs/transport.c linux-2.5.59new/fs/cifs/transport.c --- linux-2.5.59/fs/cifs/transport.c Thu Jan 16 20:21:49 2003 +++ linux-2.5.59new/fs/cifs/transport.c Thu Feb 6 02:00:22 2003 @@ -40,10 +40,9 @@ /* BB add spinlock to protect midq for each session BB */ if (ses == NULL) { - cERROR(1, ("\nNull session passed in to AllocMidQEntry ")); + cERROR(1, ("Null session passed in to AllocMidQEntry ")); return NULL; } - temp = kmalloc(sizeof (struct mid_q_entry), GFP_KERNEL); temp = (struct mid_q_entry *) kmem_cache_alloc(cifs_mid_cachep, SLAB_KERNEL); if (temp == NULL) @@ -53,21 +52,19 @@ temp->mid = smb_buffer->Mid; /* always LE */ temp->pid = current->pid; temp->command = smb_buffer->Command; - cFYI(1, ("\nFor smb_command %d", temp->command)); + cFYI(1, ("For smb_command %d", temp->command)); do_gettimeofday(&temp->when_sent); temp->ses = ses; temp->tsk = current; } - if (ses->status == CifsGood) { + if (ses->server->tcpStatus == CifsGood) { write_lock(&GlobalMid_Lock); list_add_tail(&temp->qhead, &ses->server->pending_mid_q); atomic_inc(&midCount); temp->midState = MID_REQUEST_ALLOCATED; write_unlock(&GlobalMid_Lock); - } else { /* BB add reconnect code here BB */ - - cERROR(1, - ("\nNeed to reconnect after session died to server\n")); + } else { /* could add more reconnect code here BB */ + cERROR(1,("Need to reconnect after session died to server")); if (temp) kmem_cache_free(cifs_mid_cachep, temp); return NULL; @@ -121,7 +118,7 @@ sign_smb(smb_buffer); */ /* BB enable when signing tested more */ smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length); - cFYI(1, ("\nSending smb of length %d ", smb_buf_length)); + cFYI(1, ("Sending smb of length %d ", smb_buf_length)); dump_smb(smb_buffer, smb_buf_length + 4); temp_fs = get_fs(); /* we must turn off socket api parm checking */ @@ -132,7 +129,7 @@ if (rc < 0) { cERROR(1, - ("\nError %d sending data on socket to server.\n", rc)); + ("Error %d sending data on socket to server.", rc)); } else rc = 0; @@ -154,7 +151,7 @@ return -EIO; /* reconnect should be done, if possible, in AllocMidQEntry */ if (in_buf->smb_buf_length > CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE) { cERROR(1, - ("\nIllegal length, greater than maximum frame, %d ", + ("Illegal length, greater than maximum frame, %d ", in_buf->smb_buf_length)); DeleteMidQEntry(midQ); return -EIO; @@ -163,27 +160,21 @@ rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length, (struct sockaddr *) &(ses->server->sockAddr)); - if (long_op > 1) /* writes past end of file can take a looooooong time */ + if (long_op > 1) /* writes past end of file can take looooong time */ timeout = 300 * HZ; else if (long_op == 1) timeout = 60 * HZ; else timeout = 15 * HZ; - /* wait for 15 seconds or until woken up due to response arriving or due to - last connection to this server being unmounted */ - - /* timeout = interruptible_sleep_on_timeout(&ses->server->response_q,timeout); */ - /* Replace above line with wait_event to get rid of sleep_on per lk guidelines */ + /* wait for 15 seconds or until woken up due to response arriving or + due to last connection to this server being unmounted */ timeout = wait_event_interruptible_timeout(ses->server->response_q, midQ-> midState & MID_RESPONSE_RECEIVED, timeout); - cFYI(1, - (" with timeout %ld and Out_buf: %p midQ->resp_buf: %p ", timeout, - out_buf, midQ->resp_buf)); if (signal_pending(current)) { - cERROR(1, (KERN_ERR "\nCIFS: caught signal")); + cERROR(1, ("CIFS: caught signal")); DeleteMidQEntry(midQ); return -EINTR; } else { @@ -198,11 +189,11 @@ if (timeout == 0) { cFYI(1, - ("\nTimeout on receive. Assume response SMB is invalid.\n")); + ("Timeout on receive. Assume response SMB is invalid.")); rc = -ETIMEDOUT; } else if (receive_len > CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE) { cERROR(1, - ("\nFrame too large received. Length: %d Xid: %d\n", + ("Frame too large received. Length: %d Xid: %d", receive_len, xid)); rc = -EIO; } else { /* rcvd frame is ok */ @@ -215,7 +206,7 @@ /* convert the length back to a form that we can use */ dump_smb(out_buf, 92); - + cFYI(0,("Copied length %d to %p from %p",receive_len+4,out_buf,midQ->resp_buf)); /* BB remove */ out_buf->smb_buf_length = be32_to_cpu(out_buf->smb_buf_length); if (out_buf->smb_buf_length > 12)