Commit cd73e609 authored by Steve French's avatar Steve French Committed by Steve French

Merge fixes from version 0.58 of cifs vfs

parent 2aa60962
......@@ -14,3 +14,9 @@ and others for their work on the Linux smbfs module over the years. Thanks to
the other members of the Storage Network Industry Association CIFS Technical
Workgroup for their work specifying this highly complex protocol and finally
thanks to the Samba team for their technical advice and encouragement.
Patch Contributors
------------------
Zwane Mwaikambo
Andi Kleen
Version 0.58
------------
Changed read and write to go through pagecache. Added additional address space operations.
Memory mapped operations now working.
Version 0.57
------------
Added writepage code for additional memory mapping support. Fixed leak in xids causing
the simultaneous operations counter (/proc/fs/cifs/SimultaneousOps) to increase on
every stat call. Additional formatting cleanup.
Version 0.56
------------
Fix bigendian bug in order of time conversion. Merge 2.5 to 2.4 version. Formatting cleanup.
Version 0.55
------------
Fixes from Zwane Mwaikambo for adding missing return code checking in a few places.
Also included a modified version of his fix to protect global list manipulation of
the smb session and tree connection and mid related global variables.
Version 0.54
------------
Fix problem with captive thread hanging around at unmount time. Adjust to 2.5.42-pre
......
......@@ -31,9 +31,6 @@ i) support for the Linux 2.5 kernel new feature get_xattr and set_xattr
j) finish off the mount helper, mount.cifs - (started)
k) support for memory mapped files only partially works until support for
MS_INVALIDATE implemented. readpage and writepage code not finished (started)
KNOWN BUGS (updated October 8nd, 2002)
====================================
1) symbolic links (Windows reparse points) are recognized but
......@@ -42,6 +39,8 @@ 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
=================
......
......@@ -115,7 +115,6 @@ cifs_put_super(struct super_block *sb)
struct cifs_sb_info *cifs_sb;
cFYI(1, ("In cifs_put_super\n"));
schedule_timeout(HZ*4);
cifs_sb = CIFS_SB(sb);
if(cifs_sb == NULL) {
cFYI(1,("\nEmpty cifs superblock info passed to unmount"));
......@@ -159,7 +158,7 @@ cifs_statfs(struct super_block *sb, struct statfs *buf)
__fsid_t f_fsid;
int f_namelen; */
/* BB get from info put in tcon struct at mount time with call to QFSAttrInfo */
FreeXid(xid);
return 0; /* always return success? what if volume is no longer available? */
}
......@@ -262,6 +261,7 @@ static struct file_system_type cifs_fs_type = {
struct inode_operations cifs_dir_inode_ops = {
.create = cifs_create,
.lookup = cifs_lookup,
.getattr = cifs_getattr,
.unlink = cifs_unlink,
.link = cifs_hardlink,
.mkdir = cifs_mkdir,
......@@ -275,6 +275,7 @@ struct inode_operations cifs_dir_inode_ops = {
struct inode_operations cifs_file_inode_ops = {
/* revalidate:cifs_revalidate, */
.setattr = cifs_setattr,
.getattr = cifs_getattr,
.rename = cifs_rename,
};
......@@ -287,12 +288,13 @@ struct inode_operations cifs_symlink_inode_ops = {
};
struct file_operations cifs_file_ops = {
.read = cifs_read,
.write = cifs_write,
.read = generic_file_read,
.write = generic_file_write,
.open = cifs_open,
.release = cifs_close,
.lock = cifs_lock,
.fsync = cifs_fsync,
.mmap = cifs_file_mmap,
};
struct file_operations cifs_dir_ops = {
......
......@@ -55,6 +55,7 @@ extern int cifs_rmdir(struct inode *, struct dentry *);
extern int cifs_rename(struct inode *, struct dentry *, struct inode *,
struct dentry *);
extern int cifs_revalidate(struct dentry *);
extern int cifs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
extern int cifs_setattr(struct dentry *, struct iattr *);
extern struct inode_operations cifs_file_inode_ops;
......@@ -73,7 +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_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);
extern int cifs_readdir(struct file *file, void *direntry, filldir_t filldir);
......
......@@ -201,6 +201,7 @@ struct cifsFileInfo {
__u16 netfid; /* file id from remote */
/* BB add lock scope info here if needed */ ;
/* lock scope id (0 if none) */
struct file * pfile; /* needed for writepage */
int endOfSearch:1; /* we have reached end of search */
int closePend:1; /* file is marked to close */
};
......@@ -244,7 +245,7 @@ struct mid_q_entry {
struct cifsSesInfo *ses; /* smb was sent to this server */
struct task_struct *tsk; /* task waiting for response */
struct smb_hdr *resp_buf; /* response buffer */
int midState; /* wish this could be an enum but can not pass that to wait_event */
int midState; /* wish this were enum but can not pass to wait_event */
};
#define MID_FREE 0
......
......@@ -497,16 +497,20 @@ CIFSSMBRead(const int xid, const struct cifsTconInfo *tcon,
} else {
pSMBr->DataLength = le16_to_cpu(pSMBr->DataLength);
*nbytes = pSMBr->DataLength;
/* BB check that DataLength would not go beyond end of SMB BB */
if (pSMBr->DataLength > CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE) {
/*check that DataLength would not go beyond end of SMB */
if ((pSMBr->DataLength > CIFS_MAX_MSGSIZE)
|| (pSMBr->DataLength > count)) {
rc = -EIO;
*nbytes = 0;
} else {
pReadData =
(char *) (&pSMBr->hdr.Protocol) +
le16_to_cpu(pSMBr->DataOffset);
if(copy_to_user(buf, pReadData, pSMBr->DataLength))
/* if(rc = copy_to_user(buf, pReadData, pSMBr->DataLength)) {
cERROR(1,("\nFaulting on read rc = %d",rc));
rc = -EFAULT;
}*/ /* can not use copy_to_user when using page cache*/
memcpy(buf,pReadData,pSMBr->DataLength);
}
}
......@@ -546,12 +550,7 @@ CIFSSMBWrite(const int xid, const struct cifsTconInfo *tcon,
pSMB->DataOffset =
cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4);
if(copy_from_user(pSMB->Data, buf, pSMB->DataLengthLow)) {
buf_release(pSMB);
return -EFAULT;
}
memcpy(pSMB->Data,buf,pSMB->DataLengthLow);
pSMB->ByteCount += pSMB->DataLengthLow + 1 /* pad */ ;
pSMB->DataLengthLow = cpu_to_le16(pSMB->DataLengthLow);
......
......@@ -821,6 +821,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
"",
cifs_sb->
local_nls);
FreeXid(xid);
return -ENODEV;
} else {
rc = CIFSTCon(xid, pSesInfo,
......@@ -1081,7 +1082,6 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, char *user,
kcalloc(2, GFP_KERNEL);
}
} else { /* ASCII */
len = strnlen(bcc_ptr, 1024);
if (((long) bcc_ptr + len) - (long)
pByteArea(smb_buffer_response)
......@@ -1661,7 +1661,6 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
kcalloc(2, GFP_KERNEL);
}
} else { /* ASCII */
len = strnlen(bcc_ptr, 1024);
if (((long) bcc_ptr + len) - (long)
pByteArea(smb_buffer_response)
......@@ -2048,7 +2047,6 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
ses->serverNOS = kcalloc(2, GFP_KERNEL);
}
} else { /* ASCII */
len = strnlen(bcc_ptr, 1024);
if (((long) bcc_ptr + len) -
(long) pByteArea(smb_buffer_response)
......
......@@ -35,6 +35,8 @@
#include "cifs_debug.h"
#include "cifs_fs_sb.h"
int
cifs_open(struct inode *inode, struct file *file)
{
......@@ -107,25 +109,24 @@ cifs_open(struct inode *inode, struct file *file)
pCifsFile = (struct cifsFileInfo *) file->private_data;
pCifsFile->netfid = netfid;
pCifsFile->pid = current->pid;
pCifsFile->pfile = file; /* needed for writepage */
list_add(&pCifsFile->tlist,&pTcon->openFileList);
pCifsInode = CIFS_I(file->f_dentry->d_inode);
list_add(&pCifsFile->flist,&pCifsInode->openFileList);
if(file->f_flags & O_CREAT) {
/* time to set mode which we can not
set earlier due to problems creating new read-only files */
/* time to set mode which we can not set earlier due
to problems creating new read-only files */
if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)
CIFSSMBUnixSetPerms(xid, pTcon, full_path, inode->i_mode,
0xFFFFFFFFFFFFFFFF,
0xFFFFFFFFFFFFFFFF,
cifs_sb->local_nls);
else {/* BB to be implemented via Windows secrty descriptors*/
else {/* BB implement via Windows security descriptors */
/* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/
/* in the meantime we could set the r/o dos attribute
when perms are e.g.:
/* in the meantime could set r/o dos attribute when perms are eg:
mode & 0222 == 0 */
}
}
}
}
......@@ -162,7 +163,6 @@ cifs_close(struct inode *inode, struct file *file)
FreeXid(xid);
return rc;
}
int
......@@ -344,20 +344,24 @@ cifs_write(struct file * file, const char *write_data,
file->f_dentry->d_inode->i_size = *poffset;
}
mark_inode_dirty_sync(file->f_dentry->d_inode);
FreeXid(xid);
return total_written;
}
static int
cifs_writepage(struct page *page)
cifs_partialpagewrite(struct page *page,unsigned from, unsigned to)
{
struct address_space *mapping = page->mapping;
loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
char * write_data = kmap(page);
int rc = -EFAULT;
int bytes_written = 0;
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon;
int xid;
struct inode *inode = page->mapping->host;
loff_t *poffset = NULL;
struct cifsInodeInfo *cifsInode;
struct cifsFileInfo *open_file = NULL;
int xid;
xid = GetXid();
......@@ -373,43 +377,82 @@ cifs_writepage(struct page *page)
if (!mapping) {
FreeXid(xid);
return -EFAULT;
} else if(!mapping->host) {
FreeXid(xid);
return -EFAULT;
}
/* BB fix and add missing call to cifs_writepage_sync here */
inode->i_ctime = inode->i_mtime = CURRENT_TIME; /* BB is this right? */
if ((bytes_written > 0) && (poffset)) {
if (*poffset > inode->i_size)
inode->i_size = *poffset;
if((to > PAGE_CACHE_SIZE) || (from > to))
return -EIO;
offset += (loff_t)from;
write_data += from;
cifsInode = CIFS_I(mapping->host);
if(!list_empty(&(cifsInode->openFileList))) {
open_file = list_entry(cifsInode->openFileList.next,
struct cifsFileInfo, flist);
/* We could check if file is open for writing first */
if(open_file->pfile)
bytes_written = cifs_write(open_file->pfile, write_data,
to-from, &offset);
/* Does mm or vfs already set times? */
inode->i_atime = inode->i_mtime = CURRENT_TIME;
if ((bytes_written > 0) && (offset)) {
rc = 0;
if (offset > inode->i_size)
inode->i_size = offset;
} else if(bytes_written < 0) {
rc = bytes_written;
}
mark_inode_dirty_sync(inode);
} else {
cFYI(1,("\nNo open files to get file handle from"));
rc = -EIO;
}
FreeXid(xid);
return rc;
}
static int
cifs_prepare_write(struct file *file, struct page *page, unsigned offset,
unsigned to)
cifs_writepage(struct page* page)
{
return 0; /* eventually add code to flush any incompatible requests */
int rc = -EFAULT;
int xid;
xid = GetXid();
page_cache_get(page);
rc = cifs_partialpagewrite(page,0,PAGE_CACHE_SIZE);
/* insert call to SetPageToUpdate like function here? */
unlock_page(page);
page_cache_release(page);
FreeXid(xid);
return rc;
}
static int
cifs_commit_write(struct file *file, struct page *page, unsigned offset,
unsigned to)
{
long rc = -EFAULT;
lock_kernel();
/* status = cifs_updatepage(file, page, offset, to-offset); */
int xid,rc;
xid = GetXid();
/* BB add - do we really need to lock the kernel here for so long ? */
if(offset > to)
return -EIO;
rc = cifs_partialpagewrite(page,offset,to);
unlock_kernel();
FreeXid(xid);
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
cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
{
......@@ -489,13 +532,30 @@ cifs_read(struct file * file, char *read_data, size_t read_size,
return total_read;
}
int
cifs_file_mmap(struct file * file, struct vm_area_struct * vma)
{
struct dentry * dentry = file->f_dentry;
int rc, xid;
xid = GetXid();
rc = cifs_revalidate(dentry);
if (rc) {
cFYI(1,("Validation prior to mmap failed, error=%d\n", rc));
FreeXid(xid);
return rc;
}
rc = generic_file_mmap(file, vma);
FreeXid(xid);
return rc;
}
static int
cifs_readpage_sync(struct file *file, struct page *page)
cifs_readpage(struct file *file, struct page *page)
{
unsigned int count = PAGE_CACHE_SIZE;
loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
char * read_data;
int rc = -EACCES;
int bytes_read = 0;
int total_read = 0;
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon;
int xid;
......@@ -508,26 +568,33 @@ cifs_readpage_sync(struct file *file, struct page *page)
FreeXid(xid);
return -EBADF;
}
page_cache_get(page);
read_data = kmap(page);
/* for reads over a certain size we could initiate async read ahead */
/* BB finish adding missing here */
rc = cifs_read(file, read_data, PAGE_CACHE_SIZE, &offset);
cFYI(1,
("\nCount is %d total read %d bytes read %d ", count, total_read,
bytes_read));
if (rc < 0)
goto io_error;
else {
cFYI(1,("\nBytes read %d ",rc));
}
FreeXid(xid);
return rc;
}
file->f_dentry->d_inode->i_atime = CURRENT_TIME;
static int
cifs_readpage(struct file *file, struct page *page)
{
int rc;
if(PAGE_CACHE_SIZE > rc) {
memset(read_data+rc, 0, PAGE_CACHE_SIZE - rc);
}
flush_dcache_page(page);
SetPageUptodate(page);
rc = 0;
io_error:
kunmap(page);
unlock_page(page);
page_cache_get(page);
rc = cifs_readpage_sync(file, page);
/* for reads over a certain size we could initiate async read ahead */
page_cache_release(page);
FreeXid(xid);
return rc;
}
......@@ -546,11 +613,11 @@ fill_in_inode(struct inode *tmp_inode,
/* Linux can not store file creation time unfortunately so we ignore it */
tmp_inode->i_atime =
le64_to_cpu(cifs_NTtimeToUnix(pfindData->LastAccessTime));
cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime));
tmp_inode->i_mtime =
le64_to_cpu(cifs_NTtimeToUnix(pfindData->LastWriteTime));
cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
tmp_inode->i_ctime =
le64_to_cpu(cifs_NTtimeToUnix(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 */
tmp_inode->i_mode = S_IALLUGO & ~(S_ISUID | S_IXGRP); /* 2767 perms - indicate mandatory locking */
cFYI(0,
......@@ -605,16 +672,12 @@ unix_fill_in_inode(struct inode *tmp_inode,
atomic_inc(&cifsInfo->inUse);
tmp_inode->i_atime =
le64_to_cpu(cifs_NTtimeToUnix(pfindData->LastAccessTime));
cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime));
tmp_inode->i_mtime =
le64_to_cpu(cifs_NTtimeToUnix(pfindData->LastModificationTime));
cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastModificationTime));
tmp_inode->i_ctime =
le64_to_cpu(cifs_NTtimeToUnix(pfindData->LastStatusChange));
cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastStatusChange));
/* tmp_inode->i_mtime =
cifs_NTtimeToUnix(pfindData->LastModificationTime);
tmp_inode->i_ctime =
cifs_NTtimeToUnix(pfindData->LastStatusChange); */
tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions);
pfindData->Type = le32_to_cpu(pfindData->Type);
if (pfindData->Type == UNIX_FILE) {
......@@ -1013,8 +1076,17 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
struct address_space_operations cifs_addr_ops = {
.readpage = cifs_readpage,
.sync_page = cifs_sync_page,
.writepage = cifs_writepage,
.prepare_write = cifs_prepare_write,
.commit_write = cifs_commit_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_ops2 = {
.readpage = cifs_readpage,
.writepage = cifs_writepage,
.prepare_write = cifs_prepare_write,
.commit_write = cifs_commit_write,
.sync_page = cifs_sync_page,
};
......@@ -99,12 +99,12 @@ cifs_get_inode_info_unix(struct inode **pinode,
atomic_inc(&cifsInfo->inUse); /* inc on every refresh of inode */
inode->i_atime =
le64_to_cpu(cifs_NTtimeToUnix(findData.LastAccessTime));
cifs_NTtimeToUnix(le64_to_cpu(findData.LastAccessTime));
inode->i_mtime =
le64_to_cpu(cifs_NTtimeToUnix
cifs_NTtimeToUnix(le64_to_cpu
(findData.LastModificationTime));
inode->i_ctime =
le64_to_cpu(cifs_NTtimeToUnix(findData.LastStatusChange));
cifs_NTtimeToUnix(le64_to_cpu(findData.LastStatusChange));
inode->i_mode = le64_to_cpu(findData.Permissions);
findData.Type = le32_to_cpu(findData.Type);
if (findData.Type == UNIX_FILE) {
......@@ -140,6 +140,7 @@ cifs_get_inode_info_unix(struct inode **pinode,
cFYI(1, (" File inode "));
inode->i_op = &cifs_file_inode_ops;
inode->i_fop = &cifs_file_ops;
inode->i_data.a_ops = &cifs_addr_ops;
} else if (S_ISDIR(inode->i_mode)) {
cFYI(1, (" Directory inode"));
inode->i_op = &cifs_dir_inode_ops;
......@@ -265,6 +266,7 @@ cifs_get_inode_info(struct inode **pinode,
cFYI(1, (" File inode "));
inode->i_op = &cifs_file_inode_ops;
inode->i_fop = &cifs_file_ops;
inode->i_data.a_ops = &cifs_addr_ops;
} else if (S_ISDIR(inode->i_mode)) {
cFYI(1, (" Directory inode "));
inode->i_op = &cifs_dir_inode_ops;
......@@ -441,9 +443,11 @@ cifs_rename(struct inode *source_inode, struct dentry *source_direntry,
cifs_sb_source = CIFS_SB(source_inode->i_sb);
pTcon = cifs_sb_source->tcon;
if (pTcon != cifs_sb_target->tcon)
if (pTcon != cifs_sb_target->tcon) {
return -EXDEV; /* BB actually could be allowed if same server, but
different share. Might eventually add support for this */
FreeXid(xid);
}
fromName = build_path_from_dentry(source_direntry);
toName = build_path_from_dentry(target_direntry);
......@@ -455,6 +459,7 @@ cifs_rename(struct inode *source_inode, struct dentry *source_direntry,
if (toName)
kfree(toName);
FreeXid(xid);
return rc;
}
......@@ -479,7 +484,7 @@ cifs_revalidate(struct dentry *direntry)
direntry->d_time, jiffies));
cifsInode = CIFS_I(direntry->d_inode);
/* BB add check - do not need to revalidate oplocked files */
if ((time_before(jiffies, cifsInode->time + HZ))
&& (direntry->d_inode->i_nlink == 1)) {
cFYI(1, (" Do not need to revalidate "));
......@@ -505,6 +510,14 @@ cifs_revalidate(struct dentry *direntry)
return rc;
}
int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
{
int err = cifs_revalidate(dentry);
if (!err)
generic_fillattr(dentry->d_inode, stat);
return err;
}
void
cifs_truncate_file(struct inode *inode)
{ /* BB remove - may not need this function after all BB */
......@@ -540,9 +553,7 @@ cifs_truncate_file(struct inode *inode)
if(!list_empty(&(cifsInode->openFileList))) {
open_file = list_entry(cifsInode->openFileList.next,
struct cifsFileInfo, flist);
/* We could check if file is open for writing first and
also we could also override the smb pid with the pid
of the file opener when sending the CIFS request */
/* We could check if file is open for writing first */
rc = CIFSSMBSetFileSize(xid, pTcon, inode->i_size,
open_file->netfid,open_file->pid,FALSE);
} else {
......@@ -684,5 +695,4 @@ cifs_delete_inode(struct inode *inode)
cFYI(1, ("In cifs_delete_inode, inode = 0x%p\n", inode));
/* may have to add back in when safe distributed caching of
directories via e.g. FindNotify added */
}
......@@ -745,7 +745,28 @@ const static struct {
ERRDOS, ERRnoaccess, 0xc0000290}, {
ERRDOS, ERRbadfunc, 0xc000029c},};
void
/*****************************************************************************
Print an error message from the status code
*****************************************************************************/
static void
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);
}
idx++;
}
return;
}
static void
ntstatus_to_dos(__u32 ntstatus, __u8 * eclass, __u16 * ecode)
{
int i;
......@@ -781,9 +802,9 @@ map_smb_to_linux_error(struct smb_hdr *smb)
if (smb->Flags2 & SMBFLG2_ERR_STATUS) {
/* translate the newer STATUS codes to old style errors and then to POSIX errors */
cFYI(1,
(" !!Mapping cifs error code %d ", smb->Status.CifsError));
smb->Status.CifsError = le32_to_cpu(smb->Status.CifsError);
if(cifsFYI)
cifs_print_status(smb->Status.CifsError);
ntstatus_to_dos(smb->Status.CifsError, &smberrclass,
&smberrcode);
} else {
......
......@@ -20,14 +20,9 @@
*/
/* NT error codes - see nterr.h */
#include "nterr.h"
#include <linux/types.h>
#include <linux/fs.h>
struct nt_err_code_struct {
char *nt_errstr;
__u32 nt_errcode;
};
#include "nterr.h"
const struct nt_err_code_struct nt_errs[] = {
{"NT_STATUS_OK", NT_STATUS_OK},
......@@ -690,23 +685,3 @@ const struct nt_err_code_struct nt_errs[] = {
{"STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED},
{NULL, 0}
};
/*****************************************************************************
Print an error message from the status code
*****************************************************************************/
/* void
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);
}
idx++;
}
return;
} */
......@@ -22,9 +22,18 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _NTERR_H
#define _NTERR_H
struct nt_err_code_struct {
char *nt_errstr;
__u32 nt_errcode;
};
extern const struct nt_err_code_struct nt_errs[];
/* Win32 Status codes. */
#define STATUS_BUFFER_OVERFLOW 0x80000005
......
......@@ -208,16 +208,23 @@ ntv2_owf_gen(const unsigned char owf[16], const char *user_n,
const char *domain_n, unsigned char kr_buf[16],
const struct nls_table *nls_codepage)
{
wchar_t user_u[1024];
wchar_t dom_u[1024];
wchar_t * user_u;
wchar_t * dom_u;
int user_l, domain_l;
struct HMACMD5Context ctx;
/* might as well do one alloc to hold both (user_u and dom_u) */
user_u = kmalloc(2048 * sizeof(wchar_t),GFP_KERNEL);
if(user_u == NULL)
return;
dom_u = user_u + 1024;
/* push_ucs2(NULL, user_u, user_n, (user_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER);
push_ucs2(NULL, dom_u, domain_n, (domain_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); */
/* do not think it is supposed to be uppercased */
int user_l = cifs_strtoUCS(user_u, user_n, 511, nls_codepage);
int domain_l = cifs_strtoUCS(dom_u, domain_n, 511, nls_codepage);
user_l = cifs_strtoUCS(user_u, user_n, 511, nls_codepage);
domain_l = cifs_strtoUCS(dom_u, domain_n, 511, nls_codepage);
user_l++; /* trailing null */
domain_l++;
......@@ -234,6 +241,7 @@ ntv2_owf_gen(const unsigned char owf[16], const char *user_n,
dump_data(100, owf, 16);
dump_data(100, kr_buf, 16);
#endif
kfree(user_u);
}
/* Does the des encryption from the NT or LM MD4 hash. */
......
......@@ -163,8 +163,6 @@ 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));
cFYI(1, ("\ncifs smb_send rc %d", rc)); /* BB remove */
/* BB add code to wait for response and copy to out_buf */
if (long_op > 1) /* writes past end of file can take a looooooong time */
timeout = 300 * HZ;
else if (long_op == 1)
......@@ -179,9 +177,8 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
timeout = wait_event_interruptible_timeout(ses->server->response_q,
midQ->
midState &
MID_RESPONSE_RECEIVED,
15 * HZ);
midState & MID_RESPONSE_RECEIVED,
timeout);
cFYI(1,
(" with timeout %ld and Out_buf: %p midQ->resp_buf: %p ", timeout,
out_buf, midQ->resp_buf));
......@@ -244,6 +241,8 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
rc = -EIO;
}
DeleteMidQEntry(midQ); /* BB what if process is killed ? - BB add background daemon to clean up Mid entries from killed processes BB test killing process with active mid */
DeleteMidQEntry(midQ); /* BB what if process is killed?
- BB add background daemon to clean up Mid entries from
killed processes & test killing process with active mid */
return rc;
}
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