Commit b668ec86 authored by Steve French's avatar Steve French

Merge in fixes from version 0.6.5 of the CIFS VFS. Greatly improved...

Merge in fixes from version 0.6.5 of the CIFS VFS.  Greatly improved performance including improved distributed caching support and support for readpages and larger read sizes. Cache data now flushed properly at file close time. Socket and memory leak fixed.  Fix two oops. Fix error logging and made more consistent.  Generic sendfile added.
parent 15f1049d
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
------------
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
=====================================================
......@@ -7,7 +7,8 @@ Contributions are welcome. There are plenty of opportunities
for visible, important contributions to this module. Here
is a partial list of the known problems and missing features:
a) Support for SecurityDescriptors for chmod/chgrp/chown
a) Support for SecurityDescriptors for chmod/chgrp/chown so
these can be supported for Windows servers
b) Better pam/winbind integration
......@@ -16,9 +17,9 @@ c) multi-user mounts - multiplexed sessionsetups over single vc
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
using FindNotify or equivalent. - (started)
......@@ -28,27 +29,34 @@ of recent 2.5 kernel improvements in byte-range locking
h) quota support
i) support for the Linux 2.5 kernel new feature get_xattr and set_xattr
which will allow us to expose dos attributes as well as real
ACLs
j) finish off the mount helper, mount.cifs - (started)
KNOWN BUGS (updated October 8nd, 2002)
k) finish writepages support (multi-page write behind for improved
performance) and syncpage
l) hook lower into the sockets api (as NFS/SunRPC does) to avoid the
extra copy in/out of the socket buffers in some cases.
m) finish support for IPv6
KNOWN BUGS (updated 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
support the CIFS Unix extensions but Samba has a bug currently handling
symlink text beginning with slash
2) delete of file with read-only attribute set will fail (may be ok)
3) autoreconnection logic is only partially complete.
4) there may be a problem with truncating a memmapped file to smaller than 4k with
the size being reported as exactly 4k.
Misc testing to do
=================
1) check out max path names and max path name components against various server
types.
2) Run POSIX bencharks against cifs
2) Run dbench
3) Run dbench
3) Finish FSX testing on SMP now that we workaround the Samba bug
4) Finish FSX testing on SMP now that we workaround the Samba bug
4) Additional performance testing and optimization
......@@ -458,16 +458,18 @@ decode_negTokenInit(unsigned char *security_blob, int length,
unsigned int cls, con, tag, oidlen, rc;
int use_ntlmssp = FALSE;
*secType = NTLM; /* BB eventually make Kerberos or NLTMSSP the default */
/* cifs_dump_mem(" Received SecBlob ", security_blob, length); */
asn1_open(&ctx, security_blob, length);
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
cFYI(1, ("\nError decoding negTokenInit header "));
cFYI(1, ("Error decoding negTokenInit header "));
return 0;
} else if ((cls != ASN1_APL) || (con != ASN1_CON)
|| (tag != ASN1_EOC)) {
cFYI(1, ("\ncls = %d con = %d tag = %d", cls, con, tag));
cFYI(1, ("cls = %d con = %d tag = %d", cls, con, tag));
return 0;
} else {
/* remember to free obj->oid */
......@@ -486,51 +488,49 @@ decode_negTokenInit(unsigned char *security_blob, int length,
}
if (!rc) {
cFYI(1, ("\nError decoding negTokenInit header"));
cFYI(1, ("Error decoding negTokenInit header"));
return 0;
}
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
cFYI(1, ("\nError decoding negTokenInit "));
cFYI(1, ("Error decoding negTokenInit "));
return 0;
} else if ((cls != ASN1_CTX) || (con != ASN1_CON)
|| (tag != ASN1_EOC)) {
cFYI(1,
("\ncls = %d con = %d tag = %d end = %p (%d) exit 0",
cFYI(1,("cls = %d con = %d tag = %d end = %p (%d) exit 0",
cls, con, tag, end, *end));
return 0;
}
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
cFYI(1, ("\nError decoding negTokenInit "));
cFYI(1, ("Error decoding negTokenInit "));
return 0;
} else if ((cls != ASN1_UNI) || (con != ASN1_CON)
|| (tag != ASN1_SEQ)) {
cFYI(1,
("\ncls = %d con = %d tag = %d end = %p (%d) exit 1",
cFYI(1,("cls = %d con = %d tag = %d end = %p (%d) exit 1",
cls, con, tag, end, *end));
return 0;
}
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
cFYI(1, ("\nError decoding 2nd part of negTokenInit "));
cFYI(1, ("Error decoding 2nd part of negTokenInit "));
return 0;
} else if ((cls != ASN1_CTX) || (con != ASN1_CON)
|| (tag != ASN1_EOC)) {
cFYI(1,
("\ncls = %d con = %d tag = %d end = %p (%d) exit 0",
("cls = %d con = %d tag = %d end = %p (%d) exit 0",
cls, con, tag, end, *end));
return 0;
}
if (asn1_header_decode
(&ctx, &sequence_end, &cls, &con, &tag) == 0) {
cFYI(1, ("\nError decoding 2nd part of negTokenInit "));
cFYI(1, ("Error decoding 2nd part of negTokenInit "));
return 0;
} else if ((cls != ASN1_UNI) || (con != ASN1_CON)
|| (tag != ASN1_SEQ)) {
cFYI(1,
("\ncls = %d con = %d tag = %d end = %p (%d) exit 1",
("cls = %d con = %d tag = %d end = %p (%d) exit 1",
cls, con, tag, end, *end));
return 0;
}
......@@ -539,13 +539,13 @@ decode_negTokenInit(unsigned char *security_blob, int length,
rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag);
if (!rc) {
cFYI(1,
("\nError 1 decoding negTokenInit header exit 2"));
("Error 1 decoding negTokenInit header exit 2"));
return 0;
}
if ((tag == ASN1_OJI) && (con == ASN1_PRI)) {
asn1_oid_decode(&ctx, end, &oid, &oidlen);
cFYI(1,
("\nOID len = %d oid = 0x%lx 0x%lx 0x%lx 0x%lx",
("OID len = %d oid = 0x%lx 0x%lx 0x%lx 0x%lx",
oidlen, *oid, *(oid + 1), *(oid + 2),
*(oid + 3)));
rc = compare_oid(oid, oidlen, NTLMSSP_OID,
......@@ -554,54 +554,53 @@ decode_negTokenInit(unsigned char *security_blob, int length,
if (rc)
use_ntlmssp = TRUE;
} else {
cFYI(1,
("\nThis should be an oid what is going on? "));
cFYI(1,("This should be an oid what is going on? "));
}
}
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
cFYI(1,
("\nError decoding last part of negTokenInit exit 3"));
("Error decoding last part of negTokenInit exit 3"));
return 0;
} else if ((cls != ASN1_CTX) || (con != ASN1_CON)) { /* tag = 3 indicating mechListMIC */
cFYI(1,
("\nExit 4 cls = %d con = %d tag = %d end = %p (%d)",
("Exit 4 cls = %d con = %d tag = %d end = %p (%d)",
cls, con, tag, end, *end));
return 0;
}
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
cFYI(1,
("\nError decoding last part of negTokenInit exit 5"));
("Error decoding last part of negTokenInit exit 5"));
return 0;
} else if ((cls != ASN1_UNI) || (con != ASN1_CON)
|| (tag != ASN1_SEQ)) {
cFYI(1,
("\nExit 6 cls = %d con = %d tag = %d end = %p (%d)",
("Exit 6 cls = %d con = %d tag = %d end = %p (%d)",
cls, con, tag, end, *end));
}
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
cFYI(1,
("\nError decoding last part of negTokenInit exit 7"));
("Error decoding last part of negTokenInit exit 7"));
return 0;
} else if ((cls != ASN1_CTX) || (con != ASN1_CON)) {
cFYI(1,
("\nExit 8 cls = %d con = %d tag = %d end = %p (%d)",
("Exit 8 cls = %d con = %d tag = %d end = %p (%d)",
cls, con, tag, end, *end));
return 0;
}
if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
cFYI(1,
("\nError decoding last part of negTokenInit exit 9"));
("Error decoding last part of negTokenInit exit 9"));
return 0;
} else if ((cls != ASN1_UNI) || (con != ASN1_PRI)
|| (tag != ASN1_GENSTR)) {
cFYI(1,
("\nExit 10 cls = %d con = %d tag = %d end = %p (%d)",
("Exit 10 cls = %d con = %d tag = %d end = %p (%d)",
cls, con, tag, end, *end));
return 0;
}
cFYI(1, ("\nNeed to call asn1_octets_decode() function for this %s", ctx.pointer)); /* is this UTF-8 or ASCII? */
cFYI(1, ("Need to call asn1_octets_decode() function for this %s", ctx.pointer)); /* is this UTF-8 or ASCII? */
}
/* if (use_kerberos)
......
......@@ -39,7 +39,8 @@ cifs_dump_mem(char *label, void *data, int length)
char *charptr = data;
char buf[10], line[80];
printk("%s: dump of %d bytes of data at 0x%p\n\n", label, length, data);
printk(KERN_DEBUG "%s: dump of %d bytes of data at 0x%p\n\n",
label, length, data);
for (i = 0; i < length; i += 16) {
line[0] = 0;
for (j = 0; (j < 4) && (i + j * 4 < length); j++) {
......@@ -52,7 +53,7 @@ cifs_dump_mem(char *label, void *data, int length)
buf[1] = isprint(charptr[i + j]) ? charptr[i + j] : '.';
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,
int length = 0;
char *buf_start = buf;
printk("\n\nEntering cifs_debug_data_read: buf=0x%p, beginBuffer=0x%p, offset=%ld, count=%d, eof=%d, data=0x%p\n", buf, *beginBuffer, offset, count, *eof, data); /* BB remove */
length =
sprintf(buf,
"Display Internal CIFS Data Structures for Debugging\n"
......@@ -85,17 +85,17 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
length =
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),
ses->serverOS, ses->serverNOS, ses->capabilities);
buf += length;
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);
sprintf(buf, "\n");
buf++;
printk("\nTotal Buffer so far: %s\n", buf_start);
length = sprintf(buf, "\nShares: \n");
buf += length;
......@@ -107,7 +107,7 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
length =
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,
atomic_read(&tcon->useCount),
tcon->nativeFileSystem,
......
......@@ -33,19 +33,24 @@ void dump_smb(struct smb_hdr *, int);
*/
#ifdef CIFS_DEBUG
/* information message: e.g., configuration, major event */
extern int cifsFYI;
#define cFYI(button,prspec)\
{ if (button && cifsFYI) printk prspec; }
#define cifsfyi(format,arg...) if (cifsFYI) printk(KERN_DEBUG " " __FILE__ ": " format "\n" "" , ## arg)
#define cFYI(button,prspec) if (button) cifsfyi prspec
#define cifswarn(format, arg...) printk(KERN_WARNING ": " format "\n" , ## arg)
/* debug event message: */
#define cEVENT(button,prspec)\
{ if (button) printk prspec; }
extern int cifsERROR;
#define cEVENT(format,arg...) if (cifsERROR) printk(KERN_EVENT __FILE__ ": " format "\n" , ## arg)
/* error event message: e.g., i/o error */
extern int cifsERROR;
#define cERROR(button, prspec)\
{ if (button && cifsERROR) { printk prspec; if (button > 1) BUG(); } }
#define cifserror(format,arg...) if (cifsERROR) printk(KERN_ERR " CIFS VFS: " format "\n" "" , ## arg)
#define cERROR(button, prspec) if (button) cifserror prspec
/*
* debug OFF
......@@ -53,8 +58,9 @@ extern int cifsERROR;
*/
#else /* _CIFS_DEBUG */
#define cERROR(button,prspec)
#define cEVENT(button,prspec)
#define cEVENT(format,arg...)
#define cFYI(button, prspec)
#define cifserror(format,arg...)
#endif /* _CIFS_DEBUG */
/*
......
......@@ -69,7 +69,6 @@ cifs_strfromUCS_le(char *to, const wchar_t * from, /* LITTLE ENDIAN */
}
}
to[outlen] = 0;
cEVENT(0, ("cifs_strfromUCS returning %d - '%s'\n", outlen, to));
return outlen;
}
......@@ -86,15 +85,13 @@ cifs_strtoUCS(wchar_t * to, const char *from, int len,
int charlen;
int i;
cEVENT(0, ("cifs_strtoUCS - '%s'\n", from));
for (i = 0; len && *from; i++, from += charlen, len -= charlen) {
/* works for 2.4.0 kernel or later */
charlen = codepage->char2uni(from, len, &to[i]);
if (charlen < 1) {
cERROR(1,
("cifs_strtoUCS: char2uni returned %d.\n",
("cifs_strtoUCS: char2uni returned %d",
charlen));
to[i] = cpu_to_le16(0x003f); /* a question mark */
charlen = 1;
......@@ -103,8 +100,6 @@ cifs_strtoUCS(wchar_t * to, const char *from, int len,
}
cEVENT(0, (" returning %d\n", i));
to[i] = 0;
return i;
}
......
......@@ -71,12 +71,13 @@ cifs_read_super(struct super_block *sb, void *data, char *devname, int silent)
if(cifs_sb == NULL)
return -ENOMEM;
cifs_sb->local_nls = load_nls_default(); /* needed for ASCII cp to Unicode converts */
rc = cifs_mount(sb, cifs_sb, data, devname);
if (rc) {
if (!silent)
cERROR(1,
("cifs_mount failed w/return code = %d\n", rc));
("cifs_mount failed w/return code = %d", rc));
goto out_mount_failed;
}
......@@ -97,13 +98,10 @@ cifs_read_super(struct super_block *sb, void *data, char *devname, int silent)
return 0;
out_no_root:
cEVENT(1, ("cifs_read_super: get root inode failed\n"));
cERROR(1, ("cifs_read_super: get root inode failed"));
if (inode)
iput(inode);
if (rc) {
cERROR(1, ("cifs_mount failed with no root inode"));
}
out_mount_failed:
if(cifs_sb)
kfree(cifs_sb);
......@@ -116,15 +114,15 @@ cifs_put_super(struct super_block *sb)
int rc = 0;
struct cifs_sb_info *cifs_sb;
cFYI(1, ("In cifs_put_super\n"));
cFYI(1, ("In cifs_put_super"));
cifs_sb = CIFS_SB(sb);
if(cifs_sb == NULL) {
cFYI(1,("\nEmpty cifs superblock info passed to unmount"));
cFYI(1,("Empty cifs superblock info passed to unmount"));
return;
}
rc = cifs_umount(sb, cifs_sb);
if (rc) {
cERROR(1, ("cifs_umount failed with return code %d\n", rc));
cERROR(1, ("cifs_umount failed with return code %d", rc));
}
unload_nls(cifs_sb->local_nls);
kfree(cifs_sb);
......@@ -180,7 +178,8 @@ cifs_alloc_inode(struct super_block *sb)
cifs_inode->cifsAttrs = 0x20; /* default */
atomic_set(&cifs_inode->inUse, 0);
cifs_inode->time = 0;
cifs_inode->clientCanCache = 0;
if(oplockEnabled)
cifs_inode->clientCanCacheAll = 1;
INIT_LIST_HEAD(&cifs_inode->openFileList);
return &cifs_inode->vfs_inode;
}
......@@ -236,7 +235,7 @@ cifs_get_sb(struct file_system_type *fs_type,
int rc;
struct super_block *sb = sget(fs_type, NULL, set_anon_super, NULL);
cFYI(1, ("\nDevname: %s flags: %d ", dev_name, flags));
cFYI(1, ("Devname: %s flags: %d ", dev_name, flags));
if (IS_ERR(sb))
return sb;
......@@ -277,8 +276,15 @@ struct inode_operations cifs_dir_inode_ops = {
struct inode_operations cifs_file_inode_ops = {
/* revalidate:cifs_revalidate, */
.setattr = cifs_setattr,
.getattr = cifs_getattr,
.getattr = cifs_getattr, /* do we need this anymore? */
.rename = cifs_rename,
#ifdef CIFS_XATTR
.setxattr = cifs_setxattr,
.getxattr = cifs_getxattr,
.listxattr = cifs_listxattr,
.removexattr = cifs_removexattr,
.permission = cifs_permission,
#endif
};
struct inode_operations cifs_symlink_inode_ops = {
......@@ -287,6 +293,12 @@ struct inode_operations cifs_symlink_inode_ops = {
/* BB add the following two eventually */
/* revalidate: cifs_revalidate,
setattr: cifs_notify_change, *//* BB do we need notify change */
#ifdef CIFS_XATTR
.setxattr = cifs_setxattr,
.getxattr = cifs_getxattr,
.listxattr = cifs_listxattr,
.removexattr = cifs_removexattr,
#endif
};
struct file_operations cifs_file_ops = {
......@@ -296,7 +308,9 @@ struct file_operations cifs_file_ops = {
.release = cifs_close,
.lock = cifs_lock,
.fsync = cifs_fsync,
.flush = cifs_flush,
.mmap = cifs_file_mmap,
.sendfile = generic_file_sendfile,
};
struct file_operations cifs_dir_ops = {
......@@ -333,7 +347,7 @@ void
cifs_destroy_inodecache(void)
{
if (kmem_cache_destroy(cifs_inode_cachep))
printk(KERN_INFO "cifs_inode_cache: error freeing\n");
printk(KERN_WARNING "cifs_inode_cache: error freeing\n");
}
int
......@@ -353,7 +367,7 @@ void
cifs_destroy_request_bufs(void)
{
if (kmem_cache_destroy(cifs_req_cachep))
printk(KERN_INFO
printk(KERN_WARNING
"cifs_destroy_request_cache: error not all structures were freed\n");
}
......@@ -373,7 +387,7 @@ void
cifs_destroy_mids(void)
{
if (kmem_cache_destroy(cifs_mid_cachep))
printk(KERN_INFO
printk(KERN_WARNING
"cifs_destroy_mids: error not all structures were freed\n");
}
......@@ -426,7 +440,7 @@ init_cifs(void)
static void __exit
exit_cifs(void)
{
cFYI(0, ("\nIn unregister ie exit_cifs"));
cFYI(0, ("In unregister ie exit_cifs"));
#if CONFIG_PROC_FS
cifs_proc_clean();
#endif
......
......@@ -74,6 +74,7 @@ extern ssize_t cifs_write(struct file *file, const char *write_data,
size_t write_size, loff_t * poffset);
extern int cifs_lock(struct file *, int, struct file_lock *);
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 struct file_operations cifs_dir_ops;
extern int cifs_dir_open(struct inode *inode, struct file *file);
......
......@@ -27,7 +27,7 @@
#define MAX_TREE_SIZE 2 + MAX_SERVER_SIZE + 1 + MAX_SHARE_SIZE + 1
#define MAX_SERVER_SIZE 15
#define MAX_SHARE_SIZE 64 /* used to be 20 - this should still be enough */
#define MAX_USERNAME_SIZE 32 /* 22 is to allow for 15 char names + null
#define MAX_USERNAME_SIZE 32 /* 32 is to allow for 15 char names + null
termination then *2 for unicode versions */
#define MAX_PASSWORD_SIZE 16
......@@ -109,6 +109,21 @@ struct TCP_Server_Info {
struct semaphore tcpSem;
struct task_struct *tsk;
char server_GUID[16];
char secMode;
enum securityEnum secType;
unsigned int maxReq; /* Clients should submit no more */
/* than maxReq distinct unanswered SMBs to the server when using */
/* multiplexed reads or writes */
unsigned int maxBuf; /* maxBuf specifies the maximum */
/* message size the server can send or receive for non-raw SMBs */
unsigned int maxRw; /* maxRw specifies the maximum */
/* message size the server can send or receive for */
/* SMB_COM_WRITE_RAW or SMB_COM_READ_RAW. */
char sessid[4]; /* unique token id for this session */
/* (returned on Negotiate */
int capabilities; /* allow selective disabling of caps by smb sess */
__u16 timeZone;
char cryptKey[CIFS_CRYPTO_KEY_SIZE];
};
/*
......@@ -117,12 +132,11 @@ struct TCP_Server_Info {
* has changed. We also hang a list of sessions owned by this user off here.
*/
struct cifsUidInfo {
struct cifsUidInfo *next1; /* BB replace with list and atomicize */
struct cifsSesInfo *ses; /* list of sessions *//* BB replace with list and atomicize */
struct srSesInfo *sesSR; /* Save/Restore session list */
struct list_head userList;
struct list_head sessionList; /* SMB sessions for this user */
uid_t linux_uid;
char user[MAX_USERNAME_SIZE + 1]; /* ascii name of user */
/* BB eventually need ptr into PAM or WinBind info */
/* BB may need ptr or callback for PAM or WinBind info */
};
/*
......@@ -135,28 +149,16 @@ struct cifsSesInfo {
struct TCP_Server_Info *server; /* pointer to server info */
atomic_t inUse; /* # of CURRENT users of this ses */
enum statusEnum status;
int dialectIndex; /* the negotiated dialect index */
char secMode;
enum securityEnum secType;
unsigned int maxReq; /* Clients should submit no more */
/* than maxReq distinct unanswered SMBs to the server when using */
/* multiplexed reads or writes */
unsigned int maxBuf; /* maxBuf specifies the maximum */
/* message size the server can send or receive for non-raw SMBs */
unsigned int maxRw; /* maxRw specifies the maximum */
/* message size the server can send or receive for */
/* SMB_COM_WRITE_RAW or SMB_COM_READ_RAW. */
char sessid[4]; /* unique token id for this session */
/* (returned on Negotiate */
__u16 ipc_tid; /* special tid for connection to IPC share */
int capabilities;
__u16 timeZone;
char *serverOS; /* name of operating system underlying the server */
char *serverNOS; /* name of network operating system that the server is running */
char *serverDomain; /* security realm of server */
int Suid; /* needed for user level security */
int capabilities;
char serverName[SERVER_NAME_LEN_WITH_NULL * 2]; /* BB make bigger for tcp names - will ipv6 and sctp addresses fit here?? */
char userName[MAX_USERNAME_SIZE + 1]; /* BB remove and replace with list of cifsUidInfo structures */
char userName[MAX_USERNAME_SIZE + 1];
char domainName[MAX_USERNAME_SIZE + 1];
char password_with_pad[CIFS_ENCPWD_SIZE];
};
/*
......@@ -172,6 +174,7 @@ struct cifsTconInfo {
char *nativeFileSystem;
__u16 tid; /* The 2 byte transaction id */
__u16 Flags; /* optional support bits */
enum statusEnum tidStatus;
atomic_t useCount; /* how many mounts (explicit or implicit refer to this share */
FILE_SYSTEM_DEVICE_INFO fsDevInfo;
FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* note file system name may be truncated - but very unlikely */
......@@ -214,11 +217,11 @@ struct cifsInodeInfo {
struct list_head lockList;
/* BB add in lists for dirty pages - i.e. write caching info for oplock */
struct list_head openFileList;
__u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system etc. */
atomic_t inUse; /* num concurrent users (local openers cifs) of file */
__u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */
atomic_t inUse; /* num concurrent users (local openers cifs) of file*/
unsigned long time; /* jiffies of last update/check of inode */
int clientCanCache:1; /* oplocked. We need to extend cases beyond this i.e. what
if file read-only or if file locked? or if file on r/o vol? */
int clientCanCacheRead:1; /* read oplock */
int clientCanCacheAll:1; /* read and writebehind oplock */
struct inode vfs_inode;
};
......
......@@ -79,7 +79,7 @@
/*
* Starting value for maximum SMB size negotiation
*/
#define CIFS_MAX_MSGSIZE (4*1024)
#define CIFS_MAX_MSGSIZE (4*4096)
/*
* Size of encrypted user password in bytes
......
......@@ -36,8 +36,8 @@ extern int smb_send(struct socket *, struct smb_hdr *,
unsigned int /* length */ , struct sockaddr *);
extern unsigned int _GetXid(void);
extern void _FreeXid(unsigned int);
#define GetXid() (int)_GetXid(); cFYI(1,("\nCIFS VFS: in %s as Xid: %d with uid: %d",__FUNCTION__, xid,current->fsuid));
#define FreeXid(curr_xid) {_FreeXid(curr_xid); cFYI(1,("\nCIFS VFS: leaving %s (xid = %d) rc = %d\n",__FUNCTION__,curr_xid,rc));}
#define GetXid() (int)_GetXid(); cFYI(1,("CIFS VFS: in %s as Xid: %d with uid: %d",__FUNCTION__, xid,current->fsuid));
#define FreeXid(curr_xid) {_FreeXid(curr_xid); cFYI(1,("CIFS VFS: leaving %s (xid = %d) rc = %d",__FUNCTION__,curr_xid,rc));}
extern char *build_path_from_dentry(struct dentry *);
extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
extern void renew_parental_timestamps(struct dentry *direntry);
......@@ -72,28 +72,21 @@ extern int cifs_get_inode_info_unix(struct inode **pinode,
const unsigned char *search_path,
struct super_block *sb);
extern int CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses,
char cryptokey[CIFS_CRYPTO_KEY_SIZE]);
extern int setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
struct nls_table * nls_info);
extern int CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses);
extern int CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
char *user, char *domain,
char *session_key, char *ntlm_session_key,
const struct nls_table *);
extern int CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
char *user, char *domain,
char *SecurityBlob,
int SecurityBlobLength,
char *SecurityBlob,int SecurityBlobLength,
const struct nls_table *);
extern int CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
struct cifsSesInfo *ses,
char *domain,
char *ntlm_session_key,
int *ntlmv2_flag,
struct cifsSesInfo *ses, int *ntlmv2_flag,
const struct nls_table *);
extern int CIFSNTLMSSPAuthSessSetup(unsigned int xid,
struct cifsSesInfo *ses, char *user,
char *domain, char *ntlm_session_key,
char *lanman_session_key,
int ntlmv2_flag,
struct cifsSesInfo *ses, char *ntlm_session_key,
char *lanman_session_key,int ntlmv2_flag,
const struct nls_table *);
extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
......@@ -202,7 +195,7 @@ extern int CIFSSMBClose(const int xid, const struct cifsTconInfo *tcon,
extern int CIFSSMBRead(const int xid, const struct cifsTconInfo *tcon,
const int netfid, unsigned int count,
const __u64 lseek, unsigned int *nbytes, char *buf);
const __u64 lseek, unsigned int *nbytes, char **buf);
extern int CIFSSMBWrite(const int xid, const struct cifsTconInfo *tcon,
const int netfid, const unsigned int count,
const __u64 lseek, unsigned int *nbytes,
......
This diff is collapsed.
This diff is collapsed.
......@@ -54,7 +54,6 @@ build_path_from_dentry(struct dentry *direntry)
temp = temp->d_parent;
}
namelen += 1; /* allow for trailing null */
cFYI(1, ("Final namelength (in build_path): %d ", namelen)); /* BB remove */
full_path = kmalloc(namelen, GFP_KERNEL);
namelen--;
full_path[namelen] = 0; /* trailing null */
......@@ -66,13 +65,13 @@ build_path_from_dentry(struct dentry *direntry)
full_path[namelen] = '\\';
strncpy(full_path + namelen + 1, temp->d_name.name,
temp->d_name.len);
cFYI(1, (" name: %s ", full_path + namelen)); /* BB remove */
cFYI(0, (" name: %s ", full_path + namelen));
}
temp = temp->d_parent;
}
if (namelen != 0)
cERROR(1,
("\nWe did not end path lookup where we expected namelen is %d",
("We did not end path lookup where we expected namelen is %d",
namelen));
return full_path;
......@@ -111,7 +110,7 @@ build_wildcard_path_from_dentry(struct dentry *direntry)
}
if (namelen != 0)
cERROR(1,
("\nWe did not end path lookup where we expected namelen is %d",
("We did not end path lookup where we expected namelen is %d",
namelen));
return full_path;
......@@ -124,7 +123,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode)
{
int rc = -ENOENT;
int xid;
int oplock = FALSE; /* no need to oplock when we are not going to read from the file */
int oplock = REQ_OPLOCK;
__u16 fileHandle;
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon;
......@@ -144,7 +143,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode)
/* 0x20197 was used previously */ , CREATE_NOT_DIR,
&fileHandle, &oplock, cifs_sb->local_nls);
if (rc) {
cFYI(1, ("\ncifs_create returned 0x%x ", rc));
cFYI(1, ("cifs_create returned 0x%x ", rc));
} else {
if (pTcon->ses->capabilities & CAP_UNIX)
rc = cifs_get_inode_info_unix(&newinode, full_path,
......@@ -154,14 +153,17 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode)
inode->i_sb);
if (rc != 0) {
cFYI(1,
("\nCreate worked but get_inode_info failed with rc = %d ",
cFYI(1,("Create worked but get_inode_info failed with rc = %d",
rc));
/* close handle */
} else {
direntry->d_op = &cifs_dentry_ops;
d_instantiate(direntry, newinode);
}
/* BB check oplock state before deciding to call following */
/* if(*oplock)
save off handle in inode and dontdoclose */
CIFSSMBClose(xid, pTcon, fileHandle);
/* BB In the future chain close with the NTCreateX to narrow window */
......@@ -204,7 +206,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry)
cFYI(1, (" NULL inode in lookup"));
}
cFYI(1,
(" Full path: %s inode = 0x%p\n", full_path, direntry->d_inode));
(" Full path: %s inode = 0x%p", full_path, direntry->d_inode));
if (pTcon->ses->capabilities & CAP_UNIX)
rc = cifs_get_inode_info_unix(&newInode, full_path,
parent_dir_inode->i_sb);
......@@ -224,7 +226,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry)
d_add(direntry, NULL);
} else {
cERROR(1,
("Error 0x%x or (%d decimal) on cifs_get_inode_info in lookup\n",
("Error 0x%x or (%d decimal) on cifs_get_inode_info in lookup",
rc, rc));
/* BB special case check for Access Denied - watch security exposure of returning dir info implicitly via different rc if file exists or not but no access BB */
}
......@@ -251,7 +253,7 @@ cifs_dir_open(struct inode *inode, struct file *file)
full_path = build_wildcard_path_from_dentry(file->f_dentry);
cFYI(1, (" inode = 0x%p and full path is %s\n", inode, full_path));
cFYI(1, (" inode = 0x%p and full path is %s", inode, full_path));
if (full_path)
kfree(full_path);
......@@ -273,7 +275,7 @@ cifs_d_revalidate(struct dentry *direntry, int flags)
}
} else {
cFYI(1,
("In cifs_d_revalidate with no inode but name = %s and dentry 0x%p\n",
("In cifs_d_revalidate with no inode but name = %s and dentry 0x%p",
direntry->d_name.name, direntry));
}
......@@ -286,7 +288,7 @@ cifs_d_revalidate(struct dentry *direntry, int flags)
{
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;
} */
......
This diff is collapsed.
This diff is collapsed.
......@@ -88,7 +88,7 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
xid = GetXid();
full_path = build_path_from_dentry(direntry);
cFYI(1, ("\nFull path: %s inode = 0x%p\n", full_path, inode));
cFYI(1, ("Full path: %s inode = 0x%p", full_path, inode));
cifs_sb = CIFS_SB(inode->i_sb);
pTcon = cifs_sb->tcon;
......@@ -136,8 +136,8 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
pTcon = cifs_sb->tcon;
full_path = build_path_from_dentry(direntry);
cFYI(1, ("\nFull path: %s ", full_path));
cFYI(1, (" symname is %s\n", symname));
cFYI(1, ("Full path: %s ", full_path));
cFYI(1, ("symname is %s", symname));
/* BB what if DFS and this volume is on different share? BB */
if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)
......@@ -156,7 +156,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
if (rc != 0) {
cFYI(1,
("\nCreate symlink worked but get_inode_info failed with rc = %d ",
("Create symlink worked but get_inode_info failed with rc = %d ",
rc));
} else {
direntry->d_op = &cifs_dentry_ops;
......@@ -188,7 +188,7 @@ cifs_readlink(struct dentry *direntry, char *pBuffer, int buflen)
pTcon = cifs_sb->tcon;
full_path = build_path_from_dentry(direntry);
cFYI(1,
("\nFull path: %s inode = 0x%p pBuffer = 0x%p buflen = %d\n",
("Full path: %s inode = 0x%p pBuffer = 0x%p buflen = %d",
full_path, inode, pBuffer, buflen));
/* BB add read reparse point symlink code and Unix extensions symlink code here BB */
......
......@@ -81,7 +81,7 @@ void
sesInfoFree(struct cifsSesInfo *buf_to_free)
{
if (buf_to_free == NULL) {
cFYI(1, ("\nNull buffer passed to sesInfoFree"));
cFYI(1, ("Null buffer passed to sesInfoFree"));
return;
}
......@@ -122,7 +122,7 @@ void
tconInfoFree(struct cifsTconInfo *buf_to_free)
{
if (buf_to_free == NULL) {
cFYI(1, ("\nNull buffer passed to tconInfoFree"));
cFYI(1, ("Null buffer passed to tconInfoFree"));
return;
}
write_lock(&GlobalSMBSeslock);
......@@ -169,7 +169,7 @@ buf_release(void *buf_to_free)
{
if (buf_to_free == NULL) {
cFYI(1, ("\nNull buffer passed to buf_release"));
cFYI(1, ("Null buffer passed to buf_release"));
return;
}
kmem_cache_free(cifs_req_cachep, buf_to_free);
......@@ -225,7 +225,9 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
}
if (treeCon->Flags & SMB_SHARE_IS_IN_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;
}
......@@ -248,17 +250,17 @@ checkSMBhdr(struct smb_hdr *smb, __u16 mid)
if(smb->Command == SMB_COM_LOCKING_ANDX)
return 0;
else
cERROR(1, ("\n Rcvd Request not response "));
cERROR(1, ("Rcvd Request not response "));
}
} else { /* bad signature or mid */
if (*(unsigned int *) smb->Protocol != cpu_to_le32(0x424d53ff))
cERROR(1,
("\nBad protocol string signature header %x ",
("Bad protocol string signature header %x ",
*(unsigned int *) smb->Protocol));
if (mid != smb->Mid)
cERROR(1, ("\n Mids do not match \n"));
cERROR(1, ("Mids do not match"));
}
cERROR(1, ("\nCIFS: bad smb detected. The Mid=%d\n", smb->Mid));
cERROR(1, ("bad smb detected. The Mid=%d", smb->Mid));
return 1;
}
......@@ -266,13 +268,13 @@ int
checkSMB(struct smb_hdr *smb, __u16 mid, int length)
{
cFYI(0,
("\nEntering checkSMB with Length: %x, smb_buf_length: %x ",
("Entering checkSMB with Length: %x, smb_buf_length: %x ",
length, ntohl(smb->smb_buf_length)));
if ((length < 2 + sizeof (struct smb_hdr))
|| (4 + ntohl(smb->smb_buf_length) >
CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE)) {
if (length < 2 + sizeof (struct smb_hdr)) {
cERROR(1, ("\n Length less than 2 + sizeof smb_hdr "));
cERROR(1, ("Length less than 2 + sizeof smb_hdr "));
if ((length >= sizeof (struct smb_hdr) - 1)
&& (smb->Status.CifsError != 0))
return 0; /* some error cases do not return wct and bcc */
......@@ -281,9 +283,9 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
if (4 + ntohl(smb->smb_buf_length) >
CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE)
cERROR(1,
("\n smb_buf_length greater than CIFS_MAX_MSGSIZE ... "));
("smb_buf_length greater than CIFS_MAX_MSGSIZE ... "));
cERROR(1,
("CIFS: bad smb detected. Illegal length. The mid=%d\n",
("bad smb detected. Illegal length. The mid=%d",
smb->Mid));
return 1;
}
......@@ -295,9 +297,9 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
|| (4 + ntohl(smb->smb_buf_length) != length)) {
return 0;
} else {
cERROR(1, ("\nCIFS: smbCalcSize %x ", smbCalcSize(smb)));
cERROR(1, ("smbCalcSize %x ", smbCalcSize(smb)));
cERROR(1,
("CIFS: bad smb size detected. The Mid=%d\n", smb->Mid));
("bad smb size detected. The Mid=%d", smb->Mid));
return 1;
}
}
......@@ -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 list_head *tmp;
struct list_head *tmp1;
struct cifsTconInfo *tcon;
struct cifsFileInfo *netfile;
/* 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)
return FALSE;
if(pSMB->hdr.Flags & SMBFLG_RESPONSE)
......@@ -325,20 +329,29 @@ is_valid_oplock_break(struct smb_hdr *buf)
read_lock(&GlobalSMBSeslock);
list_for_each(tmp, &GlobalTreeConnectionList) {
tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
if (tcon->tid == buf->Tid)
if(tcon->ses->Suid == buf->Uid) {
if (tcon->tid == buf->Tid) {
list_for_each(tmp1,&tcon->openFileList){
netfile = list_entry(tmp1,struct cifsFileInfo,tlist);
if(pSMB->Fid == netfile->netfid) {
/* BB Add following logic:
2) look up inode from tcon->openFileList->file->f_dentry->d_inode
3) flush dirty pages and cached byte range locks and mark inode
4) depending on break type change to r/o caching or no caching
5) send oplock break response to server */
cifsinode->clientCanCacheAll = 0
5) inode->i_data.a_ops = &cifs_addr_ops_writethrough;
6) send oplock break response to server */
read_unlock(&GlobalSMBSeslock);
cFYI(1,("\nFound matching connection, process oplock break"));
cFYI(1,("Matching file id, processing oplock break"));
return TRUE;
}
}
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;
}
......@@ -355,7 +368,7 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length)
buffer = (unsigned char *) smb_buf;
for (i = 0, j = 0; i < smb_buf_length; i++, j++) {
if (i % 8 == 0) { /* we have reached the beginning of line */
printk("\n| ");
printk(KERN_DEBUG "| ");
j = 0;
}
printk("%0#4x ", buffer[i]);
......@@ -367,7 +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 */
debug_line[16] = 0;
printk(" | %s", debug_line);
printk(" | %s\n", debug_line);
}
}
for (; j < 8; j++) {
......@@ -375,6 +388,6 @@ dump_smb(struct smb_hdr *smb_buf, int smb_buf_length)
debug_line[2 * j] = ' ';
debug_line[1 + (2 * j)] = ' ';
}
printk(" | %s\n", debug_line);
printk( " | %s\n", debug_line);
return;
}
......@@ -753,12 +753,11 @@ cifs_print_status(__u32 status_code)
{
int idx = 0;
printk("\nStatus code returned: 0x%08x ", status_code);
while (nt_errs[idx].nt_errstr != NULL) {
if (((nt_errs[idx].nt_errcode) & 0xFFFFFF) ==
(status_code & 0xFFFFFF)) {
printk(nt_errs[idx].nt_errstr);
printk(KERN_NOTICE "Status code returned 0x%08x %s\n",
status_code,nt_errs[idx].nt_errstr);
}
idx++;
}
......@@ -815,11 +814,8 @@ map_smb_to_linux_error(struct smb_hdr *smb)
}
/* old style errors */
cFYI(1, (" !!Mapping smb error code %d ", smberrcode));
/* DOS class smb error codes - map DOS */
/* BB special case reconnect tid and reconnect uid here? */
/* DOS class smb error codes - map DOS */
if (smberrclass == ERRDOS) { /* one byte field no need to byte reverse */
for (i = 0;
i <
......@@ -849,10 +845,7 @@ map_smb_to_linux_error(struct smb_hdr *smb)
}
/* else ERRHRD class errors or junk - return EIO */
/* BB get smb->error_class and code lookup in table if ERR_STATUS is not
set in this frame else translate newer NT Status code - in both cases
change to equivalent posix error BB */
cFYI(1, (" to POSIX err %d !!", rc));
cFYI(1, (" !!Mapping smb error code %d to POSIX err %d !!", smberrcode,rc));
/* generic corrective action e.g. reconnect SMB session on ERRbaduid could be added */
......
......@@ -305,7 +305,7 @@ make_oem_passwd_hash(char data[516], const char *passwd,
if (new_pw_len > 512) {
cERROR(1,
("CIFS make_oem_passwd_hash: new password is too long.\n"));
("CIFS make_oem_passwd_hash: new password is too long."));
return FALSE;
}
......
......@@ -40,10 +40,9 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
/* BB add spinlock to protect midq for each session BB */
if (ses == NULL) {
cERROR(1, ("\nNull session passed in to AllocMidQEntry "));
cERROR(1, ("Null session passed in to AllocMidQEntry "));
return NULL;
}
temp = kmalloc(sizeof (struct mid_q_entry), GFP_KERNEL);
temp = (struct mid_q_entry *) kmem_cache_alloc(cifs_mid_cachep,
SLAB_KERNEL);
if (temp == NULL)
......@@ -53,21 +52,19 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
temp->mid = smb_buffer->Mid; /* always LE */
temp->pid = current->pid;
temp->command = smb_buffer->Command;
cFYI(1, ("\nFor smb_command %d", temp->command));
cFYI(1, ("For smb_command %d", temp->command));
do_gettimeofday(&temp->when_sent);
temp->ses = ses;
temp->tsk = current;
}
if (ses->status == CifsGood) {
if (ses->server->tcpStatus == CifsGood) {
write_lock(&GlobalMid_Lock);
list_add_tail(&temp->qhead, &ses->server->pending_mid_q);
atomic_inc(&midCount);
temp->midState = MID_REQUEST_ALLOCATED;
write_unlock(&GlobalMid_Lock);
} else { /* BB add reconnect code here BB */
cERROR(1,
("\nNeed to reconnect after session died to server\n"));
} else { /* could add more reconnect code here BB */
cERROR(1,("Need to reconnect after session died to server"));
if (temp)
kmem_cache_free(cifs_mid_cachep, temp);
return NULL;
......@@ -121,7 +118,7 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
sign_smb(smb_buffer); */ /* BB enable when signing tested more */
smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length);
cFYI(1, ("\nSending smb of length %d ", smb_buf_length));
cFYI(1, ("Sending smb of length %d ", smb_buf_length));
dump_smb(smb_buffer, smb_buf_length + 4);
temp_fs = get_fs(); /* we must turn off socket api parm checking */
......@@ -132,7 +129,7 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
if (rc < 0) {
cERROR(1,
("\nError %d sending data on socket to server.\n", rc));
("Error %d sending data on socket to server.", rc));
} else
rc = 0;
......@@ -154,7 +151,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
return -EIO; /* reconnect should be done, if possible, in AllocMidQEntry */
if (in_buf->smb_buf_length > CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE) {
cERROR(1,
("\nIllegal length, greater than maximum frame, %d ",
("Illegal length, greater than maximum frame, %d ",
in_buf->smb_buf_length));
DeleteMidQEntry(midQ);
return -EIO;
......@@ -163,27 +160,21 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
(struct sockaddr *) &(ses->server->sockAddr));
if (long_op > 1) /* writes past end of file can take a looooooong time */
if (long_op > 1) /* writes past end of file can take looooong time */
timeout = 300 * HZ;
else if (long_op == 1)
timeout = 60 * HZ;
else
timeout = 15 * HZ;
/* wait for 15 seconds or until woken up due to response arriving or due to
last connection to this server being unmounted */
/* timeout = interruptible_sleep_on_timeout(&ses->server->response_q,timeout); */
/* Replace above line with wait_event to get rid of sleep_on per lk guidelines */
/* wait for 15 seconds or until woken up due to response arriving or
due to last connection to this server being unmounted */
timeout = wait_event_interruptible_timeout(ses->server->response_q,
midQ->
midState & MID_RESPONSE_RECEIVED,
timeout);
cFYI(1,
(" with timeout %ld and Out_buf: %p midQ->resp_buf: %p ", timeout,
out_buf, midQ->resp_buf));
if (signal_pending(current)) {
cERROR(1, (KERN_ERR "\nCIFS: caught signal"));
cERROR(1, ("CIFS: caught signal"));
DeleteMidQEntry(midQ);
return -EINTR;
} else {
......@@ -198,11 +189,11 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
if (timeout == 0) {
cFYI(1,
("\nTimeout on receive. Assume response SMB is invalid.\n"));
("Timeout on receive. Assume response SMB is invalid."));
rc = -ETIMEDOUT;
} else if (receive_len > CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE) {
cERROR(1,
("\nFrame too large received. Length: %d Xid: %d\n",
("Frame too large received. Length: %d Xid: %d",
receive_len, xid));
rc = -EIO;
} else { /* rcvd frame is ok */
......@@ -215,7 +206,6 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
/* convert the length back to a form that we can use */
dump_smb(out_buf, 92);
out_buf->smb_buf_length =
be32_to_cpu(out_buf->smb_buf_length);
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