bk://cifs.bkbits.net/linux-2.5cifs stevef@smfhome1.smfdom|ChangeSet|20040614060758|24934 stevef # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/06/14 01:07:58-05:00 stevef@smfhome1.smfdom # fix listxattr error path # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/xattr.c # 2004/06/14 01:07:52-05:00 stevef@smfhome1.smfdom +1 -1 # fix listxattr error path # # fs/cifs/cifspdu.h # 2004/06/14 01:07:52-05:00 stevef@smfhome1.smfdom +5 -4 # cleanup EA structure field names # # fs/cifs/cifs_debug.c # 2004/06/14 01:07:52-05:00 stevef@smfhome1.smfdom +5 -5 # Cleanup cifs stats proc display # # fs/cifs/README # 2004/06/14 01:07:52-05:00 stevef@smfhome1.smfdom +7 -4 # Update cifs readme # # fs/cifs/CHANGES # 2004/06/14 01:07:52-05:00 stevef@smfhome1.smfdom +4 -1 # Update cifs readme for 1.18a # # ChangeSet # 2004/06/14 01:04:43-05:00 stevef@smfhome1.smfdom # do not filemap_fdatawrite when reconnecting in write to avoid potential deadlock # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/file.c # 2004/06/14 01:04:37-05:00 stevef@smfhome1.smfdom +25 -13 # do not filemap_fdatawrite when reconnecting in write to avoid potential deadlock # # fs/cifs/connect.c # 2004/06/14 01:04:37-05:00 stevef@smfhome1.smfdom +1 -1 # fix compiler warning # # ChangeSet # 2004/06/13 21:10:19-05:00 stevef@smfhome.smfdom # lock session when reconnecting so we do not oops in retrying sendmsg # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/transport.c # 2004/06/13 21:10:12-05:00 stevef@smfhome.smfdom +20 -1 # better handle errors on send_msg and do not retry forever if socket stuck # # fs/cifs/connect.c # 2004/06/13 21:10:11-05:00 stevef@smfhome.smfdom +3 -2 # lock session when reconnecting so we do not oops in retrying sendmsg # # ChangeSet # 2004/06/13 11:11:30-07:00 akpm@bix.(none) # Merge bk://cifs.bkbits.net/linux-2.5cifs # into bix.(none):/usr/src/bk-cifs # # fs/cifs/cifssmb.c # 2004/06/13 11:11:26-07:00 akpm@bix.(none) +0 -0 # Auto merged # # fs/cifs/cifsfs.c # 2004/06/13 11:11:26-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/06/12 19:12:17-05:00 stevef@smfhome.smfdom # remove compile warning # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/xattr.c # 2004/06/12 19:12:10-05:00 stevef@smfhome.smfdom +1 -1 # remove compile warning # # ChangeSet # 2004/06/12 15:35:12-05:00 stevef@smfhome.smfdom # Extended Attributes part 1 # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/xattr.c # 2004/06/12 15:34:57-05:00 stevef@smfhome.smfdom +41 -10 # Extended Attributes part 1 # # fs/cifs/cifssmb.c # 2004/06/12 15:34:57-05:00 stevef@smfhome.smfdom +87 -0 # Extended Attributes part 1 # # fs/cifs/cifsproto.h # 2004/06/12 15:34:57-05:00 stevef@smfhome.smfdom +4 -0 # add missing SMB Extended Attribute prototype # # fs/cifs/TODO # 2004/06/12 15:34:57-05:00 stevef@smfhome.smfdom +1 -15 # update cifs todo list # # ChangeSet # 2004/06/11 18:15:21-05:00 stevef@stevef95.austin.ibm.com # Add missing EA info levels # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/cifspdu.h # 2004/06/11 18:15:11-05:00 stevef@stevef95.austin.ibm.com +3 -0 # Add missing EA info levels # # ChangeSet # 2004/06/11 14:00:42-05:00 stevef@smfhome1.smfdom # Handle rename of hardlinked files properly (treat as a noop) # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/inode.c # 2004/06/11 14:00:35-05:00 stevef@smfhome1.smfdom +32 -3 # Handle rename of hardlinked files properly (treat as a noop) # # fs/cifs/cifsfs.h # 2004/06/11 14:00:35-05:00 stevef@smfhome1.smfdom +1 -1 # update cifs vfs module version to 1.18 # # fs/cifs/cifs_debug.c # 2004/06/11 14:00:35-05:00 stevef@smfhome1.smfdom +1 -1 # trim debug text for cifs stats # # fs/cifs/CHANGES # 2004/06/11 14:00:35-05:00 stevef@smfhome1.smfdom +5 -0 # Update cifs change log for 1.18 # # ChangeSet # 2004/06/11 12:32:03-05:00 stevef@smfhome.smfdom # flush write behind cached data, for files reopened after session reconnection after session drop # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/file.c # 2004/06/11 12:31:56-05:00 stevef@smfhome.smfdom +20 -11 # flush write data, for files reopened after session reconnection after session drop # # ChangeSet # 2004/06/10 19:19:19-05:00 stevef@smfhome.smfdom # Fix sparse tool compile warnings for cifs # # Signed-off-by: Steve French (sfrench@us.ibm.com> # # fs/cifs/link.c # 2004/06/10 19:19:12-05:00 stevef@smfhome.smfdom +1 -1 # remove sparse tool compile warnings # # fs/cifs/connect.c # 2004/06/10 19:19:12-05:00 stevef@smfhome.smfdom +6 -6 # remove sparse tool compile warnings # # fs/cifs/cifsfs.h # 2004/06/10 19:19:12-05:00 stevef@smfhome.smfdom +1 -1 # remove sparse tool compile warnings # # fs/cifs/cifsfs.c # 2004/06/10 19:19:12-05:00 stevef@smfhome.smfdom +2 -2 # remove sparse tool compile warnings # # fs/cifs/cifs_debug.c # 2004/06/10 19:19:12-05:00 stevef@smfhome.smfdom +10 -10 # remove sparse tool compile warnings # # ChangeSet # 2004/06/07 14:00:04-07:00 akpm@bix.(none) # Merge bk://cifs.bkbits.net/linux-2.5cifs # into bix.(none):/usr/src/bk-cifs # # fs/cifs/cifssmb.c # 2004/06/07 14:00:00-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/06/02 13:18:48-07:00 akpm@bix.(none) # Merge bk://cifs.bkbits.net/linux-2.5cifs # into bix.(none):/usr/src/bk-cifs # # fs/cifs/cifssmb.c # 2004/06/02 13:18:44-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/27 21:24:47-07:00 akpm@bix.(none) # Merge bk://cifs.bkbits.net/linux-2.5cifs # into bix.(none):/usr/src/bk-cifs # # fs/cifs/cifssmb.c # 2004/05/27 21:24:44-07:00 akpm@bix.(none) +0 -0 # Auto merged # # fs/cifs/cifsfs.c # 2004/05/27 21:24:43-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/27 12:36:56-07:00 akpm@bix.(none) # Merge bk://cifs.bkbits.net/linux-2.5cifs # into bix.(none):/usr/src/bk-cifs # # fs/cifs/cifssmb.c # 2004/05/27 12:36:53-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/25 21:18:56-07:00 akpm@bix.(none) # Merge bk://cifs.bkbits.net/linux-2.5cifs # into bix.(none):/usr/src/bk-cifs # # fs/cifs/cifssmb.c # 2004/05/25 21:18:53-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/24 18:04:01-07:00 akpm@bix.(none) # Merge bk://cifs.bkbits.net/linux-2.5cifs # into bix.(none):/usr/src/bk-cifs # # fs/cifs/cifssmb.c # 2004/05/24 18:03:57-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/22 23:28:34-07:00 akpm@bix.(none) # Merge bk://cifs.bkbits.net/linux-2.5cifs # into bix.(none):/usr/src/bk-cifs # # fs/cifs/cifssmb.c # 2004/05/22 23:28:31-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/18 14:31:25-07:00 akpm@bix.(none) # Merge bk://cifs.bkbits.net/linux-2.5cifs # into bix.(none):/usr/src/bk-cifs # # fs/cifs/cifsfs.c # 2004/05/18 14:31:22-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/11 16:37:09-07:00 akpm@bix.(none) # Merge bk://cifs.bkbits.net/linux-2.5cifs # into bix.(none):/usr/src/bk-cifs # # fs/cifs/cifssmb.c # 2004/05/11 16:37:06-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/04 13:51:19-07:00 akpm@bix.(none) # Merge bk://cifs.bkbits.net/linux-2.5cifs # into bix.(none):/usr/src/bk-cifs # # fs/cifs/cifssmb.c # 2004/05/04 13:51:17-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/02 21:56:11-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-cifs # # fs/cifs/cifssmb.c # 2004/05/02 21:56:09-07:00 akpm@bix.(none) +0 -0 # Auto merged # # fs/cifs/cifsfs.c # 2004/05/02 21:56:08-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/05/01 15:05:17-07:00 akpm@bix.(none) # Merge bk://cifs.bkbits.net/linux-2.5cifs # into bix.(none):/usr/src/bk-cifs # # fs/cifs/cifssmb.c # 2004/05/01 15:05:14-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/29 15:41:50-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-cifs # # fs/cifs/cifssmb.c # 2004/04/29 15:41:48-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/26 18:11:55-07:00 akpm@bix.(none) # Merge bk://cifs.bkbits.net/linux-2.5cifs # into bix.(none):/usr/src/bk-cifs # # fs/cifs/cifsfs.c # 2004/04/26 18:11:52-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/23 12:36:52-07:00 akpm@bix.(none) # Merge bk://cifs.bkbits.net/linux-2.5cifs # into bix.(none):/usr/src/bk-cifs # # fs/cifs/cifsfs.c # 2004/04/23 12:36:49-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/19 19:23:58-07:00 akpm@bix.(none) # Merge bk://cifs.bkbits.net/linux-2.5cifs # into bix.(none):/usr/src/bk-cifs # # fs/cifs/cifsfs.c # 2004/04/19 19:23:56-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/16 20:19:53-07:00 akpm@bix.(none) # Merge bk://cifs.bkbits.net/linux-2.5cifs # into bix.(none):/usr/src/bk-cifs # # fs/cifs/cifsfs.c # 2004/04/16 20:19:51-07:00 akpm@bix.(none) +0 -0 # Auto merged # # ChangeSet # 2004/04/16 20:18:59-07:00 akpm@bix.(none) # Merge bix.(none):/usr/src/bk25 into bix.(none):/usr/src/bk-cifs # # fs/cifs/cifsfs.c # 2004/04/16 20:18:56-07:00 akpm@bix.(none) +0 -0 # Auto merged # diff -Nru a/fs/cifs/CHANGES b/fs/cifs/CHANGES --- a/fs/cifs/CHANGES 2004-06-13 23:47:43 -07:00 +++ b/fs/cifs/CHANGES 2004-06-13 23:47:43 -07:00 @@ -1,3 +1,11 @@ +Version 1.18 +------------ +Do not rename hardlinked files (since that should be a noop). Flush +cached write behind data when reopening a file after session abend, +except when already in write. Grab per socket sem during reconnect +to avoid oops in sendmsg if overlapping with reconnect. + + Version 1.17 ------------ Update number of blocks in file so du command is happier (in Linux a fake diff -Nru a/fs/cifs/README b/fs/cifs/README --- a/fs/cifs/README 2004-06-13 23:47:43 -07:00 +++ b/fs/cifs/README 2004-06-13 23:47:43 -07:00 @@ -97,7 +97,9 @@ case sensitive = yes delete readonly = yes - + ea support = yes + +Note that ea support is required for supporting Linux xattrs. Some administrators also change the "map archive" and the "create mask" parameters from their default values. Creating special devices (mknod) remotely may require specifying a mkdev function to Samba. For more information on these @@ -268,11 +270,12 @@ ======================================= Informational pseudo-files: DebugData Displays information about active CIFS sessions - as well as per share statistics (if CONFIG_CIFS_STATS - is enabled in the kernel configuration). + and shares. SimultaneousOps Counter which holds maximum number of simultaneous outstanding SMB/CIFS requests. -Stats Lists summary resource usage information +Stats Lists summary resource usage information as well as per + share statistics, if CONFIG_CIFS_STATS in enabled + in the kernel configuration. Configuration pseudo-files: MultiuserMount If set to one, more than one CIFS session to diff -Nru a/fs/cifs/TODO b/fs/cifs/TODO --- a/fs/cifs/TODO 2004-06-13 23:47:43 -07:00 +++ b/fs/cifs/TODO 2004-06-13 23:47:43 -07:00 @@ -80,27 +80,13 @@ but recognizes them 3) create of new files to FAT partitions on Windows servers can succeed but still return access denied (appears to be Windows -not client problem) and has not been reproduced recently. +server not cifs client problem) and has not been reproduced recently. NTFS partitions do not have this problem. 4) debug connectation lock test case 10 which fails against Samba (may be unmappable due to POSIX to Windows lock model differences but worth investigating). Also debug Samba to see why lock test case 7 takes longer to complete to Samba than to Windows. -5) prepare_write does not initialize pages properly when partial -page writes begin in the middle of a page (pages can get zeroed). -6) Write caching done incorrectly when files are only opened -with write permission by the application. -7) Rename of files that are hardlinked does not work correctly e.g. - ln source target - mv source target -This should be no op since files are linked but in cifs it causes -the source file to go away. This may require implementation of -the cifs POSIX extensions (Unix Extensions version 2) for -it to be done correctly since Samba is failing the rename, -(rather than ignoring it) so the client not knowing they -are linked proceeds to delete the target and then retry the -move which succeeds this time (but the source is gone). Misc testing to do ================== diff -Nru a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c --- a/fs/cifs/cifs_debug.c 2004-06-13 23:47:43 -07:00 +++ b/fs/cifs/cifs_debug.c 2004-06-13 23:47:43 -07:00 @@ -190,26 +190,26 @@ struct cifsTconInfo *tcon; length = sprintf(buf, - "Currently Allocated structures\nCIFS Sessions: %d\n", + "Resources in use\nCIFS Session: %d\n", sesInfoAllocCount.counter); buf += length; item_length = - sprintf(buf,"Shares (unique mount targets): %d\n", + sprintf(buf,"Share (unique mount targets): %d\n", tconInfoAllocCount.counter); length += item_length; buf += item_length; item_length = - sprintf(buf,"Allocated SMB Request/Response Buffers: %d\n", + sprintf(buf,"SMB Request/Response Buffer: %d\n", bufAllocCount.counter); length += item_length; buf += item_length; item_length = - sprintf(buf,"Active Operations (MIDs in use): %d\n", + sprintf(buf,"Operations (MIDs): %d\n", midCount.counter); length += item_length; buf += item_length; item_length = sprintf(buf, - "%d sessions and %d shares reconnected after failure\n", + "\n%d session %d share reconnects\n", tcpSesReconnectCount.counter,tconInfoReconnectCount.counter); length += item_length; buf += item_length; @@ -400,7 +400,7 @@ return len; } static int -cifsFYI_write(struct file *file, const char *buffer, +cifsFYI_write(struct file *file, const char __user *buffer, unsigned long count, void *data) { char c; @@ -439,7 +439,7 @@ return len; } static int -oplockEnabled_write(struct file *file, const char *buffer, +oplockEnabled_write(struct file *file, const char __user *buffer, unsigned long count, void *data) { char c; @@ -479,7 +479,7 @@ return len; } static int -quotaEnabled_write(struct file *file, const char *buffer, +quotaEnabled_write(struct file *file, const char __user *buffer, unsigned long count, void *data) { char c; @@ -519,7 +519,7 @@ return len; } static int -linuxExtensionsEnabled_write(struct file *file, const char *buffer, +linuxExtensionsEnabled_write(struct file *file, const char __user *buffer, unsigned long count, void *data) { char c; @@ -559,7 +559,7 @@ return len; } static int -lookupFlag_write(struct file *file, const char *buffer, +lookupFlag_write(struct file *file, const char __user *buffer, unsigned long count, void *data) { char c; @@ -597,7 +597,7 @@ return len; } static int -traceSMB_write(struct file *file, const char *buffer, +traceSMB_write(struct file *file, const char __user *buffer, unsigned long count, void *data) { char c; @@ -636,7 +636,7 @@ return len; } static int -multiuser_mount_write(struct file *file, const char *buffer, +multiuser_mount_write(struct file *file, const char __user *buffer, unsigned long count, void *data) { char c; @@ -675,7 +675,7 @@ return len; } static int -extended_security_write(struct file *file, const char *buffer, +extended_security_write(struct file *file, const char __user *buffer, unsigned long count, void *data) { char c; @@ -714,7 +714,7 @@ return len; } static int -ntlmv2_enabled_write(struct file *file, const char *buffer, +ntlmv2_enabled_write(struct file *file, const char __user *buffer, unsigned long count, void *data) { char c; @@ -753,7 +753,7 @@ return len; } static int -packet_signing_enabled_write(struct file *file, const char *buffer, +packet_signing_enabled_write(struct file *file, const char __user *buffer, unsigned long count, void *data) { char c; diff -Nru a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c --- a/fs/cifs/cifsfs.c 2004-06-13 23:47:43 -07:00 +++ b/fs/cifs/cifsfs.c 2004-06-13 23:47:43 -07:00 @@ -426,7 +426,7 @@ } static ssize_t -cifs_read_wrapper(struct file * file, char *read_data, size_t read_size, +cifs_read_wrapper(struct file * file, char __user *read_data, size_t read_size, loff_t * poffset) { if(file == NULL) @@ -455,7 +455,7 @@ } static ssize_t -cifs_write_wrapper(struct file * file, const char *write_data, +cifs_write_wrapper(struct file * file, const char __user *write_data, size_t write_size, loff_t * poffset) { ssize_t written; diff -Nru a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h --- a/fs/cifs/cifsfs.h 2004-06-13 23:47:43 -07:00 +++ b/fs/cifs/cifsfs.h 2004-06-13 23:47:43 -07:00 @@ -85,7 +85,7 @@ /* Functions related to symlinks */ extern int cifs_follow_link(struct dentry *direntry, struct nameidata *nd); -extern int cifs_readlink(struct dentry *direntry, char *buffer, int buflen); +extern int cifs_readlink(struct dentry *direntry, char __user *buffer, int buflen); extern int cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname); extern int cifs_removexattr(struct dentry *, const char *); @@ -93,5 +93,5 @@ size_t, int); extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); -#define CIFS_VERSION "1.17" +#define CIFS_VERSION "1.18" #endif /* _CIFSFS_H */ diff -Nru a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h --- a/fs/cifs/cifspdu.h 2004-06-13 23:47:43 -07:00 +++ b/fs/cifs/cifspdu.h 2004-06-13 23:47:43 -07:00 @@ -1046,9 +1046,12 @@ /* PathInfo/FileInfo infolevels */ #define SMB_INFO_STANDARD 1 +#define SMB_INFO_QUERY_EAS_FROM_LIST 3 +#define SMB_INFO_QUERY_ALL_EAS 4 #define SMB_INFO_IS_NAME_VALID 6 #define SMB_QUERY_FILE_BASIC_INFO 0x101 #define SMB_QUERY_FILE_STANDARD_INFO 0x102 +#define SMB_QUERY_FILE_EA_INFO 0x103 #define SMB_QUERY_FILE_NAME_INFO 0x104 #define SMB_QUERY_FILE_ALLOCATION_INFO 0x105 #define SMB_QUERY_FILE_END_OF_FILEINFO 0x106 @@ -1687,16 +1690,17 @@ }; struct fea { - unsigned char fEA; - unsigned char cbName; - unsigned short cbValue; + unsigned char EA_flags; + __u8 name_len; + __u16 value_len; char szName[1]; + /* optionally followed by value */ }; /* flags for _FEA.fEA */ #define FEA_NEEDEA 0x80 /* need EA bit */ struct fealist { - unsigned long cbList; + unsigned long list_len; struct fea list[1]; }; diff -Nru a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h --- a/fs/cifs/cifsproto.h 2004-06-13 23:47:43 -07:00 +++ b/fs/cifs/cifsproto.h 2004-06-13 23:47:43 -07:00 @@ -247,4 +247,8 @@ extern int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, const int notify_subdirs,const __u16 netfid,__u32 filter, const struct nls_table *nls_codepage); +extern int CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, + const unsigned char *searchName, + char * EAData, size_t size, + const struct nls_table *nls_codepage); #endif /* _CIFSPROTO_H */ diff -Nru a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c --- a/fs/cifs/cifssmb.c 2004-06-13 23:47:43 -07:00 +++ b/fs/cifs/cifssmb.c 2004-06-13 23:47:43 -07:00 @@ -1596,6 +1596,8 @@ } else { /* decode response */ pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset); /* BB also check enough total bytes returned */ + /* BB we need to improve the validity checking + of these trans2 responses */ if ((pSMBr->ByteCount < 40) || (pSMBr->DataOffset > 512)) rc = -EIO; /* bad smb */ else if (pFindData){ @@ -2879,3 +2881,88 @@ goto NotifyRetry; */ return rc; } +#ifdef CONFIG_CIFS_XATTR +int +CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon, + const unsigned char *searchName, + char * EAData, size_t size, + const struct nls_table *nls_codepage) +{ + /* BB assumes one setup word */ + TRANSACTION2_QPI_REQ *pSMB = NULL; + TRANSACTION2_QPI_RSP *pSMBr = NULL; + int rc = 0; + int bytes_returned; + int name_len; + + cFYI(1, ("In Query All EAs path %s", searchName)); +QAllEAsRetry: + rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, + (void **) &pSMBr); + if (rc) + return rc; + + if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { + name_len = + cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, 530 + /* find define for this maxpathcomponent */ + , nls_codepage); + name_len++; /* trailing null */ + name_len *= 2; + } else { /* BB improve the check for buffer overruns BB */ + name_len = strnlen(searchName, 530); + name_len++; /* trailing null */ + strncpy(pSMB->FileName, searchName, name_len); + } + + pSMB->TotalParameterCount = 2 /* level */ + 4 /* reserved */ + + name_len /* includes null */ ; + pSMB->TotalDataCount = 0; + pSMB->MaxParameterCount = cpu_to_le16(2); + pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */ + pSMB->MaxSetupCount = 0; + pSMB->Reserved = 0; + pSMB->Flags = 0; + pSMB->Timeout = 0; + pSMB->Reserved2 = 0; + pSMB->ParameterOffset = cpu_to_le16(offsetof( + struct smb_com_transaction2_qpi_req ,InformationLevel) - 4); + pSMB->DataCount = 0; + pSMB->DataOffset = 0; + pSMB->SetupCount = 1; + pSMB->Reserved3 = 0; + pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION); + pSMB->ByteCount = pSMB->TotalParameterCount + 1 /* pad */ ; + pSMB->TotalParameterCount = cpu_to_le16(pSMB->TotalParameterCount); + pSMB->ParameterCount = pSMB->TotalParameterCount; + pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS); + pSMB->Reserved4 = 0; + pSMB->hdr.smb_buf_length += pSMB->ByteCount; + pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount); + + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + (struct smb_hdr *) pSMBr, &bytes_returned, 0); + if (rc) { + cFYI(1, ("Send error in QueryAllEAs = %d", rc)); + } else { /* decode response */ + pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset); + /* BB also check enough total bytes returned */ + /* BB we need to improve the validity checking + of these trans2 responses */ + if ((pSMBr->ByteCount < 4) || (pSMBr->DataOffset > 512)) + rc = -EIO; /* bad smb */ + /* else if (pFindData){ + memcpy((char *) pFindData, + (char *) &pSMBr->hdr.Protocol + + pSMBr->DataOffset, kl); + }*/ else + rc = -ENOMEM; + } + if (pSMB) + cifs_buf_release(pSMB); + if (rc == -EAGAIN) + goto QAllEAsRetry; + + return rc; +} +#endif diff -Nru a/fs/cifs/connect.c b/fs/cifs/connect.c --- a/fs/cifs/connect.c 2004-06-13 23:47:43 -07:00 +++ b/fs/cifs/connect.c 2004-06-13 23:47:43 -07:00 @@ -128,7 +128,8 @@ } } read_unlock(&GlobalSMBSeslock); - + /* do not want to be sending data on a socket we are freeing */ + down(&server->tcpSem); if(server->ssocket) { cFYI(1,("State: 0x%x Flags: 0x%lx", server->ssocket->state, server->ssocket->flags)); @@ -154,7 +155,7 @@ } } spin_unlock(&GlobalMid_Lock); - + up(&server->tcpSem); while ((server->tcpStatus != CifsExiting) && (server->tcpStatus != CifsGood)) { @@ -279,7 +280,7 @@ length = sock_recvmsg(csocket, &smb_msg, 4, 0); cFYI(0,("Received 4 byte keep alive packet")); } else if (temp[0] == (char) RFC1002_POSITIVE_SESSION_RESPONSE) { - iov.iov_base = smb_buffer; + iov.iov_base = smb_buffer; iov.iov_len = 4; length = sock_recvmsg(csocket, &smb_msg, 4, 0); cFYI(1,("Good RFC 1002 session rsp")); @@ -1559,7 +1560,7 @@ bcc_ptr += pSMBr->resp.SecurityBlobLength; - if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) { + if (smb_buffer->Flags2 & SMBFLG2_UNICODE) { if ((long) (bcc_ptr) % 2) { remaining_words = (BCC(smb_buffer_response) @@ -1812,7 +1813,7 @@ pSMBr->resp.SecurityBlobLength)); } - if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) { + if (smb_buffer->Flags2 & SMBFLG2_UNICODE) { if ((long) (bcc_ptr) % 2) { remaining_words = (BCC(smb_buffer_response) @@ -2123,7 +2124,7 @@ ses->server->secMode |= SECMODE_SIGN_ENABLED; - if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) { + if (smb_buffer->Flags2 & SMBFLG2_UNICODE) { if ((long) (bcc_ptr) % 2) { remaining_words = (BCC(smb_buffer_response) @@ -2519,7 +2520,7 @@ cFYI(1, ("NTLMSSP response to Authenticate ")); - if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) { + if (smb_buffer->Flags2 & SMBFLG2_UNICODE) { if ((long) (bcc_ptr) % 2) { remaining_words = (BCC(smb_buffer_response) @@ -2718,7 +2719,7 @@ /* skip service field (NB: this field is always ASCII) */ bcc_ptr += length + 1; strncpy(tcon->treeName, tree, MAX_TREE_SIZE); - if (smb_buffer->Flags2 &= SMBFLG2_UNICODE) { + if (smb_buffer->Flags2 & SMBFLG2_UNICODE) { length = UniStrnlen((wchar_t *) bcc_ptr, 512); if (((long) bcc_ptr + (2 * length)) - (long) pByteArea(smb_buffer_response) <= diff -Nru a/fs/cifs/file.c b/fs/cifs/file.c --- a/fs/cifs/file.c 2004-06-13 23:47:43 -07:00 +++ b/fs/cifs/file.c 2004-06-13 23:47:43 -07:00 @@ -143,6 +143,10 @@ /* Also refresh inode by passing in file_info buf returned by SMBOpen and calling get_inode_info with returned buf (at least helps non-Unix server case */ + + /* BB we can not do this if this is the second open of a file + and the first handle has writebehind data, we might be + able to simply do a filemap_fdatawrite/filemap_fdatawait first */ buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL); if(buf==0) { if (full_path) @@ -263,7 +267,7 @@ return rc; } -static int cifs_reopen_file(struct inode *inode, struct file *file) +static int cifs_reopen_file(struct inode *inode, struct file *file, int can_flush) { int rc = -EACCES; int xid, oplock; @@ -275,7 +279,6 @@ int desiredAccess = 0x20197; int disposition = FILE_OPEN; __u16 netfid; - FILE_ALL_INFO * buf = NULL; if(inode == NULL) return -EBADF; @@ -328,21 +331,23 @@ else oplock = FALSE; - /* BB pass O_SYNC flag through on file attributes .. BB */ + + /* Can not refresh inode by passing in file_info buf to be returned + by SMBOpen and then calling get_inode_info with returned buf + since file might have write behind data that needs to be flushed + and server version of file size can be stale. If we + knew for sure that inode was not dirty locally we could do this */ - /* Also refresh inode by passing in file_info buf returned by SMBOpen - and calling get_inode_info with returned buf (at least - helps non-Unix server case */ - buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL); +/* buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL); if(buf==0) { up(&pCifsFile->fh_sem); if (full_path) kfree(full_path); FreeXid(xid); return -ENOMEM; - } + }*/ rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess, - CREATE_NOT_DIR, &netfid, &oplock, buf, cifs_sb->local_nls); + CREATE_NOT_DIR, &netfid, &oplock, NULL, cifs_sb->local_nls); if (rc) { up(&pCifsFile->fh_sem); cFYI(1, ("cifs_open returned 0x%x ", rc)); @@ -353,13 +358,25 @@ up(&pCifsFile->fh_sem); pCifsInode = CIFS_I(inode); if(pCifsInode) { - if (pTcon->ses->capabilities & CAP_UNIX) - rc = cifs_get_inode_info_unix(&inode, + if(can_flush) { + filemap_fdatawrite(inode->i_mapping); + filemap_fdatawait(inode->i_mapping); + /* temporarily disable caching while we + go to server to get inode info */ + pCifsInode->clientCanCacheAll = FALSE; + pCifsInode->clientCanCacheRead = FALSE; + if (pTcon->ses->capabilities & CAP_UNIX) + rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb); - else - rc = cifs_get_inode_info(&inode, - full_path, buf, inode->i_sb); - + else + rc = cifs_get_inode_info(&inode, + full_path, NULL, inode->i_sb); + } /* else we are writing out data to server already + and could deadlock if we tried to flush data, and + since we do not know if we have data that would + invalidate the current end of file on the server + we can not go to the server to get the new + inod info */ if((oplock & 0xF) == OPLOCK_EXCLUSIVE) { pCifsInode->clientCanCacheAll = TRUE; pCifsInode->clientCanCacheRead = TRUE; @@ -375,8 +392,6 @@ } } - if (buf) - kfree(buf); if (full_path) kfree(full_path); FreeXid(xid); @@ -612,7 +627,11 @@ FreeXid(xid); return total_written; } - rc = cifs_reopen_file(file->f_dentry->d_inode,file); + /* we could deadlock if we called + filemap_fdatawait from here so tell + reopen_file not to flush data to server now */ + rc = cifs_reopen_file(file->f_dentry->d_inode, + file,FALSE); if(rc != 0) break; } @@ -968,7 +987,8 @@ rc = -EAGAIN; while(rc == -EAGAIN) { if ((open_file->invalidHandle) && (!open_file->closePend)) { - rc = cifs_reopen_file(file->f_dentry->d_inode,file); + rc = cifs_reopen_file(file->f_dentry->d_inode, + file,TRUE); if(rc != 0) break; } @@ -1123,7 +1143,8 @@ rc = -EAGAIN; while(rc == -EAGAIN) { if ((open_file->invalidHandle) && (!open_file->closePend)) { - rc = cifs_reopen_file(file->f_dentry->d_inode,file); + rc = cifs_reopen_file(file->f_dentry->d_inode, + file, TRUE); if(rc != 0) break; } diff -Nru a/fs/cifs/inode.c b/fs/cifs/inode.c --- a/fs/cifs/inode.c 2004-06-13 23:47:43 -07:00 +++ b/fs/cifs/inode.c 2004-06-13 23:47:43 -07:00 @@ -568,9 +568,38 @@ rc = CIFSSMBRename(xid, pTcon, fromName, toName, cifs_sb_source->local_nls); if(rc == -EEXIST) { - cifs_unlink(target_inode, target_direntry); - rc = CIFSSMBRename(xid, pTcon, fromName, toName, - cifs_sb_source->local_nls); + /* check if they are the same file + because rename of hardlinked files is a noop */ + FILE_UNIX_BASIC_INFO * info_buf_source; + FILE_UNIX_BASIC_INFO * info_buf_target; + + info_buf_source = + kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO),GFP_KERNEL); + if(info_buf_source != NULL) { + info_buf_target = info_buf_source+1; + rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName, + info_buf_source, cifs_sb_source->local_nls); + if(rc == 0) { + rc = CIFSSMBUnixQPathInfo(xid,pTcon,toName, + info_buf_target, + cifs_sb_target->local_nls); + } + if((rc == 0) && + (info_buf_source->UniqueId == + info_buf_target->UniqueId)) { + /* do not rename since the files are hardlinked + which is a noop */ + } else { + /* we either can not tell the files are hardlinked + (as with Windows servers) or files are not hardlinked + so delete the target manually before renaming to + follow POSIX rather than Windows semantics */ + cifs_unlink(target_inode, target_direntry); + rc = CIFSSMBRename(xid, pTcon, fromName, toName, + cifs_sb_source->local_nls); + } + kfree(info_buf_source); + } /* if we can not get memory just leave rc as EEXIST */ } if((rc == -EIO)||(rc == -EEXIST)) { diff -Nru a/fs/cifs/link.c b/fs/cifs/link.c --- a/fs/cifs/link.c 2004-06-13 23:47:43 -07:00 +++ b/fs/cifs/link.c 2004-06-13 23:47:43 -07:00 @@ -210,7 +210,7 @@ } int -cifs_readlink(struct dentry *direntry, char *pBuffer, int buflen) +cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen) { struct inode *inode = direntry->d_inode; int rc = -EACCES; diff -Nru a/fs/cifs/transport.c b/fs/cifs/transport.c --- a/fs/cifs/transport.c 2004-06-13 23:47:43 -07:00 +++ b/fs/cifs/transport.c 2004-06-13 23:47:43 -07:00 @@ -120,6 +120,7 @@ unsigned int smb_buf_length, struct sockaddr *sin) { int rc = 0; + int i = 0; struct msghdr smb_msg; struct iovec iov; mm_segment_t temp_fs; @@ -151,6 +152,14 @@ while(iov.iov_len > 0) { rc = sock_sendmsg(ssocket, &smb_msg, smb_buf_length + 4); if ((rc == -ENOSPC) || (rc == -EAGAIN)) { + i++; + if(i > 60) { + cERROR(1, + ("sends on sock %p stuck for 30 seconds", + ssocket)); + rc = -EAGAIN; + break; + } set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ/2); continue; @@ -259,7 +268,17 @@ midQ->midState = MID_REQUEST_SUBMITTED; rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length, (struct sockaddr *) &(ses->server->addr.sockAddr)); - up(&ses->server->tcpSem); + if(rc < 0) { + DeleteMidQEntry(midQ); + up(&ses->server->tcpSem); + /* If not lock req, update # of requests on wire to server */ + if(long_op < 3) { + atomic_dec(&ses->server->inFlight); + wake_up(&ses->server->request_q); + } + return rc; + } else + up(&ses->server->tcpSem); if (long_op == -1) goto cifs_no_response_exit; else if (long_op == 2) /* writes past end of file can take looooong time */ diff -Nru a/fs/cifs/xattr.c b/fs/cifs/xattr.c --- a/fs/cifs/xattr.c 2004-06-13 23:47:43 -07:00 +++ b/fs/cifs/xattr.c 2004-06-13 23:47:43 -07:00 @@ -20,37 +20,68 @@ */ #include +#include "cifsfs.h" +#include "cifspdu.h" +#include "cifsglob.h" +#include "cifsproto.h" +#include "cifs_debug.h" int cifs_removexattr(struct dentry * direntry, const char * name) { - int rc = -EOPNOTSUPP; - return rc; + int rc = -EOPNOTSUPP; + return rc; } int cifs_setxattr(struct dentry * direntry, const char * name, const void * value, size_t size, int flags) { - int rc = -EOPNOTSUPP; - return rc; + int rc = -EOPNOTSUPP; + return rc; } ssize_t cifs_getxattr(struct dentry * direntry, const char * name, void * value, size_t size) { - ssize_t rc = -EOPNOTSUPP; - return rc; + ssize_t rc = -EOPNOTSUPP; + return rc; } ssize_t cifs_listxattr(struct dentry * direntry, char * ea_data, size_t ea_size) { - ssize_t rc = -EOPNOTSUPP; - + ssize_t rc = -EOPNOTSUPP; +#ifdef CONFIG_CIFS_XATTR + int xid; + struct cifs_sb_info *cifs_sb; + struct cifsTconInfo *pTcon; + struct super_block * sb; + char * full_path; + if(direntry == NULL) + return -EIO; + if(direntry->d_inode == NULL) + return -EIO; + sb = direntry->d_inode->i_sb; + if(sb == NULL) + return -EIO; + xid = GetXid(); + + cifs_sb = CIFS_SB(sb); + pTcon = cifs_sb->tcon; + + down(&sb->s_vfs_rename_sem); + full_path = build_path_from_dentry(direntry); + up(&sb->s_vfs_rename_sem); + if(full_path == NULL) { + FreeXid(xid); + return -ENOMEM; + } /* return dosattributes as pseudo xattr */ /* return alt name if available as pseudo attr */ /* if proc/fs/cifs/streamstoxattr is set then search server for EAs or streams to returns as xattrs */ - - return rc; + rc = CIFSSMBQAllEAs(xid,pTcon,full_path,ea_data,ea_size,cifs_sb->local_nls); + FreeXid(xid); +#endif + return rc; }