Commit 8fde121d authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://cifs.bkbits.net/linux-2.5cifs

into home.transmeta.com:/home/torvalds/v2.5/linux
parents b6ab3b3d b668ec86
Version 0.65
------------
Finish fixes to commit write for caching/readahead consistency. fsx
now works to Samba servers. Fix oops caused when readahead
was interrupted by a signal.
Version 0.64
------------
Fix data corruption (in partial page after truncate) that caused fsx to
fail to Windows servers. Cleaned up some extraneous error logging in
common error paths. Add generic sendfile support.
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 username 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 Version 0.60
------------ ------------
Fix oops in readpages caused by not setting address space operations in inode in Fix oops in readpages caused by not setting address space operations in inode in
......
version 0.5.3 October 8th, 2002 version 0.6.5 February 15, 2003
A Partial List of Known Problems and Missing Features A Partial List of Known Problems and Missing Features
===================================================== =====================================================
...@@ -7,7 +7,8 @@ Contributions are welcome. There are plenty of opportunities ...@@ -7,7 +7,8 @@ Contributions are welcome. There are plenty of opportunities
for visible, important contributions to this module. Here for visible, important contributions to this module. Here
is a partial list of the known problems and missing features: 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 b) Better pam/winbind integration
...@@ -16,9 +17,9 @@ c) multi-user mounts - multiplexed sessionsetups over single vc ...@@ -16,9 +17,9 @@ c) multi-user mounts - multiplexed sessionsetups over single vc
d) Kerberos/SPNEGO session setup support - (started) 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. f) oplock support (ie safe CIFS distributed file caching) is not quite complete.
In addition Directory entry caching relies on a 1 second timer, rather than In addition Directory entry caching relies on a 1 second timer, rather than
using FindNotify or equivalent. - (started) using FindNotify or equivalent. - (started)
...@@ -28,27 +29,34 @@ of recent 2.5 kernel improvements in byte-range locking ...@@ -28,27 +29,34 @@ of recent 2.5 kernel improvements in byte-range locking
h) quota support h) quota support
i) support for the Linux 2.5 kernel new feature get_xattr and set_xattr 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) 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 February 15, 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 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 support the CIFS Unix extensions but Samba has a bug currently handling
symlink text beginning with slash symlink text beginning with slash
2) delete of file with read-only attribute set will fail (may be ok) 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
the size being reported as exactly 4k.
Misc testing to do Misc testing to do
================= =================
1) check out max path names and max path name components against various server 1) check out max path names and max path name components against various server
types. 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
...@@ -458,16 +458,18 @@ decode_negTokenInit(unsigned char *security_blob, int length, ...@@ -458,16 +458,18 @@ decode_negTokenInit(unsigned char *security_blob, int length,
unsigned int cls, con, tag, oidlen, rc; unsigned int cls, con, tag, oidlen, rc;
int use_ntlmssp = FALSE; int use_ntlmssp = FALSE;
*secType = NTLM; /* BB eventually make Kerberos or NLTMSSP the default */
/* cifs_dump_mem(" Received SecBlob ", security_blob, length); */ /* cifs_dump_mem(" Received SecBlob ", security_blob, length); */
asn1_open(&ctx, security_blob, length); asn1_open(&ctx, security_blob, length);
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
cFYI(1, ("\nError decoding negTokenInit header ")); cFYI(1, ("Error decoding negTokenInit header "));
return 0; return 0;
} else if ((cls != ASN1_APL) || (con != ASN1_CON) } else if ((cls != ASN1_APL) || (con != ASN1_CON)
|| (tag != ASN1_EOC)) { || (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; return 0;
} else { } else {
/* remember to free obj->oid */ /* remember to free obj->oid */
...@@ -486,51 +488,49 @@ decode_negTokenInit(unsigned char *security_blob, int length, ...@@ -486,51 +488,49 @@ decode_negTokenInit(unsigned char *security_blob, int length,
} }
if (!rc) { if (!rc) {
cFYI(1, ("\nError decoding negTokenInit header")); cFYI(1, ("Error decoding negTokenInit header"));
return 0; return 0;
} }
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
cFYI(1, ("\nError decoding negTokenInit ")); cFYI(1, ("Error decoding negTokenInit "));
return 0; return 0;
} else if ((cls != ASN1_CTX) || (con != ASN1_CON) } else if ((cls != ASN1_CTX) || (con != ASN1_CON)
|| (tag != ASN1_EOC)) { || (tag != ASN1_EOC)) {
cFYI(1, cFYI(1,("cls = %d con = %d tag = %d end = %p (%d) exit 0",
("\ncls = %d con = %d tag = %d end = %p (%d) exit 0",
cls, con, tag, end, *end)); cls, con, tag, end, *end));
return 0; return 0;
} }
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
cFYI(1, ("\nError decoding negTokenInit ")); cFYI(1, ("Error decoding negTokenInit "));
return 0; return 0;
} else if ((cls != ASN1_UNI) || (con != ASN1_CON) } else if ((cls != ASN1_UNI) || (con != ASN1_CON)
|| (tag != ASN1_SEQ)) { || (tag != ASN1_SEQ)) {
cFYI(1, cFYI(1,("cls = %d con = %d tag = %d end = %p (%d) exit 1",
("\ncls = %d con = %d tag = %d end = %p (%d) exit 1",
cls, con, tag, end, *end)); cls, con, tag, end, *end));
return 0; return 0;
} }
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 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; return 0;
} else if ((cls != ASN1_CTX) || (con != ASN1_CON) } else if ((cls != ASN1_CTX) || (con != ASN1_CON)
|| (tag != ASN1_EOC)) { || (tag != ASN1_EOC)) {
cFYI(1, 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)); cls, con, tag, end, *end));
return 0; return 0;
} }
if (asn1_header_decode if (asn1_header_decode
(&ctx, &sequence_end, &cls, &con, &tag) == 0) { (&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; return 0;
} else if ((cls != ASN1_UNI) || (con != ASN1_CON) } else if ((cls != ASN1_UNI) || (con != ASN1_CON)
|| (tag != ASN1_SEQ)) { || (tag != ASN1_SEQ)) {
cFYI(1, 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)); cls, con, tag, end, *end));
return 0; return 0;
} }
...@@ -539,13 +539,13 @@ decode_negTokenInit(unsigned char *security_blob, int length, ...@@ -539,13 +539,13 @@ decode_negTokenInit(unsigned char *security_blob, int length,
rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag); rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag);
if (!rc) { if (!rc) {
cFYI(1, cFYI(1,
("\nError 1 decoding negTokenInit header exit 2")); ("Error 1 decoding negTokenInit header exit 2"));
return 0; return 0;
} }
if ((tag == ASN1_OJI) && (con == ASN1_PRI)) { if ((tag == ASN1_OJI) && (con == ASN1_PRI)) {
asn1_oid_decode(&ctx, end, &oid, &oidlen); asn1_oid_decode(&ctx, end, &oid, &oidlen);
cFYI(1, 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), oidlen, *oid, *(oid + 1), *(oid + 2),
*(oid + 3))); *(oid + 3)));
rc = compare_oid(oid, oidlen, NTLMSSP_OID, rc = compare_oid(oid, oidlen, NTLMSSP_OID,
...@@ -554,54 +554,53 @@ decode_negTokenInit(unsigned char *security_blob, int length, ...@@ -554,54 +554,53 @@ decode_negTokenInit(unsigned char *security_blob, int length,
if (rc) if (rc)
use_ntlmssp = TRUE; use_ntlmssp = TRUE;
} else { } else {
cFYI(1, cFYI(1,("This should be an oid what is going on? "));
("\nThis should be an oid what is going on? "));
} }
} }
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
cFYI(1, cFYI(1,
("\nError decoding last part of negTokenInit exit 3")); ("Error decoding last part of negTokenInit exit 3"));
return 0; return 0;
} else if ((cls != ASN1_CTX) || (con != ASN1_CON)) { /* tag = 3 indicating mechListMIC */ } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) { /* tag = 3 indicating mechListMIC */
cFYI(1, 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)); cls, con, tag, end, *end));
return 0; return 0;
} }
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
cFYI(1, cFYI(1,
("\nError decoding last part of negTokenInit exit 5")); ("Error decoding last part of negTokenInit exit 5"));
return 0; return 0;
} else if ((cls != ASN1_UNI) || (con != ASN1_CON) } else if ((cls != ASN1_UNI) || (con != ASN1_CON)
|| (tag != ASN1_SEQ)) { || (tag != ASN1_SEQ)) {
cFYI(1, 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)); cls, con, tag, end, *end));
} }
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
cFYI(1, cFYI(1,
("\nError decoding last part of negTokenInit exit 7")); ("Error decoding last part of negTokenInit exit 7"));
return 0; return 0;
} else if ((cls != ASN1_CTX) || (con != ASN1_CON)) { } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) {
cFYI(1, 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)); cls, con, tag, end, *end));
return 0; return 0;
} }
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
cFYI(1, cFYI(1,
("\nError decoding last part of negTokenInit exit 9")); ("Error decoding last part of negTokenInit exit 9"));
return 0; return 0;
} else if ((cls != ASN1_UNI) || (con != ASN1_PRI) } else if ((cls != ASN1_UNI) || (con != ASN1_PRI)
|| (tag != ASN1_GENSTR)) { || (tag != ASN1_GENSTR)) {
cFYI(1, 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)); cls, con, tag, end, *end));
return 0; 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) /* if (use_kerberos)
......
...@@ -39,7 +39,8 @@ cifs_dump_mem(char *label, void *data, int length) ...@@ -39,7 +39,8 @@ cifs_dump_mem(char *label, void *data, int length)
char *charptr = data; char *charptr = data;
char buf[10], line[80]; 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) { for (i = 0; i < length; i += 16) {
line[0] = 0; line[0] = 0;
for (j = 0; (j < 4) && (i + j * 4 < length); j++) { for (j = 0; (j < 4) && (i + j * 4 < length); j++) {
...@@ -52,7 +53,7 @@ cifs_dump_mem(char *label, void *data, int length) ...@@ -52,7 +53,7 @@ cifs_dump_mem(char *label, void *data, int length)
buf[1] = isprint(charptr[i + j]) ? charptr[i + j] : '.'; buf[1] = isprint(charptr[i + j]) ? charptr[i + j] : '.';
strcat(line, buf); strcat(line, buf);
} }
printk("%s\n", line); printk(KERN_DEBUG "%s\n", line);
} }
} }
...@@ -68,7 +69,6 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, ...@@ -68,7 +69,6 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
int length = 0; int length = 0;
char *buf_start = buf; 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 = length =
sprintf(buf, sprintf(buf,
"Display Internal CIFS Data Structures for Debugging\n" "Display Internal CIFS Data Structures for Debugging\n"
...@@ -85,17 +85,17 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, ...@@ -85,17 +85,17 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList); ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
length = length =
sprintf(buf, sprintf(buf,
"\n%d) Name: %s Domain: %s HowManyMounts: %d ServerOS: %s ServerNOS: %s\n\tCapabilities: 0x%x", "\n%d) Name: %s Domain: %s Mounts: %d ServerOS: %s ServerNOS: %s\n\tCapabilities: 0x%x",
i, ses->serverName, ses->serverDomain, atomic_read(&ses->inUse), i, ses->serverName, ses->serverDomain, atomic_read(&ses->inUse),
ses->serverOS, ses->serverNOS, ses->capabilities); ses->serverOS, ses->serverNOS, ses->capabilities);
buf += length; buf += length;
if(ses->server) if(ses->server)
buf += sprintf(buf, "\tLocal Users To Same Server: %d ",atomic_read(&ses->server->socketUseCount)); buf += sprintf(buf, "\tLocal Users To Same Server: %d ",
atomic_read(&ses->server->socketUseCount));
} }
read_unlock(&GlobalSMBSeslock); read_unlock(&GlobalSMBSeslock);
sprintf(buf, "\n"); sprintf(buf, "\n");
buf++; buf++;
printk("\nTotal Buffer so far: %s\n", buf_start);
length = sprintf(buf, "\nShares: \n"); length = sprintf(buf, "\nShares: \n");
buf += length; buf += length;
...@@ -107,7 +107,7 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, ...@@ -107,7 +107,7 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
length = length =
sprintf(buf, sprintf(buf,
"\n%d) %s UseCount: %d on FS: %s with characteristics: 0x%x Attributes: 0x%x\n\tPathComponentLengthMax: %d", "\n%d) %s Uses: %d on FS: %s with characteristics: 0x%x Attributes: 0x%x\n\tPathComponentMax: %d",
i, tcon->treeName, i, tcon->treeName,
atomic_read(&tcon->useCount), atomic_read(&tcon->useCount),
tcon->nativeFileSystem, tcon->nativeFileSystem,
......
...@@ -33,19 +33,24 @@ void dump_smb(struct smb_hdr *, int); ...@@ -33,19 +33,24 @@ void dump_smb(struct smb_hdr *, int);
*/ */
#ifdef CIFS_DEBUG #ifdef CIFS_DEBUG
/* information message: e.g., configuration, major event */ /* information message: e.g., configuration, major event */
extern int cifsFYI; extern int cifsFYI;
#define cFYI(button,prspec)\ #define cifsfyi(format,arg...) if (cifsFYI) printk(KERN_DEBUG " " __FILE__ ": " format "\n" "" , ## arg)
{ if (button && cifsFYI) printk prspec; }
#define cFYI(button,prspec) if (button) cifsfyi prspec
#define cifswarn(format, arg...) printk(KERN_WARNING ": " format "\n" , ## arg)
/* debug event message: */ /* debug event message: */
#define cEVENT(button,prspec)\ extern int cifsERROR;
{ if (button) printk prspec; }
#define cEVENT(format,arg...) if (cifsERROR) printk(KERN_EVENT __FILE__ ": " format "\n" , ## arg)
/* error event message: e.g., i/o error */ /* error event message: e.g., i/o error */
extern int cifsERROR; #define cifserror(format,arg...) if (cifsERROR) printk(KERN_ERR " CIFS VFS: " format "\n" "" , ## arg)
#define cERROR(button, prspec)\
{ if (button && cifsERROR) { printk prspec; if (button > 1) BUG(); } } #define cERROR(button, prspec) if (button) cifserror prspec
/* /*
* debug OFF * debug OFF
...@@ -53,8 +58,9 @@ extern int cifsERROR; ...@@ -53,8 +58,9 @@ extern int cifsERROR;
*/ */
#else /* _CIFS_DEBUG */ #else /* _CIFS_DEBUG */
#define cERROR(button,prspec) #define cERROR(button,prspec)
#define cEVENT(button,prspec) #define cEVENT(format,arg...)
#define cFYI(button, prspec) #define cFYI(button, prspec)
#define cifserror(format,arg...)
#endif /* _CIFS_DEBUG */ #endif /* _CIFS_DEBUG */
/* /*
......
...@@ -69,7 +69,6 @@ cifs_strfromUCS_le(char *to, const wchar_t * from, /* LITTLE ENDIAN */ ...@@ -69,7 +69,6 @@ cifs_strfromUCS_le(char *to, const wchar_t * from, /* LITTLE ENDIAN */
} }
} }
to[outlen] = 0; to[outlen] = 0;
cEVENT(0, ("cifs_strfromUCS returning %d - '%s'\n", outlen, to));
return outlen; return outlen;
} }
...@@ -86,15 +85,13 @@ cifs_strtoUCS(wchar_t * to, const char *from, int len, ...@@ -86,15 +85,13 @@ cifs_strtoUCS(wchar_t * to, const char *from, int len,
int charlen; int charlen;
int i; int i;
cEVENT(0, ("cifs_strtoUCS - '%s'\n", from));
for (i = 0; len && *from; i++, from += charlen, len -= charlen) { for (i = 0; len && *from; i++, from += charlen, len -= charlen) {
/* works for 2.4.0 kernel or later */ /* works for 2.4.0 kernel or later */
charlen = codepage->char2uni(from, len, &to[i]); charlen = codepage->char2uni(from, len, &to[i]);
if (charlen < 1) { if (charlen < 1) {
cERROR(1, cERROR(1,
("cifs_strtoUCS: char2uni returned %d.\n", ("cifs_strtoUCS: char2uni returned %d",
charlen)); charlen));
to[i] = cpu_to_le16(0x003f); /* a question mark */ to[i] = cpu_to_le16(0x003f); /* a question mark */
charlen = 1; charlen = 1;
...@@ -103,8 +100,6 @@ cifs_strtoUCS(wchar_t * to, const char *from, int len, ...@@ -103,8 +100,6 @@ cifs_strtoUCS(wchar_t * to, const char *from, int len,
} }
cEVENT(0, (" returning %d\n", i));
to[i] = 0; to[i] = 0;
return i; return i;
} }
......
...@@ -71,12 +71,13 @@ cifs_read_super(struct super_block *sb, void *data, char *devname, int silent) ...@@ -71,12 +71,13 @@ cifs_read_super(struct super_block *sb, void *data, char *devname, int silent)
if(cifs_sb == NULL) if(cifs_sb == NULL)
return -ENOMEM; return -ENOMEM;
cifs_sb->local_nls = load_nls_default(); /* needed for ASCII cp to Unicode converts */ cifs_sb->local_nls = load_nls_default(); /* needed for ASCII cp to Unicode converts */
rc = cifs_mount(sb, cifs_sb, data, devname); rc = cifs_mount(sb, cifs_sb, data, devname);
if (rc) { if (rc) {
if (!silent) if (!silent)
cERROR(1, cERROR(1,
("cifs_mount failed w/return code = %d\n", rc)); ("cifs_mount failed w/return code = %d", rc));
goto out_mount_failed; goto out_mount_failed;
} }
...@@ -97,13 +98,10 @@ cifs_read_super(struct super_block *sb, void *data, char *devname, int silent) ...@@ -97,13 +98,10 @@ cifs_read_super(struct super_block *sb, void *data, char *devname, int silent)
return 0; return 0;
out_no_root: out_no_root:
cEVENT(1, ("cifs_read_super: get root inode failed\n")); cERROR(1, ("cifs_read_super: get root inode failed"));
if (inode) if (inode)
iput(inode); iput(inode);
if (rc) {
cERROR(1, ("cifs_mount failed with no root inode"));
}
out_mount_failed: out_mount_failed:
if(cifs_sb) if(cifs_sb)
kfree(cifs_sb); kfree(cifs_sb);
...@@ -116,15 +114,15 @@ cifs_put_super(struct super_block *sb) ...@@ -116,15 +114,15 @@ cifs_put_super(struct super_block *sb)
int rc = 0; int rc = 0;
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
cFYI(1, ("In cifs_put_super\n")); cFYI(1, ("In cifs_put_super"));
cifs_sb = CIFS_SB(sb); cifs_sb = CIFS_SB(sb);
if(cifs_sb == NULL) { if(cifs_sb == NULL) {
cFYI(1,("\nEmpty cifs superblock info passed to unmount")); cFYI(1,("Empty cifs superblock info passed to unmount"));
return; return;
} }
rc = cifs_umount(sb, cifs_sb); rc = cifs_umount(sb, cifs_sb);
if (rc) { 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); unload_nls(cifs_sb->local_nls);
kfree(cifs_sb); kfree(cifs_sb);
...@@ -180,7 +178,8 @@ cifs_alloc_inode(struct super_block *sb) ...@@ -180,7 +178,8 @@ cifs_alloc_inode(struct super_block *sb)
cifs_inode->cifsAttrs = 0x20; /* default */ cifs_inode->cifsAttrs = 0x20; /* default */
atomic_set(&cifs_inode->inUse, 0); atomic_set(&cifs_inode->inUse, 0);
cifs_inode->time = 0; cifs_inode->time = 0;
cifs_inode->clientCanCache = 0; if(oplockEnabled)
cifs_inode->clientCanCacheAll = 1;
INIT_LIST_HEAD(&cifs_inode->openFileList); INIT_LIST_HEAD(&cifs_inode->openFileList);
return &cifs_inode->vfs_inode; return &cifs_inode->vfs_inode;
} }
...@@ -236,7 +235,7 @@ cifs_get_sb(struct file_system_type *fs_type, ...@@ -236,7 +235,7 @@ cifs_get_sb(struct file_system_type *fs_type,
int rc; int rc;
struct super_block *sb = sget(fs_type, NULL, set_anon_super, NULL); 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)) if (IS_ERR(sb))
return sb; return sb;
...@@ -277,8 +276,15 @@ struct inode_operations cifs_dir_inode_ops = { ...@@ -277,8 +276,15 @@ struct inode_operations cifs_dir_inode_ops = {
struct inode_operations cifs_file_inode_ops = { struct inode_operations cifs_file_inode_ops = {
/* revalidate:cifs_revalidate, */ /* revalidate:cifs_revalidate, */
.setattr = cifs_setattr, .setattr = cifs_setattr,
.getattr = cifs_getattr, .getattr = cifs_getattr, /* do we need this anymore? */
.rename = cifs_rename, .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 = { struct inode_operations cifs_symlink_inode_ops = {
...@@ -287,6 +293,12 @@ struct inode_operations cifs_symlink_inode_ops = { ...@@ -287,6 +293,12 @@ struct inode_operations cifs_symlink_inode_ops = {
/* BB add the following two eventually */ /* BB add the following two eventually */
/* revalidate: cifs_revalidate, /* revalidate: cifs_revalidate,
setattr: cifs_notify_change, *//* BB do we need notify change */ 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 = { struct file_operations cifs_file_ops = {
...@@ -296,7 +308,9 @@ struct file_operations cifs_file_ops = { ...@@ -296,7 +308,9 @@ struct file_operations cifs_file_ops = {
.release = cifs_close, .release = cifs_close,
.lock = cifs_lock, .lock = cifs_lock,
.fsync = cifs_fsync, .fsync = cifs_fsync,
.flush = cifs_flush,
.mmap = cifs_file_mmap, .mmap = cifs_file_mmap,
.sendfile = generic_file_sendfile,
}; };
struct file_operations cifs_dir_ops = { struct file_operations cifs_dir_ops = {
...@@ -333,7 +347,7 @@ void ...@@ -333,7 +347,7 @@ void
cifs_destroy_inodecache(void) cifs_destroy_inodecache(void)
{ {
if (kmem_cache_destroy(cifs_inode_cachep)) 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 int
...@@ -353,7 +367,7 @@ void ...@@ -353,7 +367,7 @@ void
cifs_destroy_request_bufs(void) cifs_destroy_request_bufs(void)
{ {
if (kmem_cache_destroy(cifs_req_cachep)) if (kmem_cache_destroy(cifs_req_cachep))
printk(KERN_INFO printk(KERN_WARNING
"cifs_destroy_request_cache: error not all structures were freed\n"); "cifs_destroy_request_cache: error not all structures were freed\n");
} }
...@@ -373,7 +387,7 @@ void ...@@ -373,7 +387,7 @@ void
cifs_destroy_mids(void) cifs_destroy_mids(void)
{ {
if (kmem_cache_destroy(cifs_mid_cachep)) if (kmem_cache_destroy(cifs_mid_cachep))
printk(KERN_INFO printk(KERN_WARNING
"cifs_destroy_mids: error not all structures were freed\n"); "cifs_destroy_mids: error not all structures were freed\n");
} }
...@@ -426,7 +440,7 @@ init_cifs(void) ...@@ -426,7 +440,7 @@ init_cifs(void)
static void __exit static void __exit
exit_cifs(void) exit_cifs(void)
{ {
cFYI(0, ("\nIn unregister ie exit_cifs")); cFYI(0, ("In unregister ie exit_cifs"));
#if CONFIG_PROC_FS #if CONFIG_PROC_FS
cifs_proc_clean(); cifs_proc_clean();
#endif #endif
......
...@@ -74,6 +74,7 @@ extern ssize_t cifs_write(struct file *file, const char *write_data, ...@@ -74,6 +74,7 @@ extern ssize_t cifs_write(struct file *file, const char *write_data,
size_t write_size, loff_t * poffset); size_t write_size, loff_t * poffset);
extern int cifs_lock(struct file *, int, struct file_lock *); extern int cifs_lock(struct file *, int, struct file_lock *);
extern int cifs_fsync(struct file *, struct dentry *, int); extern int cifs_fsync(struct file *, struct dentry *, int);
extern int cifs_flush(struct file *);
extern int cifs_file_mmap(struct file * , struct vm_area_struct *); extern int cifs_file_mmap(struct file * , struct vm_area_struct *);
extern struct file_operations cifs_dir_ops; extern struct file_operations cifs_dir_ops;
extern int cifs_dir_open(struct inode *inode, struct file *file); extern int cifs_dir_open(struct inode *inode, struct file *file);
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#define MAX_TREE_SIZE 2 + MAX_SERVER_SIZE + 1 + MAX_SHARE_SIZE + 1 #define MAX_TREE_SIZE 2 + MAX_SERVER_SIZE + 1 + MAX_SHARE_SIZE + 1
#define MAX_SERVER_SIZE 15 #define MAX_SERVER_SIZE 15
#define MAX_SHARE_SIZE 64 /* used to be 20 - this should still be enough */ #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 */ termination then *2 for unicode versions */
#define MAX_PASSWORD_SIZE 16 #define MAX_PASSWORD_SIZE 16
...@@ -109,6 +109,21 @@ struct TCP_Server_Info { ...@@ -109,6 +109,21 @@ struct TCP_Server_Info {
struct semaphore tcpSem; struct semaphore tcpSem;
struct task_struct *tsk; struct task_struct *tsk;
char server_GUID[16]; 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 @@ struct TCP_Server_Info { ...@@ -117,12 +132,11 @@ struct TCP_Server_Info {
* has changed. We also hang a list of sessions owned by this user off here. * has changed. We also hang a list of sessions owned by this user off here.
*/ */
struct cifsUidInfo { struct cifsUidInfo {
struct cifsUidInfo *next1; /* BB replace with list and atomicize */ struct list_head userList;
struct cifsSesInfo *ses; /* list of sessions *//* BB replace with list and atomicize */ struct list_head sessionList; /* SMB sessions for this user */
struct srSesInfo *sesSR; /* Save/Restore session list */
uid_t linux_uid; uid_t linux_uid;
char user[MAX_USERNAME_SIZE + 1]; /* ascii name of user */ 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 cifsSesInfo { ...@@ -135,28 +149,16 @@ struct cifsSesInfo {
struct TCP_Server_Info *server; /* pointer to server info */ struct TCP_Server_Info *server; /* pointer to server info */
atomic_t inUse; /* # of CURRENT users of this ses */ atomic_t inUse; /* # of CURRENT users of this ses */
enum statusEnum status; 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 */ __u16 ipc_tid; /* special tid for connection to IPC share */
int capabilities;
__u16 timeZone;
char *serverOS; /* name of operating system underlying the server */ char *serverOS; /* name of operating system underlying the server */
char *serverNOS; /* name of network operating system that the server is running */ char *serverNOS; /* name of network operating system that the server is running */
char *serverDomain; /* security realm of server */ char *serverDomain; /* security realm of server */
int Suid; /* needed for user level security */ 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 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 @@ struct cifsTconInfo { ...@@ -172,6 +174,7 @@ struct cifsTconInfo {
char *nativeFileSystem; char *nativeFileSystem;
__u16 tid; /* The 2 byte transaction id */ __u16 tid; /* The 2 byte transaction id */
__u16 Flags; /* optional support bits */ __u16 Flags; /* optional support bits */
enum statusEnum tidStatus;
atomic_t useCount; /* how many mounts (explicit or implicit refer to this share */ atomic_t useCount; /* how many mounts (explicit or implicit refer to this share */
FILE_SYSTEM_DEVICE_INFO fsDevInfo; FILE_SYSTEM_DEVICE_INFO fsDevInfo;
FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* note file system name may be truncated - but very unlikely */ FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* note file system name may be truncated - but very unlikely */
...@@ -214,11 +217,11 @@ struct cifsInodeInfo { ...@@ -214,11 +217,11 @@ struct cifsInodeInfo {
struct list_head lockList; struct list_head lockList;
/* BB add in lists for dirty pages - i.e. write caching info for oplock */ /* BB add in lists for dirty pages - i.e. write caching info for oplock */
struct list_head openFileList; struct list_head openFileList;
__u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system etc. */ __u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */
atomic_t inUse; /* num concurrent users (local openers cifs) of file */ atomic_t inUse; /* num concurrent users (local openers cifs) of file*/
unsigned long time; /* jiffies of last update/check of inode */ unsigned long time; /* jiffies of last update/check of inode */
int clientCanCache:1; /* oplocked. We need to extend cases beyond this i.e. what int clientCanCacheRead:1; /* read oplock */
if file read-only or if file locked? or if file on r/o vol? */ int clientCanCacheAll:1; /* read and writebehind oplock */
struct inode vfs_inode; struct inode vfs_inode;
}; };
......
...@@ -79,7 +79,7 @@ ...@@ -79,7 +79,7 @@
/* /*
* Starting value for maximum SMB size negotiation * 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 * Size of encrypted user password in bytes
......
...@@ -36,8 +36,8 @@ extern int smb_send(struct socket *, struct smb_hdr *, ...@@ -36,8 +36,8 @@ extern int smb_send(struct socket *, struct smb_hdr *,
unsigned int /* length */ , struct sockaddr *); unsigned int /* length */ , struct sockaddr *);
extern unsigned int _GetXid(void); extern unsigned int _GetXid(void);
extern void _FreeXid(unsigned int); 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 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,("\nCIFS VFS: leaving %s (xid = %d) rc = %d\n",__FUNCTION__,curr_xid,rc));} #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_path_from_dentry(struct dentry *);
extern char *build_wildcard_path_from_dentry(struct dentry *direntry); extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
extern void renew_parental_timestamps(struct dentry *direntry); extern void renew_parental_timestamps(struct dentry *direntry);
...@@ -72,28 +72,21 @@ extern int cifs_get_inode_info_unix(struct inode **pinode, ...@@ -72,28 +72,21 @@ extern int cifs_get_inode_info_unix(struct inode **pinode,
const unsigned char *search_path, const unsigned char *search_path,
struct super_block *sb); struct super_block *sb);
extern int CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses, extern int setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
char cryptokey[CIFS_CRYPTO_KEY_SIZE]); struct nls_table * nls_info);
extern int CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses);
extern int CIFSSessSetup(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, char *session_key, char *ntlm_session_key,
const struct nls_table *); const struct nls_table *);
extern int CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, 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 *); const struct nls_table *);
extern int CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, extern int CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
struct cifsSesInfo *ses, struct cifsSesInfo *ses, int *ntlmv2_flag,
char *domain,
char *ntlm_session_key,
int *ntlmv2_flag,
const struct nls_table *); const struct nls_table *);
extern int CIFSNTLMSSPAuthSessSetup(unsigned int xid, extern int CIFSNTLMSSPAuthSessSetup(unsigned int xid,
struct cifsSesInfo *ses, char *user, struct cifsSesInfo *ses, char *ntlm_session_key,
char *domain, char *ntlm_session_key, char *lanman_session_key,int ntlmv2_flag,
char *lanman_session_key,
int ntlmv2_flag,
const struct nls_table *); const struct nls_table *);
extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
...@@ -202,7 +195,7 @@ extern int CIFSSMBClose(const int xid, const struct cifsTconInfo *tcon, ...@@ -202,7 +195,7 @@ extern int CIFSSMBClose(const int xid, const struct cifsTconInfo *tcon,
extern int CIFSSMBRead(const int xid, const struct cifsTconInfo *tcon, extern int CIFSSMBRead(const int xid, const struct cifsTconInfo *tcon,
const int netfid, unsigned int count, 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, extern int CIFSSMBWrite(const int xid, const struct cifsTconInfo *tcon,
const int netfid, const unsigned int count, const int netfid, const unsigned int count,
const __u64 lseek, unsigned int *nbytes, const __u64 lseek, unsigned int *nbytes,
......
...@@ -49,6 +49,11 @@ smb_init(int smb_command, int wct, const struct cifsTconInfo *tcon, ...@@ -49,6 +49,11 @@ smb_init(int smb_command, int wct, const struct cifsTconInfo *tcon,
{ {
int rc = 0; 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(); *request_buf = buf_get();
if (request_buf == 0) { if (request_buf == 0) {
return -ENOMEM; return -ENOMEM;
...@@ -65,13 +70,20 @@ smb_init(int smb_command, int wct, const struct cifsTconInfo *tcon, ...@@ -65,13 +70,20 @@ smb_init(int smb_command, int wct, const struct cifsTconInfo *tcon,
} }
int int
CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses, CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
char cryptokey[CIFS_CRYPTO_KEY_SIZE])
{ {
NEGOTIATE_REQ *pSMB; NEGOTIATE_REQ *pSMB;
NEGOTIATE_RSP *pSMBr; NEGOTIATE_RSP *pSMBr;
int rc = 0; int rc = 0;
int bytes_returned; 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 */ , rc = smb_init(SMB_COM_NEGOTIATE, 0, 0 /* no tcon yet */ ,
(void **) &pSMB, (void **) &pSMBr); (void **) &pSMB, (void **) &pSMBr);
...@@ -95,22 +107,22 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses, ...@@ -95,22 +107,22 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses,
rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc == 0) { if (rc == 0) {
ses->dialectIndex = le16_to_cpu(pSMBr->DialectIndex); server->secMode = pSMBr->SecurityMode;
ses->secMode = pSMBr->SecurityMode; server->secType = NTLM; /* BB override default for NTLMv2 or krb*/
/* one byte - no need to convert this or EncryptionKeyLen from le,*/ /* 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 */ /* probably no need to store and check maxvcs */
ses->maxBuf = server->maxBuf =
min(le32_to_cpu(pSMBr->MaxBufferSize), min(le32_to_cpu(pSMBr->MaxBufferSize),
(__u32) CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE); (__u32) CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE);
ses->maxRw = le32_to_cpu(pSMBr->MaxRawSize); server->maxRw = le32_to_cpu(pSMBr->MaxRawSize);
cFYI(1, ("\nMax buf = %d ", ses->maxBuf)); cFYI(0, ("Max buf = %d ", ses->server->maxBuf));
GETU32(ses->sessid) = le32_to_cpu(pSMBr->SessionKey); GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey);
ses->capabilities = le32_to_cpu(pSMBr->Capabilities); server->capabilities = le32_to_cpu(pSMBr->Capabilities);
ses->timeZone = le16_to_cpu(pSMBr->ServerTimeZone); server->timeZone = le16_to_cpu(pSMBr->ServerTimeZone);
/* BB with UTC do we ever need to be using srvr timezone? */ /* BB with UTC do we ever need to be using srvr timezone? */
if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) { if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
memcpy(cryptokey, pSMBr->u.EncryptionKey, memcpy(server->cryptKey, pSMBr->u.EncryptionKey,
CIFS_CRYPTO_KEY_SIZE); CIFS_CRYPTO_KEY_SIZE);
} else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC)
&& (pSMBr->EncryptionKeyLength == 0)) { && (pSMBr->EncryptionKeyLength == 0)) {
...@@ -124,22 +136,22 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses, ...@@ -124,22 +136,22 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses,
if (pSMBr->ByteCount < 16) if (pSMBr->ByteCount < 16)
rc = -EIO; rc = -EIO;
else if (pSMBr->ByteCount == 16) { else if (pSMBr->ByteCount == 16) {
ses->secType = RawNTLMSSP; server->secType = RawNTLMSSP;
if (ses->server->socketUseCount.counter > 1) { if (server->socketUseCount.counter > 1) {
if (memcmp if (memcmp
(ses->server->server_GUID, (server->server_GUID,
pSMBr->u.extended_response. pSMBr->u.extended_response.
GUID, 16) != 0) { GUID, 16) != 0) {
cFYI(1, cFYI(1,
("UID of server does not match that of previous connection to same ip address")); ("UID of server does not match that of previous connection to same ip address"));
memcpy(ses->server-> memcpy(server->
server_GUID, server_GUID,
pSMBr->u. pSMBr->u.
extended_response. extended_response.
GUID, 16); GUID, 16);
} }
} else } else
memcpy(ses->server->server_GUID, memcpy(server->server_GUID,
pSMBr->u.extended_response. pSMBr->u.extended_response.
GUID, 16); GUID, 16);
} else { } else {
...@@ -147,15 +159,15 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses, ...@@ -147,15 +159,15 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses,
extended_response. extended_response.
SecurityBlob, SecurityBlob,
pSMBr->ByteCount - pSMBr->ByteCount -
16, &ses->secType); 16, &server->secType);
} }
} else } else
ses->capabilities &= ~CAP_EXTENDED_SECURITY; server->capabilities &= ~CAP_EXTENDED_SECURITY;
if(sign_CIFS_PDUs == FALSE) { if(sign_CIFS_PDUs == FALSE) {
if(ses->secMode & SECMODE_SIGN_REQUIRED) if(server->secMode & SECMODE_SIGN_REQUIRED)
cERROR(1,("\nServer required CIFS packet signing - enable /proc/fs/cifs/PacketSigningEnabled")); cERROR(1,("Server required CIFS packet signing - enable /proc/fs/cifs/PacketSigningEnabled"));
ses->secMode &= ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); server->secMode &= ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
} }
} }
if (pSMB) if (pSMB)
...@@ -171,7 +183,7 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon) ...@@ -171,7 +183,7 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
int rc = 0; int rc = 0;
int length; int length;
cFYI(1, ("\nIn tree disconnect")); cFYI(1, ("In tree disconnect"));
/* /*
* If last user of the connection and * If last user of the connection and
* connection alive - disconnect it * connection alive - disconnect it
...@@ -192,6 +204,10 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon) ...@@ -192,6 +204,10 @@ CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
/* BB remove (from server) list of shares - but with smp safety BB */ /* 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 */ /* 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, rc = smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
(void **) &smb_buffer, (void **) &smb_buffer_response); (void **) &smb_buffer, (void **) &smb_buffer_response);
...@@ -218,7 +234,7 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses) ...@@ -218,7 +234,7 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
int rc = 0; int rc = 0;
int length; int length;
cFYI(1, ("\nIn SMBLogoff for session disconnect")); cFYI(1, ("In SMBLogoff for session disconnect"));
if (ses) if (ses)
down(&ses->sesSem); /* need to add more places where this sem is checked */ down(&ses->sesSem); /* need to add more places where this sem is checked */
...@@ -230,7 +246,7 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses) ...@@ -230,7 +246,7 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
up(&ses->sesSem); up(&ses->sesSem);
return -EBUSY; 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; pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
rc = smb_init(SMB_COM_LOGOFF_ANDX, 2, 0 /* no tcon anymore */ , rc = smb_init(SMB_COM_LOGOFF_ANDX, 2, 0 /* no tcon anymore */ ,
(void **) &pSMB, (void **) &smb_buffer_response); (void **) &pSMB, (void **) &smb_buffer_response);
...@@ -278,7 +294,6 @@ CIFSSMBDelFile(const int xid, const struct cifsTconInfo *tcon, ...@@ -278,7 +294,6 @@ CIFSSMBDelFile(const int xid, const struct cifsTconInfo *tcon,
name_len++; /* trailing null */ name_len++; /* trailing null */
name_len *= 2; name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */ } else { /* BB improve the check for buffer overruns BB */
name_len = strnlen(fileName, 530); name_len = strnlen(fileName, 530);
name_len++; /* trailing null */ name_len++; /* trailing null */
strncpy(pSMB->fileName, fileName, name_len); strncpy(pSMB->fileName, fileName, name_len);
...@@ -292,7 +307,7 @@ CIFSSMBDelFile(const int xid, const struct cifsTconInfo *tcon, ...@@ -292,7 +307,7 @@ CIFSSMBDelFile(const int xid, const struct cifsTconInfo *tcon,
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) { if (rc) {
cERROR(1, ("\nSend error in RMFile = %d\n", rc)); cFYI(1, ("Error in RMFile = %d", rc));
} }
if (pSMB) if (pSMB)
buf_release(pSMB); buf_release(pSMB);
...@@ -309,7 +324,7 @@ CIFSSMBRmDir(const int xid, const struct cifsTconInfo *tcon, ...@@ -309,7 +324,7 @@ CIFSSMBRmDir(const int xid, const struct cifsTconInfo *tcon,
int bytes_returned; int bytes_returned;
int name_len; int name_len;
cFYI(1, ("\nIn CIFSSMBRmDir")); cFYI(1, ("In CIFSSMBRmDir"));
rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB, rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
...@@ -323,7 +338,6 @@ CIFSSMBRmDir(const int xid, const struct cifsTconInfo *tcon, ...@@ -323,7 +338,6 @@ CIFSSMBRmDir(const int xid, const struct cifsTconInfo *tcon,
name_len++; /* trailing null */ name_len++; /* trailing null */
name_len *= 2; name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */ } else { /* BB improve the check for buffer overruns BB */
name_len = strnlen(dirName, 530); name_len = strnlen(dirName, 530);
name_len++; /* trailing null */ name_len++; /* trailing null */
strncpy(pSMB->DirName, dirName, name_len); strncpy(pSMB->DirName, dirName, name_len);
...@@ -336,7 +350,7 @@ CIFSSMBRmDir(const int xid, const struct cifsTconInfo *tcon, ...@@ -336,7 +350,7 @@ CIFSSMBRmDir(const int xid, const struct cifsTconInfo *tcon,
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) { if (rc) {
cERROR(1, ("\nSend error in RMDir = %d\n", rc)); cFYI(1, ("Error in RMDir = %d", rc));
} }
if (pSMB) if (pSMB)
buf_release(pSMB); buf_release(pSMB);
...@@ -353,7 +367,7 @@ CIFSSMBMkDir(const int xid, const struct cifsTconInfo *tcon, ...@@ -353,7 +367,7 @@ CIFSSMBMkDir(const int xid, const struct cifsTconInfo *tcon,
int bytes_returned; int bytes_returned;
int name_len; int name_len;
cFYI(1, ("\nIn CIFSSMBMkDir")); cFYI(1, ("In CIFSSMBMkDir"));
rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB, rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
...@@ -367,7 +381,6 @@ CIFSSMBMkDir(const int xid, const struct cifsTconInfo *tcon, ...@@ -367,7 +381,6 @@ CIFSSMBMkDir(const int xid, const struct cifsTconInfo *tcon,
name_len++; /* trailing null */ name_len++; /* trailing null */
name_len *= 2; name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */ } else { /* BB improve the check for buffer overruns BB */
name_len = strnlen(name, 530); name_len = strnlen(name, 530);
name_len++; /* trailing null */ name_len++; /* trailing null */
strncpy(pSMB->DirName, name, name_len); strncpy(pSMB->DirName, name, name_len);
...@@ -380,7 +393,7 @@ CIFSSMBMkDir(const int xid, const struct cifsTconInfo *tcon, ...@@ -380,7 +393,7 @@ CIFSSMBMkDir(const int xid, const struct cifsTconInfo *tcon,
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) { if (rc) {
cERROR(1, ("\nSend error in RMDir = %d\n", rc)); cFYI(1, ("Error in Mkdir = %d", rc));
} }
if (pSMB) if (pSMB)
buf_release(pSMB); buf_release(pSMB);
...@@ -418,15 +431,17 @@ CIFSSMBOpen(const int xid, const struct cifsTconInfo *tcon, ...@@ -418,15 +431,17 @@ CIFSSMBOpen(const int xid, const struct cifsTconInfo *tcon,
name_len *= 2; name_len *= 2;
pSMB->NameLength = cpu_to_le16(name_len); pSMB->NameLength = cpu_to_le16(name_len);
} else { /* BB improve the check for buffer overruns BB */ } else { /* BB improve the check for buffer overruns BB */
pSMB->ByteCount = 0; /* no pad */ pSMB->ByteCount = 0; /* no pad */
name_len = strnlen(fileName, 530); name_len = strnlen(fileName, 530);
name_len++; /* trailing null */ name_len++; /* trailing null */
pSMB->NameLength = cpu_to_le16(name_len); pSMB->NameLength = cpu_to_le16(name_len);
strncpy(pSMB->fileName, fileName, name_len); strncpy(pSMB->fileName, fileName, name_len);
} }
if (*pOplock) if (*pOplock & REQ_OPLOCK)
pSMB->OpenFlags = cpu_to_le32(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->DesiredAccess = cpu_to_le32(access_flags);
pSMB->AllocationSize = 0; pSMB->AllocationSize = 0;
pSMB->FileAttributes = ATTR_NORMAL; /* XP does not handle ATTR_POSIX_SEMANTICS */ pSMB->FileAttributes = ATTR_NORMAL; /* XP does not handle ATTR_POSIX_SEMANTICS */
...@@ -449,7 +464,7 @@ CIFSSMBOpen(const int xid, const struct cifsTconInfo *tcon, ...@@ -449,7 +464,7 @@ CIFSSMBOpen(const int xid, const struct cifsTconInfo *tcon,
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) { if (rc) {
cERROR(1, ("\nSend error in Open = %d\n", rc)); cFYI(1, ("Error in Open = %d", rc));
} else { } else {
*pOplock = pSMBr->OplockLevel; /* one byte no need to le_to_cpu */ *pOplock = pSMBr->OplockLevel; /* one byte no need to le_to_cpu */
*netfid = pSMBr->Fid; /* cifs fid stays in le */ *netfid = pSMBr->Fid; /* cifs fid stays in le */
...@@ -463,17 +478,22 @@ CIFSSMBOpen(const int xid, const struct cifsTconInfo *tcon, ...@@ -463,17 +478,22 @@ CIFSSMBOpen(const int xid, const struct cifsTconInfo *tcon,
return rc; 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 int
CIFSSMBRead(const int xid, const struct cifsTconInfo *tcon, CIFSSMBRead(const int xid, const struct cifsTconInfo *tcon,
const int netfid, const unsigned int count, 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; int rc = -EACCES;
READ_REQ *pSMB = NULL; READ_REQ *pSMB = NULL;
READ_RSP *pSMBr = NULL; READ_RSP *pSMBr = NULL;
char *pReadData; char *pReadData = NULL;
int bytes_returned; int bytes_returned;
*nbytes = 0;
rc = smb_init(SMB_COM_READ_ANDX, 12, tcon, (void **) &pSMB, rc = smb_init(SMB_COM_READ_ANDX, 12, tcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
if (rc) if (rc)
...@@ -485,7 +505,7 @@ CIFSSMBRead(const int xid, const struct cifsTconInfo *tcon, ...@@ -485,7 +505,7 @@ CIFSSMBRead(const int xid, const struct cifsTconInfo *tcon,
pSMB->OffsetHigh = cpu_to_le32(lseek >> 32); pSMB->OffsetHigh = cpu_to_le32(lseek >> 32);
pSMB->Remaining = 0; pSMB->Remaining = 0;
pSMB->MaxCount = cpu_to_le16(min(count, pSMB->MaxCount = cpu_to_le16(min(count,
(tcon->ses->maxBuf - (tcon->ses->server->maxBuf -
MAX_CIFS_HDR_SIZE) & 0xFFFFFF00)); MAX_CIFS_HDR_SIZE) & 0xFFFFFF00));
pSMB->MaxCountHigh = 0; pSMB->MaxCountHigh = 0;
pSMB->ByteCount = 0; /* no need to do le conversion since it is 0 */ pSMB->ByteCount = 0; /* no need to do le conversion since it is 0 */
...@@ -493,14 +513,14 @@ CIFSSMBRead(const int xid, const struct cifsTconInfo *tcon, ...@@ -493,14 +513,14 @@ CIFSSMBRead(const int xid, const struct cifsTconInfo *tcon,
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) { if (rc) {
cERROR(1, ("\nSend error in read = %d\n", rc)); cERROR(1, ("Send error in read = %d", rc));
*nbytes = 0;
} else { } else {
pSMBr->DataLength = le16_to_cpu(pSMBr->DataLength); pSMBr->DataLength = le16_to_cpu(pSMBr->DataLength);
*nbytes = pSMBr->DataLength; *nbytes = pSMBr->DataLength;
/*check that DataLength would not go beyond end of SMB */ /*check that DataLength would not go beyond end of SMB */
if ((pSMBr->DataLength > CIFS_MAX_MSGSIZE) if ((pSMBr->DataLength > CIFS_MAX_MSGSIZE)
|| (pSMBr->DataLength > count)) { || (pSMBr->DataLength > count)) {
cFYI(1,("bad length %d for count %d",pSMBr->DataLength,count));
rc = -EIO; rc = -EIO;
*nbytes = 0; *nbytes = 0;
} else { } else {
...@@ -508,16 +528,19 @@ CIFSSMBRead(const int xid, const struct cifsTconInfo *tcon, ...@@ -508,16 +528,19 @@ CIFSSMBRead(const int xid, const struct cifsTconInfo *tcon,
(char *) (&pSMBr->hdr.Protocol) + (char *) (&pSMBr->hdr.Protocol) +
le16_to_cpu(pSMBr->DataOffset); le16_to_cpu(pSMBr->DataOffset);
/* if(rc = copy_to_user(buf, pReadData, pSMBr->DataLength)) { /* 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; rc = -EFAULT;
}*/ /* can not use copy_to_user when using page cache*/ }*/ /* can not use copy_to_user when using page cache*/
memcpy(buf,pReadData,pSMBr->DataLength); if(*buf)
memcpy(*buf,pReadData,pSMBr->DataLength);
} }
} }
if (pSMB) {
if (pSMB) if(*buf)
buf_release(pSMB); buf_release(pSMB);
else
*buf = (char *)pSMB;
}
return rc; return rc;
} }
...@@ -542,9 +565,9 @@ CIFSSMBWrite(const int xid, const struct cifsTconInfo *tcon, ...@@ -542,9 +565,9 @@ CIFSSMBWrite(const int xid, const struct cifsTconInfo *tcon,
pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF); pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
pSMB->OffsetHigh = cpu_to_le32(offset >> 32); pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
pSMB->Remaining = 0; 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 = pSMB->DataLengthLow =
(tcon->ses->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFF00; (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFF00;
else else
pSMB->DataLengthLow = count; pSMB->DataLengthLow = count;
pSMB->DataLengthHigh = 0; pSMB->DataLengthHigh = 0;
...@@ -561,7 +584,7 @@ CIFSSMBWrite(const int xid, const struct cifsTconInfo *tcon, ...@@ -561,7 +584,7 @@ CIFSSMBWrite(const int xid, const struct cifsTconInfo *tcon,
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, long_op); (struct smb_hdr *) pSMBr, &bytes_returned, long_op);
if (rc) { if (rc) {
cERROR(1, ("\nSend error in write = %d\n", rc)); cERROR(1, ("Send error in write = %d", rc));
*nbytes = 0; *nbytes = 0;
} else } else
*nbytes = le16_to_cpu(pSMBr->Count); *nbytes = le16_to_cpu(pSMBr->Count);
...@@ -583,7 +606,7 @@ CIFSSMBLock(const int xid, const struct cifsTconInfo *tcon, ...@@ -583,7 +606,7 @@ CIFSSMBLock(const int xid, const struct cifsTconInfo *tcon,
LOCK_RSP *pSMBr = NULL; LOCK_RSP *pSMBr = NULL;
int bytes_returned; int bytes_returned;
cFYI(1, ("\nIn CIFSSMBLock")); cFYI(1, ("In CIFSSMBLock"));
rc = smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB, rc = smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
...@@ -607,7 +630,7 @@ CIFSSMBLock(const int xid, const struct cifsTconInfo *tcon, ...@@ -607,7 +630,7 @@ CIFSSMBLock(const int xid, const struct cifsTconInfo *tcon,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) { if (rc) {
cERROR(1, ("\nSend error in Lock = %d\n", rc)); cERROR(1, ("Send error in Lock = %d", rc));
} }
if (pSMB) if (pSMB)
buf_release(pSMB); buf_release(pSMB);
...@@ -622,7 +645,7 @@ CIFSSMBClose(const int xid, const struct cifsTconInfo *tcon, int smb_file_id) ...@@ -622,7 +645,7 @@ CIFSSMBClose(const int xid, const struct cifsTconInfo *tcon, int smb_file_id)
CLOSE_REQ *pSMB = NULL; CLOSE_REQ *pSMB = NULL;
CLOSE_RSP *pSMBr = NULL; CLOSE_RSP *pSMBr = NULL;
int bytes_returned; int bytes_returned;
cFYI(1, ("\nIn CIFSSMBClose")); cFYI(1, ("In CIFSSMBClose"));
rc = smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB, rc = smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
...@@ -635,7 +658,7 @@ CIFSSMBClose(const int xid, const struct cifsTconInfo *tcon, int smb_file_id) ...@@ -635,7 +658,7 @@ CIFSSMBClose(const int xid, const struct cifsTconInfo *tcon, int smb_file_id)
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) { if (rc) {
cERROR(1, ("\nSend error in Close = %d\n", rc)); cERROR(1, ("Send error in Close = %d", rc));
} }
if (pSMB) if (pSMB)
buf_release(pSMB); buf_release(pSMB);
...@@ -654,7 +677,7 @@ CIFSSMBRename(const int xid, const struct cifsTconInfo *tcon, ...@@ -654,7 +677,7 @@ CIFSSMBRename(const int xid, const struct cifsTconInfo *tcon,
int bytes_returned; int bytes_returned;
int name_len, name_len2; int name_len, name_len2;
cFYI(1, ("\nIn CIFSSMBRename")); cFYI(1, ("In CIFSSMBRename"));
rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB, rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
...@@ -682,7 +705,6 @@ CIFSSMBRename(const int xid, const struct cifsTconInfo *tcon, ...@@ -682,7 +705,6 @@ CIFSSMBRename(const int xid, const struct cifsTconInfo *tcon,
name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
name_len2 *= 2; /* convert to bytes */ name_len2 *= 2; /* convert to bytes */
} else { /* BB improve the check for buffer overruns BB */ } else { /* BB improve the check for buffer overruns BB */
name_len = strnlen(fromName, 530); name_len = strnlen(fromName, 530);
name_len++; /* trailing null */ name_len++; /* trailing null */
strncpy(pSMB->OldFileName, fromName, name_len); strncpy(pSMB->OldFileName, fromName, name_len);
...@@ -702,7 +724,7 @@ CIFSSMBRename(const int xid, const struct cifsTconInfo *tcon, ...@@ -702,7 +724,7 @@ CIFSSMBRename(const int xid, const struct cifsTconInfo *tcon,
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) { if (rc) {
cFYI(1, ("\nSend error in RMDir = %d\n", rc)); cFYI(1, ("Send error in RMDir = %d", rc));
} }
if (pSMB) if (pSMB)
buf_release(pSMB); buf_release(pSMB);
...@@ -723,7 +745,7 @@ CIFSUnixCreateSymLink(const int xid, const struct cifsTconInfo *tcon, ...@@ -723,7 +745,7 @@ CIFSUnixCreateSymLink(const int xid, const struct cifsTconInfo *tcon,
int rc = 0; int rc = 0;
int bytes_returned = 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, rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
...@@ -788,7 +810,7 @@ CIFSUnixCreateSymLink(const int xid, const struct cifsTconInfo *tcon, ...@@ -788,7 +810,7 @@ CIFSUnixCreateSymLink(const int xid, const struct cifsTconInfo *tcon,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) { if (rc) {
cFYI(1, cFYI(1,
("\nSend error in SetPathInfo (create symlink) = %d\n", ("Send error in SetPathInfo (create symlink) = %d",
rc)); rc));
} }
...@@ -810,7 +832,7 @@ CIFSUnixCreateHardLink(const int xid, const struct cifsTconInfo *tcon, ...@@ -810,7 +832,7 @@ CIFSUnixCreateHardLink(const int xid, const struct cifsTconInfo *tcon,
int rc = 0; int rc = 0;
int bytes_returned = 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, rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
...@@ -873,7 +895,7 @@ CIFSUnixCreateHardLink(const int xid, const struct cifsTconInfo *tcon, ...@@ -873,7 +895,7 @@ CIFSUnixCreateHardLink(const int xid, const struct cifsTconInfo *tcon,
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) { 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) if (pSMB)
...@@ -892,7 +914,7 @@ CIFSCreateHardLink(const int xid, const struct cifsTconInfo *tcon, ...@@ -892,7 +914,7 @@ CIFSCreateHardLink(const int xid, const struct cifsTconInfo *tcon,
int bytes_returned; int bytes_returned;
int name_len, name_len2; int name_len, name_len2;
cFYI(1, ("\nIn CIFSCreateHardLink")); cFYI(1, ("In CIFSCreateHardLink"));
rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB, rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
...@@ -923,7 +945,6 @@ CIFSCreateHardLink(const int xid, const struct cifsTconInfo *tcon, ...@@ -923,7 +945,6 @@ CIFSCreateHardLink(const int xid, const struct cifsTconInfo *tcon,
name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ; name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
name_len2 *= 2; /* convert to bytes */ name_len2 *= 2; /* convert to bytes */
} else { /* BB improve the check for buffer overruns BB */ } else { /* BB improve the check for buffer overruns BB */
name_len = strnlen(fromName, 530); name_len = strnlen(fromName, 530);
name_len++; /* trailing null */ name_len++; /* trailing null */
strncpy(pSMB->OldFileName, fromName, name_len); strncpy(pSMB->OldFileName, fromName, name_len);
...@@ -942,7 +963,7 @@ CIFSCreateHardLink(const int xid, const struct cifsTconInfo *tcon, ...@@ -942,7 +963,7 @@ CIFSCreateHardLink(const int xid, const struct cifsTconInfo *tcon,
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) { 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) if (pSMB)
buf_release(pSMB); buf_release(pSMB);
...@@ -963,7 +984,7 @@ CIFSSMBUnixQuerySymLink(const int xid, const struct cifsTconInfo *tcon, ...@@ -963,7 +984,7 @@ CIFSSMBUnixQuerySymLink(const int xid, const struct cifsTconInfo *tcon,
int bytes_returned; int bytes_returned;
int name_len; 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, rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
if (rc) if (rc)
...@@ -977,7 +998,6 @@ CIFSSMBUnixQuerySymLink(const int xid, const struct cifsTconInfo *tcon, ...@@ -977,7 +998,6 @@ CIFSSMBUnixQuerySymLink(const int xid, const struct cifsTconInfo *tcon,
name_len++; /* trailing null */ name_len++; /* trailing null */
name_len *= 2; name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */ } else { /* BB improve the check for buffer overruns BB */
name_len = strnlen(searchName, 530); name_len = strnlen(searchName, 530);
name_len++; /* trailing null */ name_len++; /* trailing null */
strncpy(pSMB->FileName, searchName, name_len); strncpy(pSMB->FileName, searchName, name_len);
...@@ -1011,7 +1031,7 @@ CIFSSMBUnixQuerySymLink(const int xid, const struct cifsTconInfo *tcon, ...@@ -1011,7 +1031,7 @@ CIFSSMBUnixQuerySymLink(const int xid, const struct cifsTconInfo *tcon,
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) { if (rc) {
cFYI(1, ("\nSend error in QuerySymLinkInfo = %d\n", rc)); cFYI(1, ("Send error in QuerySymLinkInfo = %d", rc));
} else { /* decode response */ } else { /* decode response */
pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset); pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
pSMBr->DataCount = le16_to_cpu(pSMBr->DataCount); pSMBr->DataCount = le16_to_cpu(pSMBr->DataCount);
...@@ -1066,7 +1086,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, const struct cifsTconInfo *tcon, ...@@ -1066,7 +1086,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, const struct cifsTconInfo *tcon,
struct smb_com_transaction_ioctl_req * pSMB; struct smb_com_transaction_ioctl_req * pSMB;
struct smb_com_transaction_ioctl_rsp * pSMBr; 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, rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
if (rc) if (rc)
...@@ -1093,7 +1113,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, const struct cifsTconInfo *tcon, ...@@ -1093,7 +1113,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, const struct cifsTconInfo *tcon,
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) { if (rc) {
cFYI(1, ("\nSend error in QueryReparseLinkInfo = %d\n", rc)); cFYI(1, ("Send error in QueryReparseLinkInfo = %d", rc));
} else { /* decode response */ } else { /* decode response */
pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset); pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
pSMBr->DataCount = le16_to_cpu(pSMBr->DataCount); pSMBr->DataCount = le16_to_cpu(pSMBr->DataCount);
...@@ -1121,11 +1141,11 @@ CIFSSMBQueryReparseLinkInfo(const int xid, const struct cifsTconInfo *tcon, ...@@ -1121,11 +1141,11 @@ CIFSSMBQueryReparseLinkInfo(const int xid, const struct cifsTconInfo *tcon,
} }
} else { } else {
rc = -EIO; 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 symlinkinfo[buflen] = 0; /* just in case so the caller
does not go off the end of the buffer */ does not go off the end of the buffer */
cFYI(1,("\nreadlink result - %s ",symlinkinfo)); cFYI(1,("readlink result - %s ",symlinkinfo));
} }
} }
if (pSMB) if (pSMB)
...@@ -1146,7 +1166,7 @@ CIFSSMBQPathInfo(const int xid, const struct cifsTconInfo *tcon, ...@@ -1146,7 +1166,7 @@ CIFSSMBQPathInfo(const int xid, const struct cifsTconInfo *tcon,
int bytes_returned; int bytes_returned;
int name_len; 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, rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
if (rc) if (rc)
...@@ -1160,7 +1180,6 @@ CIFSSMBQPathInfo(const int xid, const struct cifsTconInfo *tcon, ...@@ -1160,7 +1180,6 @@ CIFSSMBQPathInfo(const int xid, const struct cifsTconInfo *tcon,
name_len++; /* trailing null */ name_len++; /* trailing null */
name_len *= 2; name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */ } else { /* BB improve the check for buffer overruns BB */
name_len = strnlen(searchName, 530); name_len = strnlen(searchName, 530);
name_len++; /* trailing null */ name_len++; /* trailing null */
strncpy(pSMB->FileName, searchName, name_len); strncpy(pSMB->FileName, searchName, name_len);
...@@ -1194,7 +1213,7 @@ CIFSSMBQPathInfo(const int xid, const struct cifsTconInfo *tcon, ...@@ -1194,7 +1213,7 @@ CIFSSMBQPathInfo(const int xid, const struct cifsTconInfo *tcon,
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) { if (rc) {
cFYI(1, ("\nSend error in QPathInfo = %d\n", rc)); cFYI(1, ("Send error in QPathInfo = %d", rc));
} else { /* decode response */ } else { /* decode response */
pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset); pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
if ((pSMBr->ByteCount < 40) || (pSMBr->DataOffset > 512)) /* BB also check enough total bytes returned */ if ((pSMBr->ByteCount < 40) || (pSMBr->DataOffset > 512)) /* BB also check enough total bytes returned */
...@@ -1223,7 +1242,7 @@ CIFSSMBUnixQPathInfo(const int xid, const struct cifsTconInfo *tcon, ...@@ -1223,7 +1242,7 @@ CIFSSMBUnixQPathInfo(const int xid, const struct cifsTconInfo *tcon,
int bytes_returned; int bytes_returned;
int name_len; 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, rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
if (rc) if (rc)
...@@ -1237,7 +1256,6 @@ CIFSSMBUnixQPathInfo(const int xid, const struct cifsTconInfo *tcon, ...@@ -1237,7 +1256,6 @@ CIFSSMBUnixQPathInfo(const int xid, const struct cifsTconInfo *tcon,
name_len++; /* trailing null */ name_len++; /* trailing null */
name_len *= 2; name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */ } else { /* BB improve the check for buffer overruns BB */
name_len = strnlen(searchName, 530); name_len = strnlen(searchName, 530);
name_len++; /* trailing null */ name_len++; /* trailing null */
strncpy(pSMB->FileName, searchName, name_len); strncpy(pSMB->FileName, searchName, name_len);
...@@ -1271,7 +1289,7 @@ CIFSSMBUnixQPathInfo(const int xid, const struct cifsTconInfo *tcon, ...@@ -1271,7 +1289,7 @@ CIFSSMBUnixQPathInfo(const int xid, const struct cifsTconInfo *tcon,
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) { if (rc) {
cFYI(1, ("\nSend error in QPathInfo = %d\n", rc)); cFYI(1, ("Send error in QPathInfo = %d", rc));
} else { /* decode response */ } else { /* decode response */
pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset); pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
if ((pSMBr->ByteCount < 40) || (pSMBr->DataOffset > 512)) /* BB also check enough total bytes returned */ if ((pSMBr->ByteCount < 40) || (pSMBr->DataOffset > 512)) /* BB also check enough total bytes returned */
...@@ -1300,7 +1318,7 @@ CIFSFindSingle(const int xid, const struct cifsTconInfo *tcon, ...@@ -1300,7 +1318,7 @@ CIFSFindSingle(const int xid, const struct cifsTconInfo *tcon,
int bytes_returned; int bytes_returned;
int name_len; int name_len;
cFYI(1, ("\nIn FindUnique")); cFYI(1, ("In FindUnique"));
rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
if (rc) if (rc)
...@@ -1314,7 +1332,6 @@ CIFSFindSingle(const int xid, const struct cifsTconInfo *tcon, ...@@ -1314,7 +1332,6 @@ CIFSFindSingle(const int xid, const struct cifsTconInfo *tcon,
name_len++; /* trailing null */ name_len++; /* trailing null */
name_len *= 2; name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */ } else { /* BB improve the check for buffer overruns BB */
name_len = strnlen(searchName, 530); name_len = strnlen(searchName, 530);
name_len++; /* trailing null */ name_len++; /* trailing null */
strncpy(pSMB->FileName, searchName, name_len); strncpy(pSMB->FileName, searchName, name_len);
...@@ -1353,7 +1370,7 @@ CIFSFindSingle(const int xid, const struct cifsTconInfo *tcon, ...@@ -1353,7 +1370,7 @@ CIFSFindSingle(const int xid, const struct cifsTconInfo *tcon,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) { if (rc) {
cFYI(1, ("\nSend error in FindFileDirInfo = %d\n", rc)); cFYI(1, ("Send error in FindFileDirInfo = %d", rc));
} else { /* decode response */ } else { /* decode response */
/* BB fill in */ /* BB fill in */
...@@ -1378,7 +1395,7 @@ CIFSFindFirst(const int xid, const struct cifsTconInfo *tcon, ...@@ -1378,7 +1395,7 @@ CIFSFindFirst(const int xid, const struct cifsTconInfo *tcon,
int bytes_returned; int bytes_returned;
int name_len; int name_len;
cFYI(1, ("\nIn FindFirst")); cFYI(1, ("In FindFirst"));
rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
if (rc) if (rc)
...@@ -1392,7 +1409,6 @@ CIFSFindFirst(const int xid, const struct cifsTconInfo *tcon, ...@@ -1392,7 +1409,6 @@ CIFSFindFirst(const int xid, const struct cifsTconInfo *tcon,
name_len++; /* trailing null */ name_len++; /* trailing null */
name_len *= 2; name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */ } else { /* BB improve the check for buffer overruns BB */
name_len = strnlen(searchName, 530); name_len = strnlen(searchName, 530);
name_len++; /* trailing null */ name_len++; /* trailing null */
strncpy(pSMB->FileName, searchName, name_len); strncpy(pSMB->FileName, searchName, name_len);
...@@ -1401,7 +1417,7 @@ CIFSFindFirst(const int xid, const struct cifsTconInfo *tcon, ...@@ -1401,7 +1417,7 @@ CIFSFindFirst(const int xid, const struct cifsTconInfo *tcon,
pSMB->TotalParameterCount = 12 + name_len /* includes null */ ; pSMB->TotalParameterCount = 12 + name_len /* includes null */ ;
pSMB->TotalDataCount = 0; /* no EAs */ pSMB->TotalDataCount = 0; /* no EAs */
pSMB->MaxParameterCount = cpu_to_le16(10); 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); MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
pSMB->MaxSetupCount = 0; pSMB->MaxSetupCount = 0;
pSMB->Reserved = 0; pSMB->Reserved = 0;
...@@ -1441,7 +1457,7 @@ CIFSFindFirst(const int xid, const struct cifsTconInfo *tcon, ...@@ -1441,7 +1457,7 @@ CIFSFindFirst(const int xid, const struct cifsTconInfo *tcon,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) { /* BB add logic to retry regular search if Unix search rejected unexpectedly by server */ 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 */ } else { /* decode response */
/* BB add safety checks for these memcpys */ /* BB add safety checks for these memcpys */
if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
...@@ -1480,7 +1496,7 @@ CIFSFindNext(const int xid, const struct cifsTconInfo *tcon, ...@@ -1480,7 +1496,7 @@ CIFSFindNext(const int xid, const struct cifsTconInfo *tcon,
int rc = 0; int rc = 0;
int bytes_returned; int bytes_returned;
cFYI(1, ("\nIn FindNext")); cFYI(1, ("In FindNext"));
rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
if (rc) if (rc)
...@@ -1490,7 +1506,7 @@ CIFSFindNext(const int xid, const struct cifsTconInfo *tcon, ...@@ -1490,7 +1506,7 @@ CIFSFindNext(const int xid, const struct cifsTconInfo *tcon,
pSMB->TotalDataCount = 0; /* no EAs */ pSMB->TotalDataCount = 0; /* no EAs */
pSMB->MaxParameterCount = cpu_to_le16(8); pSMB->MaxParameterCount = cpu_to_le16(8);
pSMB->MaxDataCount = 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->MaxSetupCount = 0;
pSMB->Reserved = 0; pSMB->Reserved = 0;
pSMB->Flags = 0; pSMB->Flags = 0;
...@@ -1533,7 +1549,7 @@ CIFSFindNext(const int xid, const struct cifsTconInfo *tcon, ...@@ -1533,7 +1549,7 @@ CIFSFindNext(const int xid, const struct cifsTconInfo *tcon,
if (rc == -EBADF) if (rc == -EBADF)
rc = 0; /* search probably was closed at end of search above */ rc = 0; /* search probably was closed at end of search above */
else else
cFYI(1, ("\nFindNext returned = %d\n", rc)); cFYI(1, ("FindNext returned = %d", rc));
} else { /* decode response */ } else { /* decode response */
/* BB add safety checks for these memcpys */ /* BB add safety checks for these memcpys */
if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
...@@ -1574,7 +1590,7 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, ...@@ -1574,7 +1590,7 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
*number_of_UNC_in_array = 0; *number_of_UNC_in_array = 0;
*targetUNCs = NULL; *targetUNCs = NULL;
cFYI(1, ("\nIn GetDFSRefer the path %s", searchName)); cFYI(1, ("In GetDFSRefer the path %s", searchName));
if (ses == NULL) if (ses == NULL)
return -ENODEV; return -ENODEV;
...@@ -1591,7 +1607,7 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, ...@@ -1591,7 +1607,7 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
if (ses->capabilities & CAP_DFS) { if (ses->capabilities & CAP_DFS) {
pSMB->hdr.Flags2 |= SMBFLG2_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; pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
if (ses->capabilities & CAP_UNICODE) { if (ses->capabilities & CAP_UNICODE) {
...@@ -1604,7 +1620,6 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, ...@@ -1604,7 +1620,6 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
name_len++; /* trailing null */ name_len++; /* trailing null */
name_len *= 2; name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */ } else { /* BB improve the check for buffer overruns BB */
name_len = strnlen(searchName, 530); name_len = strnlen(searchName, 530);
name_len++; /* trailing null */ name_len++; /* trailing null */
strncpy(pSMB->RequestFileName, searchName, name_len); strncpy(pSMB->RequestFileName, searchName, name_len);
...@@ -1636,7 +1651,7 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, ...@@ -1636,7 +1651,7 @@ CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB, rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) { if (rc) {
cFYI(1, ("\nSend error in GetDFSRefer = %d\n", rc)); cFYI(1, ("Send error in GetDFSRefer = %d", rc));
} else { /* decode response */ } else { /* decode response */
/* BB Add logic to parse referrals here */ /* BB Add logic to parse referrals here */
} }
...@@ -1656,7 +1671,7 @@ CIFSSMBQFSInfo(const int xid, const struct cifsTconInfo *tcon, ...@@ -1656,7 +1671,7 @@ CIFSSMBQFSInfo(const int xid, const struct cifsTconInfo *tcon,
int rc = 0; int rc = 0;
int bytes_returned = 0; int bytes_returned = 0;
cFYI(1, ("\nIn QFSInfo")); cFYI(1, ("In QFSInfo"));
rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
...@@ -1689,11 +1704,11 @@ CIFSSMBQFSInfo(const int xid, const struct cifsTconInfo *tcon, ...@@ -1689,11 +1704,11 @@ CIFSSMBQFSInfo(const int xid, const struct cifsTconInfo *tcon,
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) { if (rc) {
cERROR(1, ("\nSend error in QFSInfo = %d\n", rc)); cERROR(1, ("Send error in QFSInfo = %d", rc));
} else { /* decode response */ } else { /* decode response */
pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset); pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
cFYI(1, cFYI(1,
("\nDecoding qfsinfo response. BCC: %d Offset %d\n", ("Decoding qfsinfo response. BCC: %d Offset %d",
pSMBr->ByteCount, pSMBr->DataOffset)); pSMBr->ByteCount, pSMBr->DataOffset));
if ((pSMBr->ByteCount < 24) || (pSMBr->DataOffset > 512)) /* BB also check enough total bytes returned */ if ((pSMBr->ByteCount < 24) || (pSMBr->DataOffset > 512)) /* BB also check enough total bytes returned */
rc = -EIO; /* bad smb */ rc = -EIO; /* bad smb */
...@@ -1711,7 +1726,7 @@ CIFSSMBQFSInfo(const int xid, const struct cifsTconInfo *tcon, ...@@ -1711,7 +1726,7 @@ CIFSSMBQFSInfo(const int xid, const struct cifsTconInfo *tcon,
FSData->f_bfree = FSData->f_bavail = FSData->f_bfree = FSData->f_bavail =
le64_to_cpu(response_data->FreeAllocationUnits); le64_to_cpu(response_data->FreeAllocationUnits);
cFYI(1, 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_blocks, FSData->f_bfree,
FSData->f_bsize)); FSData->f_bsize));
} }
...@@ -1732,7 +1747,7 @@ CIFSSMBQFSAttributeInfo(int xid, struct cifsTconInfo *tcon, ...@@ -1732,7 +1747,7 @@ CIFSSMBQFSAttributeInfo(int xid, struct cifsTconInfo *tcon,
int rc = 0; int rc = 0;
int bytes_returned = 0; int bytes_returned = 0;
cFYI(1, ("\nIn QFSAttributeInfo")); cFYI(1, ("In QFSAttributeInfo"));
rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
if (rc) if (rc)
...@@ -1764,7 +1779,7 @@ CIFSSMBQFSAttributeInfo(int xid, struct cifsTconInfo *tcon, ...@@ -1764,7 +1779,7 @@ CIFSSMBQFSAttributeInfo(int xid, struct cifsTconInfo *tcon,
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) { if (rc) {
cERROR(1, ("\nSend error in QFSAttributeInfo = %d\n", rc)); cERROR(1, ("Send error in QFSAttributeInfo = %d", rc));
} else { /* decode response */ } else { /* decode response */
pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset); pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
if ((pSMBr->ByteCount < 13) || (pSMBr->DataOffset > 512)) { /* BB also check enough bytes returned */ if ((pSMBr->ByteCount < 13) || (pSMBr->DataOffset > 512)) { /* BB also check enough bytes returned */
...@@ -1794,7 +1809,7 @@ CIFSSMBQFSDeviceInfo(int xid, struct cifsTconInfo *tcon, ...@@ -1794,7 +1809,7 @@ CIFSSMBQFSDeviceInfo(int xid, struct cifsTconInfo *tcon,
int rc = 0; int rc = 0;
int bytes_returned = 0; int bytes_returned = 0;
cFYI(1, ("\nIn QFSDeviceInfo")); cFYI(1, ("In QFSDeviceInfo"));
rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
...@@ -1828,7 +1843,7 @@ CIFSSMBQFSDeviceInfo(int xid, struct cifsTconInfo *tcon, ...@@ -1828,7 +1843,7 @@ CIFSSMBQFSDeviceInfo(int xid, struct cifsTconInfo *tcon,
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) { if (rc) {
cERROR(1, ("\nSend error in QFSDeviceInfo = %d\n", rc)); cERROR(1, ("Send error in QFSDeviceInfo = %d", rc));
} else { /* decode response */ } else { /* decode response */
pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset); pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
if ((pSMBr->ByteCount < sizeof (FILE_SYSTEM_DEVICE_INFO)) if ((pSMBr->ByteCount < sizeof (FILE_SYSTEM_DEVICE_INFO))
...@@ -1859,7 +1874,7 @@ CIFSSMBQFSUnixInfo(int xid, struct cifsTconInfo *tcon, ...@@ -1859,7 +1874,7 @@ CIFSSMBQFSUnixInfo(int xid, struct cifsTconInfo *tcon,
int rc = 0; int rc = 0;
int bytes_returned = 0; int bytes_returned = 0;
cFYI(1, ("\nIn QFSUnixInfo")); cFYI(1, ("In QFSUnixInfo"));
rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
if (rc) if (rc)
...@@ -1891,7 +1906,7 @@ CIFSSMBQFSUnixInfo(int xid, struct cifsTconInfo *tcon, ...@@ -1891,7 +1906,7 @@ CIFSSMBQFSUnixInfo(int xid, struct cifsTconInfo *tcon,
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) { if (rc) {
cERROR(1, ("\nSend error in QFSUnixInfo = %d\n", rc)); cERROR(1, ("Send error in QFSUnixInfo = %d", rc));
} else { /* decode response */ } else { /* decode response */
pSMBr->DataOffset = cpu_to_le16(pSMBr->DataOffset); pSMBr->DataOffset = cpu_to_le16(pSMBr->DataOffset);
if ((pSMBr->ByteCount < 13) || (pSMBr->DataOffset > 512)) { if ((pSMBr->ByteCount < 13) || (pSMBr->DataOffset > 512)) {
...@@ -1927,7 +1942,7 @@ CIFSSMBSetEOF(int xid, struct cifsTconInfo *tcon, char *fileName, ...@@ -1927,7 +1942,7 @@ CIFSSMBSetEOF(int xid, struct cifsTconInfo *tcon, char *fileName,
int rc = 0; int rc = 0;
int bytes_returned = 0; int bytes_returned = 0;
cFYI(1, ("\nIn SetEOF")); cFYI(1, ("In SetEOF"));
rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
...@@ -1942,7 +1957,6 @@ CIFSSMBSetEOF(int xid, struct cifsTconInfo *tcon, char *fileName, ...@@ -1942,7 +1957,6 @@ CIFSSMBSetEOF(int xid, struct cifsTconInfo *tcon, char *fileName,
name_len++; /* trailing null */ name_len++; /* trailing null */
name_len *= 2; name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */ } else { /* BB improve the check for buffer overruns BB */
name_len = strnlen(fileName, 530); name_len = strnlen(fileName, 530);
name_len++; /* trailing null */ name_len++; /* trailing null */
strncpy(pSMB->FileName, fileName, name_len); strncpy(pSMB->FileName, fileName, name_len);
...@@ -1995,7 +2009,7 @@ CIFSSMBSetEOF(int xid, struct cifsTconInfo *tcon, char *fileName, ...@@ -1995,7 +2009,7 @@ CIFSSMBSetEOF(int xid, struct cifsTconInfo *tcon, char *fileName,
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) { if (rc) {
cFYI(1, ("\nSetPathInfo (file size) returned %d\n", rc)); cFYI(1, ("SetPathInfo (file size) returned %d", rc));
} }
if (pSMB) if (pSMB)
...@@ -2015,7 +2029,7 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size, ...@@ -2015,7 +2029,7 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
int bytes_returned = 0; int bytes_returned = 0;
__u32 tmp; __u32 tmp;
cFYI(1, ("\nSetFileSize (via SetFileInfo)")); cFYI(1, ("SetFileSize (via SetFileInfo)"));
rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
...@@ -2080,7 +2094,7 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size, ...@@ -2080,7 +2094,7 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) { if (rc) {
cFYI(1, cFYI(1,
("\nSend error in SetFileInfo (SetFileSize) = %d\n", ("Send error in SetFileInfo (SetFileSize) = %d",
rc)); rc));
} }
...@@ -2100,7 +2114,7 @@ CIFSSMBSetTimes(int xid, struct cifsTconInfo *tcon, char *fileName, ...@@ -2100,7 +2114,7 @@ CIFSSMBSetTimes(int xid, struct cifsTconInfo *tcon, char *fileName,
int bytes_returned = 0; int bytes_returned = 0;
char *data_offset; char *data_offset;
cFYI(1, ("\nIn SetTimes")); cFYI(1, ("In SetTimes"));
rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
...@@ -2115,7 +2129,6 @@ CIFSSMBSetTimes(int xid, struct cifsTconInfo *tcon, char *fileName, ...@@ -2115,7 +2129,6 @@ CIFSSMBSetTimes(int xid, struct cifsTconInfo *tcon, char *fileName,
name_len++; /* trailing null */ name_len++; /* trailing null */
name_len *= 2; name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */ } else { /* BB improve the check for buffer overruns BB */
name_len = strnlen(fileName, 530); name_len = strnlen(fileName, 530);
name_len++; /* trailing null */ name_len++; /* trailing null */
strncpy(pSMB->FileName, fileName, name_len); strncpy(pSMB->FileName, fileName, name_len);
...@@ -2156,7 +2169,7 @@ CIFSSMBSetTimes(int xid, struct cifsTconInfo *tcon, char *fileName, ...@@ -2156,7 +2169,7 @@ CIFSSMBSetTimes(int xid, struct cifsTconInfo *tcon, char *fileName,
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) { if (rc) {
cFYI(1, ("\nSetPathInfo (times) returned %d\n", rc)); cFYI(1, ("SetPathInfo (times) returned %d", rc));
} }
if (pSMB) if (pSMB)
...@@ -2176,7 +2189,7 @@ CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon, ...@@ -2176,7 +2189,7 @@ CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon,
int bytes_returned = 0; int bytes_returned = 0;
FILE_UNIX_BASIC_INFO *data_offset; 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, rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
(void **) &pSMBr); (void **) &pSMBr);
...@@ -2191,7 +2204,6 @@ CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon, ...@@ -2191,7 +2204,6 @@ CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon,
name_len++; /* trailing null */ name_len++; /* trailing null */
name_len *= 2; name_len *= 2;
} else { /* BB improve the check for buffer overruns BB */ } else { /* BB improve the check for buffer overruns BB */
name_len = strnlen(fileName, 530); name_len = strnlen(fileName, 530);
name_len++; /* trailing null */ name_len++; /* trailing null */
strncpy(pSMB->FileName, fileName, name_len); strncpy(pSMB->FileName, fileName, name_len);
...@@ -2232,7 +2244,7 @@ CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon, ...@@ -2232,7 +2244,7 @@ CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon,
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0); (struct smb_hdr *) pSMBr, &bytes_returned, 0);
if (rc) { if (rc) {
cFYI(1, ("\nSetPathInfo (perms) returned %d\n", rc)); cFYI(1, ("SetPathInfo (perms) returned %d", rc));
} }
if (pSMB) if (pSMB)
......
...@@ -60,22 +60,61 @@ struct smb_vol { ...@@ -60,22 +60,61 @@ struct smb_vol {
int ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket); 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 int
cifs_reconnect(struct TCP_Server_Info *server) cifs_reconnect(struct TCP_Server_Info *server)
{ {
int rc = 0; int rc = 0;
struct list_head *tmp;
struct cifsSesInfo *ses;
cFYI(1, ("\nReconnecting tcp session ")); server->tcpStatus = CifsNeedReconnect;
server->maxBuf = 0;
/* lock tcp session */ cFYI(1, ("Reconnecting tcp session "));
/* mark all smb sessions as reconnecting which use this tcp session */
/* reconnect tcp session */ read_lock(&GlobalSMBSeslock);
/* wake up waiters on reconnection */ list_for_each(tmp, &GlobalSMBSessionList) {
cFYI(1, ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
("\nState: 0x%x Flags: 0x%lx", server->ssocket->state, 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)); 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; return rc;
} }
...@@ -99,7 +138,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -99,7 +138,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
allow_signal(SIGKILL); allow_signal(SIGKILL);
server->tsk = current; /* save process info to wake at shutdown */ 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 */ temp_fs = get_fs(); /* we must turn off socket api parm checking */
set_fs(get_ds()); set_fs(get_ds());
...@@ -112,7 +151,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -112,7 +151,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
if (smb_buffer == NULL) { if (smb_buffer == NULL) {
cERROR(1, cERROR(1,
("\n Error - can not get mem for SMB response buffer ")); ("Can not get mem for SMB response buffer "));
return -ENOMEM; return -ENOMEM;
} }
iov.iov_base = smb_buffer; iov.iov_base = smb_buffer;
...@@ -130,25 +169,26 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -130,25 +169,26 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
MSG_PEEK /* flags see socket.h */ ); MSG_PEEK /* flags see socket.h */ );
if (length < 0) { if (length < 0) {
if (length == -ECONNRESET) { if (length == -ECONNRESET) {
cERROR(1, ("\nConnection reset by peer ")); cERROR(1, ("Connection reset by peer "));
/* BB fix call below */ cifs_reconnect(server);
/* cifs_reconnect(server); */ csocket = server->ssocket;
continue;
} else { /* find define for the -512 returned at unmount time */ } else { /* find define for the -512 returned at unmount time */
cFYI(1, cFYI(1,
("\nReceived error on sock_recvmsg( peek) with length = %d\n", ("Received error on sock_recvmsg( peek) with length = %d",
length)); length));
} }
break; break;
} }
if (length == 0) { if (length == 0) {
cFYI(1, cFYI(1,
("\nZero length peek received - dead session?? ")); ("Zero length peek received - dead session?"));
/* schedule_timeout(HZ/4); cifs_reconnect(server);
continue; */ csocket = server->ssocket;
break; continue;
} }
pdu_length = 4 + ntohl(smb_buffer->smb_buf_length); 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; temp = (char *) smb_buffer;
if (length > 3) { if (length > 3) {
...@@ -157,18 +197,18 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -157,18 +197,18 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
iov.iov_len = 4; iov.iov_len = 4;
length = sock_recvmsg(csocket, &smb_msg, 4, 0); length = sock_recvmsg(csocket, &smb_msg, 4, 0);
cFYI(0, cFYI(0,
("\nReceived 4 byte keep alive packet ")); ("Received 4 byte keep alive packet "));
} else if ((temp[0] == (char) 0x83) } else if ((temp[0] == (char) 0x83)
&& (length == 5)) { && (length == 5)) {
/* we get this from Windows 98 instead of error on SMB negprot response */ /* we get this from Windows 98 instead of error on SMB negprot response */
cERROR(1, cERROR(1,
("\nNegative RFC 1002 Session response. Error = 0x%x", ("Negative RFC 1002 Session response. Error = 0x%x",
temp[4])); temp[4]));
break; break;
} else if (temp[0] != (char) 0) { } else if (temp[0] != (char) 0) {
cERROR(1, 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); cifs_dump_mem(" Received Data is: ", temp, length);
break; break;
} else { } else {
...@@ -182,7 +222,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -182,7 +222,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
(smb_buffer, smb_buffer->Mid))) { (smb_buffer, smb_buffer->Mid))) {
cERROR(1, cERROR(1,
(KERN_ERR (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)); length, pdu_length));
/* BB fix by finding next smb signature - and reading off data until next smb ? BB */ /* BB fix by finding next smb signature - and reading off data until next smb ? BB */
...@@ -200,11 +240,11 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -200,11 +240,11 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
iov.iov_len = pdu_length-total_read; */ iov.iov_len = pdu_length-total_read; */
length = sock_recvmsg(csocket, &smb_msg, length = sock_recvmsg(csocket, &smb_msg,
pdu_length - total_read, 0); 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)); */ iov.iov_len, length,total_read)); */
if (length == 0) { if (length == 0) {
cERROR(1, cERROR(1,
("\nZero length receive when expecting %d ", ("Zero length receive when expecting %d ",
pdu_length - total_read)); pdu_length - total_read));
/* BB add reconnect here */ /* BB add reconnect here */
break; break;
...@@ -215,7 +255,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -215,7 +255,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
dump_smb(smb_buffer, length); dump_smb(smb_buffer, length);
if (checkSMB if (checkSMB
(smb_buffer, smb_buffer->Mid, total_read)) { (smb_buffer, smb_buffer->Mid, total_read)) {
cERROR(1, ("\n Bad SMB Received ")); cERROR(1, ("Bad SMB Received "));
continue; continue;
} }
...@@ -228,7 +268,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -228,7 +268,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
if (mid_entry->mid == smb_buffer->Mid) { if (mid_entry->mid == smb_buffer->Mid) {
cFYI(1, 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; task_to_wake = mid_entry->tsk;
mid_entry->resp_buf = mid_entry->resp_buf =
smb_buffer; smb_buffer;
...@@ -241,17 +281,17 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -241,17 +281,17 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
smb_buffer = NULL; /* will be freed by users thread after he is done */ smb_buffer = NULL; /* will be freed by users thread after he is done */
wake_up_process(task_to_wake); wake_up_process(task_to_wake);
} else if (is_valid_oplock_break(smb_buffer) == FALSE) { } 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 { } else {
cFYI(0, cFYI(0,
("\nFrame less than four bytes received %d bytes long.", ("Frame less than four bytes received %d bytes long.",
length)); length));
if (length > 0) { if (length > 0) {
length = sock_recvmsg(csocket, &smb_msg, length, 0); /* throw away junk frame */ length = sock_recvmsg(csocket, &smb_msg, length, 0); /* throw away junk frame */
cFYI(1, cFYI(1,
(" with junk 0x%x in it\n", (" with junk 0x%x in it ",
*(__u32 *) smb_buffer)); *(__u32 *) smb_buffer));
} }
} }
...@@ -280,13 +320,12 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) ...@@ -280,13 +320,12 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
kfree(server); kfree(server);
} else /* BB need to more gracefully handle the rare negative session } else /* BB need to more gracefully handle the rare negative session
response case because response will be still outstanding */ 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 /* 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 */ time out and then free the tcp per server struct BB */
read_unlock(&GlobalSMBSeslock); read_unlock(&GlobalSMBSeslock);
cFYI(1, ("About to exit from demultiplex thread"));
cFYI(1, ("\nAbout to exit from demultiplex thread\n"));
return 0; return 0;
} }
...@@ -315,14 +354,14 @@ parse_mount_options(char *options, char *devname, struct smb_vol *vol) ...@@ -315,14 +354,14 @@ parse_mount_options(char *options, char *devname, struct smb_vol *vol)
*value++ = '\0'; *value++ = '\0';
if (strnicmp(data, "user", 4) == 0) { if (strnicmp(data, "user", 4) == 0) {
if (!value || !*value) { if (!value || !*value) {
printk(KERN_ERR printk(KERN_WARNING
"CIFS: invalid or missing username"); "CIFS: invalid or missing username\n");
return 1; /* needs_arg; */ return 1; /* needs_arg; */
} }
if (strnlen(value, 200) < 200) { if (strnlen(value, 200) < 200) {
vol->username = value; vol->username = value;
} else { } else {
printk(KERN_ERR "CIFS: username too long"); printk(KERN_WARNING "CIFS: username too long\n");
return 1; return 1;
} }
} else if (strnicmp(data, "pass", 4) == 0) { } else if (strnicmp(data, "pass", 4) == 0) {
...@@ -331,15 +370,15 @@ parse_mount_options(char *options, char *devname, struct smb_vol *vol) ...@@ -331,15 +370,15 @@ parse_mount_options(char *options, char *devname, struct smb_vol *vol)
} else if (strnlen(value, 17) < 17) { } else if (strnlen(value, 17) < 17) {
vol->password = value; vol->password = value;
} else { } else {
printk(KERN_ERR "CIFS: password too long"); printk(KERN_WARNING "CIFS: password too long\n");
return 1; return 1;
} }
} else if ((strnicmp(data, "unc", 3) == 0) } else if ((strnicmp(data, "unc", 3) == 0)
|| (strnicmp(data, "target", 6) == 0) || (strnicmp(data, "target", 6) == 0)
|| (strnicmp(data, "path", 4) == 0)) { || (strnicmp(data, "path", 4) == 0)) {
if (!value || !*value) { if (!value || !*value) {
printk(KERN_ERR printk(KERN_WARNING
"CIFS: invalid path to network resource"); "CIFS: invalid path to network resource\n");
return 1; /* needs_arg; */ return 1; /* needs_arg; */
} }
if (strnlen(value, 300) < 300) { if (strnlen(value, 300) < 300) {
...@@ -348,26 +387,26 @@ parse_mount_options(char *options, char *devname, struct smb_vol *vol) ...@@ -348,26 +387,26 @@ parse_mount_options(char *options, char *devname, struct smb_vol *vol)
vol->UNC[0] = '\\'; vol->UNC[0] = '\\';
vol->UNC[1] = '\\'; vol->UNC[1] = '\\';
} else if (strncmp(vol->UNC, "\\\\", 2) != 0) { } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
printk(KERN_ERR printk(KERN_WARNING
"CIFS: UNC Path does not begin with // or \\\\"); "CIFS: UNC Path does not begin with // or \\\\ \n");
return 1; return 1;
} }
vol->UNCip = &vol->UNC[2]; vol->UNCip = &vol->UNC[2];
} else { } else {
printk(KERN_ERR "CIFS: UNC name too long"); printk(KERN_WARNING "CIFS: UNC name too long\n");
return 1; return 1;
} }
} else if ((strnicmp(data, "domain", 3) == 0) } else if ((strnicmp(data, "domain", 3) == 0)
|| (strnicmp(data, "workgroup", 5) == 0)) { || (strnicmp(data, "workgroup", 5) == 0)) {
if (!value || !*value) { if (!value || !*value) {
printk(KERN_ERR "CIFS: invalid domain name"); printk(KERN_WARNING "CIFS: invalid domain name\n");
return 1; /* needs_arg; */ return 1; /* needs_arg; */
} }
if (strnlen(value, 65) < 65) { if (strnlen(value, 65) < 65) {
vol->domainname = value; vol->domainname = value;
cFYI(1, ("\nDomain name set")); cFYI(1, ("Domain name set"));
} else { } else {
printk(KERN_ERR "CIFS: domain name too long"); printk(KERN_WARNING "CIFS: domain name too long\n");
return 1; return 1;
} }
} else if (strnicmp(data, "uid", 3) == 0) { } else if (strnicmp(data, "uid", 3) == 0) {
...@@ -395,9 +434,7 @@ parse_mount_options(char *options, char *devname, struct smb_vol *vol) ...@@ -395,9 +434,7 @@ parse_mount_options(char *options, char *devname, struct smb_vol *vol)
} else if (strnicmp(data, "rw", 2) == 0) { } else if (strnicmp(data, "rw", 2) == 0) {
vol->rw = TRUE; vol->rw = TRUE;
} else } else
printk(KERN_ERR printk(KERN_WARNING "CIFS: Unknown mount option %s\n",data);
"CIFS: Unrecognized mount option %s = %s",
data, value);
} }
if (vol->UNC == NULL) { if (vol->UNC == NULL) {
if (strnlen(devname, 300) < 300) { if (strnlen(devname, 300) < 300) {
...@@ -406,13 +443,12 @@ parse_mount_options(char *options, char *devname, struct smb_vol *vol) ...@@ -406,13 +443,12 @@ parse_mount_options(char *options, char *devname, struct smb_vol *vol)
vol->UNC[0] = '\\'; vol->UNC[0] = '\\';
vol->UNC[1] = '\\'; vol->UNC[1] = '\\';
} else if (strncmp(vol->UNC, "\\\\", 2) != 0) { } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
printk(KERN_ERR printk(KERN_WARNING "CIFS: UNC Path does not begin with // or \\\\ \n");
"CIFS: UNC Path does not begin with // or \\\\");
return 1; return 1;
} }
vol->UNCip = &vol->UNC[2]; vol->UNCip = &vol->UNC[2];
} else { } else {
printk(KERN_ERR "CIFS: UNC name too long"); printk(KERN_WARNING "CIFS: UNC name too long\n");
return 1; return 1;
} }
} }
...@@ -458,7 +494,7 @@ find_unc(__u32 new_target_ip_addr, char *uncName, char *userName) ...@@ -458,7 +494,7 @@ find_unc(__u32 new_target_ip_addr, char *uncName, char *userName)
read_lock(&GlobalSMBSeslock); read_lock(&GlobalSMBSeslock);
list_for_each(tmp, &GlobalTreeConnectionList) { list_for_each(tmp, &GlobalTreeConnectionList) {
cFYI(1, ("\nNext tcon - ")); cFYI(1, ("Next tcon - "));
tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
if (tcon->ses) { if (tcon->ses) {
if (tcon->ses->server) { if (tcon->ses->server) {
...@@ -472,13 +508,13 @@ find_unc(__u32 new_target_ip_addr, char *uncName, char *userName) ...@@ -472,13 +508,13 @@ find_unc(__u32 new_target_ip_addr, char *uncName, char *userName)
/* found a match on the TCP session */ /* found a match on the TCP session */
/* BB check if reconnection needed */ /* BB check if reconnection needed */
cFYI(1, cFYI(1,
("\nMatched ip, old UNC: %s == new: %s ?", ("Matched ip, old UNC: %s == new: %s ?",
tcon->treeName, uncName)); tcon->treeName, uncName));
if (strncmp if (strncmp
(tcon->treeName, uncName, (tcon->treeName, uncName,
MAX_TREE_SIZE) == 0) { MAX_TREE_SIZE) == 0) {
cFYI(1, cFYI(1,
("\nMatched UNC, old user: %s == new: %s ?", ("Matched UNC, old user: %s == new: %s ?",
tcon->treeName, uncName)); tcon->treeName, uncName));
if (strncmp if (strncmp
(tcon->ses->userName, (tcon->ses->userName,
...@@ -522,27 +558,104 @@ connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo, ...@@ -522,27 +558,104 @@ connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
SERVER_NAME_LEN_WITH_NULL * 2), "\\IPC$", 6); SERVER_NAME_LEN_WITH_NULL * 2), "\\IPC$", 6);
rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage); rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);
cFYI(1, cFYI(1,
("\nCIFS Tcon rc = %d ipc_tid = %d\n", rc, ("CIFS Tcon rc = %d ipc_tid = %d", rc,pSesInfo->ipc_tid));
pSesInfo->ipc_tid));
kfree(temp_unc); kfree(temp_unc);
} }
if (rc == 0) if (rc == 0)
rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, &referrals, rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, &referrals,
&num_referrals, nls_codepage); &num_referrals, nls_codepage);
return -ENODEV; /* BB remove and add return rc; */ return -ENODEV; /* BB remove and add return code processing */
} }
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 int
ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket) ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket)
{ {
int rc = 0; int rc = 0;
if(*csocket == NULL) {
rc = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, csocket); rc = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, csocket);
if (rc < 0) { if (rc < 0) {
cERROR(1, ("Error creating socket. Aborting operation\n")); cERROR(1, ("Error %d creating socket",rc));
*csocket = NULL;
return rc; return rc;
} else {
cFYI(1,("Socket created"));
}
} }
psin_server->sin_family = AF_INET; psin_server->sin_family = AF_INET;
...@@ -550,17 +663,13 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket) ...@@ -550,17 +663,13 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket)
rc = (*csocket)->ops->connect(*csocket, rc = (*csocket)->ops->connect(*csocket,
(struct sockaddr *) psin_server, (struct sockaddr *) psin_server,
sizeof (struct sockaddr_in), 0 sizeof (struct sockaddr_in),0);
/* Is there a way to fix a polling timeout -
and find out what more of the flags really mean? */
);
if (rc < 0) { if (rc < 0) {
psin_server->sin_port = htons(RFC1001_PORT); psin_server->sin_port = htons(RFC1001_PORT);
rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *) rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
psin_server, psin_server, sizeof (struct sockaddr_in),0);
sizeof (struct sockaddr_in), 0);
if (rc < 0) { if (rc < 0) {
cFYI(1, ("Error connecting to socket. %d\n", rc)); cFYI(1, ("Error connecting to socket. %d", rc));
sock_release(*csocket); sock_release(*csocket);
*csocket = NULL; *csocket = NULL;
return rc; return rc;
...@@ -578,7 +687,7 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket) ...@@ -578,7 +687,7 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
rc = sock_create(PF_INET6, SOCK_STREAM, rc = sock_create(PF_INET6, SOCK_STREAM,
IPPROTO_TCP /* IPPROTO_IPV6 ? */ , csocket); IPPROTO_TCP /* IPPROTO_IPV6 ? */ , csocket);
if (rc < 0) { if (rc < 0) {
cERROR(1, ("Error creating socket. Aborting operation\n")); cERROR(1, ("Error creating socket. Aborting operation"));
return rc; return rc;
} }
...@@ -597,7 +706,7 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket) ...@@ -597,7 +706,7 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
sizeof (struct sockaddr_in6), 0); sizeof (struct sockaddr_in6), 0);
if (rc < 0) { if (rc < 0) {
cFYI(1, cFYI(1,
("Error connecting to socket (via ipv6). %d\n", ("Error connecting to socket (via ipv6). %d",
rc)); rc));
sock_release(*csocket); sock_release(*csocket);
*csocket = NULL; *csocket = NULL;
...@@ -614,8 +723,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -614,8 +723,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
{ {
int rc = 0; int rc = 0;
int xid; int xid;
int ntlmv2_flag = FALSE; struct socket *csocket = NULL;
struct socket *csocket;
struct sockaddr_in sin_server; struct sockaddr_in sin_server;
/* struct sockaddr_in6 sin_server6; */ /* struct sockaddr_in6 sin_server6; */
struct smb_vol volume_info; struct smb_vol volume_info;
...@@ -623,35 +731,33 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -623,35 +731,33 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
struct cifsSesInfo *existingCifsSes = NULL; struct cifsSesInfo *existingCifsSes = NULL;
struct cifsTconInfo *tcon = NULL; struct cifsTconInfo *tcon = NULL;
struct TCP_Server_Info *srvTcp = 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(); 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)) { if(parse_mount_options(mount_data, devname, &volume_info)) {
FreeXid(xid); FreeXid(xid);
return -EINVAL; return -EINVAL;
} }
if (volume_info.username) { if (volume_info.username) {
cFYI(1, ("\nUsername: %s ", volume_info.username)); cFYI(1, ("Username: %s ", volume_info.username));
} else { } else {
cERROR(1, ("\nNo username specified ")); cifserror("No username specified ");
/* Could add ways to allow getting user name from alternate locations */ /* 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) { if (volume_info.UNC) {
sin_server.sin_addr.s_addr = inet_addr(volume_info.UNCip); 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 { } else {
/* BB we could connect to the DFS root? but which server do we ask? */ /* BB we could connect to the DFS root? but which server do we ask? */
cERROR(1, 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); FreeXid(xid);
return -EINVAL; return -EINVAL;
} }
...@@ -660,12 +766,14 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -660,12 +766,14 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
find_tcp_session(sin_server.sin_addr.s_addr, find_tcp_session(sin_server.sin_addr.s_addr,
volume_info.username, &srvTcp); volume_info.username, &srvTcp);
if (srvTcp) { if (srvTcp) {
cFYI(1, ("\nExisting tcp session with server found ")); cFYI(1, ("Existing tcp session with server found "));
} else { /* create socket */ } else { /* create socket */
rc = ipv4_connect(&sin_server, &csocket); rc = ipv4_connect(&sin_server, &csocket);
if (rc < 0) { if (rc < 0) {
cERROR(1, 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); FreeXid(xid);
return rc; return rc;
} }
...@@ -683,6 +791,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -683,6 +791,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
srvTcp->ssocket = csocket; srvTcp->ssocket = csocket;
init_waitqueue_head(&srvTcp->response_q); init_waitqueue_head(&srvTcp->response_q);
INIT_LIST_HEAD(&srvTcp->pending_mid_q); INIT_LIST_HEAD(&srvTcp->pending_mid_q);
srvTcp->tcpStatus = CifsGood;
kernel_thread((void *) (void *) kernel_thread((void *) (void *)
cifs_demultiplex_thread, srvTcp, cifs_demultiplex_thread, srvTcp,
CLONE_FS | CLONE_FILES | CLONE_VM); CLONE_FS | CLONE_FILES | CLONE_VM);
...@@ -691,115 +800,34 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -691,115 +800,34 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
if (existingCifsSes) { if (existingCifsSes) {
pSesInfo = existingCifsSes; pSesInfo = existingCifsSes;
cFYI(1, ("\nExisting smb sess found ")); cFYI(1, ("Existing smb sess found "));
} else if (!rc) { } else if (!rc) {
cFYI(1, ("\nExisting smb sess not found ")); cFYI(1, ("Existing smb sess not found "));
pSesInfo = sesInfoAlloc(); pSesInfo = sesInfoAlloc();
if (pSesInfo == NULL) if (pSesInfo == NULL)
rc = -ENOMEM; rc = -ENOMEM;
else { else {
pSesInfo->server = srvTcp; pSesInfo->server = srvTcp;
pSesInfo->status = CifsGood;
sprintf(pSesInfo->serverName, "%u.%u.%u.%u", sprintf(pSesInfo->serverName, "%u.%u.%u.%u",
NIPQUAD(sin_server.sin_addr.s_addr)); NIPQUAD(sin_server.sin_addr.s_addr));
} }
/* send negotiate protocol smb */ if (!rc){
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 (volume_info.password) if (volume_info.password)
strcpy(password_with_pad, volume_info.password); strncpy(pSesInfo->password_with_pad,
volume_info.password,CIFS_ENCPWD_SIZE);
if (extended_security if (volume_info.username)
&& (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->userName, strncpy(pSesInfo->userName,
volume_info.username, volume_info.username,MAX_USERNAME_SIZE);
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); atomic_inc(&srvTcp->socketUseCount);
} }
} }
}
/* search for existing tcon to this server share */ /* search for existing tcon to this server share */
if (!rc) { if (!rc) {
...@@ -807,7 +835,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -807,7 +835,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
find_unc(sin_server.sin_addr.s_addr, volume_info.UNC, find_unc(sin_server.sin_addr.s_addr, volume_info.UNC,
volume_info.username); volume_info.username);
if (tcon) { if (tcon) {
cFYI(1, ("\nFound match on UNC path ")); cFYI(1, ("Found match on UNC path "));
} else { } else {
tcon = tconInfoAlloc(); tcon = tconInfoAlloc();
if (tcon == NULL) if (tcon == NULL)
...@@ -830,7 +858,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -830,7 +858,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
rc = CIFSTCon(xid, pSesInfo, rc = CIFSTCon(xid, pSesInfo,
volume_info.UNC, volume_info.UNC,
tcon, cifs_sb->local_nls); tcon, cifs_sb->local_nls);
cFYI(1, ("\nCIFS Tcon rc = %d\n", rc)); cFYI(1, ("CIFS Tcon rc = %d", rc));
} }
if (!rc) if (!rc)
atomic_inc(&pSesInfo->inUse); atomic_inc(&pSesInfo->inUse);
...@@ -838,7 +866,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -838,7 +866,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
} }
} }
if (pSesInfo->capabilities & CAP_LARGE_FILES) { if (pSesInfo->capabilities & CAP_LARGE_FILES) {
cFYI(0, ("\nLarge files supported ")); cFYI(0, ("Large files supported "));
sb->s_maxbytes = (u64) 1 << 63; sb->s_maxbytes = (u64) 1 << 63;
} else } else
sb->s_maxbytes = (u64) 1 << 31; /* 2 GB */ sb->s_maxbytes = (u64) 1 << 31; /* 2 GB */
...@@ -851,14 +879,16 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -851,14 +879,16 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
if (existingCifsSes == 0) { if (existingCifsSes == 0) {
if (pSesInfo) { if (pSesInfo) {
if (pSesInfo->server) { if (pSesInfo->server) {
cFYI(0,
("\nAbout to check if we need to do SMBLogoff "));
if (pSesInfo->Suid) if (pSesInfo->Suid)
CIFSSMBLogoff(xid, pSesInfo); 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 */ schedule_timeout(HZ / 4); /* give captive thread time to exit */
} else } else
cFYI(1, ("\nNo session or bad tcon")); cFYI(1, ("No session or bad tcon"));
sesInfoFree(pSesInfo); sesInfoFree(pSesInfo);
/* pSesInfo = NULL; */ /* pSesInfo = NULL; */
} }
...@@ -876,13 +906,12 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -876,13 +906,12 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
} }
FreeXid(xid); FreeXid(xid);
return rc; return rc;
} }
int int
CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, char *user, CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
char *domain, char session_key[CIFS_SESSION_KEY_SIZE], char session_key[CIFS_SESSION_KEY_SIZE],
char session_key2[CIFS_SESSION_KEY_SIZE], char session_key2[CIFS_SESSION_KEY_SIZE],
const struct nls_table *nls_codepage) const struct nls_table *nls_codepage)
{ {
...@@ -891,12 +920,14 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, char *user, ...@@ -891,12 +920,14 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, char *user,
SESSION_SETUP_ANDX *pSMB; SESSION_SETUP_ANDX *pSMB;
SESSION_SETUP_ANDX *pSMBr; SESSION_SETUP_ANDX *pSMBr;
char *bcc_ptr; char *bcc_ptr;
char *user = ses->userName;
char *domain = ses->domainName;
int rc = 0; int rc = 0;
int remaining_words = 0; int remaining_words = 0;
int bytes_returned = 0; int bytes_returned = 0;
int len; int len;
cFYI(1, ("\nIn sesssetup ")); cFYI(1, ("In sesssetup "));
smb_buffer = buf_get(); smb_buffer = buf_get();
if (smb_buffer == 0) { if (smb_buffer == 0) {
...@@ -910,10 +941,10 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, char *user, ...@@ -910,10 +941,10 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, char *user,
0 /* no tCon exists yet */ , 13 /* wct */ ); 0 /* no tCon exists yet */ , 13 /* wct */ );
pSMB->req_no_secext.AndXCommand = 0xFF; pSMB->req_no_secext.AndXCommand = 0xFF;
pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->maxBuf); pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->maxReq); 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; smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
pSMB->req_no_secext.Capabilities = pSMB->req_no_secext.Capabilities =
...@@ -1136,8 +1167,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, char *user, ...@@ -1136,8 +1167,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, char *user,
int int
CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
char *user, char *domain, char *SecurityBlob, char *SecurityBlob,int SecurityBlobLength,
int SecurityBlobLength,
const struct nls_table *nls_codepage) const struct nls_table *nls_codepage)
{ {
struct smb_hdr *smb_buffer; struct smb_hdr *smb_buffer;
...@@ -1145,12 +1175,14 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -1145,12 +1175,14 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
SESSION_SETUP_ANDX *pSMB; SESSION_SETUP_ANDX *pSMB;
SESSION_SETUP_ANDX *pSMBr; SESSION_SETUP_ANDX *pSMBr;
char *bcc_ptr; char *bcc_ptr;
char *user = ses->userName;
char *domain = ses->domainName;
int rc = 0; int rc = 0;
int remaining_words = 0; int remaining_words = 0;
int bytes_returned = 0; int bytes_returned = 0;
int len; int len;
cFYI(1, ("\nIn v2 sesssetup ")); cFYI(1, ("In v2 sesssetup "));
smb_buffer = buf_get(); smb_buffer = buf_get();
if (smb_buffer == 0) { if (smb_buffer == 0) {
...@@ -1164,10 +1196,10 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -1164,10 +1196,10 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
0 /* no tCon exists yet */ , 12 /* wct */ ); 0 /* no tCon exists yet */ , 12 /* wct */ );
pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
pSMB->req.AndXCommand = 0xFF; pSMB->req.AndXCommand = 0xFF;
pSMB->req.MaxBufferSize = cpu_to_le16(ses->maxBuf); pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
pSMB->req.MaxMpxCount = cpu_to_le16(ses->maxReq); 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; smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
pSMB->req.Capabilities = pSMB->req.Capabilities =
...@@ -1276,7 +1308,7 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -1276,7 +1308,7 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
bcc_ptr += bcc_ptr +=
pSMBr->resp.SecurityBlobLength; pSMBr->resp.SecurityBlobLength;
cFYI(1, cFYI(1,
("\nSecurity Blob Length %d ", ("Security Blob Length %d ",
pSMBr->resp.SecurityBlobLength)); pSMBr->resp.SecurityBlobLength));
} }
...@@ -1394,9 +1426,7 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -1394,9 +1426,7 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
int int
CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
struct cifsSesInfo *ses, struct cifsSesInfo *ses, int * pNTLMv2_flag,
char *challenge_from_server,
char *domain, int * pNTLMv2_flag,
const struct nls_table *nls_codepage) const struct nls_table *nls_codepage)
{ {
struct smb_hdr *smb_buffer; struct smb_hdr *smb_buffer;
...@@ -1404,6 +1434,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, ...@@ -1404,6 +1434,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
SESSION_SETUP_ANDX *pSMB; SESSION_SETUP_ANDX *pSMB;
SESSION_SETUP_ANDX *pSMBr; SESSION_SETUP_ANDX *pSMBr;
char *bcc_ptr; char *bcc_ptr;
char *domain = ses->domainName;
int rc = 0; int rc = 0;
int remaining_words = 0; int remaining_words = 0;
int bytes_returned = 0; int bytes_returned = 0;
...@@ -1412,7 +1443,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, ...@@ -1412,7 +1443,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
PNEGOTIATE_MESSAGE SecurityBlob; PNEGOTIATE_MESSAGE SecurityBlob;
PCHALLENGE_MESSAGE SecurityBlob2; PCHALLENGE_MESSAGE SecurityBlob2;
cFYI(1, ("\nIn NTLMSSP sesssetup (negotiate) ")); cFYI(1, ("In NTLMSSP sesssetup (negotiate) "));
*pNTLMv2_flag = FALSE; *pNTLMv2_flag = FALSE;
smb_buffer = buf_get(); smb_buffer = buf_get();
if (smb_buffer == 0) { if (smb_buffer == 0) {
...@@ -1429,10 +1460,10 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, ...@@ -1429,10 +1460,10 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT); pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
pSMB->req.AndXCommand = 0xFF; pSMB->req.AndXCommand = 0xFF;
pSMB->req.MaxBufferSize = cpu_to_le16(ses->maxBuf); pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
pSMB->req.MaxMpxCount = cpu_to_le16(ses->maxReq); 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; smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
pSMB->req.Capabilities = pSMB->req.Capabilities =
...@@ -1555,7 +1586,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, ...@@ -1555,7 +1586,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr; SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr;
if (SecurityBlob2->MessageType != NtLmChallenge) { if (SecurityBlob2->MessageType != NtLmChallenge) {
cFYI(1, cFYI(1,
("\nUnexpected NTLMSSP message type received %d", ("Unexpected NTLMSSP message type received %d",
SecurityBlob2->MessageType)); SecurityBlob2->MessageType));
} else if (ses) { } else if (ses) {
ses->Suid = smb_buffer_response->Uid; /* UID left in le format */ ses->Suid = smb_buffer_response->Uid; /* UID left in le format */
...@@ -1568,13 +1599,13 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, ...@@ -1568,13 +1599,13 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
bcc_ptr += bcc_ptr +=
pSMBr->resp.SecurityBlobLength; pSMBr->resp.SecurityBlobLength;
cFYI(1, cFYI(1,
("\nSecurity Blob Length %d ", ("Security Blob Length %d ",
pSMBr->resp.SecurityBlobLength)); pSMBr->resp.SecurityBlobLength));
} }
cFYI(1, ("\nNTLMSSP Challenge rcvd ")); cFYI(1, ("NTLMSSP Challenge rcvd "));
memcpy(challenge_from_server, memcpy(ses->server->cryptKey,
SecurityBlob2->Challenge, SecurityBlob2->Challenge,
CIFS_CRYPTO_KEY_SIZE); CIFS_CRYPTO_KEY_SIZE);
if(SecurityBlob2->NegotiateFlags & NTLMSSP_NEGOTIATE_NTLMV2) if(SecurityBlob2->NegotiateFlags & NTLMSSP_NEGOTIATE_NTLMV2)
...@@ -1722,9 +1753,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, ...@@ -1722,9 +1753,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
int int
CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
char *user, char *domain, char *ntlm_session_key, char *lanman_session_key, int ntlmv2_flag,
char *ntlm_session_key,
char *lanman_session_key, int ntlmv2_flag,
const struct nls_table *nls_codepage) const struct nls_table *nls_codepage)
{ {
struct smb_hdr *smb_buffer; struct smb_hdr *smb_buffer;
...@@ -1732,6 +1761,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -1732,6 +1761,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
SESSION_SETUP_ANDX *pSMB; SESSION_SETUP_ANDX *pSMB;
SESSION_SETUP_ANDX *pSMBr; SESSION_SETUP_ANDX *pSMBr;
char *bcc_ptr; char *bcc_ptr;
char *user = ses->userName;
char *domain = ses->domainName;
int rc = 0; int rc = 0;
int remaining_words = 0; int remaining_words = 0;
int bytes_returned = 0; int bytes_returned = 0;
...@@ -1739,7 +1770,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -1739,7 +1770,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
int SecurityBlobLength = sizeof (AUTHENTICATE_MESSAGE); int SecurityBlobLength = sizeof (AUTHENTICATE_MESSAGE);
PAUTHENTICATE_MESSAGE SecurityBlob; PAUTHENTICATE_MESSAGE SecurityBlob;
cFYI(1, ("\nIn NTLMSSPSessSetup (Authenticate)")); cFYI(1, ("In NTLMSSPSessSetup (Authenticate)"));
smb_buffer = buf_get(); smb_buffer = buf_get();
if (smb_buffer == 0) { if (smb_buffer == 0) {
...@@ -1755,12 +1786,12 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -1755,12 +1786,12 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT); pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
pSMB->req.AndXCommand = 0xFF; pSMB->req.AndXCommand = 0xFF;
pSMB->req.MaxBufferSize = cpu_to_le16(ses->maxBuf); pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
pSMB->req.MaxMpxCount = cpu_to_le16(ses->maxReq); pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
pSMB->req.hdr.Uid = ses->Suid; 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; smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
pSMB->req.Capabilities = pSMB->req.Capabilities =
...@@ -1949,7 +1980,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -1949,7 +1980,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
if (pSMBr->resp.Action & GUEST_LOGIN) if (pSMBr->resp.Action & GUEST_LOGIN)
cFYI(1, (" Guest login")); /* BB do we want to set anything in SesInfo struct ? */ cFYI(1, (" Guest login")); /* BB do we want to set anything in SesInfo struct ? */
/* if(SecurityBlob2->MessageType != NtLm??){ /* if(SecurityBlob2->MessageType != NtLm??){
cFYI("\nUnexpected message type on auth response is %d ")); cFYI("Unexpected message type on auth response is %d "));
} */ } */
if (ses) { if (ses) {
cFYI(1, cFYI(1,
...@@ -1966,12 +1997,12 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -1966,12 +1997,12 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
bcc_ptr += bcc_ptr +=
pSMBr->resp.SecurityBlobLength; pSMBr->resp.SecurityBlobLength;
cFYI(1, cFYI(1,
("\nSecurity Blob Length %d ", ("Security Blob Length %d ",
pSMBr->resp.SecurityBlobLength)); pSMBr->resp.SecurityBlobLength));
} }
cFYI(1, cFYI(1,
("\nNTLMSSP response to Authenticate ")); ("NTLMSSP response to Authenticate "));
if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) { if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) {
if ((long) (bcc_ptr) % 2) { if ((long) (bcc_ptr) % 2) {
...@@ -2133,7 +2164,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, ...@@ -2133,7 +2164,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
bcc_ptr = &(pSMB->Password[0]); bcc_ptr = &(pSMB->Password[0]);
bcc_ptr++; /* skip password */ 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; smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
if (ses->capabilities & CAP_STATUS32) { if (ses->capabilities & CAP_STATUS32) {
...@@ -2200,7 +2231,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, ...@@ -2200,7 +2231,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
/* else do not bother copying these informational fields */ /* else do not bother copying these informational fields */
} }
tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport); 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) { } else if ((rc == 0) && tcon == NULL) {
/* all we need to save for IPC$ connection */ /* all we need to save for IPC$ connection */
ses->ipc_tid = smb_buffer_response->Tid; ses->ipc_tid = smb_buffer_response->Tid;
...@@ -2229,27 +2260,28 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) ...@@ -2229,27 +2260,28 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
} }
tconInfoFree(cifs_sb->tcon); tconInfoFree(cifs_sb->tcon);
if ((ses) && (ses->server)) { if ((ses) && (ses->server)) {
cFYI(1, ("\nAbout to do SMBLogoff ")); cFYI(1, ("About to do SMBLogoff "));
rc = CIFSSMBLogoff(xid, ses); rc = CIFSSMBLogoff(xid, ses);
if (rc == -EBUSY) { if (rc == -EBUSY) {
/* BB this looks wrong - why is this here? */
FreeXid(xid); FreeXid(xid);
return 0; return 0;
} }
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ / 4); /* give captive thread time to exit */ schedule_timeout(HZ / 4); /* give captive thread time to exit */
if((ses->server) && (ses->server->ssocket)) { 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); send_sig(SIGINT,ses->server->tsk,1);
} }
} else } 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 */ /* BB future check active count of tcon and then free if needed BB */
cifs_sb->tcon = NULL; cifs_sb->tcon = NULL;
if (ses) { if (ses) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(HZ / 2); schedule_timeout(HZ / 2);
/* if ((ses->server) && (ses->server->ssocket)) { /* if ((ses->server) && (ses->server->ssocket)) {
cFYI(1,("\nReleasing socket ")); cFYI(1,("Releasing socket "));
sock_release(ses->server->ssocket); sock_release(ses->server->ssocket);
kfree(ses->server); kfree(ses->server);
} */ } */
......
...@@ -54,7 +54,6 @@ build_path_from_dentry(struct dentry *direntry) ...@@ -54,7 +54,6 @@ build_path_from_dentry(struct dentry *direntry)
temp = temp->d_parent; temp = temp->d_parent;
} }
namelen += 1; /* allow for trailing null */ namelen += 1; /* allow for trailing null */
cFYI(1, ("Final namelength (in build_path): %d ", namelen)); /* BB remove */
full_path = kmalloc(namelen, GFP_KERNEL); full_path = kmalloc(namelen, GFP_KERNEL);
namelen--; namelen--;
full_path[namelen] = 0; /* trailing null */ full_path[namelen] = 0; /* trailing null */
...@@ -66,13 +65,13 @@ build_path_from_dentry(struct dentry *direntry) ...@@ -66,13 +65,13 @@ build_path_from_dentry(struct dentry *direntry)
full_path[namelen] = '\\'; full_path[namelen] = '\\';
strncpy(full_path + namelen + 1, temp->d_name.name, strncpy(full_path + namelen + 1, temp->d_name.name,
temp->d_name.len); temp->d_name.len);
cFYI(1, (" name: %s ", full_path + namelen)); /* BB remove */ cFYI(0, (" name: %s ", full_path + namelen));
} }
temp = temp->d_parent; temp = temp->d_parent;
} }
if (namelen != 0) if (namelen != 0)
cERROR(1, 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)); namelen));
return full_path; return full_path;
...@@ -111,7 +110,7 @@ build_wildcard_path_from_dentry(struct dentry *direntry) ...@@ -111,7 +110,7 @@ build_wildcard_path_from_dentry(struct dentry *direntry)
} }
if (namelen != 0) if (namelen != 0)
cERROR(1, 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)); namelen));
return full_path; return full_path;
...@@ -124,7 +123,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode) ...@@ -124,7 +123,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode)
{ {
int rc = -ENOENT; int rc = -ENOENT;
int xid; 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; __u16 fileHandle;
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon; struct cifsTconInfo *pTcon;
...@@ -144,7 +143,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode) ...@@ -144,7 +143,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode)
/* 0x20197 was used previously */ , CREATE_NOT_DIR, /* 0x20197 was used previously */ , CREATE_NOT_DIR,
&fileHandle, &oplock, cifs_sb->local_nls); &fileHandle, &oplock, cifs_sb->local_nls);
if (rc) { if (rc) {
cFYI(1, ("\ncifs_create returned 0x%x ", rc)); cFYI(1, ("cifs_create returned 0x%x ", rc));
} else { } else {
if (pTcon->ses->capabilities & CAP_UNIX) if (pTcon->ses->capabilities & CAP_UNIX)
rc = cifs_get_inode_info_unix(&newinode, full_path, rc = cifs_get_inode_info_unix(&newinode, full_path,
...@@ -154,14 +153,17 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode) ...@@ -154,14 +153,17 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode)
inode->i_sb); inode->i_sb);
if (rc != 0) { if (rc != 0) {
cFYI(1, cFYI(1,("Create worked but get_inode_info failed with rc = %d",
("\nCreate worked but get_inode_info failed with rc = %d ",
rc)); rc));
/* close handle */ /* close handle */
} else { } else {
direntry->d_op = &cifs_dentry_ops; direntry->d_op = &cifs_dentry_ops;
d_instantiate(direntry, newinode); 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); CIFSSMBClose(xid, pTcon, fileHandle);
/* BB In the future chain close with the NTCreateX to narrow window */ /* BB In the future chain close with the NTCreateX to narrow window */
...@@ -204,7 +206,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry) ...@@ -204,7 +206,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry)
cFYI(1, (" NULL inode in lookup")); cFYI(1, (" NULL inode in lookup"));
} }
cFYI(1, 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) if (pTcon->ses->capabilities & CAP_UNIX)
rc = cifs_get_inode_info_unix(&newInode, full_path, rc = cifs_get_inode_info_unix(&newInode, full_path,
parent_dir_inode->i_sb); parent_dir_inode->i_sb);
...@@ -224,7 +226,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry) ...@@ -224,7 +226,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry)
d_add(direntry, NULL); d_add(direntry, NULL);
} else { } else {
cERROR(1, 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)); 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 */ /* 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 +253,7 @@ cifs_dir_open(struct inode *inode, struct file *file) ...@@ -251,7 +253,7 @@ cifs_dir_open(struct inode *inode, struct file *file)
full_path = build_wildcard_path_from_dentry(file->f_dentry); 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) if (full_path)
kfree(full_path); kfree(full_path);
...@@ -273,7 +275,7 @@ cifs_d_revalidate(struct dentry *direntry, int flags) ...@@ -273,7 +275,7 @@ cifs_d_revalidate(struct dentry *direntry, int flags)
} }
} else { } else {
cFYI(1, 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)); direntry->d_name.name, direntry));
} }
...@@ -286,7 +288,7 @@ cifs_d_revalidate(struct dentry *direntry, int flags) ...@@ -286,7 +288,7 @@ cifs_d_revalidate(struct dentry *direntry, int flags)
{ {
int rc = 0; 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; return rc;
} */ } */
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/fcntl.h> #include <linux/fcntl.h>
#include <linux/version.h> #include <linux/version.h>
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/pagevec.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <asm/div64.h> #include <asm/div64.h>
#include "cifsfs.h" #include "cifsfs.h"
...@@ -85,9 +86,11 @@ cifs_open(struct inode *inode, struct file *file) ...@@ -85,9 +86,11 @@ cifs_open(struct inode *inode, struct file *file)
if (file->f_flags & O_CREAT) if (file->f_flags & O_CREAT)
disposition = FILE_OVERWRITE; disposition = FILE_OVERWRITE;
/* BB first check if file has batch oplock (or oplock ?) */
/* BB finish adding in oplock support BB */ /* BB finish adding in oplock support BB */
if (oplockEnabled) if (oplockEnabled)
oplock = TRUE; oplock = REQ_OPLOCK;
else else
oplock = FALSE; oplock = FALSE;
...@@ -95,8 +98,8 @@ cifs_open(struct inode *inode, struct file *file) ...@@ -95,8 +98,8 @@ cifs_open(struct inode *inode, struct file *file)
rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess, rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess,
CREATE_NOT_DIR, &netfid, &oplock, cifs_sb->local_nls); CREATE_NOT_DIR, &netfid, &oplock, cifs_sb->local_nls);
if (rc) { if (rc) {
cFYI(1, ("\ncifs_open returned 0x%x ", rc)); cFYI(1, ("cifs_open returned 0x%x ", rc));
cFYI(1, (" oplock: %d ", oplock)); cFYI(1, ("oplock: %d ", oplock));
} else { } else {
file->private_data = file->private_data =
kmalloc(sizeof (struct cifsFileInfo), GFP_KERNEL); kmalloc(sizeof (struct cifsFileInfo), GFP_KERNEL);
...@@ -144,8 +147,6 @@ cifs_close(struct inode *inode, struct file *file) ...@@ -144,8 +147,6 @@ cifs_close(struct inode *inode, struct file *file)
struct cifsFileInfo *pSMBFile = struct cifsFileInfo *pSMBFile =
(struct cifsFileInfo *) file->private_data; (struct cifsFileInfo *) file->private_data;
cFYI(1, ("\n inode = 0x%p with ", inode));
xid = GetXid(); xid = GetXid();
cifs_sb = CIFS_SB(inode->i_sb); cifs_sb = CIFS_SB(inode->i_sb);
...@@ -172,12 +173,12 @@ cifs_closedir(struct inode *inode, struct file *file) ...@@ -172,12 +173,12 @@ cifs_closedir(struct inode *inode, struct file *file)
struct cifsFileInfo *pSMBFileStruct = struct cifsFileInfo *pSMBFileStruct =
(struct cifsFileInfo *) file->private_data; (struct cifsFileInfo *) file->private_data;
cFYI(1, ("\nClosedir inode = 0x%p with ", inode)); cFYI(1, ("Closedir inode = 0x%p with ", inode));
xid = GetXid(); xid = GetXid();
if (pSMBFileStruct) { if (pSMBFileStruct) {
cFYI(1, ("\nFreeing private data in close dir")); cFYI(1, ("Freeing private data in close dir"));
kfree(file->private_data); kfree(file->private_data);
file->private_data = NULL; file->private_data = NULL;
} }
...@@ -202,42 +203,42 @@ cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) ...@@ -202,42 +203,42 @@ cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
xid = GetXid(); xid = GetXid();
cFYI(1, 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, cmd, pfLock->fl_flags, pfLock->fl_type, pfLock->fl_start,
pfLock->fl_end)); pfLock->fl_end));
if (pfLock->fl_flags & FL_POSIX) if (pfLock->fl_flags & FL_POSIX)
cFYI(1, ("\nPosix ")); cFYI(1, ("Posix "));
if (pfLock->fl_flags & FL_FLOCK) if (pfLock->fl_flags & FL_FLOCK)
cFYI(1, ("\nFlock ")); cFYI(1, ("Flock "));
if (pfLock->fl_flags & FL_SLEEP) if (pfLock->fl_flags & FL_SLEEP)
cFYI(1, ("\nBlocking lock ")); cFYI(1, ("Blocking lock "));
if (pfLock->fl_flags & FL_ACCESS) 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) if (pfLock->fl_flags & FL_LEASE)
cFYI(1, ("\nLease on file ")); cFYI(1, ("Lease on file "));
if (pfLock->fl_flags & 0xFFD0) if (pfLock->fl_flags & 0xFFD0)
cFYI(1, ("\n Unknown lock flags ")); cFYI(1, ("Unknown lock flags "));
if (pfLock->fl_type == F_WRLCK) { if (pfLock->fl_type == F_WRLCK) {
cFYI(1, ("\nF_WRLCK ")); cFYI(1, ("F_WRLCK "));
numLock = 1; numLock = 1;
} else if (pfLock->fl_type == F_UNLCK) { } else if (pfLock->fl_type == F_UNLCK) {
cFYI(1, ("\nF_UNLCK ")); cFYI(1, ("F_UNLCK "));
numUnlock = 1; numUnlock = 1;
} else if (pfLock->fl_type == F_RDLCK) { } else if (pfLock->fl_type == F_RDLCK) {
cFYI(1, ("\nF_RDLCK ")); cFYI(1, ("F_RDLCK "));
lockType |= LOCKING_ANDX_SHARED_LOCK; lockType |= LOCKING_ANDX_SHARED_LOCK;
numLock = 1; numLock = 1;
} else if (pfLock->fl_type == F_EXLCK) { } else if (pfLock->fl_type == F_EXLCK) {
cFYI(1, ("\nF_EXLCK ")); cFYI(1, ("F_EXLCK "));
numLock = 1; numLock = 1;
} else if (pfLock->fl_type == F_SHLCK) { } else if (pfLock->fl_type == F_SHLCK) {
cFYI(1, ("\nF_SHLCK ")); cFYI(1, ("F_SHLCK "));
lockType |= LOCKING_ANDX_SHARED_LOCK; lockType |= LOCKING_ANDX_SHARED_LOCK;
numLock = 1; numLock = 1;
} else } else
cFYI(1, ("\nUnknown type of lock ")); cFYI(1, ("Unknown type of lock "));
cifs_sb = CIFS_SB(file->f_dentry->d_sb); cifs_sb = CIFS_SB(file->f_dentry->d_sb);
pTcon = cifs_sb->tcon; pTcon = cifs_sb->tcon;
...@@ -265,7 +266,7 @@ cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) ...@@ -265,7 +266,7 @@ cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
pfLock->fl_type = F_UNLCK; pfLock->fl_type = F_UNLCK;
if (rc != 0) if (rc != 0)
cERROR(1, cERROR(1,
("\nError unlocking previously locked range %d during test of lock ", ("Error unlocking previously locked range %d during test of lock ",
rc)); rc));
rc = 0; rc = 0;
...@@ -304,7 +305,7 @@ cifs_write(struct file * file, const char *write_data, ...@@ -304,7 +305,7 @@ cifs_write(struct file * file, const char *write_data,
pTcon = cifs_sb->tcon; pTcon = cifs_sb->tcon;
/*cFYI(1, /*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)); */ *poffset, file->f_dentry->d_name.name)); */
if (file->private_data == NULL) { if (file->private_data == NULL) {
...@@ -360,6 +361,7 @@ cifs_partialpagewrite(struct page *page,unsigned from, unsigned to) ...@@ -360,6 +361,7 @@ cifs_partialpagewrite(struct page *page,unsigned from, unsigned to)
struct inode *inode = page->mapping->host; struct inode *inode = page->mapping->host;
struct cifsInodeInfo *cifsInode; struct cifsInodeInfo *cifsInode;
struct cifsFileInfo *open_file = NULL; struct cifsFileInfo *open_file = NULL;
struct list_head *tmp;
int xid; int xid;
xid = GetXid(); xid = GetXid();
...@@ -381,32 +383,39 @@ cifs_partialpagewrite(struct page *page,unsigned from, unsigned to) ...@@ -381,32 +383,39 @@ cifs_partialpagewrite(struct page *page,unsigned from, unsigned to)
return -EFAULT; return -EFAULT;
} }
if((to > PAGE_CACHE_SIZE) || (from > to))
return -EIO;
offset += (loff_t)from; offset += (loff_t)from;
write_data += from; write_data += from;
if((to > PAGE_CACHE_SIZE) || (from > to) || (offset > mapping->host->i_size)) {
FreeXid(xid);
return -EIO;
}
/* check to make sure that we are not extending the file */
if(mapping->host->i_size - offset < (loff_t)to)
to = (unsigned)(mapping->host->i_size - offset);
cifsInode = CIFS_I(mapping->host); cifsInode = CIFS_I(mapping->host);
if(!list_empty(&(cifsInode->openFileList))) { list_for_each(tmp, &cifsInode->openFileList) {
open_file = list_entry(cifsInode->openFileList.next, open_file = list_entry(tmp,struct cifsFileInfo, flist);
struct cifsFileInfo, flist);
/* We could check if file is open for writing first */ /* 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, bytes_written = cifs_write(open_file->pfile, write_data,
to-from, &offset); to-from, &offset);
/* Does mm or vfs already set times? */ /* Does mm or vfs already set times? */
inode->i_atime = inode->i_mtime = CURRENT_TIME; inode->i_atime = inode->i_mtime = CURRENT_TIME;
if ((bytes_written > 0) && (offset)) { if ((bytes_written > 0) && (offset)) {
rc = 0; rc = 0;
if (offset > inode->i_size)
inode->i_size = offset;
} else if(bytes_written < 0) { } else if(bytes_written < 0) {
rc = bytes_written; 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; rc = -EIO;
} }
...@@ -414,6 +423,18 @@ cifs_partialpagewrite(struct page *page,unsigned from, unsigned to) ...@@ -414,6 +423,18 @@ cifs_partialpagewrite(struct page *page,unsigned from, unsigned to)
return rc; return rc;
} }
static int
cifs_writepages(struct address_space *mapping, struct writeback_control *wbc)
{
int rc = -EFAULT;
int xid;
xid = GetXid();
/* call 16K write then Setpageuptodate */
FreeXid(xid);
return rc;
}
static int static int
cifs_writepage(struct page* page, struct writeback_control *wbc) cifs_writepage(struct page* page, struct writeback_control *wbc)
{ {
...@@ -421,9 +442,11 @@ cifs_writepage(struct page* page, struct writeback_control *wbc) ...@@ -421,9 +442,11 @@ cifs_writepage(struct page* page, struct writeback_control *wbc)
int xid; int xid;
xid = GetXid(); xid = GetXid();
/* BB add check for wbc flags */
page_cache_get(page); page_cache_get(page);
rc = cifs_partialpagewrite(page,0,PAGE_CACHE_SIZE); rc = cifs_partialpagewrite(page,0,PAGE_CACHE_SIZE);
/* insert call to SetPageToUpdate like function here? */ SetPageUptodate(page); /* BB add check for error and Clearuptodate? */
unlock_page(page); unlock_page(page);
page_cache_release(page); page_cache_release(page);
FreeXid(xid); FreeXid(xid);
...@@ -434,32 +457,47 @@ static int ...@@ -434,32 +457,47 @@ static int
cifs_commit_write(struct file *file, struct page *page, unsigned offset, cifs_commit_write(struct file *file, struct page *page, unsigned offset,
unsigned to) unsigned to)
{ {
int xid,rc; int xid;
int rc = 0;
struct inode *inode = page->mapping->host;
loff_t position = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
struct cifsFileInfo *open_file;
struct cifs_sb_info *cifs_sb;
xid = GetXid(); xid = GetXid();
if(offset > to) if (position > inode->i_size){
return -EIO; inode->i_size = position;
rc = cifs_partialpagewrite(page,offset,to); if (file->private_data == NULL) {
rc = -EBADF;
} else {
cifs_sb = CIFS_SB(inode->i_sb);
open_file = (struct cifsFileInfo *)file->private_data;
rc = CIFSSMBSetFileSize(xid, cifs_sb->tcon, position,
open_file->netfid,open_file->pid,FALSE);
cFYI(1,(" SetEOF (commit write) rc = %d",rc));
}
}
set_page_dirty(page);
FreeXid(xid); FreeXid(xid);
return rc; return rc;
} }
static int
cifs_prepare_write(struct file *file, struct page *page, unsigned offset,
unsigned to)
{
return 0; /* eventually add code to flush any incompatible requests */
}
int int
cifs_fsync(struct file *file, struct dentry *dentry, int datasync) cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
{ {
int xid; int xid;
int rc = 0; int rc = 0;
struct inode * inode = file->f_dentry->d_inode;
xid = GetXid(); xid = GetXid();
/* BB fill in code to flush write behind buffers - when we start supporting oplock */
cFYI(1, (" name: %s datasync: 0x%x ", dentry->d_name.name, datasync)); cFYI(1, ("Sync file - name: %s datasync: 0x%x ",
dentry->d_name.name, datasync));
rc = filemap_fdatawrite(inode->i_mapping);
FreeXid(xid); FreeXid(xid);
return rc; return rc;
} }
...@@ -473,6 +511,7 @@ cifs_sync_page(struct page *page) ...@@ -473,6 +511,7 @@ cifs_sync_page(struct page *page)
unsigned int rpages = 0; unsigned int rpages = 0;
int rc = 0; int rc = 0;
cFYI(1,("sync page %p",page));
mapping = page->mapping; mapping = page->mapping;
if (!mapping) if (!mapping)
return 0; return 0;
...@@ -483,13 +522,39 @@ cifs_sync_page(struct page *page) ...@@ -483,13 +522,39 @@ cifs_sync_page(struct page *page)
/* fill in rpages then /* fill in rpages then
result = cifs_pagein_inode(inode, index, rpages); *//* BB finish */ 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) if (rc < 0)
return rc; return rc;
return 0; return 0;
} }
/*
* As file closes, flush all cached write data for this inode checking
* for write behind errors.
*
*/
int cifs_flush(struct file *file)
{
struct inode * inode = file->f_dentry->d_inode;
int rc = 0;
/* Rather than do the steps manually: */
/* lock the inode for writing */
/* loop through pages looking for write behind data (dirty pages) */
/* coalesce into contiguous 16K (or smaller) chunks to write to server */
/* send to server (prefer in parallel) */
/* deal with writebehind errors */
/* unlock inode for writing */
/* filemapfdatawrite appears easier for the time being */
rc = filemap_fdatawrite(inode->i_mapping);
cFYI(1,("Flush inode %p file %p rc %d",inode,file,rc));
return rc;
}
ssize_t ssize_t
cifs_read(struct file * file, char *read_data, size_t read_size, cifs_read(struct file * file, char *read_data, size_t read_size,
loff_t * poffset) loff_t * poffset)
...@@ -500,6 +565,7 @@ cifs_read(struct file * file, char *read_data, size_t read_size, ...@@ -500,6 +565,7 @@ cifs_read(struct file * file, char *read_data, size_t read_size,
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon; struct cifsTconInfo *pTcon;
int xid; int xid;
char * current_offset;
xid = GetXid(); xid = GetXid();
cifs_sb = CIFS_SB(file->f_dentry->d_sb); cifs_sb = CIFS_SB(file->f_dentry->d_sb);
...@@ -510,12 +576,13 @@ cifs_read(struct file * file, char *read_data, size_t read_size, ...@@ -510,12 +576,13 @@ cifs_read(struct file * file, char *read_data, size_t read_size,
return -EBADF; 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, rc = CIFSSMBRead(xid, pTcon,
((struct cifsFileInfo *) file-> ((struct cifsFileInfo *) file->
private_data)->netfid, private_data)->netfid,
read_size - total_read, *poffset, read_size - total_read, *poffset,
&bytes_read, read_data + total_read); &bytes_read, &current_offset);
if (rc || (bytes_read == 0)) { if (rc || (bytes_read == 0)) {
if (total_read) { if (total_read) {
break; break;
...@@ -531,8 +598,7 @@ cifs_read(struct file * file, char *read_data, size_t read_size, ...@@ -531,8 +598,7 @@ cifs_read(struct file * file, char *read_data, size_t read_size,
return total_read; return total_read;
} }
int int cifs_file_mmap(struct file * file, struct vm_area_struct * vma)
cifs_file_mmap(struct file * file, struct vm_area_struct * vma)
{ {
struct dentry * dentry = file->f_dentry; struct dentry * dentry = file->f_dentry;
int rc, xid; int rc, xid;
...@@ -540,7 +606,7 @@ cifs_file_mmap(struct file * file, struct vm_area_struct * vma) ...@@ -540,7 +606,7 @@ cifs_file_mmap(struct file * file, struct vm_area_struct * vma)
xid = GetXid(); xid = GetXid();
rc = cifs_revalidate(dentry); rc = cifs_revalidate(dentry);
if (rc) { 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); FreeXid(xid);
return rc; return rc;
} }
...@@ -549,34 +615,157 @@ cifs_file_mmap(struct file * file, struct vm_area_struct * vma) ...@@ -549,34 +615,157 @@ cifs_file_mmap(struct file * file, struct vm_area_struct * vma)
return rc; return rc;
} }
static void cifs_copy_cache_pages(struct address_space *mapping,
struct list_head *pages, int bytes_read,
char *data,struct pagevec * plru_pvec)
{
struct page *page;
char * target;
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);
cFYI(1,("Add page cache failed"));
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(plru_pvec, page))
__pagevec_lru_add(plru_pvec);
flush_dcache_page(page);
SetPageUptodate(page);
kunmap(page);
unlock_page(page);
page_cache_release(page);
data += PAGE_CACHE_SIZE;
}
return;
}
static int
cifs_readpages(struct file *file, struct address_space *mapping,
struct list_head *page_list, unsigned num_pages)
{
int rc = -EACCES;
int xid,i;
loff_t offset;
struct page * page;
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon;
int bytes_read = 0;
unsigned int read_size;
char * smb_read_data = 0;
struct smb_com_read_rsp * pSMBr;
struct pagevec lru_pvec;
xid = GetXid();
if (file->private_data == NULL) {
FreeXid(xid);
return -EBADF;
}
cifs_sb = CIFS_SB(file->f_dentry->d_sb);
pTcon = cifs_sb->tcon;
pagevec_init(&lru_pvec, 0);
for(i = 0;i<num_pages;) {
if(list_empty(page_list)) {
break;
}
page = list_entry(page_list->prev, struct page, list);
offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
/* for reads over a certain size could initiate async read ahead */
cFYI(0,("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));
/* clean up remaing pages off list */
while (!list_empty(page_list) && (i < num_pages)) {
page = list_entry(page_list->prev, struct page, list);
list_del(&page->list);
}
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), &lru_pvec);
i += bytes_read >> PAGE_CACHE_SHIFT;
if((bytes_read & PAGE_CACHE_MASK) != bytes_read) {
cFYI(1,("Partial page %d of %d read to 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;
}
pagevec_lru_add(&lru_pvec);
FreeXid(xid);
return rc;
}
static int static int
cifs_readpage(struct file *file, struct page *page) cifs_readpage(struct file *file, struct page *page)
{ {
loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT; loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
char * read_data; char * read_data;
int rc = -EACCES; int rc = -EACCES;
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon;
int xid; int xid;
xid = GetXid(); xid = GetXid();
cifs_sb = CIFS_SB(file->f_dentry->d_sb);
pTcon = cifs_sb->tcon;
if (file->private_data == NULL) { if (file->private_data == NULL) {
FreeXid(xid); FreeXid(xid);
return -EBADF; return -EBADF;
} }
cFYI(0,("readpage %p at offset %d 0x%x\n",page,(int)offset,(int)offset));
page_cache_get(page); page_cache_get(page);
read_data = kmap(page); read_data = kmap(page);
/* for reads over a certain size we could initiate async read ahead */ /* for reads over a certain size could initiate async read ahead */
rc = cifs_read(file, read_data, PAGE_CACHE_SIZE, &offset); rc = cifs_read(file, read_data, PAGE_CACHE_SIZE, &offset);
if (rc < 0) if (rc < 0)
goto io_error; goto io_error;
else { else {
cFYI(1,("\nBytes read %d ",rc)); cFYI(1,("Bytes read %d ",rc));
} }
file->f_dentry->d_inode->i_atime = CURRENT_TIME; file->f_dentry->d_inode->i_atime = CURRENT_TIME;
...@@ -610,38 +799,41 @@ fill_in_inode(struct inode *tmp_inode, ...@@ -610,38 +799,41 @@ fill_in_inode(struct inode *tmp_inode,
cifsInfo->time = jiffies; cifsInfo->time = jiffies;
atomic_inc(&cifsInfo->inUse); /* inc on every refresh of inode info */ atomic_inc(&cifsInfo->inUse); /* inc on every refresh of inode info */
/* Linux can not store file creation time unfortunately so we ignore it */ /* Linux can not store file creation time unfortunately so ignore it */
tmp_inode->i_atime = tmp_inode->i_atime =
cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime)); cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime));
tmp_inode->i_mtime = tmp_inode->i_mtime =
cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime)); cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
tmp_inode->i_ctime = tmp_inode->i_ctime =
cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime)); cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
/* should we treat the dos attribute of read-only as read-only mode bit e.g. 555 */ /* treat 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 */ /* 2767 perms - indicate mandatory locking */
tmp_inode->i_mode = S_IALLUGO & ~(S_ISUID | S_IXGRP);
cFYI(0, cFYI(0,
("\nCIFS FFIRST: Attributes came in as 0x%x", ("CIFS FFIRST: Attributes came in as 0x%x",
pfindData->ExtFileAttributes)); pfindData->ExtFileAttributes));
if (pfindData->ExtFileAttributes & ATTR_REPARSE) { if (pfindData->ExtFileAttributes & ATTR_REPARSE) {
*pobject_type = DT_LNK; *pobject_type = DT_LNK;
tmp_inode->i_mode |= S_IFLNK; /* BB can this and S_IFREG or S_IFDIR be set at same time as in Windows? */ /* BB can this and S_IFREG or S_IFDIR be set as in Windows? */
tmp_inode->i_mode |= S_IFLNK;
} else if (pfindData->ExtFileAttributes & ATTR_DIRECTORY) { } else if (pfindData->ExtFileAttributes & ATTR_DIRECTORY) {
*pobject_type = DT_DIR; *pobject_type = DT_DIR;
tmp_inode->i_mode = S_IRWXUGO; /* override default perms since we do not lock dirs */ /* override default perms since we do not lock dirs */
tmp_inode->i_mode = S_IRWXUGO;
tmp_inode->i_mode |= S_IFDIR; tmp_inode->i_mode |= S_IFDIR;
} else { } else {
*pobject_type = DT_REG; *pobject_type = DT_REG;
tmp_inode->i_mode |= S_IFREG; tmp_inode->i_mode |= S_IFREG;
}/* could add code here - to validate if device or weird share type? */ }/* could add code here - to validate if device or weird share type? */
/* can not fill in nlink here as in qpathinfo version and in Unx search */ /* can not fill in nlink here as in qpathinfo version and Unx search */
tmp_inode->i_size = pfindData->EndOfFile; tmp_inode->i_size = pfindData->EndOfFile;
tmp_inode->i_blocks = tmp_inode->i_blocks =
do_div(pfindData->AllocationSize, tmp_inode->i_blksize); do_div(pfindData->AllocationSize, tmp_inode->i_blksize);
if (pfindData->AllocationSize < pfindData->EndOfFile) 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, 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, (unsigned long) tmp_inode->i_size, tmp_inode->i_blocks,
tmp_inode->i_blksize)); tmp_inode->i_blksize));
if (S_ISREG(tmp_inode->i_mode)) { if (S_ISREG(tmp_inode->i_mode)) {
...@@ -657,7 +849,7 @@ fill_in_inode(struct inode *tmp_inode, ...@@ -657,7 +849,7 @@ fill_in_inode(struct inode *tmp_inode,
cFYI(1, (" Symbolic Link inode ")); cFYI(1, (" Symbolic Link inode "));
tmp_inode->i_op = &cifs_symlink_inode_ops; tmp_inode->i_op = &cifs_symlink_inode_ops;
} else { } else {
cFYI(1, ("\nInit special inode ")); cFYI(1, (" Init special inode "));
init_special_inode(tmp_inode, tmp_inode->i_mode, init_special_inode(tmp_inode, tmp_inode->i_mode,
kdev_t_to_nr(tmp_inode->i_rdev)); kdev_t_to_nr(tmp_inode->i_rdev));
} }
...@@ -726,7 +918,7 @@ unix_fill_in_inode(struct inode *tmp_inode, ...@@ -726,7 +918,7 @@ unix_fill_in_inode(struct inode *tmp_inode,
tmp_inode->i_op = &cifs_symlink_inode_ops; tmp_inode->i_op = &cifs_symlink_inode_ops;
/* tmp_inode->i_fop = *//* do not need to set to anything */ /* tmp_inode->i_fop = *//* do not need to set to anything */
} else { } else {
cFYI(1, ("\nInit special inode ")); cFYI(1, (" Init special inode "));
init_special_inode(tmp_inode, tmp_inode->i_mode, init_special_inode(tmp_inode, tmp_inode->i_mode,
kdev_t_to_nr(tmp_inode->i_rdev)); kdev_t_to_nr(tmp_inode->i_rdev));
} }
...@@ -740,22 +932,21 @@ construct_dentry(struct qstr *qstring, struct file *file, ...@@ -740,22 +932,21 @@ construct_dentry(struct qstr *qstring, struct file *file,
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon; struct cifsTconInfo *pTcon;
cFYI(1, ("\nFor %s ", qstring->name)); cFYI(1, ("For %s ", qstring->name));
cifs_sb = CIFS_SB(file->f_dentry->d_sb); cifs_sb = CIFS_SB(file->f_dentry->d_sb);
pTcon = cifs_sb->tcon; pTcon = cifs_sb->tcon;
qstring->hash = full_name_hash(qstring->name, qstring->len); qstring->hash = full_name_hash(qstring->name, qstring->len);
tmp_dentry = d_lookup(file->f_dentry, qstring); tmp_dentry = d_lookup(file->f_dentry, qstring);
if (tmp_dentry) { if (tmp_dentry) {
cFYI(1, (" existing dentry with inode 0x%p ", tmp_dentry->d_inode)); /* BB remove */ cFYI(0, (" existing dentry with inode 0x%p", tmp_dentry->d_inode));
*ptmp_inode = tmp_dentry->d_inode; *ptmp_inode = tmp_dentry->d_inode;
/* BB overwrite the old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len ?? */ /* BB overwrite the old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len ?? */
} else { } else {
tmp_dentry = d_alloc(file->f_dentry, qstring); tmp_dentry = d_alloc(file->f_dentry, qstring);
*ptmp_inode = new_inode(file->f_dentry->d_sb); *ptmp_inode = new_inode(file->f_dentry->d_sb);
cFYI(1, ("\nAlloc new inode %p ", *ptmp_inode));
tmp_dentry->d_op = &cifs_dentry_ops; tmp_dentry->d_op = &cifs_dentry_ops;
cFYI(1, (" instantiate dentry 0x%p with inode 0x%p ", cFYI(0, (" instantiate dentry 0x%p with inode 0x%p ",
tmp_dentry, *ptmp_inode)); tmp_dentry, *ptmp_inode));
d_instantiate(tmp_dentry, *ptmp_inode); d_instantiate(tmp_dentry, *ptmp_inode);
d_rehash(tmp_dentry); d_rehash(tmp_dentry);
...@@ -763,8 +954,8 @@ construct_dentry(struct qstr *qstring, struct file *file, ...@@ -763,8 +954,8 @@ construct_dentry(struct qstr *qstring, struct file *file,
tmp_dentry->d_time = jiffies; tmp_dentry->d_time = jiffies;
(*ptmp_inode)->i_blksize = (*ptmp_inode)->i_blksize =
(pTcon->ses->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00; (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;
cFYI(1, ("\ni_blksize = %ld", (*ptmp_inode)->i_blksize)); cFYI(1, ("i_blksize = %ld", (*ptmp_inode)->i_blksize));
*pnew_dentry = tmp_dentry; *pnew_dentry = tmp_dentry;
} }
...@@ -836,14 +1027,14 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir) ...@@ -836,14 +1027,14 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
full_path = build_wildcard_path_from_dentry(file->f_dentry); 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) { switch ((int) file->f_pos) {
case 0: case 0:
if (filldir if (filldir
(direntry, ".", 1, file->f_pos, (direntry, ".", 1, file->f_pos,
file->f_dentry->d_inode->i_ino, DT_DIR) < 0) { 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; break;
} }
file->f_pos++; file->f_pos++;
...@@ -852,7 +1043,7 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir) ...@@ -852,7 +1043,7 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
if (filldir if (filldir
(direntry, "..", 2, file->f_pos, (direntry, "..", 2, file->f_pos,
file->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) { 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; break;
} }
file->f_pos++; file->f_pos++;
...@@ -957,13 +1148,13 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir) ...@@ -957,13 +1148,13 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
if (file->private_data == NULL) { if (file->private_data == NULL) {
rc = -EBADF; rc = -EBADF;
cFYI(1, cFYI(1,
("\nReaddir on closed srch, pos = %lld", ("Readdir on closed srch, pos = %lld",
file->f_pos)); file->f_pos));
} else { } else {
cifsFile = (struct cifsFileInfo *) file->private_data; cifsFile = (struct cifsFileInfo *) file->private_data;
if (cifsFile->endOfSearch) { if (cifsFile->endOfSearch) {
rc = 0; rc = 0;
cFYI(1, ("\nEnd of search ")); cFYI(1, ("End of search "));
break; break;
} }
searchHandle = cifsFile->netfid; searchHandle = cifsFile->netfid;
...@@ -1077,17 +1268,28 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir) ...@@ -1077,17 +1268,28 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
struct address_space_operations cifs_addr_ops = { struct address_space_operations cifs_addr_ops = {
.readpage = cifs_readpage, .readpage = cifs_readpage,
.readpages = cifs_readpages,
.writepage = cifs_writepage, .writepage = cifs_writepage,
.prepare_write = cifs_prepare_write, .prepare_write = simple_prepare_write,
.commit_write = cifs_commit_write, .commit_write = cifs_commit_write,
/* .sync_page = cifs_sync_page, */ .sync_page = cifs_sync_page,
};
struct address_space_operations cifs_addr_ops_writethrough = {
.readpage = cifs_readpage,
.readpages = cifs_readpages,
.writepage = cifs_writepage,
.prepare_write = simple_prepare_write,
.commit_write = cifs_commit_write,
.sync_page = cifs_sync_page,
}; };
/* change over to struct below when sync page tested and complete */ struct address_space_operations cifs_addr_ops_nocache = {
struct address_space_operations cifs_addr_ops2 = {
.readpage = cifs_readpage, .readpage = cifs_readpage,
.readpages = cifs_readpages,
.writepage = cifs_writepage, .writepage = cifs_writepage,
.prepare_write = cifs_prepare_write, .prepare_write = simple_prepare_write,
.commit_write = cifs_commit_write, .commit_write = cifs_commit_write,
.sync_page = cifs_sync_page, .sync_page = cifs_sync_page,
}; };
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/buffer_head.h>
#include <linux/stat.h> #include <linux/stat.h>
#include <asm/div64.h> #include <asm/div64.h>
#include "cifsfs.h" #include "cifsfs.h"
...@@ -44,7 +45,7 @@ cifs_get_inode_info_unix(struct inode **pinode, ...@@ -44,7 +45,7 @@ cifs_get_inode_info_unix(struct inode **pinode,
xid = GetXid(); xid = GetXid();
pTcon = cifs_sb->tcon; 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 */ /* we could have done a find first instead but this returns more info */
rc = CIFSSMBUnixQPathInfo(xid, pTcon, search_path, &findData, rc = CIFSSMBUnixQPathInfo(xid, pTcon, search_path, &findData,
cifs_sb->local_nls); cifs_sb->local_nls);
...@@ -85,7 +86,7 @@ cifs_get_inode_info_unix(struct inode **pinode, ...@@ -85,7 +86,7 @@ cifs_get_inode_info_unix(struct inode **pinode,
/* get new inode */ /* get new inode */
if (*pinode == NULL) { if (*pinode == NULL) {
*pinode = new_inode(sb); *pinode = new_inode(sb);
cFYI(1, ("\nAlloc new inode %p ", *pinode)); cFYI(1, (" Alloc new inode %p ", *pinode));
} }
inode = *pinode; inode = *pinode;
/* new_inode = iget(parent_dir_inode->i_sb, findData.IndexNumber); */ /* new_inode = iget(parent_dir_inode->i_sb, findData.IndexNumber); */
...@@ -93,7 +94,7 @@ cifs_get_inode_info_unix(struct inode **pinode, ...@@ -93,7 +94,7 @@ cifs_get_inode_info_unix(struct inode **pinode,
cifsInfo = CIFS_I(inode); cifsInfo = CIFS_I(inode);
cFYI(1, ("\nOld time %ld ", cifsInfo->time)); cFYI(1, (" Old time %ld ", cifsInfo->time));
cifsInfo->time = jiffies; cifsInfo->time = jiffies;
cFYI(1, (" New time %ld ", cifsInfo->time)); cFYI(1, (" New time %ld ", cifsInfo->time));
atomic_inc(&cifsInfo->inUse); /* inc on every refresh of inode */ atomic_inc(&cifsInfo->inUse); /* inc on every refresh of inode */
...@@ -129,12 +130,12 @@ cifs_get_inode_info_unix(struct inode **pinode, ...@@ -129,12 +130,12 @@ cifs_get_inode_info_unix(struct inode **pinode,
findData.EndOfFile = le64_to_cpu(findData.EndOfFile); findData.EndOfFile = le64_to_cpu(findData.EndOfFile);
inode->i_size = findData.EndOfFile; inode->i_size = findData.EndOfFile;
inode->i_blksize = 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); inode->i_blocks = do_div(findData.NumOfBytes, inode->i_blksize);
if (findData.NumOfBytes < findData.EndOfFile) 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, cFYI(1,
("\nCIFS FFIRST: Size %ld and blocks %ld ", ("Size %ld and blocks %ld ",
(unsigned long) inode->i_size, inode->i_blocks)); (unsigned long) inode->i_size, inode->i_blocks));
if (S_ISREG(inode->i_mode)) { if (S_ISREG(inode->i_mode)) {
cFYI(1, (" File inode ")); cFYI(1, (" File inode "));
...@@ -150,7 +151,7 @@ cifs_get_inode_info_unix(struct inode **pinode, ...@@ -150,7 +151,7 @@ cifs_get_inode_info_unix(struct inode **pinode,
inode->i_op = &cifs_symlink_inode_ops; inode->i_op = &cifs_symlink_inode_ops;
/* tmp_inode->i_fop = *//* do not need to set to anything */ /* tmp_inode->i_fop = *//* do not need to set to anything */
} else { } else {
cFYI(1, ("\nInit special inode ")); cFYI(1, (" Init special inode "));
init_special_inode(inode, inode->i_mode, init_special_inode(inode, inode->i_mode,
kdev_t_to_nr(inode->i_rdev)); kdev_t_to_nr(inode->i_rdev));
} }
...@@ -174,7 +175,7 @@ cifs_get_inode_info(struct inode **pinode, ...@@ -174,7 +175,7 @@ cifs_get_inode_info(struct inode **pinode,
xid = GetXid(); xid = GetXid();
pTcon = cifs_sb->tcon; 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 */ /* we could have done a find first instead but this returns more info */
rc = CIFSSMBQPathInfo(xid, pTcon, search_path, &findData, rc = CIFSSMBQPathInfo(xid, pTcon, search_path, &findData,
cifs_sb->local_nls); cifs_sb->local_nls);
...@@ -214,20 +215,20 @@ cifs_get_inode_info(struct inode **pinode, ...@@ -214,20 +215,20 @@ cifs_get_inode_info(struct inode **pinode,
/* get new inode */ /* get new inode */
if (*pinode == NULL) { if (*pinode == NULL) {
*pinode = new_inode(sb); *pinode = new_inode(sb);
cFYI(1, ("\nAlloc new inode %p ", *pinode)); cFYI(1, (" Alloc new inode %p ", *pinode));
} }
inode = *pinode; inode = *pinode;
cifsInfo = CIFS_I(inode); cifsInfo = CIFS_I(inode);
findData.Attributes = le32_to_cpu(findData.Attributes); findData.Attributes = le32_to_cpu(findData.Attributes);
cifsInfo->cifsAttrs = findData.Attributes; cifsInfo->cifsAttrs = findData.Attributes;
cFYI(1, ("\nOld time %ld ", cifsInfo->time)); cFYI(1, (" Old time %ld ", cifsInfo->time));
cifsInfo->time = jiffies; cifsInfo->time = jiffies;
cFYI(1, (" New time %ld ", cifsInfo->time)); cFYI(1, (" New time %ld ", cifsInfo->time));
atomic_inc(&cifsInfo->inUse); /* inc on every refresh of inode */ atomic_inc(&cifsInfo->inUse); /* inc on every refresh of inode */
inode->i_blksize = 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 */ /* Linux can not store file creation time unfortunately so we ignore it */
inode->i_atime = inode->i_atime =
cifs_NTtimeToUnix(le64_to_cpu(findData.LastAccessTime)); cifs_NTtimeToUnix(le64_to_cpu(findData.LastAccessTime));
...@@ -239,7 +240,7 @@ cifs_get_inode_info(struct inode **pinode, ...@@ -239,7 +240,7 @@ cifs_get_inode_info(struct inode **pinode,
/* should we treat the dos attribute of read-only as read-only mode bit e.g. 555 */ /* 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 */ inode->i_mode = S_IALLUGO & ~(S_ISUID | S_IXGRP); /* 2767 perms indicate mandatory locking - will override for dirs later */
cFYI(0, cFYI(0,
("\nAttributes came in as 0x%x\n", findData.Attributes)); (" Attributes came in as 0x%x ", findData.Attributes));
if (findData.Attributes & ATTR_REPARSE) { if (findData.Attributes & ATTR_REPARSE) {
/* Can IFLNK be set as it basically is on windows with IFREG or IFDIR? */ /* Can IFLNK be set as it basically is on windows with IFREG or IFDIR? */
inode->i_mode |= S_IFLNK; inode->i_mode |= S_IFLNK;
...@@ -256,7 +257,7 @@ cifs_get_inode_info(struct inode **pinode, ...@@ -256,7 +257,7 @@ cifs_get_inode_info(struct inode **pinode,
inode->i_blocks = inode->i_blocks =
do_div(findData.AllocationSize, inode->i_blksize); do_div(findData.AllocationSize, inode->i_blksize);
cFYI(1, cFYI(1,
("\n Size %ld and blocks %ld ", (" Size %ld and blocks %ld ",
(unsigned long) inode->i_size, inode->i_blocks)); (unsigned long) inode->i_size, inode->i_blocks));
inode->i_nlink = le32_to_cpu(findData.NumberOfLinks); inode->i_nlink = le32_to_cpu(findData.NumberOfLinks);
...@@ -307,7 +308,7 @@ cifs_unlink(struct inode *inode, struct dentry *direntry) ...@@ -307,7 +308,7 @@ cifs_unlink(struct inode *inode, struct dentry *direntry)
char *full_path = NULL; char *full_path = NULL;
struct cifsInodeInfo *cifsInode; struct cifsInodeInfo *cifsInode;
cFYI(1, ("\n cifs_unlink, inode = 0x%p with ", inode)); cFYI(1, (" cifs_unlink, inode = 0x%p with ", inode));
xid = GetXid(); xid = GetXid();
...@@ -356,7 +357,7 @@ cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) ...@@ -356,7 +357,7 @@ cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
char *full_path = NULL; char *full_path = NULL;
struct inode *newinode = 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(); xid = GetXid();
...@@ -367,7 +368,7 @@ cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) ...@@ -367,7 +368,7 @@ cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
/* BB add setting the equivalent of mode via CreateX w/ACLs */ /* BB add setting the equivalent of mode via CreateX w/ACLs */
rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls); rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls);
if (rc) { if (rc) {
cFYI(1, ("\ncifs_mkdir returned 0x%x ", rc)); cFYI(1, ("cifs_mkdir returned 0x%x ", rc));
} else { } else {
inode->i_nlink++; inode->i_nlink++;
if (pTcon->ses->capabilities & CAP_UNIX) if (pTcon->ses->capabilities & CAP_UNIX)
...@@ -407,7 +408,7 @@ cifs_rmdir(struct inode *inode, struct dentry *direntry) ...@@ -407,7 +408,7 @@ cifs_rmdir(struct inode *inode, struct dentry *direntry)
char *full_path = NULL; char *full_path = NULL;
struct cifsInodeInfo *cifsInode; struct cifsInodeInfo *cifsInode;
cFYI(1, ("\nn cifs_rmdir, inode = 0x%p with ", inode)); cFYI(1, (" cifs_rmdir, inode = 0x%p with ", inode));
xid = GetXid(); xid = GetXid();
...@@ -493,7 +494,7 @@ cifs_revalidate(struct dentry *direntry) ...@@ -493,7 +494,7 @@ cifs_revalidate(struct dentry *direntry)
full_path = build_path_from_dentry(direntry); full_path = build_path_from_dentry(direntry);
cFYI(1, 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, full_path, direntry->d_inode,
direntry->d_inode->i_count.counter, direntry, direntry->d_inode->i_count.counter, direntry,
direntry->d_time, jiffies)); direntry->d_time, jiffies));
...@@ -562,7 +563,7 @@ cifs_truncate_file(struct inode *inode) ...@@ -562,7 +563,7 @@ cifs_truncate_file(struct inode *inode)
full_path = build_path_from_dentry(dirent); full_path = build_path_from_dentry(dirent);
rc = CIFSSMBSetEOF(xid, pTcon, full_path, inode->i_size,FALSE, rc = CIFSSMBSetEOF(xid, pTcon, full_path, inode->i_size,FALSE,
cifs_sb->local_nls); cifs_sb->local_nls);
cFYI(1,("\nSetEOF (truncate) rc = %d",rc)); cFYI(1,(" SetEOF (truncate) rc = %d",rc));
if(rc == -ETXTBSY) { if(rc == -ETXTBSY) {
cifsInode = CIFS_I(inode); cifsInode = CIFS_I(inode);
if(!list_empty(&(cifsInode->openFileList))) { if(!list_empty(&(cifsInode->openFileList))) {
...@@ -572,7 +573,7 @@ cifs_truncate_file(struct inode *inode) ...@@ -572,7 +573,7 @@ cifs_truncate_file(struct inode *inode)
rc = CIFSSMBSetFileSize(xid, pTcon, inode->i_size, rc = CIFSSMBSetFileSize(xid, pTcon, inode->i_size,
open_file->netfid,open_file->pid,FALSE); open_file->netfid,open_file->pid,FALSE);
} else { } else {
cFYI(1,("\nNo open files to get file handle from")); cFYI(1,(" No open files to get file handle from"));
} }
} }
if (!rc) if (!rc)
...@@ -604,7 +605,7 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs) ...@@ -604,7 +605,7 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs)
xid = GetXid(); xid = GetXid();
cFYI(1, 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)); direntry->d_name.name, attrs->ia_valid));
cifs_sb = CIFS_SB(direntry->d_inode->i_sb); cifs_sb = CIFS_SB(direntry->d_inode->i_sb);
pTcon = cifs_sb->tcon; pTcon = cifs_sb->tcon;
...@@ -614,12 +615,12 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs) ...@@ -614,12 +615,12 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs)
/* BB check if we need to refresh inode from server now ? BB */ /* 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) { if (attrs->ia_valid & ATTR_SIZE) {
rc = CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size,FALSE, rc = CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size,FALSE,
cifs_sb->local_nls); cifs_sb->local_nls);
cFYI(1,("\nSetEOF (setattrs) rc = %d",rc)); cFYI(1,(" SetEOF (setattrs) rc = %d",rc));
if(rc == -ETXTBSY) { if(rc == -ETXTBSY) {
if(!list_empty(&(cifsInode->openFileList))) { if(!list_empty(&(cifsInode->openFileList))) {
...@@ -629,29 +630,30 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs) ...@@ -629,29 +630,30 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs)
rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size,
open_file->netfid,open_file->pid,FALSE); open_file->netfid,open_file->pid,FALSE);
} else { } 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 /* For Allocation Size - do not need to call the following
following but might as well and it does not hurt if it fails */ it did not hurt if it fails but why bother */
CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size, TRUE, cifs_sb->local_nls); /* CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size, TRUE, cifs_sb->local_nls);*/
if (rc == 0) if (rc == 0) {
vmtruncate(direntry->d_inode, attrs->ia_size); rc = vmtruncate(direntry->d_inode, attrs->ia_size);
/* BB add special case to handle sharing violation (due to Samba bug) nobh_truncate_page(direntry->d_inode->i_mapping, direntry->d_inode->i_size);
by calling SetFileInfo to set the sizes */ /* cFYI(1,("truncate_page to 0x%lx \n",direntry->d_inode->i_size)); */
}
} }
if (attrs->ia_valid & ATTR_UID) { 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; uid = attrs->ia_uid;
/* entry->uid = cpu_to_le16(attr->ia_uid); */ /* entry->uid = cpu_to_le16(attr->ia_uid); */
} }
if (attrs->ia_valid & ATTR_GID) { 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; gid = attrs->ia_gid;
/* entry->gid = cpu_to_le16(attr->ia_gid); */ /* entry->gid = cpu_to_le16(attr->ia_gid); */
} }
if (attrs->ia_valid & ATTR_MODE) { 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; mode = attrs->ia_mode;
/* entry->mode = cpu_to_le16(attr->ia_mode); */ /* entry->mode = cpu_to_le16(attr->ia_mode); */
} }
...@@ -680,7 +682,7 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs) ...@@ -680,7 +682,7 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs)
if (attrs->ia_valid & ATTR_CTIME) { if (attrs->ia_valid & ATTR_CTIME) {
set_time = TRUE; 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 = time_buf.ChangeTime =
cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime)); cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime));
} else } else
...@@ -695,7 +697,7 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs) ...@@ -695,7 +697,7 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs)
rc = CIFSSMBSetTimes(xid, pTcon, full_path, &time_buf, rc = CIFSSMBSetTimes(xid, pTcon, full_path, &time_buf,
cifs_sb->local_nls); cifs_sb->local_nls);
} }
cifsInode->time = 0; /* force revalidate to get attributes when needed */ /* cifsInode->time = 0; */ /* force revalidate to get attributes when needed */
if (full_path) if (full_path)
kfree(full_path); kfree(full_path);
...@@ -707,7 +709,7 @@ void ...@@ -707,7 +709,7 @@ void
cifs_delete_inode(struct inode *inode) cifs_delete_inode(struct inode *inode)
{ {
/* Note: called without the big kernel filelock - remember spinlocks! */ /* 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 /* may have to add back in when safe distributed caching of
directories via e.g. FindNotify added */ directories via e.g. FindNotify added */
} }
...@@ -88,7 +88,7 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd) ...@@ -88,7 +88,7 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
xid = GetXid(); xid = GetXid();
full_path = build_path_from_dentry(direntry); 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); cifs_sb = CIFS_SB(inode->i_sb);
pTcon = cifs_sb->tcon; pTcon = cifs_sb->tcon;
...@@ -136,8 +136,8 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname) ...@@ -136,8 +136,8 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
pTcon = cifs_sb->tcon; pTcon = cifs_sb->tcon;
full_path = build_path_from_dentry(direntry); full_path = build_path_from_dentry(direntry);
cFYI(1, ("\nFull path: %s ", full_path)); cFYI(1, ("Full path: %s ", full_path));
cFYI(1, (" symname is %s\n", symname)); cFYI(1, ("symname is %s", symname));
/* BB what if DFS and this volume is on different share? BB */ /* BB what if DFS and this volume is on different share? BB */
if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)
...@@ -156,7 +156,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname) ...@@ -156,7 +156,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
if (rc != 0) { if (rc != 0) {
cFYI(1, 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)); rc));
} else { } else {
direntry->d_op = &cifs_dentry_ops; direntry->d_op = &cifs_dentry_ops;
...@@ -188,7 +188,7 @@ cifs_readlink(struct dentry *direntry, char *pBuffer, int buflen) ...@@ -188,7 +188,7 @@ cifs_readlink(struct dentry *direntry, char *pBuffer, int buflen)
pTcon = cifs_sb->tcon; pTcon = cifs_sb->tcon;
full_path = build_path_from_dentry(direntry); full_path = build_path_from_dentry(direntry);
cFYI(1, 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)); full_path, inode, pBuffer, buflen));
/* BB add read reparse point symlink code and Unix extensions symlink code here BB */ /* BB add read reparse point symlink code and Unix extensions symlink code here BB */
......
...@@ -81,7 +81,7 @@ void ...@@ -81,7 +81,7 @@ void
sesInfoFree(struct cifsSesInfo *buf_to_free) sesInfoFree(struct cifsSesInfo *buf_to_free)
{ {
if (buf_to_free == NULL) { if (buf_to_free == NULL) {
cFYI(1, ("\nNull buffer passed to sesInfoFree")); cFYI(1, ("Null buffer passed to sesInfoFree"));
return; return;
} }
...@@ -122,7 +122,7 @@ void ...@@ -122,7 +122,7 @@ void
tconInfoFree(struct cifsTconInfo *buf_to_free) tconInfoFree(struct cifsTconInfo *buf_to_free)
{ {
if (buf_to_free == NULL) { if (buf_to_free == NULL) {
cFYI(1, ("\nNull buffer passed to tconInfoFree")); cFYI(1, ("Null buffer passed to tconInfoFree"));
return; return;
} }
write_lock(&GlobalSMBSeslock); write_lock(&GlobalSMBSeslock);
...@@ -169,7 +169,7 @@ buf_release(void *buf_to_free) ...@@ -169,7 +169,7 @@ buf_release(void *buf_to_free)
{ {
if (buf_to_free == NULL) { if (buf_to_free == NULL) {
cFYI(1, ("\nNull buffer passed to buf_release")); cFYI(1, ("Null buffer passed to buf_release"));
return; return;
} }
kmem_cache_free(cifs_req_cachep, buf_to_free); kmem_cache_free(cifs_req_cachep, buf_to_free);
...@@ -225,7 +225,9 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ , ...@@ -225,7 +225,9 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
} }
if (treeCon->Flags & SMB_SHARE_IS_IN_DFS) if (treeCon->Flags & SMB_SHARE_IS_IN_DFS)
buffer->Flags2 |= SMBFLG2_DFS; buffer->Flags2 |= SMBFLG2_DFS;
if(treeCon->ses->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) if(treeCon->ses->server)
if(treeCon->ses->server->secMode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
} }
...@@ -248,17 +250,17 @@ checkSMBhdr(struct smb_hdr *smb, __u16 mid) ...@@ -248,17 +250,17 @@ checkSMBhdr(struct smb_hdr *smb, __u16 mid)
if(smb->Command == SMB_COM_LOCKING_ANDX) if(smb->Command == SMB_COM_LOCKING_ANDX)
return 0; return 0;
else else
cERROR(1, ("\n Rcvd Request not response ")); cERROR(1, ("Rcvd Request not response "));
} }
} else { /* bad signature or mid */ } else { /* bad signature or mid */
if (*(unsigned int *) smb->Protocol != cpu_to_le32(0x424d53ff)) if (*(unsigned int *) smb->Protocol != cpu_to_le32(0x424d53ff))
cERROR(1, cERROR(1,
("\nBad protocol string signature header %x ", ("Bad protocol string signature header %x ",
*(unsigned int *) smb->Protocol)); *(unsigned int *) smb->Protocol));
if (mid != smb->Mid) 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; return 1;
} }
...@@ -266,13 +268,13 @@ int ...@@ -266,13 +268,13 @@ int
checkSMB(struct smb_hdr *smb, __u16 mid, int length) checkSMB(struct smb_hdr *smb, __u16 mid, int length)
{ {
cFYI(0, 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))); length, ntohl(smb->smb_buf_length)));
if ((length < 2 + sizeof (struct smb_hdr)) if ((length < 2 + sizeof (struct smb_hdr))
|| (4 + ntohl(smb->smb_buf_length) > || (4 + ntohl(smb->smb_buf_length) >
CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE)) { CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE)) {
if (length < 2 + sizeof (struct smb_hdr)) { 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) if ((length >= sizeof (struct smb_hdr) - 1)
&& (smb->Status.CifsError != 0)) && (smb->Status.CifsError != 0))
return 0; /* some error cases do not return wct and bcc */ return 0; /* some error cases do not return wct and bcc */
...@@ -281,9 +283,9 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length) ...@@ -281,9 +283,9 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
if (4 + ntohl(smb->smb_buf_length) > if (4 + ntohl(smb->smb_buf_length) >
CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE) CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE)
cERROR(1, cERROR(1,
("\n smb_buf_length greater than CIFS_MAX_MSGSIZE ... ")); ("smb_buf_length greater than CIFS_MAX_MSGSIZE ... "));
cERROR(1, cERROR(1,
("CIFS: bad smb detected. Illegal length. The mid=%d\n", ("bad smb detected. Illegal length. The mid=%d",
smb->Mid)); smb->Mid));
return 1; return 1;
} }
...@@ -295,9 +297,9 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length) ...@@ -295,9 +297,9 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
|| (4 + ntohl(smb->smb_buf_length) != length)) { || (4 + ntohl(smb->smb_buf_length) != length)) {
return 0; return 0;
} else { } else {
cERROR(1, ("\nCIFS: smbCalcSize %x ", smbCalcSize(smb))); cERROR(1, ("smbCalcSize %x ", smbCalcSize(smb)));
cERROR(1, cERROR(1,
("CIFS: bad smb size detected. The Mid=%d\n", smb->Mid)); ("bad smb size detected. The Mid=%d", smb->Mid));
return 1; return 1;
} }
} }
...@@ -306,10 +308,12 @@ is_valid_oplock_break(struct smb_hdr *buf) ...@@ -306,10 +308,12 @@ is_valid_oplock_break(struct smb_hdr *buf)
{ {
struct smb_com_lock_req * pSMB = (struct smb_com_lock_req *)buf; struct smb_com_lock_req * pSMB = (struct smb_com_lock_req *)buf;
struct list_head *tmp; struct list_head *tmp;
struct list_head *tmp1;
struct cifsTconInfo *tcon; struct cifsTconInfo *tcon;
struct cifsFileInfo *netfile;
/* could add check for smb response flag 0x80 */ /* could add check for smb response flag 0x80 */
cFYI(1,("\nChecking for oplock break")); cFYI(1,("Checking for oplock break"));
if(pSMB->hdr.Command != SMB_COM_LOCKING_ANDX) if(pSMB->hdr.Command != SMB_COM_LOCKING_ANDX)
return FALSE; return FALSE;
if(pSMB->hdr.Flags & SMBFLG_RESPONSE) if(pSMB->hdr.Flags & SMBFLG_RESPONSE)
...@@ -325,20 +329,29 @@ is_valid_oplock_break(struct smb_hdr *buf) ...@@ -325,20 +329,29 @@ is_valid_oplock_break(struct smb_hdr *buf)
read_lock(&GlobalSMBSeslock); read_lock(&GlobalSMBSeslock);
list_for_each(tmp, &GlobalTreeConnectionList) { list_for_each(tmp, &GlobalTreeConnectionList) {
tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
if (tcon->tid == buf->Tid) if (tcon->tid == buf->Tid) {
if(tcon->ses->Suid == buf->Uid) { list_for_each(tmp1,&tcon->openFileList){
netfile = list_entry(tmp1,struct cifsFileInfo,tlist);
if(pSMB->Fid == netfile->netfid) {
/* BB Add following logic: /* BB Add following logic:
2) look up inode from tcon->openFileList->file->f_dentry->d_inode 2) look up inode from tcon->openFileList->file->f_dentry->d_inode
3) flush dirty pages and cached byte range locks and mark 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 4) depending on break type change to r/o caching or no caching
5) send oplock break response to server */ cifsinode->clientCanCacheAll = 0
5) inode->i_data.a_ops = &cifs_addr_ops_writethrough;
6) send oplock break response to server */
read_unlock(&GlobalSMBSeslock); read_unlock(&GlobalSMBSeslock);
cFYI(1,("\nFound matching connection, process oplock break")); cFYI(1,("Matching file id, processing oplock break"));
return TRUE; return TRUE;
} }
} }
read_unlock(&GlobalSMBSeslock); read_unlock(&GlobalSMBSeslock);
cFYI(1,("\nProcessing oplock break for non-existent connection")); 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; return TRUE;
} }
...@@ -355,7 +368,7 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length) ...@@ -355,7 +368,7 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length)
buffer = (unsigned char *) smb_buf; buffer = (unsigned char *) smb_buf;
for (i = 0, j = 0; i < smb_buf_length; i++, j++) { for (i = 0, j = 0; i < smb_buf_length; i++, j++) {
if (i % 8 == 0) { /* we have reached the beginning of line */ if (i % 8 == 0) { /* we have reached the beginning of line */
printk("\n| "); printk(KERN_DEBUG "| ");
j = 0; j = 0;
} }
printk("%0#4x ", buffer[i]); printk("%0#4x ", buffer[i]);
...@@ -367,7 +380,7 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length) ...@@ -367,7 +380,7 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length)
if (i % 8 == 7) { /* we have reached end of line, time to print ascii */ if (i % 8 == 7) { /* we have reached end of line, time to print ascii */
debug_line[16] = 0; debug_line[16] = 0;
printk(" | %s", debug_line); printk(" | %s\n", debug_line);
} }
} }
for (; j < 8; j++) { for (; j < 8; j++) {
...@@ -375,6 +388,6 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length) ...@@ -375,6 +388,6 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length)
debug_line[2 * j] = ' '; debug_line[2 * j] = ' ';
debug_line[1 + (2 * j)] = ' '; debug_line[1 + (2 * j)] = ' ';
} }
printk(" | %s\n", debug_line); printk( " | %s\n", debug_line);
return; return;
} }
...@@ -753,12 +753,11 @@ cifs_print_status(__u32 status_code) ...@@ -753,12 +753,11 @@ cifs_print_status(__u32 status_code)
{ {
int idx = 0; int idx = 0;
printk("\nStatus code returned: 0x%08x ", status_code);
while (nt_errs[idx].nt_errstr != NULL) { while (nt_errs[idx].nt_errstr != NULL) {
if (((nt_errs[idx].nt_errcode) & 0xFFFFFF) == if (((nt_errs[idx].nt_errcode) & 0xFFFFFF) ==
(status_code & 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++; idx++;
} }
...@@ -815,11 +814,8 @@ map_smb_to_linux_error(struct smb_hdr *smb) ...@@ -815,11 +814,8 @@ map_smb_to_linux_error(struct smb_hdr *smb)
} }
/* old style errors */ /* 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 */ if (smberrclass == ERRDOS) { /* one byte field no need to byte reverse */
for (i = 0; for (i = 0;
i < i <
...@@ -849,10 +845,7 @@ map_smb_to_linux_error(struct smb_hdr *smb) ...@@ -849,10 +845,7 @@ map_smb_to_linux_error(struct smb_hdr *smb)
} }
/* else ERRHRD class errors or junk - return EIO */ /* else ERRHRD class errors or junk - return EIO */
/* BB get smb->error_class and code lookup in table if ERR_STATUS is not cFYI(1, (" !!Mapping smb error code %d to POSIX err %d !!", smberrcode,rc));
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));
/* generic corrective action e.g. reconnect SMB session on ERRbaduid could be added */ /* generic corrective action e.g. reconnect SMB session on ERRbaduid could be added */
......
...@@ -305,7 +305,7 @@ make_oem_passwd_hash(char data[516], const char *passwd, ...@@ -305,7 +305,7 @@ make_oem_passwd_hash(char data[516], const char *passwd,
if (new_pw_len > 512) { if (new_pw_len > 512) {
cERROR(1, 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; return FALSE;
} }
......
...@@ -40,10 +40,9 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses) ...@@ -40,10 +40,9 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
/* BB add spinlock to protect midq for each session BB */ /* BB add spinlock to protect midq for each session BB */
if (ses == NULL) { if (ses == NULL) {
cERROR(1, ("\nNull session passed in to AllocMidQEntry ")); cERROR(1, ("Null session passed in to AllocMidQEntry "));
return NULL; return NULL;
} }
temp = kmalloc(sizeof (struct mid_q_entry), GFP_KERNEL);
temp = (struct mid_q_entry *) kmem_cache_alloc(cifs_mid_cachep, temp = (struct mid_q_entry *) kmem_cache_alloc(cifs_mid_cachep,
SLAB_KERNEL); SLAB_KERNEL);
if (temp == NULL) if (temp == NULL)
...@@ -53,21 +52,19 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses) ...@@ -53,21 +52,19 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
temp->mid = smb_buffer->Mid; /* always LE */ temp->mid = smb_buffer->Mid; /* always LE */
temp->pid = current->pid; temp->pid = current->pid;
temp->command = smb_buffer->Command; 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); do_gettimeofday(&temp->when_sent);
temp->ses = ses; temp->ses = ses;
temp->tsk = current; temp->tsk = current;
} }
if (ses->status == CifsGood) { if (ses->server->tcpStatus == CifsGood) {
write_lock(&GlobalMid_Lock); write_lock(&GlobalMid_Lock);
list_add_tail(&temp->qhead, &ses->server->pending_mid_q); list_add_tail(&temp->qhead, &ses->server->pending_mid_q);
atomic_inc(&midCount); atomic_inc(&midCount);
temp->midState = MID_REQUEST_ALLOCATED; temp->midState = MID_REQUEST_ALLOCATED;
write_unlock(&GlobalMid_Lock); write_unlock(&GlobalMid_Lock);
} else { /* BB add reconnect code here BB */ } else { /* could add more reconnect code here BB */
cERROR(1,("Need to reconnect after session died to server"));
cERROR(1,
("\nNeed to reconnect after session died to server\n"));
if (temp) if (temp)
kmem_cache_free(cifs_mid_cachep, temp); kmem_cache_free(cifs_mid_cachep, temp);
return NULL; return NULL;
...@@ -121,7 +118,7 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer, ...@@ -121,7 +118,7 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
sign_smb(smb_buffer); */ /* BB enable when signing tested more */ sign_smb(smb_buffer); */ /* BB enable when signing tested more */
smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length); 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); dump_smb(smb_buffer, smb_buf_length + 4);
temp_fs = get_fs(); /* we must turn off socket api parm checking */ temp_fs = get_fs(); /* we must turn off socket api parm checking */
...@@ -132,7 +129,7 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer, ...@@ -132,7 +129,7 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
if (rc < 0) { if (rc < 0) {
cERROR(1, cERROR(1,
("\nError %d sending data on socket to server.\n", rc)); ("Error %d sending data on socket to server.", rc));
} else } else
rc = 0; rc = 0;
...@@ -154,7 +151,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, ...@@ -154,7 +151,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
return -EIO; /* reconnect should be done, if possible, in AllocMidQEntry */ return -EIO; /* reconnect should be done, if possible, in AllocMidQEntry */
if (in_buf->smb_buf_length > CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE) { if (in_buf->smb_buf_length > CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE) {
cERROR(1, cERROR(1,
("\nIllegal length, greater than maximum frame, %d ", ("Illegal length, greater than maximum frame, %d ",
in_buf->smb_buf_length)); in_buf->smb_buf_length));
DeleteMidQEntry(midQ); DeleteMidQEntry(midQ);
return -EIO; return -EIO;
...@@ -163,27 +160,21 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, ...@@ -163,27 +160,21 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length, rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
(struct sockaddr *) &(ses->server->sockAddr)); (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; timeout = 300 * HZ;
else if (long_op == 1) else if (long_op == 1)
timeout = 60 * HZ; timeout = 60 * HZ;
else else
timeout = 15 * HZ; timeout = 15 * HZ;
/* wait for 15 seconds or until woken up due to response arriving or due to /* wait for 15 seconds or until woken up due to response arriving or
last connection to this server being unmounted */ 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 */
timeout = wait_event_interruptible_timeout(ses->server->response_q, timeout = wait_event_interruptible_timeout(ses->server->response_q,
midQ-> midQ->
midState & MID_RESPONSE_RECEIVED, midState & MID_RESPONSE_RECEIVED,
timeout); timeout);
cFYI(1,
(" with timeout %ld and Out_buf: %p midQ->resp_buf: %p ", timeout,
out_buf, midQ->resp_buf));
if (signal_pending(current)) { if (signal_pending(current)) {
cERROR(1, (KERN_ERR "\nCIFS: caught signal")); cERROR(1, ("CIFS: caught signal"));
DeleteMidQEntry(midQ); DeleteMidQEntry(midQ);
return -EINTR; return -EINTR;
} else { } else {
...@@ -198,11 +189,11 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, ...@@ -198,11 +189,11 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
if (timeout == 0) { if (timeout == 0) {
cFYI(1, cFYI(1,
("\nTimeout on receive. Assume response SMB is invalid.\n")); ("Timeout on receive. Assume response SMB is invalid."));
rc = -ETIMEDOUT; rc = -ETIMEDOUT;
} else if (receive_len > CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE) { } else if (receive_len > CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE) {
cERROR(1, cERROR(1,
("\nFrame too large received. Length: %d Xid: %d\n", ("Frame too large received. Length: %d Xid: %d",
receive_len, xid)); receive_len, xid));
rc = -EIO; rc = -EIO;
} else { /* rcvd frame is ok */ } else { /* rcvd frame is ok */
...@@ -215,7 +206,6 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, ...@@ -215,7 +206,6 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
/* convert the length back to a form that we can use */ /* convert the length back to a form that we can use */
dump_smb(out_buf, 92); dump_smb(out_buf, 92);
out_buf->smb_buf_length = out_buf->smb_buf_length =
be32_to_cpu(out_buf->smb_buf_length); be32_to_cpu(out_buf->smb_buf_length);
if (out_buf->smb_buf_length > 12) if (out_buf->smb_buf_length > 12)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment