Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag '4.19-smb3' of git://git.samba.org/sfrench/cifs-2.6

Pull cifs updates from Steve French:
"smb3/cifs fixes (including 8 for stable).

Other improvements include:

- improved tracing, improved stats

- snapshots (previous version mounts work now over SMB3)

- performance (compounding enabled for statfs, ~40% faster).

- security (make it possible to build cifs.ko with insecure vers=1.0
disabled in Kconfig)"

* tag '4.19-smb3' of git://git.samba.org/sfrench/cifs-2.6: (43 commits)
smb3: create smb3 equivalent alias for cifs pseudo-xattrs
smb3: allow previous versions to be mounted with snapshot= mount parm
cifs: don't show domain= in mount output when domain is empty
cifs: add missing support for ACLs in SMB 3.11
smb3: enumerating snapshots was leaving part of the data off end
cifs: update smb2_queryfs() to use compounding
cifs: update receive_encrypted_standard to handle compounded responses
cifs: create SMB2_open_init()/SMB2_open_free() helpers.
cifs: add SMB2_query_info_[init|free]()
cifs: add SMB2_close_init()/SMB2_close_free()
smb3: display stats counters for number of slow commands
CIFS: fix uninitialized ptr deref in smb2 signing
smb3: Do not send SMB3 SET_INFO if nothing changed
smb3: fix minor debug output for CONFIG_CIFS_STATS
smb3: add tracepoint for slow responses
cifs: add compound_send_recv()
cifs: make smb_send_rqst take an array of requests
cifs: update init_sg, crypt_message to take an array of rqst
smb3: update readme to correct information about /proc/fs/cifs/Stats
smb3: fix reset of bytes read and written stats
...

+1288 -1762
+4 -1068
Documentation/filesystems/cifs/CHANGES
··· 1 - See https://wiki.samba.org/index.php/LinuxCIFSKernel for 2 - more current information. 3 - 4 - Version 1.62 5 - ------------ 6 - Add sockopt=TCP_NODELAY mount option. EA (xattr) routines hardened 7 - to more strictly handle corrupt frames. 8 - 9 - Version 1.61 10 - ------------ 11 - Fix append problem to Samba servers (files opened with O_APPEND could 12 - have duplicated data). Fix oops in cifs_lookup. Workaround problem 13 - mounting to OS/400 Netserve. Fix oops in cifs_get_tcp_session. 14 - Disable use of server inode numbers when server only 15 - partially supports them (e.g. for one server querying inode numbers on 16 - FindFirst fails but QPathInfo queries works). Fix oops with dfs in 17 - cifs_put_smb_ses. Fix mmap to work on directio mounts (needed 18 - for OpenOffice when on forcedirectio mount e.g.) 19 - 20 - Version 1.60 21 - ------------- 22 - Fix memory leak in reconnect. Fix oops in DFS mount error path. 23 - Set s_maxbytes to smaller (the max that vfs can handle) so that 24 - sendfile will now work over cifs mounts again. Add noforcegid 25 - and noforceuid mount parameters. Fix small mem leak when using 26 - ntlmv2. Fix 2nd mount to same server but with different port to 27 - be allowed (rather than reusing the 1st port) - only when the 28 - user explicitly overrides the port on the 2nd mount. 29 - 30 - Version 1.59 31 - ------------ 32 - Client uses server inode numbers (which are persistent) rather than 33 - client generated ones by default (mount option "serverino" turned 34 - on by default if server supports it). Add forceuid and forcegid 35 - mount options (so that when negotiating unix extensions specifying 36 - which uid mounted does not immediately force the server's reported 37 - uids to be overridden). Add support for scope mount parm. Improve 38 - hard link detection to use same inode for both. Do not set 39 - read-only dos attribute on directories (for chmod) since Windows 40 - explorer special cases this attribute bit for directories for 41 - a different purpose. 42 - 43 - Version 1.58 44 - ------------ 45 - Guard against buffer overruns in various UCS-2 to UTF-8 string conversions 46 - when the UTF-8 string is composed of unusually long (more than 4 byte) converted 47 - characters. Add support for mounting root of a share which redirects immediately 48 - to DFS target. Convert string conversion functions from Unicode to more 49 - accurately mark string length before allocating memory (which may help the 50 - rare cases where a UTF-8 string is much larger than the UCS2 string that 51 - we converted from). Fix endianness of the vcnum field used during 52 - session setup to distinguish multiple mounts to same server from different 53 - userids. Raw NTLMSSP fixed (it requires /proc/fs/cifs/experimental 54 - flag to be set to 2, and mount must enable krb5 to turn on extended security). 55 - Performance of file create to Samba improved (posix create on lookup 56 - removes 1 of 2 network requests sent on file create) 57 - 58 - Version 1.57 59 - ------------ 60 - Improve support for multiple security contexts to the same server. We 61 - used to use the same "vcnumber" for all connections which could cause 62 - the server to treat subsequent connections, especially those that 63 - are authenticated as guest, as reconnections, invalidating the earlier 64 - user's smb session. This fix allows cifs to mount multiple times to the 65 - same server with different userids without risking invalidating earlier 66 - established security contexts. fsync now sends SMB Flush operation 67 - to better ensure that we wait for server to write all of the data to 68 - server disk (not just write it over the network). Add new mount 69 - parameter to allow user to disable sending the (slow) SMB flush on 70 - fsync if desired (fsync still flushes all cached write data to the server). 71 - Posix file open support added (turned off after one attempt if server 72 - fails to support it properly, as with Samba server versions prior to 3.3.2) 73 - Fix "redzone overwritten" bug in cifs_put_tcon (CIFSTcon may allocate too 74 - little memory for the "nativeFileSystem" field returned by the server 75 - during mount). Endian convert inode numbers if necessary (makes it easier 76 - to compare inode numbers on network files from big endian systems). 77 - 78 - Version 1.56 79 - ------------ 80 - Add "forcemandatorylock" mount option to allow user to use mandatory 81 - rather than posix (advisory) byte range locks, even though server would 82 - support posix byte range locks. Fix query of root inode when prefixpath 83 - specified and user does not have access to query information about the 84 - top of the share. Fix problem in 2.6.28 resolving DFS paths to 85 - Samba servers (worked to Windows). Fix rmdir so that pending search 86 - (readdir) requests do not get invalid results which include the now 87 - removed directory. Fix oops in cifs_dfs_ref.c when prefixpath is not reachable 88 - when using DFS. Add better file create support to servers which support 89 - the CIFS POSIX protocol extensions (this adds support for new flags 90 - on create, and improves semantics for write of locked ranges). 91 - 92 - Version 1.55 93 - ------------ 94 - Various fixes to make delete of open files behavior more predictable 95 - (when delete of an open file fails we mark the file as "delete-on-close" 96 - in a way that more servers accept, but only if we can first rename the 97 - file to a temporary name). Add experimental support for more safely 98 - handling fcntl(F_SETLEASE). Convert cifs to using blocking tcp 99 - sends, and also let tcp autotune the socket send and receive buffers. 100 - This reduces the number of EAGAIN errors returned by TCP/IP in 101 - high stress workloads (and the number of retries on socket writes 102 - when sending large SMBWriteX requests). Fix case in which a portion of 103 - data can in some cases not get written to the file on the server before the 104 - file is closed. Fix DFS parsing to properly handle path consumed field, 105 - and to handle certain codepage conversions better. Fix mount and 106 - umount race that can cause oops in mount or umount or reconnect. 107 - 108 - Version 1.54 109 - ------------ 110 - Fix premature write failure on congested networks (we would give up 111 - on EAGAIN from the socket too quickly on large writes). 112 - Cifs_mkdir and cifs_create now respect the setgid bit on parent dir. 113 - Fix endian problems in acl (mode from/to cifs acl) on bigendian 114 - architectures. Fix problems with preserving timestamps on copying open 115 - files (e.g. "cp -a") to Windows servers. For mkdir and create honor setgid bit 116 - on parent directory when server supports Unix Extensions but not POSIX 117 - create. Update cifs.upcall version to handle new Kerberos sec flags 118 - (this requires update of cifs.upcall program from Samba). Fix memory leak 119 - on dns_upcall (resolving DFS referralls). Fix plain text password 120 - authentication (requires setting SecurityFlags to 0x30030 to enable 121 - lanman and plain text though). Fix writes to be at correct offset when 122 - file is open with O_APPEND and file is on a directio (forcediretio) mount. 123 - Fix bug in rewinding readdir directory searches. Add nodfs mount option. 124 - 125 - Version 1.53 126 - ------------ 127 - DFS support added (Microsoft Distributed File System client support needed 128 - for referrals which enable a hierarchical name space among servers). 129 - Disable temporary caching of mode bits to servers which do not support 130 - storing of mode (e.g. Windows servers, when client mounts without cifsacl 131 - mount option) and add new "dynperm" mount option to enable temporary caching 132 - of mode (enable old behavior). Fix hang on mount caused when server crashes 133 - tcp session during negotiate protocol. 134 - 135 - Version 1.52 136 - ------------ 137 - Fix oops on second mount to server when null auth is used. 138 - Enable experimental Kerberos support. Return writebehind errors on flush 139 - and sync so that events like out of disk space get reported properly on 140 - cached files. Fix setxattr failure to certain Samba versions. Fix mount 141 - of second share to disconnected server session (autoreconnect on this). 142 - Add ability to modify cifs acls for handling chmod (when mounted with 143 - cifsacl flag). Fix prefixpath path separator so we can handle mounts 144 - with prefixpaths longer than one directory (one path component) when 145 - mounted to Windows servers. Fix slow file open when cifsacl 146 - enabled. Fix memory leak in FindNext when the SMB call returns -EBADF. 147 - 148 - 149 - Version 1.51 150 - ------------ 151 - Fix memory leak in statfs when mounted to very old servers (e.g. 152 - Windows 9x). Add new feature "POSIX open" which allows servers 153 - which support the current POSIX Extensions to provide better semantics 154 - (e.g. delete for open files opened with posix open). Take into 155 - account umask on posix mkdir not just older style mkdir. Add 156 - ability to mount to IPC$ share (which allows CIFS named pipes to be 157 - opened, read and written as if they were files). When 1st tree 158 - connect fails (e.g. due to signing negotiation failure) fix 159 - leak that causes cifsd not to stop and rmmod to fail to cleanup 160 - cifs_request_buffers pool. Fix problem with POSIX Open/Mkdir on 161 - bigendian architectures. Fix possible memory corruption when 162 - EAGAIN returned on kern_recvmsg. Return better error if server 163 - requires packet signing but client has disabled it. When mounted 164 - with cifsacl mount option - mode bits are approximated based 165 - on the contents of the ACL of the file or directory. When cifs 166 - mount helper is missing convert make sure that UNC name 167 - has backslash (not forward slash) between ip address of server 168 - and the share name. 169 - 170 - Version 1.50 171 - ------------ 172 - Fix NTLMv2 signing. NFS server mounted over cifs works (if cifs mount is 173 - done with "serverino" mount option). Add support for POSIX Unlink 174 - (helps with certain sharing violation cases when server such as 175 - Samba supports newer POSIX CIFS Protocol Extensions). Add "nounix" 176 - mount option to allow disabling the CIFS Unix Extensions for just 177 - that mount. Fix hang on spinlock in find_writable_file (race when 178 - reopening file after session crash). Byte range unlock request to 179 - windows server could unlock more bytes (on server copy of file) 180 - than intended if start of unlock request is well before start of 181 - a previous byte range lock that we issued. 182 - 183 - Version 1.49 184 - ------------ 185 - IPv6 support. Enable ipv6 addresses to be passed on mount (put the ipv6 186 - address after the "ip=" mount option, at least until mount.cifs is fixed to 187 - handle DNS host to ipv6 name translation). Accept override of uid or gid 188 - on mount even when Unix Extensions are negotiated (it used to be ignored 189 - when Unix Extensions were ignored). This allows users to override the 190 - default uid and gid for files when they are certain that the uids or 191 - gids on the server do not match those of the client. Make "sec=none" 192 - mount override username (so that null user connection is attempted) 193 - to match what documentation said. Support for very large reads, over 127K, 194 - available to some newer servers (such as Samba 3.0.26 and later but 195 - note that it also requires setting CIFSMaxBufSize at module install 196 - time to a larger value which may hurt performance in some cases). 197 - Make sign option force signing (or fail if server does not support it). 198 - 199 - Version 1.48 200 - ------------ 201 - Fix mtime bouncing around from local idea of last write times to remote time. 202 - Fix hang (in i_size_read) when simultaneous size update of same remote file 203 - on smp system corrupts sequence number. Do not reread unnecessarily partial page 204 - (which we are about to overwrite anyway) when writing out file opened rw. 205 - When DOS attribute of file on non-Unix server's file changes on the server side 206 - from read-only back to read-write, reflect this change in default file mode 207 - (we had been leaving a file's mode read-only until the inode were reloaded). 208 - Allow setting of attribute back to ATTR_NORMAL (removing readonly dos attribute 209 - when archive dos attribute not set and we are changing mode back to writeable 210 - on server which does not support the Unix Extensions). Remove read only dos 211 - attribute on chmod when adding any write permission (ie on any of 212 - user/group/other (not all of user/group/other ie 0222) when 213 - mounted to windows. Add support for POSIX MkDir (slight performance 214 - enhancement and eliminates the network race between the mkdir and set 215 - path info of the mode). 216 - 217 - 218 - Version 1.47 219 - ------------ 220 - Fix oops in list_del during mount caused by unaligned string. 221 - Fix file corruption which could occur on some large file 222 - copies caused by writepages page i/o completion bug. 223 - Seek to SEEK_END forces check for update of file size for non-cached 224 - files. Allow file size to be updated on remote extend of locally open, 225 - non-cached file. Fix reconnect to newer Samba servers (or other servers 226 - which support the CIFS Unix/POSIX extensions) so that we again tell the 227 - server the Unix/POSIX cifs capabilities which we support (SetFSInfo). 228 - Add experimental support for new POSIX Open/Mkdir (which returns 229 - stat information on the open, and allows setting the mode). 230 - 231 - Version 1.46 232 - ------------ 233 - Support deep tree mounts. Better support OS/2, Win9x (DOS) time stamps. 234 - Allow null user to be specified on mount ("username="). Do not return 235 - EINVAL on readdir when filldir fails due to overwritten blocksize 236 - (fixes FC problem). Return error in rename 2nd attempt retry (ie report 237 - if rename by handle also fails, after rename by path fails, we were 238 - not reporting whether the retry worked or not). Fix NTLMv2 to 239 - work to Windows servers (mount with option "sec=ntlmv2"). 240 - 241 - Version 1.45 242 - ------------ 243 - Do not time out lockw calls when using posix extensions. Do not 244 - time out requests if server still responding reasonably fast 245 - on requests on other threads. Improve POSIX locking emulation, 246 - (lock cancel now works, and unlock of merged range works even 247 - to Windows servers now). Fix oops on mount to lanman servers 248 - (win9x, os/2 etc.) when null password. Do not send listxattr 249 - (SMB to query all EAs) if nouser_xattr specified. Fix SE Linux 250 - problem (instantiate inodes/dentries in right order for readdir). 251 - 252 - Version 1.44 253 - ------------ 254 - Rewritten sessionsetup support, including support for legacy SMB 255 - session setup needed for OS/2 and older servers such as Windows 95 and 98. 256 - Fix oops on ls to OS/2 servers. Add support for level 1 FindFirst 257 - so we can do search (ls etc.) to OS/2. Do not send NTCreateX 258 - or recent levels of FindFirst unless server says it supports NT SMBs 259 - (instead use legacy equivalents from LANMAN dialect). Fix to allow 260 - NTLMv2 authentication support (now can use stronger password hashing 261 - on mount if corresponding /proc/fs/cifs/SecurityFlags is set (0x4004). 262 - Allow override of global cifs security flags on mount via "sec=" option(s). 263 - 264 - Version 1.43 265 - ------------ 266 - POSIX locking to servers which support CIFS POSIX Extensions 267 - (disabled by default controlled by proc/fs/cifs/Experimental). 268 - Handle conversion of long share names (especially Asian languages) 269 - to Unicode during mount. Fix memory leak in sess struct on reconnect. 270 - Fix rare oops after acpi suspend. Fix O_TRUNC opens to overwrite on 271 - cifs open which helps rare case when setpathinfo fails or server does 272 - not support it. 273 - 274 - Version 1.42 275 - ------------ 276 - Fix slow oplock break when mounted to different servers at the same time and 277 - the tids match and we try to find matching fid on wrong server. Fix read 278 - looping when signing required by server (2.6.16 kernel only). Fix readdir 279 - vs. rename race which could cause each to hang. Return . and .. even 280 - if server does not. Allow searches to skip first three entries and 281 - begin at any location. Fix oops in find_writeable_file. 282 - 283 - Version 1.41 284 - ------------ 285 - Fix NTLMv2 security (can be enabled in /proc/fs/cifs) so customers can 286 - configure stronger authentication. Fix sfu symlinks so they can 287 - be followed (not just recognized). Fix wraparound of bcc on 288 - read responses when buffer size over 64K and also fix wrap of 289 - max smb buffer size when CIFSMaxBufSize over 64K. Fix oops in 290 - cifs_user_read and cifs_readpages (when EAGAIN on send of smb 291 - on socket is returned over and over). Add POSIX (advisory) byte range 292 - locking support (requires server with newest CIFS UNIX Extensions 293 - to the protocol implemented). Slow down negprot slightly in port 139 294 - RFC1001 case to give session_init time on buggy servers. 295 - 296 - Version 1.40 297 - ------------ 298 - Use fsuid (fsgid) more consistently instead of uid (gid). Improve performance 299 - of readpages by eliminating one extra memcpy. Allow update of file size 300 - from remote server even if file is open for write as long as mount is 301 - directio. Recognize share mode security and send NTLM encrypted password 302 - on tree connect if share mode negotiated. 303 - 304 - Version 1.39 305 - ------------ 306 - Defer close of a file handle slightly if pending writes depend on that handle 307 - (this reduces the EBADF bad file handle errors that can be logged under heavy 308 - stress on writes). Modify cifs Kconfig options to expose CONFIG_CIFS_STATS2 309 - Fix SFU style symlinks and mknod needed for servers which do not support the 310 - CIFS Unix Extensions. Fix setfacl/getfacl on bigendian. Timeout negative 311 - dentries so files that the client sees as deleted but that later get created 312 - on the server will be recognized. Add client side permission check on setattr. 313 - Timeout stuck requests better (where server has never responded or sent corrupt 314 - responses) 315 - 316 - Version 1.38 317 - ------------ 318 - Fix tcp socket retransmission timeouts (e.g. on ENOSPACE from the socket) 319 - to be smaller at first (but increasing) so large write performance performance 320 - over GigE is better. Do not hang thread on illegal byte range lock response 321 - from Windows (Windows can send an RFC1001 size which does not match smb size) by 322 - allowing an SMBs TCP length to be up to a few bytes longer than it should be. 323 - wsize and rsize can now be larger than negotiated buffer size if server 324 - supports large readx/writex, even when directio mount flag not specified. 325 - Write size will in many cases now be 16K instead of 4K which greatly helps 326 - file copy performance on lightly loaded networks. Fix oops in dnotify 327 - when experimental config flag enabled. Make cifsFYI more granular. 328 - 329 - Version 1.37 330 - ------------ 331 - Fix readdir caching when unlink removes file in current search buffer, 332 - and this is followed by a rewind search to just before the deleted entry. 333 - Do not attempt to set ctime unless atime and/or mtime change requested 334 - (most servers throw it away anyway). Fix length check of received smbs 335 - to be more accurate. Fix big endian problem with mapchars mount option, 336 - and with a field returned by statfs. 337 - 338 - Version 1.36 339 - ------------ 340 - Add support for mounting to older pre-CIFS servers such as Windows9x and ME. 341 - For these older servers, add option for passing netbios name of server in 342 - on mount (servernetbiosname). Add suspend support for power management, to 343 - avoid cifsd thread preventing software suspend from working. 344 - Add mount option for disabling the default behavior of sending byte range lock 345 - requests to the server (necessary for certain applications which break with 346 - mandatory lock behavior such as Evolution), and also mount option for 347 - requesting case insensitive matching for path based requests (requesting 348 - case sensitive is the default). 349 - 350 - Version 1.35 351 - ------------ 352 - Add writepage performance improvements. Fix path name conversions 353 - for long filenames on mounts which were done with "mapchars" mount option 354 - specified. Ensure multiplex ids do not collide. Fix case in which 355 - rmmod can oops if done soon after last unmount. Fix truncated 356 - search (readdir) output when resume filename was a long filename. 357 - Fix filename conversion when mapchars mount option was specified and 358 - filename was a long filename. 359 - 360 - Version 1.34 361 - ------------ 362 - Fix error mapping of the TOO_MANY_LINKS (hardlinks) case. 363 - Do not oops if root user kills cifs oplock kernel thread or 364 - kills the cifsd thread (NB: killing the cifs kernel threads is not 365 - recommended, unmount and rmmod cifs will kill them when they are 366 - no longer needed). Fix readdir to ASCII servers (ie older servers 367 - which do not support Unicode) and also require asterisk. 368 - Fix out of memory case in which data could be written one page 369 - off in the page cache. 370 - 371 - Version 1.33 372 - ------------ 373 - Fix caching problem, in which readdir of directory containing a file 374 - which was cached could cause the file's time stamp to be updated 375 - without invalidating the readahead data (so we could get stale 376 - file data on the client for that file even as the server copy changed). 377 - Cleanup response processing so cifsd can not loop when abnormally 378 - terminated. 379 - 380 - 381 - Version 1.32 382 - ------------ 383 - Fix oops in ls when Transact2 FindFirst (or FindNext) returns more than one 384 - transact response for an SMB request and search entry split across two frames. 385 - Add support for lsattr (getting ext2/ext3/reiserfs attr flags from the server) 386 - as new protocol extensions. Do not send Get/Set calls for POSIX ACLs 387 - unless server explicitly claims to support them in CIFS Unix extensions 388 - POSIX ACL capability bit. Fix packet signing when multiuser mounting with 389 - different users from the same client to the same server. Fix oops in 390 - cifs_close. Add mount option for remapping reserved characters in 391 - filenames (also allow recognizing files with created by SFU which have any 392 - of these seven reserved characters, except backslash, to be recognized). 393 - Fix invalid transact2 message (we were sometimes trying to interpret 394 - oplock breaks as SMB responses). Add ioctl for checking that the 395 - current uid matches the uid of the mounter (needed by umount.cifs). 396 - Reduce the number of large buffer allocations in cifs response processing 397 - (significantly reduces memory pressure under heavy stress with multiple 398 - processes accessing the same server at the same time). 399 - 400 - Version 1.31 401 - ------------ 402 - Fix updates of DOS attributes and time fields so that files on NT4 servers 403 - do not get marked delete on close. Display sizes of cifs buffer pools in 404 - cifs stats. Fix oops in unmount when cifsd thread being killed by 405 - shutdown. Add generic readv/writev and aio support. Report inode numbers 406 - consistently in readdir and lookup (when serverino mount option is 407 - specified use the inode number that the server reports - for both lookup 408 - and readdir, otherwise by default the locally generated inode number is used 409 - for inodes created in either path since servers are not always able to 410 - provide unique inode numbers when exporting multiple volumes from under one 411 - sharename). 412 - 413 - Version 1.30 414 - ------------ 415 - Allow new nouser_xattr mount parm to disable xattr support for user namespace. 416 - Do not flag user_xattr mount parm in dmesg. Retry failures setting file time 417 - (mostly affects NT4 servers) by retry with handle based network operation. 418 - Add new POSIX Query FS Info for returning statfs info more accurately. 419 - Handle passwords with multiple commas in them. 420 - 421 - Version 1.29 422 - ------------ 423 - Fix default mode in sysfs of cifs module parms. Remove old readdir routine. 424 - Fix capabilities flags for large readx so as to allow reads larger than 64K. 425 - 426 - Version 1.28 427 - ------------ 428 - Add module init parm for large SMB buffer size (to allow it to be changed 429 - from its default of 16K) which is especially useful for large file copy 430 - when mounting with the directio mount option. Fix oops after 431 - returning from mount when experimental ExtendedSecurity enabled and 432 - SpnegoNegotiated returning invalid error. Fix case to retry better when 433 - peek returns from 1 to 3 bytes on socket which should have more data. 434 - Fixed path based calls (such as cifs lookup) to handle path names 435 - longer than 530 (now can handle PATH_MAX). Fix pass through authentication 436 - from Samba server to DC (Samba required dummy LM password). 437 - 438 - Version 1.27 439 - ------------ 440 - Turn off DNOTIFY (directory change notification support) by default 441 - (unless built with the experimental flag) to fix hang with KDE 442 - file browser. Fix DNOTIFY flag mappings. Fix hang (in wait_event 443 - waiting on an SMB response) in SendReceive when session dies but 444 - reconnects quickly from another task. Add module init parms for 445 - minimum number of large and small network buffers in the buffer pools, 446 - and for the maximum number of simultaneous requests. 447 - 448 - Version 1.26 449 - ------------ 450 - Add setfacl support to allow setting of ACLs remotely to Samba 3.10 and later 451 - and other POSIX CIFS compliant servers. Fix error mapping for getfacl 452 - to EOPNOTSUPP when server does not support posix acls on the wire. Fix 453 - improperly zeroed buffer in CIFS Unix extensions set times call. 454 - 455 - Version 1.25 456 - ------------ 457 - Fix internationalization problem in cifs readdir with filenames that map to 458 - longer UTF-8 strings than the string on the wire was in Unicode. Add workaround 459 - for readdir to netapp servers. Fix search rewind (seek into readdir to return 460 - non-consecutive entries). Do not do readdir when server negotiates 461 - buffer size to small to fit filename. Add support for reading POSIX ACLs from 462 - the server (add also acl and noacl mount options). 463 - 464 - Version 1.24 465 - ------------ 466 - Optionally allow using server side inode numbers, rather than client generated 467 - ones by specifying mount option "serverino" - this is required for some apps 468 - to work which double check hardlinked files and have persistent inode numbers. 469 - 470 - Version 1.23 471 - ------------ 472 - Multiple bigendian fixes. On little endian systems (for reconnect after 473 - network failure) fix tcp session reconnect code so we do not try first 474 - to reconnect on reverse of port 445. Treat reparse points (NTFS junctions) 475 - as directories rather than symlinks because we can do follow link on them. 476 - 477 - Version 1.22 478 - ------------ 479 - Add config option to enable XATTR (extended attribute) support, mapping 480 - xattr names in the "user." namespace space to SMB/CIFS EAs. Lots of 481 - minor fixes pointed out by the Stanford SWAT checker (mostly missing 482 - or out of order NULL pointer checks in little used error paths). 483 - 484 - Version 1.21 485 - ------------ 486 - Add new mount parm to control whether mode check (generic_permission) is done 487 - on the client. If Unix extensions are enabled and the uids on the client 488 - and server do not match, client permission checks are meaningless on 489 - server uids that do not exist on the client (this does not affect the 490 - normal ACL check which occurs on the server). Fix default uid 491 - on mknod to match create and mkdir. Add optional mount parm to allow 492 - override of the default uid behavior (in which the server sets the uid 493 - and gid of newly created files). Normally for network filesystem mounts 494 - user want the server to set the uid/gid on newly created files (rather than 495 - using uid of the client processes you would in a local filesystem). 496 - 497 - Version 1.20 498 - ------------ 499 - Make transaction counts more consistent. Merge /proc/fs/cifs/SimultaneousOps 500 - info into /proc/fs/cifs/DebugData. Fix oops in rare oops in readdir 501 - (in build_wildcard_path_from_dentry). Fix mknod to pass type field 502 - (block/char/fifo) properly. Remove spurious mount warning log entry when 503 - credentials passed as mount argument. Set major/minor device number in 504 - inode for block and char devices when unix extensions enabled. 505 - 506 - Version 1.19 507 - ------------ 508 - Fix /proc/fs/cifs/Stats and DebugData display to handle larger 509 - amounts of return data. Properly limit requests to MAX_REQ (50 510 - is the usual maximum active multiplex SMB/CIFS requests per server). 511 - Do not kill cifsd (and thus hurt the other SMB session) when more than one 512 - session to the same server (but with different userids) exists and one 513 - of the two user's smb sessions is being removed while leaving the other. 514 - Do not loop reconnecting in cifsd demultiplex thread when admin 515 - kills the thread without going through unmount. 516 - 517 - Version 1.18 518 - ------------ 519 - Do not rename hardlinked files (since that should be a noop). Flush 520 - cached write behind data when reopening a file after session abend, 521 - except when already in write. Grab per socket sem during reconnect 522 - to avoid oops in sendmsg if overlapping with reconnect. Do not 523 - reset cached inode file size on readdir for files open for write on 524 - client. 525 - 526 - 527 - Version 1.17 528 - ------------ 529 - Update number of blocks in file so du command is happier (in Linux a fake 530 - blocksize of 512 is required for calculating number of blocks in inode). 531 - Fix prepare write of partial pages to read in data from server if possible. 532 - Fix race on tcpStatus field between unmount and reconnection code, causing 533 - cifsd process sometimes to hang around forever. Improve out of memory 534 - checks in cifs_filldir 535 - 536 - Version 1.16 537 - ------------ 538 - Fix incorrect file size in file handle based setattr on big endian hardware. 539 - Fix oops in build_path_from_dentry when out of memory. Add checks for invalid 540 - and closing file structs in writepage/partialpagewrite. Add statistics 541 - for each mounted share (new menuconfig option). Fix endianness problem in 542 - volume information displayed in /proc/fs/cifs/DebugData (only affects 543 - affects big endian architectures). Prevent renames while constructing 544 - path names for open, mkdir and rmdir. 545 - 546 - Version 1.15 547 - ------------ 548 - Change to mempools for alloc smb request buffers and multiplex structs 549 - to better handle low memory problems (and potential deadlocks). 550 - 551 - Version 1.14 552 - ------------ 553 - Fix incomplete listings of large directories on Samba servers when Unix 554 - extensions enabled. Fix oops when smb_buffer can not be allocated. Fix 555 - rename deadlock when writing out dirty pages at same time. 556 - 557 - Version 1.13 558 - ------------ 559 - Fix open of files in which O_CREATE can cause the mode to change in 560 - some cases. Fix case in which retry of write overlaps file close. 561 - Fix PPC64 build error. Reduce excessive stack usage in smb password 562 - hashing. Fix overwrite of Linux user's view of file mode to Windows servers. 563 - 564 - Version 1.12 565 - ------------ 566 - Fixes for large file copy, signal handling, socket retry, buffer 567 - allocation and low memory situations. 568 - 569 - Version 1.11 570 - ------------ 571 - Better port 139 support to Windows servers (RFC1001/RFC1002 Session_Initialize) 572 - also now allowing support for specifying client netbiosname. NT4 support added. 573 - 574 - Version 1.10 575 - ------------ 576 - Fix reconnection (and certain failed mounts) to properly wake up the 577 - blocked users thread so it does not seem hung (in some cases was blocked 578 - until the cifs receive timeout expired). Fix spurious error logging 579 - to kernel log when application with open network files killed. 580 - 581 - Version 1.09 582 - ------------ 583 - Fix /proc/fs module unload warning message (that could be logged 584 - to the kernel log). Fix intermittent failure in connectathon 585 - test7 (hardlink count not immediately refreshed in case in which 586 - inode metadata can be incorrectly kept cached when time near zero) 587 - 588 - Version 1.08 589 - ------------ 590 - Allow file_mode and dir_mode (specified at mount time) to be enforced 591 - locally (the server already enforced its own ACLs too) for servers 592 - that do not report the correct mode (do not support the 593 - CIFS Unix Extensions). 594 - 595 - Version 1.07 596 - ------------ 597 - Fix some small memory leaks in some unmount error paths. Fix major leak 598 - of cache pages in readpages causing multiple read oriented stress 599 - testcases (including fsx, and even large file copy) to fail over time. 600 - 601 - Version 1.06 602 - ------------ 603 - Send NTCreateX with ATTR_POSIX if Linux/Unix extensions negotiated with server. 604 - This allows files that differ only in case and improves performance of file 605 - creation and file open to such servers. Fix semaphore conflict which causes 606 - slow delete of open file to Samba (which unfortunately can cause an oplock 607 - break to self while vfs_unlink held i_sem) which can hang for 20 seconds. 608 - 609 - Version 1.05 610 - ------------ 611 - fixes to cifs_readpages for fsx test case 612 - 613 - Version 1.04 614 - ------------ 615 - Fix caching data integrity bug when extending file size especially when no 616 - oplock on file. Fix spurious logging of valid already parsed mount options 617 - that are parsed outside of the cifs vfs such as nosuid. 618 - 619 - 620 - Version 1.03 621 - ------------ 622 - Connect to server when port number override not specified, and tcp port 623 - unitialized. Reset search to restart at correct file when kernel routine 624 - filldir returns error during large directory searches (readdir). 625 - 626 - Version 1.02 627 - ------------ 628 - Fix caching problem when files opened by multiple clients in which 629 - page cache could contain stale data, and write through did 630 - not occur often enough while file was still open when read ahead 631 - (read oplock) not allowed. Treat "sep=" when first mount option 632 - as an override of comma as the default separator between mount 633 - options. 634 - 635 - Version 1.01 636 - ------------ 637 - Allow passwords longer than 16 bytes. Allow null password string. 638 - 639 - Version 1.00 640 - ------------ 641 - Gracefully clean up failed mounts when attempting to mount to servers such as 642 - Windows 98 that terminate tcp sessions during protocol negotiation. Handle 643 - embedded commas in mount parsing of passwords. 644 - 645 - Version 0.99 646 - ------------ 647 - Invalidate local inode cached pages on oplock break and when last file 648 - instance is closed so that the client does not continue using stale local 649 - copy rather than later modified server copy of file. Do not reconnect 650 - when server drops the tcp session prematurely before negotiate 651 - protocol response. Fix oops in reopen_file when dentry freed. Allow 652 - the support for CIFS Unix Extensions to be disabled via proc interface. 653 - 654 - Version 0.98 655 - ------------ 656 - Fix hang in commit_write during reconnection of open files under heavy load. 657 - Fix unload_nls oops in a mount failure path. Serialize writes to same socket 658 - which also fixes any possible races when cifs signatures are enabled in SMBs 659 - being sent out of signature sequence number order. 660 - 661 - Version 0.97 662 - ------------ 663 - Fix byte range locking bug (endian problem) causing bad offset and 664 - length. 665 - 666 - Version 0.96 667 - ------------ 668 - Fix oops (in send_sig) caused by CIFS unmount code trying to 669 - wake up the demultiplex thread after it had exited. Do not log 670 - error on harmless oplock release of closed handle. 671 - 672 - Version 0.95 673 - ------------ 674 - Fix unsafe global variable usage and password hash failure on gcc 3.3.1 675 - Fix problem reconnecting secondary mounts to same server after session 676 - failure. Fix invalid dentry - race in mkdir when directory gets created 677 - by another client between the lookup and mkdir. 678 - 679 - Version 0.94 680 - ------------ 681 - Fix to list processing in reopen_files. Fix reconnection when server hung 682 - but tcpip session still alive. Set proper timeout on socket read. 683 - 684 - Version 0.93 685 - ------------ 686 - Add missing mount options including iocharset. SMP fixes in write and open. 687 - Fix errors in reconnecting after TCP session failure. Fix module unloading 688 - of default nls codepage 689 - 690 - Version 0.92 691 - ------------ 692 - Active smb transactions should never go negative (fix double FreeXid). Fix 693 - list processing in file routines. Check return code on kmalloc in open. 694 - Fix spinlock usage for SMP. 695 - 696 - Version 0.91 697 - ------------ 698 - Fix oops in reopen_files when invalid dentry. drop dentry on server rename 699 - and on revalidate errors. Fix cases where pid is now tgid. Fix return code 700 - on create hard link when server does not support them. 701 - 702 - Version 0.90 703 - ------------ 704 - Fix scheduling while atomic error in getting inode info on newly created file. 705 - Fix truncate of existing files opened with O_CREAT but not O_TRUNC set. 706 - 707 - Version 0.89 708 - ------------ 709 - Fix oops on write to dead tcp session. Remove error log write for case when file open 710 - O_CREAT but not O_EXCL 711 - 712 - Version 0.88 713 - ------------ 714 - Fix non-POSIX behavior on rename of open file and delete of open file by taking 715 - advantage of trans2 SetFileInfo rename facility if available on target server. 716 - Retry on ENOSPC and EAGAIN socket errors. 717 - 718 - Version 0.87 719 - ------------ 720 - Fix oops on big endian readdir. Set blksize to be even power of two (2**blkbits) to fix 721 - allocation size miscalculation. After oplock token lost do not read through 722 - cache. 723 - 724 - Version 0.86 725 - ------------ 726 - Fix oops on empty file readahead. Fix for file size handling for locally cached files. 727 - 728 - Version 0.85 729 - ------------ 730 - Fix oops in mkdir when server fails to return inode info. Fix oops in reopen_files 731 - during auto reconnection to server after server recovered from failure. 732 - 733 - Version 0.84 734 - ------------ 735 - Finish support for Linux 2.5 open/create changes, which removes the 736 - redundant NTCreate/QPathInfo/close that was sent during file create. 737 - Enable oplock by default. Enable packet signing by default (needed to 738 - access many recent Windows servers) 739 - 740 - Version 0.83 741 - ------------ 742 - Fix oops when mounting to long server names caused by inverted parms to kmalloc. 743 - Fix MultiuserMount (/proc/fs/cifs configuration setting) so that when enabled 744 - we will choose a cifs user session (smb uid) that better matches the local 745 - uid if a) the mount uid does not match the current uid and b) we have another 746 - session to the same server (ip address) for a different mount which 747 - matches the current local uid. 748 - 749 - Version 0.82 750 - ------------ 751 - Add support for mknod of block or character devices. Fix oplock 752 - code (distributed caching) to properly send response to oplock 753 - break from server. 754 - 755 - Version 0.81 756 - ------------ 757 - Finish up CIFS packet digital signing for the default 758 - NTLM security case. This should help Windows 2003 759 - network interoperability since it is common for 760 - packet signing to be required now. Fix statfs (stat -f) 761 - which recently started returning errors due to 762 - invalid value (-1 instead of 0) being set in the 763 - struct kstatfs f_ffiles field. 764 - 765 - Version 0.80 766 - ----------- 767 - Fix oops on stopping oplock thread when removing cifs when 768 - built as module. 769 - 770 - Version 0.79 771 - ------------ 772 - Fix mount options for ro (readonly), uid, gid and file and directory mode. 773 - 774 - Version 0.78 775 - ------------ 776 - Fix errors displayed on failed mounts to be more understandable. 777 - Fixed various incorrect or misleading smb to posix error code mappings. 778 - 779 - Version 0.77 780 - ------------ 781 - Fix display of NTFS DFS junctions to display as symlinks. 782 - They are the network equivalent. Fix oops in 783 - cifs_partialpagewrite caused by missing spinlock protection 784 - of openfile linked list. Allow writebehind caching errors to 785 - be returned to the application at file close. 786 - 787 - Version 0.76 788 - ------------ 789 - Clean up options displayed in /proc/mounts by show_options to 790 - be more consistent with other filesystems. 791 - 792 - Version 0.75 793 - ------------ 794 - Fix delete of readonly file to Windows servers. Reflect 795 - presence or absence of read only dos attribute in mode 796 - bits for servers that do not support CIFS Unix extensions. 797 - Fix shortened results on readdir of large directories to 798 - servers supporting CIFS Unix extensions (caused by 799 - incorrect resume key). 800 - 801 - Version 0.74 802 - ------------ 803 - Fix truncate bug (set file size) that could cause hangs e.g. running fsx 804 - 805 - Version 0.73 806 - ------------ 807 - unload nls if mount fails. 808 - 809 - Version 0.72 810 - ------------ 811 - Add resume key support to search (readdir) code to workaround 812 - Windows bug. Add /proc/fs/cifs/LookupCacheEnable which 813 - allows disabling caching of attribute information for 814 - lookups. 815 - 816 - Version 0.71 817 - ------------ 818 - Add more oplock handling (distributed caching code). Remove 819 - dead code. Remove excessive stack space utilization from 820 - symlink routines. 821 - 822 - Version 0.70 823 - ------------ 824 - Fix oops in get dfs referral (triggered when null path sent in to 825 - mount). Add support for overriding rsize at mount time. 826 - 827 - Version 0.69 828 - ------------ 829 - Fix buffer overrun in readdir which caused intermittent kernel oopses. 830 - Fix writepage code to release kmap on write data. Allow "-ip=" new 831 - mount option to be passed in on parameter distinct from the first part 832 - (server name portion of) the UNC name. Allow override of the 833 - tcp port of the target server via new mount option "-port=" 834 - 835 - Version 0.68 836 - ------------ 837 - Fix search handle leak on rewind. Fix setuid and gid so that they are 838 - reflected in the local inode immediately. Cleanup of whitespace 839 - to make 2.4 and 2.5 versions more consistent. 840 - 841 - 842 - Version 0.67 843 - ------------ 844 - Fix signal sending so that captive thread (cifsd) exits on umount 845 - (which was causing the warning in kmem_cache_free of the request buffers 846 - at rmmod time). This had broken as a sideeffect of the recent global 847 - kernel change to daemonize. Fix memory leak in readdir code which 848 - showed up in "ls -R" (and applications that did search rewinding). 849 - 850 - Version 0.66 851 - ------------ 852 - Reconnect tids and fids after session reconnection (still do not 853 - reconnect byte range locks though). Fix problem caching 854 - lookup information for directory inodes, improving performance, 855 - especially in deep directory trees. Fix various build warnings. 856 - 857 - Version 0.65 858 - ------------ 859 - Finish fixes to commit write for caching/readahead consistency. fsx 860 - now works to Samba servers. Fix oops caused when readahead 861 - was interrupted by a signal. 862 - 863 - Version 0.64 864 - ------------ 865 - Fix data corruption (in partial page after truncate) that caused fsx to 866 - fail to Windows servers. Cleaned up some extraneous error logging in 867 - common error paths. Add generic sendfile support. 868 - 869 - Version 0.63 870 - ------------ 871 - Fix memory leak in AllocMidQEntry. 872 - Finish reconnection logic, so connection with server can be dropped 873 - (or server rebooted) and the cifs client will reconnect. 874 - 875 - Version 0.62 876 - ------------ 877 - Fix temporary socket leak when bad userid or password specified 878 - (or other SMBSessSetup failure). Increase maximum buffer size to slightly 879 - over 16K to allow negotiation of up to Samba and Windows server default read 880 - sizes. Add support for readpages 881 - 882 - Version 0.61 883 - ------------ 884 - Fix oops when username not passed in on mount. Extensive fixes and improvements 885 - to error logging (strip redundant newlines, change debug macros to ensure newline 886 - passed in and to be more consistent). Fix writepage wrong file handle problem, 887 - a readonly file handle could be incorrectly used to attempt to write out 888 - file updates through the page cache to multiply open files. This could cause 889 - the iozone benchmark to fail on the fwrite test. Fix bug mounting two different 890 - shares to the same Windows server when using different usernames 891 - (doing this to Samba servers worked but Windows was rejecting it) - now it is 892 - possible to use different userids when connecting to the same server from a 893 - Linux client. Fix oops when treeDisconnect called during unmount on 894 - previously freed socket. 895 - 896 - Version 0.60 897 - ------------ 898 - Fix oops in readpages caused by not setting address space operations in inode in 899 - rare code path. 900 - 901 - Version 0.59 902 - ------------ 903 - Includes support for deleting of open files and renaming over existing files (per POSIX 904 - requirement). Add readlink support for Windows junction points (directory symlinks). 905 - 906 - Version 0.58 907 - ------------ 908 - Changed read and write to go through pagecache. Added additional address space operations. 909 - Memory mapped operations now working. 910 - 911 - Version 0.57 912 - ------------ 913 - Added writepage code for additional memory mapping support. Fixed leak in xids causing 914 - the simultaneous operations counter (/proc/fs/cifs/SimultaneousOps) to increase on 915 - every stat call. Additional formatting cleanup. 916 - 917 - Version 0.56 918 - ------------ 919 - Fix bigendian bug in order of time conversion. Merge 2.5 to 2.4 version. Formatting cleanup. 920 - 921 - Version 0.55 922 - ------------ 923 - Fixes from Zwane Mwaikambo for adding missing return code checking in a few places. 924 - Also included a modified version of his fix to protect global list manipulation of 925 - the smb session and tree connection and mid related global variables. 926 - 927 - Version 0.54 928 - ------------ 929 - Fix problem with captive thread hanging around at unmount time. Adjust to 2.5.42-pre 930 - changes to superblock layout. Remove wasteful allocation of smb buffers (now the send 931 - buffer is reused for responses). Add more oplock handling. Additional minor cleanup. 932 - 933 - Version 0.53 934 - ------------ 935 - More stylistic updates to better match kernel style. Add additional statistics 936 - for filesystem which can be viewed via /proc/fs/cifs. Add more pieces of NTLMv2 937 - and CIFS Packet Signing enablement. 938 - 939 - Version 0.52 940 - ------------ 941 - Replace call to sleep_on with safer wait_on_event. 942 - Make stylistic changes to better match kernel style recommendations. 943 - Remove most typedef usage (except for the PDUs themselves). 944 - 945 - Version 0.51 946 - ------------ 947 - Update mount so the -unc mount option is no longer required (the ip address can be specified 948 - in a UNC style device name. Implementation of readpage/writepage started. 949 - 950 - Version 0.50 951 - ------------ 952 - Fix intermittent problem with incorrect smb header checking on badly 953 - fragmented tcp responses 954 - 955 - Version 0.49 956 - ------------ 957 - Fixes to setting of allocation size and file size. 958 - 959 - Version 0.48 960 - ------------ 961 - Various 2.5.38 fixes. Now works on 2.5.38 962 - 963 - Version 0.47 964 - ------------ 965 - Prepare for 2.5 kernel merge. Remove ifdefs. 966 - 967 - Version 0.46 968 - ------------ 969 - Socket buffer management fixes. Fix dual free. 970 - 971 - Version 0.45 972 - ------------ 973 - Various big endian fixes for hardlinks and symlinks and also for dfs. 974 - 975 - Version 0.44 976 - ------------ 977 - Various big endian fixes for servers with Unix extensions such as Samba 978 - 979 - Version 0.43 980 - ------------ 981 - Various FindNext fixes for incorrect filenames on large directory searches on big endian 982 - clients. basic posix file i/o tests now work on big endian machines, not just le 983 - 984 - Version 0.42 985 - ------------ 986 - SessionSetup and NegotiateProtocol now work from Big Endian machines. 987 - Various Big Endian fixes found during testing on the Linux on 390. Various fixes for compatibility with older 988 - versions of 2.4 kernel (now builds and works again on kernels at least as early as 2.4.7). 989 - 990 - Version 0.41 991 - ------------ 992 - Various minor fixes for Connectathon Posix "basic" file i/o test suite. Directory caching fixed so hardlinked 993 - files now return the correct number of links on fstat as they are repeatedly linked and unlinked. 994 - 995 - Version 0.40 996 - ------------ 997 - Implemented "Raw" (i.e. not encapsulated in SPNEGO) NTLMSSP (i.e. the Security Provider Interface used to negotiate 998 - session advanced session authentication). Raw NTLMSSP is preferred by Windows 2000 Professional and Windows XP. 999 - Began implementing support for SPNEGO encapsulation of NTLMSSP based session authentication blobs 1000 - (which is the mechanism preferred by Windows 2000 server in the absence of Kerberos). 1001 - 1002 - Version 0.38 1003 - ------------ 1004 - Introduced optional mount helper utility mount.cifs and made coreq changes to cifs vfs to enable 1005 - it. Fixed a few bugs in the DFS code (e.g. bcc two bytes too short and incorrect uid in PDU). 1006 - 1007 - Version 0.37 1008 - ------------ 1009 - Rewrote much of connection and mount/unmount logic to handle bugs with 1010 - multiple uses to same share, multiple users to same server etc. 1011 - 1012 - Version 0.36 1013 - ------------ 1014 - Fixed major problem with dentry corruption (missing call to dput) 1015 - 1016 - Version 0.35 1017 - ------------ 1018 - Rewrite of readdir code to fix bug. Various fixes for bigendian machines. 1019 - Begin adding oplock support. Multiusermount and oplockEnabled flags added to /proc/fs/cifs 1020 - although corresponding function not fully implemented in the vfs yet 1021 - 1022 - Version 0.34 1023 - ------------ 1024 - Fixed dentry caching bug, misc. cleanup 1025 - 1026 - Version 0.33 1027 - ------------ 1028 - Fixed 2.5 support to handle build and configure changes as well as misc. 2.5 changes. Now can build 1029 - on current 2.5 beta version (2.5.24) of the Linux kernel as well as on 2.4 Linux kernels. 1030 - Support for STATUS codes (newer 32 bit NT error codes) added. DFS support begun to be added. 1031 - 1032 - Version 0.32 1033 - ------------ 1034 - Unix extensions (symlink, readlink, hardlink, chmod and some chgrp and chown) implemented 1035 - and tested against Samba 2.2.5 1036 - 1037 - 1038 - Version 0.31 1039 - ------------ 1040 - 1) Fixed lockrange to be correct (it was one byte too short) 1041 - 1042 - 2) Fixed GETLK (i.e. the fcntl call to test a range of bytes in a file to see if locked) to correctly 1043 - show range as locked when there is a conflict with an existing lock. 1044 - 1045 - 3) default file perms are now 2767 (indicating support for mandatory locks) instead of 777 for directories 1046 - in most cases. Eventually will offer optional ability to query server for the correct perms. 1047 - 1048 - 3) Fixed eventual trap when mounting twice to different shares on the same server when the first succeeded 1049 - but the second one was invalid and failed (the second one was incorrectly disconnecting the tcp and smb 1050 - session) 1051 - 1052 - 4) Fixed error logging of valid mount options 1053 - 1054 - 5) Removed logging of password field. 1055 - 1056 - 6) Moved negotiate, treeDisconnect and uloggoffX (only tConx and SessSetup remain in connect.c) to cifssmb.c 1057 - and cleaned them up and made them more consistent with other cifs functions. 1058 - 1059 - 7) Server support for Unix extensions is now fully detected and FindFirst is implemented both ways 1060 - (with or without Unix extensions) but FindNext and QueryPathInfo with the Unix extensions are not completed, 1061 - nor is the symlink support using the Unix extensions 1062 - 1063 - 8) Started adding the readlink and follow_link code 1064 - 1065 - Version 0.3 1066 - ----------- 1067 - Initial drop 1068 - 1 + See https://wiki.samba.org/index.php/LinuxCIFSKernel for summary 2 + information (that may be easier to read than parsing the output of 3 + "git log fs/cifs") about fixes/improvements to CIFS/SMB2/SMB3 support (changes 4 + to cifs.ko module) by kernel version (and cifs internal module version).
+10 -12
Documentation/filesystems/cifs/README
··· 603 603 shares, features enabled as well as the cifs.ko 604 604 version. 605 605 Stats Lists summary resource usage information as well as per 606 - share statistics, if CONFIG_CIFS_STATS in enabled 607 - in the kernel configuration. 606 + share statistics. 608 607 609 608 Configuration pseudo-files: 610 609 SecurityFlags Flags which control security negotiation and ··· 686 687 logging of various informational messages. 2 enables logging of non-zero 687 688 SMB return codes while 4 enables logging of requests that take longer 688 689 than one second to complete (except for byte range lock requests). 689 - Setting it to 4 requires defining CONFIG_CIFS_STATS2 manually in the 690 - source code (typically by setting it in the beginning of cifsglob.h), 691 - and setting it to seven enables all three. Finally, tracing 690 + Setting it to 4 requires CONFIG_CIFS_STATS2 to be set in kernel configuration 691 + (.config). Setting it to seven enables all three. Finally, tracing 692 692 the start of smb requests and responses can be enabled via: 693 693 694 694 echo 1 > /proc/fs/cifs/traceSMB 695 695 696 - Per share (per client mount) statistics are available in /proc/fs/cifs/Stats 697 - if the kernel was configured with cifs statistics enabled. The statistics 698 - represent the number of successful (ie non-zero return code from the server) 699 - SMB responses to some of the more common commands (open, delete, mkdir etc.). 696 + Per share (per client mount) statistics are available in /proc/fs/cifs/Stats. 697 + Additional information is available if CONFIG_CIFS_STATS2 is enabled in the 698 + kernel configuration (.config). The statistics returned include counters which 699 + represent the number of attempted and failed (ie non-zero return code from the 700 + server) SMB3 (or cifs) requests grouped by request type (read, write, close etc.). 700 701 Also recorded is the total bytes read and bytes written to the server for 701 702 that share. Note that due to client caching effects this can be less than the 702 703 number of bytes read and written by the application running on the client. 703 - The statistics for the number of total SMBs and oplock breaks are different in 704 - that they represent all for that share, not just those for which the server 705 - returned success. 704 + Statistics can be reset to zero by "echo 0 > /proc/fs/cifs/Stats" which may be 705 + useful if comparing performance of two different scenarios. 706 706 707 707 Also note that "cat /proc/fs/cifs/DebugData" will display information about 708 708 the active sessions and the shares that are mounted.
+31 -28
fs/cifs/Kconfig
··· 16 16 select CRYPTO_DES 17 17 help 18 18 This is the client VFS module for the SMB3 family of NAS protocols, 19 - as well as for earlier dialects such as SMB2.1, SMB2 and the 19 + (including support for the most recent, most secure dialect SMB3.1.1) 20 + as well as for earlier dialects such as SMB2.1, SMB2 and the older 20 21 Common Internet File System (CIFS) protocol. CIFS was the successor 21 22 to the original dialect, the Server Message Block (SMB) protocol, the 22 23 native file sharing mechanism for most early PC operating systems. 23 24 24 - The SMB3 protocol is supported by most modern operating systems and 25 - NAS appliances (e.g. Samba, Windows 8, Windows 2012, MacOS). 25 + The SMB3 protocol is supported by most modern operating systems 26 + and NAS appliances (e.g. Samba, Windows 10, Windows Server 2016, 27 + MacOS) and even in the cloud (e.g. Microsoft Azure). 26 28 The older CIFS protocol was included in Windows NT4, 2000 and XP (and 27 29 later) as well by Samba (which provides excellent CIFS and SMB3 28 - server support for Linux and many other operating systems). Limited 29 - support for OS/2 and Windows ME and similar very old servers is 30 - provided as well. 30 + server support for Linux and many other operating systems). Use of 31 + dialects older than SMB2.1 is often discouraged on public networks. 32 + This module also provides limited support for OS/2 and Windows ME 33 + and similar very old servers. 31 34 32 - The cifs module provides an advanced network file system client 35 + This module provides an advanced network file system client 33 36 for mounting to SMB3 (and CIFS) compliant servers. It includes 34 37 support for DFS (hierarchical name space), secure per-user 35 - session establishment via Kerberos or NTLM or NTLMv2, 36 - safe distributed caching (oplock), optional packet 38 + session establishment via Kerberos or NTLM or NTLMv2, RDMA 39 + (smbdirect), advanced security features, per-share encryption, 40 + directory leases, safe distributed caching (oplock), optional packet 37 41 signing, Unicode and other internationalization improvements. 38 42 39 43 In general, the default dialects, SMB3 and later, enable better ··· 47 43 than SMB3 mounts. SMB2/SMB3 mount options are also 48 44 slightly simpler (compared to CIFS) due to protocol improvements. 49 45 50 - If you need to mount to Samba, Macs or Windows from this machine, say Y. 51 - 52 - config CIFS_STATS 53 - bool "CIFS statistics" 54 - depends on CIFS 55 - help 56 - Enabling this option will cause statistics for each server share 57 - mounted by the cifs client to be displayed in /proc/fs/cifs/Stats 46 + If you need to mount to Samba, Azure, Macs or Windows from this machine, say Y. 58 47 59 48 config CIFS_STATS2 60 49 bool "Extended statistics" 61 - depends on CIFS_STATS 50 + depends on CIFS 62 51 help 63 52 Enabling this option will allow more detailed statistics on SMB 64 53 request timing to be displayed in /proc/fs/cifs/DebugData and also ··· 63 66 Unless you are a developer or are doing network performance analysis 64 67 or tuning, say N. 65 68 69 + config CIFS_ALLOW_INSECURE_LEGACY 70 + bool "Support legacy servers which use less secure dialects" 71 + depends on CIFS 72 + default y 73 + help 74 + Modern dialects, SMB2.1 and later (including SMB3 and 3.1.1), have 75 + additional security features, including protection against 76 + man-in-the-middle attacks and stronger crypto hashes, so the use 77 + of legacy dialects (SMB1/CIFS and SMB2.0) is discouraged. 78 + 79 + Disabling this option prevents users from using vers=1.0 or vers=2.0 80 + on mounts with cifs.ko 81 + 82 + If unsure, say Y. 83 + 66 84 config CIFS_WEAK_PW_HASH 67 85 bool "Support legacy servers which use weaker LANMAN security" 68 - depends on CIFS 86 + depends on CIFS && CIFS_ALLOW_INSECURE_LEGACY 69 87 help 70 88 Modern CIFS servers including Samba and most Windows versions 71 89 (since 1997) support stronger NTLM (and even NTLMv2 and Kerberos) ··· 197 185 depends on CIFS && BROKEN 198 186 help 199 187 Allows NFS server to export a CIFS mounted share (nfsd over cifs) 200 - 201 - config CIFS_SMB311 202 - bool "SMB3.1.1 network file system support" 203 - depends on CIFS 204 - select CRYPTO_SHA512 205 - 206 - help 207 - This enables support for the newest, and most secure dialect, SMB3.11. 208 - If unsure, say Y 209 188 210 189 config CIFS_SMB_DIRECT 211 190 bool "SMB Direct support (Experimental)"
+4 -2
fs/cifs/cache.c
··· 128 128 129 129 memset(&auxdata, 0, sizeof(auxdata)); 130 130 auxdata.eof = cifsi->server_eof; 131 - auxdata.last_write_time = timespec64_to_timespec(cifsi->vfs_inode.i_mtime); 132 - auxdata.last_change_time = timespec64_to_timespec(cifsi->vfs_inode.i_ctime); 131 + auxdata.last_write_time_sec = cifsi->vfs_inode.i_mtime.tv_sec; 132 + auxdata.last_change_time_sec = cifsi->vfs_inode.i_ctime.tv_sec; 133 + auxdata.last_write_time_nsec = cifsi->vfs_inode.i_mtime.tv_nsec; 134 + auxdata.last_change_time_nsec = cifsi->vfs_inode.i_ctime.tv_nsec; 133 135 134 136 if (memcmp(data, &auxdata, datalen) != 0) 135 137 return FSCACHE_CHECKAUX_OBSOLETE;
+49 -17
fs/cifs/cifs_debug.c
··· 160 160 seq_printf(m, "CIFS Version %s\n", CIFS_VERSION); 161 161 seq_printf(m, "Features:"); 162 162 #ifdef CONFIG_CIFS_DFS_UPCALL 163 - seq_printf(m, " dfs"); 163 + seq_printf(m, " DFS"); 164 164 #endif 165 165 #ifdef CONFIG_CIFS_FSCACHE 166 - seq_printf(m, " fscache"); 166 + seq_printf(m, ",FSCACHE"); 167 + #endif 168 + #ifdef CONFIG_CIFS_SMB_DIRECT 169 + seq_printf(m, ",SMB_DIRECT"); 170 + #endif 171 + #ifdef CONFIG_CIFS_STATS2 172 + seq_printf(m, ",STATS2"); 173 + #else 174 + seq_printf(m, ",STATS"); 175 + #endif 176 + #ifdef CONFIG_CIFS_DEBUG2 177 + seq_printf(m, ",DEBUG2"); 178 + #elif defined(CONFIG_CIFS_DEBUG) 179 + seq_printf(m, ",DEBUG"); 180 + #endif 181 + #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY 182 + seq_printf(m, ",ALLOW_INSECURE_LEGACY"); 167 183 #endif 168 184 #ifdef CONFIG_CIFS_WEAK_PW_HASH 169 - seq_printf(m, " lanman"); 185 + seq_printf(m, ",WEAK_PW_HASH"); 170 186 #endif 171 187 #ifdef CONFIG_CIFS_POSIX 172 - seq_printf(m, " posix"); 188 + seq_printf(m, ",CIFS_POSIX"); 173 189 #endif 174 190 #ifdef CONFIG_CIFS_UPCALL 175 - seq_printf(m, " spnego"); 191 + seq_printf(m, ",UPCALL(SPNEGO)"); 176 192 #endif 177 193 #ifdef CONFIG_CIFS_XATTR 178 - seq_printf(m, " xattr"); 194 + seq_printf(m, ",XATTR"); 179 195 #endif 180 196 #ifdef CONFIG_CIFS_ACL 181 - seq_printf(m, " acl"); 197 + seq_printf(m, ",ACL"); 182 198 #endif 183 199 seq_putc(m, '\n'); 184 200 seq_printf(m, "Active VFS Requests: %d\n", GlobalTotalActiveXid); ··· 275 259 server->credits, server->dialect); 276 260 if (server->sign) 277 261 seq_printf(m, " signed"); 278 - #ifdef CONFIG_CIFS_SMB311 279 262 if (server->posix_ext_supported) 280 263 seq_printf(m, " posix"); 281 - #endif /* 3.1.1 */ 264 + 282 265 i++; 283 266 list_for_each(tmp2, &server->smb_ses_list) { 284 267 ses = list_entry(tmp2, struct cifs_ses, ··· 365 350 return 0; 366 351 } 367 352 368 - #ifdef CONFIG_CIFS_STATS 369 353 static ssize_t cifs_stats_proc_write(struct file *file, 370 354 const char __user *buffer, size_t count, loff_t *ppos) 371 355 { ··· 378 364 rc = kstrtobool_from_user(buffer, count, &bv); 379 365 if (rc == 0) { 380 366 #ifdef CONFIG_CIFS_STATS2 367 + int i; 368 + 381 369 atomic_set(&totBufAllocCount, 0); 382 370 atomic_set(&totSmBufAllocCount, 0); 383 371 #endif /* CONFIG_CIFS_STATS2 */ 372 + spin_lock(&GlobalMid_Lock); 373 + GlobalMaxActiveXid = 0; 374 + GlobalCurrentXid = 0; 375 + spin_unlock(&GlobalMid_Lock); 384 376 spin_lock(&cifs_tcp_ses_lock); 385 377 list_for_each(tmp1, &cifs_tcp_ses_list) { 386 378 server = list_entry(tmp1, struct TCP_Server_Info, 387 379 tcp_ses_list); 380 + #ifdef CONFIG_CIFS_STATS2 381 + for (i = 0; i < NUMBER_OF_SMB2_COMMANDS; i++) 382 + atomic_set(&server->smb2slowcmd[i], 0); 383 + #endif /* CONFIG_CIFS_STATS2 */ 388 384 list_for_each(tmp2, &server->smb_ses_list) { 389 385 ses = list_entry(tmp2, struct cifs_ses, 390 386 smb_ses_list); ··· 403 379 struct cifs_tcon, 404 380 tcon_list); 405 381 atomic_set(&tcon->num_smbs_sent, 0); 382 + spin_lock(&tcon->stat_lock); 383 + tcon->bytes_read = 0; 384 + tcon->bytes_written = 0; 385 + spin_unlock(&tcon->stat_lock); 406 386 if (server->ops->clear_stats) 407 387 server->ops->clear_stats(tcon); 408 388 } ··· 423 395 static int cifs_stats_proc_show(struct seq_file *m, void *v) 424 396 { 425 397 int i; 398 + #ifdef CONFIG_CIFS_STATS2 399 + int j; 400 + #endif /* STATS2 */ 426 401 struct list_head *tmp1, *tmp2, *tmp3; 427 402 struct TCP_Server_Info *server; 428 403 struct cifs_ses *ses; 429 404 struct cifs_tcon *tcon; 430 405 431 - seq_printf(m, 432 - "Resources in use\nCIFS Session: %d\n", 406 + seq_printf(m, "Resources in use\nCIFS Session: %d\n", 433 407 sesInfoAllocCount.counter); 434 408 seq_printf(m, "Share (unique mount targets): %d\n", 435 409 tconInfoAllocCount.counter); ··· 460 430 list_for_each(tmp1, &cifs_tcp_ses_list) { 461 431 server = list_entry(tmp1, struct TCP_Server_Info, 462 432 tcp_ses_list); 433 + #ifdef CONFIG_CIFS_STATS2 434 + for (j = 0; j < NUMBER_OF_SMB2_COMMANDS; j++) 435 + if (atomic_read(&server->smb2slowcmd[j])) 436 + seq_printf(m, "%d slow responses from %s for command %d\n", 437 + atomic_read(&server->smb2slowcmd[j]), 438 + server->hostname, j); 439 + #endif /* STATS2 */ 463 440 list_for_each(tmp2, &server->smb_ses_list) { 464 441 ses = list_entry(tmp2, struct cifs_ses, 465 442 smb_ses_list); ··· 503 466 .release = single_release, 504 467 .write = cifs_stats_proc_write, 505 468 }; 506 - #endif /* STATS */ 507 469 508 470 #ifdef CONFIG_CIFS_SMB_DIRECT 509 471 #define PROC_FILE_DEFINE(name) \ ··· 560 524 proc_create_single("DebugData", 0, proc_fs_cifs, 561 525 cifs_debug_data_proc_show); 562 526 563 - #ifdef CONFIG_CIFS_STATS 564 527 proc_create("Stats", 0644, proc_fs_cifs, &cifs_stats_proc_fops); 565 - #endif /* STATS */ 566 528 proc_create("cifsFYI", 0644, proc_fs_cifs, &cifsFYI_proc_fops); 567 529 proc_create("traceSMB", 0644, proc_fs_cifs, &traceSMB_proc_fops); 568 530 proc_create("LinuxExtensionsEnabled", 0644, proc_fs_cifs, ··· 598 564 remove_proc_entry("DebugData", proc_fs_cifs); 599 565 remove_proc_entry("cifsFYI", proc_fs_cifs); 600 566 remove_proc_entry("traceSMB", proc_fs_cifs); 601 - #ifdef CONFIG_CIFS_STATS 602 567 remove_proc_entry("Stats", proc_fs_cifs); 603 - #endif 604 568 remove_proc_entry("SecurityFlags", proc_fs_cifs); 605 569 remove_proc_entry("LinuxExtensionsEnabled", proc_fs_cifs); 606 570 remove_proc_entry("LookupCacheEnabled", proc_fs_cifs);
+9 -3
fs/cifs/cifsencrypt.c
··· 83 83 84 84 kaddr = (char *) kmap(rqst->rq_pages[i]) + offset; 85 85 86 - crypto_shash_update(shash, kaddr, len); 86 + rc = crypto_shash_update(shash, kaddr, len); 87 + if (rc) { 88 + cifs_dbg(VFS, "%s: Could not update with payload\n", 89 + __func__); 90 + kunmap(rqst->rq_pages[i]); 91 + return rc; 92 + } 87 93 88 94 kunmap(rqst->rq_pages[i]); 89 95 } ··· 458 452 unsigned char *blobptr; 459 453 unsigned char *blobend; 460 454 struct ntlmssp2_name *attrptr; 461 - struct timespec ts; 455 + struct timespec64 ts; 462 456 463 457 if (!ses->auth_key.len || !ses->auth_key.response) 464 458 return 0; ··· 483 477 blobptr += attrsize; /* advance attr value */ 484 478 } 485 479 486 - ktime_get_real_ts(&ts); 480 + ktime_get_real_ts64(&ts); 487 481 return cpu_to_le64(cifs_UnixTimeToNT(ts)); 488 482 } 489 483
+16 -17
fs/cifs/cifsfs.c
··· 139 139 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIXACL) 140 140 sb->s_flags |= SB_POSIXACL; 141 141 142 + if (tcon->snapshot_time) 143 + sb->s_flags |= SB_RDONLY; 144 + 142 145 if (tcon->ses->capabilities & tcon->ses->server->vals->cap_large_files) 143 146 sb->s_maxbytes = MAX_LFS_FILESIZE; 144 147 else ··· 212 209 213 210 xid = get_xid(); 214 211 215 - /* 216 - * PATH_MAX may be too long - it would presumably be total path, 217 - * but note that some servers (includinng Samba 3) have a shorter 218 - * maximum path. 219 - * 220 - * Instead could get the real value via SMB_QUERY_FS_ATTRIBUTE_INFO. 221 - */ 222 - buf->f_namelen = PATH_MAX; 212 + if (le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength) > 0) 213 + buf->f_namelen = 214 + le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength); 215 + else 216 + buf->f_namelen = PATH_MAX; 217 + 218 + buf->f_fsid.val[0] = tcon->vol_serial_number; 219 + /* are using part of create time for more randomness, see man statfs */ 220 + buf->f_fsid.val[1] = (int)le64_to_cpu(tcon->vol_create_time); 221 + 223 222 buf->f_files = 0; /* undefined */ 224 223 buf->f_ffree = 0; /* unlimited */ 225 224 ··· 432 427 else if (tcon->ses->user_name) 433 428 seq_show_option(s, "username", tcon->ses->user_name); 434 429 435 - if (tcon->ses->domainName) 430 + if (tcon->ses->domainName && tcon->ses->domainName[0] != 0) 436 431 seq_show_option(s, "domain", tcon->ses->domainName); 437 432 438 433 if (srcaddr->sa_family != AF_UNSPEC) { ··· 486 481 seq_puts(s, ",persistenthandles"); 487 482 else if (tcon->use_resilient) 488 483 seq_puts(s, ",resilienthandles"); 489 - 490 - #ifdef CONFIG_CIFS_SMB311 491 484 if (tcon->posix_extensions) 492 485 seq_puts(s, ",posix"); 493 486 else if (tcon->unix_ext) 494 487 seq_puts(s, ",unix"); 495 488 else 496 489 seq_puts(s, ",nounix"); 497 - #else 498 - if (tcon->unix_ext) 499 - seq_puts(s, ",unix"); 500 - else 501 - seq_puts(s, ",nounix"); 502 - #endif /* SMB311 */ 503 490 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) 504 491 seq_puts(s, ",posixpaths"); 505 492 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) ··· 543 546 seq_printf(s, ",wsize=%u", cifs_sb->wsize); 544 547 seq_printf(s, ",echo_interval=%lu", 545 548 tcon->ses->server->echo_interval / HZ); 549 + if (tcon->snapshot_time) 550 + seq_printf(s, ",snapshot=%llu", tcon->snapshot_time); 546 551 /* convert actimeo and display it in seconds */ 547 552 seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ); 548 553
+13 -41
fs/cifs/cifsglob.h
··· 76 76 #define SMB_ECHO_INTERVAL_MAX 600 77 77 #define SMB_ECHO_INTERVAL_DEFAULT 60 78 78 79 + /* maximum number of PDUs in one compound */ 80 + #define MAX_COMPOUND 5 81 + 79 82 /* 80 83 * Default number of credits to keep available for SMB3. 81 84 * This value is chosen somewhat arbitrarily. The Windows client ··· 194 191 Smb_21, 195 192 Smb_30, 196 193 Smb_302, 197 - #ifdef CONFIG_CIFS_SMB311 198 194 Smb_311, 199 - #endif /* SMB311 */ 200 195 Smb_3any, 201 196 Smb_default, 202 197 Smb_version_err ··· 457 456 long (*fallocate)(struct file *, struct cifs_tcon *, int, loff_t, 458 457 loff_t); 459 458 /* init transform request - used for encryption for now */ 460 - int (*init_transform_rq)(struct TCP_Server_Info *, struct smb_rqst *, 461 - struct smb_rqst *); 462 - /* free transform request */ 463 - void (*free_transform_rq)(struct smb_rqst *); 459 + int (*init_transform_rq)(struct TCP_Server_Info *, int num_rqst, 460 + struct smb_rqst *, struct smb_rqst *); 464 461 int (*is_transform_hdr)(void *buf); 465 462 int (*receive_transform)(struct TCP_Server_Info *, 466 - struct mid_q_entry **); 463 + struct mid_q_entry **, char **, int *); 467 464 enum securityEnum (*select_sectype)(struct TCP_Server_Info *, 468 465 enum securityEnum); 469 466 int (*next_header)(char *); ··· 683 684 #ifdef CONFIG_CIFS_STATS2 684 685 atomic_t in_send; /* requests trying to send */ 685 686 atomic_t num_waiters; /* blocked waiting to get in sendrecv */ 686 - #endif 687 + atomic_t smb2slowcmd[NUMBER_OF_SMB2_COMMANDS]; /* count resps > 1 sec */ 688 + #endif /* STATS2 */ 687 689 unsigned int max_read; 688 690 unsigned int max_write; 689 - #ifdef CONFIG_CIFS_SMB311 690 691 __le16 cipher_type; 691 692 /* save initital negprot hash */ 692 693 __u8 preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE]; 693 694 bool posix_ext_supported; 694 - #endif /* 3.1.1 */ 695 695 struct delayed_work reconnect; /* reconnect workqueue job */ 696 696 struct mutex reconnect_mutex; /* prevent simultaneous reconnects */ 697 697 unsigned long echo_interval; ··· 884 886 __u8 smb3signingkey[SMB3_SIGN_KEY_SIZE]; 885 887 __u8 smb3encryptionkey[SMB3_SIGN_KEY_SIZE]; 886 888 __u8 smb3decryptionkey[SMB3_SIGN_KEY_SIZE]; 887 - #ifdef CONFIG_CIFS_SMB311 888 889 __u8 preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE]; 889 - #endif /* 3.1.1 */ 890 890 891 891 /* 892 892 * Network interfaces available on the server this session is ··· 909 913 910 914 struct cached_fid { 911 915 bool is_valid:1; /* Do we have a useable root fid */ 916 + struct kref refcount; 912 917 struct cifs_fid *fid; 913 918 struct mutex fid_mutex; 914 919 struct cifs_tcon *tcon; ··· 933 936 __u32 tid; /* The 4 byte tree id */ 934 937 __u16 Flags; /* optional support bits */ 935 938 enum statusEnum tidStatus; 936 - #ifdef CONFIG_CIFS_STATS 937 939 atomic_t num_smbs_sent; 938 940 union { 939 941 struct { ··· 963 967 atomic_t smb2_com_failed[NUMBER_OF_SMB2_COMMANDS]; 964 968 } smb2_stats; 965 969 } stats; 966 - #ifdef CONFIG_CIFS_STATS2 967 - unsigned long long time_writes; 968 - unsigned long long time_reads; 969 - unsigned long long time_opens; 970 - unsigned long long time_deletes; 971 - unsigned long long time_closes; 972 - unsigned long long time_mkdirs; 973 - unsigned long long time_rmdirs; 974 - unsigned long long time_renames; 975 - unsigned long long time_t2renames; 976 - unsigned long long time_ffirst; 977 - unsigned long long time_fnext; 978 - unsigned long long time_fclose; 979 - #endif /* CONFIG_CIFS_STATS2 */ 980 970 __u64 bytes_read; 981 971 __u64 bytes_written; 982 972 spinlock_t stat_lock; /* protects the two fields above */ 983 - #endif /* CONFIG_CIFS_STATS */ 984 973 FILE_SYSTEM_DEVICE_INFO fsDevInfo; 985 974 FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if fs name truncated */ 986 975 FILE_SYSTEM_UNIX_INFO fsUnixInfo; ··· 978 997 bool seal:1; /* transport encryption for this mounted share */ 979 998 bool unix_ext:1; /* if false disable Linux extensions to CIFS protocol 980 999 for this mount even if server would support */ 981 - #ifdef CONFIG_CIFS_SMB311 982 1000 bool posix_extensions; /* if true SMB3.11 posix extensions enabled */ 983 - #endif /* CIFS_311 */ 984 1001 bool local_lease:1; /* check leases (only) on local system not remote */ 985 1002 bool broken_posix_open; /* e.g. Samba server versions < 3.3.2, 3.2.9 */ 986 1003 bool broken_sparse_sup; /* if server or share does not support sparse */ ··· 1025 1046 }; 1026 1047 1027 1048 extern struct tcon_link *cifs_sb_tlink(struct cifs_sb_info *cifs_sb); 1049 + extern void smb3_free_compound_rqst(int num_rqst, struct smb_rqst *rqst); 1028 1050 1029 1051 static inline struct cifs_tcon * 1030 1052 tlink_tcon(struct tcon_link *tlink) ··· 1332 1352 *pos = delim; 1333 1353 } 1334 1354 1335 - #ifdef CONFIG_CIFS_STATS 1336 1355 #define cifs_stats_inc atomic_inc 1337 1356 1338 1357 static inline void cifs_stats_bytes_written(struct cifs_tcon *tcon, ··· 1351 1372 tcon->bytes_read += bytes; 1352 1373 spin_unlock(&tcon->stat_lock); 1353 1374 } 1354 - #else 1355 - 1356 - #define cifs_stats_inc(field) do {} while (0) 1357 - #define cifs_stats_bytes_written(tcon, bytes) do {} while (0) 1358 - #define cifs_stats_bytes_read(tcon, bytes) do {} while (0) 1359 - 1360 - #endif 1361 1375 1362 1376 1363 1377 /* ··· 1516 1544 dev_t cf_rdev; 1517 1545 unsigned int cf_nlink; 1518 1546 unsigned int cf_dtype; 1519 - struct timespec cf_atime; 1520 - struct timespec cf_mtime; 1521 - struct timespec cf_ctime; 1547 + struct timespec64 cf_atime; 1548 + struct timespec64 cf_mtime; 1549 + struct timespec64 cf_ctime; 1522 1550 }; 1523 1551 1524 1552 static inline void free_dfs_info_param(struct dfs_info3_param *param)
+7 -3
fs/cifs/cifsproto.h
··· 94 94 extern int cifs_send_recv(const unsigned int xid, struct cifs_ses *ses, 95 95 struct smb_rqst *rqst, int *resp_buf_type, 96 96 const int flags, struct kvec *resp_iov); 97 + extern int compound_send_recv(const unsigned int xid, struct cifs_ses *ses, 98 + const int flags, const int num_rqst, 99 + struct smb_rqst *rqst, int *resp_buf_type, 100 + struct kvec *resp_iov); 97 101 extern int SendReceive(const unsigned int /* xid */ , struct cifs_ses *, 98 102 struct smb_hdr * /* input */ , 99 103 struct smb_hdr * /* out */ , ··· 147 143 enum securityEnum requested); 148 144 extern int CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses, 149 145 const struct nls_table *nls_cp); 150 - extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601); 151 - extern u64 cifs_UnixTimeToNT(struct timespec); 152 - extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, 146 + extern struct timespec64 cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601); 147 + extern u64 cifs_UnixTimeToNT(struct timespec64); 148 + extern struct timespec64 cnvrtDosUnixTm(__le16 le_date, __le16 le_time, 153 149 int offset); 154 150 extern void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock); 155 151 extern int cifs_get_writer(struct cifsInodeInfo *cinode);
+6 -6
fs/cifs/cifssmb.c
··· 508 508 * this requirement. 509 509 */ 510 510 int val, seconds, remain, result; 511 - struct timespec ts; 512 - unsigned long utc = ktime_get_real_seconds(); 511 + struct timespec64 ts; 512 + time64_t utc = ktime_get_real_seconds(); 513 513 ts = cnvrtDosUnixTm(rsp->SrvTime.Date, 514 514 rsp->SrvTime.Time, 0); 515 - cifs_dbg(FYI, "SrvTime %d sec since 1970 (utc: %d) diff: %d\n", 516 - (int)ts.tv_sec, (int)utc, 517 - (int)(utc - ts.tv_sec)); 515 + cifs_dbg(FYI, "SrvTime %lld sec since 1970 (utc: %lld) diff: %lld\n", 516 + ts.tv_sec, utc, 517 + utc - ts.tv_sec); 518 518 val = (int)(utc - ts.tv_sec); 519 519 seconds = abs(val); 520 520 result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ; ··· 4082 4082 if (rc) { 4083 4083 cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc); 4084 4084 } else if (data) { 4085 - struct timespec ts; 4085 + struct timespec64 ts; 4086 4086 __u32 time = le32_to_cpu(pSMBr->last_write_time); 4087 4087 4088 4088 /* decode response */
+66 -43
fs/cifs/connect.c
··· 303 303 { Smb_21, SMB21_VERSION_STRING }, 304 304 { Smb_30, SMB30_VERSION_STRING }, 305 305 { Smb_302, SMB302_VERSION_STRING }, 306 - #ifdef CONFIG_CIFS_SMB311 307 306 { Smb_311, SMB311_VERSION_STRING }, 308 307 { Smb_311, ALT_SMB311_VERSION_STRING }, 309 - #endif /* SMB311 */ 310 308 { Smb_3any, SMB3ANY_VERSION_STRING }, 311 309 { Smb_default, SMBDEFAULT_VERSION_STRING }, 312 310 { Smb_version_err, NULL } ··· 348 350 server->max_read = 0; 349 351 350 352 cifs_dbg(FYI, "Reconnecting tcp session\n"); 353 + trace_smb3_reconnect(server->CurrentMid, server->hostname); 351 354 352 355 /* before reconnecting the tcp session, mark the smb session (uid) 353 356 and the tid bad so they are not used until reconnected */ ··· 850 851 static int 851 852 cifs_demultiplex_thread(void *p) 852 853 { 853 - int length; 854 + int i, num_mids, length; 854 855 struct TCP_Server_Info *server = p; 855 856 unsigned int pdu_length; 856 857 unsigned int next_offset; 857 858 char *buf = NULL; 858 859 struct task_struct *task_to_wake = NULL; 859 - struct mid_q_entry *mid_entry; 860 + struct mid_q_entry *mids[MAX_COMPOUND]; 861 + char *bufs[MAX_COMPOUND]; 860 862 861 863 current->flags |= PF_MEMALLOC; 862 864 cifs_dbg(FYI, "Demultiplex PID: %d\n", task_pid_nr(current)); ··· 924 924 server->pdu_size = next_offset; 925 925 } 926 926 927 - mid_entry = NULL; 927 + memset(mids, 0, sizeof(mids)); 928 + memset(bufs, 0, sizeof(bufs)); 929 + num_mids = 0; 930 + 928 931 if (server->ops->is_transform_hdr && 929 932 server->ops->receive_transform && 930 933 server->ops->is_transform_hdr(buf)) { 931 934 length = server->ops->receive_transform(server, 932 - &mid_entry); 935 + mids, 936 + bufs, 937 + &num_mids); 933 938 } else { 934 - mid_entry = server->ops->find_mid(server, buf); 939 + mids[0] = server->ops->find_mid(server, buf); 940 + bufs[0] = buf; 941 + if (mids[0]) 942 + num_mids = 1; 935 943 936 - if (!mid_entry || !mid_entry->receive) 937 - length = standard_receive3(server, mid_entry); 944 + if (!mids[0] || !mids[0]->receive) 945 + length = standard_receive3(server, mids[0]); 938 946 else 939 - length = mid_entry->receive(server, mid_entry); 947 + length = mids[0]->receive(server, mids[0]); 940 948 } 941 949 942 950 if (length < 0) { 943 - if (mid_entry) 944 - cifs_mid_q_entry_release(mid_entry); 951 + for (i = 0; i < num_mids; i++) 952 + if (mids[i]) 953 + cifs_mid_q_entry_release(mids[i]); 945 954 continue; 946 955 } 947 956 948 957 if (server->large_buf) 949 958 buf = server->bigbuf; 950 959 960 + 951 961 server->lstrp = jiffies; 952 - if (mid_entry != NULL) { 953 - mid_entry->resp_buf_size = server->pdu_size; 954 - if ((mid_entry->mid_flags & MID_WAIT_CANCELLED) && 955 - mid_entry->mid_state == MID_RESPONSE_RECEIVED && 956 - server->ops->handle_cancelled_mid) 957 - server->ops->handle_cancelled_mid( 958 - mid_entry->resp_buf, 962 + 963 + for (i = 0; i < num_mids; i++) { 964 + if (mids[i] != NULL) { 965 + mids[i]->resp_buf_size = server->pdu_size; 966 + if ((mids[i]->mid_flags & MID_WAIT_CANCELLED) && 967 + mids[i]->mid_state == MID_RESPONSE_RECEIVED && 968 + server->ops->handle_cancelled_mid) 969 + server->ops->handle_cancelled_mid( 970 + mids[i]->resp_buf, 959 971 server); 960 972 961 - if (!mid_entry->multiRsp || mid_entry->multiEnd) 962 - mid_entry->callback(mid_entry); 973 + if (!mids[i]->multiRsp || mids[i]->multiEnd) 974 + mids[i]->callback(mids[i]); 963 975 964 - cifs_mid_q_entry_release(mid_entry); 965 - } else if (server->ops->is_oplock_break && 966 - server->ops->is_oplock_break(buf, server)) { 967 - cifs_dbg(FYI, "Received oplock break\n"); 968 - } else { 969 - cifs_dbg(VFS, "No task to wake, unknown frame received! NumMids %d\n", 970 - atomic_read(&midCount)); 971 - cifs_dump_mem("Received Data is: ", buf, 972 - HEADER_SIZE(server)); 976 + cifs_mid_q_entry_release(mids[i]); 977 + } else if (server->ops->is_oplock_break && 978 + server->ops->is_oplock_break(bufs[i], 979 + server)) { 980 + cifs_dbg(FYI, "Received oplock break\n"); 981 + } else { 982 + cifs_dbg(VFS, "No task to wake, unknown frame " 983 + "received! NumMids %d\n", 984 + atomic_read(&midCount)); 985 + cifs_dump_mem("Received Data is: ", bufs[i], 986 + HEADER_SIZE(server)); 973 987 #ifdef CONFIG_CIFS_DEBUG2 974 - if (server->ops->dump_detail) 975 - server->ops->dump_detail(buf, server); 976 - cifs_dump_mids(server); 988 + if (server->ops->dump_detail) 989 + server->ops->dump_detail(bufs[i], 990 + server); 991 + cifs_dump_mids(server); 977 992 #endif /* CIFS_DEBUG2 */ 993 + } 978 994 } 995 + 979 996 if (pdu_length > server->pdu_size) { 980 997 if (!allocate_buffers(server)) 981 998 continue; ··· 1191 1174 substring_t args[MAX_OPT_ARGS]; 1192 1175 1193 1176 switch (match_token(value, cifs_smb_version_tokens, args)) { 1177 + #ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY 1194 1178 case Smb_1: 1195 1179 if (disable_legacy_dialects) { 1196 1180 cifs_dbg(VFS, "mount with legacy dialect disabled\n"); ··· 1216 1198 vol->ops = &smb20_operations; 1217 1199 vol->vals = &smb20_values; 1218 1200 break; 1201 + #else 1202 + case Smb_1: 1203 + cifs_dbg(VFS, "vers=1.0 (cifs) mount not permitted when legacy dialects disabled\n"); 1204 + return 1; 1205 + case Smb_20: 1206 + cifs_dbg(VFS, "vers=2.0 mount not permitted when legacy dialects disabled\n"); 1207 + return 1; 1208 + #endif /* CIFS_ALLOW_INSECURE_LEGACY */ 1219 1209 case Smb_21: 1220 1210 vol->ops = &smb21_operations; 1221 1211 vol->vals = &smb21_values; ··· 1236 1210 vol->ops = &smb30_operations; /* currently identical with 3.0 */ 1237 1211 vol->vals = &smb302_values; 1238 1212 break; 1239 - #ifdef CONFIG_CIFS_SMB311 1240 1213 case Smb_311: 1241 1214 vol->ops = &smb311_operations; 1242 1215 vol->vals = &smb311_values; 1243 1216 break; 1244 - #endif /* SMB311 */ 1245 1217 case Smb_3any: 1246 1218 vol->ops = &smb30_operations; /* currently identical with 3.0 */ 1247 1219 vol->vals = &smb3any_values; ··· 3054 3030 } 3055 3031 } 3056 3032 3057 - #ifdef CONFIG_CIFS_SMB311 3058 - if ((volume_info->linux_ext) && (ses->server->posix_ext_supported)) { 3059 - if (ses->server->vals->protocol_id == SMB311_PROT_ID) { 3033 + if (volume_info->linux_ext) { 3034 + if (ses->server->posix_ext_supported) { 3060 3035 tcon->posix_extensions = true; 3061 3036 printk_once(KERN_WARNING 3062 3037 "SMB3.11 POSIX Extensions are experimental\n"); 3038 + } else { 3039 + cifs_dbg(VFS, "Server does not support mounting with posix SMB3.11 extensions.\n"); 3040 + rc = -EOPNOTSUPP; 3041 + goto out_fail; 3063 3042 } 3064 3043 } 3065 - #endif /* 311 */ 3066 3044 3067 3045 /* 3068 3046 * BB Do we need to wrap session_mutex around this TCon call and Unix ··· 4018 3992 goto remote_path_check; 4019 3993 } 4020 3994 4021 - #ifdef CONFIG_CIFS_SMB311 4022 3995 /* if new SMB3.11 POSIX extensions are supported do not remap / and \ */ 4023 3996 if (tcon->posix_extensions) 4024 3997 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS; 4025 - #endif /* SMB3.11 */ 4026 3998 4027 3999 /* tell server which Unix caps we support */ 4028 4000 if (cap_unix(tcon->ses)) { ··· 4483 4459 goto out; 4484 4460 } 4485 4461 4486 - #ifdef CONFIG_CIFS_SMB311 4487 4462 /* if new SMB3.11 POSIX extensions are supported do not remap / and \ */ 4488 4463 if (tcon->posix_extensions) 4489 4464 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS; 4490 - #endif /* SMB3.11 */ 4465 + 4491 4466 if (cap_unix(ses)) 4492 4467 reset_cifs_unix_caps(0, tcon, NULL, vol_info); 4493 4468
+8 -4
fs/cifs/fscache.c
··· 129 129 130 130 memset(&auxdata, 0, sizeof(auxdata)); 131 131 auxdata.eof = cifsi->server_eof; 132 - auxdata.last_write_time = timespec64_to_timespec(cifsi->vfs_inode.i_mtime); 133 - auxdata.last_change_time = timespec64_to_timespec(cifsi->vfs_inode.i_ctime); 132 + auxdata.last_write_time_sec = cifsi->vfs_inode.i_mtime.tv_sec; 133 + auxdata.last_change_time_sec = cifsi->vfs_inode.i_ctime.tv_sec; 134 + auxdata.last_write_time_nsec = cifsi->vfs_inode.i_mtime.tv_nsec; 135 + auxdata.last_change_time_nsec = cifsi->vfs_inode.i_ctime.tv_nsec; 134 136 135 137 cifsi->fscache = 136 138 fscache_acquire_cookie(tcon->fscache, ··· 168 166 if (cifsi->fscache) { 169 167 memset(&auxdata, 0, sizeof(auxdata)); 170 168 auxdata.eof = cifsi->server_eof; 171 - auxdata.last_write_time = timespec64_to_timespec(cifsi->vfs_inode.i_mtime); 172 - auxdata.last_change_time = timespec64_to_timespec(cifsi->vfs_inode.i_ctime); 169 + auxdata.last_write_time_sec = cifsi->vfs_inode.i_mtime.tv_sec; 170 + auxdata.last_change_time_sec = cifsi->vfs_inode.i_ctime.tv_sec; 171 + auxdata.last_write_time_nsec = cifsi->vfs_inode.i_mtime.tv_nsec; 172 + auxdata.last_change_time_nsec = cifsi->vfs_inode.i_ctime.tv_nsec; 173 173 174 174 cifs_dbg(FYI, "%s: (0x%p)\n", __func__, cifsi->fscache); 175 175 fscache_relinquish_cookie(cifsi->fscache, &auxdata, false);
+5 -3
fs/cifs/fscache.h
··· 31 31 * Auxiliary data attached to CIFS inode within the cache 32 32 */ 33 33 struct cifs_fscache_inode_auxdata { 34 - struct timespec last_write_time; 35 - struct timespec last_change_time; 36 - u64 eof; 34 + u64 last_write_time_sec; 35 + u64 last_change_time_sec; 36 + u32 last_write_time_nsec; 37 + u32 last_change_time_nsec; 38 + u64 eof; 37 39 }; 38 40 39 41 /*
+18 -20
fs/cifs/inode.c
··· 95 95 cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr) 96 96 { 97 97 struct cifsInodeInfo *cifs_i = CIFS_I(inode); 98 - struct timespec ts; 99 98 100 99 cifs_dbg(FYI, "%s: revalidating inode %llu\n", 101 100 __func__, cifs_i->uniqueid); ··· 113 114 } 114 115 115 116 /* revalidate if mtime or size have changed */ 116 - ts = timespec64_to_timespec(inode->i_mtime); 117 - if (timespec_equal(&ts, &fattr->cf_mtime) && 117 + if (timespec64_equal(&inode->i_mtime, &fattr->cf_mtime) && 118 118 cifs_i->server_eof == fattr->cf_eof) { 119 119 cifs_dbg(FYI, "%s: inode %llu is unchanged\n", 120 120 __func__, cifs_i->uniqueid); ··· 162 164 cifs_revalidate_cache(inode, fattr); 163 165 164 166 spin_lock(&inode->i_lock); 165 - inode->i_atime = timespec_to_timespec64(fattr->cf_atime); 166 - inode->i_mtime = timespec_to_timespec64(fattr->cf_mtime); 167 - inode->i_ctime = timespec_to_timespec64(fattr->cf_ctime); 167 + inode->i_atime = fattr->cf_atime; 168 + inode->i_mtime = fattr->cf_mtime; 169 + inode->i_ctime = fattr->cf_ctime; 168 170 inode->i_rdev = fattr->cf_rdev; 169 171 cifs_nlink_fattr_to_inode(inode, fattr); 170 172 inode->i_uid = fattr->cf_uid; ··· 325 327 fattr->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU; 326 328 fattr->cf_uid = cifs_sb->mnt_uid; 327 329 fattr->cf_gid = cifs_sb->mnt_gid; 328 - ktime_get_real_ts(&fattr->cf_mtime); 329 - fattr->cf_mtime = timespec_trunc(fattr->cf_mtime, sb->s_time_gran); 330 + ktime_get_real_ts64(&fattr->cf_mtime); 331 + fattr->cf_mtime = timespec64_trunc(fattr->cf_mtime, sb->s_time_gran); 330 332 fattr->cf_atime = fattr->cf_ctime = fattr->cf_mtime; 331 333 fattr->cf_nlink = 2; 332 334 fattr->cf_flags |= CIFS_FATTR_DFS_REFERRAL; ··· 602 604 if (info->LastAccessTime) 603 605 fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime); 604 606 else { 605 - ktime_get_real_ts(&fattr->cf_atime); 606 - fattr->cf_atime = timespec_trunc(fattr->cf_atime, sb->s_time_gran); 607 + ktime_get_real_ts64(&fattr->cf_atime); 608 + fattr->cf_atime = timespec64_trunc(fattr->cf_atime, sb->s_time_gran); 607 609 } 608 610 609 611 fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime); ··· 1120 1122 if (!server->ops->set_file_info) 1121 1123 return -ENOSYS; 1122 1124 1125 + info_buf.Pad = 0; 1126 + 1123 1127 if (attrs->ia_valid & ATTR_ATIME) { 1124 1128 set_time = true; 1125 1129 info_buf.LastAccessTime = 1126 - cpu_to_le64(cifs_UnixTimeToNT(timespec64_to_timespec(attrs->ia_atime))); 1130 + cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_atime)); 1127 1131 } else 1128 1132 info_buf.LastAccessTime = 0; 1129 1133 1130 1134 if (attrs->ia_valid & ATTR_MTIME) { 1131 1135 set_time = true; 1132 1136 info_buf.LastWriteTime = 1133 - cpu_to_le64(cifs_UnixTimeToNT(timespec64_to_timespec(attrs->ia_mtime))); 1137 + cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime)); 1134 1138 } else 1135 1139 info_buf.LastWriteTime = 0; 1136 1140 ··· 1145 1145 if (set_time && (attrs->ia_valid & ATTR_CTIME)) { 1146 1146 cifs_dbg(FYI, "CIFS - CTIME changed\n"); 1147 1147 info_buf.ChangeTime = 1148 - cpu_to_le64(cifs_UnixTimeToNT(timespec64_to_timespec(attrs->ia_ctime))); 1148 + cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime)); 1149 1149 } else 1150 1150 info_buf.ChangeTime = 0; 1151 1151 ··· 1577 1577 1578 1578 server = tcon->ses->server; 1579 1579 1580 - #ifdef CONFIG_CIFS_SMB311 1581 1580 if ((server->ops->posix_mkdir) && (tcon->posix_extensions)) { 1582 1581 rc = server->ops->posix_mkdir(xid, inode, mode, tcon, full_path, 1583 1582 cifs_sb); 1584 1583 d_drop(direntry); /* for time being always refresh inode info */ 1585 1584 goto mkdir_out; 1586 1585 } 1587 - #endif /* SMB311 */ 1588 1586 1589 1587 if (cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP & 1590 1588 le64_to_cpu(tcon->fsUnixInfo.Capability))) { ··· 2069 2071 /* old CIFS Unix Extensions doesn't return create time */ 2070 2072 if (CIFS_I(inode)->createtime) { 2071 2073 stat->result_mask |= STATX_BTIME; 2072 - stat->btime = timespec_to_timespec64( 2073 - cifs_NTtimeToUnix(cpu_to_le64(CIFS_I(inode)->createtime))); 2074 + stat->btime = 2075 + cifs_NTtimeToUnix(cpu_to_le64(CIFS_I(inode)->createtime)); 2074 2076 } 2075 2077 2076 2078 stat->attributes_mask |= (STATX_ATTR_COMPRESSED | STATX_ATTR_ENCRYPTED); ··· 2276 2278 args->gid = INVALID_GID; /* no change */ 2277 2279 2278 2280 if (attrs->ia_valid & ATTR_ATIME) 2279 - args->atime = cifs_UnixTimeToNT(timespec64_to_timespec(attrs->ia_atime)); 2281 + args->atime = cifs_UnixTimeToNT(attrs->ia_atime); 2280 2282 else 2281 2283 args->atime = NO_CHANGE_64; 2282 2284 2283 2285 if (attrs->ia_valid & ATTR_MTIME) 2284 - args->mtime = cifs_UnixTimeToNT(timespec64_to_timespec(attrs->ia_mtime)); 2286 + args->mtime = cifs_UnixTimeToNT(attrs->ia_mtime); 2285 2287 else 2286 2288 args->mtime = NO_CHANGE_64; 2287 2289 2288 2290 if (attrs->ia_valid & ATTR_CTIME) 2289 - args->ctime = cifs_UnixTimeToNT(timespec64_to_timespec(attrs->ia_ctime)); 2291 + args->ctime = cifs_UnixTimeToNT(attrs->ia_ctime); 2290 2292 else 2291 2293 args->ctime = NO_CHANGE_64; 2292 2294
+2 -2
fs/cifs/link.c
··· 396 396 struct cifs_io_parms io_parms; 397 397 int buf_type = CIFS_NO_BUFFER; 398 398 __le16 *utf16_path; 399 - __u8 oplock = SMB2_OPLOCK_LEVEL_II; 399 + __u8 oplock = SMB2_OPLOCK_LEVEL_NONE; 400 400 struct smb2_file_all_info *pfile_info = NULL; 401 401 402 402 oparms.tcon = tcon; ··· 459 459 struct cifs_io_parms io_parms; 460 460 int create_options = CREATE_NOT_DIR; 461 461 __le16 *utf16_path; 462 - __u8 oplock = SMB2_OPLOCK_LEVEL_EXCLUSIVE; 462 + __u8 oplock = SMB2_OPLOCK_LEVEL_NONE; 463 463 struct kvec iov[2]; 464 464 465 465 if (backup_cred(cifs_sb))
-2
fs/cifs/misc.c
··· 122 122 mutex_init(&ret_buf->crfid.fid_mutex); 123 123 ret_buf->crfid.fid = kzalloc(sizeof(struct cifs_fid), 124 124 GFP_KERNEL); 125 - #ifdef CONFIG_CIFS_STATS 126 125 spin_lock_init(&ret_buf->stat_lock); 127 - #endif 128 126 } 129 127 return ret_buf; 130 128 }
+10 -9
fs/cifs/netmisc.c
··· 918 918 * Convert the NT UTC (based 1601-01-01, in hundred nanosecond units) 919 919 * into Unix UTC (based 1970-01-01, in seconds). 920 920 */ 921 - struct timespec 921 + struct timespec64 922 922 cifs_NTtimeToUnix(__le64 ntutc) 923 923 { 924 - struct timespec ts; 924 + struct timespec64 ts; 925 925 /* BB what about the timezone? BB */ 926 926 927 927 /* Subtract the NTFS time offset, then convert to 1s intervals. */ ··· 935 935 */ 936 936 if (t < 0) { 937 937 abs_t = -t; 938 - ts.tv_nsec = (long)(do_div(abs_t, 10000000) * 100); 938 + ts.tv_nsec = (time64_t)(do_div(abs_t, 10000000) * 100); 939 939 ts.tv_nsec = -ts.tv_nsec; 940 940 ts.tv_sec = -abs_t; 941 941 } else { 942 942 abs_t = t; 943 - ts.tv_nsec = (long)do_div(abs_t, 10000000) * 100; 943 + ts.tv_nsec = (time64_t)do_div(abs_t, 10000000) * 100; 944 944 ts.tv_sec = abs_t; 945 945 } 946 946 ··· 949 949 950 950 /* Convert the Unix UTC into NT UTC. */ 951 951 u64 952 - cifs_UnixTimeToNT(struct timespec t) 952 + cifs_UnixTimeToNT(struct timespec64 t) 953 953 { 954 954 /* Convert to 100ns intervals and then add the NTFS time offset. */ 955 955 return (u64) t.tv_sec * 10000000 + t.tv_nsec/100 + NTFS_TIME_OFFSET; ··· 959 959 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 960 960 }; 961 961 962 - struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset) 962 + struct timespec64 cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset) 963 963 { 964 - struct timespec ts; 965 - int sec, min, days, month, year; 964 + struct timespec64 ts; 965 + time64_t sec; 966 + int min, days, month, year; 966 967 u16 date = le16_to_cpu(le_date); 967 968 u16 time = le16_to_cpu(le_time); 968 969 SMB_TIME *st = (SMB_TIME *)&time; ··· 974 973 sec = 2 * st->TwoSeconds; 975 974 min = st->Minutes; 976 975 if ((sec > 59) || (min > 59)) 977 - cifs_dbg(VFS, "illegal time min %d sec %d\n", min, sec); 976 + cifs_dbg(VFS, "illegal time min %d sec %lld\n", min, sec); 978 977 sec += (min * 60); 979 978 sec += 60 * 60 * st->Hours; 980 979 if (st->Hours > 24)
-4
fs/cifs/smb1ops.c
··· 624 624 static void 625 625 cifs_clear_stats(struct cifs_tcon *tcon) 626 626 { 627 - #ifdef CONFIG_CIFS_STATS 628 627 atomic_set(&tcon->stats.cifs_stats.num_writes, 0); 629 628 atomic_set(&tcon->stats.cifs_stats.num_reads, 0); 630 629 atomic_set(&tcon->stats.cifs_stats.num_flushes, 0); ··· 645 646 atomic_set(&tcon->stats.cifs_stats.num_locks, 0); 646 647 atomic_set(&tcon->stats.cifs_stats.num_acl_get, 0); 647 648 atomic_set(&tcon->stats.cifs_stats.num_acl_set, 0); 648 - #endif 649 649 } 650 650 651 651 static void 652 652 cifs_print_stats(struct seq_file *m, struct cifs_tcon *tcon) 653 653 { 654 - #ifdef CONFIG_CIFS_STATS 655 654 seq_printf(m, " Oplocks breaks: %d", 656 655 atomic_read(&tcon->stats.cifs_stats.num_oplock_brks)); 657 656 seq_printf(m, "\nReads: %d Bytes: %llu", ··· 681 684 atomic_read(&tcon->stats.cifs_stats.num_ffirst), 682 685 atomic_read(&tcon->stats.cifs_stats.num_fnext), 683 686 atomic_read(&tcon->stats.cifs_stats.num_fclose)); 684 - #endif 685 687 } 686 688 687 689 static void
+4 -2
fs/cifs/smb2inode.c
··· 120 120 break; 121 121 } 122 122 123 - if (use_cached_root_handle == false) 123 + if (use_cached_root_handle) 124 + close_shroot(&tcon->crfid); 125 + else 124 126 rc = SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); 125 127 if (tmprc) 126 128 rc = tmprc; ··· 283 281 int rc; 284 282 285 283 if ((buf->CreationTime == 0) && (buf->LastAccessTime == 0) && 286 - (buf->LastWriteTime == 0) && (buf->ChangeTime) && 284 + (buf->LastWriteTime == 0) && (buf->ChangeTime == 0) && 287 285 (buf->Attributes == 0)) 288 286 return 0; /* would be a no op, no sense sending this */ 289 287
+3 -10
fs/cifs/smb2misc.c
··· 93 93 /* SMB2_OPLOCK_BREAK */ cpu_to_le16(24) 94 94 }; 95 95 96 - #ifdef CONFIG_CIFS_SMB311 97 96 static __u32 get_neg_ctxt_len(struct smb2_sync_hdr *hdr, __u32 len, 98 97 __u32 non_ctxlen) 99 98 { ··· 126 127 /* length of negcontexts including pad from end of sec blob to them */ 127 128 return (len - nc_offset) + size_of_pad_before_neg_ctxts; 128 129 } 129 - #endif /* CIFS_SMB311 */ 130 130 131 131 int 132 132 smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *srvr) ··· 220 222 221 223 clc_len = smb2_calc_size(buf, srvr); 222 224 223 - #ifdef CONFIG_CIFS_SMB311 224 225 if (shdr->Command == SMB2_NEGOTIATE) 225 226 clc_len += get_neg_ctxt_len(shdr, len, clc_len); 226 - #endif /* SMB311 */ 227 + 227 228 if (len != clc_len) { 228 229 cifs_dbg(FYI, "Calculated size %u length %u mismatch mid %llu\n", 229 230 clc_len, len, mid); ··· 448 451 /* Windows doesn't allow paths beginning with \ */ 449 452 if (from[0] == '\\') 450 453 start_of_path = from + 1; 451 - #ifdef CONFIG_CIFS_SMB311 454 + 452 455 /* SMB311 POSIX extensions paths do not include leading slash */ 453 456 else if (cifs_sb_master_tlink(cifs_sb) && 454 457 cifs_sb_master_tcon(cifs_sb)->posix_extensions && 455 458 (from[0] == '/')) { 456 459 start_of_path = from + 1; 457 - } 458 - #endif /* 311 */ 459 - else 460 + } else 460 461 start_of_path = from; 461 462 462 463 to = cifs_strndup_to_utf16(start_of_path, PATH_MAX, &len, ··· 754 759 return 0; 755 760 } 756 761 757 - #ifdef CONFIG_CIFS_SMB311 758 762 /** 759 763 * smb311_update_preauth_hash - update @ses hash with the packet data in @iov 760 764 * ··· 815 821 816 822 return 0; 817 823 } 818 - #endif
+392 -170
fs/cifs/smb2ops.c
··· 444 444 FSCTL_QUERY_NETWORK_INTERFACE_INFO, true /* is_fsctl */, 445 445 NULL /* no data input */, 0 /* no data input */, 446 446 (char **)&out_buf, &ret_data_len); 447 - if (rc != 0) { 447 + if (rc == -EOPNOTSUPP) { 448 + cifs_dbg(FYI, 449 + "server does not support query network interfaces\n"); 450 + goto out; 451 + } else if (rc != 0) { 448 452 cifs_dbg(VFS, "error %d on ioctl to get interface list\n", rc); 449 453 goto out; 450 454 } ··· 470 466 return rc; 471 467 } 472 468 473 - void 474 - smb2_cached_lease_break(struct work_struct *work) 469 + static void 470 + smb2_close_cached_fid(struct kref *ref) 475 471 { 476 - struct cached_fid *cfid = container_of(work, 477 - struct cached_fid, lease_break); 478 - mutex_lock(&cfid->fid_mutex); 472 + struct cached_fid *cfid = container_of(ref, struct cached_fid, 473 + refcount); 474 + 479 475 if (cfid->is_valid) { 480 476 cifs_dbg(FYI, "clear cached root file handle\n"); 481 477 SMB2_close(0, cfid->tcon, cfid->fid->persistent_fid, 482 478 cfid->fid->volatile_fid); 483 479 cfid->is_valid = false; 484 480 } 481 + } 482 + 483 + void close_shroot(struct cached_fid *cfid) 484 + { 485 + mutex_lock(&cfid->fid_mutex); 486 + kref_put(&cfid->refcount, smb2_close_cached_fid); 485 487 mutex_unlock(&cfid->fid_mutex); 488 + } 489 + 490 + void 491 + smb2_cached_lease_break(struct work_struct *work) 492 + { 493 + struct cached_fid *cfid = container_of(work, 494 + struct cached_fid, lease_break); 495 + 496 + close_shroot(cfid); 486 497 } 487 498 488 499 /* ··· 514 495 if (tcon->crfid.is_valid) { 515 496 cifs_dbg(FYI, "found a cached root file handle\n"); 516 497 memcpy(pfid, tcon->crfid.fid, sizeof(struct cifs_fid)); 498 + kref_get(&tcon->crfid.refcount); 517 499 mutex_unlock(&tcon->crfid.fid_mutex); 518 500 return 0; 519 501 } ··· 531 511 memcpy(tcon->crfid.fid, pfid, sizeof(struct cifs_fid)); 532 512 tcon->crfid.tcon = tcon; 533 513 tcon->crfid.is_valid = true; 514 + kref_init(&tcon->crfid.refcount); 515 + kref_get(&tcon->crfid.refcount); 534 516 } 535 517 mutex_unlock(&tcon->crfid.fid_mutex); 536 518 return rc; ··· 571 549 SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid, 572 550 FS_DEVICE_INFORMATION); 573 551 SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid, 552 + FS_VOLUME_INFORMATION); 553 + SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid, 574 554 FS_SECTOR_SIZE_INFORMATION); /* SMB3 specific */ 575 555 if (no_cached_open) 576 556 SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); 557 + else 558 + close_shroot(&tcon->crfid); 559 + 577 560 return; 578 561 } 579 562 ··· 900 873 static void 901 874 smb2_clear_stats(struct cifs_tcon *tcon) 902 875 { 903 - #ifdef CONFIG_CIFS_STATS 904 876 int i; 905 877 for (i = 0; i < NUMBER_OF_SMB2_COMMANDS; i++) { 906 878 atomic_set(&tcon->stats.smb2_stats.smb2_com_sent[i], 0); 907 879 atomic_set(&tcon->stats.smb2_stats.smb2_com_failed[i], 0); 908 880 } 909 - #endif 910 881 } 911 882 912 883 static void ··· 943 918 static void 944 919 smb2_print_stats(struct seq_file *m, struct cifs_tcon *tcon) 945 920 { 946 - #ifdef CONFIG_CIFS_STATS 947 921 atomic_t *sent = tcon->stats.smb2_stats.smb2_com_sent; 948 922 atomic_t *failed = tcon->stats.smb2_stats.smb2_com_failed; 949 - seq_printf(m, "\nNegotiates: %d sent %d failed", 950 - atomic_read(&sent[SMB2_NEGOTIATE_HE]), 951 - atomic_read(&failed[SMB2_NEGOTIATE_HE])); 952 - seq_printf(m, "\nSessionSetups: %d sent %d failed", 953 - atomic_read(&sent[SMB2_SESSION_SETUP_HE]), 954 - atomic_read(&failed[SMB2_SESSION_SETUP_HE])); 955 - seq_printf(m, "\nLogoffs: %d sent %d failed", 956 - atomic_read(&sent[SMB2_LOGOFF_HE]), 957 - atomic_read(&failed[SMB2_LOGOFF_HE])); 958 - seq_printf(m, "\nTreeConnects: %d sent %d failed", 923 + 924 + /* 925 + * Can't display SMB2_NEGOTIATE, SESSION_SETUP, LOGOFF, CANCEL and ECHO 926 + * totals (requests sent) since those SMBs are per-session not per tcon 927 + */ 928 + seq_printf(m, "\nBytes read: %llu Bytes written: %llu", 929 + (long long)(tcon->bytes_read), 930 + (long long)(tcon->bytes_written)); 931 + seq_printf(m, "\nTreeConnects: %d total %d failed", 959 932 atomic_read(&sent[SMB2_TREE_CONNECT_HE]), 960 933 atomic_read(&failed[SMB2_TREE_CONNECT_HE])); 961 - seq_printf(m, "\nTreeDisconnects: %d sent %d failed", 934 + seq_printf(m, "\nTreeDisconnects: %d total %d failed", 962 935 atomic_read(&sent[SMB2_TREE_DISCONNECT_HE]), 963 936 atomic_read(&failed[SMB2_TREE_DISCONNECT_HE])); 964 - seq_printf(m, "\nCreates: %d sent %d failed", 937 + seq_printf(m, "\nCreates: %d total %d failed", 965 938 atomic_read(&sent[SMB2_CREATE_HE]), 966 939 atomic_read(&failed[SMB2_CREATE_HE])); 967 - seq_printf(m, "\nCloses: %d sent %d failed", 940 + seq_printf(m, "\nCloses: %d total %d failed", 968 941 atomic_read(&sent[SMB2_CLOSE_HE]), 969 942 atomic_read(&failed[SMB2_CLOSE_HE])); 970 - seq_printf(m, "\nFlushes: %d sent %d failed", 943 + seq_printf(m, "\nFlushes: %d total %d failed", 971 944 atomic_read(&sent[SMB2_FLUSH_HE]), 972 945 atomic_read(&failed[SMB2_FLUSH_HE])); 973 - seq_printf(m, "\nReads: %d sent %d failed", 946 + seq_printf(m, "\nReads: %d total %d failed", 974 947 atomic_read(&sent[SMB2_READ_HE]), 975 948 atomic_read(&failed[SMB2_READ_HE])); 976 - seq_printf(m, "\nWrites: %d sent %d failed", 949 + seq_printf(m, "\nWrites: %d total %d failed", 977 950 atomic_read(&sent[SMB2_WRITE_HE]), 978 951 atomic_read(&failed[SMB2_WRITE_HE])); 979 - seq_printf(m, "\nLocks: %d sent %d failed", 952 + seq_printf(m, "\nLocks: %d total %d failed", 980 953 atomic_read(&sent[SMB2_LOCK_HE]), 981 954 atomic_read(&failed[SMB2_LOCK_HE])); 982 - seq_printf(m, "\nIOCTLs: %d sent %d failed", 955 + seq_printf(m, "\nIOCTLs: %d total %d failed", 983 956 atomic_read(&sent[SMB2_IOCTL_HE]), 984 957 atomic_read(&failed[SMB2_IOCTL_HE])); 985 - seq_printf(m, "\nCancels: %d sent %d failed", 986 - atomic_read(&sent[SMB2_CANCEL_HE]), 987 - atomic_read(&failed[SMB2_CANCEL_HE])); 988 - seq_printf(m, "\nEchos: %d sent %d failed", 989 - atomic_read(&sent[SMB2_ECHO_HE]), 990 - atomic_read(&failed[SMB2_ECHO_HE])); 991 - seq_printf(m, "\nQueryDirectories: %d sent %d failed", 958 + seq_printf(m, "\nQueryDirectories: %d total %d failed", 992 959 atomic_read(&sent[SMB2_QUERY_DIRECTORY_HE]), 993 960 atomic_read(&failed[SMB2_QUERY_DIRECTORY_HE])); 994 - seq_printf(m, "\nChangeNotifies: %d sent %d failed", 961 + seq_printf(m, "\nChangeNotifies: %d total %d failed", 995 962 atomic_read(&sent[SMB2_CHANGE_NOTIFY_HE]), 996 963 atomic_read(&failed[SMB2_CHANGE_NOTIFY_HE])); 997 - seq_printf(m, "\nQueryInfos: %d sent %d failed", 964 + seq_printf(m, "\nQueryInfos: %d total %d failed", 998 965 atomic_read(&sent[SMB2_QUERY_INFO_HE]), 999 966 atomic_read(&failed[SMB2_QUERY_INFO_HE])); 1000 - seq_printf(m, "\nSetInfos: %d sent %d failed", 967 + seq_printf(m, "\nSetInfos: %d total %d failed", 1001 968 atomic_read(&sent[SMB2_SET_INFO_HE]), 1002 969 atomic_read(&failed[SMB2_SET_INFO_HE])); 1003 970 seq_printf(m, "\nOplockBreaks: %d sent %d failed", 1004 971 atomic_read(&sent[SMB2_OPLOCK_BREAK_HE]), 1005 972 atomic_read(&failed[SMB2_OPLOCK_BREAK_HE])); 1006 - #endif 1007 973 } 1008 974 1009 975 static void ··· 1369 1353 1370 1354 } 1371 1355 1356 + /* GMT Token is @GMT-YYYY.MM.DD-HH.MM.SS Unicode which is 48 bytes + null */ 1357 + #define GMT_TOKEN_SIZE 50 1358 + 1359 + /* 1360 + * Input buffer contains (empty) struct smb_snapshot array with size filled in 1361 + * For output see struct SRV_SNAPSHOT_ARRAY in MS-SMB2 section 2.2.32.2 1362 + */ 1372 1363 static int 1373 1364 smb3_enum_snapshots(const unsigned int xid, struct cifs_tcon *tcon, 1374 1365 struct cifsFileInfo *cfile, void __user *ioc_buf) ··· 1405 1382 kfree(retbuf); 1406 1383 return rc; 1407 1384 } 1408 - if (snapshot_in.snapshot_array_size < sizeof(struct smb_snapshot_array)) { 1409 - rc = -ERANGE; 1410 - kfree(retbuf); 1411 - return rc; 1412 - } 1413 1385 1414 - if (ret_data_len > snapshot_in.snapshot_array_size) 1415 - ret_data_len = snapshot_in.snapshot_array_size; 1386 + /* 1387 + * Check for min size, ie not large enough to fit even one GMT 1388 + * token (snapshot). On the first ioctl some users may pass in 1389 + * smaller size (or zero) to simply get the size of the array 1390 + * so the user space caller can allocate sufficient memory 1391 + * and retry the ioctl again with larger array size sufficient 1392 + * to hold all of the snapshot GMT tokens on the second try. 1393 + */ 1394 + if (snapshot_in.snapshot_array_size < GMT_TOKEN_SIZE) 1395 + ret_data_len = sizeof(struct smb_snapshot_array); 1396 + 1397 + /* 1398 + * We return struct SRV_SNAPSHOT_ARRAY, followed by 1399 + * the snapshot array (of 50 byte GMT tokens) each 1400 + * representing an available previous version of the data 1401 + */ 1402 + if (ret_data_len > (snapshot_in.snapshot_array_size + 1403 + sizeof(struct smb_snapshot_array))) 1404 + ret_data_len = snapshot_in.snapshot_array_size + 1405 + sizeof(struct smb_snapshot_array); 1416 1406 1417 1407 if (copy_to_user(ioc_buf, retbuf, ret_data_len)) 1418 1408 rc = -EFAULT; ··· 1523 1487 shdr->Status != STATUS_USER_SESSION_DELETED) 1524 1488 return false; 1525 1489 1490 + trace_smb3_ses_expired(shdr->TreeId, shdr->SessionId, 1491 + le16_to_cpu(shdr->Command), 1492 + le64_to_cpu(shdr->MessageId)); 1526 1493 cifs_dbg(FYI, "Session expired or deleted\n"); 1494 + 1527 1495 return true; 1528 1496 } 1529 1497 ··· 1544 1504 CIFS_CACHE_READ(cinode) ? 1 : 0); 1545 1505 } 1546 1506 1507 + static void 1508 + smb2_set_related(struct smb_rqst *rqst) 1509 + { 1510 + struct smb2_sync_hdr *shdr; 1511 + 1512 + shdr = (struct smb2_sync_hdr *)(rqst->rq_iov[0].iov_base); 1513 + shdr->Flags |= SMB2_FLAGS_RELATED_OPERATIONS; 1514 + } 1515 + 1516 + char smb2_padding[7] = {0, 0, 0, 0, 0, 0, 0}; 1517 + 1518 + static void 1519 + smb2_set_next_command(struct TCP_Server_Info *server, struct smb_rqst *rqst) 1520 + { 1521 + struct smb2_sync_hdr *shdr; 1522 + unsigned long len = smb_rqst_len(server, rqst); 1523 + 1524 + /* SMB headers in a compound are 8 byte aligned. */ 1525 + if (len & 7) { 1526 + rqst->rq_iov[rqst->rq_nvec].iov_base = smb2_padding; 1527 + rqst->rq_iov[rqst->rq_nvec].iov_len = 8 - (len & 7); 1528 + rqst->rq_nvec++; 1529 + len = smb_rqst_len(server, rqst); 1530 + } 1531 + 1532 + shdr = (struct smb2_sync_hdr *)(rqst->rq_iov[0].iov_base); 1533 + shdr->NextCommand = cpu_to_le32(len); 1534 + } 1535 + 1547 1536 static int 1548 1537 smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon, 1538 + struct kstatfs *buf) 1539 + { 1540 + struct smb2_query_info_rsp *rsp; 1541 + struct smb2_fs_full_size_info *info = NULL; 1542 + struct smb_rqst rqst[3]; 1543 + int resp_buftype[3]; 1544 + struct kvec rsp_iov[3]; 1545 + struct kvec open_iov[5]; /* 4 + potential padding. */ 1546 + struct kvec qi_iov[1]; 1547 + struct kvec close_iov[1]; 1548 + struct cifs_ses *ses = tcon->ses; 1549 + struct TCP_Server_Info *server = ses->server; 1550 + __le16 srch_path = 0; /* Null - open root of share */ 1551 + u8 oplock = SMB2_OPLOCK_LEVEL_NONE; 1552 + struct cifs_open_parms oparms; 1553 + struct cifs_fid fid; 1554 + int flags = 0; 1555 + int rc; 1556 + 1557 + if (smb3_encryption_required(tcon)) 1558 + flags |= CIFS_TRANSFORM_REQ; 1559 + 1560 + memset(rqst, 0, sizeof(rqst)); 1561 + memset(resp_buftype, 0, sizeof(resp_buftype)); 1562 + memset(rsp_iov, 0, sizeof(rsp_iov)); 1563 + 1564 + memset(&open_iov, 0, sizeof(open_iov)); 1565 + rqst[0].rq_iov = open_iov; 1566 + rqst[0].rq_nvec = 4; 1567 + 1568 + oparms.tcon = tcon; 1569 + oparms.desired_access = FILE_READ_ATTRIBUTES; 1570 + oparms.disposition = FILE_OPEN; 1571 + oparms.create_options = 0; 1572 + oparms.fid = &fid; 1573 + oparms.reconnect = false; 1574 + 1575 + rc = SMB2_open_init(tcon, &rqst[0], &oplock, &oparms, &srch_path); 1576 + if (rc) 1577 + goto qfs_exit; 1578 + smb2_set_next_command(server, &rqst[0]); 1579 + 1580 + memset(&qi_iov, 0, sizeof(qi_iov)); 1581 + rqst[1].rq_iov = qi_iov; 1582 + rqst[1].rq_nvec = 1; 1583 + 1584 + rc = SMB2_query_info_init(tcon, &rqst[1], COMPOUND_FID, COMPOUND_FID, 1585 + FS_FULL_SIZE_INFORMATION, 1586 + SMB2_O_INFO_FILESYSTEM, 0, 1587 + sizeof(struct smb2_fs_full_size_info)); 1588 + if (rc) 1589 + goto qfs_exit; 1590 + smb2_set_next_command(server, &rqst[1]); 1591 + smb2_set_related(&rqst[1]); 1592 + 1593 + memset(&close_iov, 0, sizeof(close_iov)); 1594 + rqst[2].rq_iov = close_iov; 1595 + rqst[2].rq_nvec = 1; 1596 + 1597 + rc = SMB2_close_init(tcon, &rqst[2], COMPOUND_FID, COMPOUND_FID); 1598 + if (rc) 1599 + goto qfs_exit; 1600 + smb2_set_related(&rqst[2]); 1601 + 1602 + rc = compound_send_recv(xid, ses, flags, 3, rqst, 1603 + resp_buftype, rsp_iov); 1604 + if (rc) 1605 + goto qfs_exit; 1606 + 1607 + rsp = (struct smb2_query_info_rsp *)rsp_iov[1].iov_base; 1608 + buf->f_type = SMB2_MAGIC_NUMBER; 1609 + info = (struct smb2_fs_full_size_info *)( 1610 + le16_to_cpu(rsp->OutputBufferOffset) + (char *)rsp); 1611 + rc = smb2_validate_iov(le16_to_cpu(rsp->OutputBufferOffset), 1612 + le32_to_cpu(rsp->OutputBufferLength), 1613 + &rsp_iov[1], 1614 + sizeof(struct smb2_fs_full_size_info)); 1615 + if (!rc) 1616 + smb2_copy_fs_info_to_kstatfs(info, buf); 1617 + 1618 + qfs_exit: 1619 + SMB2_open_free(&rqst[0]); 1620 + SMB2_query_info_free(&rqst[1]); 1621 + SMB2_close_free(&rqst[2]); 1622 + free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base); 1623 + free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base); 1624 + free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base); 1625 + return rc; 1626 + } 1627 + 1628 + static int 1629 + smb311_queryfs(const unsigned int xid, struct cifs_tcon *tcon, 1549 1630 struct kstatfs *buf) 1550 1631 { 1551 1632 int rc; ··· 1674 1513 u8 oplock = SMB2_OPLOCK_LEVEL_NONE; 1675 1514 struct cifs_open_parms oparms; 1676 1515 struct cifs_fid fid; 1516 + 1517 + if (!tcon->posix_extensions) 1518 + return smb2_queryfs(xid, tcon, buf); 1677 1519 1678 1520 oparms.tcon = tcon; 1679 1521 oparms.desired_access = FILE_READ_ATTRIBUTES; ··· 1688 1524 rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL, NULL); 1689 1525 if (rc) 1690 1526 return rc; 1527 + 1528 + rc = SMB311_posix_qfs_info(xid, tcon, fid.persistent_fid, 1529 + fid.volatile_fid, buf); 1691 1530 buf->f_type = SMB2_MAGIC_NUMBER; 1692 - rc = SMB2_QFS_info(xid, tcon, fid.persistent_fid, fid.volatile_fid, 1693 - buf); 1694 1531 SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); 1695 1532 return rc; 1696 1533 } ··· 1865 1700 &resp_buftype); 1866 1701 if (!rc || !err_iov.iov_base) { 1867 1702 rc = -ENOENT; 1868 - goto querty_exit; 1703 + goto free_path; 1869 1704 } 1870 1705 1871 1706 err_buf = err_iov.iov_base; ··· 1906 1741 1907 1742 querty_exit: 1908 1743 free_rsp_buf(resp_buftype, err_buf); 1744 + free_path: 1909 1745 kfree(utf16_path); 1910 1746 return rc; 1911 1747 } ··· 2492 2326 sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf)); 2493 2327 } 2494 2328 2495 - /* Assumes: 2496 - * rqst->rq_iov[0] is transform header 2497 - * rqst->rq_iov[1+] data to be encrypted/decrypted 2329 + /* Assumes the first rqst has a transform header as the first iov. 2330 + * I.e. 2331 + * rqst[0].rq_iov[0] is transform header 2332 + * rqst[0].rq_iov[1+] data to be encrypted/decrypted 2333 + * rqst[1+].rq_iov[0+] data to be encrypted/decrypted 2498 2334 */ 2499 2335 static struct scatterlist * 2500 - init_sg(struct smb_rqst *rqst, u8 *sign) 2336 + init_sg(int num_rqst, struct smb_rqst *rqst, u8 *sign) 2501 2337 { 2502 - unsigned int sg_len = rqst->rq_nvec + rqst->rq_npages + 1; 2503 - unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20; 2338 + unsigned int sg_len; 2504 2339 struct scatterlist *sg; 2505 2340 unsigned int i; 2506 2341 unsigned int j; 2342 + unsigned int idx = 0; 2343 + int skip; 2344 + 2345 + sg_len = 1; 2346 + for (i = 0; i < num_rqst; i++) 2347 + sg_len += rqst[i].rq_nvec + rqst[i].rq_npages; 2507 2348 2508 2349 sg = kmalloc_array(sg_len, sizeof(struct scatterlist), GFP_KERNEL); 2509 2350 if (!sg) 2510 2351 return NULL; 2511 2352 2512 2353 sg_init_table(sg, sg_len); 2513 - smb2_sg_set_buf(&sg[0], rqst->rq_iov[0].iov_base + 20, assoc_data_len); 2514 - for (i = 1; i < rqst->rq_nvec; i++) 2515 - smb2_sg_set_buf(&sg[i], rqst->rq_iov[i].iov_base, 2516 - rqst->rq_iov[i].iov_len); 2517 - for (j = 0; i < sg_len - 1; i++, j++) { 2518 - unsigned int len, offset; 2354 + for (i = 0; i < num_rqst; i++) { 2355 + for (j = 0; j < rqst[i].rq_nvec; j++) { 2356 + /* 2357 + * The first rqst has a transform header where the 2358 + * first 20 bytes are not part of the encrypted blob 2359 + */ 2360 + skip = (i == 0) && (j == 0) ? 20 : 0; 2361 + smb2_sg_set_buf(&sg[idx++], 2362 + rqst[i].rq_iov[j].iov_base + skip, 2363 + rqst[i].rq_iov[j].iov_len - skip); 2364 + } 2519 2365 2520 - rqst_page_get_length(rqst, j, &len, &offset); 2521 - sg_set_page(&sg[i], rqst->rq_pages[j], len, offset); 2366 + for (j = 0; j < rqst[i].rq_npages; j++) { 2367 + unsigned int len, offset; 2368 + 2369 + rqst_page_get_length(&rqst[i], j, &len, &offset); 2370 + sg_set_page(&sg[idx++], rqst[i].rq_pages[j], len, offset); 2371 + } 2522 2372 } 2523 - smb2_sg_set_buf(&sg[sg_len - 1], sign, SMB2_SIGNATURE_SIZE); 2373 + smb2_sg_set_buf(&sg[idx], sign, SMB2_SIGNATURE_SIZE); 2524 2374 return sg; 2525 2375 } 2526 2376 ··· 2568 2386 * untouched. 2569 2387 */ 2570 2388 static int 2571 - crypt_message(struct TCP_Server_Info *server, struct smb_rqst *rqst, int enc) 2389 + crypt_message(struct TCP_Server_Info *server, int num_rqst, 2390 + struct smb_rqst *rqst, int enc) 2572 2391 { 2573 2392 struct smb2_transform_hdr *tr_hdr = 2574 - (struct smb2_transform_hdr *)rqst->rq_iov[0].iov_base; 2393 + (struct smb2_transform_hdr *)rqst[0].rq_iov[0].iov_base; 2575 2394 unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20; 2576 2395 int rc = 0; 2577 2396 struct scatterlist *sg; ··· 2623 2440 crypt_len += SMB2_SIGNATURE_SIZE; 2624 2441 } 2625 2442 2626 - sg = init_sg(rqst, sign); 2443 + sg = init_sg(num_rqst, rqst, sign); 2627 2444 if (!sg) { 2628 2445 cifs_dbg(VFS, "%s: Failed to init sg", __func__); 2629 2446 rc = -ENOMEM; ··· 2660 2477 return rc; 2661 2478 } 2662 2479 2663 - static int 2664 - smb3_init_transform_rq(struct TCP_Server_Info *server, struct smb_rqst *new_rq, 2665 - struct smb_rqst *old_rq) 2480 + void 2481 + smb3_free_compound_rqst(int num_rqst, struct smb_rqst *rqst) 2666 2482 { 2667 - struct kvec *iov; 2668 - struct page **pages; 2669 - struct smb2_transform_hdr *tr_hdr; 2670 - unsigned int npages = old_rq->rq_npages; 2671 - unsigned int orig_len; 2672 - int i; 2673 - int rc = -ENOMEM; 2483 + int i, j; 2674 2484 2675 - pages = kmalloc_array(npages, sizeof(struct page *), GFP_KERNEL); 2676 - if (!pages) 2677 - return rc; 2678 - 2679 - new_rq->rq_pages = pages; 2680 - new_rq->rq_offset = old_rq->rq_offset; 2681 - new_rq->rq_npages = old_rq->rq_npages; 2682 - new_rq->rq_pagesz = old_rq->rq_pagesz; 2683 - new_rq->rq_tailsz = old_rq->rq_tailsz; 2684 - 2685 - for (i = 0; i < npages; i++) { 2686 - pages[i] = alloc_page(GFP_KERNEL|__GFP_HIGHMEM); 2687 - if (!pages[i]) 2688 - goto err_free_pages; 2485 + for (i = 0; i < num_rqst; i++) { 2486 + if (rqst[i].rq_pages) { 2487 + for (j = rqst[i].rq_npages - 1; j >= 0; j--) 2488 + put_page(rqst[i].rq_pages[j]); 2489 + kfree(rqst[i].rq_pages); 2490 + } 2689 2491 } 2690 - 2691 - iov = kmalloc_array(old_rq->rq_nvec + 1, sizeof(struct kvec), 2692 - GFP_KERNEL); 2693 - if (!iov) 2694 - goto err_free_pages; 2695 - 2696 - /* copy all iovs from the old */ 2697 - memcpy(&iov[1], &old_rq->rq_iov[0], 2698 - sizeof(struct kvec) * old_rq->rq_nvec); 2699 - 2700 - new_rq->rq_iov = iov; 2701 - new_rq->rq_nvec = old_rq->rq_nvec + 1; 2702 - 2703 - tr_hdr = kmalloc(sizeof(struct smb2_transform_hdr), GFP_KERNEL); 2704 - if (!tr_hdr) 2705 - goto err_free_iov; 2706 - 2707 - orig_len = smb_rqst_len(server, old_rq); 2708 - 2709 - /* fill the 2nd iov with a transform header */ 2710 - fill_transform_hdr(tr_hdr, orig_len, old_rq); 2711 - new_rq->rq_iov[0].iov_base = tr_hdr; 2712 - new_rq->rq_iov[0].iov_len = sizeof(struct smb2_transform_hdr); 2713 - 2714 - /* copy pages form the old */ 2715 - for (i = 0; i < npages; i++) { 2716 - char *dst, *src; 2717 - unsigned int offset, len; 2718 - 2719 - rqst_page_get_length(new_rq, i, &len, &offset); 2720 - 2721 - dst = (char *) kmap(new_rq->rq_pages[i]) + offset; 2722 - src = (char *) kmap(old_rq->rq_pages[i]) + offset; 2723 - 2724 - memcpy(dst, src, len); 2725 - kunmap(new_rq->rq_pages[i]); 2726 - kunmap(old_rq->rq_pages[i]); 2727 - } 2728 - 2729 - rc = crypt_message(server, new_rq, 1); 2730 - cifs_dbg(FYI, "encrypt message returned %d", rc); 2731 - if (rc) 2732 - goto err_free_tr_hdr; 2733 - 2734 - return rc; 2735 - 2736 - err_free_tr_hdr: 2737 - kfree(tr_hdr); 2738 - err_free_iov: 2739 - kfree(iov); 2740 - err_free_pages: 2741 - for (i = i - 1; i >= 0; i--) 2742 - put_page(pages[i]); 2743 - kfree(pages); 2744 - return rc; 2745 2492 } 2746 2493 2747 - static void 2748 - smb3_free_transform_rq(struct smb_rqst *rqst) 2494 + /* 2495 + * This function will initialize new_rq and encrypt the content. 2496 + * The first entry, new_rq[0], only contains a single iov which contains 2497 + * a smb2_transform_hdr and is pre-allocated by the caller. 2498 + * This function then populates new_rq[1+] with the content from olq_rq[0+]. 2499 + * 2500 + * The end result is an array of smb_rqst structures where the first structure 2501 + * only contains a single iov for the transform header which we then can pass 2502 + * to crypt_message(). 2503 + * 2504 + * new_rq[0].rq_iov[0] : smb2_transform_hdr pre-allocated by the caller 2505 + * new_rq[1+].rq_iov[*] == old_rq[0+].rq_iov[*] : SMB2/3 requests 2506 + */ 2507 + static int 2508 + smb3_init_transform_rq(struct TCP_Server_Info *server, int num_rqst, 2509 + struct smb_rqst *new_rq, struct smb_rqst *old_rq) 2749 2510 { 2750 - int i = rqst->rq_npages - 1; 2511 + struct page **pages; 2512 + struct smb2_transform_hdr *tr_hdr = new_rq[0].rq_iov[0].iov_base; 2513 + unsigned int npages; 2514 + unsigned int orig_len = 0; 2515 + int i, j; 2516 + int rc = -ENOMEM; 2751 2517 2752 - for (; i >= 0; i--) 2753 - put_page(rqst->rq_pages[i]); 2754 - kfree(rqst->rq_pages); 2755 - /* free transform header */ 2756 - kfree(rqst->rq_iov[0].iov_base); 2757 - kfree(rqst->rq_iov); 2518 + for (i = 1; i < num_rqst; i++) { 2519 + npages = old_rq[i - 1].rq_npages; 2520 + pages = kmalloc_array(npages, sizeof(struct page *), 2521 + GFP_KERNEL); 2522 + if (!pages) 2523 + goto err_free; 2524 + 2525 + new_rq[i].rq_pages = pages; 2526 + new_rq[i].rq_npages = npages; 2527 + new_rq[i].rq_offset = old_rq[i - 1].rq_offset; 2528 + new_rq[i].rq_pagesz = old_rq[i - 1].rq_pagesz; 2529 + new_rq[i].rq_tailsz = old_rq[i - 1].rq_tailsz; 2530 + new_rq[i].rq_iov = old_rq[i - 1].rq_iov; 2531 + new_rq[i].rq_nvec = old_rq[i - 1].rq_nvec; 2532 + 2533 + orig_len += smb_rqst_len(server, &old_rq[i - 1]); 2534 + 2535 + for (j = 0; j < npages; j++) { 2536 + pages[j] = alloc_page(GFP_KERNEL|__GFP_HIGHMEM); 2537 + if (!pages[j]) 2538 + goto err_free; 2539 + } 2540 + 2541 + /* copy pages form the old */ 2542 + for (j = 0; j < npages; j++) { 2543 + char *dst, *src; 2544 + unsigned int offset, len; 2545 + 2546 + rqst_page_get_length(&new_rq[i], j, &len, &offset); 2547 + 2548 + dst = (char *) kmap(new_rq[i].rq_pages[j]) + offset; 2549 + src = (char *) kmap(old_rq[i - 1].rq_pages[j]) + offset; 2550 + 2551 + memcpy(dst, src, len); 2552 + kunmap(new_rq[i].rq_pages[j]); 2553 + kunmap(old_rq[i - 1].rq_pages[j]); 2554 + } 2555 + } 2556 + 2557 + /* fill the 1st iov with a transform header */ 2558 + fill_transform_hdr(tr_hdr, orig_len, old_rq); 2559 + 2560 + rc = crypt_message(server, num_rqst, new_rq, 1); 2561 + cifs_dbg(FYI, "encrypt message returned %d", rc); 2562 + if (rc) 2563 + goto err_free; 2564 + 2565 + return rc; 2566 + 2567 + err_free: 2568 + smb3_free_compound_rqst(num_rqst - 1, &new_rq[1]); 2569 + return rc; 2758 2570 } 2759 2571 2760 2572 static int ··· 2781 2603 rqst.rq_pagesz = PAGE_SIZE; 2782 2604 rqst.rq_tailsz = (page_data_size % PAGE_SIZE) ? : PAGE_SIZE; 2783 2605 2784 - rc = crypt_message(server, &rqst, 0); 2606 + rc = crypt_message(server, 1, &rqst, 0); 2785 2607 cifs_dbg(FYI, "decrypt message returned %d\n", rc); 2786 2608 2787 2609 if (rc) ··· 3056 2878 3057 2879 static int 3058 2880 receive_encrypted_standard(struct TCP_Server_Info *server, 3059 - struct mid_q_entry **mid) 2881 + struct mid_q_entry **mids, char **bufs, 2882 + int *num_mids) 3060 2883 { 3061 - int length; 2884 + int ret, length; 3062 2885 char *buf = server->smallbuf; 2886 + char *tmpbuf; 2887 + struct smb2_sync_hdr *shdr; 3063 2888 unsigned int pdu_length = server->pdu_size; 3064 2889 unsigned int buf_size; 3065 2890 struct mid_q_entry *mid_entry; 2891 + int next_is_large; 2892 + char *next_buffer = NULL; 2893 + 2894 + *num_mids = 0; 3066 2895 3067 2896 /* switch to large buffer if too big for a small one */ 3068 2897 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE) { ··· 3090 2905 if (length) 3091 2906 return length; 3092 2907 2908 + next_is_large = server->large_buf; 2909 + one_more: 2910 + shdr = (struct smb2_sync_hdr *)buf; 2911 + if (shdr->NextCommand) { 2912 + if (next_is_large) { 2913 + tmpbuf = server->bigbuf; 2914 + next_buffer = (char *)cifs_buf_get(); 2915 + } else { 2916 + tmpbuf = server->smallbuf; 2917 + next_buffer = (char *)cifs_small_buf_get(); 2918 + } 2919 + memcpy(next_buffer, 2920 + tmpbuf + le32_to_cpu(shdr->NextCommand), 2921 + pdu_length - le32_to_cpu(shdr->NextCommand)); 2922 + } 2923 + 3093 2924 mid_entry = smb2_find_mid(server, buf); 3094 2925 if (mid_entry == NULL) 3095 2926 cifs_dbg(FYI, "mid not found\n"); 3096 2927 else { 3097 2928 cifs_dbg(FYI, "mid found\n"); 3098 2929 mid_entry->decrypted = true; 2930 + mid_entry->resp_buf_size = server->pdu_size; 3099 2931 } 3100 2932 3101 - *mid = mid_entry; 2933 + if (*num_mids >= MAX_COMPOUND) { 2934 + cifs_dbg(VFS, "too many PDUs in compound\n"); 2935 + return -1; 2936 + } 2937 + bufs[*num_mids] = buf; 2938 + mids[(*num_mids)++] = mid_entry; 3102 2939 3103 2940 if (mid_entry && mid_entry->handle) 3104 - return mid_entry->handle(server, mid_entry); 2941 + ret = mid_entry->handle(server, mid_entry); 2942 + else 2943 + ret = cifs_handle_standard(server, mid_entry); 3105 2944 3106 - return cifs_handle_standard(server, mid_entry); 2945 + if (ret == 0 && shdr->NextCommand) { 2946 + pdu_length -= le32_to_cpu(shdr->NextCommand); 2947 + server->large_buf = next_is_large; 2948 + if (next_is_large) 2949 + server->bigbuf = next_buffer; 2950 + else 2951 + server->smallbuf = next_buffer; 2952 + 2953 + buf += le32_to_cpu(shdr->NextCommand); 2954 + goto one_more; 2955 + } 2956 + 2957 + return ret; 3107 2958 } 3108 2959 3109 2960 static int 3110 - smb3_receive_transform(struct TCP_Server_Info *server, struct mid_q_entry **mid) 2961 + smb3_receive_transform(struct TCP_Server_Info *server, 2962 + struct mid_q_entry **mids, char **bufs, int *num_mids) 3111 2963 { 3112 2964 char *buf = server->smallbuf; 3113 2965 unsigned int pdu_length = server->pdu_size; ··· 3167 2945 return -ECONNABORTED; 3168 2946 } 3169 2947 2948 + /* TODO: add support for compounds containing READ. */ 3170 2949 if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE(server)) 3171 - return receive_encrypted_read(server, mid); 2950 + return receive_encrypted_read(server, &mids[0]); 3172 2951 3173 - return receive_encrypted_standard(server, mid); 2952 + return receive_encrypted_standard(server, mids, bufs, num_mids); 3174 2953 } 3175 2954 3176 2955 int ··· 3473 3250 .fallocate = smb3_fallocate, 3474 3251 .enum_snapshots = smb3_enum_snapshots, 3475 3252 .init_transform_rq = smb3_init_transform_rq, 3476 - .free_transform_rq = smb3_free_transform_rq, 3477 3253 .is_transform_hdr = smb3_is_transform_hdr, 3478 3254 .receive_transform = smb3_receive_transform, 3479 3255 .get_dfs_refer = smb2_get_dfs_refer, ··· 3489 3267 .next_header = smb2_next_header, 3490 3268 }; 3491 3269 3492 - #ifdef CONFIG_CIFS_SMB311 3493 3270 struct smb_version_operations smb311_operations = { 3494 3271 .compare_fids = smb2_compare_fids, 3495 3272 .setup_request = smb2_setup_request, ··· 3556 3335 .is_status_pending = smb2_is_status_pending, 3557 3336 .is_session_expired = smb2_is_session_expired, 3558 3337 .oplock_response = smb2_oplock_response, 3559 - .queryfs = smb2_queryfs, 3338 + .queryfs = smb311_queryfs, 3560 3339 .mand_lock = smb2_mand_lock, 3561 3340 .mand_unlock_range = smb2_unlock_range, 3562 3341 .push_mand_locks = smb2_push_mandatory_locks, ··· 3578 3357 .fallocate = smb3_fallocate, 3579 3358 .enum_snapshots = smb3_enum_snapshots, 3580 3359 .init_transform_rq = smb3_init_transform_rq, 3581 - .free_transform_rq = smb3_free_transform_rq, 3582 3360 .is_transform_hdr = smb3_is_transform_hdr, 3583 3361 .receive_transform = smb3_receive_transform, 3584 3362 .get_dfs_refer = smb2_get_dfs_refer, ··· 3586 3366 .query_all_EAs = smb2_query_eas, 3587 3367 .set_EA = smb2_set_ea, 3588 3368 #endif /* CIFS_XATTR */ 3369 + #ifdef CONFIG_CIFS_ACL 3370 + .get_acl = get_smb2_acl, 3371 + .get_acl_by_fid = get_smb2_acl_by_fid, 3372 + .set_acl = set_smb2_acl, 3373 + #endif /* CIFS_ACL */ 3589 3374 .next_header = smb2_next_header, 3590 3375 }; 3591 - #endif /* CIFS_SMB311 */ 3592 3376 3593 3377 struct smb_version_values smb20_values = { 3594 3378 .version_string = SMB20_VERSION_STRING, ··· 3720 3496 .create_lease_size = sizeof(struct create_lease_v2), 3721 3497 }; 3722 3498 3723 - #ifdef CONFIG_CIFS_SMB311 3724 3499 struct smb_version_values smb311_values = { 3725 3500 .version_string = SMB311_VERSION_STRING, 3726 3501 .protocol_id = SMB311_PROT_ID, ··· 3740 3517 .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED, 3741 3518 .create_lease_size = sizeof(struct create_lease_v2), 3742 3519 }; 3743 - #endif /* SMB311 */
+359 -200
fs/cifs/smb2pdu.c
··· 80 80 /* SMB2_OPLOCK_BREAK */ 24 /* BB this is 36 for LEASE_BREAK variant */ 81 81 }; 82 82 83 - static int smb3_encryption_required(const struct cifs_tcon *tcon) 83 + int smb3_encryption_required(const struct cifs_tcon *tcon) 84 84 { 85 85 if (!tcon) 86 86 return 0; ··· 360 360 total_len); 361 361 362 362 if (tcon != NULL) { 363 - #ifdef CONFIG_CIFS_STATS2 364 363 uint16_t com_code = le16_to_cpu(smb2_command); 365 364 cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_sent[com_code]); 366 - #endif 367 365 cifs_stats_inc(&tcon->num_smbs_sent); 368 366 } 369 367 370 368 return rc; 371 369 } 372 370 373 - #ifdef CONFIG_CIFS_SMB311 371 + 374 372 /* offset is sizeof smb2_negotiate_req but rounded up to 8 bytes */ 375 373 #define OFFSET_OF_NEG_CONTEXT 0x68 /* sizeof(struct smb2_negotiate_req) */ 376 374 ··· 583 585 return 0; 584 586 } 585 587 586 - #else 587 - static void assemble_neg_contexts(struct smb2_negotiate_req *req, 588 - unsigned int *total_len) 589 - { 590 - return; 591 - } 592 - #endif /* SMB311 */ 593 588 594 589 /* 595 590 * ··· 627 636 return rc; 628 637 629 638 req->sync_hdr.SessionId = 0; 630 - #ifdef CONFIG_CIFS_SMB311 639 + 631 640 memset(server->preauth_sha_hash, 0, SMB2_PREAUTH_HASH_SIZE); 632 641 memset(ses->preauth_sha_hash, 0, SMB2_PREAUTH_HASH_SIZE); 633 - #endif 634 642 635 643 if (strcmp(ses->server->vals->version_string, 636 644 SMB3ANY_VERSION_STRING) == 0) { ··· 731 741 cifs_dbg(FYI, "negotiated smb3.0 dialect\n"); 732 742 else if (rsp->DialectRevision == cpu_to_le16(SMB302_PROT_ID)) 733 743 cifs_dbg(FYI, "negotiated smb3.02 dialect\n"); 734 - #ifdef CONFIG_CIFS_SMB311 735 744 else if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID)) 736 745 cifs_dbg(FYI, "negotiated smb3.1.1 dialect\n"); 737 - #endif /* SMB311 */ 738 746 else { 739 747 cifs_dbg(VFS, "Illegal dialect returned by server 0x%x\n", 740 748 le16_to_cpu(rsp->DialectRevision)); ··· 741 753 } 742 754 server->dialect = le16_to_cpu(rsp->DialectRevision); 743 755 744 - /* BB: add check that dialect was valid given dialect(s) we asked for */ 745 - 746 - #ifdef CONFIG_CIFS_SMB311 747 756 /* 748 757 * Keep a copy of the hash after negprot. This hash will be 749 758 * the starting hash value for all sessions made from this ··· 748 763 */ 749 764 memcpy(server->preauth_sha_hash, ses->preauth_sha_hash, 750 765 SMB2_PREAUTH_HASH_SIZE); 751 - #endif 766 + 752 767 /* SMB2 only has an extended negflavor */ 753 768 server->negflavor = CIFS_NEGFLAVOR_EXTENDED; 754 769 /* set it to the maximum buffer size value we can send with 1 credit */ ··· 789 804 rc = -EIO; 790 805 } 791 806 792 - #ifdef CONFIG_CIFS_SMB311 793 807 if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID)) { 794 808 if (rsp->NegotiateContextCount) 795 809 rc = smb311_decode_neg_context(rsp, server, ··· 796 812 else 797 813 cifs_dbg(VFS, "Missing expected negotiate contexts\n"); 798 814 } 799 - #endif /* CONFIG_CIFS_SMB311 */ 800 815 neg_exit: 801 816 free_rsp_buf(resp_buftype, rsp); 802 817 return rc; ··· 1356 1373 sess_data->nls_cp = (struct nls_table *) nls_cp; 1357 1374 sess_data->previous_session = ses->Suid; 1358 1375 1359 - #ifdef CONFIG_CIFS_SMB311 1360 1376 /* 1361 1377 * Initialize the session hash with the server one. 1362 1378 */ 1363 1379 memcpy(ses->preauth_sha_hash, ses->server->preauth_sha_hash, 1364 1380 SMB2_PREAUTH_HASH_SIZE); 1365 - #endif 1366 1381 1367 1382 while (sess_data->func) 1368 1383 sess_data->func(sess_data); ··· 1856 1875 return 0; 1857 1876 } 1858 1877 1878 + /* See MS-SMB2 2.2.13.2.7 */ 1879 + static struct crt_twarp_ctxt * 1880 + create_twarp_buf(__u64 timewarp) 1881 + { 1882 + struct crt_twarp_ctxt *buf; 1883 + 1884 + buf = kzalloc(sizeof(struct crt_twarp_ctxt), GFP_KERNEL); 1885 + if (!buf) 1886 + return NULL; 1887 + 1888 + buf->ccontext.DataOffset = cpu_to_le16(offsetof 1889 + (struct crt_twarp_ctxt, Timestamp)); 1890 + buf->ccontext.DataLength = cpu_to_le32(8); 1891 + buf->ccontext.NameOffset = cpu_to_le16(offsetof 1892 + (struct crt_twarp_ctxt, Name)); 1893 + buf->ccontext.NameLength = cpu_to_le16(4); 1894 + /* SMB2_CREATE_TIMEWARP_TOKEN is "TWrp" */ 1895 + buf->Name[0] = 'T'; 1896 + buf->Name[1] = 'W'; 1897 + buf->Name[2] = 'r'; 1898 + buf->Name[3] = 'p'; 1899 + buf->Timestamp = cpu_to_le64(timewarp); 1900 + return buf; 1901 + } 1902 + 1903 + /* See MS-SMB2 2.2.13.2.7 */ 1904 + static int 1905 + add_twarp_context(struct kvec *iov, unsigned int *num_iovec, __u64 timewarp) 1906 + { 1907 + struct smb2_create_req *req = iov[0].iov_base; 1908 + unsigned int num = *num_iovec; 1909 + 1910 + iov[num].iov_base = create_twarp_buf(timewarp); 1911 + if (iov[num].iov_base == NULL) 1912 + return -ENOMEM; 1913 + iov[num].iov_len = sizeof(struct crt_twarp_ctxt); 1914 + if (!req->CreateContextsOffset) 1915 + req->CreateContextsOffset = cpu_to_le32( 1916 + sizeof(struct smb2_create_req) + 1917 + iov[num - 1].iov_len); 1918 + le32_add_cpu(&req->CreateContextsLength, sizeof(struct crt_twarp_ctxt)); 1919 + *num_iovec = num + 1; 1920 + return 0; 1921 + } 1922 + 1859 1923 static int 1860 1924 alloc_path_with_tree_prefix(__le16 **out_path, int *out_size, int *out_len, 1861 1925 const char *treename, const __le16 *path) ··· 1946 1920 return 0; 1947 1921 } 1948 1922 1949 - #ifdef CONFIG_CIFS_SMB311 1950 1923 int smb311_posix_mkdir(const unsigned int xid, struct inode *inode, 1951 1924 umode_t mode, struct cifs_tcon *tcon, 1952 1925 const char *full_path, ··· 1953 1928 { 1954 1929 struct smb_rqst rqst; 1955 1930 struct smb2_create_req *req; 1956 - struct smb2_create_rsp *rsp; 1931 + struct smb2_create_rsp *rsp = NULL; 1957 1932 struct TCP_Server_Info *server; 1958 1933 struct cifs_ses *ses = tcon->ses; 1959 1934 struct kvec iov[3]; /* make sure at least one for each open context */ ··· 1968 1943 char *pc_buf = NULL; 1969 1944 int flags = 0; 1970 1945 unsigned int total_len; 1971 - __le16 *path = cifs_convert_path_to_utf16(full_path, cifs_sb); 1972 - 1973 - if (!path) 1974 - return -ENOMEM; 1946 + __le16 *utf16_path = NULL; 1975 1947 1976 1948 cifs_dbg(FYI, "mkdir\n"); 1977 1949 1950 + /* resource #1: path allocation */ 1951 + utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb); 1952 + if (!utf16_path) 1953 + return -ENOMEM; 1954 + 1978 1955 if (ses && (ses->server)) 1979 1956 server = ses->server; 1980 - else 1981 - return -EIO; 1957 + else { 1958 + rc = -EIO; 1959 + goto err_free_path; 1960 + } 1982 1961 1962 + /* resource #2: request */ 1983 1963 rc = smb2_plain_req_init(SMB2_CREATE, tcon, (void **) &req, &total_len); 1984 - 1985 1964 if (rc) 1986 - return rc; 1965 + goto err_free_path; 1966 + 1987 1967 1988 1968 if (smb3_encryption_required(tcon)) 1989 1969 flags |= CIFS_TRANSFORM_REQ; 1990 - 1991 1970 1992 1971 req->ImpersonationLevel = IL_IMPERSONATION; 1993 1972 req->DesiredAccess = cpu_to_le32(FILE_WRITE_ATTRIBUTES); ··· 2021 1992 req->sync_hdr.Flags |= SMB2_FLAGS_DFS_OPERATIONS; 2022 1993 rc = alloc_path_with_tree_prefix(&copy_path, &copy_size, 2023 1994 &name_len, 2024 - tcon->treeName, path); 2025 - if (rc) { 2026 - cifs_small_buf_release(req); 2027 - return rc; 2028 - } 1995 + tcon->treeName, utf16_path); 1996 + if (rc) 1997 + goto err_free_req; 1998 + 2029 1999 req->NameLength = cpu_to_le16(name_len * 2); 2030 2000 uni_path_len = copy_size; 2031 - path = copy_path; 2001 + /* free before overwriting resource */ 2002 + kfree(utf16_path); 2003 + utf16_path = copy_path; 2032 2004 } else { 2033 - uni_path_len = (2 * UniStrnlen((wchar_t *)path, PATH_MAX)) + 2; 2005 + uni_path_len = (2 * UniStrnlen((wchar_t *)utf16_path, PATH_MAX)) + 2; 2034 2006 /* MUST set path len (NameLength) to 0 opening root of share */ 2035 2007 req->NameLength = cpu_to_le16(uni_path_len - 2); 2036 2008 if (uni_path_len % 8 != 0) { 2037 2009 copy_size = roundup(uni_path_len, 8); 2038 2010 copy_path = kzalloc(copy_size, GFP_KERNEL); 2039 2011 if (!copy_path) { 2040 - cifs_small_buf_release(req); 2041 - return -ENOMEM; 2012 + rc = -ENOMEM; 2013 + goto err_free_req; 2042 2014 } 2043 - memcpy((char *)copy_path, (const char *)path, 2015 + memcpy((char *)copy_path, (const char *)utf16_path, 2044 2016 uni_path_len); 2045 2017 uni_path_len = copy_size; 2046 - path = copy_path; 2018 + /* free before overwriting resource */ 2019 + kfree(utf16_path); 2020 + utf16_path = copy_path; 2047 2021 } 2048 2022 } 2049 2023 2050 2024 iov[1].iov_len = uni_path_len; 2051 - iov[1].iov_base = path; 2025 + iov[1].iov_base = utf16_path; 2052 2026 req->RequestedOplockLevel = SMB2_OPLOCK_LEVEL_NONE; 2053 2027 2054 2028 if (tcon->posix_extensions) { 2055 - if (n_iov > 2) { 2056 - struct create_context *ccontext = 2057 - (struct create_context *)iov[n_iov-1].iov_base; 2058 - ccontext->Next = 2059 - cpu_to_le32(iov[n_iov-1].iov_len); 2060 - } 2061 - 2029 + /* resource #3: posix buf */ 2062 2030 rc = add_posix_context(iov, &n_iov, mode); 2063 - if (rc) { 2064 - cifs_small_buf_release(req); 2065 - kfree(copy_path); 2066 - return rc; 2067 - } 2031 + if (rc) 2032 + goto err_free_req; 2068 2033 pc_buf = iov[n_iov-1].iov_base; 2069 2034 } 2070 2035 ··· 2067 2044 rqst.rq_iov = iov; 2068 2045 rqst.rq_nvec = n_iov; 2069 2046 2070 - rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, 2071 - &rsp_iov); 2072 - 2073 - cifs_small_buf_release(req); 2074 - rsp = (struct smb2_create_rsp *)rsp_iov.iov_base; 2075 - 2076 - if (rc != 0) { 2047 + /* resource #4: response buffer */ 2048 + rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov); 2049 + if (rc) { 2077 2050 cifs_stats_fail_inc(tcon, SMB2_CREATE_HE); 2078 2051 trace_smb3_posix_mkdir_err(xid, tcon->tid, ses->Suid, 2079 - CREATE_NOT_FILE, FILE_WRITE_ATTRIBUTES, rc); 2080 - goto smb311_mkdir_exit; 2081 - } else 2082 - trace_smb3_posix_mkdir_done(xid, rsp->PersistentFileId, tcon->tid, 2083 - ses->Suid, CREATE_NOT_FILE, 2084 - FILE_WRITE_ATTRIBUTES); 2052 + CREATE_NOT_FILE, 2053 + FILE_WRITE_ATTRIBUTES, rc); 2054 + goto err_free_rsp_buf; 2055 + } 2056 + 2057 + rsp = (struct smb2_create_rsp *)rsp_iov.iov_base; 2058 + trace_smb3_posix_mkdir_done(xid, rsp->PersistentFileId, tcon->tid, 2059 + ses->Suid, CREATE_NOT_FILE, 2060 + FILE_WRITE_ATTRIBUTES); 2085 2061 2086 2062 SMB2_close(xid, tcon, rsp->PersistentFileId, rsp->VolatileFileId); 2087 2063 2088 2064 /* Eventually save off posix specific response info and timestaps */ 2089 2065 2090 - smb311_mkdir_exit: 2091 - kfree(copy_path); 2092 - kfree(pc_buf); 2066 + err_free_rsp_buf: 2093 2067 free_rsp_buf(resp_buftype, rsp); 2068 + kfree(pc_buf); 2069 + err_free_req: 2070 + cifs_small_buf_release(req); 2071 + err_free_path: 2072 + kfree(utf16_path); 2094 2073 return rc; 2095 - 2096 2074 } 2097 - #endif /* SMB311 */ 2098 2075 2099 2076 int 2100 - SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, 2101 - __u8 *oplock, struct smb2_file_all_info *buf, 2102 - struct kvec *err_iov, int *buftype) 2077 + SMB2_open_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, __u8 *oplock, 2078 + struct cifs_open_parms *oparms, __le16 *path) 2103 2079 { 2104 - struct smb_rqst rqst; 2080 + struct TCP_Server_Info *server = tcon->ses->server; 2105 2081 struct smb2_create_req *req; 2106 - struct smb2_create_rsp *rsp; 2107 - struct TCP_Server_Info *server; 2108 - struct cifs_tcon *tcon = oparms->tcon; 2109 - struct cifs_ses *ses = tcon->ses; 2110 - struct kvec iov[5]; /* make sure at least one for each open context */ 2111 - struct kvec rsp_iov = {NULL, 0}; 2112 - int resp_buftype; 2113 - int uni_path_len; 2114 - __le16 *copy_path = NULL; 2115 - int copy_size; 2116 - int rc = 0; 2117 2082 unsigned int n_iov = 2; 2118 2083 __u32 file_attributes = 0; 2119 - char *dhc_buf = NULL, *lc_buf = NULL, *pc_buf = NULL; 2120 - int flags = 0; 2084 + int copy_size; 2085 + int uni_path_len; 2121 2086 unsigned int total_len; 2122 - 2123 - cifs_dbg(FYI, "create/open\n"); 2124 - 2125 - if (ses && (ses->server)) 2126 - server = ses->server; 2127 - else 2128 - return -EIO; 2087 + struct kvec *iov = rqst->rq_iov; 2088 + __le16 *copy_path; 2089 + int rc; 2129 2090 2130 2091 rc = smb2_plain_req_init(SMB2_CREATE, tcon, (void **) &req, &total_len); 2131 - 2132 2092 if (rc) 2133 2093 return rc; 2134 2094 2135 - if (smb3_encryption_required(tcon)) 2136 - flags |= CIFS_TRANSFORM_REQ; 2095 + iov[0].iov_base = (char *)req; 2096 + /* -1 since last byte is buf[0] which is sent below (path) */ 2097 + iov[0].iov_len = total_len - 1; 2137 2098 2138 2099 if (oparms->create_options & CREATE_OPTION_READONLY) 2139 2100 file_attributes |= ATTR_READONLY; ··· 2131 2124 req->ShareAccess = FILE_SHARE_ALL_LE; 2132 2125 req->CreateDisposition = cpu_to_le32(oparms->disposition); 2133 2126 req->CreateOptions = cpu_to_le32(oparms->create_options & CREATE_OPTIONS_MASK); 2134 - 2135 - iov[0].iov_base = (char *)req; 2136 - /* -1 since last byte is buf[0] which is sent below (path) */ 2137 - iov[0].iov_len = total_len - 1; 2138 - 2139 2127 req->NameOffset = cpu_to_le16(sizeof(struct smb2_create_req)); 2140 2128 2141 2129 /* [MS-SMB2] 2.2.13 NameOffset: ··· 2148 2146 rc = alloc_path_with_tree_prefix(&copy_path, &copy_size, 2149 2147 &name_len, 2150 2148 tcon->treeName, path); 2151 - if (rc) { 2152 - cifs_small_buf_release(req); 2149 + if (rc) 2153 2150 return rc; 2154 - } 2155 2151 req->NameLength = cpu_to_le16(name_len * 2); 2156 2152 uni_path_len = copy_size; 2157 2153 path = copy_path; ··· 2157 2157 uni_path_len = (2 * UniStrnlen((wchar_t *)path, PATH_MAX)) + 2; 2158 2158 /* MUST set path len (NameLength) to 0 opening root of share */ 2159 2159 req->NameLength = cpu_to_le16(uni_path_len - 2); 2160 - if (uni_path_len % 8 != 0) { 2161 - copy_size = roundup(uni_path_len, 8); 2162 - copy_path = kzalloc(copy_size, GFP_KERNEL); 2163 - if (!copy_path) { 2164 - cifs_small_buf_release(req); 2165 - return -ENOMEM; 2166 - } 2167 - memcpy((char *)copy_path, (const char *)path, 2168 - uni_path_len); 2169 - uni_path_len = copy_size; 2170 - path = copy_path; 2171 - } 2160 + copy_size = uni_path_len; 2161 + if (copy_size % 8 != 0) 2162 + copy_size = roundup(copy_size, 8); 2163 + copy_path = kzalloc(copy_size, GFP_KERNEL); 2164 + if (!copy_path) 2165 + return -ENOMEM; 2166 + memcpy((char *)copy_path, (const char *)path, 2167 + uni_path_len); 2168 + uni_path_len = copy_size; 2169 + path = copy_path; 2172 2170 } 2173 2171 2174 2172 iov[1].iov_len = uni_path_len; ··· 2181 2183 else { 2182 2184 rc = add_lease_context(server, iov, &n_iov, 2183 2185 oparms->fid->lease_key, oplock); 2184 - if (rc) { 2185 - cifs_small_buf_release(req); 2186 - kfree(copy_path); 2186 + if (rc) 2187 2187 return rc; 2188 - } 2189 - lc_buf = iov[n_iov-1].iov_base; 2190 2188 } 2191 2189 2192 2190 if (*oplock == SMB2_OPLOCK_LEVEL_BATCH) { ··· 2196 2202 2197 2203 rc = add_durable_context(iov, &n_iov, oparms, 2198 2204 tcon->use_persistent); 2199 - if (rc) { 2200 - cifs_small_buf_release(req); 2201 - kfree(copy_path); 2202 - kfree(lc_buf); 2205 + if (rc) 2203 2206 return rc; 2204 - } 2205 - dhc_buf = iov[n_iov-1].iov_base; 2206 2207 } 2207 2208 2208 - #ifdef CONFIG_CIFS_SMB311 2209 2209 if (tcon->posix_extensions) { 2210 2210 if (n_iov > 2) { 2211 2211 struct create_context *ccontext = ··· 2209 2221 } 2210 2222 2211 2223 rc = add_posix_context(iov, &n_iov, oparms->mode); 2212 - if (rc) { 2213 - cifs_small_buf_release(req); 2214 - kfree(copy_path); 2215 - kfree(lc_buf); 2216 - kfree(dhc_buf); 2224 + if (rc) 2217 2225 return rc; 2218 - } 2219 - pc_buf = iov[n_iov-1].iov_base; 2220 2226 } 2221 - #endif /* SMB311 */ 2227 + 2228 + if (tcon->snapshot_time) { 2229 + cifs_dbg(FYI, "adding snapshot context\n"); 2230 + if (n_iov > 2) { 2231 + struct create_context *ccontext = 2232 + (struct create_context *)iov[n_iov-1].iov_base; 2233 + ccontext->Next = 2234 + cpu_to_le32(iov[n_iov-1].iov_len); 2235 + } 2236 + 2237 + rc = add_twarp_context(iov, &n_iov, tcon->snapshot_time); 2238 + if (rc) 2239 + return rc; 2240 + } 2241 + 2242 + 2243 + rqst->rq_nvec = n_iov; 2244 + return 0; 2245 + } 2246 + 2247 + /* rq_iov[0] is the request and is released by cifs_small_buf_release(). 2248 + * All other vectors are freed by kfree(). 2249 + */ 2250 + void 2251 + SMB2_open_free(struct smb_rqst *rqst) 2252 + { 2253 + int i; 2254 + 2255 + cifs_small_buf_release(rqst->rq_iov[0].iov_base); 2256 + for (i = 1; i < rqst->rq_nvec; i++) 2257 + if (rqst->rq_iov[i].iov_base != smb2_padding) 2258 + kfree(rqst->rq_iov[i].iov_base); 2259 + } 2260 + 2261 + int 2262 + SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, 2263 + __u8 *oplock, struct smb2_file_all_info *buf, 2264 + struct kvec *err_iov, int *buftype) 2265 + { 2266 + struct smb_rqst rqst; 2267 + struct smb2_create_rsp *rsp = NULL; 2268 + struct TCP_Server_Info *server; 2269 + struct cifs_tcon *tcon = oparms->tcon; 2270 + struct cifs_ses *ses = tcon->ses; 2271 + struct kvec iov[5]; /* make sure at least one for each open context */ 2272 + struct kvec rsp_iov = {NULL, 0}; 2273 + int resp_buftype; 2274 + int rc = 0; 2275 + int flags = 0; 2276 + 2277 + cifs_dbg(FYI, "create/open\n"); 2278 + if (ses && (ses->server)) 2279 + server = ses->server; 2280 + else 2281 + return -EIO; 2282 + 2283 + if (smb3_encryption_required(tcon)) 2284 + flags |= CIFS_TRANSFORM_REQ; 2222 2285 2223 2286 memset(&rqst, 0, sizeof(struct smb_rqst)); 2287 + memset(&iov, 0, sizeof(iov)); 2224 2288 rqst.rq_iov = iov; 2225 - rqst.rq_nvec = n_iov; 2289 + rqst.rq_nvec = 5; 2290 + 2291 + rc = SMB2_open_init(tcon, &rqst, oplock, oparms, path); 2292 + if (rc) 2293 + goto creat_exit; 2226 2294 2227 2295 rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, 2228 2296 &rsp_iov); 2229 - cifs_small_buf_release(req); 2230 2297 rsp = (struct smb2_create_rsp *)rsp_iov.iov_base; 2231 2298 2232 2299 if (rc != 0) { ··· 2318 2275 else 2319 2276 *oplock = rsp->OplockLevel; 2320 2277 creat_exit: 2321 - kfree(copy_path); 2322 - kfree(lc_buf); 2323 - kfree(dhc_buf); 2324 - kfree(pc_buf); 2278 + SMB2_open_free(&rqst); 2325 2279 free_rsp_buf(resp_buftype, rsp); 2326 2280 return rc; 2327 2281 } ··· 2509 2469 } 2510 2470 2511 2471 int 2472 + SMB2_close_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, 2473 + u64 persistent_fid, u64 volatile_fid) 2474 + { 2475 + struct smb2_close_req *req; 2476 + struct kvec *iov = rqst->rq_iov; 2477 + unsigned int total_len; 2478 + int rc; 2479 + 2480 + rc = smb2_plain_req_init(SMB2_CLOSE, tcon, (void **) &req, &total_len); 2481 + if (rc) 2482 + return rc; 2483 + 2484 + req->PersistentFileId = persistent_fid; 2485 + req->VolatileFileId = volatile_fid; 2486 + iov[0].iov_base = (char *)req; 2487 + iov[0].iov_len = total_len; 2488 + 2489 + return 0; 2490 + } 2491 + 2492 + void 2493 + SMB2_close_free(struct smb_rqst *rqst) 2494 + { 2495 + cifs_small_buf_release(rqst->rq_iov[0].iov_base); /* request */ 2496 + } 2497 + 2498 + int 2512 2499 SMB2_close_flags(const unsigned int xid, struct cifs_tcon *tcon, 2513 2500 u64 persistent_fid, u64 volatile_fid, int flags) 2514 2501 { 2515 2502 struct smb_rqst rqst; 2516 - struct smb2_close_req *req; 2517 - struct smb2_close_rsp *rsp; 2503 + struct smb2_close_rsp *rsp = NULL; 2518 2504 struct cifs_ses *ses = tcon->ses; 2519 2505 struct kvec iov[1]; 2520 2506 struct kvec rsp_iov; 2521 2507 int resp_buftype; 2522 2508 int rc = 0; 2523 - unsigned int total_len; 2524 2509 2525 2510 cifs_dbg(FYI, "Close\n"); 2526 2511 2527 2512 if (!ses || !(ses->server)) 2528 2513 return -EIO; 2529 2514 2530 - rc = smb2_plain_req_init(SMB2_CLOSE, tcon, (void **) &req, &total_len); 2531 - if (rc) 2532 - return rc; 2533 - 2534 2515 if (smb3_encryption_required(tcon)) 2535 2516 flags |= CIFS_TRANSFORM_REQ; 2536 2517 2537 - req->PersistentFileId = persistent_fid; 2538 - req->VolatileFileId = volatile_fid; 2539 - 2540 - iov[0].iov_base = (char *)req; 2541 - iov[0].iov_len = total_len; 2542 - 2543 2518 memset(&rqst, 0, sizeof(struct smb_rqst)); 2519 + memset(&iov, 0, sizeof(iov)); 2544 2520 rqst.rq_iov = iov; 2545 2521 rqst.rq_nvec = 1; 2546 2522 2523 + rc = SMB2_close_init(tcon, &rqst, persistent_fid, volatile_fid); 2524 + if (rc) 2525 + goto close_exit; 2526 + 2547 2527 rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov); 2548 - cifs_small_buf_release(req); 2549 2528 rsp = (struct smb2_close_rsp *)rsp_iov.iov_base; 2550 2529 2551 2530 if (rc != 0) { ··· 2577 2518 /* BB FIXME - decode close response, update inode for caching */ 2578 2519 2579 2520 close_exit: 2521 + SMB2_close_free(&rqst); 2580 2522 free_rsp_buf(resp_buftype, rsp); 2581 2523 return rc; 2582 2524 } ··· 2589 2529 return SMB2_close_flags(xid, tcon, persistent_fid, volatile_fid, 0); 2590 2530 } 2591 2531 2592 - static int 2593 - validate_iov(unsigned int offset, unsigned int buffer_length, 2594 - struct kvec *iov, unsigned int min_buf_size) 2532 + int 2533 + smb2_validate_iov(unsigned int offset, unsigned int buffer_length, 2534 + struct kvec *iov, unsigned int min_buf_size) 2595 2535 { 2596 2536 unsigned int smb_len = iov->iov_len; 2597 2537 char *end_of_smb = smb_len + (char *)iov->iov_base; ··· 2635 2575 if (!data) 2636 2576 return -EINVAL; 2637 2577 2638 - rc = validate_iov(offset, buffer_length, iov, minbufsize); 2578 + rc = smb2_validate_iov(offset, buffer_length, iov, minbufsize); 2639 2579 if (rc) 2640 2580 return rc; 2641 2581 ··· 2644 2584 return 0; 2645 2585 } 2646 2586 2647 - static int 2648 - query_info(const unsigned int xid, struct cifs_tcon *tcon, 2649 - u64 persistent_fid, u64 volatile_fid, u8 info_class, u8 info_type, 2650 - u32 additional_info, size_t output_len, size_t min_len, void **data, 2651 - u32 *dlen) 2587 + int 2588 + SMB2_query_info_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, 2589 + u64 persistent_fid, u64 volatile_fid, 2590 + u8 info_class, u8 info_type, u32 additional_info, 2591 + size_t output_len) 2652 2592 { 2653 - struct smb_rqst rqst; 2654 2593 struct smb2_query_info_req *req; 2655 - struct smb2_query_info_rsp *rsp = NULL; 2656 - struct kvec iov[2]; 2657 - struct kvec rsp_iov; 2658 - int rc = 0; 2659 - int resp_buftype; 2660 - struct cifs_ses *ses = tcon->ses; 2661 - int flags = 0; 2594 + struct kvec *iov = rqst->rq_iov; 2662 2595 unsigned int total_len; 2663 - 2664 - cifs_dbg(FYI, "Query Info\n"); 2665 - 2666 - if (!ses || !(ses->server)) 2667 - return -EIO; 2596 + int rc; 2668 2597 2669 2598 rc = smb2_plain_req_init(SMB2_QUERY_INFO, tcon, (void **) &req, 2670 2599 &total_len); 2671 2600 if (rc) 2672 2601 return rc; 2673 - 2674 - if (smb3_encryption_required(tcon)) 2675 - flags |= CIFS_TRANSFORM_REQ; 2676 2602 2677 2603 req->InfoType = info_type; 2678 2604 req->FileInfoClass = info_class; ··· 2676 2630 iov[0].iov_base = (char *)req; 2677 2631 /* 1 for Buffer */ 2678 2632 iov[0].iov_len = total_len - 1; 2633 + return 0; 2634 + } 2635 + 2636 + void 2637 + SMB2_query_info_free(struct smb_rqst *rqst) 2638 + { 2639 + cifs_small_buf_release(rqst->rq_iov[0].iov_base); /* request */ 2640 + } 2641 + 2642 + static int 2643 + query_info(const unsigned int xid, struct cifs_tcon *tcon, 2644 + u64 persistent_fid, u64 volatile_fid, u8 info_class, u8 info_type, 2645 + u32 additional_info, size_t output_len, size_t min_len, void **data, 2646 + u32 *dlen) 2647 + { 2648 + struct smb_rqst rqst; 2649 + struct smb2_query_info_rsp *rsp = NULL; 2650 + struct kvec iov[1]; 2651 + struct kvec rsp_iov; 2652 + int rc = 0; 2653 + int resp_buftype; 2654 + struct cifs_ses *ses = tcon->ses; 2655 + int flags = 0; 2656 + 2657 + cifs_dbg(FYI, "Query Info\n"); 2658 + 2659 + if (!ses || !(ses->server)) 2660 + return -EIO; 2661 + 2662 + if (smb3_encryption_required(tcon)) 2663 + flags |= CIFS_TRANSFORM_REQ; 2679 2664 2680 2665 memset(&rqst, 0, sizeof(struct smb_rqst)); 2666 + memset(&iov, 0, sizeof(iov)); 2681 2667 rqst.rq_iov = iov; 2682 2668 rqst.rq_nvec = 1; 2683 2669 2670 + rc = SMB2_query_info_init(tcon, &rqst, persistent_fid, volatile_fid, 2671 + info_class, info_type, additional_info, 2672 + output_len); 2673 + if (rc) 2674 + goto qinf_exit; 2675 + 2684 2676 rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov); 2685 - cifs_small_buf_release(req); 2686 2677 rsp = (struct smb2_query_info_rsp *)rsp_iov.iov_base; 2687 2678 2688 2679 if (rc) { ··· 2748 2665 &rsp_iov, min_len, *data); 2749 2666 2750 2667 qinf_exit: 2668 + SMB2_query_info_free(&rqst); 2751 2669 free_rsp_buf(resp_buftype, rsp); 2752 2670 return rc; 2753 2671 } ··· 3707 3623 goto qdir_exit; 3708 3624 } 3709 3625 3710 - rc = validate_iov(le16_to_cpu(rsp->OutputBufferOffset), 3711 - le32_to_cpu(rsp->OutputBufferLength), &rsp_iov, 3712 - info_buf_size); 3626 + rc = smb2_validate_iov(le16_to_cpu(rsp->OutputBufferOffset), 3627 + le32_to_cpu(rsp->OutputBufferLength), &rsp_iov, 3628 + info_buf_size); 3713 3629 if (rc) 3714 3630 goto qdir_exit; 3715 3631 ··· 4011 3927 return rc; 4012 3928 } 4013 3929 4014 - static void 4015 - copy_fs_info_to_kstatfs(struct smb2_fs_full_size_info *pfs_inf, 4016 - struct kstatfs *kst) 3930 + void 3931 + smb2_copy_fs_info_to_kstatfs(struct smb2_fs_full_size_info *pfs_inf, 3932 + struct kstatfs *kst) 4017 3933 { 4018 3934 kst->f_bsize = le32_to_cpu(pfs_inf->BytesPerSector) * 4019 3935 le32_to_cpu(pfs_inf->SectorsPerAllocationUnit); 4020 3936 kst->f_blocks = le64_to_cpu(pfs_inf->TotalAllocationUnits); 4021 3937 kst->f_bfree = kst->f_bavail = 4022 3938 le64_to_cpu(pfs_inf->CallerAvailableAllocationUnits); 3939 + return; 3940 + } 3941 + 3942 + static void 3943 + copy_posix_fs_info_to_kstatfs(FILE_SYSTEM_POSIX_INFO *response_data, 3944 + struct kstatfs *kst) 3945 + { 3946 + kst->f_bsize = le32_to_cpu(response_data->BlockSize); 3947 + kst->f_blocks = le64_to_cpu(response_data->TotalBlocks); 3948 + kst->f_bfree = le64_to_cpu(response_data->BlocksAvail); 3949 + if (response_data->UserBlocksAvail == cpu_to_le64(-1)) 3950 + kst->f_bavail = kst->f_bfree; 3951 + else 3952 + kst->f_bavail = le64_to_cpu(response_data->UserBlocksAvail); 3953 + if (response_data->TotalFileNodes != cpu_to_le64(-1)) 3954 + kst->f_files = le64_to_cpu(response_data->TotalFileNodes); 3955 + if (response_data->FreeFileNodes != cpu_to_le64(-1)) 3956 + kst->f_ffree = le64_to_cpu(response_data->FreeFileNodes); 3957 + 4023 3958 return; 4024 3959 } 4025 3960 ··· 4079 3976 } 4080 3977 4081 3978 int 3979 + SMB311_posix_qfs_info(const unsigned int xid, struct cifs_tcon *tcon, 3980 + u64 persistent_fid, u64 volatile_fid, struct kstatfs *fsdata) 3981 + { 3982 + struct smb_rqst rqst; 3983 + struct smb2_query_info_rsp *rsp = NULL; 3984 + struct kvec iov; 3985 + struct kvec rsp_iov; 3986 + int rc = 0; 3987 + int resp_buftype; 3988 + struct cifs_ses *ses = tcon->ses; 3989 + FILE_SYSTEM_POSIX_INFO *info = NULL; 3990 + int flags = 0; 3991 + 3992 + rc = build_qfs_info_req(&iov, tcon, FS_POSIX_INFORMATION, 3993 + sizeof(FILE_SYSTEM_POSIX_INFO), 3994 + persistent_fid, volatile_fid); 3995 + if (rc) 3996 + return rc; 3997 + 3998 + if (smb3_encryption_required(tcon)) 3999 + flags |= CIFS_TRANSFORM_REQ; 4000 + 4001 + memset(&rqst, 0, sizeof(struct smb_rqst)); 4002 + rqst.rq_iov = &iov; 4003 + rqst.rq_nvec = 1; 4004 + 4005 + rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov); 4006 + cifs_small_buf_release(iov.iov_base); 4007 + if (rc) { 4008 + cifs_stats_fail_inc(tcon, SMB2_QUERY_INFO_HE); 4009 + goto posix_qfsinf_exit; 4010 + } 4011 + rsp = (struct smb2_query_info_rsp *)rsp_iov.iov_base; 4012 + 4013 + info = (FILE_SYSTEM_POSIX_INFO *)( 4014 + le16_to_cpu(rsp->OutputBufferOffset) + (char *)rsp); 4015 + rc = smb2_validate_iov(le16_to_cpu(rsp->OutputBufferOffset), 4016 + le32_to_cpu(rsp->OutputBufferLength), &rsp_iov, 4017 + sizeof(FILE_SYSTEM_POSIX_INFO)); 4018 + if (!rc) 4019 + copy_posix_fs_info_to_kstatfs(info, fsdata); 4020 + 4021 + posix_qfsinf_exit: 4022 + free_rsp_buf(resp_buftype, rsp_iov.iov_base); 4023 + return rc; 4024 + } 4025 + 4026 + int 4082 4027 SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon, 4083 4028 u64 persistent_fid, u64 volatile_fid, struct kstatfs *fsdata) 4084 4029 { ··· 4163 4012 4164 4013 info = (struct smb2_fs_full_size_info *)( 4165 4014 le16_to_cpu(rsp->OutputBufferOffset) + (char *)rsp); 4166 - rc = validate_iov(le16_to_cpu(rsp->OutputBufferOffset), 4167 - le32_to_cpu(rsp->OutputBufferLength), &rsp_iov, 4168 - sizeof(struct smb2_fs_full_size_info)); 4015 + rc = smb2_validate_iov(le16_to_cpu(rsp->OutputBufferOffset), 4016 + le32_to_cpu(rsp->OutputBufferLength), &rsp_iov, 4017 + sizeof(struct smb2_fs_full_size_info)); 4169 4018 if (!rc) 4170 - copy_fs_info_to_kstatfs(info, fsdata); 4019 + smb2_copy_fs_info_to_kstatfs(info, fsdata); 4171 4020 4172 4021 qfsinf_exit: 4173 4022 free_rsp_buf(resp_buftype, rsp_iov.iov_base); ··· 4197 4046 } else if (level == FS_SECTOR_SIZE_INFORMATION) { 4198 4047 max_len = sizeof(struct smb3_fs_ss_info); 4199 4048 min_len = sizeof(struct smb3_fs_ss_info); 4049 + } else if (level == FS_VOLUME_INFORMATION) { 4050 + max_len = sizeof(struct smb3_fs_vol_info) + MAX_VOL_LABEL_LEN; 4051 + min_len = sizeof(struct smb3_fs_vol_info); 4200 4052 } else { 4201 4053 cifs_dbg(FYI, "Invalid qfsinfo level %d\n", level); 4202 4054 return -EINVAL; ··· 4227 4073 4228 4074 rsp_len = le32_to_cpu(rsp->OutputBufferLength); 4229 4075 offset = le16_to_cpu(rsp->OutputBufferOffset); 4230 - rc = validate_iov(offset, rsp_len, &rsp_iov, min_len); 4076 + rc = smb2_validate_iov(offset, rsp_len, &rsp_iov, min_len); 4231 4077 if (rc) 4232 4078 goto qfsattr_exit; 4233 4079 ··· 4244 4090 tcon->ss_flags = le32_to_cpu(ss_info->Flags); 4245 4091 tcon->perf_sector_size = 4246 4092 le32_to_cpu(ss_info->PhysicalBytesPerSectorForPerf); 4093 + } else if (level == FS_VOLUME_INFORMATION) { 4094 + struct smb3_fs_vol_info *vol_info = (struct smb3_fs_vol_info *) 4095 + (offset + (char *)rsp); 4096 + tcon->vol_serial_number = vol_info->VolumeSerialNumber; 4097 + tcon->vol_create_time = vol_info->VolumeCreationTime; 4247 4098 } 4248 4099 4249 4100 qfsattr_exit:
+24
fs/cifs/smb2pdu.h
··· 153 153 * 154 154 */ 155 155 156 + #define COMPOUND_FID 0xFFFFFFFFFFFFFFFFULL 157 + 156 158 #define SMB2_ERROR_STRUCTURE_SIZE2 cpu_to_le16(9) 157 159 158 160 struct smb2_err_rsp { ··· 767 765 struct durable_reconnect_context_v2 dcontext; 768 766 } __packed; 769 767 768 + /* See MS-SMB2 2.2.13.2.5 */ 769 + struct crt_twarp_ctxt { 770 + struct create_context ccontext; 771 + __u8 Name[8]; 772 + __le64 Timestamp; 773 + 774 + } __packed; 775 + 770 776 #define COPY_CHUNK_RES_KEY_SIZE 24 771 777 struct resume_key_req { 772 778 char ResumeKey[COPY_CHUNK_RES_KEY_SIZE]; ··· 1233 1223 #define FS_DRIVER_PATH_INFORMATION 9 /* Local only */ 1234 1224 #define FS_VOLUME_FLAGS_INFORMATION 10 /* Local only */ 1235 1225 #define FS_SECTOR_SIZE_INFORMATION 11 /* SMB3 or later. Query */ 1226 + #define FS_POSIX_INFORMATION 100 /* SMB3.1.1 POSIX. Query */ 1236 1227 1237 1228 struct smb2_fs_full_size_info { 1238 1229 __le64 TotalAllocationUnits; ··· 1257 1246 __le32 Flags; 1258 1247 __le32 ByteOffsetForSectorAlignment; 1259 1248 __le32 ByteOffsetForPartitionAlignment; 1249 + } __packed; 1250 + 1251 + /* volume info struct - see MS-FSCC 2.5.9 */ 1252 + #define MAX_VOL_LABEL_LEN 32 1253 + struct smb3_fs_vol_info { 1254 + __le64 VolumeCreationTime; 1255 + __u32 VolumeSerialNumber; 1256 + __le32 VolumeLabelLength; /* includes trailing null */ 1257 + __u8 SupportsObjects; /* True if eg like NTFS, supports objects */ 1258 + __u8 Reserved; 1259 + __u8 VolumeLabel[0]; /* variable len */ 1260 1260 } __packed; 1261 1261 1262 1262 /* partial list of QUERY INFO levels */ ··· 1382 1360 struct smb2_file_eof_info { /* encoding of request for level 10 */ 1383 1361 __le64 EndOfFile; /* new end of file value */ 1384 1362 } __packed; /* level 20 Set */ 1363 + 1364 + extern char smb2_padding[7]; 1385 1365 1386 1366 #endif /* _SMB2PDU_H */
+22 -2
fs/cifs/smb2proto.h
··· 68 68 69 69 extern int open_shroot(unsigned int xid, struct cifs_tcon *tcon, 70 70 struct cifs_fid *pfid); 71 + extern void close_shroot(struct cached_fid *cfid); 71 72 extern void move_smb2_info_to_cifs(FILE_ALL_INFO *dst, 72 73 struct smb2_file_all_info *src); 73 74 extern int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, ··· 133 132 __le16 *path, __u8 *oplock, 134 133 struct smb2_file_all_info *buf, 135 134 struct kvec *err_iov, int *resp_buftype); 135 + extern int SMB2_open_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, 136 + __u8 *oplock, struct cifs_open_parms *oparms, 137 + __le16 *path); 138 + extern void SMB2_open_free(struct smb_rqst *rqst); 136 139 extern int SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, 137 140 u64 persistent_fid, u64 volatile_fid, u32 opcode, 138 141 bool is_fsctl, char *in_data, u32 indatalen, ··· 145 140 u64 persistent_file_id, u64 volatile_file_id); 146 141 extern int SMB2_close_flags(const unsigned int xid, struct cifs_tcon *tcon, 147 142 u64 persistent_fid, u64 volatile_fid, int flags); 143 + extern int SMB2_close_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, 144 + u64 persistent_file_id, u64 volatile_file_id); 145 + extern void SMB2_close_free(struct smb_rqst *rqst); 148 146 extern int SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, 149 147 u64 persistent_file_id, u64 volatile_file_id); 150 148 extern int SMB2_query_eas(const unsigned int xid, struct cifs_tcon *tcon, ··· 157 149 extern int SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon, 158 150 u64 persistent_file_id, u64 volatile_file_id, 159 151 struct smb2_file_all_info *data); 152 + extern int SMB2_query_info_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, 153 + u64 persistent_fid, u64 volatile_fid, 154 + u8 info_class, u8 info_type, 155 + u32 additional_info, size_t output_len); 156 + extern void SMB2_query_info_free(struct smb_rqst *rqst); 160 157 extern int SMB2_query_acl(const unsigned int xid, struct cifs_tcon *tcon, 161 158 u64 persistent_file_id, u64 volatile_file_id, 162 159 void **data, unsigned int *plen); ··· 210 197 extern int SMB2_QFS_info(const unsigned int xid, struct cifs_tcon *tcon, 211 198 u64 persistent_file_id, u64 volatile_file_id, 212 199 struct kstatfs *FSData); 200 + extern int SMB311_posix_qfs_info(const unsigned int xid, struct cifs_tcon *tcon, 201 + u64 persistent_file_id, u64 volatile_file_id, 202 + struct kstatfs *FSData); 213 203 extern int SMB2_QFS_attr(const unsigned int xid, struct cifs_tcon *tcon, 214 204 u64 persistent_file_id, u64 volatile_file_id, int lvl); 215 205 extern int SMB2_lock(const unsigned int xid, struct cifs_tcon *tcon, ··· 229 213 230 214 extern enum securityEnum smb2_select_sectype(struct TCP_Server_Info *, 231 215 enum securityEnum); 232 - #ifdef CONFIG_CIFS_SMB311 216 + extern int smb3_encryption_required(const struct cifs_tcon *tcon); 217 + extern int smb2_validate_iov(unsigned int offset, unsigned int buffer_length, 218 + struct kvec *iov, unsigned int min_buf_size); 219 + extern void smb2_copy_fs_info_to_kstatfs( 220 + struct smb2_fs_full_size_info *pfs_inf, 221 + struct kstatfs *kst); 233 222 extern int smb311_crypto_shash_allocate(struct TCP_Server_Info *server); 234 223 extern int smb311_update_preauth_hash(struct cifs_ses *ses, 235 224 struct kvec *iov, int nvec); 236 - #endif 237 225 #endif /* _SMB2PROTO_H */
+3 -6
fs/cifs/smb2transport.c
··· 70 70 return rc; 71 71 } 72 72 73 - #ifdef CONFIG_CIFS_SMB311 74 73 int 75 74 smb311_crypto_shash_allocate(struct TCP_Server_Info *server) 76 75 { ··· 97 98 cifs_free_hash(&p->hmacsha256, &p->sdeschmacsha256); 98 99 return rc; 99 100 } 100 - #endif 101 101 102 102 static struct cifs_ses * 103 103 smb2_find_smb_ses_unlocked(struct TCP_Server_Info *server, __u64 ses_id) ··· 171 173 struct kvec *iov = rqst->rq_iov; 172 174 struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)iov[0].iov_base; 173 175 struct cifs_ses *ses; 174 - struct shash_desc *shash = &server->secmech.sdeschmacsha256->shash; 176 + struct shash_desc *shash; 175 177 struct smb_rqst drqst; 176 178 177 179 ses = smb2_find_smb_ses(server, shdr->SessionId); ··· 185 187 186 188 rc = smb2_crypto_shash_allocate(server); 187 189 if (rc) { 188 - cifs_dbg(VFS, "%s: shah256 alloc failed\n", __func__); 190 + cifs_dbg(VFS, "%s: sha256 alloc failed\n", __func__); 189 191 return rc; 190 192 } 191 193 ··· 196 198 return rc; 197 199 } 198 200 201 + shash = &server->secmech.sdeschmacsha256->shash; 199 202 rc = crypto_shash_init(shash); 200 203 if (rc) { 201 204 cifs_dbg(VFS, "%s: Could not init sha256", __func__); ··· 394 395 return generate_smb3signingkey(ses, &triplet); 395 396 } 396 397 397 - #ifdef CONFIG_CIFS_SMB311 398 398 int 399 399 generate_smb311signingkey(struct cifs_ses *ses) 400 400 ··· 421 423 422 424 return generate_smb3signingkey(ses, &triplet); 423 425 } 424 - #endif /* 311 */ 425 426 426 427 int 427 428 smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server)
+64
fs/cifs/trace.h
··· 281 281 TP_ARGS(tid, sesid, cmd, mid)) 282 282 283 283 DEFINE_SMB3_CMD_DONE_EVENT(cmd_done); 284 + DEFINE_SMB3_CMD_DONE_EVENT(ses_expired); 285 + 286 + DECLARE_EVENT_CLASS(smb3_mid_class, 287 + TP_PROTO(__u16 cmd, 288 + __u64 mid, 289 + __u32 pid, 290 + unsigned long when_sent, 291 + unsigned long when_received), 292 + TP_ARGS(cmd, mid, pid, when_sent, when_received), 293 + TP_STRUCT__entry( 294 + __field(__u16, cmd) 295 + __field(__u64, mid) 296 + __field(__u32, pid) 297 + __field(unsigned long, when_sent) 298 + __field(unsigned long, when_received) 299 + ), 300 + TP_fast_assign( 301 + __entry->cmd = cmd; 302 + __entry->mid = mid; 303 + __entry->pid = pid; 304 + __entry->when_sent = when_sent; 305 + __entry->when_received = when_received; 306 + ), 307 + TP_printk("\tcmd=%u mid=%llu pid=%u, when_sent=%lu when_rcv=%lu", 308 + __entry->cmd, __entry->mid, __entry->pid, __entry->when_sent, 309 + __entry->when_received) 310 + ) 311 + 312 + #define DEFINE_SMB3_MID_EVENT(name) \ 313 + DEFINE_EVENT(smb3_mid_class, smb3_##name, \ 314 + TP_PROTO(__u16 cmd, \ 315 + __u64 mid, \ 316 + __u32 pid, \ 317 + unsigned long when_sent, \ 318 + unsigned long when_received), \ 319 + TP_ARGS(cmd, mid, pid, when_sent, when_received)) 320 + 321 + DEFINE_SMB3_MID_EVENT(slow_rsp); 284 322 285 323 DECLARE_EVENT_CLASS(smb3_exit_err_class, 286 324 TP_PROTO(unsigned int xid, ··· 459 421 460 422 DEFINE_SMB3_OPEN_DONE_EVENT(open_done); 461 423 DEFINE_SMB3_OPEN_DONE_EVENT(posix_mkdir_done); 424 + 425 + DECLARE_EVENT_CLASS(smb3_reconnect_class, 426 + TP_PROTO(__u64 currmid, 427 + char *hostname), 428 + TP_ARGS(currmid, hostname), 429 + TP_STRUCT__entry( 430 + __field(__u64, currmid) 431 + __field(char *, hostname) 432 + ), 433 + TP_fast_assign( 434 + __entry->currmid = currmid; 435 + __entry->hostname = hostname; 436 + ), 437 + TP_printk("server=%s current_mid=0x%llx", 438 + __entry->hostname, 439 + __entry->currmid) 440 + ) 441 + 442 + #define DEFINE_SMB3_RECONNECT_EVENT(name) \ 443 + DEFINE_EVENT(smb3_reconnect_class, smb3_##name, \ 444 + TP_PROTO(__u64 currmid, \ 445 + char *hostname), \ 446 + TP_ARGS(currmid, hostname)) 447 + 448 + DEFINE_SMB3_RECONNECT_EVENT(reconnect); 449 + DEFINE_SMB3_RECONNECT_EVENT(partial_send_reconnect); 462 450 463 451 #endif /* _CIFS_TRACE_H */ 464 452
+133 -86
fs/cifs/transport.c
··· 115 115 now = jiffies; 116 116 /* commands taking longer than one second are indications that 117 117 something is wrong, unless it is quite a slow link or server */ 118 - if (time_after(now, midEntry->when_alloc + HZ)) { 119 - if ((cifsFYI & CIFS_TIMER) && (midEntry->command != command)) { 118 + if (time_after(now, midEntry->when_alloc + HZ) && 119 + (midEntry->command != command)) { 120 + /* smb2slowcmd[NUMBER_OF_SMB2_COMMANDS] counts by command */ 121 + if ((le16_to_cpu(midEntry->command) < NUMBER_OF_SMB2_COMMANDS) && 122 + (le16_to_cpu(midEntry->command) >= 0)) 123 + cifs_stats_inc(&midEntry->server->smb2slowcmd[le16_to_cpu(midEntry->command)]); 124 + 125 + trace_smb3_slow_rsp(le16_to_cpu(midEntry->command), 126 + midEntry->mid, midEntry->pid, 127 + midEntry->when_sent, midEntry->when_received); 128 + if (cifsFYI & CIFS_TIMER) { 120 129 pr_debug(" CIFS slow rsp: cmd %d mid %llu", 121 130 midEntry->command, midEntry->mid); 122 131 pr_info(" A: 0x%lx S: 0x%lx R: 0x%lx\n", ··· 370 361 * socket so the server throws away the partial SMB 371 362 */ 372 363 server->tcpStatus = CifsNeedReconnect; 364 + trace_smb3_partial_send_reconnect(server->CurrentMid, 365 + server->hostname); 373 366 } 374 367 smbd_done: 375 368 if (rc < 0 && rc != -EINTR) ··· 384 373 } 385 374 386 375 static int 387 - smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst, int flags) 376 + smb_send_rqst(struct TCP_Server_Info *server, int num_rqst, 377 + struct smb_rqst *rqst, int flags) 388 378 { 389 - struct smb_rqst cur_rqst; 379 + struct kvec iov; 380 + struct smb2_transform_hdr tr_hdr; 381 + struct smb_rqst cur_rqst[MAX_COMPOUND]; 390 382 int rc; 391 383 392 384 if (!(flags & CIFS_TRANSFORM_REQ)) 393 - return __smb_send_rqst(server, 1, rqst); 385 + return __smb_send_rqst(server, num_rqst, rqst); 394 386 395 - if (!server->ops->init_transform_rq || 396 - !server->ops->free_transform_rq) { 397 - cifs_dbg(VFS, "Encryption requested but transform callbacks are missed\n"); 387 + if (num_rqst > MAX_COMPOUND - 1) 388 + return -ENOMEM; 389 + 390 + memset(&cur_rqst[0], 0, sizeof(cur_rqst)); 391 + memset(&iov, 0, sizeof(iov)); 392 + memset(&tr_hdr, 0, sizeof(tr_hdr)); 393 + 394 + iov.iov_base = &tr_hdr; 395 + iov.iov_len = sizeof(tr_hdr); 396 + cur_rqst[0].rq_iov = &iov; 397 + cur_rqst[0].rq_nvec = 1; 398 + 399 + if (!server->ops->init_transform_rq) { 400 + cifs_dbg(VFS, "Encryption requested but transform callback " 401 + "is missing\n"); 398 402 return -EIO; 399 403 } 400 404 401 - rc = server->ops->init_transform_rq(server, &cur_rqst, rqst); 405 + rc = server->ops->init_transform_rq(server, num_rqst + 1, 406 + &cur_rqst[0], rqst); 402 407 if (rc) 403 408 return rc; 404 409 405 - rc = __smb_send_rqst(server, 1, &cur_rqst); 406 - server->ops->free_transform_rq(&cur_rqst); 410 + rc = __smb_send_rqst(server, num_rqst + 1, &cur_rqst[0]); 411 + smb3_free_compound_rqst(num_rqst, &cur_rqst[1]); 407 412 return rc; 408 413 } 409 414 ··· 633 606 */ 634 607 cifs_save_when_sent(mid); 635 608 cifs_in_send_inc(server); 636 - rc = smb_send_rqst(server, rqst, flags); 609 + rc = smb_send_rqst(server, 1, rqst, flags); 637 610 cifs_in_send_dec(server); 638 611 639 612 if (rc < 0) { ··· 773 746 } 774 747 775 748 int 776 - cifs_send_recv(const unsigned int xid, struct cifs_ses *ses, 777 - struct smb_rqst *rqst, int *resp_buf_type, const int flags, 778 - struct kvec *resp_iov) 749 + compound_send_recv(const unsigned int xid, struct cifs_ses *ses, 750 + const int flags, const int num_rqst, struct smb_rqst *rqst, 751 + int *resp_buf_type, struct kvec *resp_iov) 779 752 { 780 - int rc = 0; 753 + int i, j, rc = 0; 781 754 int timeout, optype; 782 - struct mid_q_entry *midQ; 755 + struct mid_q_entry *midQ[MAX_COMPOUND]; 783 756 unsigned int credits = 1; 784 757 char *buf; 785 758 786 759 timeout = flags & CIFS_TIMEOUT_MASK; 787 760 optype = flags & CIFS_OP_MASK; 788 761 789 - *resp_buf_type = CIFS_NO_BUFFER; /* no response buf yet */ 762 + for (i = 0; i < num_rqst; i++) 763 + resp_buf_type[i] = CIFS_NO_BUFFER; /* no response buf yet */ 790 764 791 765 if ((ses == NULL) || (ses->server == NULL)) { 792 766 cifs_dbg(VFS, "Null session\n"); ··· 814 786 815 787 mutex_lock(&ses->server->srv_mutex); 816 788 817 - midQ = ses->server->ops->setup_request(ses, rqst); 818 - if (IS_ERR(midQ)) { 819 - mutex_unlock(&ses->server->srv_mutex); 820 - /* Update # of requests on wire to server */ 821 - add_credits(ses->server, 1, optype); 822 - return PTR_ERR(midQ); 789 + for (i = 0; i < num_rqst; i++) { 790 + midQ[i] = ses->server->ops->setup_request(ses, &rqst[i]); 791 + if (IS_ERR(midQ[i])) { 792 + for (j = 0; j < i; j++) 793 + cifs_delete_mid(midQ[j]); 794 + mutex_unlock(&ses->server->srv_mutex); 795 + /* Update # of requests on wire to server */ 796 + add_credits(ses->server, 1, optype); 797 + return PTR_ERR(midQ[i]); 798 + } 799 + 800 + midQ[i]->mid_state = MID_REQUEST_SUBMITTED; 823 801 } 824 802 825 - midQ->mid_state = MID_REQUEST_SUBMITTED; 826 803 cifs_in_send_inc(ses->server); 827 - rc = smb_send_rqst(ses->server, rqst, flags); 804 + rc = smb_send_rqst(ses->server, num_rqst, rqst, flags); 828 805 cifs_in_send_dec(ses->server); 829 - cifs_save_when_sent(midQ); 806 + 807 + for (i = 0; i < num_rqst; i++) 808 + cifs_save_when_sent(midQ[i]); 830 809 831 810 if (rc < 0) 832 811 ses->server->sequence_number -= 2; 812 + 833 813 mutex_unlock(&ses->server->srv_mutex); 834 814 835 - if (rc < 0) 836 - goto out; 815 + for (i = 0; i < num_rqst; i++) { 816 + if (rc < 0) 817 + goto out; 837 818 838 - #ifdef CONFIG_CIFS_SMB311 839 - if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP)) 840 - smb311_update_preauth_hash(ses, rqst->rq_iov, 841 - rqst->rq_nvec); 842 - #endif 819 + if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP)) 820 + smb311_update_preauth_hash(ses, rqst[i].rq_iov, 821 + rqst[i].rq_nvec); 843 822 844 - if (timeout == CIFS_ASYNC_OP) 845 - goto out; 823 + if (timeout == CIFS_ASYNC_OP) 824 + goto out; 846 825 847 - rc = wait_for_response(ses->server, midQ); 848 - if (rc != 0) { 849 - cifs_dbg(FYI, "Cancelling wait for mid %llu\n", midQ->mid); 850 - send_cancel(ses->server, rqst, midQ); 851 - spin_lock(&GlobalMid_Lock); 852 - if (midQ->mid_state == MID_REQUEST_SUBMITTED) { 853 - midQ->mid_flags |= MID_WAIT_CANCELLED; 854 - midQ->callback = DeleteMidQEntry; 826 + rc = wait_for_response(ses->server, midQ[i]); 827 + if (rc != 0) { 828 + cifs_dbg(FYI, "Cancelling wait for mid %llu\n", 829 + midQ[i]->mid); 830 + send_cancel(ses->server, &rqst[i], midQ[i]); 831 + spin_lock(&GlobalMid_Lock); 832 + if (midQ[i]->mid_state == MID_REQUEST_SUBMITTED) { 833 + midQ[i]->mid_flags |= MID_WAIT_CANCELLED; 834 + midQ[i]->callback = DeleteMidQEntry; 835 + spin_unlock(&GlobalMid_Lock); 836 + add_credits(ses->server, 1, optype); 837 + return rc; 838 + } 855 839 spin_unlock(&GlobalMid_Lock); 840 + } 841 + 842 + rc = cifs_sync_mid_result(midQ[i], ses->server); 843 + if (rc != 0) { 856 844 add_credits(ses->server, 1, optype); 857 845 return rc; 858 846 } 859 - spin_unlock(&GlobalMid_Lock); 847 + 848 + if (!midQ[i]->resp_buf || 849 + midQ[i]->mid_state != MID_RESPONSE_RECEIVED) { 850 + rc = -EIO; 851 + cifs_dbg(FYI, "Bad MID state?\n"); 852 + goto out; 853 + } 854 + 855 + buf = (char *)midQ[i]->resp_buf; 856 + resp_iov[i].iov_base = buf; 857 + resp_iov[i].iov_len = midQ[i]->resp_buf_size + 858 + ses->server->vals->header_preamble_size; 859 + 860 + if (midQ[i]->large_buf) 861 + resp_buf_type[i] = CIFS_LARGE_BUFFER; 862 + else 863 + resp_buf_type[i] = CIFS_SMALL_BUFFER; 864 + 865 + if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP)) { 866 + struct kvec iov = { 867 + .iov_base = resp_iov[i].iov_base, 868 + .iov_len = resp_iov[i].iov_len 869 + }; 870 + smb311_update_preauth_hash(ses, &iov, 1); 871 + } 872 + 873 + credits = ses->server->ops->get_credits(midQ[i]); 874 + 875 + rc = ses->server->ops->check_receive(midQ[i], ses->server, 876 + flags & CIFS_LOG_ERROR); 877 + 878 + /* mark it so buf will not be freed by cifs_delete_mid */ 879 + if ((flags & CIFS_NO_RESP) == 0) 880 + midQ[i]->resp_buf = NULL; 860 881 } 861 - 862 - rc = cifs_sync_mid_result(midQ, ses->server); 863 - if (rc != 0) { 864 - add_credits(ses->server, 1, optype); 865 - return rc; 866 - } 867 - 868 - if (!midQ->resp_buf || midQ->mid_state != MID_RESPONSE_RECEIVED) { 869 - rc = -EIO; 870 - cifs_dbg(FYI, "Bad MID state?\n"); 871 - goto out; 872 - } 873 - 874 - buf = (char *)midQ->resp_buf; 875 - resp_iov->iov_base = buf; 876 - resp_iov->iov_len = midQ->resp_buf_size + 877 - ses->server->vals->header_preamble_size; 878 - if (midQ->large_buf) 879 - *resp_buf_type = CIFS_LARGE_BUFFER; 880 - else 881 - *resp_buf_type = CIFS_SMALL_BUFFER; 882 - 883 - #ifdef CONFIG_CIFS_SMB311 884 - if ((ses->status == CifsNew) || (optype & CIFS_NEG_OP)) { 885 - struct kvec iov = { 886 - .iov_base = resp_iov->iov_base, 887 - .iov_len = resp_iov->iov_len 888 - }; 889 - smb311_update_preauth_hash(ses, &iov, 1); 890 - } 891 - #endif 892 - 893 - credits = ses->server->ops->get_credits(midQ); 894 - 895 - rc = ses->server->ops->check_receive(midQ, ses->server, 896 - flags & CIFS_LOG_ERROR); 897 - 898 - /* mark it so buf will not be freed by cifs_delete_mid */ 899 - if ((flags & CIFS_NO_RESP) == 0) 900 - midQ->resp_buf = NULL; 901 882 out: 902 - cifs_delete_mid(midQ); 883 + for (i = 0; i < num_rqst; i++) 884 + cifs_delete_mid(midQ[i]); 903 885 add_credits(ses->server, credits, optype); 904 886 905 887 return rc; 888 + } 889 + 890 + int 891 + cifs_send_recv(const unsigned int xid, struct cifs_ses *ses, 892 + struct smb_rqst *rqst, int *resp_buf_type, const int flags, 893 + struct kvec *resp_iov) 894 + { 895 + return compound_send_recv(xid, ses, flags, 1, rqst, resp_buf_type, 896 + resp_iov); 906 897 } 907 898 908 899 int
+26 -2
fs/cifs/xattr.c
··· 35 35 #define CIFS_XATTR_CIFS_ACL "system.cifs_acl" 36 36 #define CIFS_XATTR_ATTRIB "cifs.dosattrib" /* full name: user.cifs.dosattrib */ 37 37 #define CIFS_XATTR_CREATETIME "cifs.creationtime" /* user.cifs.creationtime */ 38 + /* 39 + * Although these three are just aliases for the above, need to move away from 40 + * confusing users and using the 20+ year old term 'cifs' when it is no longer 41 + * secure, replaced by SMB2 (then even more highly secure SMB3) many years ago 42 + */ 43 + #define SMB3_XATTR_CIFS_ACL "system.smb3_acl" 44 + #define SMB3_XATTR_ATTRIB "smb3.dosattrib" /* full name: user.smb3.dosattrib */ 45 + #define SMB3_XATTR_CREATETIME "smb3.creationtime" /* user.smb3.creationtime */ 38 46 /* BB need to add server (Samba e.g) support for security and trusted prefix */ 39 47 40 48 enum { XATTR_USER, XATTR_CIFS_ACL, XATTR_ACL_ACCESS, XATTR_ACL_DEFAULT }; ··· 228 220 switch (handler->flags) { 229 221 case XATTR_USER: 230 222 cifs_dbg(FYI, "%s:querying user xattr %s\n", __func__, name); 231 - if (strcmp(name, CIFS_XATTR_ATTRIB) == 0) { 223 + if ((strcmp(name, CIFS_XATTR_ATTRIB) == 0) || 224 + (strcmp(name, SMB3_XATTR_ATTRIB) == 0)) { 232 225 rc = cifs_attrib_get(dentry, inode, value, size); 233 226 break; 234 - } else if (strcmp(name, CIFS_XATTR_CREATETIME) == 0) { 227 + } else if ((strcmp(name, CIFS_XATTR_CREATETIME) == 0) || 228 + (strcmp(name, SMB3_XATTR_CREATETIME) == 0)) { 235 229 rc = cifs_creation_time_get(dentry, inode, value, size); 236 230 break; 237 231 } ··· 373 363 .set = cifs_xattr_set, 374 364 }; 375 365 366 + /* 367 + * Although this is just an alias for the above, need to move away from 368 + * confusing users and using the 20 year old term 'cifs' when it is no 369 + * longer secure and was replaced by SMB2/SMB3 a long time ago, and 370 + * SMB3 and later are highly secure. 371 + */ 372 + static const struct xattr_handler smb3_acl_xattr_handler = { 373 + .name = SMB3_XATTR_CIFS_ACL, 374 + .flags = XATTR_CIFS_ACL, 375 + .get = cifs_xattr_get, 376 + .set = cifs_xattr_set, 377 + }; 378 + 376 379 static const struct xattr_handler cifs_posix_acl_access_xattr_handler = { 377 380 .name = XATTR_NAME_POSIX_ACL_ACCESS, 378 381 .flags = XATTR_ACL_ACCESS, ··· 404 381 &cifs_user_xattr_handler, 405 382 &cifs_os2_xattr_handler, 406 383 &cifs_cifs_acl_xattr_handler, 384 + &smb3_acl_xattr_handler, /* alias for above since avoiding "cifs" */ 407 385 &cifs_posix_acl_access_xattr_handler, 408 386 &cifs_posix_acl_default_xattr_handler, 409 387 NULL