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 ...@@ -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 the other members of the Storage Network Industry Association CIFS Technical
Workgroup for their work specifying this highly complex protocol and finally Workgroup for their work specifying this highly complex protocol and finally
thanks to the Samba team for their technical advice and encouragement. 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 Version 0.54
------------ ------------
Fix problem with captive thread hanging around at unmount time. Adjust to 2.5.42-pre 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 ...@@ -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) 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) KNOWN BUGS (updated October 8nd, 2002)
==================================== ====================================
1) symbolic links (Windows reparse points) are recognized but 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 ...@@ -42,6 +39,8 @@ 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. 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
================= =================
......
...@@ -115,7 +115,6 @@ cifs_put_super(struct super_block *sb) ...@@ -115,7 +115,6 @@ cifs_put_super(struct super_block *sb)
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\n"));
schedule_timeout(HZ*4);
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,("\nEmpty cifs superblock info passed to unmount"));
...@@ -159,7 +158,7 @@ cifs_statfs(struct super_block *sb, struct statfs *buf) ...@@ -159,7 +158,7 @@ cifs_statfs(struct super_block *sb, struct statfs *buf)
__fsid_t f_fsid; __fsid_t f_fsid;
int f_namelen; */ int f_namelen; */
/* BB get from info put in tcon struct at mount time with call to QFSAttrInfo */ /* 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? */ return 0; /* always return success? what if volume is no longer available? */
} }
...@@ -180,7 +179,7 @@ cifs_alloc_inode(struct super_block *sb) ...@@ -180,7 +179,7 @@ cifs_alloc_inode(struct super_block *sb)
atomic_set(&cifs_inode->inUse, 0); atomic_set(&cifs_inode->inUse, 0);
cifs_inode->time = 0; cifs_inode->time = 0;
cifs_inode->clientCanCache = 0; cifs_inode->clientCanCache = 0;
INIT_LIST_HEAD(&cifs_inode->openFileList); INIT_LIST_HEAD(&cifs_inode->openFileList);
return &cifs_inode->vfs_inode; return &cifs_inode->vfs_inode;
} }
...@@ -262,6 +261,7 @@ static struct file_system_type cifs_fs_type = { ...@@ -262,6 +261,7 @@ static struct file_system_type cifs_fs_type = {
struct inode_operations cifs_dir_inode_ops = { struct inode_operations cifs_dir_inode_ops = {
.create = cifs_create, .create = cifs_create,
.lookup = cifs_lookup, .lookup = cifs_lookup,
.getattr = cifs_getattr,
.unlink = cifs_unlink, .unlink = cifs_unlink,
.link = cifs_hardlink, .link = cifs_hardlink,
.mkdir = cifs_mkdir, .mkdir = cifs_mkdir,
...@@ -275,6 +275,7 @@ struct inode_operations cifs_dir_inode_ops = { ...@@ -275,6 +275,7 @@ 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,
.rename = cifs_rename, .rename = cifs_rename,
}; };
...@@ -282,17 +283,18 @@ struct inode_operations cifs_symlink_inode_ops = { ...@@ -282,17 +283,18 @@ struct inode_operations cifs_symlink_inode_ops = {
.readlink = cifs_readlink, .readlink = cifs_readlink,
.follow_link = cifs_follow_link, .follow_link = cifs_follow_link,
/* 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 */
}; };
struct file_operations cifs_file_ops = { struct file_operations cifs_file_ops = {
.read = cifs_read, .read = generic_file_read,
.write = cifs_write, .write = generic_file_write,
.open = cifs_open, .open = cifs_open,
.release = cifs_close, .release = cifs_close,
.lock = cifs_lock, .lock = cifs_lock,
.fsync = cifs_fsync, .fsync = cifs_fsync,
.mmap = cifs_file_mmap,
}; };
struct file_operations cifs_dir_ops = { struct file_operations cifs_dir_ops = {
...@@ -426,7 +428,7 @@ exit_cifs(void) ...@@ -426,7 +428,7 @@ exit_cifs(void)
#if CONFIG_PROC_FS #if CONFIG_PROC_FS
cifs_proc_clean(); cifs_proc_clean();
#endif #endif
unregister_filesystem(&cifs_fs_type); unregister_filesystem(&cifs_fs_type);
cifs_destroy_inodecache(); cifs_destroy_inodecache();
cifs_destroy_mids(); cifs_destroy_mids();
cifs_destroy_request_bufs(); cifs_destroy_request_bufs();
......
...@@ -55,6 +55,7 @@ extern int cifs_rmdir(struct inode *, struct dentry *); ...@@ -55,6 +55,7 @@ extern int cifs_rmdir(struct inode *, struct dentry *);
extern int cifs_rename(struct inode *, struct dentry *, struct inode *, extern int cifs_rename(struct inode *, struct dentry *, struct inode *,
struct dentry *); struct dentry *);
extern int cifs_revalidate(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 int cifs_setattr(struct dentry *, struct iattr *);
extern struct inode_operations cifs_file_inode_ops; extern struct inode_operations cifs_file_inode_ops;
...@@ -73,7 +74,7 @@ extern ssize_t cifs_write(struct file *file, const char *write_data, ...@@ -73,7 +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_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);
extern int cifs_readdir(struct file *file, void *direntry, filldir_t filldir); extern int cifs_readdir(struct file *file, void *direntry, filldir_t filldir);
......
...@@ -165,7 +165,7 @@ struct cifsSesInfo { ...@@ -165,7 +165,7 @@ struct cifsSesInfo {
*/ */
struct cifsTconInfo { struct cifsTconInfo {
struct list_head cifsConnectionList; struct list_head cifsConnectionList;
struct list_head openFileList; struct list_head openFileList;
struct semaphore tconSem; struct semaphore tconSem;
struct cifsSesInfo *ses; /* pointer to session associated with */ struct cifsSesInfo *ses; /* pointer to session associated with */
char treeName[MAX_TREE_SIZE + 1]; /* The ascii or unicode name of this resource depending on the ses->capabilities *//* BB fill in this field */ char treeName[MAX_TREE_SIZE + 1]; /* The ascii or unicode name of this resource depending on the ses->capabilities *//* BB fill in this field */
...@@ -201,6 +201,7 @@ struct cifsFileInfo { ...@@ -201,6 +201,7 @@ struct cifsFileInfo {
__u16 netfid; /* file id from remote */ __u16 netfid; /* file id from remote */
/* BB add lock scope info here if needed */ ; /* BB add lock scope info here if needed */ ;
/* lock scope id (0 if none) */ /* lock scope id (0 if none) */
struct file * pfile; /* needed for writepage */
int endOfSearch:1; /* we have reached end of search */ int endOfSearch:1; /* we have reached end of search */
int closePend:1; /* file is marked to close */ int closePend:1; /* file is marked to close */
}; };
...@@ -212,12 +213,12 @@ struct cifsFileInfo { ...@@ -212,12 +213,12 @@ struct cifsFileInfo {
struct cifsInodeInfo { 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 etc. */
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 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? */ if file read-only or if file locked? or if file on r/o vol? */
struct inode vfs_inode; struct inode vfs_inode;
}; };
...@@ -244,7 +245,7 @@ struct mid_q_entry { ...@@ -244,7 +245,7 @@ struct mid_q_entry {
struct cifsSesInfo *ses; /* smb was sent to this server */ struct cifsSesInfo *ses; /* smb was sent to this server */
struct task_struct *tsk; /* task waiting for response */ struct task_struct *tsk; /* task waiting for response */
struct smb_hdr *resp_buf; /* response buffer */ 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 #define MID_FREE 0
...@@ -304,7 +305,7 @@ GLOBAL_EXTERN unsigned int GlobalCurrentXid; /* protected by GlobalMid_Sem */ ...@@ -304,7 +305,7 @@ GLOBAL_EXTERN unsigned int GlobalCurrentXid; /* protected by GlobalMid_Sem */
GLOBAL_EXTERN unsigned int GlobalTotalActiveXid; /* prot by GlobalMid_Sem */ GLOBAL_EXTERN unsigned int GlobalTotalActiveXid; /* prot by GlobalMid_Sem */
GLOBAL_EXTERN unsigned int GlobalMaxActiveXid; /* prot by GlobalMid_Sem */ GLOBAL_EXTERN unsigned int GlobalMaxActiveXid; /* prot by GlobalMid_Sem */
GLOBAL_EXTERN rwlock_t GlobalMid_Lock; /* protects above and list operations */ GLOBAL_EXTERN rwlock_t GlobalMid_Lock; /* protects above and list operations */
/* on midQ entries */ /* on midQ entries */
GLOBAL_EXTERN char Local_System_Name[15]; GLOBAL_EXTERN char Local_System_Name[15];
/* /*
...@@ -319,12 +320,12 @@ GLOBAL_EXTERN atomic_t midCount; ...@@ -319,12 +320,12 @@ GLOBAL_EXTERN atomic_t midCount;
/* Misc globals */ /* Misc globals */
GLOBAL_EXTERN unsigned int multiuser_mount; /* if enabled allows new sessions GLOBAL_EXTERN unsigned int multiuser_mount; /* if enabled allows new sessions
to be established on existing mount if we to be established on existing mount if we
have the uid/password or Kerberos credential have the uid/password or Kerberos credential
or equivalent for current user */ or equivalent for current user */
GLOBAL_EXTERN unsigned int oplockEnabled; GLOBAL_EXTERN unsigned int oplockEnabled;
GLOBAL_EXTERN unsigned int extended_security; /* if on, session setup sent GLOBAL_EXTERN unsigned int extended_security; /* if on, session setup sent
with more secure ntlmssp2 challenge/resp */ with more secure ntlmssp2 challenge/resp */
GLOBAL_EXTERN unsigned int ntlmv2_support; /* better optional password hash */ GLOBAL_EXTERN unsigned int ntlmv2_support; /* better optional password hash */
GLOBAL_EXTERN unsigned int sign_CIFS_PDUs; /* enable smb packet signing */ GLOBAL_EXTERN unsigned int sign_CIFS_PDUs; /* enable smb packet signing */
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
extern struct smb_hdr *buf_get(void); extern struct smb_hdr *buf_get(void);
extern void buf_release(void *); extern void buf_release(void *);
extern int smb_send(struct socket *, struct smb_hdr *, 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,("\nCIFS VFS: in %s as Xid: %d with uid: %d",__FUNCTION__, xid,current->fsuid));
...@@ -41,70 +41,70 @@ extern char *build_wildcard_path_from_dentry(struct dentry *direntry); ...@@ -41,70 +41,70 @@ 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);
extern void *kcalloc(size_t mem, int type); extern void *kcalloc(size_t mem, int type);
extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *, extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *,
struct smb_hdr * /* input */ , struct smb_hdr * /* input */ ,
struct smb_hdr * /* out */ , struct smb_hdr * /* out */ ,
int * /* bytes returned */ , const int long_op); int * /* bytes returned */ , const int long_op);
extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid); extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid);
extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length); extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length);
extern int is_valid_oplock_break(struct smb_hdr *smb); extern int is_valid_oplock_break(struct smb_hdr *smb);
extern int smbCalcSize(struct smb_hdr *ptr); extern int smbCalcSize(struct smb_hdr *ptr);
extern int decode_negTokenInit(unsigned char *security_blob, int length, extern int decode_negTokenInit(unsigned char *security_blob, int length,
enum securityEnum *secType); enum securityEnum *secType);
extern int map_smb_to_linux_error(struct smb_hdr *smb); extern int map_smb_to_linux_error(struct smb_hdr *smb);
extern void header_assemble(struct smb_hdr *, char /* command */ , extern void header_assemble(struct smb_hdr *, char /* command */ ,
const struct cifsTconInfo *, int const struct cifsTconInfo *, int
/* length of fixed section (word count) in two byte units */ /* length of fixed section (word count) in two byte units */
); );
extern time_t cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ ); extern time_t cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ );
extern u64 cifs_UnixTimeToNT(time_t); extern u64 cifs_UnixTimeToNT(time_t);
extern void RevUcode_to_Ucode(char *revUnicode, char *UnicodeName); extern void RevUcode_to_Ucode(char *revUnicode, char *UnicodeName);
extern void Ucode_to_RevUcode(char *Unicode, char *revUnicodeName); extern void Ucode_to_RevUcode(char *Unicode, char *revUnicodeName);
extern void RevUcode_to_Ucode_with_Len(char *revUnicode, char *UnicodeName, extern void RevUcode_to_Ucode_with_Len(char *revUnicode, char *UnicodeName,
int Len); int Len);
extern void Ucode_to_RevUcode_with_Len(char *Unicode, char *revUnicodeName, extern void Ucode_to_RevUcode_with_Len(char *Unicode, char *revUnicodeName,
int Len); int Len);
extern int cifs_get_inode_info(struct inode **pinode, extern int cifs_get_inode_info(struct inode **pinode,
const unsigned char *search_path, const unsigned char *search_path,
struct super_block *sb); struct super_block *sb);
extern int cifs_get_inode_info_unix(struct inode **pinode, 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 CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses,
char cryptokey[CIFS_CRYPTO_KEY_SIZE]); char cryptokey[CIFS_CRYPTO_KEY_SIZE]);
extern int CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, extern int CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
char *user, char *domain, 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 *user, char *domain,
char *SecurityBlob, char *SecurityBlob,
int SecurityBlobLength, 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,
char *domain, char *domain,
char *ntlm_session_key, char *ntlm_session_key,
int *ntlmv2_flag, 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 *user,
char *domain, char *ntlm_session_key, char *domain, char *ntlm_session_key,
char *lanman_session_key, char *lanman_session_key,
int ntlmv2_flag, 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,
const char *tree, struct cifsTconInfo *tcon, const char *tree, struct cifsTconInfo *tcon,
const struct nls_table *); const struct nls_table *);
extern int CIFSFindFirst(const int xid, const struct cifsTconInfo *tcon, extern int CIFSFindFirst(const int xid, const struct cifsTconInfo *tcon,
const char *searchName, const char *searchName,
FILE_DIRECTORY_INFO * findData, FILE_DIRECTORY_INFO * findData,
T2_FFIRST_RSP_PARMS * findParms, T2_FFIRST_RSP_PARMS * findParms,
const struct nls_table *nls_codepage, const struct nls_table *nls_codepage,
int *pUnicodeFlag, int *pUnicodeFlag,
int *pUnixFlag /* if Unix extensions used */ ); int *pUnixFlag /* if Unix extensions used */ );
extern int CIFSFindNext(const int xid, const struct cifsTconInfo *tcon, extern int CIFSFindNext(const int xid, const struct cifsTconInfo *tcon,
FILE_DIRECTORY_INFO * findData, FILE_DIRECTORY_INFO * findData,
T2_FNEXT_RSP_PARMS * findParms, T2_FNEXT_RSP_PARMS * findParms,
...@@ -112,48 +112,48 @@ extern int CIFSFindNext(const int xid, const struct cifsTconInfo *tcon, ...@@ -112,48 +112,48 @@ extern int CIFSFindNext(const int xid, const struct cifsTconInfo *tcon,
int *UnicodeFlag, int *pUnixFlag); int *UnicodeFlag, int *pUnixFlag);
extern int CIFSSMBQPathInfo(const int xid, const struct cifsTconInfo *tcon, extern int CIFSSMBQPathInfo(const int xid, const struct cifsTconInfo *tcon,
const unsigned char *searchName, const unsigned char *searchName,
FILE_ALL_INFO * findData, FILE_ALL_INFO * findData,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
extern int CIFSSMBUnixQPathInfo(const int xid, extern int CIFSSMBUnixQPathInfo(const int xid,
const struct cifsTconInfo *tcon, const struct cifsTconInfo *tcon,
const unsigned char *searchName, const unsigned char *searchName,
FILE_UNIX_BASIC_INFO * pFindData, FILE_UNIX_BASIC_INFO * pFindData,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
extern int CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses, extern int CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
const unsigned char *searchName, const unsigned char *searchName,
unsigned char **targetUNCs, unsigned char **targetUNCs,
int *number_of_UNC_in_array, int *number_of_UNC_in_array,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
extern int connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo, extern int connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
const char *old_path, const char *old_path,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
extern int CIFSSMBQFSInfo(const int xid, const struct cifsTconInfo *tcon, extern int CIFSSMBQFSInfo(const int xid, const struct cifsTconInfo *tcon,
struct statfs *FSData, struct statfs *FSData,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
extern int CIFSSMBQFSAttributeInfo(const int xid, extern int CIFSSMBQFSAttributeInfo(const int xid,
struct cifsTconInfo *tcon, struct cifsTconInfo *tcon,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
extern int CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
extern int CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
extern int CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon,
char *fileName, FILE_BASIC_INFO * data, char *fileName, FILE_BASIC_INFO * data,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
extern int CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon,
char *fileName, __u64 size,int setAllocationSizeFlag, char *fileName, __u64 size,int setAllocationSizeFlag,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
extern int CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon,
__u64 size, __u16 fileHandle,__u32 opener_pid, int AllocSizeFlag); __u64 size, __u16 fileHandle,__u32 opener_pid, int AllocSizeFlag);
extern int CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *pTcon, extern int CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *pTcon,
char *full_path, __u64 mode, __u64 uid, char *full_path, __u64 mode, __u64 uid,
__u64 gid, const struct nls_table *nls_codepage); __u64 gid, const struct nls_table *nls_codepage);
extern int CIFSSMBMkDir(const int xid, const struct cifsTconInfo *tcon, extern int CIFSSMBMkDir(const int xid, const struct cifsTconInfo *tcon,
const char *newName, const char *newName,
...@@ -162,49 +162,49 @@ extern int CIFSSMBRmDir(const int xid, const struct cifsTconInfo *tcon, ...@@ -162,49 +162,49 @@ extern int CIFSSMBRmDir(const int xid, const struct cifsTconInfo *tcon,
const char *name, const struct nls_table *nls_codepage); const char *name, const struct nls_table *nls_codepage);
extern int CIFSSMBDelFile(const int xid, const struct cifsTconInfo *tcon, extern int CIFSSMBDelFile(const int xid, const struct cifsTconInfo *tcon,
const char *name, const char *name,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
extern int CIFSSMBRename(const int xid, const struct cifsTconInfo *tcon, extern int CIFSSMBRename(const int xid, const struct cifsTconInfo *tcon,
const char *fromName, const char *toName, const char *fromName, const char *toName,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
extern int CIFSCreateHardLink(const int xid, extern int CIFSCreateHardLink(const int xid,
const struct cifsTconInfo *tcon, const struct cifsTconInfo *tcon,
const char *fromName, const char *toName, const char *fromName, const char *toName,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
extern int CIFSUnixCreateHardLink(const int xid, extern int CIFSUnixCreateHardLink(const int xid,
const struct cifsTconInfo *tcon, const struct cifsTconInfo *tcon,
const char *fromName, const char *toName, const char *fromName, const char *toName,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
extern int CIFSUnixCreateSymLink(const int xid, extern int CIFSUnixCreateSymLink(const int xid,
const struct cifsTconInfo *tcon, const struct cifsTconInfo *tcon,
const char *fromName, const char *toName, const char *fromName, const char *toName,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
extern int CIFSSMBUnixQuerySymLink(const int xid, extern int CIFSSMBUnixQuerySymLink(const int xid,
const struct cifsTconInfo *tcon, const struct cifsTconInfo *tcon,
const unsigned char *searchName, const unsigned char *searchName,
char *syminfo, const int buflen, char *syminfo, const int buflen,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
extern int CIFSSMBOpen(const int xid, const struct cifsTconInfo *tcon, extern int CIFSSMBOpen(const int xid, const struct cifsTconInfo *tcon,
const char *fileName, const int disposition, const char *fileName, const int disposition,
const int access_flags, const int omode, const int access_flags, const int omode,
__u16 * netfid, int *pOplock, __u16 * netfid, int *pOplock,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
extern int CIFSSMBClose(const int xid, const struct cifsTconInfo *tcon, extern int CIFSSMBClose(const int xid, const struct cifsTconInfo *tcon,
const int smb_file_id); const int smb_file_id);
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,
const char *buf, const int long_op); const char *buf, const int long_op);
extern int CIFSSMBLock(const int xid, const struct cifsTconInfo *tcon, extern int CIFSSMBLock(const int xid, const struct cifsTconInfo *tcon,
const __u16 netfid, const __u64 len, const __u16 netfid, const __u64 len,
const __u64 offset, const __u32 numUnlock, const __u64 offset, const __u32 numUnlock,
const __u32 numLock, const __u8 lockType, const __u32 numLock, const __u8 lockType,
const int waitFlag); const int waitFlag);
extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon); extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon);
extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses); extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses);
...@@ -220,32 +220,32 @@ extern int cifs_reconnect(struct TCP_Server_Info *server); ...@@ -220,32 +220,32 @@ extern int cifs_reconnect(struct TCP_Server_Info *server);
/* BB routines below not implemented yet BB */ /* BB routines below not implemented yet BB */
extern int CIFSBuildServerList(int xid, char *serverBufferList, extern int CIFSBuildServerList(int xid, char *serverBufferList,
int recordlength, int *entries, int recordlength, int *entries,
int *totalEntries, int *topoChangedFlag); int *totalEntries, int *topoChangedFlag);
extern int CIFSSMBQueryShares(int xid, struct cifsTconInfo *tcon, extern int CIFSSMBQueryShares(int xid, struct cifsTconInfo *tcon,
struct shareInfo *shareList, int bufferLen, struct shareInfo *shareList, int bufferLen,
int *entries, int *totalEntries); int *entries, int *totalEntries);
extern int CIFSSMBQueryAlias(int xid, struct cifsTconInfo *tcon, extern int CIFSSMBQueryAlias(int xid, struct cifsTconInfo *tcon,
struct aliasInfo *aliasList, int bufferLen, struct aliasInfo *aliasList, int bufferLen,
int *entries, int *totalEntries); int *entries, int *totalEntries);
extern int CIFSSMBAliasInfo(int xid, struct cifsTconInfo *tcon, extern int CIFSSMBAliasInfo(int xid, struct cifsTconInfo *tcon,
char *aliasName, char *serverName, char *aliasName, char *serverName,
char *shareName, char *comment); char *shareName, char *comment);
extern int CIFSSMBGetShareInfo(int xid, struct cifsTconInfo *tcon, extern int CIFSSMBGetShareInfo(int xid, struct cifsTconInfo *tcon,
char *share, char *comment); char *share, char *comment);
extern int CIFSSMBGetUserPerms(int xid, struct cifsTconInfo *tcon, extern int CIFSSMBGetUserPerms(int xid, struct cifsTconInfo *tcon,
char *userName, char *searchName, int *perms); char *userName, char *searchName, int *perms);
extern int CIFSSMBSync(int xid, struct cifsTconInfo *tcon, int netfid, int pid); extern int CIFSSMBSync(int xid, struct cifsTconInfo *tcon, int netfid, int pid);
extern int CIFSSMBSeek(int xid, extern int CIFSSMBSeek(int xid,
struct cifsTconInfo *tcon, struct cifsTconInfo *tcon,
int netfid, int netfid,
int pid, int pid,
int whence, unsigned long offset, long long *newoffset); int whence, unsigned long offset, long long *newoffset);
extern int CIFSSMBCopy(int xid, extern int CIFSSMBCopy(int xid,
struct cifsTconInfo *ftcon, struct cifsTconInfo *ftcon,
char *fromName, char *fromName,
struct cifsTconInfo *ttcon, struct cifsTconInfo *ttcon,
char *toName, int ofun, int flags); char *toName, int ofun, int flags);
#endif /* _CIFSPROTO_H */ #endif /* _CIFSPROTO_H */
...@@ -487,7 +487,7 @@ CIFSSMBRead(const int xid, const struct cifsTconInfo *tcon, ...@@ -487,7 +487,7 @@ CIFSSMBRead(const int xid, const struct cifsTconInfo *tcon,
(tcon->ses->maxBuf - (tcon->ses->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 */
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);
...@@ -497,16 +497,20 @@ CIFSSMBRead(const int xid, const struct cifsTconInfo *tcon, ...@@ -497,16 +497,20 @@ CIFSSMBRead(const int xid, const struct cifsTconInfo *tcon,
} else { } else {
pSMBr->DataLength = le16_to_cpu(pSMBr->DataLength); pSMBr->DataLength = le16_to_cpu(pSMBr->DataLength);
*nbytes = pSMBr->DataLength; *nbytes = pSMBr->DataLength;
/* BB check that DataLength would not go beyond end of SMB BB */ /*check that DataLength would not go beyond end of SMB */
if (pSMBr->DataLength > CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE) { if ((pSMBr->DataLength > CIFS_MAX_MSGSIZE)
|| (pSMBr->DataLength > count)) {
rc = -EIO; rc = -EIO;
*nbytes = 0; *nbytes = 0;
} else { } else {
pReadData = pReadData =
(char *) (&pSMBr->hdr.Protocol) + (char *) (&pSMBr->hdr.Protocol) +
le16_to_cpu(pSMBr->DataOffset); le16_to_cpu(pSMBr->DataOffset);
if(copy_to_user(buf, pReadData, pSMBr->DataLength)) /* if(rc = copy_to_user(buf, pReadData, pSMBr->DataLength)) {
rc = -EFAULT; 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, ...@@ -546,12 +550,7 @@ CIFSSMBWrite(const int xid, const struct cifsTconInfo *tcon,
pSMB->DataOffset = pSMB->DataOffset =
cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4); cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4);
if(copy_from_user(pSMB->Data, buf, pSMB->DataLengthLow)) { memcpy(pSMB->Data,buf,pSMB->DataLengthLow);
buf_release(pSMB);
return -EFAULT;
}
pSMB->ByteCount += pSMB->DataLengthLow + 1 /* pad */ ; pSMB->ByteCount += pSMB->DataLengthLow + 1 /* pad */ ;
pSMB->DataLengthLow = cpu_to_le16(pSMB->DataLengthLow); pSMB->DataLengthLow = cpu_to_le16(pSMB->DataLengthLow);
......
...@@ -736,18 +736,18 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -736,18 +736,18 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
&& (pSesInfo->secType == RawNTLMSSP)) { && (pSesInfo->secType == RawNTLMSSP)) {
cFYI(1, ("\nNTLMSSP sesssetup ")); cFYI(1, ("\nNTLMSSP sesssetup "));
rc = CIFSNTLMSSPNegotiateSessSetup(xid, rc = CIFSNTLMSSPNegotiateSessSetup(xid,
pSesInfo, pSesInfo,
cryptKey, cryptKey,
volume_info.domainname, volume_info.domainname,
&ntlmv2_flag, &ntlmv2_flag,
cifs_sb->local_nls); cifs_sb->local_nls);
if (!rc) { if (!rc) {
if(ntlmv2_flag) { if(ntlmv2_flag) {
cFYI(1,("\nAble to use the more secure NTLM version 2 password hash")); cFYI(1,("\nAble to use the more secure NTLM version 2 password hash"));
/* SMBNTv2encrypt( ...); */ /* BB fix this up - /* SMBNTv2encrypt( ...); */ /* BB fix this up -
and note that Samba client equivalent looks wrong */ and note that Samba client equivalent looks wrong */
} else } else
SMBNTencrypt(password_with_pad,cryptKey,ntlm_session_key); SMBNTencrypt(password_with_pad,cryptKey,ntlm_session_key);
/* for better security the weaker lanman hash not sent /* for better security the weaker lanman hash not sent
in AuthSessSetup so why bother calculating it */ in AuthSessSetup so why bother calculating it */
...@@ -758,13 +758,13 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -758,13 +758,13 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
cryptKey, session_key); */ cryptKey, session_key); */
rc = CIFSNTLMSSPAuthSessSetup(xid, rc = CIFSNTLMSSPAuthSessSetup(xid,
pSesInfo, pSesInfo,
volume_info. volume_info.
username, username,
volume_info.domainname, volume_info.domainname,
ntlm_session_key, ntlm_session_key,
session_key, session_key,
ntlmv2_flag, ntlmv2_flag,
cifs_sb->local_nls); cifs_sb->local_nls);
} }
} else { /* old style NTLM 0.12 session setup */ } else { /* old style NTLM 0.12 session setup */
...@@ -821,6 +821,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -821,6 +821,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
"", "",
cifs_sb-> cifs_sb->
local_nls); local_nls);
FreeXid(xid);
return -ENODEV; return -ENODEV;
} else { } else {
rc = CIFSTCon(xid, pSesInfo, rc = CIFSTCon(xid, pSesInfo,
...@@ -909,8 +910,8 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, char *user, ...@@ -909,8 +910,8 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, char *user,
pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->maxBuf); pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->maxBuf);
pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->maxReq); pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->maxReq);
if(ses->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) if(ses->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 =
CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS; CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS;
...@@ -944,8 +945,8 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, char *user, ...@@ -944,8 +945,8 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, char *user,
*bcc_ptr = 0; *bcc_ptr = 0;
bcc_ptr++; bcc_ptr++;
} }
if(user == NULL) if(user == NULL)
bytes_returned = 0; /* skill null user */ bytes_returned = 0; /* skill null user */
else else
bytes_returned = bytes_returned =
cifs_strtoUCS((wchar_t *) bcc_ptr, user, 100, nls_codepage); cifs_strtoUCS((wchar_t *) bcc_ptr, user, 100, nls_codepage);
...@@ -976,10 +977,10 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, char *user, ...@@ -976,10 +977,10 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, char *user,
bcc_ptr += 2 * bytes_returned; bcc_ptr += 2 * bytes_returned;
bcc_ptr += 2; bcc_ptr += 2;
} else { } else {
if(user != NULL) { if(user != NULL) {
strncpy(bcc_ptr, user, 200); strncpy(bcc_ptr, user, 200);
bcc_ptr += strnlen(user, 200); bcc_ptr += strnlen(user, 200);
} }
*bcc_ptr = 0; *bcc_ptr = 0;
bcc_ptr++; bcc_ptr++;
if (domain == NULL) { if (domain == NULL) {
...@@ -1081,7 +1082,6 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, char *user, ...@@ -1081,7 +1082,6 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, char *user,
kcalloc(2, GFP_KERNEL); kcalloc(2, GFP_KERNEL);
} }
} else { /* ASCII */ } else { /* ASCII */
len = strnlen(bcc_ptr, 1024); len = strnlen(bcc_ptr, 1024);
if (((long) bcc_ptr + len) - (long) if (((long) bcc_ptr + len) - (long)
pByteArea(smb_buffer_response) pByteArea(smb_buffer_response)
...@@ -1164,8 +1164,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -1164,8 +1164,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
pSMB->req.MaxBufferSize = cpu_to_le16(ses->maxBuf); pSMB->req.MaxBufferSize = cpu_to_le16(ses->maxBuf);
pSMB->req.MaxMpxCount = cpu_to_le16(ses->maxReq); pSMB->req.MaxMpxCount = cpu_to_le16(ses->maxReq);
if(ses->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) if(ses->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 =
CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS | CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
...@@ -1410,7 +1410,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, ...@@ -1410,7 +1410,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
PCHALLENGE_MESSAGE SecurityBlob2; PCHALLENGE_MESSAGE SecurityBlob2;
cFYI(1, ("\nIn NTLMSSP sesssetup (negotiate) ")); cFYI(1, ("\nIn 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) {
return -ENOMEM; return -ENOMEM;
...@@ -1429,8 +1429,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, ...@@ -1429,8 +1429,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
pSMB->req.MaxBufferSize = cpu_to_le16(ses->maxBuf); pSMB->req.MaxBufferSize = cpu_to_le16(ses->maxBuf);
pSMB->req.MaxMpxCount = cpu_to_le16(ses->maxReq); pSMB->req.MaxMpxCount = cpu_to_le16(ses->maxReq);
if(ses->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) if(ses->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 =
CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS | CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
...@@ -1457,8 +1457,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, ...@@ -1457,8 +1457,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM | NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM |
NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM | 0x80000000 | NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM | 0x80000000 |
NTLMSSP_NEGOTIATE_ALWAYS_SIGN | NTLMSSP_NEGOTIATE_128; NTLMSSP_NEGOTIATE_ALWAYS_SIGN | NTLMSSP_NEGOTIATE_128;
if(ntlmv2_support) if(ntlmv2_support)
SecurityBlob->NegotiateFlags |= NTLMSSP_NEGOTIATE_NTLMV2; SecurityBlob->NegotiateFlags |= NTLMSSP_NEGOTIATE_NTLMV2;
/* setup pointers to domain name and workstation name */ /* setup pointers to domain name and workstation name */
bcc_ptr += SecurityBlobLength; bcc_ptr += SecurityBlobLength;
...@@ -1574,8 +1574,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, ...@@ -1574,8 +1574,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
memcpy(challenge_from_server, memcpy(challenge_from_server,
SecurityBlob2->Challenge, SecurityBlob2->Challenge,
CIFS_CRYPTO_KEY_SIZE); CIFS_CRYPTO_KEY_SIZE);
if(SecurityBlob2->NegotiateFlags & NTLMSSP_NEGOTIATE_NTLMV2) if(SecurityBlob2->NegotiateFlags & NTLMSSP_NEGOTIATE_NTLMV2)
*pNTLMv2_flag = TRUE; *pNTLMv2_flag = TRUE;
if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) { if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) {
if ((long) (bcc_ptr) % 2) { if ((long) (bcc_ptr) % 2) {
remaining_words = remaining_words =
...@@ -1661,7 +1661,6 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, ...@@ -1661,7 +1661,6 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
kcalloc(2, GFP_KERNEL); kcalloc(2, GFP_KERNEL);
} }
} else { /* ASCII */ } else { /* ASCII */
len = strnlen(bcc_ptr, 1024); len = strnlen(bcc_ptr, 1024);
if (((long) bcc_ptr + len) - (long) if (((long) bcc_ptr + len) - (long)
pByteArea(smb_buffer_response) pByteArea(smb_buffer_response)
...@@ -1758,8 +1757,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -1758,8 +1757,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
pSMB->req.hdr.Uid = ses->Suid; pSMB->req.hdr.Uid = ses->Suid;
if(ses->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) if(ses->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 =
CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS | CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
...@@ -1787,8 +1786,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -1787,8 +1786,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
0x80000000 | NTLMSSP_NEGOTIATE_ALWAYS_SIGN | NTLMSSP_NEGOTIATE_128; 0x80000000 | NTLMSSP_NEGOTIATE_ALWAYS_SIGN | NTLMSSP_NEGOTIATE_128;
if(ntlmv2_flag) if(ntlmv2_flag)
SecurityBlob->NegotiateFlags |= NTLMSSP_NEGOTIATE_NTLMV2; SecurityBlob->NegotiateFlags |= NTLMSSP_NEGOTIATE_NTLMV2;
/* setup pointers to domain name and workstation name */ /* setup pointers to domain name and workstation name */
...@@ -2048,7 +2047,6 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, ...@@ -2048,7 +2047,6 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
ses->serverNOS = kcalloc(2, GFP_KERNEL); ses->serverNOS = kcalloc(2, GFP_KERNEL);
} }
} else { /* ASCII */ } else { /* ASCII */
len = strnlen(bcc_ptr, 1024); len = strnlen(bcc_ptr, 1024);
if (((long) bcc_ptr + len) - if (((long) bcc_ptr + len) -
(long) pByteArea(smb_buffer_response) (long) pByteArea(smb_buffer_response)
...@@ -2132,8 +2130,8 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, ...@@ -2132,8 +2130,8 @@ 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->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) {
smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS; smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
......
...@@ -35,6 +35,8 @@ ...@@ -35,6 +35,8 @@
#include "cifs_debug.h" #include "cifs_debug.h"
#include "cifs_fs_sb.h" #include "cifs_fs_sb.h"
int int
cifs_open(struct inode *inode, struct file *file) cifs_open(struct inode *inode, struct file *file)
{ {
...@@ -42,8 +44,8 @@ cifs_open(struct inode *inode, struct file *file) ...@@ -42,8 +44,8 @@ cifs_open(struct inode *inode, struct file *file)
int xid, oplock; int xid, oplock;
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon; struct cifsTconInfo *pTcon;
struct cifsFileInfo *pCifsFile; struct cifsFileInfo *pCifsFile;
struct cifsInodeInfo *pCifsInode; struct cifsInodeInfo *pCifsInode;
char *full_path = NULL; char *full_path = NULL;
int desiredAccess = 0x20197; int desiredAccess = 0x20197;
int disposition = FILE_OPEN; int disposition = FILE_OPEN;
...@@ -104,28 +106,27 @@ cifs_open(struct inode *inode, struct file *file) ...@@ -104,28 +106,27 @@ cifs_open(struct inode *inode, struct file *file)
if (file->private_data) { if (file->private_data) {
memset(file->private_data, 0, memset(file->private_data, 0,
sizeof (struct cifsFileInfo)); sizeof (struct cifsFileInfo));
pCifsFile = (struct cifsFileInfo *) file->private_data; pCifsFile = (struct cifsFileInfo *) file->private_data;
pCifsFile->netfid = netfid; pCifsFile->netfid = netfid;
pCifsFile->pid = current->pid; pCifsFile->pid = current->pid;
list_add(&pCifsFile->tlist,&pTcon->openFileList); pCifsFile->pfile = file; /* needed for writepage */
pCifsInode = CIFS_I(file->f_dentry->d_inode); list_add(&pCifsFile->tlist,&pTcon->openFileList);
list_add(&pCifsFile->flist,&pCifsInode->openFileList); pCifsInode = CIFS_I(file->f_dentry->d_inode);
if(file->f_flags & O_CREAT) { list_add(&pCifsFile->flist,&pCifsInode->openFileList);
/* time to set mode which we can not if(file->f_flags & O_CREAT) {
set earlier due to problems creating new read-only files */ /* time to set mode which we can not set earlier due
if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) to problems creating new read-only files */
CIFSSMBUnixSetPerms(xid, pTcon, full_path, inode->i_mode, if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)
0xFFFFFFFFFFFFFFFF, CIFSSMBUnixSetPerms(xid, pTcon, full_path, inode->i_mode,
0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF,
cifs_sb->local_nls); 0xFFFFFFFFFFFFFFFF,
else {/* BB to be implemented via Windows secrty descriptors*/ cifs_sb->local_nls);
/* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/ else {/* BB implement via Windows security descriptors */
/* in the meantime we could set the r/o dos attribute /* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/
when perms are e.g.: /* in the meantime could set r/o dos attribute when perms are eg:
mode & 0222 == 0 */ mode & 0222 == 0 */
} }
} }
} }
} }
...@@ -151,10 +152,10 @@ cifs_close(struct inode *inode, struct file *file) ...@@ -151,10 +152,10 @@ cifs_close(struct inode *inode, struct file *file)
cifs_sb = CIFS_SB(inode->i_sb); cifs_sb = CIFS_SB(inode->i_sb);
pTcon = cifs_sb->tcon; pTcon = cifs_sb->tcon;
if (pSMBFile) { if (pSMBFile) {
list_del(&pSMBFile->flist); list_del(&pSMBFile->flist);
list_del(&pSMBFile->tlist); list_del(&pSMBFile->tlist);
rc = CIFSSMBClose(xid, pTcon, pSMBFile->netfid); rc = CIFSSMBClose(xid, pTcon, pSMBFile->netfid);
kfree(file->private_data); kfree(file->private_data);
file->private_data = NULL; file->private_data = NULL;
} else } else
...@@ -162,7 +163,6 @@ cifs_close(struct inode *inode, struct file *file) ...@@ -162,7 +163,6 @@ cifs_close(struct inode *inode, struct file *file)
FreeXid(xid); FreeXid(xid);
return rc; return rc;
} }
int int
...@@ -344,20 +344,24 @@ cifs_write(struct file * file, const char *write_data, ...@@ -344,20 +344,24 @@ cifs_write(struct file * file, const char *write_data,
file->f_dentry->d_inode->i_size = *poffset; file->f_dentry->d_inode->i_size = *poffset;
} }
mark_inode_dirty_sync(file->f_dentry->d_inode); mark_inode_dirty_sync(file->f_dentry->d_inode);
FreeXid(xid);
return total_written; return total_written;
} }
static int static int
cifs_writepage(struct page *page) cifs_partialpagewrite(struct page *page,unsigned from, unsigned to)
{ {
struct address_space *mapping = page->mapping; 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 rc = -EFAULT;
int bytes_written = 0; int bytes_written = 0;
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon; struct cifsTconInfo *pTcon;
int xid;
struct inode *inode = page->mapping->host; struct inode *inode = page->mapping->host;
loff_t *poffset = NULL; struct cifsInodeInfo *cifsInode;
struct cifsFileInfo *open_file = NULL;
int xid;
xid = GetXid(); xid = GetXid();
...@@ -365,51 +369,90 @@ cifs_writepage(struct page *page) ...@@ -365,51 +369,90 @@ cifs_writepage(struct page *page)
pTcon = cifs_sb->tcon; pTcon = cifs_sb->tcon;
/* figure out which file struct to use /* figure out which file struct to use
if (file->private_data == NULL) { if (file->private_data == NULL) {
FreeXid(xid); FreeXid(xid);
return -EBADF; return -EBADF;
} }
*/ */
if (!mapping) { if (!mapping) {
FreeXid(xid); FreeXid(xid);
return -EFAULT; return -EFAULT;
} else if(!mapping->host) {
FreeXid(xid);
return -EFAULT;
} }
/* BB fix and add missing call to cifs_writepage_sync here */ if((to > PAGE_CACHE_SIZE) || (from > to))
return -EIO;
inode->i_ctime = inode->i_mtime = CURRENT_TIME; /* BB is this right? */
if ((bytes_written > 0) && (poffset)) { offset += (loff_t)from;
if (*poffset > inode->i_size) write_data += from;
inode->i_size = *poffset;
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;
} }
mark_inode_dirty_sync(inode);
FreeXid(xid); FreeXid(xid);
return rc; return rc;
} }
static int static int
cifs_prepare_write(struct file *file, struct page *page, unsigned offset, cifs_writepage(struct page* page)
unsigned to)
{ {
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 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)
{ {
long rc = -EFAULT; int xid,rc;
xid = GetXid();
lock_kernel();
/* status = cifs_updatepage(file, page, offset, to-offset); */
/* 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; 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)
{ {
...@@ -489,13 +532,30 @@ cifs_read(struct file * file, char *read_data, size_t read_size, ...@@ -489,13 +532,30 @@ cifs_read(struct file * file, char *read_data, size_t read_size,
return total_read; 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 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 rc = -EACCES;
int bytes_read = 0;
int total_read = 0;
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon; struct cifsTconInfo *pTcon;
int xid; int xid;
...@@ -508,26 +568,33 @@ cifs_readpage_sync(struct file *file, struct page *page) ...@@ -508,26 +568,33 @@ cifs_readpage_sync(struct file *file, struct page *page)
FreeXid(xid); FreeXid(xid);
return -EBADF; 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, if (rc < 0)
("\nCount is %d total read %d bytes read %d ", count, total_read, goto io_error;
bytes_read)); else {
cFYI(1,("\nBytes read %d ",rc));
}
FreeXid(xid); file->f_dentry->d_inode->i_atime = CURRENT_TIME;
return rc;
}
static int if(PAGE_CACHE_SIZE > rc) {
cifs_readpage(struct file *file, struct page *page) memset(read_data+rc, 0, PAGE_CACHE_SIZE - rc);
{ }
int 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); page_cache_release(page);
FreeXid(xid);
return rc; return rc;
} }
...@@ -546,11 +613,11 @@ fill_in_inode(struct inode *tmp_inode, ...@@ -546,11 +613,11 @@ fill_in_inode(struct inode *tmp_inode,
/* Linux can not store file creation time unfortunately so we ignore it */ /* Linux can not store file creation time unfortunately so we ignore it */
tmp_inode->i_atime = tmp_inode->i_atime =
le64_to_cpu(cifs_NTtimeToUnix(pfindData->LastAccessTime)); cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime));
tmp_inode->i_mtime = tmp_inode->i_mtime =
le64_to_cpu(cifs_NTtimeToUnix(pfindData->LastWriteTime)); cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
tmp_inode->i_ctime = 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 */ /* 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 */ tmp_inode->i_mode = S_IALLUGO & ~(S_ISUID | S_IXGRP); /* 2767 perms - indicate mandatory locking */
cFYI(0, cFYI(0,
...@@ -605,16 +672,12 @@ unix_fill_in_inode(struct inode *tmp_inode, ...@@ -605,16 +672,12 @@ unix_fill_in_inode(struct inode *tmp_inode,
atomic_inc(&cifsInfo->inUse); atomic_inc(&cifsInfo->inUse);
tmp_inode->i_atime = tmp_inode->i_atime =
le64_to_cpu(cifs_NTtimeToUnix(pfindData->LastAccessTime)); cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime));
tmp_inode->i_mtime = tmp_inode->i_mtime =
le64_to_cpu(cifs_NTtimeToUnix(pfindData->LastModificationTime)); cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastModificationTime));
tmp_inode->i_ctime = 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); tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions);
pfindData->Type = le32_to_cpu(pfindData->Type); pfindData->Type = le32_to_cpu(pfindData->Type);
if (pfindData->Type == UNIX_FILE) { if (pfindData->Type == UNIX_FILE) {
...@@ -1013,8 +1076,17 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir) ...@@ -1013,8 +1076,17 @@ 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,
.sync_page = cifs_sync_page,
.writepage = cifs_writepage, .writepage = cifs_writepage,
.prepare_write = cifs_prepare_write, .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,
}; };
...@@ -52,9 +52,9 @@ cifs_get_inode_info_unix(struct inode **pinode, ...@@ -52,9 +52,9 @@ cifs_get_inode_info_unix(struct inode **pinode,
if (rc) { if (rc) {
if (rc == -EREMOTE) { if (rc == -EREMOTE) {
/* rc = *//* CIFSGetDFSRefer(xid, pTcon->ses, search_path, /* rc = *//* CIFSGetDFSRefer(xid, pTcon->ses, search_path,
&referrals, &referrals,
&num_referrals, &num_referrals,
cifs_sb->local_nls); */ cifs_sb->local_nls); */
tmp_path = tmp_path =
kmalloc(strnlen kmalloc(strnlen
(pTcon->treeName, (pTcon->treeName,
...@@ -99,12 +99,12 @@ cifs_get_inode_info_unix(struct inode **pinode, ...@@ -99,12 +99,12 @@ cifs_get_inode_info_unix(struct inode **pinode,
atomic_inc(&cifsInfo->inUse); /* inc on every refresh of inode */ atomic_inc(&cifsInfo->inUse); /* inc on every refresh of inode */
inode->i_atime = inode->i_atime =
le64_to_cpu(cifs_NTtimeToUnix(findData.LastAccessTime)); cifs_NTtimeToUnix(le64_to_cpu(findData.LastAccessTime));
inode->i_mtime = inode->i_mtime =
le64_to_cpu(cifs_NTtimeToUnix cifs_NTtimeToUnix(le64_to_cpu
(findData.LastModificationTime)); (findData.LastModificationTime));
inode->i_ctime = 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); inode->i_mode = le64_to_cpu(findData.Permissions);
findData.Type = le32_to_cpu(findData.Type); findData.Type = le32_to_cpu(findData.Type);
if (findData.Type == UNIX_FILE) { if (findData.Type == UNIX_FILE) {
...@@ -140,6 +140,7 @@ cifs_get_inode_info_unix(struct inode **pinode, ...@@ -140,6 +140,7 @@ cifs_get_inode_info_unix(struct inode **pinode,
cFYI(1, (" File inode ")); cFYI(1, (" File inode "));
inode->i_op = &cifs_file_inode_ops; inode->i_op = &cifs_file_inode_ops;
inode->i_fop = &cifs_file_ops; inode->i_fop = &cifs_file_ops;
inode->i_data.a_ops = &cifs_addr_ops;
} else if (S_ISDIR(inode->i_mode)) { } else if (S_ISDIR(inode->i_mode)) {
cFYI(1, (" Directory inode")); cFYI(1, (" Directory inode"));
inode->i_op = &cifs_dir_inode_ops; inode->i_op = &cifs_dir_inode_ops;
...@@ -182,9 +183,9 @@ cifs_get_inode_info(struct inode **pinode, ...@@ -182,9 +183,9 @@ cifs_get_inode_info(struct inode **pinode,
if (rc == -EREMOTE) { if (rc == -EREMOTE) {
/* BB add call to new func rc = GetDFSReferral(); */ /* BB add call to new func rc = GetDFSReferral(); */
/* rc = *//* CIFSGetDFSRefer(xid, pTcon->ses, search_path, /* rc = *//* CIFSGetDFSRefer(xid, pTcon->ses, search_path,
&referrals, &referrals,
&num_referrals, &num_referrals,
cifs_sb->local_nls); */ cifs_sb->local_nls); */
tmp_path = tmp_path =
kmalloc(strnlen kmalloc(strnlen
(pTcon->treeName, (pTcon->treeName,
...@@ -265,6 +266,7 @@ cifs_get_inode_info(struct inode **pinode, ...@@ -265,6 +266,7 @@ cifs_get_inode_info(struct inode **pinode,
cFYI(1, (" File inode ")); cFYI(1, (" File inode "));
inode->i_op = &cifs_file_inode_ops; inode->i_op = &cifs_file_inode_ops;
inode->i_fop = &cifs_file_ops; inode->i_fop = &cifs_file_ops;
inode->i_data.a_ops = &cifs_addr_ops;
} else if (S_ISDIR(inode->i_mode)) { } else if (S_ISDIR(inode->i_mode)) {
cFYI(1, (" Directory inode ")); cFYI(1, (" Directory inode "));
inode->i_op = &cifs_dir_inode_ops; inode->i_op = &cifs_dir_inode_ops;
...@@ -441,9 +443,11 @@ cifs_rename(struct inode *source_inode, struct dentry *source_direntry, ...@@ -441,9 +443,11 @@ cifs_rename(struct inode *source_inode, struct dentry *source_direntry,
cifs_sb_source = CIFS_SB(source_inode->i_sb); cifs_sb_source = CIFS_SB(source_inode->i_sb);
pTcon = cifs_sb_source->tcon; 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 return -EXDEV; /* BB actually could be allowed if same server, but
different share. Might eventually add support for this */ different share. Might eventually add support for this */
FreeXid(xid);
}
fromName = build_path_from_dentry(source_direntry); fromName = build_path_from_dentry(source_direntry);
toName = build_path_from_dentry(target_direntry); toName = build_path_from_dentry(target_direntry);
...@@ -455,6 +459,7 @@ cifs_rename(struct inode *source_inode, struct dentry *source_direntry, ...@@ -455,6 +459,7 @@ cifs_rename(struct inode *source_inode, struct dentry *source_direntry,
if (toName) if (toName)
kfree(toName); kfree(toName);
FreeXid(xid);
return rc; return rc;
} }
...@@ -479,7 +484,7 @@ cifs_revalidate(struct dentry *direntry) ...@@ -479,7 +484,7 @@ cifs_revalidate(struct dentry *direntry)
direntry->d_time, jiffies)); direntry->d_time, jiffies));
cifsInode = CIFS_I(direntry->d_inode); cifsInode = CIFS_I(direntry->d_inode);
/* BB add check - do not need to revalidate oplocked files */
if ((time_before(jiffies, cifsInode->time + HZ)) if ((time_before(jiffies, cifsInode->time + HZ))
&& (direntry->d_inode->i_nlink == 1)) { && (direntry->d_inode->i_nlink == 1)) {
cFYI(1, (" Do not need to revalidate ")); cFYI(1, (" Do not need to revalidate "));
...@@ -505,12 +510,20 @@ cifs_revalidate(struct dentry *direntry) ...@@ -505,12 +510,20 @@ cifs_revalidate(struct dentry *direntry)
return rc; 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 void
cifs_truncate_file(struct inode *inode) cifs_truncate_file(struct inode *inode)
{ /* BB remove - may not need this function after all BB */ { /* BB remove - may not need this function after all BB */
int xid; int xid;
int rc = 0; int rc = 0;
struct cifsFileInfo *open_file = NULL; struct cifsFileInfo *open_file = NULL;
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon; struct cifsTconInfo *pTcon;
struct cifsInodeInfo *cifsInode; struct cifsInodeInfo *cifsInode;
...@@ -534,21 +547,19 @@ cifs_truncate_file(struct inode *inode) ...@@ -534,21 +547,19 @@ 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,("\nSetEOF (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))) {
open_file = list_entry(cifsInode->openFileList.next, open_file = list_entry(cifsInode->openFileList.next,
struct cifsFileInfo, flist); struct cifsFileInfo, flist);
/* We could check if file is open for writing first and /* We could check if file is open for writing first */
also we could also override the smb pid with the pid rc = CIFSSMBSetFileSize(xid, pTcon, inode->i_size,
of the file opener when sending the CIFS request */ open_file->netfid,open_file->pid,FALSE);
rc = CIFSSMBSetFileSize(xid, pTcon, inode->i_size, } else {
open_file->netfid,open_file->pid,FALSE); cFYI(1,("\nNo open files to get file handle from"));
} else { }
cFYI(1,("\nNo open files to get file handle from")); }
}
}
if (!rc) if (!rc)
CIFSSMBSetEOF(xid,pTcon,full_path,inode->i_size,TRUE,cifs_sb->local_nls); CIFSSMBSetEOF(xid,pTcon,full_path,inode->i_size,TRUE,cifs_sb->local_nls);
/* allocation size setting seems optional so ignore return code */ /* allocation size setting seems optional so ignore return code */
...@@ -567,7 +578,7 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs) ...@@ -567,7 +578,7 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs)
struct cifsTconInfo *pTcon; struct cifsTconInfo *pTcon;
char *full_path = NULL; char *full_path = NULL;
int rc = -EACCES; int rc = -EACCES;
struct cifsFileInfo *open_file = NULL; struct cifsFileInfo *open_file = NULL;
FILE_BASIC_INFO time_buf; FILE_BASIC_INFO time_buf;
int set_time = FALSE; int set_time = FALSE;
__u64 mode = 0xFFFFFFFFFFFFFFFF; __u64 mode = 0xFFFFFFFFFFFFFFFF;
...@@ -593,19 +604,19 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs) ...@@ -593,19 +604,19 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs)
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,("\nSetEOF (setattrs) rc = %d",rc));
if(rc == -ETXTBSY) { if(rc == -ETXTBSY) {
if(!list_empty(&(cifsInode->openFileList))) { if(!list_empty(&(cifsInode->openFileList))) {
open_file = list_entry(cifsInode->openFileList.next, open_file = list_entry(cifsInode->openFileList.next,
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 */
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,("\nNo open files to get file handle from"));
} }
} }
/* Set Allocation Size of file - might not even need to call the /* Set Allocation Size of file - might not even need to call the
following but might as well and it does not hurt if it fails */ following but might as well and it does not hurt if it fails */
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);
...@@ -684,5 +695,4 @@ cifs_delete_inode(struct inode *inode) ...@@ -684,5 +695,4 @@ cifs_delete_inode(struct inode *inode)
cFYI(1, ("In cifs_delete_inode, inode = 0x%p\n", inode)); cFYI(1, ("In cifs_delete_inode, inode = 0x%p\n", 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 */
} }
...@@ -22,17 +22,17 @@ struct HMACMD5Context { ...@@ -22,17 +22,17 @@ struct HMACMD5Context {
void MD5Init(struct MD5Context *context); void MD5Init(struct MD5Context *context);
void MD5Update(struct MD5Context *context, unsigned char const *buf, void MD5Update(struct MD5Context *context, unsigned char const *buf,
unsigned len); unsigned len);
void MD5Final(unsigned char digest[16], struct MD5Context *context); void MD5Final(unsigned char digest[16], struct MD5Context *context);
/* The following definitions come from lib/hmacmd5.c */ /* The following definitions come from lib/hmacmd5.c */
void hmac_md5_init_rfc2104(unsigned char *key, int key_len, void hmac_md5_init_rfc2104(unsigned char *key, int key_len,
struct HMACMD5Context *ctx); struct HMACMD5Context *ctx);
void hmac_md5_init_limK_to_64(const unsigned char *key, int key_len, void hmac_md5_init_limK_to_64(const unsigned char *key, int key_len,
struct HMACMD5Context *ctx); struct HMACMD5Context *ctx);
void hmac_md5_update(const unsigned char *text, int text_len, void hmac_md5_update(const unsigned char *text, int text_len,
struct HMACMD5Context *ctx); struct HMACMD5Context *ctx);
void hmac_md5_final(unsigned char *digest, struct HMACMD5Context *ctx); void hmac_md5_final(unsigned char *digest, struct HMACMD5Context *ctx);
void hmac_md5(unsigned char key[16], unsigned char *data, int data_len, void hmac_md5(unsigned char key[16], unsigned char *data, int data_len,
unsigned char *digest); unsigned char *digest);
...@@ -304,42 +304,42 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length) ...@@ -304,42 +304,42 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
int int
is_valid_oplock_break(struct smb_hdr *buf) 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 cifsTconInfo *tcon; struct cifsTconInfo *tcon;
/* could add check for smb response flag 0x80 */ /* could add check for smb response flag 0x80 */
cFYI(1,("\nChecking for oplock break")); cFYI(1,("\nChecking 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)
return FALSE; /* server sends us "request" here */ return FALSE; /* server sends us "request" here */
if(pSMB->hdr.WordCount != 8) if(pSMB->hdr.WordCount != 8)
return FALSE; return FALSE;
cFYI(1,(" oplock type 0x%d level 0x%d",pSMB->LockType,pSMB->OplockLevel)); cFYI(1,(" oplock type 0x%d level 0x%d",pSMB->LockType,pSMB->OplockLevel));
if(!(pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE)) if(!(pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE))
return FALSE; return FALSE;
/* look up tcon based on tid & uid */ /* look up tcon based on tid & uid */
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) { if(tcon->ses->Suid == buf->Uid) {
/* 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 */ 5) send oplock break response to server */
read_unlock(&GlobalSMBSeslock); read_unlock(&GlobalSMBSeslock);
cFYI(1,("\nFound matching connection, process oplock break")); cFYI(1,("\nFound matching connection, process oplock break"));
return TRUE; return TRUE;
} }
} }
read_unlock(&GlobalSMBSeslock); read_unlock(&GlobalSMBSeslock);
cFYI(1,("\nProcessing oplock break for non-existent connection")); cFYI(1,("\nProcessing oplock break for non-existent connection"));
return TRUE; return TRUE;
} }
void void
......
...@@ -745,7 +745,28 @@ const static struct { ...@@ -745,7 +745,28 @@ const static struct {
ERRDOS, ERRnoaccess, 0xc0000290}, { ERRDOS, ERRnoaccess, 0xc0000290}, {
ERRDOS, ERRbadfunc, 0xc000029c},}; 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) ntstatus_to_dos(__u32 ntstatus, __u8 * eclass, __u16 * ecode)
{ {
int i; int i;
...@@ -781,9 +802,9 @@ map_smb_to_linux_error(struct smb_hdr *smb) ...@@ -781,9 +802,9 @@ map_smb_to_linux_error(struct smb_hdr *smb)
if (smb->Flags2 & SMBFLG2_ERR_STATUS) { if (smb->Flags2 & SMBFLG2_ERR_STATUS) {
/* translate the newer STATUS codes to old style errors and then to POSIX errors */ /* 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); smb->Status.CifsError = le32_to_cpu(smb->Status.CifsError);
if(cifsFYI)
cifs_print_status(smb->Status.CifsError);
ntstatus_to_dos(smb->Status.CifsError, &smberrclass, ntstatus_to_dos(smb->Status.CifsError, &smberrclass,
&smberrcode); &smberrcode);
} else { } else {
......
...@@ -20,14 +20,9 @@ ...@@ -20,14 +20,9 @@
*/ */
/* NT error codes - see nterr.h */ /* NT error codes - see nterr.h */
#include "nterr.h"
#include <linux/types.h> #include <linux/types.h>
#include <linux/fs.h> #include <linux/fs.h>
#include "nterr.h"
struct nt_err_code_struct {
char *nt_errstr;
__u32 nt_errcode;
};
const struct nt_err_code_struct nt_errs[] = { const struct nt_err_code_struct nt_errs[] = {
{"NT_STATUS_OK", NT_STATUS_OK}, {"NT_STATUS_OK", NT_STATUS_OK},
...@@ -690,23 +685,3 @@ const struct nt_err_code_struct nt_errs[] = { ...@@ -690,23 +685,3 @@ const struct nt_err_code_struct nt_errs[] = {
{"STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED}, {"STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED},
{NULL, 0} {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 @@ ...@@ -22,9 +22,18 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef _NTERR_H #ifndef _NTERR_H
#define _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. */ /* Win32 Status codes. */
#define STATUS_BUFFER_OVERFLOW 0x80000005 #define STATUS_BUFFER_OVERFLOW 0x80000005
......
...@@ -205,19 +205,26 @@ nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]) ...@@ -205,19 +205,26 @@ nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16])
/* Does the NTLMv2 owfs of a user's password */ /* Does the NTLMv2 owfs of a user's password */
void void
ntv2_owf_gen(const unsigned char owf[16], const char *user_n, ntv2_owf_gen(const unsigned char owf[16], const char *user_n,
const char *domain_n, unsigned char kr_buf[16], const char *domain_n, unsigned char kr_buf[16],
const struct nls_table *nls_codepage) const struct nls_table *nls_codepage)
{ {
wchar_t user_u[1024]; wchar_t * user_u;
wchar_t dom_u[1024]; wchar_t * dom_u;
int user_l, domain_l;
struct HMACMD5Context ctx; 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, 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); */ 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 */ /* do not think it is supposed to be uppercased */
int user_l = cifs_strtoUCS(user_u, user_n, 511, nls_codepage); user_l = cifs_strtoUCS(user_u, user_n, 511, nls_codepage);
int domain_l = cifs_strtoUCS(dom_u, domain_n, 511, nls_codepage); domain_l = cifs_strtoUCS(dom_u, domain_n, 511, nls_codepage);
user_l++; /* trailing null */ user_l++; /* trailing null */
domain_l++; domain_l++;
...@@ -234,6 +241,7 @@ ntv2_owf_gen(const unsigned char owf[16], const char *user_n, ...@@ -234,6 +241,7 @@ ntv2_owf_gen(const unsigned char owf[16], const char *user_n,
dump_data(100, owf, 16); dump_data(100, owf, 16);
dump_data(100, kr_buf, 16); dump_data(100, kr_buf, 16);
#endif #endif
kfree(user_u);
} }
/* Does the des encryption from the NT or LM MD4 hash. */ /* Does the des encryption from the NT or LM MD4 hash. */
......
...@@ -59,11 +59,11 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses) ...@@ -59,11 +59,11 @@ AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
temp->tsk = current; temp->tsk = current;
} }
if (ses->status == CifsGood) { if (ses->status == 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 { /* BB add reconnect code here BB */
cERROR(1, cERROR(1,
...@@ -97,8 +97,8 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer, ...@@ -97,8 +97,8 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
struct iovec iov; struct iovec iov;
mm_segment_t temp_fs; mm_segment_t temp_fs;
if(ssocket == NULL) if(ssocket == NULL)
return -ENOTSOCK; /* BB eventually add reconnect code here */ return -ENOTSOCK; /* BB eventually add reconnect code here */
/* ssocket->sk->allocation = GFP_BUFFER; *//* BB is this spurious? */ /* ssocket->sk->allocation = GFP_BUFFER; *//* BB is this spurious? */
iov.iov_base = smb_buffer; iov.iov_base = smb_buffer;
iov.iov_len = smb_buf_length + 4; iov.iov_len = smb_buf_length + 4;
...@@ -163,8 +163,6 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, ...@@ -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, rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
(struct sockaddr *) &(ses->server->sockAddr)); (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 */ if (long_op > 1) /* writes past end of file can take a looooooong time */
timeout = 300 * HZ; timeout = 300 * HZ;
else if (long_op == 1) else if (long_op == 1)
...@@ -178,10 +176,9 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, ...@@ -178,10 +176,9 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
/* Replace above line with wait_event to get rid of sleep_on per lk guidelines */ /* 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 & midState & MID_RESPONSE_RECEIVED,
MID_RESPONSE_RECEIVED, timeout);
15 * HZ);
cFYI(1, cFYI(1,
(" with timeout %ld and Out_buf: %p midQ->resp_buf: %p ", timeout, (" with timeout %ld and Out_buf: %p midQ->resp_buf: %p ", timeout,
out_buf, midQ->resp_buf)); out_buf, midQ->resp_buf));
...@@ -244,6 +241,8 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, ...@@ -244,6 +241,8 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
rc = -EIO; 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; 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