# This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2005/03/07 21:15:17-06:00 stevef@smfhome.smfdom # Merge bk://cifs.bkbits.net/linux-2.5cifs # into smfhome.smfdom:/home/stevef/bk_cifs_org/linux-2.5cifs # # fs/cifs/connect.c # 2005/03/07 21:15:04-06:00 stevef@smfhome.smfdom +0 -0 # Auto merged # # ChangeSet # 2005/03/07 18:18:45-06:00 stevef@smf-t23.(none) # [CIFS] recognize nouser_xattr and user_xattr mount options (default is still xattr # enabled if built with xattr support) # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/xattr.c # 2005/03/07 18:18:24-06:00 stevef@smf-t23.(none) +20 -2 # recognize nouser_xattr and user_xattr mount options (default is still xattr # enabled if built with xattr support) # # fs/cifs/connect.c # 2005/03/07 18:18:24-06:00 stevef@smf-t23.(none) +9 -1 # recognize nouser_xattr and user_xattr mount options (default is still xattr # enabled if built with xattr support) # # fs/cifs/cifsfs.h # 2005/03/07 18:18:24-06:00 stevef@smf-t23.(none) +1 -1 # update cifs version to 1.30 # # fs/cifs/cifs_fs_sb.h # 2005/03/07 18:18:24-06:00 stevef@smf-t23.(none) +2 -1 # recognize nouser_xattr and user_xattr mount options (default is still xattr # enabled if built with xattr support) # # fs/cifs/CHANGES # 2005/03/07 18:18:24-06:00 stevef@smf-t23.(none) +4 -0 # allow disabling of user. xattr support on a mount, update change log for 1.30 # # ChangeSet # 2005/03/07 17:12:19-06:00 stevef@smf-t23.(none) # [CIFS] ioctl support part 1 # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/ioctl.c # 2005/03/07 17:11:57-06:00 stevef@smf-t23.(none) +49 -0 # # fs/cifs/ioctl.c # 2005/03/07 17:11:57-06:00 stevef@smf-t23.(none) +0 -0 # BitKeeper file /home/stevef/linux-2.5cifs/fs/cifs/ioctl.c # # ChangeSet # 2005/03/07 00:17:42-06:00 stevef@smf-t23.(none) # [CIFS] cifs ioctl support part 1 # # This is needed for getflags and setflags (chattr) support and the new CIFS # POSIX extensions # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/smbencrypt.c # 2005/03/07 00:17:21-06:00 stevef@smf-t23.(none) +2 -0 # remove sparse warning on function that is not used yet # # fs/cifs/cifsproto.h # 2005/03/07 00:17:21-06:00 stevef@smf-t23.(none) +2 -0 # cifs ioctl part 1 # # fs/cifs/cifspdu.h # 2005/03/07 00:17:21-06:00 stevef@smf-t23.(none) +2 -0 # cifs ioctl part 1 # # fs/cifs/Makefile # 2005/03/07 00:17:21-06:00 stevef@smf-t23.(none) +1 -1 # cifs ioctl part 1 # # ChangeSet # 2005/03/06 17:55:20-06:00 stevef@smf-t23.(none) # [CIFS] replace schedule_timeout with msleep (uninterrutable) in send retry path # when clogged socket # # Signed-off-by: Nishanth Aravamudan # Signed-off-by: Domen Puncer # Signed-off-by: Steve French # # fs/cifs/transport.c # 2005/03/06 17:55:05-06:00 stevef@smf-t23.(none) +3 -4 # replace schedule_timeout with msleep (uninterrutable) in send retry path on clogged socket # # ChangeSet # 2005/03/06 17:08:39-06:00 stevef@smf-t23.(none) # [CIFS] remove sparse warnings - moving externs & making more functions static # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/transport.c # 2005/03/06 17:04:28-06:00 stevef@smf-t23.(none) +2 -2 # remove sparse warnings - changing externs and make more functions static # # fs/cifs/smbencrypt.c # 2005/03/06 17:04:28-06:00 stevef@smf-t23.(none) +1 -1 # remove sparse warnings - changing externs and make more functions static # # fs/cifs/readdir.c # 2005/03/06 17:04:28-06:00 stevef@smf-t23.(none) +55 -10 # remove sparse warnings - changing externs and make more functions static # # fs/cifs/netmisc.c # 2005/03/06 17:04:28-06:00 stevef@smf-t23.(none) +3 -3 # remove sparse warnings - changing externs and make more functions static # # fs/cifs/misc.c # 2005/03/06 17:04:28-06:00 stevef@smf-t23.(none) +1 -1 # remove sparse warnings - changing externs and make more functions static # # fs/cifs/inode.c # 2005/03/06 17:04:28-06:00 stevef@smf-t23.(none) +0 -2 # remove sparse warnings - changing externs and make more functions static # # fs/cifs/file.c # 2005/03/06 17:04:28-06:00 stevef@smf-t23.(none) +1 -51 # remove sparse warnings - changing externs and make more functions static # # fs/cifs/fcntl.c # 2005/03/06 17:04:28-06:00 stevef@smf-t23.(none) +2 -1 # remove sparse warnings - changing externs and make more functions static # # fs/cifs/connect.c # 2005/03/06 17:04:28-06:00 stevef@smf-t23.(none) +10 -5 # remove sparse warnings - changing externs and make more functions static. fix ntlmv2 error path # # fs/cifs/cifssmb.c # 2005/03/06 17:04:28-06:00 stevef@smf-t23.(none) +4 -220 # remove sparse warnings - changing externs and make more functions static. Remove dead code # # fs/cifs/cifsproto.h # 2005/03/06 17:04:28-06:00 stevef@smf-t23.(none) +13 -15 # remove sparse warnings - changing externs and make more functions static # # fs/cifs/cifsencrypt.c # 2005/03/06 17:04:28-06:00 stevef@smf-t23.(none) +1 -0 # remove sparse warnings - changing externs and make more functions static # # fs/cifs/cifs_debug.c # 2005/03/06 17:04:28-06:00 stevef@smf-t23.(none) +3 -3 # remove sparse warnings - changing externs and make more functions static # # fs/cifs/asn1.c # 2005/03/06 17:04:28-06:00 stevef@smf-t23.(none) +3 -2 # remove sparse warnings - changing externs and make more functions static # # ChangeSet # 2005/02/17 22:52:34-06:00 stevef@smfhome.smfdom # [CIFS] Handle RFC1001 NACK with length of 4 # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/connect.c # 2005/02/17 22:52:25-06:00 stevef@smfhome.smfdom +1 -2 # Handle RFC1001 NACK with length of 4 # # ChangeSet # 2005/01/29 12:21:23-08:00 cifs.adm@bkbits.net # Merge bk://linux.bkbits.net/linux-2.5 # into bkbits.net:/repos/c/cifs/linux-2.5cifs # # fs/cifs/connect.c # 2005/01/29 12:21:17-08:00 cifs.adm@bkbits.net +0 -0 # Auto merged # # ChangeSet # 2005/01/26 17:30:51-06:00 stevef@stevef95.austin.ibm.com # [CIFS] Add support for updating Windows NT times/dates (part 1) # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/inode.c # 2005/01/26 17:30:40-06:00 stevef@stevef95.austin.ibm.com +5 -6 # Add support for updating Windows NT times/dates # # fs/cifs/cifssmb.c # 2005/01/26 17:30:40-06:00 stevef@stevef95.austin.ibm.com +6 -3 # Add support for updating Windows NT times/dates # # fs/cifs/cifspdu.h # 2005/01/26 17:30:40-06:00 stevef@stevef95.austin.ibm.com +25 -10 # Add support for updating Windows NT times/dates # # ChangeSet # 2005/01/20 21:37:57-06:00 sfrench@sambaltcdom.austin.ibm.com # [CIFS] misc cleanup - compare pointers to NULL not zero # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/connect.c # 2005/01/20 21:37:49-06:00 sfrench@sambaltcdom.austin.ibm.com +7 -7 # compare pointers to NULL not zero # # fs/cifs/cifssmb.c # 2005/01/20 21:37:49-06:00 sfrench@sambaltcdom.austin.ibm.com +3 -3 # compare pointers to NULL not zero # # fs/cifs/asn1.c # 2005/01/20 21:37:49-06:00 sfrench@sambaltcdom.austin.ibm.com +1 -1 # compare pointers to NULL not zero # # ChangeSet # 2005/01/17 20:08:33-06:00 sfrench@sambaltcdom.austin.ibm.com # [CIFS] Fix length check for short smbs in cifs demultiplexing and remove unneeded debug messages # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/connect.c # 2005/01/17 20:08:24-06:00 sfrench@sambaltcdom.austin.ibm.com +2 -4 # Fix length check for short smbs in cifs demultiplexing. Remove unneeded debug messages # # ChangeSet # 2005/01/17 08:36:45-06:00 sfrench@sambaltcdom.austin.ibm.com # [CIFS] get rid of tcp peek usage on cifs socket. Makes more sense to read normally # first four bytes off the socket (then read the rest of the frame) rather than peek # first few bytes then read because we were having to retry the peek multiple times # when peek would return less than four bytes and four bytes is the minimum we # ever get. # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/transport.c # 2005/01/17 08:36:36-06:00 sfrench@sambaltcdom.austin.ibm.com +66 -1 # get rid of tcp peek usage on cifs socket # # fs/cifs/connect.c # 2005/01/17 08:36:36-06:00 sfrench@sambaltcdom.austin.ibm.com +27 -59 # Add new send function (part 1) to avoid extra memcopy in smb sending # # ChangeSet # 2005/01/17 08:29:15-06:00 sfrench@sambaltcdom.austin.ibm.com # [CIFS] remove old cifs_readdir routine # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/readdir.c # 2005/01/17 08:29:06-06:00 sfrench@sambaltcdom.austin.ibm.com +3 -3 # remove old readdir routines # # fs/cifs/file.c # 2005/01/17 08:29:06-06:00 sfrench@sambaltcdom.austin.ibm.com +5 -598 # remove old readdir routines # # fs/cifs/CHANGES # 2005/01/17 08:29:06-06:00 sfrench@sambaltcdom.austin.ibm.com +2 -1 # Update cifs changelog # # ChangeSet # 2005/01/09 08:20:07-08:00 cifs.adm@bkbits.net # Merge bk://linux.bkbits.net/linux-2.5 # into bkbits.net:/repos/c/cifs/linux-2.5cifs # # fs/cifs/cifsfs.c # 2005/01/09 08:20:01-08:00 cifs.adm@bkbits.net +0 -0 # Auto merged # # ChangeSet # 2005/01/05 15:06:36-08:00 cifs.adm@bkbits.net # Merge bk://linux.bkbits.net/linux-2.5 # into bkbits.net:/repos/c/cifs/linux-2.5cifs # # fs/cifs/file.c # 2005/01/05 15:06:29-08:00 cifs.adm@bkbits.net +0 -0 # Auto merged # # fs/cifs/connect.c # 2005/01/05 15:06:28-08:00 cifs.adm@bkbits.net +0 -0 # Auto merged # # ChangeSet # 2005/01/04 18:11:57-06:00 stevef@stevef95.austin.ibm.com # [CIFS] Fix default mode on cifs module parms in sysfs # # Pointed out by Domen Puncer # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/cifsfs.h # 2005/01/04 18:11:46-06:00 stevef@stevef95.austin.ibm.com +1 -1 # update cifs contributors # # fs/cifs/cifsfs.c # 2005/01/04 18:11:46-06:00 stevef@stevef95.austin.ibm.com +4 -4 # Fix default mode on cifs module parms in sysfs # # fs/cifs/CHANGES # 2005/01/04 18:11:46-06:00 stevef@stevef95.austin.ibm.com +6 -1 # update to cifs version 1.29 # # fs/cifs/AUTHORS # 2005/01/04 18:11:46-06:00 stevef@stevef95.austin.ibm.com +2 -0 # update cifs contributors # # ChangeSet # 2004/12/22 12:11:36-06:00 stevef@smfhome.smfdom # [CIFS] Fix whitespace # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/cifssmb.c # 2004/12/22 12:11:27-06:00 stevef@smfhome.smfdom +3 -3 # Fix whitespace # # ChangeSet # 2004/12/21 11:08:59-06:00 sfrench@sambaltcdom.austin.ibm.com # [CIFS] Enable reads over 64K by setting large read and write capability at SMB session negotiation # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/connect.c # 2004/12/21 11:08:51-06:00 sfrench@sambaltcdom.austin.ibm.com +1 -1 # Enable reads over 64K by setting large read and write capability at SMB session negotiation # # ChangeSet # 2004/12/19 10:19:16-06:00 sfrench@sambaltcdom.austin.ibm.com # [CIFS] Fix set of mount option rsize so it can be set above negotiated buffer size. # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/connect.c # 2004/12/19 10:19:08-06:00 sfrench@sambaltcdom.austin.ibm.com +1 -1 # Fix set of mount option rsize so it can be set above negotiated buffer size. # # ChangeSet # 2004/12/18 16:01:31-06:00 sfrench@sambaltcdom.austin.ibm.com # check rc of copy_to_user (pointed out by John Cherry) # fix wsize mount parm so it works to control writes # allow reads bigger than 64K (although Samba does not handle them yet). # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/file.c # 2004/12/18 16:01:12-06:00 sfrench@sambaltcdom.austin.ibm.com +14 -10 # check rc of copy_to_user to fix warning pointed out by John Cherry # # fs/cifs/connect.c # 2004/12/18 16:01:12-06:00 sfrench@sambaltcdom.austin.ibm.com +2 -2 # adjust wsize default, and fix wsize mount parm so it is used # # fs/cifs/cifssmb.c # 2004/12/18 16:01:12-06:00 sfrench@sambaltcdom.austin.ibm.com +39 -22 # misc large read/write fixes, for sizes > 64K # # fs/cifs/cifspdu.h # 2004/12/18 16:01:11-06:00 sfrench@sambaltcdom.austin.ibm.com +2 -2 # Definition of write frame missing high offset of count field. # diff -Nru a/fs/cifs/AUTHORS b/fs/cifs/AUTHORS --- a/fs/cifs/AUTHORS 2005-03-08 01:32:25 -08:00 +++ b/fs/cifs/AUTHORS 2005-03-08 01:32:25 -08:00 @@ -25,6 +25,8 @@ Richard Hughes Yury Umanets Mark Hamzy +Domen Puncer +Jesper Juhl Test case and Bug Report contributors ------------------------------------- diff -Nru a/fs/cifs/CHANGES b/fs/cifs/CHANGES --- a/fs/cifs/CHANGES 2005-03-08 01:32:25 -08:00 +++ b/fs/cifs/CHANGES 2005-03-08 01:32:25 -08:00 @@ -1,3 +1,12 @@ +Version 1.30 +------------ +Allow new nouser_xattr mount parm to disable xattr support for user namespace. + +Version 1.29 +------------ +Fix default mode in sysfs of cifs module parms. Remove old readdir routine. +Fix capabilities flags for large readx so as to allow reads larger than 64K. + Version 1.28 ------------ Add module init parm for large SMB buffer size (to allow it to be changed @@ -7,7 +16,8 @@ SpnegoNegotiated returning invalid error. Fix case to retry better when peek returns from 1 to 3 bytes on socket which should have more data. Fixed path based calls (such as cifs lookup) to handle path names -longer than 530 (now can handle PATH_MAX). +longer than 530 (now can handle PATH_MAX). Fix pass through authentication +from Samba server to DC (Samba required dummy LM password). Version 1.27 ------------ diff -Nru a/fs/cifs/Makefile b/fs/cifs/Makefile --- a/fs/cifs/Makefile 2005-03-08 01:32:25 -08:00 +++ b/fs/cifs/Makefile 2005-03-08 01:32:25 -08:00 @@ -3,4 +3,4 @@ # obj-$(CONFIG_CIFS) += cifs.o -cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o +cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o ioctl.o diff -Nru a/fs/cifs/asn1.c b/fs/cifs/asn1.c --- a/fs/cifs/asn1.c 2005-03-08 01:32:25 -08:00 +++ b/fs/cifs/asn1.c 2005-03-08 01:32:25 -08:00 @@ -26,6 +26,7 @@ #include "cifspdu.h" #include "cifsglob.h" #include "cifs_debug.h" +#include "cifsproto.h" /***************************************************************************** * @@ -77,8 +78,8 @@ #define SPNEGO_OID_LEN 7 #define NTLMSSP_OID_LEN 10 -unsigned long SPNEGO_OID[7] = { 1, 3, 6, 1, 5, 5, 2 }; -unsigned long NTLMSSP_OID[10] = { 1, 3, 6, 1, 4, 1, 311, 2, 2, 10 }; +static unsigned long SPNEGO_OID[7] = { 1, 3, 6, 1, 5, 5, 2 }; +static unsigned long NTLMSSP_OID[10] = { 1, 3, 6, 1, 4, 1, 311, 2, 2, 10 }; /* * ASN.1 context. @@ -210,7 +211,7 @@ { unsigned char ch; - if (eoc == 0) { + if (eoc == NULL) { if (!asn1_octet_decode(ctx, &ch)) return 0; diff -Nru a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c --- a/fs/cifs/cifs_debug.c 2005-03-08 01:32:25 -08:00 +++ b/fs/cifs/cifs_debug.c 2005-03-08 01:32:25 -08:00 @@ -57,7 +57,7 @@ } #ifdef CONFIG_PROC_FS -int +static int cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, int count, int *eof, void *data) { @@ -178,7 +178,7 @@ } #ifdef CONFIG_CIFS_STATS -int +static int cifs_stats_read(char *buf, char **beginBuffer, off_t offset, int count, int *eof, void *data) { @@ -286,7 +286,7 @@ } #endif -struct proc_dir_entry *proc_fs_cifs; +static struct proc_dir_entry *proc_fs_cifs; read_proc_t cifs_txanchor_read; static read_proc_t cifsFYI_read; static write_proc_t cifsFYI_write; diff -Nru a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h --- a/fs/cifs/cifs_fs_sb.h 2005-03-08 01:32:25 -08:00 +++ b/fs/cifs/cifs_fs_sb.h 2005-03-08 01:32:25 -08:00 @@ -21,7 +21,8 @@ #define CIFS_MOUNT_NO_PERM 1 /* do not do client vfs_perm check */ #define CIFS_MOUNT_SET_UID 2 /* set current->euid in create etc. */ #define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */ -#define CIFS_MOUNT_DIRECT_IO 8 /* do not write nor read through page cache */ +#define CIFS_MOUNT_DIRECT_IO 8 /* do not write nor read through page cache */ +#define CIFS_MOUNT_NO_XATTR 0x10 /* if set - disable xattr support */ struct cifs_sb_info { struct cifsTconInfo *tcon; /* primary mount */ diff -Nru a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c --- a/fs/cifs/cifsencrypt.c 2005-03-08 01:32:25 -08:00 +++ b/fs/cifs/cifsencrypt.c 2005-03-08 01:32:25 -08:00 @@ -25,6 +25,7 @@ #include "cifs_debug.h" #include "md5.h" #include "cifs_unicode.h" +#include "cifsproto.h" /* Calculate and return the CIFS signature based on the mac key and the smb pdu */ /* the 16 byte signature must be allocated by the caller */ diff -Nru a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c --- a/fs/cifs/cifsfs.c 2005-03-08 01:32:25 -08:00 +++ b/fs/cifs/cifsfs.c 2005-03-08 01:32:25 -08:00 @@ -59,16 +59,16 @@ unsigned int sign_CIFS_PDUs = 1; struct task_struct * oplockThread = NULL; unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE; -module_param(CIFSMaxBufSize, int, CIFS_MAX_MSGSIZE); +module_param(CIFSMaxBufSize, int, 0); MODULE_PARM_DESC(CIFSMaxBufSize,"Network buffer size (not including header). Default: 16384 Range: 8192 to 130048"); unsigned int cifs_min_rcv = CIFS_MIN_RCV_POOL; -module_param(cifs_min_rcv, int, CIFS_MIN_RCV_POOL); +module_param(cifs_min_rcv, int, 0); MODULE_PARM_DESC(cifs_min_rcv,"Network buffers in pool. Default: 4 Range: 1 to 64"); unsigned int cifs_min_small = 30; -module_param(cifs_min_small, int, 30); +module_param(cifs_min_small, int, 0); MODULE_PARM_DESC(cifs_small_rcv,"Small network buffers in pool. Default: 30 Range: 2 to 256"); unsigned int cifs_max_pending = CIFS_MAX_REQ; -module_param(cifs_max_pending, int, CIFS_MAX_REQ); +module_param(cifs_max_pending, int, 0); MODULE_PARM_DESC(cifs_max_pending,"Simultaneous requests to server. Default: 50 Range: 2 to 256"); diff -Nru a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h --- a/fs/cifs/cifsfs.h 2005-03-08 01:32:25 -08:00 +++ b/fs/cifs/cifsfs.h 2005-03-08 01:32:25 -08:00 @@ -90,5 +90,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.28" +#define CIFS_VERSION "1.30" #endif /* _CIFSFS_H */ diff -Nru a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h --- a/fs/cifs/cifspdu.h 2005-03-08 01:32:25 -08:00 +++ b/fs/cifs/cifspdu.h 2005-03-08 01:32:25 -08:00 @@ -568,7 +568,6 @@ #define SMB_SHARE_IS_IN_DFS 0x0002 typedef struct smb_com_logoff_andx_req { - struct smb_hdr hdr; /* wct = 2 */ __u8 AndXCommand; __u8 AndXReserved; @@ -695,7 +694,8 @@ __le16 AndXOffset; __le16 Count; __le16 Remaining; - __le32 Reserved; + __le16 CountHigh; + __u16 Reserved; __u16 ByteCount; } WRITE_RSP; @@ -1078,6 +1078,7 @@ #define SMB_QUERY_FILE_UNIX_LINK 0x201 #define SMB_QUERY_POSIX_ACL 0x204 #define SMB_QUERY_XATTR 0x205 +#define SMB_QUERY_ATTR_FLAGS 0x206 /* append,immutable etc. */ #define SMB_QUERY_FILE_INTERNAL_INFO 0x3ee #define SMB_QUERY_FILE_ACCESS_INFO 0x3f0 #define SMB_QUERY_FILE_NAME_INFO2 0x3f1 /* 0x30 bytes */ @@ -1095,6 +1096,7 @@ #define SMB_SET_FILE_UNIX_HLINK 0x203 #define SMB_SET_POSIX_ACL 0x204 #define SMB_SET_XATTR 0x205 +#define SMB_SET_ATTR_FLAGS 0x206 /* append, immutable etc. */ #define SMB_SET_FILE_BASIC_INFO2 0x3ec #define SMB_SET_FILE_RENAME_INFORMATION 0x3f2 /* BB check if qpathinfo level too */ #define SMB_FILE_ALL_INFO2 0x3fa @@ -1592,17 +1594,32 @@ char LinkDest[1]; } FILE_UNIX_LINK_INFO; /* level 0x201 QPathInfo */ +/* The following three structures are needed only for + setting time to NT4 and some older servers via + the primitive DOS time format */ +typedef struct { + __u16 Day:5; + __u16 Month:4; + __u16 Year:7; +} SMB_DATE; + typedef struct { - __u16 CreationDate; - __u16 CreationTime; - __u16 LastAccessDate; - __u16 LastAccessTime; - __u16 LastWriteDate; - __u16 LastWriteTime; - __u32 DataSize; /* File Size (EOF) */ - __u32 AllocationSize; - __u16 Attributes; /* verify not u32 */ - __u32 EASize; + __u16 TwoSeconds:5; + __u16 Minutes:6; + __u16 Hours:5; +} SMB_TIME; + +typedef struct { + __le16 CreationDate; /* SMB Date see above */ + __le16 CreationTime; /* SMB Time */ + __le16 LastAccessDate; + __le16 LastAccessTime; + __le16 LastWriteDate; + __le16 LastWriteTime; + __le32 DataSize; /* File Size (EOF) */ + __le32 AllocationSize; + __le16 Attributes; /* verify not u32 */ + __le32 EASize; } FILE_INFO_STANDARD; /* level 1 SetPath/FileInfo */ typedef struct { diff -Nru a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h --- a/fs/cifs/cifsproto.h 2005-03-08 01:32:25 -08:00 +++ b/fs/cifs/cifsproto.h 2005-03-08 01:32:25 -08:00 @@ -50,16 +50,18 @@ extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid); extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length); extern int is_valid_oplock_break(struct smb_hdr *smb); +extern int is_size_safe_to_change(struct cifsInodeInfo *); extern unsigned int smbCalcSize(struct smb_hdr *ptr); extern int decode_negTokenInit(unsigned char *security_blob, int length, enum securityEnum *secType); +extern int cifs_inet_pton(int, char * source, void *dst); extern int map_smb_to_linux_error(struct smb_hdr *smb); extern void header_assemble(struct smb_hdr *, char /* command */ , const struct cifsTconInfo *, int /* length of fixed section (word count) in two byte units */ ); -struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16, struct cifsTconInfo *); -void DeleteOplockQEntry(struct oplock_q_entry *); +extern struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16, struct cifsTconInfo *); +extern void DeleteOplockQEntry(struct oplock_q_entry *); extern struct timespec cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ ); extern u64 cifs_UnixTimeToNT(struct timespec); extern int cifs_get_inode_info(struct inode **pinode, @@ -79,18 +81,11 @@ const struct nls_table *); extern int CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, - const char *searchName, - FILE_DIRECTORY_INFO * findData, - T2_FFIRST_RSP_PARMS * findParms, - const struct nls_table *nls_codepage, - int *pUnicodeFlag, - int *pUnixFlag /* if Unix extensions used */ ); + const char *searchName, const struct nls_table *nls_codepage, + __u16 *searchHandle, struct cifs_search_info * psrch_inf); + extern int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, - FILE_DIRECTORY_INFO * findData, - T2_FNEXT_RSP_PARMS * findParms, - const __u16 searchHandle, char * resume_name, - int name_length, __u32 resume_key, - int *UnicodeFlag, int *pUnixFlag); + __u16 searchHandle, struct cifs_search_info * psrch_inf); extern int CIFSFindClose(const int, struct cifsTconInfo *tcon, const __u16 search_handle); @@ -132,6 +127,9 @@ extern int CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon, const char *fileName, const FILE_BASIC_INFO * data, const struct nls_table *nls_codepage); +extern int CIFSSMBSetTimesLegacy(int xid, struct cifsTconInfo *tcon, char *fileName, + FILE_BASIC_INFO * data, const struct nls_table *nls_codepage); + extern int CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, const char *fileName, __u64 size,int setAllocationSizeFlag, const struct nls_table *nls_codepage); @@ -211,10 +209,10 @@ extern int cifs_reconnect(struct TCP_Server_Info *server); extern int cifs_sign_smb(struct smb_hdr *, struct cifsSesInfo *,__u32 *); -extern int cifs_verify_signature(const struct smb_hdr *, const char * mac_key, +extern int cifs_verify_signature(struct smb_hdr *, const char * mac_key, __u32 expected_sequence_number); extern int cifs_calculate_mac_key(char * key,const char * rn,const char * pass); -extern void CalcNTLMv2_partial_mac_key(struct cifsSesInfo *, struct nls_table *); +extern int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *, struct nls_table *); extern void CalcNTLMv2_response(const struct cifsSesInfo *,char * ); extern int CIFSSMBCopy(int xid, struct cifsTconInfo *source_tcon, @@ -244,4 +242,6 @@ const unsigned char *fileName, const char *local_acl, const int buflen, const int acl_type, const struct nls_table *nls_codepage); +int cifs_ioctl (struct inode * inode, struct file * filep, + unsigned int command, unsigned long arg); #endif /* _CIFSPROTO_H */ diff -Nru a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c --- a/fs/cifs/cifssmb.c 2005-03-08 01:32:25 -08:00 +++ b/fs/cifs/cifssmb.c 2005-03-08 01:32:25 -08:00 @@ -154,7 +154,7 @@ return rc; *request_buf = cifs_small_buf_get(); - if (*request_buf == 0) { + if (*request_buf == NULL) { /* BB should we add a retry in here if not a writepage? */ return -ENOMEM; } @@ -246,7 +246,7 @@ return rc; *request_buf = cifs_buf_get(); - if (*request_buf == 0) { + if (*request_buf == NULL) { /* BB should we add a retry in here if not a writepage? */ return -ENOMEM; } @@ -448,7 +448,7 @@ return 0; } - if((tcon->ses == 0) || (tcon->ses->server == 0)) { + if((tcon->ses == NULL) || (tcon->ses->server == NULL)) { up(&tcon->tconSem); return -EIO; } @@ -802,6 +802,8 @@ char *pReadData = NULL; int bytes_returned; + cFYI(1,("Reading %d bytes on fid %d",count,netfid)); + *nbytes = 0; rc = smb_init(SMB_COM_READ_ANDX, 12, tcon, (void **) &pSMB, (void **) &pSMBr); @@ -817,8 +819,8 @@ pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF); pSMB->OffsetHigh = cpu_to_le32(lseek >> 32); pSMB->Remaining = 0; - pSMB->MaxCount = cpu_to_le16(count); - pSMB->MaxCountHigh = 0; + pSMB->MaxCount = cpu_to_le16(count & 0xFFFF); + pSMB->MaxCountHigh = cpu_to_le32(count >> 16); pSMB->ByteCount = 0; /* no need to do le conversion since it is 0 */ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, @@ -826,8 +828,11 @@ if (rc) { cERROR(1, ("Send error in read = %d", rc)); } else { - __u16 data_length = le16_to_cpu(pSMBr->DataLength); + int data_length = le16_to_cpu(pSMBr->DataLengthHigh); + data_length = data_length << 16; + data_length += le16_to_cpu(pSMBr->DataLength); *nbytes = data_length; + /*check that DataLength would not go beyond end of SMB */ if ((data_length > CIFSMaxBufSize) || (data_length > count)) { @@ -868,9 +873,10 @@ WRITE_REQ *pSMB = NULL; WRITE_RSP *pSMBr = NULL; int bytes_returned; - unsigned bytes_sent; + __u32 bytes_sent; __u16 byte_count; + /* cFYI(1,("write at %lld %d bytes",offset,count));*/ rc = smb_init(SMB_COM_WRITE_ANDX, 14, tcon, (void **) &pSMB, (void **) &pSMBr); if (rc) @@ -886,31 +892,41 @@ pSMB->Reserved = 0xFFFFFFFF; pSMB->WriteMode = 0; pSMB->Remaining = 0; - /* BB can relax this if buffer is big enough in some cases - ie we can - send more if LARGE_WRITE_X capability returned by the server and if + + /* Can increase buffer size if buffer is big enough in some cases - ie we + can send more if LARGE_WRITE_X capability returned by the server and if our buffer is big enough or if we convert to iovecs on socket writes and eliminate the copy to the CIFS buffer */ - bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & ~0xFF; + if(tcon->ses->capabilities & CAP_LARGE_WRITE_X) { + bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count); + } else { + bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) + & ~0xFF; + } + if (bytes_sent > count) bytes_sent = count; - pSMB->DataLengthHigh = 0; pSMB->DataOffset = cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4); - if(buf) + if(buf) memcpy(pSMB->Data,buf,bytes_sent); - else if(ubuf) - copy_from_user(pSMB->Data,ubuf,bytes_sent); - else { + else if(ubuf) { + if(copy_from_user(pSMB->Data,ubuf,bytes_sent)) { + if(pSMB) + cifs_buf_release(pSMB); + return -EFAULT; + } + } else { /* No buffer */ if(pSMB) cifs_buf_release(pSMB); return -EINVAL; } - byte_count = bytes_sent + 1 /* pad */ ; - pSMB->DataLengthLow = cpu_to_le16(bytes_sent); - pSMB->DataLengthHigh = 0; - pSMB->hdr.smb_buf_length += byte_count; + byte_count = bytes_sent + 1 /* pad */ ; /* BB fix this for sends > 64K */ + pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF); + pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16); + pSMB->hdr.smb_buf_length += bytes_sent+1; pSMB->ByteCount = cpu_to_le16(byte_count); rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, @@ -918,8 +934,11 @@ if (rc) { cFYI(1, ("Send error in write = %d", rc)); *nbytes = 0; - } else - *nbytes = le16_to_cpu(pSMBr->Count); + } else { + *nbytes = le16_to_cpu(pSMBr->CountHigh); + *nbytes = (*nbytes) << 16; + *nbytes += le16_to_cpu(pSMBr->Count); + } if (pSMB) cifs_buf_release(pSMB); @@ -1826,7 +1845,7 @@ return size; } -__u16 convert_ace_to_cifs_ace(struct cifs_posix_ace * cifs_ace, +static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace * cifs_ace, const posix_acl_xattr_entry * local_ace) { __u16 rc = 0; /* 0 = ACL converted ok */ @@ -1844,7 +1863,7 @@ } /* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */ -__u16 ACL_to_cifs_posix(char * parm_data,const char * pACL,const int buflen, +static __u16 ACL_to_cifs_posix(char * parm_data,const char * pACL,const int buflen, const int acl_type) { __u16 rc = 0; @@ -1913,14 +1932,13 @@ if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, PATH_MAX - /* BB fixme find define for this maxpathcomponent */ , nls_codepage); name_len++; /* trailing null */ name_len *= 2; pSMB->FileName[name_len] = 0; pSMB->FileName[name_len+1] = 0; } else { /* BB improve the check for buffer overruns BB */ - name_len = strnlen(searchName, PATH_MAX /* BB fixme */); + name_len = strnlen(searchName, PATH_MAX); name_len++; /* trailing null */ strncpy(pSMB->FileName, searchName, name_len); } @@ -1996,10 +2014,9 @@ (void **) &pSMBr); if (rc) return rc; - if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { + if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, PATH_MAX - /* BB fixme find define for this maxpathcomponent */ , nls_codepage); name_len++; /* trailing null */ name_len *= 2; @@ -2051,9 +2068,9 @@ setACLerrorExit: if (pSMB) cifs_buf_release(pSMB); - if (rc == -EAGAIN) + if (rc == -EAGAIN) goto setAclRetry; - return rc; + return rc; } #endif @@ -2072,7 +2089,7 @@ int name_len; __u16 params, byte_count; -/* cFYI(1, ("In QPathInfo path %s", searchName)); */ /* BB fixme BB */ +/* cFYI(1, ("In QPathInfo path %s", searchName)); */ QPathInfoRetry: rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); @@ -2306,118 +2323,9 @@ } #endif /* CIFS_EXPERIMENTAL */ -int -CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, - const char *searchName, FILE_DIRECTORY_INFO * findData, - T2_FFIRST_RSP_PARMS * findParms, - const struct nls_table *nls_codepage, int *pUnicodeFlag, - int *pUnixFlag) -{ -/* level 257 SMB_ */ - TRANSACTION2_FFIRST_REQ *pSMB = NULL; - TRANSACTION2_FFIRST_RSP *pSMBr = NULL; - char *response_data; - int rc = 0; - int bytes_returned; - int name_len; - __u16 params, byte_count; - - cFYI(1, ("In FindFirst")); -findFirstRetry: - 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, PATH_MAX - /* 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, PATH_MAX); - name_len++; /* trailing null */ - strncpy(pSMB->FileName, searchName, name_len); - } - - params = 12 + name_len /* includes null */ ; - pSMB->TotalDataCount = 0; /* no EAs */ - pSMB->MaxParameterCount = cpu_to_le16(10); - pSMB->MaxDataCount = cpu_to_le16((tcon->ses->server->maxBuf - - MAX_CIFS_HDR_SIZE) & 0xFFFFFF00); - pSMB->MaxSetupCount = 0; - pSMB->Reserved = 0; - pSMB->Flags = 0; - pSMB->Timeout = 0; - pSMB->Reserved2 = 0; - byte_count = params + 1 /* pad */ ; - pSMB->TotalParameterCount = cpu_to_le16(params); - pSMB->ParameterCount = pSMB->TotalParameterCount; - pSMB->ParameterOffset = cpu_to_le16( - offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes) - 4); - pSMB->DataCount = 0; - pSMB->DataOffset = 0; - pSMB->SetupCount = 1; /* one byte no need to make endian neutral */ - pSMB->Reserved3 = 0; - pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST); - pSMB->SearchAttributes = - cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM | - ATTR_DIRECTORY); - pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize / sizeof (FILE_DIRECTORY_INFO)); /* should this be shrunk even more ? */ - pSMB->SearchFlags = cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME); - - /* test for Unix extensions */ - if (tcon->ses->capabilities & CAP_UNIX) { - pSMB->InformationLevel = cpu_to_le16(SMB_FIND_FILE_UNIX); - *pUnixFlag = TRUE; - } else { - pSMB->InformationLevel = - cpu_to_le16(SMB_FIND_FILE_DIRECTORY_INFO); - *pUnixFlag = FALSE; - } - pSMB->SearchStorageType = 0; /* BB what should we set this to? It is not clear if it matters BB */ - pSMB->hdr.smb_buf_length += byte_count; - pSMB->ByteCount = cpu_to_le16(byte_count); - - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, - (struct smb_hdr *) pSMBr, &bytes_returned, 0); - - if (rc) { /* BB add logic to retry regular search if Unix search rejected unexpectedly by server */ - cFYI(1, ("Error in FindFirst = %d", rc)); - } else { - rc = validate_t2((struct smb_t2_rsp *)pSMBr); - if(!rc) { - /* decode response */ - /* BB add safety checks for these memcpys */ - if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) - *pUnicodeFlag = TRUE; - else - *pUnicodeFlag = FALSE; - memcpy(findParms, - (char *) &pSMBr->hdr.Protocol + - le16_to_cpu(pSMBr->t2.ParameterOffset), - sizeof (T2_FFIRST_RSP_PARMS)); - response_data = - (char *) &pSMBr->hdr.Protocol + - le16_to_cpu(pSMBr->t2.DataOffset); - memcpy(findData, response_data, - le16_to_cpu(pSMBr->t2.DataCount)); - } - } - if (pSMB) - cifs_buf_release(pSMB); - - if (rc == -EAGAIN) - goto findFirstRetry; - - return rc; -} - /* xid, tcon, searchName and codepage are input parms, rest are returned */ int -CIFSFindFirst2(const int xid, struct cifsTconInfo *tcon, +CIFSFindFirst(const int xid, struct cifsTconInfo *tcon, const char *searchName, const struct nls_table *nls_codepage, __u16 * pnetfid, @@ -2541,7 +2449,7 @@ return rc; } -int CIFSFindNext2(const int xid, struct cifsTconInfo *tcon, +int CIFSFindNext(const int xid, struct cifsTconInfo *tcon, __u16 searchHandle, struct cifs_search_info * psrch_inf) { TRANSACTION2_FNEXT_REQ *pSMB = NULL; @@ -2666,113 +2574,6 @@ } int -CIFSFindNext(const int xid, struct cifsTconInfo *tcon, - FILE_DIRECTORY_INFO * findData, T2_FNEXT_RSP_PARMS * findParms, - const __u16 searchHandle, char * resume_file_name, int name_len, - __u32 resume_key, int *pUnicodeFlag, int *pUnixFlag) -{ -/* level 257 SMB_ */ - TRANSACTION2_FNEXT_REQ *pSMB = NULL; - TRANSACTION2_FNEXT_RSP *pSMBr = NULL; - char *response_data; - int rc = 0; - int bytes_returned; - __u16 params, byte_count; - - cFYI(1, ("In FindNext")); - - if(resume_file_name == NULL) { - return -EIO; - } - rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, - (void **) &pSMBr); - if (rc) - return rc; - - params = 14; /* includes 2 bytes of null string, converted to LE below */ - byte_count = 0; - pSMB->TotalDataCount = 0; /* no EAs */ - pSMB->MaxParameterCount = cpu_to_le16(8); - pSMB->MaxDataCount = - cpu_to_le16((tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFF00); - 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_fnext_req,SearchHandle) - 4); - pSMB->DataCount = 0; - pSMB->DataOffset = 0; - pSMB->SetupCount = 1; - pSMB->Reserved3 = 0; - pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT); - pSMB->SearchHandle = searchHandle; /* always kept as le */ - findParms->SearchCount = 0; /* set to zero in case of error */ - pSMB->SearchCount = - cpu_to_le16(CIFSMaxBufSize / sizeof (FILE_UNIX_INFO)); - /* test for Unix extensions */ - if (tcon->ses->capabilities & CAP_UNIX) { - pSMB->InformationLevel = cpu_to_le16(SMB_FIND_FILE_UNIX); - *pUnixFlag = TRUE; - } else { - pSMB->InformationLevel = - cpu_to_le16(SMB_FIND_FILE_DIRECTORY_INFO); - *pUnixFlag = FALSE; - } - pSMB->ResumeKey = resume_key; - pSMB->SearchFlags = - cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME); - /* BB add check to make sure we do not cross end of smb */ - if(name_len < PATH_MAX) { - memcpy(pSMB->ResumeFileName, resume_file_name, name_len); - byte_count += name_len; - } - params += name_len; - byte_count = params + 1 /* pad */ ; - pSMB->TotalParameterCount = cpu_to_le16(params); - pSMB->ParameterCount = pSMB->TotalParameterCount; - /* BB improve error handling here */ - pSMB->hdr.smb_buf_length += byte_count; - pSMB->ByteCount = cpu_to_le16(byte_count); - - rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, - (struct smb_hdr *) pSMBr, &bytes_returned, 0); - - if (rc) { - if (rc == -EBADF) - rc = 0; /* search probably was closed at end of search above */ - else - cFYI(1, ("FindNext returned = %d", rc)); - } else { /* decode response */ - rc = validate_t2((struct smb_t2_rsp *)pSMBr); - - /* BB add safety checks for these memcpys */ - if(rc == 0) { - if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) - *pUnicodeFlag = TRUE; - else - *pUnicodeFlag = FALSE; - memcpy(findParms, - (char *) &pSMBr->hdr.Protocol + - le16_to_cpu(pSMBr->t2.ParameterOffset), - sizeof (T2_FNEXT_RSP_PARMS)); - response_data = - (char *) &pSMBr->hdr.Protocol + - le16_to_cpu(pSMBr->t2.DataOffset); - memcpy(findData,response_data,le16_to_cpu(pSMBr->t2.DataCount)); - } - } - if (pSMB) - cifs_buf_release(pSMB); - - /* Note: On -EAGAIN error only caller can retry on handle based calls - since file handle passed in no longer valid */ - - return rc; -} - -int CIFSFindClose(const int xid, struct cifsTconInfo *tcon, const __u16 searchHandle) { int rc = 0; @@ -3574,10 +3375,11 @@ int CIFSSMBSetTimesLegacy(int xid, struct cifsTconInfo *tcon, char *fileName, - FILE_INFO_STANDARD * data, const struct nls_table *nls_codepage) + FILE_BASIC_INFO * data, const struct nls_table *nls_codepage) { TRANSACTION2_SPI_REQ *pSMB = NULL; TRANSACTION2_SPI_RSP *pSMBr = NULL; + FILE_INFO_STANDARD *pfinfo; int name_len; int rc = 0; int bytes_returned = 0; @@ -3607,7 +3409,6 @@ /* BB fixme - we have to map to FILE_STANDARD_INFO (level 1 info in parent function, from the better and ususal FILE_BASIC_INFO */ params = 6 + name_len; - count = sizeof (FILE_INFO_STANDARD); pSMB->MaxParameterCount = cpu_to_le16(2); pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */ pSMB->MaxSetupCount = 0; @@ -3619,11 +3420,15 @@ InformationLevel) - 4; offset = param_offset + params; data_offset = (char *) (&pSMB->hdr.Protocol) + offset; + pfinfo = (FILE_INFO_STANDARD *)data_offset; + /* BB add conversion for FILE_BASIC_INFO data struct to + FILE_INFO_STANDARD finfo struct */ pSMB->ParameterOffset = cpu_to_le16(param_offset); pSMB->DataOffset = cpu_to_le16(offset); pSMB->SetupCount = 1; pSMB->Reserved3 = 0; pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION); + count = sizeof(FILE_INFO_STANDARD); byte_count = 3 /* pad */ + params + count; pSMB->DataCount = cpu_to_le16(count); @@ -3633,7 +3438,6 @@ pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD); pSMB->Reserved4 = 0; pSMB->hdr.smb_buf_length += byte_count; - memcpy(data_offset, data, sizeof (FILE_INFO_STANDARD)); pSMB->ByteCount = cpu_to_le16(byte_count); rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, (struct smb_hdr *) pSMBr, &bytes_returned, 0); diff -Nru a/fs/cifs/connect.c b/fs/cifs/connect.c --- a/fs/cifs/connect.c 2005-03-08 01:32:25 -08:00 +++ b/fs/cifs/connect.c 2005-03-08 01:32:25 -08:00 @@ -47,7 +47,6 @@ unsigned char *p24); extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24); -extern int cifs_inet_pton(int, const char *, void *dst); extern mempool_t *cifs_req_poolp; @@ -70,6 +69,7 @@ unsigned setuids:1; unsigned noperm:1; unsigned no_psx_acl:1; /* set if posix acl support should be disabled */ + unsigned no_xattr:1; /* set if xattr (EA) support should be disabled*/ unsigned server_ino:1; /* use inode numbers from server ie UniqueId */ unsigned direct_io:1; unsigned int rsize; @@ -210,7 +210,7 @@ current->flags |= PF_MEMALLOC; server->tsk = current; /* save process info to wake at shutdown */ cFYI(1, ("Demultiplex PID: %d", current->pid)); - write_lock(&GlobalSMBSeslock); + write_lock(&GlobalSMBSeslock); atomic_inc(&tcpSesAllocCount); length = tcpSesAllocCount.counter; write_unlock(&GlobalSMBSeslock); @@ -233,17 +233,12 @@ continue; } iov.iov_base = smb_buffer; - iov.iov_len = sizeof (struct smb_hdr) - 1; - /* 1 byte less above since wct is not always returned in error cases */ + iov.iov_len = 4; smb_msg.msg_control = NULL; smb_msg.msg_controllen = 0; - length = kernel_recvmsg(csocket, &smb_msg, - &iov, 1, - sizeof (struct smb_hdr) - - 1 /* RFC1001 header and SMB header */ , - MSG_PEEK /* flags see socket.h */ ); + &iov, 1, 4, 0 /* BB see socket.h flags */); if(server->tcpStatus == CifsExiting) { break; @@ -253,8 +248,7 @@ cFYI(1,("call to reconnect done")); csocket = server->ssocket; continue; - } else if ((length == -ERESTARTSYS) || (length == -EAGAIN) - || ((length > 0) && (length <= 3)) ) { + } else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) { set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(1); /* minimum sleep to prevent looping allowing socket to clear and app threads to set @@ -277,29 +271,18 @@ csocket = server->ssocket; wake_up(&server->response_q); continue; - } - - pdu_length = 4 + ntohl(smb_buffer->smb_buf_length); + } else if (length > 3) { + pdu_length = ntohl(smb_buffer->smb_buf_length); /* Only read pdu_length after below checks for too short (due to e.g. int overflow) and too long ie beyond end of buf */ - cFYI(1, ("Peek length rcvd: 0x%x beginning 0x%x)", length, pdu_length)); + cFYI(1,("rfc1002 length(big endian)0x%x)", pdu_length+4)); - temp = (char *) smb_buffer; - if (length > 3) { + temp = (char *) smb_buffer; if (temp[0] == (char) RFC1002_SESSION_KEEP_ALIVE) { - iov.iov_base = smb_buffer; - iov.iov_len = 4; - length = kernel_recvmsg(csocket, &smb_msg, - &iov, 1, 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_len = 4; - length = kernel_recvmsg(csocket, &smb_msg, - &iov, 1, 4, 0); cFYI(1,("Good RFC 1002 session rsp")); - } else if ((temp[0] == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) - && (length == 5)) { + } else if (temp[0] == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) { /* we get this from Windows 98 instead of error on SMB negprot response */ cFYI(1,("Negative RFC 1002 Session Response Error 0x%x)",temp[4])); if(server->tcpStatus == CifsNew) { @@ -330,38 +313,22 @@ csocket = server->ssocket; continue; } else { - if (length < 16) { - /* We can not validate the SMB unless - at least this much of SMB available - so give the socket time to copy - a few more bytes and retry */ - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(10); - continue; - } else if( (pdu_length > - CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) - || (pdu_length < - sizeof (struct smb_hdr) - 1) - || (checkSMBhdr - (smb_buffer, smb_buffer->Mid))) { + if((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) + || (pdu_length < sizeof (struct smb_hdr) - 1 - 4)) { cERROR(1, - ("Invalid size or format for SMB found with length %d and pdu_length %d", - length, pdu_length)); - cifs_dump_mem("Received Data is: ",temp,sizeof(struct smb_hdr)+3); - /* could we fix this network corruption by finding next - smb header (instead of killing the session) and - restart reading from next valid SMB found? */ + ("Invalid size SMB length %d and pdu_length %d", + length, pdu_length+4)); cifs_reconnect(server); csocket = server->ssocket; + wake_up(&server->response_q); continue; - } else { /* length ok */ - + } else { /* length ok */ length = 0; - iov.iov_base = smb_buffer; + iov.iov_base = 4 + (char *)smb_buffer; iov.iov_len = pdu_length; for (total_read = 0; total_read < pdu_length; - total_read += length) { + total_read += length) { length = kernel_recvmsg(csocket, &smb_msg, &iov, 1, pdu_length - total_read, 0); @@ -371,14 +338,16 @@ pdu_length - total_read)); cifs_reconnect(server); csocket = server->ssocket; + wake_up(&server->response_q); continue; } } + length += 4; /* account for rfc1002 hdr */ } dump_smb(smb_buffer, length); if (checkSMB - (smb_buffer, smb_buffer->Mid, total_read)) { + (smb_buffer, smb_buffer->Mid, total_read+4)) { cERROR(1, ("Bad SMB Received ")); continue; } @@ -410,17 +379,13 @@ } } } else { - cFYI(0, - ("Frame less than four bytes received %d bytes long.", + cFYI(1, + ("Frame less than four bytes received %d bytes long.", length)); - if (length > 0) { - length = kernel_recvmsg(csocket, &smb_msg, - &iov, 1, - length, 0); /* throw away junk frame */ - cFYI(1, - (" with junk 0x%x in it ", - *(__u32 *) smb_buffer)); - } + cifs_reconnect(server); + csocket = server->ssocket; + wake_up(&server->response_q); + continue; } } spin_lock(&GlobalMid_Lock); @@ -560,7 +525,12 @@ continue; if ((value = strchr(data, '=')) != NULL) *value++ = '\0'; - if (strnicmp(data, "user", 4) == 0) { + + if (strnicmp(data, "user_xattr",10) == 0) {/*parse before user*/ + vol->no_xattr = 0; + } else if (strnicmp(data, "nouser_xattr",12) == 0) { + vol->no_xattr = 1; + } else if (strnicmp(data, "user", 4) == 0) { if (!value || !*value) { printk(KERN_WARNING "CIFS: invalid or missing username\n"); @@ -845,7 +815,7 @@ return 1; } } - if(vol->UNCip == 0) + if(vol->UNCip == NULL) vol->UNCip = &vol->UNC[2]; return 0; @@ -1409,14 +1379,14 @@ /* search for existing tcon to this server share */ if (!rc) { - if((volume_info.rsize) && (volume_info.rsize + MAX_CIFS_HDR_SIZE < srvTcp->maxBuf)) + if((volume_info.rsize) && (volume_info.rsize <= CIFSMaxBufSize)) cifs_sb->rsize = volume_info.rsize; else cifs_sb->rsize = srvTcp->maxBuf - MAX_CIFS_HDR_SIZE; /* default */ - if((volume_info.wsize) && (volume_info.wsize + MAX_CIFS_HDR_SIZE < srvTcp->maxBuf)) + if((volume_info.wsize) && (volume_info.wsize <= CIFSMaxBufSize)) cifs_sb->wsize = volume_info.wsize; else - cifs_sb->wsize = srvTcp->maxBuf - MAX_CIFS_HDR_SIZE; /* default */ + cifs_sb->wsize = CIFSMaxBufSize; /* default */ if(cifs_sb->rsize < PAGE_CACHE_SIZE) { cifs_sb->rsize = PAGE_CACHE_SIZE; cERROR(1,("Attempt to set readsize for mount to less than one page (4096)")); @@ -1433,6 +1403,8 @@ cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID; if(volume_info.server_ino) cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM; + if(volume_info.no_xattr) + cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR; if(volume_info.direct_io) { cERROR(1,("mounting share using direct i/o")); cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; @@ -1504,7 +1476,7 @@ /* If find_unc succeeded then rc == 0 so we can not end */ if (tcon) /* up accidently freeing someone elses tcon struct */ tconInfoFree(tcon); - if (existingCifsSes == 0) { + if (existingCifsSes == NULL) { if (pSesInfo) { if ((pSesInfo->server) && (pSesInfo->status == CifsGood)) { @@ -1575,7 +1547,7 @@ user = ses->userName; domain = ses->domainName; smb_buffer = cifs_buf_get(); - if (smb_buffer == 0) { + if (smb_buffer == NULL) { return -ENOMEM; } smb_buffer_response = smb_buffer; @@ -1592,7 +1564,7 @@ if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; - capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS; + capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS | CAP_LARGE_WRITE_X | CAP_LARGE_READ_X; if (ses->capabilities & CAP_UNICODE) { smb_buffer->Flags2 |= SMBFLG2_UNICODE; capabilities |= CAP_UNICODE; @@ -1828,7 +1800,7 @@ domain = ses->domainName; smb_buffer = cifs_buf_get(); - if (smb_buffer == 0) { + if (smb_buffer == NULL) { return -ENOMEM; } smb_buffer_response = smb_buffer; @@ -2093,7 +2065,7 @@ domain = ses->domainName; *pNTLMv2_flag = FALSE; smb_buffer = cifs_buf_get(); - if (smb_buffer == 0) { + if (smb_buffer == NULL) { return -ENOMEM; } smb_buffer_response = smb_buffer; @@ -2435,7 +2407,7 @@ user = ses->userName; domain = ses->domainName; smb_buffer = cifs_buf_get(); - if (smb_buffer == 0) { + if (smb_buffer == NULL) { return -ENOMEM; } smb_buffer_response = smb_buffer; @@ -2809,7 +2781,7 @@ return -EIO; smb_buffer = cifs_buf_get(); - if (smb_buffer == 0) { + if (smb_buffer == NULL) { return -ENOMEM; } smb_buffer_response = smb_buffer; @@ -3011,16 +2983,21 @@ if(ntlmv2_flag) { char * v2_response; cFYI(1,("Can use more secure NTLM version 2 password hash")); - CalcNTLMv2_partial_mac_key(pSesInfo, - nls_info); - v2_response = kmalloc(16 + 64 /* blob */, GFP_KERNEL); + if(CalcNTLMv2_partial_mac_key(pSesInfo, + nls_info)) { + rc = -ENOMEM; + goto ss_err_exit; + } else + v2_response = kmalloc(16 + 64 /* blob */, GFP_KERNEL); if(v2_response) { CalcNTLMv2_response(pSesInfo,v2_response); /* cifs_calculate_ntlmv2_mac_key(pSesInfo->mac_signing_key, response, ntlm_session_key, */ kfree(v2_response); /* BB Put dummy sig in SessSetup PDU? */ - } else + } else { rc = -ENOMEM; + goto ss_err_exit; + } } else { SMBNTencrypt(pSesInfo->password, @@ -3057,6 +3034,7 @@ pSesInfo->status = CifsGood; } } +ss_err_exit: return rc; } diff -Nru a/fs/cifs/fcntl.c b/fs/cifs/fcntl.c --- a/fs/cifs/fcntl.c 2005-03-08 01:32:25 -08:00 +++ b/fs/cifs/fcntl.c 2005-03-08 01:32:25 -08:00 @@ -27,8 +27,9 @@ #include "cifsproto.h" #include "cifs_unicode.h" #include "cifs_debug.h" +#include "cifsfs.h" -__u32 convert_to_cifs_notify_flags(unsigned long fcntl_notify_flags) +static __u32 convert_to_cifs_notify_flags(unsigned long fcntl_notify_flags) { __u32 cifs_ntfy_flags = 0; diff -Nru a/fs/cifs/file.c b/fs/cifs/file.c --- a/fs/cifs/file.c 2005-03-08 01:32:25 -08:00 +++ b/fs/cifs/file.c 2005-03-08 01:32:25 -08:00 @@ -35,8 +35,6 @@ #include "cifs_debug.h" #include "cifs_fs_sb.h" -extern int cifs_readdir2(struct file *file, void *direntry, filldir_t filldir); /* BB removeme BB */ - int cifs_open(struct inode *inode, struct file *file) { @@ -680,10 +678,10 @@ } rc = CIFSSMBWrite(xid, pTcon, - open_file->netfid, - write_size - total_written, *poffset, - &bytes_written, - NULL, write_data + total_written, long_op); + open_file->netfid, + min_t(const int,cifs_sb->wsize,write_size - total_written), + *poffset, &bytes_written, + NULL, write_data + total_written, long_op); } if (rc || (bytes_written == 0)) { if (total_written) @@ -800,10 +798,10 @@ } rc = CIFSSMBWrite(xid, pTcon, - open_file->netfid, - write_size - total_written, *poffset, - &bytes_written, - write_data + total_written, NULL, long_op); + open_file->netfid, + min_t(const int,cifs_sb->wsize,write_size - total_written), + *poffset,&bytes_written, + write_data + total_written, NULL, long_op); } if (rc || (bytes_written == 0)) { if (total_written) @@ -945,7 +943,11 @@ int xid; xid = GetXid(); -/* call 16K write then Setpageuptodate */ + + /* Find contiguous pages then iterate through repeating */ +/* call 16K write then Setpageuptodate or if LARGE_WRITE_X +support then send larger writes via kevec so as to eliminate +a memcpy */ FreeXid(xid); return rc; } @@ -1145,7 +1147,6 @@ if((file->f_flags & O_ACCMODE) == O_WRONLY) { cFYI(1,("attempting read on write only file instance")); } - for (total_read = 0,current_offset=read_data; read_size > total_read; total_read += bytes_read,current_offset+=bytes_read) { current_read_size = min_t(const int,read_size - total_read,cifs_sb->rsize); @@ -1165,8 +1166,12 @@ &bytes_read, &smb_read_data); pSMBr = (struct smb_com_read_rsp *)smb_read_data; - copy_to_user(current_offset,smb_read_data + 4/* RFC1001 hdr*/ - + le16_to_cpu(pSMBr->DataOffset), bytes_read); + if(copy_to_user(current_offset,smb_read_data + 4/* RFC1001 hdr*/ + + le16_to_cpu(pSMBr->DataOffset), bytes_read)) { + rc = -EFAULT; + FreeXid(xid); + return rc; + } if(smb_read_data) { cifs_buf_release(smb_read_data); smb_read_data = NULL; @@ -1750,651 +1755,7 @@ } } -/* Returns one if new inode created (which therefore needs to be hashed) */ -/* Might check in the future if inode number changed so we can rehash inode */ -int -construct_dentry(struct qstr *qstring, struct file *file, - struct inode **ptmp_inode, struct dentry **pnew_dentry) -{ - struct dentry *tmp_dentry; - struct cifs_sb_info *cifs_sb; - struct cifsTconInfo *pTcon; - int rc = 0; - - cFYI(1, ("For %s ", qstring->name)); - cifs_sb = CIFS_SB(file->f_dentry->d_sb); - pTcon = cifs_sb->tcon; - - qstring->hash = full_name_hash(qstring->name, qstring->len); - tmp_dentry = d_lookup(file->f_dentry, qstring); - if (tmp_dentry) { - cFYI(0, (" existing dentry with inode 0x%p", tmp_dentry->d_inode)); - *ptmp_inode = tmp_dentry->d_inode; - /* BB overwrite the old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len ?? */ - if(*ptmp_inode == NULL) { - *ptmp_inode = new_inode(file->f_dentry->d_sb); - if(*ptmp_inode == NULL) - return rc; - rc = 1; - d_instantiate(tmp_dentry, *ptmp_inode); - } - } else { - tmp_dentry = d_alloc(file->f_dentry, qstring); - if(tmp_dentry == NULL) { - cERROR(1,("Failed allocating dentry")); - *ptmp_inode = NULL; - return rc; - } - - *ptmp_inode = new_inode(file->f_dentry->d_sb); - tmp_dentry->d_op = &cifs_dentry_ops; - if(*ptmp_inode == NULL) - return rc; - rc = 1; - d_instantiate(tmp_dentry, *ptmp_inode); - d_rehash(tmp_dentry); - } - - tmp_dentry->d_time = jiffies; - *pnew_dentry = tmp_dentry; - return rc; -} - -static void reset_resume_key(struct file * dir_file, - unsigned char * filename, - unsigned int len,int Unicode,struct nls_table * nls_tab) { - struct cifsFileInfo *cifsFile; - - cifsFile = (struct cifsFileInfo *)dir_file->private_data; - if(cifsFile == NULL) - return; - if(cifsFile->search_resume_name) { - kfree(cifsFile->search_resume_name); - } - - if(Unicode) - len *= 2; - cifsFile->resume_name_length = len; - - cifsFile->search_resume_name = - kmalloc(cifsFile->resume_name_length, GFP_KERNEL); - - if(cifsFile->search_resume_name == NULL) { - cERROR(1,("failed new resume key allocate, length %d", - cifsFile->resume_name_length)); - return; - } - if(Unicode) - cifs_strtoUCS((wchar_t *) cifsFile->search_resume_name, - filename, len, nls_tab); - else - memcpy(cifsFile->search_resume_name, filename, - cifsFile->resume_name_length); - cFYI(1,("Reset resume key to: %s with len %d",filename,len)); - return; -} - - - -static int -cifs_filldir(struct qstr *pqstring, FILE_DIRECTORY_INFO * pfindData, - struct file *file, filldir_t filldir, void *direntry) -{ - struct inode *tmp_inode; - struct dentry *tmp_dentry; - int object_type,rc; - - pqstring->name = pfindData->FileName; - /* pqstring->len is already set by caller */ - - rc = construct_dentry(pqstring, file, &tmp_inode, &tmp_dentry); - if((tmp_inode == NULL) || (tmp_dentry == NULL)) { - return -ENOMEM; - } - fill_in_inode(tmp_inode, pfindData, &object_type); - if(rc) { - /* We have no reliable way to get inode numbers - from servers w/o Unix extensions yet so we can not set - i_ino from pfindData yet */ - - /* new inode created, let us hash it */ - insert_inode_hash(tmp_inode); - } /* else if inode number changed do we rehash it? */ - rc = filldir(direntry, pfindData->FileName, pqstring->len, file->f_pos, - tmp_inode->i_ino, object_type); - if(rc) { - /* due to readdir error we need to recalculate resume - key so next readdir will restart on right entry */ - cFYI(1,("Error %d on filldir of %s",rc ,pfindData->FileName)); - } - dput(tmp_dentry); - return rc; -} - -static int -cifs_filldir_unix(struct qstr *pqstring, - FILE_UNIX_INFO * pUnixFindData, struct file *file, - filldir_t filldir, void *direntry) -{ - struct inode *tmp_inode; - struct dentry *tmp_dentry; - int object_type, rc; - - pqstring->name = pUnixFindData->FileName; - pqstring->len = strnlen(pUnixFindData->FileName, MAX_PATHCONF); - - rc = construct_dentry(pqstring, file, &tmp_inode, &tmp_dentry); - if((tmp_inode == NULL) || (tmp_dentry == NULL)) { - return -ENOMEM; - } - if(rc) { - struct cifs_sb_info *cifs_sb = CIFS_SB(tmp_inode->i_sb); - - if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { - tmp_inode->i_ino = - (unsigned long)pUnixFindData->UniqueId; - } - insert_inode_hash(tmp_inode); - } /* else if i_ino has changed should we rehash it? */ - unix_fill_in_inode(tmp_inode, pUnixFindData, &object_type); - rc = filldir(direntry, pUnixFindData->FileName, pqstring->len, - file->f_pos, tmp_inode->i_ino, object_type); - if(rc) { - /* due to readdir error we need to recalculate resume - key so next readdir will restart on right entry */ - cFYI(1,("Error %d on filldir of %s",rc ,pUnixFindData->FileName)); - } - dput(tmp_dentry); - return rc; -} - -int -cifs_readdir(struct file *file, void *direntry, filldir_t filldir) -{ - int rc = 0; - int xid; - int Unicode = FALSE; - int UnixSearch = FALSE; - unsigned int bufsize, i; - __u16 searchHandle; - struct cifs_sb_info *cifs_sb; - struct cifsTconInfo *pTcon; - struct cifsFileInfo *cifsFile = NULL; - char *full_path = NULL; - char *data; - struct qstr qstring; - T2_FFIRST_RSP_PARMS findParms; - T2_FNEXT_RSP_PARMS findNextParms; - FILE_DIRECTORY_INFO *pfindData; - FILE_DIRECTORY_INFO *lastFindData; - FILE_UNIX_INFO *pfindDataUnix; - - - /* BB removeme begin */ - if(!experimEnabled) - return cifs_readdir2(file,direntry,filldir); - /* BB removeme end */ - - - xid = GetXid(); - - if(file->f_dentry == NULL) { - rc = -EIO; - FreeXid(xid); - return rc; - } - cifs_sb = CIFS_SB(file->f_dentry->d_sb); - pTcon = cifs_sb->tcon; - bufsize = pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; - if(bufsize > CIFSMaxBufSize) { - rc = -EIO; - FreeXid(xid); - return rc; - } - data = kmalloc(bufsize, GFP_KERNEL); - pfindData = (FILE_DIRECTORY_INFO *) data; - if(data == NULL) { - rc = -ENOMEM; - FreeXid(xid); - return rc; - } - down(&file->f_dentry->d_sb->s_vfs_rename_sem); - full_path = build_wildcard_path_from_dentry(file->f_dentry); - up(&file->f_dentry->d_sb->s_vfs_rename_sem); - - if(full_path == NULL) { - kfree(data); - FreeXid(xid); - return -ENOMEM; - } - cFYI(1, ("Full path: %s start at: %lld ", full_path, file->f_pos)); - - switch ((int) file->f_pos) { - case 0: - if (filldir(direntry, ".", 1, file->f_pos, - file->f_dentry->d_inode->i_ino, DT_DIR) < 0) { - cERROR(1, ("Filldir for current dir failed ")); - break; - } - file->f_pos++; - /* fallthrough */ - case 1: - if (filldir(direntry, "..", 2, file->f_pos, - file->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) { - cERROR(1, ("Filldir for parent dir failed ")); - break; - } - file->f_pos++; - /* fallthrough */ - case 2: - if (file->private_data != NULL) { - cifsFile = - (struct cifsFileInfo *) file->private_data; - if (cifsFile->srch_inf.endOfSearch) { - if(cifsFile->srch_inf.emptyDir) { - cFYI(1, ("End of search, empty dir")); - rc = 0; - break; - } - } else { - cifsFile->invalidHandle = TRUE; - CIFSFindClose(xid, pTcon, cifsFile->netfid); - } - if(cifsFile->search_resume_name) { - kfree(cifsFile->search_resume_name); - cifsFile->search_resume_name = NULL; - } - } - rc = CIFSFindFirst(xid, pTcon, full_path, pfindData, - &findParms, cifs_sb->local_nls, - &Unicode, &UnixSearch); - cFYI(1, ("Count: %d End: %d ", - le16_to_cpu(findParms.SearchCount), - le16_to_cpu(findParms.EndofSearch))); - - if (rc == 0) { - __u16 count = le16_to_cpu(findParms.SearchCount); - searchHandle = findParms.SearchHandle; - if(file->private_data == NULL) - file->private_data = - kmalloc(sizeof(struct cifsFileInfo),GFP_KERNEL); - if (file->private_data) { - memset(file->private_data, 0, - sizeof (struct cifsFileInfo)); - cifsFile = - (struct cifsFileInfo *) file->private_data; - cifsFile->netfid = searchHandle; - cifsFile->invalidHandle = FALSE; - init_MUTEX(&cifsFile->fh_sem); - } else { - rc = -ENOMEM; - break; - } - - renew_parental_timestamps(file->f_dentry); - lastFindData = - (FILE_DIRECTORY_INFO *) ((char *) pfindData + - le16_to_cpu(findParms.LastNameOffset)); - if((char *)lastFindData > (char *)pfindData + bufsize) { - cFYI(1,("last search entry past end of packet")); - rc = -EIO; - break; - } - /* Offset of resume key same for levels 257 and 514 */ - cifsFile->srch_inf.resume_key = lastFindData->FileIndex; - if(UnixSearch == FALSE) { - cifsFile->resume_name_length = - le32_to_cpu(lastFindData->FileNameLength); - if(cifsFile->resume_name_length > bufsize - 64) { - cFYI(1,("Illegal resume file name length %d", - cifsFile->resume_name_length)); - rc = -ENOMEM; - break; - } - cifsFile->search_resume_name = - kmalloc(cifsFile->resume_name_length, GFP_KERNEL); - cFYI(1,("Last file: %s with name %d bytes long", - lastFindData->FileName, - cifsFile->resume_name_length)); - if(cifsFile->search_resume_name == NULL) { - rc = -ENOMEM; - break; - } - memcpy(cifsFile->search_resume_name, - lastFindData->FileName, - cifsFile->resume_name_length); - } else { - pfindDataUnix = (FILE_UNIX_INFO *)lastFindData; - if (Unicode == TRUE) { - for(i=0;(pfindDataUnix->FileName[i] - | pfindDataUnix->FileName[i+1]); - i+=2) { - if(i > bufsize-64) - break; - } - cifsFile->resume_name_length = i + 2; - } else { - cifsFile->resume_name_length = - strnlen(pfindDataUnix->FileName, - bufsize-63); - } - if(cifsFile->resume_name_length > bufsize - 64) { - cFYI(1,("Illegal resume file name length %d", - cifsFile->resume_name_length)); - rc = -ENOMEM; - break; - } - cifsFile->search_resume_name = - kmalloc(cifsFile->resume_name_length, GFP_KERNEL); - cFYI(1,("Last file: %s with name %d bytes long", - pfindDataUnix->FileName, - cifsFile->resume_name_length)); - if(cifsFile->search_resume_name == NULL) { - rc = -ENOMEM; - break; - } - memcpy(cifsFile->search_resume_name, - pfindDataUnix->FileName, - cifsFile->resume_name_length); - } - for (i = 2; i < count + 2; i++) { - if (UnixSearch == FALSE) { - __u32 len = le32_to_cpu(pfindData->FileNameLength); - if (Unicode == TRUE) - len = - cifs_strfromUCS_le - (pfindData->FileName, - (wchar_t *) - pfindData->FileName, - len / 2, - cifs_sb->local_nls); - qstring.len = len; - if (((len != 1) - || (pfindData->FileName[0] != '.')) - && ((len != 2) - || (pfindData-> - FileName[0] != '.') - || (pfindData-> - FileName[1] != '.'))) { - if(cifs_filldir(&qstring, - pfindData, - file, filldir, - direntry)) { - /* do not end search if - kernel not ready to take - remaining entries yet */ - reset_resume_key(file, pfindData->FileName,qstring.len, - Unicode, cifs_sb->local_nls); - findParms.EndofSearch = 0; - break; - } - file->f_pos++; - } - } else { /* UnixSearch */ - pfindDataUnix = - (FILE_UNIX_INFO *) pfindData; - if (Unicode == TRUE) - qstring.len = - cifs_strfromUCS_le - (pfindDataUnix->FileName, - (wchar_t *) - pfindDataUnix->FileName, - MAX_PATHCONF, - cifs_sb->local_nls); - else - qstring.len = - strnlen(pfindDataUnix-> - FileName, - MAX_PATHCONF); - if (((qstring.len != 1) - || (pfindDataUnix-> - FileName[0] != '.')) - && ((qstring.len != 2) - || (pfindDataUnix-> - FileName[0] != '.') - || (pfindDataUnix-> - FileName[1] != '.'))) { - if(cifs_filldir_unix(&qstring, - pfindDataUnix, - file, - filldir, - direntry)) { - /* do not end search if - kernel not ready to take - remaining entries yet */ - findParms.EndofSearch = 0; - reset_resume_key(file, pfindDataUnix->FileName, - qstring.len,Unicode,cifs_sb->local_nls); - break; - } - file->f_pos++; - } - } - /* works also for Unix ff struct since first field of both */ - pfindData = - (FILE_DIRECTORY_INFO *) ((char *) pfindData - + le32_to_cpu(pfindData->NextEntryOffset)); - /* BB also should check to make sure that pointer is not beyond the end of the SMB */ - /* if(pfindData > lastFindData) rc = -EIO; break; */ - } /* end for loop */ - if ((findParms.EndofSearch != 0) && cifsFile) { - cifsFile->srch_inf.endOfSearch = TRUE; - if(findParms.SearchCount == cpu_to_le16(2)) - cifsFile->srch_inf.emptyDir = TRUE; - } - } else { - if (cifsFile) - cifsFile->srch_inf.endOfSearch = TRUE; - /* unless parent directory gone do not return error */ - rc = 0; - } - break; - default: - if (file->private_data == NULL) { - rc = -EBADF; - cFYI(1, - ("Readdir on closed srch, pos = %lld", - file->f_pos)); - } else { - cifsFile = (struct cifsFileInfo *) file->private_data; - if (cifsFile->srch_inf.endOfSearch) { - rc = 0; - cFYI(1, ("End of search ")); - break; - } - searchHandle = cifsFile->netfid; - rc = CIFSFindNext(xid, pTcon, pfindData, - &findNextParms, searchHandle, - cifsFile->search_resume_name, - cifsFile->resume_name_length, - cifsFile->srch_inf.resume_key, - &Unicode, &UnixSearch); - cFYI(1,("Count: %d End: %d ", - le16_to_cpu(findNextParms.SearchCount), - le16_to_cpu(findNextParms.EndofSearch))); - if ((rc == 0) && (findNextParms.SearchCount != 0)) { - /* BB save off resume key, key name and name length */ - __u16 count = le16_to_cpu(findNextParms.SearchCount); - lastFindData = - (FILE_DIRECTORY_INFO *) ((char *) pfindData - + le16_to_cpu(findNextParms.LastNameOffset)); - if((char *)lastFindData > (char *)pfindData + bufsize) { - cFYI(1,("last search entry past end of packet")); - rc = -EIO; - break; - } - /* Offset of resume key same for levels 257 and 514 */ - cifsFile->srch_inf.resume_key = lastFindData->FileIndex; - - if(UnixSearch == FALSE) { - cifsFile->resume_name_length = - le32_to_cpu(lastFindData->FileNameLength); - if(cifsFile->resume_name_length > bufsize - 64) { - cFYI(1,("Illegal resume file name length %d", - cifsFile->resume_name_length)); - rc = -ENOMEM; - break; - } - /* Free the memory allocated by previous findfirst - or findnext call - we can not reuse the memory since - the resume name may not be same string length */ - if(cifsFile->search_resume_name) - kfree(cifsFile->search_resume_name); - cifsFile->search_resume_name = - kmalloc(cifsFile->resume_name_length, GFP_KERNEL); - cFYI(1,("Last file: %s with name %d bytes long", - lastFindData->FileName, - cifsFile->resume_name_length)); - if(cifsFile->search_resume_name == NULL) { - rc = -ENOMEM; - break; - } - - memcpy(cifsFile->search_resume_name, - lastFindData->FileName, - cifsFile->resume_name_length); - } else { - pfindDataUnix = (FILE_UNIX_INFO *)lastFindData; - if (Unicode == TRUE) { - for(i=0;(pfindDataUnix->FileName[i] - | pfindDataUnix->FileName[i+1]); - i+=2) { - if(i > bufsize-64) - break; - } - cifsFile->resume_name_length = i + 2; - } else { - cifsFile->resume_name_length = - strnlen(pfindDataUnix-> - FileName, - MAX_PATHCONF); - } - if(cifsFile->resume_name_length > bufsize - 64) { - cFYI(1,("Illegal resume file name length %d", - cifsFile->resume_name_length)); - rc = -ENOMEM; - break; - } - /* Free the memory allocated by previous findfirst - or findnext call - we can not reuse the memory since - the resume name may not be same string length */ - if(cifsFile->search_resume_name) - kfree(cifsFile->search_resume_name); - cifsFile->search_resume_name = - kmalloc(cifsFile->resume_name_length, GFP_KERNEL); - cFYI(1,("fnext last file: %s with name %d bytes long", - pfindDataUnix->FileName, - cifsFile->resume_name_length)); - if(cifsFile->search_resume_name == NULL) { - rc = -ENOMEM; - break; - } - memcpy(cifsFile->search_resume_name, - pfindDataUnix->FileName, - cifsFile->resume_name_length); - } - - for (i = 0; i < count; i++) { - __u32 len = le32_to_cpu(pfindData-> - FileNameLength); - if (UnixSearch == FALSE) { - if (Unicode == TRUE) - len = - cifs_strfromUCS_le - (pfindData->FileName, - (wchar_t *) - pfindData->FileName, - len / 2, - cifs_sb->local_nls); - qstring.len = len; - if (((len != 1) - || (pfindData->FileName[0] != '.')) - && ((len != 2) - || (pfindData->FileName[0] != '.') - || (pfindData->FileName[1] != - '.'))) { - if(cifs_filldir - (&qstring, - pfindData, - file, filldir, - direntry)) { - /* do not end search if - kernel not ready to take - remaining entries yet */ - findNextParms.EndofSearch = 0; - reset_resume_key(file, pfindData->FileName,qstring.len, - Unicode,cifs_sb->local_nls); - break; - } - file->f_pos++; - } - } else { /* UnixSearch */ - pfindDataUnix = - (FILE_UNIX_INFO *) - pfindData; - if (Unicode == TRUE) - qstring.len = - cifs_strfromUCS_le - (pfindDataUnix->FileName, - (wchar_t *) - pfindDataUnix->FileName, - MAX_PATHCONF, - cifs_sb->local_nls); - else - qstring.len = - strnlen - (pfindDataUnix-> - FileName, - MAX_PATHCONF); - if (((qstring.len != 1) - || (pfindDataUnix-> - FileName[0] != '.')) - && ((qstring.len != 2) - || (pfindDataUnix-> - FileName[0] != '.') - || (pfindDataUnix-> - FileName[1] != - '.'))) { - if(cifs_filldir_unix - (&qstring, - pfindDataUnix, - file, filldir, - direntry)) { - /* do not end search if - kernel not ready to take - remaining entries yet */ - findNextParms.EndofSearch = 0; - reset_resume_key(file, pfindDataUnix->FileName,qstring.len, - Unicode,cifs_sb->local_nls); - break; - } - file->f_pos++; - } - } - pfindData = (FILE_DIRECTORY_INFO *) ((char *) pfindData + - le32_to_cpu(pfindData->NextEntryOffset)); - /* works also for Unix find struct since first field of both */ - /* BB also should check to ensure pointer not beyond end of SMB */ - } /* end for loop */ - if (findNextParms.EndofSearch != 0) { - cifsFile->srch_inf.endOfSearch = TRUE; - } - } else { - cifsFile->srch_inf.endOfSearch = TRUE; - rc = 0; /* unless parent directory disappeared - do not - return error here (eg Access Denied or no more files) */ - } - } - } /* end switch */ - if (data) - kfree(data); - if (full_path) - kfree(full_path); - FreeXid(xid); - - return rc; -} -int cifs_prepare_write(struct file *file, struct page *page, +static int cifs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) { int rc = 0; diff -Nru a/fs/cifs/inode.c b/fs/cifs/inode.c --- a/fs/cifs/inode.c 2005-03-08 01:32:25 -08:00 +++ b/fs/cifs/inode.c 2005-03-08 01:32:25 -08:00 @@ -30,8 +30,6 @@ #include "cifs_debug.h" #include "cifs_fs_sb.h" -extern int is_size_safe_to_change(struct cifsInodeInfo *); - int cifs_get_inode_info_unix(struct inode **pinode, const unsigned char *search_path, @@ -982,13 +980,12 @@ cifs_sb->local_nls); if(rc == -EOPNOTSUPP) { cFYI(1,("OS2 level of SetPathInfo not implemented")); - /* Need to convert time_buf into old format, - but probably better to do that inside the function - below rather than here */ - /* Better to return EOPNOTSUPP until function - below is ready */ + /* For older servers converts time_buf into old DOS style + level which uses two second granularity */ + + /* return EOPNOTSUPP until function below is ready */ /* CIFSSMBSetTimesLegacy(xid, pTcon, full_path, - FILE_INFO_STANDARD * data, cifs_sb->local_nls); */ + &time_buf, cifs_sb->local_nls); */ } } diff -Nru a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/fs/cifs/ioctl.c 2005-03-08 01:32:25 -08:00 @@ -0,0 +1,49 @@ +/* + * fs/cifs/ioctl.c + * + * vfs operations that deal with io control + * + * Copyright (C) International Business Machines Corp., 2005 + * Author(s): Steve French (sfrench@us.ibm.com) + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include +#include +#include "cifspdu.h" +#include "cifsglob.h" +#include "cifsproto.h" +#include "cifs_debug.h" + +int cifs_ioctl (struct inode * inode, struct file * filep, + unsigned int command, unsigned long arg) +{ + int rc = -ENOTTY; /* strange error - but the precedent */ +#ifdef CONFIG_CIFS_POSIX + cFYI(1,("ioctl file %p cmd %u arg %lu",filep,command,arg)); + switch(command) { + case EXT2_IOC_GETFLAGS: + cFYI(1,("get flags not implemented yet")); + return -EOPNOTSUPP; + case EXT2_IOC_SETFLAGS: + cFYI(1,("set flags not implemented yet")); + return -EOPNOTSUPP; + default: + cFYI(1,("unsupported ioctl")); + return rc; + } +#endif /* CONFIG_CIFS_POSIX */ + return rc; +} diff -Nru a/fs/cifs/misc.c b/fs/cifs/misc.c --- a/fs/cifs/misc.c 2005-03-08 01:32:25 -08:00 +++ b/fs/cifs/misc.c 2005-03-08 01:32:25 -08:00 @@ -33,7 +33,7 @@ extern mempool_t *cifs_req_poolp; extern struct task_struct * oplockThread; -__u16 GlobalMid; /* multiplex id - rotating counter */ +static __u16 GlobalMid; /* multiplex id - rotating counter */ /* The xid serves as a useful identifier for each incoming vfs request, in a similar way to the mid which is useful to track each sent smb, diff -Nru a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c --- a/fs/cifs/netmisc.c 2005-03-08 01:32:25 -08:00 +++ b/fs/cifs/netmisc.c 2005-03-08 01:32:25 -08:00 @@ -43,7 +43,7 @@ int posix_code; }; -const struct smb_to_posix_error mapping_table_ERRDOS[] = { +static const struct smb_to_posix_error mapping_table_ERRDOS[] = { {ERRbadfunc, -EINVAL}, {ERRbadfile, -ENOENT}, {ERRbadpath, -ENOTDIR}, @@ -81,7 +81,7 @@ {0, 0} }; -const struct smb_to_posix_error mapping_table_ERRSRV[] = { +static const struct smb_to_posix_error mapping_table_ERRSRV[] = { {ERRerror, -EIO}, {ERRbadpw, -EPERM}, {ERRbadtype, -EREMOTE}, @@ -120,7 +120,7 @@ {0, 0} }; -const struct smb_to_posix_error mapping_table_ERRHRD[] = { +static const struct smb_to_posix_error mapping_table_ERRHRD[] = { {0, 0} }; diff -Nru a/fs/cifs/readdir.c b/fs/cifs/readdir.c --- a/fs/cifs/readdir.c 2005-03-08 01:32:25 -08:00 +++ b/fs/cifs/readdir.c 2005-03-08 01:32:25 -08:00 @@ -29,13 +29,7 @@ #include "cifs_unicode.h" #include "cifs_debug.h" #include "cifs_fs_sb.h" - -extern int CIFSFindFirst2(const int xid, struct cifsTconInfo *tcon, - const char *searchName, const struct nls_table *nls_codepage, - __u16 *searchHandle, struct cifs_search_info * psrch_inf); - -extern int CIFSFindNext2(const int xid, struct cifsTconInfo *tcon, - __u16 searchHandle, struct cifs_search_info * psrch_inf); +#include "cifsfs.h" extern int construct_dentry(struct qstr *qstring, struct file *file, struct inode **ptmp_inode, struct dentry **pnew_dentry); @@ -71,6 +65,57 @@ } } */ +/* Returns one if new inode created (which therefore needs to be hashed) */ +/* Might check in the future if inode number changed so we can rehash inode */ +int +construct_dentry(struct qstr *qstring, struct file *file, + struct inode **ptmp_inode, struct dentry **pnew_dentry) +{ + struct dentry *tmp_dentry; + struct cifs_sb_info *cifs_sb; + struct cifsTconInfo *pTcon; + int rc = 0; + + cFYI(1, ("For %s ", qstring->name)); + cifs_sb = CIFS_SB(file->f_dentry->d_sb); + pTcon = cifs_sb->tcon; + + qstring->hash = full_name_hash(qstring->name, qstring->len); + tmp_dentry = d_lookup(file->f_dentry, qstring); + if (tmp_dentry) { + cFYI(0, (" existing dentry with inode 0x%p", tmp_dentry->d_inode)); + *ptmp_inode = tmp_dentry->d_inode; + /* BB overwrite the old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len ?? */ + if(*ptmp_inode == NULL) { + *ptmp_inode = new_inode(file->f_dentry->d_sb); + if(*ptmp_inode == NULL) + return rc; + rc = 1; + d_instantiate(tmp_dentry, *ptmp_inode); + } + } else { + tmp_dentry = d_alloc(file->f_dentry, qstring); + if(tmp_dentry == NULL) { + cERROR(1,("Failed allocating dentry")); + *ptmp_inode = NULL; + return rc; + } + + *ptmp_inode = new_inode(file->f_dentry->d_sb); + tmp_dentry->d_op = &cifs_dentry_ops; + if(*ptmp_inode == NULL) + return rc; + rc = 1; + d_instantiate(tmp_dentry, *ptmp_inode); + d_rehash(tmp_dentry); + } + + tmp_dentry->d_time = jiffies; + *pnew_dentry = tmp_dentry; + return rc; +} + + static int initiate_cifs_search(const int xid, struct file * file) { int rc = 0; @@ -123,7 +168,7 @@ cifsFile->srch_inf.info_level = SMB_FIND_FILE_DIRECTORY_INFO; } - rc = CIFSFindFirst2(xid, pTcon,full_path,cifs_sb->local_nls, + rc = CIFSFindFirst(xid, pTcon,full_path,cifs_sb->local_nls, &cifsFile->netfid, &cifsFile->srch_inf); if(rc == 0) cifsFile->invalidHandle = FALSE; @@ -279,7 +324,7 @@ while((index_to_find >= cifsFile->srch_inf.index_of_last_entry) && (rc == 0) && (cifsFile->srch_inf.endOfSearch == FALSE)){ cFYI(1,("calling findnext2")); - rc = CIFSFindNext2(xid,pTcon,cifsFile->netfid, &cifsFile->srch_inf); + rc = CIFSFindNext(xid,pTcon,cifsFile->netfid, &cifsFile->srch_inf); if(rc) return -ENOENT; } @@ -394,7 +439,7 @@ static int -cifs_filldir2(char * pfindEntry, struct file *file, +cifs_filldir(char * pfindEntry, struct file *file, filldir_t filldir, void *direntry,char * scratch_buf) { int rc = 0; @@ -459,7 +504,7 @@ return rc; } -int cifs_save_resume_key(const char * current_entry,struct cifsFileInfo * cifsFile) +static int cifs_save_resume_key(const char * current_entry,struct cifsFileInfo * cifsFile) { int rc = 0; unsigned int len = 0; @@ -515,7 +560,7 @@ return rc; } -int cifs_readdir2(struct file *file, void *direntry, filldir_t filldir) +int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) { int rc = 0; int xid,i; @@ -625,7 +670,7 @@ fill in inode new_inode (which makes number locally) } also create local inode for per reasons unless new mount parm says otherwise */ - rc = cifs_filldir2(current_entry, file, + rc = cifs_filldir(current_entry, file, filldir, direntry,tmp_buf); file->f_pos++; if(file->f_pos == cifsFile->srch_inf.index_of_last_entry) { diff -Nru a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c --- a/fs/cifs/smbencrypt.c 2005-03-08 01:32:25 -08:00 +++ b/fs/cifs/smbencrypt.c 2005-03-08 01:32:25 -08:00 @@ -186,7 +186,8 @@ } /* Does the NTLMv2 owfs of a user's password */ -void +#if 0 /* function not needed yet - but will be soon */ +static void ntv2_owf_gen(const unsigned char owf[16], const char *user_n, const char *domain_n, unsigned char kr_buf[16], const struct nls_table *nls_codepage) @@ -219,6 +220,7 @@ kfree(user_u); } +#endif /* Does the des encryption from the NT or LM MD4 hash. */ void diff -Nru a/fs/cifs/transport.c b/fs/cifs/transport.c --- a/fs/cifs/transport.c 2005-03-08 01:32:25 -08:00 +++ b/fs/cifs/transport.c 2005-03-08 01:32:25 -08:00 @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -34,7 +35,7 @@ extern mempool_t *cifs_mid_poolp; extern kmem_cache_t *cifs_oplock_cachep; -struct mid_q_entry * +static struct mid_q_entry * AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses) { struct mid_q_entry *temp; @@ -70,7 +71,7 @@ return temp; } -void +static void DeleteMidQEntry(struct mid_q_entry *midEntry) { spin_lock(&GlobalMid_Lock); @@ -156,8 +157,7 @@ rc = -EAGAIN; break; } - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(HZ/2); + msleep(500); continue; } if (rc < 0) @@ -179,6 +179,70 @@ #ifdef CIFS_EXPERIMENTAL /* BB finish off this function, adding support for writing set of pages as iovec */ /* and also adding support for operations that need to parse the response smb */ + +int +smb_sendv(struct socket *ssocket, struct smb_hdr *smb_buffer, + unsigned int smb_buf_length, struct kvec * write_vector /* page list */, struct sockaddr *sin) +{ + int rc = 0; + int i = 0; + struct msghdr smb_msg; + number_of_pages += 1; /* account for SMB header */ + struct kvec * piov = kmalloc(number_of_pages * sizeof(struct kvec)); + if(i=0;ismb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length); + cFYI(1, ("Sending smb of length %d ", smb_buf_length)); + dump_smb(smb_buffer, len); + + while (len > 0) { + rc = kernel_sendmsg(ssocket, &smb_msg, &iov, number_of_pages, len?); + if ((rc == -ENOSPC) || (rc == -EAGAIN)) { + i++; + if(i > 60) { + cERROR(1, + ("sends on sock %p stuck for 30 seconds", + ssocket)); + rc = -EAGAIN; + break; + } + msleep(500); + continue; + } + if (rc < 0) + break; + iov.iov_base += rc; + iov.iov_len -= rc; + len -= rc; + } + + if (rc < 0) { + cERROR(1,("Error %d sending data on socket to server.", rc)); + } else { + rc = 0; + } + + return rc; +} + + int CIFSSendRcv(const unsigned int xid, struct cifsSesInfo *ses, struct smb_hdr *in_buf, struct kvec * write_vector /* page list */, int *pbytes_returned, const int long_op) @@ -285,7 +349,7 @@ rc = cifs_sign_smb(in_buf, ses, &midQ->sequence_number); midQ->midState = MID_REQUEST_SUBMITTED; -/* rc = smb_send2(ses->server->ssocket, in_buf, in_buf->smb_buf_length, piovec, +/* rc = smb_sendv(ses->server->ssocket, in_buf, in_buf->smb_buf_length, piovec, (struct sockaddr *) &(ses->server->addr.sockAddr));*/ if(rc < 0) { DeleteMidQEntry(midQ); diff -Nru a/fs/cifs/xattr.c b/fs/cifs/xattr.c --- a/fs/cifs/xattr.c 2005-03-08 01:32:25 -08:00 +++ b/fs/cifs/xattr.c 2005-03-08 01:32:25 -08:00 @@ -71,16 +71,21 @@ } if(ea_name == NULL) { cFYI(1,("Null xattr names not supported")); - } else if(strncmp(ea_name,CIFS_XATTR_USER_PREFIX,5)) { + } else if(strncmp(ea_name,CIFS_XATTR_USER_PREFIX,5) + && (strncmp(ea_name,CIFS_XATTR_OS2_PREFIX,4))) { cFYI(1,("illegal xattr namespace %s (only user namespace supported)",ea_name)); /* BB what if no namespace prefix? */ /* Should we just pass them to server, except for system and perhaps security prefixes? */ } else { + if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) + goto remove_ea_exit; + ea_name+=5; /* skip past user. prefix */ rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,NULL, (__u16)0, cifs_sb->local_nls); } +remove_ea_exit: if (full_path) kfree(full_path); FreeXid(xid); @@ -135,6 +140,8 @@ if(ea_name == NULL) { cFYI(1,("Null xattr names not supported")); } else if(strncmp(ea_name,CIFS_XATTR_USER_PREFIX,5) == 0) { + if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) + goto set_ea_exit; if(strncmp(ea_name,CIFS_XATTR_DOS_ATTRIB,14) == 0) { cFYI(1,("attempt to set cifs inode metadata")); } @@ -142,6 +149,9 @@ rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,ea_value, (__u16)value_size, cifs_sb->local_nls); } else if(strncmp(ea_name, CIFS_XATTR_OS2_PREFIX,4) == 0) { + if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) + goto set_ea_exit; + ea_name += 4; /* skip past os2. prefix */ rc = CIFSSMBSetEA(xid,pTcon,full_path,ea_name,ea_value, (__u16)value_size, cifs_sb->local_nls); @@ -174,7 +184,8 @@ system and perhaps security prefixes? */ } } - + +set_ea_exit: if (full_path) kfree(full_path); FreeXid(xid); @@ -218,6 +229,9 @@ if(ea_name == NULL) { cFYI(1,("Null xattr names not supported")); } else if(strncmp(ea_name,CIFS_XATTR_USER_PREFIX,5) == 0) { + if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) + goto get_ea_exit; + if(strncmp(ea_name,CIFS_XATTR_DOS_ATTRIB,14) == 0) { cFYI(1,("attempt to query cifs inode metadata")); /* revalidate/getattr then populate from inode */ @@ -226,6 +240,9 @@ rc = CIFSSMBQueryEA(xid,pTcon,full_path,ea_name,ea_value, buf_size, cifs_sb->local_nls); } else if(strncmp(ea_name, CIFS_XATTR_OS2_PREFIX,4) == 0) { + if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR) + goto get_ea_exit; + ea_name += 4; /* skip past os2. prefix */ rc = CIFSSMBQueryEA(xid,pTcon,full_path,ea_name,ea_value, buf_size, cifs_sb->local_nls); @@ -263,6 +280,7 @@ if(rc == -EINVAL) rc = -EOPNOTSUPP; +get_ea_exit: if (full_path) kfree(full_path); FreeXid(xid);