bk://cifs.bkbits.net/linux-2.5cifs cifs.adm@bkbits.net|ChangeSet|20050311204341|24663 cifs.adm # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2005/03/09 23:13:25-06:00 stevef@smfhome.smfdom # [CIFS] Fix compile warning # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/cifs_debug.c # 2005/03/09 23:13:16-06:00 stevef@smfhome.smfdom +1 -1 # fix compile warning # # ChangeSet # 2005/03/09 23:09:25-06:00 stevef@smfhome.smfdom # [CIFS] null pointer fixes pointed out by the coverity tool. Remove redundant # checks for null SMBs (in the cases where the can not be null) - pointed out by # the coverity code checker tool as well. # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/readdir.c # 2005/03/09 23:09:16-06:00 stevef@smfhome.smfdom +3 -3 # fix null pointer check - pointed out by coverity tool # # fs/cifs/inode.c # 2005/03/09 23:09:16-06:00 stevef@smfhome.smfdom +2 -1 # added check for null mapping ptr - pointed out by coverity checker # # fs/cifs/cifssmb.c # 2005/03/09 23:09:15-06:00 stevef@smfhome.smfdom +77 -91 # remove redundant check for null SMB pointer (which we know can not # be null in these places) addressing lots of warning messages pointed out # by the coverity checker tool. Also fixed one place where SMB pointer was # used before we checked if smb_init failed. # # fs/cifs/cifs_debug.c # 2005/03/09 23:09:15-06:00 stevef@smfhome.smfdom +3 -2 # Address bug pointed out by coverity checking for null tcp session pointer # # ChangeSet # 2005/03/09 20:46:48-06:00 stevef@smf-t23.(none) # [CIFS] fix build break # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/cifssmb.c # 2005/03/09 20:46:05-06:00 stevef@smf-t23.(none) +1 -1 # fix build break # # ChangeSet # 2005/03/09 16:37:52-06:00 stevef@stevef95.austin.ibm.com # [CIFS] Add new cifs posix qfs info level for improved handling of statfs # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/cifssmb.c # 2005/03/09 16:32:53-06:00 stevef@stevef95.austin.ibm.com +11 -3 # Add new cifs posix qfs info level for improved handling of statfs # # fs/cifs/cifsproto.h # 2005/03/09 16:32:53-06:00 stevef@stevef95.austin.ibm.com +2 -0 # Add new cifs posix qfs info level for improved handling of statfs # # fs/cifs/CHANGES # 2005/03/09 16:32:53-06:00 stevef@stevef95.austin.ibm.com +1 -0 # update cifs change log # # ChangeSet # 2005/03/08 18:40:07-06:00 stevef@stevef95.austin.ibm.com # [CIFS] add new statfs call for posix extensions # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/cifssmb.c # 2005/03/08 18:39:38-06:00 stevef@stevef95.austin.ibm.com +72 -0 # add new statfs call for posix extensions # # fs/cifs/cifspdu.h # 2005/03/08 18:39:38-06:00 stevef@stevef95.austin.ibm.com +15 -0 # add new statfs call for posix extensions # # ChangeSet # 2005/03/08 18:14:21-06:00 stevef@stevef95.austin.ibm.com # [CIFS] Add support for setting timestaps by handle for NT4 servers # # Signed-off-by: Steve French (sfrench@us.ibm.com) # # fs/cifs/inode.c # 2005/03/08 18:12:52-06:00 stevef@stevef95.austin.ibm.com +26 -6 # Add support for setting timestaps by handle for NT4 servers # # fs/cifs/cifssmb.c # 2005/03/08 18:12:51-06:00 stevef@stevef95.austin.ibm.com +79 -3 # Add support for setting timestaps by handle for NT4 servers # # fs/cifs/cifsproto.h # 2005/03/08 18:12:51-06:00 stevef@stevef95.austin.ibm.com +6 -3 # Add support for setting timestaps by handle for NT4 servers # # fs/cifs/README # 2005/03/08 18:12:51-06:00 stevef@stevef95.austin.ibm.com +8 -2 # update readme to reflect new mount parms nouser_xattr and user_xattr # # fs/cifs/CHANGES # 2005/03/08 18:12:51-06:00 stevef@stevef95.austin.ibm.com +2 -0 # update change log # # 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-11 13:15:10 -08:00 +++ b/fs/cifs/AUTHORS 2005-03-11 13:15:10 -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-11 13:15:10 -08:00 +++ b/fs/cifs/CHANGES 2005-03-11 13:15:10 -08:00 @@ -1,3 +1,15 @@ +Version 1.30 +------------ +Allow new nouser_xattr mount parm to disable xattr support for user namespace. +Do not flag user_xattr mount parm in dmesg. Retry failures setting file time +(mostly affects NT4 servers) by retry with handle based network operation. +Add new POSIX Query FS Info for returning statfs info more accurately. + +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 +19,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-11 13:15:10 -08:00 +++ b/fs/cifs/Makefile 2005-03-11 13:15:10 -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/README b/fs/cifs/README --- a/fs/cifs/README 2005-03-11 13:15:10 -08:00 +++ b/fs/cifs/README 2005-03-11 13:15:10 -08:00 @@ -122,12 +122,14 @@ 3.0.6 and later (also EA support works in all versions of Windows, at least to shares on NTFS filesystems). Extended Attribute (xattr) support is an optional feature of most Linux filesystems which may require enabling via -make menuconfig. +make menuconfig. Client support for extended attributes (user xattr) can be +disabled on a per-mount basis by specifying "nouser_xattr" on mount. The CIFS client can get and set POSIX ACLs (getfacl, setfacl) to Samba servers version 3.10 and later. Setting POSIX ACLs requires enabling both XATTR and then POSIX support in the CIFS configuration options when building the cifs -module. +module. POSIX ACL support can be disabled on a per mount basic by specifying +"noacl" on mount. Some administrators may want to change Samba's smb.conf "map archive" and "create mask" parameters from the default. Unless the create mask is changed @@ -370,6 +372,10 @@ acl Allow setfacl and getfacl to manage posix ACLs if server supports them. (default) noacl Do not allow setfacl and getfacl calls on this mount + user_xattr Allow getting and setting user xattrs as OS/2 EAs (extended + attributes) to the server (default) e.g. via setfattr + and getfattr utilities. + nouser_xattr Do not allow getfattr/setfattr to get/set xattrs The mount.cifs mount helper also accepts a few mount options before -o including: diff -Nru a/fs/cifs/asn1.c b/fs/cifs/asn1.c --- a/fs/cifs/asn1.c 2005-03-11 13:15:10 -08:00 +++ b/fs/cifs/asn1.c 2005-03-11 13:15:10 -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-11 13:15:10 -08:00 +++ b/fs/cifs/cifs_debug.c 2005-03-11 13:15:10 -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) { @@ -89,12 +89,13 @@ ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList); length = sprintf(buf, - "\n%d) Name: %s Domain: %s Mounts: %d ServerOS: %s \n\tServerNOS: %s\tCapabilities: 0x%x\n\tSMB session status: %d\tTCP status: %d", + "\n%d) Name: %s Domain: %s Mounts: %d ServerOS: %s \n\tServerNOS: %s\tCapabilities: 0x%x\n\tSMB session status: %d\t", i, ses->serverName, ses->serverDomain, atomic_read(&ses->inUse), - ses->serverOS, ses->serverNOS, ses->capabilities,ses->status,ses->server->tcpStatus); + ses->serverOS, ses->serverNOS, ses->capabilities,ses->status); buf += length; if(ses->server) { - buf += sprintf(buf, "\n\tLocal Users To Server: %d SecMode: 0x%x Req Active: %d", + buf += sprintf(buf, "TCP status: %d\n\tLocal Users To Server: %d SecMode: 0x%x Req Active: %d", + ses->server->tcpStatus, atomic_read(&ses->server->socketUseCount), ses->server->secMode, atomic_read(&ses->server->inFlight)); @@ -178,7 +179,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 +287,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-11 13:15:10 -08:00 +++ b/fs/cifs/cifs_fs_sb.h 2005-03-11 13:15:10 -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-11 13:15:10 -08:00 +++ b/fs/cifs/cifsencrypt.c 2005-03-11 13:15:10 -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-11 13:15:10 -08:00 +++ b/fs/cifs/cifsfs.c 2005-03-11 13:15:10 -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-11 13:15:10 -08:00 +++ b/fs/cifs/cifsfs.h 2005-03-11 13:15:10 -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-11 13:15:10 -08:00 +++ b/fs/cifs/cifspdu.h 2005-03-11 13:15:10 -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 @@ -1325,6 +1327,7 @@ #define SMB_QUERY_FS_DEVICE_INFO 0x104 #define SMB_QUERY_FS_ATTRIBUTE_INFO 0x105 #define SMB_QUERY_CIFS_UNIX_INFO 0x200 +#define SMB_QUERY_POSIX_FS_INFO 0x201 #define SMB_QUERY_LABEL_INFO 0x3ea #define SMB_QUERY_FS_QUOTA_INFO 0x3ee #define SMB_QUERY_FS_FULL_SIZE_INFO 0x3ef @@ -1505,6 +1508,20 @@ #define CIFS_UNIX_POSIX_ACL_CAP 0x00000002 #define CIFS_UNIX_XATTR_CAP 0x00000004 /*support for new namespace*/ +typedef struct { + /* For undefined values return -1 in that field */ + __le32 OptimalTransferSize; /* bsize on some os, iosize on other os */ + __le32 BlockSize; + __le64 TotalBlocks; /* redundant but easy to return */ + __le64 BlocksAvail; /* redundant but easy to return */ + __le64 UserBlocksAvail; /* bavail */ + __le64 TotalFileNodes; + __le64 FreeFileNodes; + __le64 FileSysIdentifier; /* fsid */ + /* NB Namelen comes from FILE_SYSTEM_ATTRIBUTE_INFO call */ + /* NB flags can come from FILE_SYSTEM_DEVICE_INFO call */ +} FILE_SYSTEM_POSIX_INFO; + /* DeviceType Flags */ #define FILE_DEVICE_CD_ROM 0x00000002 #define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003 @@ -1592,17 +1609,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 TwoSeconds:5; + __u16 Minutes:6; + __u16 Hours:5; +} SMB_TIME; + 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; + __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-11 13:15:10 -08:00 +++ b/fs/cifs/cifsproto.h 2005-03-11 13:15:10 -08:00 @@ -1,7 +1,7 @@ /* * fs/cifs/cifsproto.h * - * Copyright (c) International Business Machines Corp., 2002,2004 + * Copyright (c) International Business Machines Corp., 2002,2005 * Author(s): Steve French (sfrench@us.ibm.com) * * This library is free software; you can redistribute it and/or modify @@ -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); @@ -128,10 +123,18 @@ const struct nls_table *nls_codepage); extern int CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon, const struct nls_table *nls_codepage); +extern int CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon, + struct kstatfs *FSData, const struct nls_table *nls_codepage); 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 CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, + const FILE_BASIC_INFO * data, __u16 fid); +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 +214,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 +247,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-11 13:15:10 -08:00 +++ b/fs/cifs/cifssmb.c 2005-03-11 13:15:10 -08:00 @@ -1,7 +1,7 @@ /* * fs/cifs/cifssmb.c * - * Copyright (C) International Business Machines Corp., 2002,2003 + * Copyright (C) International Business Machines Corp., 2002,2005 * Author(s): Steve French (sfrench@us.ibm.com) * * Contains the routines for constructing the SMB PDUs themselves @@ -78,6 +78,7 @@ /* BB Add call to invalidate_inodes(sb) for all superblocks mounted to this tcon */ } +/* If the return code is zero, this function must fill in request_buf pointer */ static int small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, void **request_buf /* returned */) @@ -154,7 +155,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; } @@ -169,6 +170,7 @@ return rc; } +/* If the return code is zero, this function must fill in request_buf pointer */ static int smb_init(int smb_command, int wct, struct cifsTconInfo *tcon, void **request_buf /* returned */ , @@ -246,7 +248,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 +450,7 @@ return 0; } - if((tcon->ses == 0) || (tcon->ses->server == 0)) { + if((tcon->ses == NULL) || (tcon->ses->server == NULL)) { up(&tcon->tconSem); return -EIO; } @@ -496,6 +498,11 @@ return -EBUSY; } rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB); + if (rc) { + up(&ses->sesSem); + return rc; + } + smb_buffer_response = (struct smb_hdr *)pSMB; /* BB removeme BB */ if(ses->server) { @@ -504,11 +511,6 @@ pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE; } - if (rc) { - up(&ses->sesSem); - return rc; - } - pSMB->hdr.Uid = ses->Suid; pSMB->AndXCommand = 0xFF; @@ -579,8 +581,7 @@ } #endif - if (pSMB) - cifs_buf_release(pSMB); + cifs_buf_release(pSMB); if (rc == -EAGAIN) goto DelFileRetry; @@ -630,8 +631,7 @@ } #endif - if (pSMB) - cifs_buf_release(pSMB); + cifs_buf_release(pSMB); if (rc == -EAGAIN) goto RmDirRetry; return rc; @@ -679,8 +679,7 @@ atomic_inc(&tcon->num_mkdirs); } #endif - if (pSMB) - cifs_buf_release(pSMB); + cifs_buf_release(pSMB); if (rc == -EAGAIN) goto MkDirRetry; return rc; @@ -780,8 +779,7 @@ atomic_inc(&tcon->num_opens); #endif } - if (pSMB) - cifs_buf_release(pSMB); + cifs_buf_release(pSMB); if (rc == -EAGAIN) goto openRetry; return rc; @@ -802,6 +800,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 +817,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 +826,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)) { @@ -846,12 +849,10 @@ memcpy(*buf,pReadData,data_length); } } - if (pSMB) { - if(*buf) - cifs_buf_release(pSMB); - else - *buf = (char *)pSMB; - } + if(*buf) + cifs_buf_release(pSMB); + else + *buf = (char *)pSMB; /* Note: On -EAGAIN error only caller can retry on handle based calls since file handle passed in no longer valid */ @@ -868,9 +869,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 +888,39 @@ 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 { - /* No buffer */ - if(pSMB) + else if(ubuf) { + if(copy_from_user(pSMB->Data,ubuf,bytes_sent)) { cifs_buf_release(pSMB); + return -EFAULT; + } + } else { + /* No buffer */ + 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,11 +928,13 @@ 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); + cifs_buf_release(pSMB); /* Note: On -EAGAIN error only caller can retry on handle based calls since file handle passed in no longer valid */ @@ -944,10 +956,12 @@ __u16 byte_count; rc = small_smb_init(SMB_COM_WRITE_ANDX, 14, tcon, (void **) &pSMB); - pSMBr = (WRITE_RSP *)pSMB; /* BB removeme BB */ - if (rc) + if (rc) return rc; + + pSMBr = (WRITE_RSP *)pSMB; /* BB removeme BB */ + /* tcon and ses pointer are checked in smb_init */ if (tcon->ses->server == NULL) return -ECONNABORTED; @@ -980,8 +994,7 @@ } else *nbytes = le16_to_cpu(pSMBr->Count); - if (pSMB) - cifs_small_buf_release(pSMB); + cifs_small_buf_release(pSMB); /* Note: On -EAGAIN error only caller can retry on handle based calls since file handle passed in no longer valid */ @@ -1046,8 +1059,7 @@ if (rc) { cFYI(1, ("Send error in Lock = %d", rc)); } - if (pSMB) - cifs_buf_release(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 */ @@ -1065,12 +1077,13 @@ /* do not retry on dead session on close */ rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB); - pSMBr = (CLOSE_RSP *)pSMB; /* BB removeme BB */ if(rc == -EAGAIN) return 0; if (rc) return rc; + pSMBr = (CLOSE_RSP *)pSMB; /* BB removeme BB */ + pSMB->FileID = (__u16) smb_file_id; pSMB->LastWriteTime = 0; pSMB->ByteCount = 0; @@ -1083,8 +1096,7 @@ } } - if (pSMB) - cifs_small_buf_release(pSMB); + cifs_small_buf_release(pSMB); /* Since session is dead, file will be closed on server already */ if(rc == -EAGAIN) @@ -1161,8 +1173,7 @@ } #endif - if (pSMB) - cifs_buf_release(pSMB); + cifs_buf_release(pSMB); if (rc == -EAGAIN) goto renameRetry; @@ -1241,8 +1252,7 @@ atomic_inc(&pTcon->num_t2renames); } #endif - if (pSMB) - cifs_buf_release(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 */ @@ -1492,8 +1502,7 @@ cFYI(1, ("Send error in SetPathInfo (hard link) = %d", rc)); } - if (pSMB) - cifs_buf_release(pSMB); + cifs_buf_release(pSMB); if (rc == -EAGAIN) goto createHardLinkRetry; @@ -1564,8 +1573,7 @@ if (rc) { cFYI(1, ("Send error in hard link (NT rename) = %d", rc)); } - if (pSMB) - cifs_buf_release(pSMB); + cifs_buf_release(pSMB); if (rc == -EAGAIN) goto winCreateHardLinkRetry; @@ -1665,15 +1673,12 @@ /* just in case so calling code does not go off the end of buffer */ } } - if (pSMB) - cifs_buf_release(pSMB); + cifs_buf_release(pSMB); if (rc == -EAGAIN) goto querySymLinkRetry; return rc; } - - int CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, const unsigned char *searchName, @@ -1723,9 +1728,23 @@ rc = -EIO; /* bad smb */ else { if(data_count && (data_count < 2048)) { - /* could also validate reparse tag && better check name length */ + char * end_of_smb = pSMBr->ByteCount + (char *)&pSMBr->ByteCount; + struct reparse_data * reparse_buf = (struct reparse_data *) ((char *)&pSMBr->hdr.Protocol + data_offset); + if((char*)reparse_buf >= end_of_smb) { + rc = -EIO; + goto qreparse_out; + } + if((reparse_buf->LinkNamesBuf + + reparse_buf->TargetNameOffset + + reparse_buf->TargetNameLen) > + end_of_smb) { + cFYI(1,("reparse buf extended beyond SMB")); + rc = -EIO; + goto qreparse_out; + } + if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) { name_len = UniStrnlen((wchar_t *) (reparse_buf->LinkNamesBuf + @@ -1749,6 +1768,7 @@ cFYI(1,("readlink result - %s ",symlinkinfo)); } } +qreparse_out: if (pSMB) cifs_buf_release(pSMB); @@ -1826,7 +1846,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 +1864,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 +1933,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); } @@ -1969,8 +1988,7 @@ buflen,acl_type,count); } } - if (pSMB) - cifs_buf_release(pSMB); + cifs_buf_release(pSMB); if (rc == -EAGAIN) goto queryAclRetry; return rc; @@ -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; @@ -2049,11 +2066,10 @@ } setACLerrorExit: - if (pSMB) - cifs_buf_release(pSMB); - if (rc == -EAGAIN) + cifs_buf_release(pSMB); + if (rc == -EAGAIN) goto setAclRetry; - return rc; + return rc; } #endif @@ -2072,7 +2088,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); @@ -2133,8 +2149,7 @@ } else rc = -ENOMEM; } - if (pSMB) - cifs_buf_release(pSMB); + cifs_buf_release(pSMB); if (rc == -EAGAIN) goto QPathInfoRetry; @@ -2217,8 +2232,7 @@ sizeof (FILE_UNIX_BASIC_INFO)); } } - if (pSMB) - cifs_buf_release(pSMB); + cifs_buf_release(pSMB); if (rc == -EAGAIN) goto UnixQPathInfoRetry; @@ -2297,8 +2311,8 @@ /* BB fill in */ } - if (pSMB) - cifs_buf_release(pSMB); + + cifs_buf_release(pSMB); if (rc == -EAGAIN) goto findUniqueRetry; @@ -2306,118 +2320,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, @@ -2432,9 +2337,9 @@ int name_len; __u16 params, byte_count; - cFYI(1, ("In FindFirst2")); + cFYI(1, ("In FindFirst")); -findFirst2Retry: +findFirstRetry: rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, (void **) &pSMBr); if (rc) @@ -2504,7 +2409,7 @@ /* BB eventually could optimize out free and realloc of buf */ /* for this case */ if (rc == -EAGAIN) - goto findFirst2Retry; + goto findFirstRetry; } else { /* decode response */ /* BB remember to free buffer if error BB */ rc = validate_t2((struct smb_t2_rsp *)pSMBr); @@ -2533,15 +2438,14 @@ /*cFYI(1,("entries in buf %d index_of_last %d",psrch_inf->entries_in_buffer,psrch_inf->index_of_last_entry)); */ *pnetfid = parms->SearchHandle; } else { - if(pSMB) - cifs_buf_release(pSMB); + cifs_buf_release(pSMB); } } 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; @@ -2552,7 +2456,7 @@ int bytes_returned, name_len; __u16 params, byte_count; - cFYI(1, ("In FindNext2")); + cFYI(1, ("In FindNext")); if(psrch_inf->endOfSearch == TRUE) return -ENOENT; @@ -2659,120 +2563,13 @@ /* Note: On -EAGAIN error only caller can retry on handle based calls since file handle passed in no longer valid */ FNext2_err_exit: - if ((rc != 0) && pSMB) + if (rc != 0) cifs_buf_release(pSMB); return rc; } 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; @@ -2782,14 +2579,15 @@ cFYI(1, ("In CIFSSMBFindClose")); rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB); - pSMBr = (CLOSE_RSP *)pSMB; /* BB removeme BB */ + /* no sense returning error if session restarted - file handle has been closed */ + as file handle has been closed */ if(rc == -EAGAIN) return 0; if (rc) return rc; + pSMBr = (CLOSE_RSP *)pSMB; /* BB removeme BB */ pSMB->FileID = searchHandle; pSMB->ByteCount = 0; rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, @@ -2797,8 +2595,7 @@ if (rc) { cERROR(1, ("Send error in FindClose = %d", rc)); } - if (pSMB) - cifs_small_buf_release(pSMB); + cifs_small_buf_release(pSMB); /* Since session is dead, search handle closed on server already */ if (rc == -EAGAIN) @@ -3087,8 +2884,7 @@ FSData->f_bsize)); } } - if (pSMB) - cifs_buf_release(pSMB); + cifs_buf_release(pSMB); if (rc == -EAGAIN) goto QFSInfoRetry; @@ -3157,8 +2953,7 @@ sizeof (FILE_SYSTEM_ATTRIBUTE_INFO)); } } - if (pSMB) - cifs_buf_release(pSMB); + cifs_buf_release(pSMB); if (rc == -EAGAIN) goto QFSAttributeRetry; @@ -3228,8 +3023,7 @@ sizeof (FILE_SYSTEM_DEVICE_INFO)); } } - if (pSMB) - cifs_buf_release(pSMB); + cifs_buf_release(pSMB); if (rc == -EAGAIN) goto QFSDeviceRetry; @@ -3298,8 +3092,7 @@ sizeof (FILE_SYSTEM_UNIX_INFO)); } } - if (pSMB) - cifs_buf_release(pSMB); + cifs_buf_release(pSMB); if (rc == -EAGAIN) goto QFSUnixRetry; @@ -3308,6 +3101,85 @@ return rc; } + +int +CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon, + struct kstatfs *FSData, const struct nls_table *nls_codepage) +{ +/* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */ + TRANSACTION2_QFSI_REQ *pSMB = NULL; + TRANSACTION2_QFSI_RSP *pSMBr = NULL; + FILE_SYSTEM_POSIX_INFO *response_data; + int rc = 0; + int bytes_returned = 0; + __u16 params, byte_count; + + cFYI(1, ("In QFSPosixInfo")); +QFSPosixRetry: + rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, + (void **) &pSMBr); + if (rc) + return rc; + + params = 2; /* level */ + pSMB->TotalDataCount = 0; + pSMB->DataCount = 0; + pSMB->DataOffset = 0; + pSMB->MaxParameterCount = cpu_to_le16(2); + pSMB->MaxDataCount = cpu_to_le16(100); /* 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; + byte_count = params + 1 /* pad */ ; + pSMB->ParameterCount = cpu_to_le16(params); + pSMB->TotalParameterCount = pSMB->ParameterCount; + pSMB->ParameterOffset = cpu_to_le16(offsetof(struct + smb_com_transaction2_qfsi_req, InformationLevel) - 4); + pSMB->SetupCount = 1; + pSMB->Reserved3 = 0; + pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION); + pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO); + 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) { + cERROR(1, ("Send error in QFSUnixInfo = %d", rc)); + } else { /* decode response */ + rc = validate_t2((struct smb_t2_rsp *)pSMBr); + + if (rc || (pSMBr->ByteCount < 13)) { + rc = -EIO; /* bad smb */ + } else { + __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); + response_data = + (FILE_SYSTEM_POSIX_INFO + *) (((char *) &pSMBr->hdr.Protocol) + + data_offset); + FSData->f_blocks = + le64_to_cpu(response_data->TotalBlocks); + FSData->f_bfree = + le64_to_cpu(response_data->BlocksAvail); + FSData->f_bavail = + le64_to_cpu(response_data->UserBlocksAvail); + FSData->f_files = + le64_to_cpu(response_data->TotalFileNodes); + FSData->f_ffree = + le64_to_cpu(response_data->FreeFileNodes); + } + } + cifs_buf_release(pSMB); + + if (rc == -EAGAIN) + goto QFSPosixRetry; + + return rc; +} + + /* We can not use write of zero bytes trick to set file size due to need for large file support. Also note that this SetPathInfo is preferred to SetFileInfo based method in next @@ -3396,8 +3268,7 @@ cFYI(1, ("SetPathInfo (file size) returned %d", rc)); } - if (pSMB) - cifs_buf_release(pSMB); + cifs_buf_release(pSMB); if (rc == -EAGAIN) goto SetEOFRetry; @@ -3491,6 +3362,83 @@ return rc; } +/* Some legacy servers such as NT4 require that the file times be set on + an open handle, rather than by pathname - this is awkward due to + potential access conflicts on the open, but it is unavoidable for these + old servers since the only other choice is to go from 100 nanosecond DCE + time and resort to the original setpathinfo level which takes the ancient + DOS time format with 2 second granularity */ +int +CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, const FILE_BASIC_INFO * data, + __u16 fid) +{ + struct smb_com_transaction2_sfi_req *pSMB = NULL; + struct smb_com_transaction2_sfi_rsp *pSMBr = NULL; + char *data_offset; + int rc = 0; + int bytes_returned = 0; + __u16 params, param_offset, offset, byte_count, count; + + cFYI(1, ("Set Times (via SetFileInfo)")); + rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, + (void **) &pSMBr); + if (rc) + return rc; + + /* At this point there is no need to override the current pid + with the pid of the opener, but that could change if we someday + use an existing handle (rather than opening one on the fly) */ + /* pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener); + pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));*/ + + params = 6; + pSMB->MaxSetupCount = 0; + pSMB->Reserved = 0; + pSMB->Flags = 0; + pSMB->Timeout = 0; + pSMB->Reserved2 = 0; + param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4; + offset = param_offset + params; + + data_offset = (char *) (&pSMB->hdr.Protocol) + offset; + + count = sizeof (FILE_BASIC_INFO); + pSMB->MaxParameterCount = cpu_to_le16(2); + pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */ + pSMB->SetupCount = 1; + pSMB->Reserved3 = 0; + pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION); + byte_count = 3 /* pad */ + params + count; + pSMB->DataCount = cpu_to_le16(count); + pSMB->ParameterCount = cpu_to_le16(params); + pSMB->TotalDataCount = pSMB->DataCount; + pSMB->TotalParameterCount = pSMB->ParameterCount; + pSMB->ParameterOffset = cpu_to_le16(param_offset); + pSMB->DataOffset = cpu_to_le16(offset); + pSMB->Fid = fid; + if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU) + pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2); + else + pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO); + pSMB->Reserved4 = 0; + pSMB->hdr.smb_buf_length += byte_count; + pSMB->ByteCount = cpu_to_le16(byte_count); + memcpy(data_offset,data,sizeof(FILE_BASIC_INFO)); + rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, + (struct smb_hdr *) pSMBr, &bytes_returned, 0); + if (rc) { + cFYI(1,("Send error in Set Time (SetFileInfo) = %d",rc)); + } + + 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 CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon, const char *fileName, const FILE_BASIC_INFO * data, @@ -3563,8 +3511,7 @@ cFYI(1, ("SetPathInfo (times) returned %d", rc)); } - if (pSMB) - cifs_buf_release(pSMB); + cifs_buf_release(pSMB); if (rc == -EAGAIN) goto SetTimesRetry; @@ -3574,10 +3521,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 +3555,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 +3566,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 +3584,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); @@ -3641,8 +3591,7 @@ cFYI(1, ("SetPathInfo (times legacy) returned %d", rc)); } - if (pSMB) - cifs_buf_release(pSMB); + cifs_buf_release(pSMB); if (rc == -EAGAIN) goto SetTimesRetryLegacy; @@ -3789,10 +3738,7 @@ if (rc) { cFYI(1, ("Error in Notify = %d", rc)); } - if (pSMB) - cifs_buf_release(pSMB); -/* if (rc == -EAGAIN) - goto NotifyRetry; */ + cifs_buf_release(pSMB); return rc; } #ifdef CONFIG_CIFS_XATTR @@ -4162,7 +4108,8 @@ /* we checked above that name len is less than 255 */ parm_data->list[0].name_len = (__u8)name_len;; /* EA names are always ASCII */ - strncpy(parm_data->list[0].name,ea_name,name_len); + if(ea_name) + strncpy(parm_data->list[0].name,ea_name,name_len); parm_data->list[0].name[name_len] = 0; parm_data->list[0].value_len = cpu_to_le16(ea_value_len); /* caller ensures that ea_value_len is less than 64K but @@ -4185,8 +4132,7 @@ cFYI(1, ("SetPathInfo (EA) returned %d", rc)); } - if (pSMB) - cifs_buf_release(pSMB); + cifs_buf_release(pSMB); if (rc == -EAGAIN) goto SetEARetry; diff -Nru a/fs/cifs/connect.c b/fs/cifs/connect.c --- a/fs/cifs/connect.c 2005-03-11 13:15:10 -08:00 +++ b/fs/cifs/connect.c 2005-03-11 13:15:10 -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-11 13:15:10 -08:00 +++ b/fs/cifs/fcntl.c 2005-03-11 13:15:10 -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-11 13:15:10 -08:00 +++ b/fs/cifs/file.c 2005-03-11 13:15:10 -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-11 13:15:10 -08:00 +++ b/fs/cifs/inode.c 2005-03-11 13:15:10 -08:00 @@ -1,7 +1,7 @@ /* * fs/cifs/inode.c * - * Copyright (C) International Business Machines Corp., 2002,2003 + * Copyright (C) International Business Machines Corp., 2002,2005 * Author(s): Steve French (sfrench@us.ibm.com) * * This library is free software; you can redistribute it and/or modify @@ -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, @@ -642,10 +640,18 @@ } /* if we can not get memory just leave rc as EEXIST */ } + if (rc) { + cFYI(1,("rename rc %d",rc)); /* BB removeme BB */ + } + if((rc == -EIO)||(rc == -EEXIST)) { int oplock = FALSE; __u16 netfid; + /* BB FIXME Is Generic Read correct for rename? */ + /* if renaming directory - we should not say CREATE_NOT_DIR, + need to test renaming open directory, also GENERIC_READ + might not right be right access to request */ rc = CIFSSMBOpen(xid, pTcon, fromName, FILE_OPEN, GENERIC_READ, CREATE_NOT_DIR, &netfid, &oplock, NULL, cifs_sb_source->local_nls); @@ -772,7 +778,8 @@ filemap_fdatawrite(direntry->d_inode->i_mapping); } if(invalidate_inode) { - filemap_fdatawait(direntry->d_inode->i_mapping); + if(direntry->d_inode->i_mapping) + filemap_fdatawait(direntry->d_inode->i_mapping); /* may eventually have to do this for open files too */ if(list_empty(&(cifsInode->openFileList))) { /* Has changed on server - flush read ahead pages */ @@ -981,14 +988,25 @@ rc = CIFSSMBSetTimes(xid, pTcon, full_path, &time_buf, 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 */ - /* CIFSSMBSetTimesLegacy(xid, pTcon, full_path, - FILE_INFO_STANDARD * data, cifs_sb->local_nls); */ + int oplock = FALSE; + __u16 netfid; + + cFYI(1,("calling SetFileInfo since SetPathInfo for times not supported by this server")); + /* BB we could scan to see if we already have it open */ + /* and pass in pid of opener to function */ + rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, FILE_WRITE_ATTRIBUTES, + CREATE_NOT_DIR, &netfid, &oplock, NULL, cifs_sb->local_nls); + if(rc==0) { + rc = CIFSSMBSetFileTimes(xid, pTcon, + &time_buf, netfid); + CIFSSMBClose(xid, pTcon, netfid); + } else { + /* BB For even older servers we could convert time_buf + into old DOS style which uses two second granularity */ + + /* rc = CIFSSMBSetTimesLegacy(xid, pTcon, full_path, + &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-11 13:15:10 -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-11 13:15:10 -08:00 +++ b/fs/cifs/misc.c 2005-03-11 13:15:10 -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-11 13:15:10 -08:00 +++ b/fs/cifs/netmisc.c 2005-03-11 13:15:10 -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-11 13:15:10 -08:00 +++ b/fs/cifs/readdir.c 2005-03-11 13:15:10 -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; @@ -93,6 +138,9 @@ cifsFile->invalidHandle = TRUE; cifsFile->srch_inf.endOfSearch = FALSE; + if(file->f_dentry == NULL) + return -ENOENT; + cifs_sb = CIFS_SB(file->f_dentry->d_sb); if(cifs_sb == NULL) return -EINVAL; @@ -101,9 +149,6 @@ if(pTcon == NULL) return -EINVAL; - if(file->f_dentry == NULL) - return -ENOENT; - 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); @@ -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-11 13:15:10 -08:00 +++ b/fs/cifs/smbencrypt.c 2005-03-11 13:15:10 -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-11 13:15:10 -08:00 +++ b/fs/cifs/transport.c 2005-03-11 13:15:10 -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-11 13:15:10 -08:00 +++ b/fs/cifs/xattr.c 2005-03-11 13:15:10 -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);