summaryrefslogtreecommitdiff
path: root/ANDROID_3.4.5/fs/cifs
diff options
context:
space:
mode:
Diffstat (limited to 'ANDROID_3.4.5/fs/cifs')
-rw-r--r--ANDROID_3.4.5/fs/cifs/AUTHORS55
-rw-r--r--ANDROID_3.4.5/fs/cifs/CHANGES1065
-rw-r--r--ANDROID_3.4.5/fs/cifs/Kconfig160
-rw-r--r--ANDROID_3.4.5/fs/cifs/Makefile17
-rw-r--r--ANDROID_3.4.5/fs/cifs/README758
-rw-r--r--ANDROID_3.4.5/fs/cifs/TODO129
-rw-r--r--ANDROID_3.4.5/fs/cifs/asn1.c666
-rw-r--r--ANDROID_3.4.5/fs/cifs/cache.c333
-rw-r--r--ANDROID_3.4.5/fs/cifs/cifs_debug.c751
-rw-r--r--ANDROID_3.4.5/fs/cifs/cifs_debug.h96
-rw-r--r--ANDROID_3.4.5/fs/cifs/cifs_dfs_ref.c371
-rw-r--r--ANDROID_3.4.5/fs/cifs/cifs_fs_sb.h69
-rw-r--r--ANDROID_3.4.5/fs/cifs/cifs_spnego.c179
-rw-r--r--ANDROID_3.4.5/fs/cifs/cifs_spnego.h47
-rw-r--r--ANDROID_3.4.5/fs/cifs/cifs_unicode.c333
-rw-r--r--ANDROID_3.4.5/fs/cifs/cifs_unicode.h383
-rw-r--r--ANDROID_3.4.5/fs/cifs/cifs_uniupr.h253
-rw-r--r--ANDROID_3.4.5/fs/cifs/cifsacl.c1354
-rw-r--r--ANDROID_3.4.5/fs/cifs/cifsacl.h103
-rw-r--r--ANDROID_3.4.5/fs/cifs/cifsencrypt.c754
-rw-r--r--ANDROID_3.4.5/fs/cifs/cifsfs.c1211
-rw-r--r--ANDROID_3.4.5/fs/cifs/cifsfs.h129
-rw-r--r--ANDROID_3.4.5/fs/cifs/cifsglob.h1078
-rw-r--r--ANDROID_3.4.5/fs/cifs/cifspdu.h2669
-rw-r--r--ANDROID_3.4.5/fs/cifs/cifsproto.h509
-rw-r--r--ANDROID_3.4.5/fs/cifs/cifssmb.c6504
-rw-r--r--ANDROID_3.4.5/fs/cifs/connect.c4348
-rw-r--r--ANDROID_3.4.5/fs/cifs/dir.c758
-rw-r--r--ANDROID_3.4.5/fs/cifs/dns_resolve.c98
-rw-r--r--ANDROID_3.4.5/fs/cifs/dns_resolve.h30
-rw-r--r--ANDROID_3.4.5/fs/cifs/export.c67
-rw-r--r--ANDROID_3.4.5/fs/cifs/file.c3060
-rw-r--r--ANDROID_3.4.5/fs/cifs/fscache.c235
-rw-r--r--ANDROID_3.4.5/fs/cifs/fscache.h136
-rw-r--r--ANDROID_3.4.5/fs/cifs/inode.c2293
-rw-r--r--ANDROID_3.4.5/fs/cifs/ioctl.c102
-rw-r--r--ANDROID_3.4.5/fs/cifs/link.c606
-rw-r--r--ANDROID_3.4.5/fs/cifs/misc.c721
-rw-r--r--ANDROID_3.4.5/fs/cifs/netmisc.c1008
-rw-r--r--ANDROID_3.4.5/fs/cifs/nterr.c687
-rw-r--r--ANDROID_3.4.5/fs/cifs/nterr.h561
-rw-r--r--ANDROID_3.4.5/fs/cifs/ntlmssp.h128
-rw-r--r--ANDROID_3.4.5/fs/cifs/readdir.c842
-rw-r--r--ANDROID_3.4.5/fs/cifs/rfc1002pdu.h74
-rw-r--r--ANDROID_3.4.5/fs/cifs/sess.c958
-rw-r--r--ANDROID_3.4.5/fs/cifs/smbencrypt.c247
-rw-r--r--ANDROID_3.4.5/fs/cifs/smberr.h184
-rw-r--r--ANDROID_3.4.5/fs/cifs/smbfsctl.h84
-rw-r--r--ANDROID_3.4.5/fs/cifs/transport.c956
-rw-r--r--ANDROID_3.4.5/fs/cifs/xattr.c416
50 files changed, 0 insertions, 38575 deletions
diff --git a/ANDROID_3.4.5/fs/cifs/AUTHORS b/ANDROID_3.4.5/fs/cifs/AUTHORS
deleted file mode 100644
index ea940b1d..00000000
--- a/ANDROID_3.4.5/fs/cifs/AUTHORS
+++ /dev/null
@@ -1,55 +0,0 @@
-Original Author
-===============
-Steve French (sfrench@samba.org)
-
-The author wishes to express his appreciation and thanks to:
-Andrew Tridgell (Samba team) for his early suggestions about smb/cifs VFS
-improvements. Thanks to IBM for allowing me time and test resources to pursue
-this project, to Jim McDonough from IBM (and the Samba Team) for his help, to
-the IBM Linux JFS team for explaining many esoteric Linux filesystem features.
-Jeremy Allison of the Samba team has done invaluable work in adding the server
-side of the original CIFS Unix extensions and reviewing and implementing
-portions of the newer CIFS POSIX extensions into the Samba 3 file server. Thank
-Dave Boutcher of IBM Rochester (author of the OS/400 smb/cifs filesystem client)
-for proving years ago that very good smb/cifs clients could be done on Unix-like
-operating systems. Volker Lendecke, Andrew Tridgell, Urban Widmark, John
-Newbigin and others for their work on the Linux smbfs module. Thanks to
-the other members of the Storage Network Industry Association CIFS Technical
-Workgroup for their work specifying this highly complex protocol and finally
-thanks to the Samba team for their technical advice and encouragement.
-
-Patch Contributors
-------------------
-Zwane Mwaikambo
-Andi Kleen
-Amrut Joshi
-Shobhit Dayal
-Sergey Vlasov
-Richard Hughes
-Yury Umanets
-Mark Hamzy (for some of the early cifs IPv6 work)
-Domen Puncer
-Jesper Juhl (in particular for lots of whitespace/formatting cleanup)
-Vince Negri and Dave Stahl (for finding an important caching bug)
-Adrian Bunk (kcalloc cleanups)
-Miklos Szeredi
-Kazeon team for various fixes especially for 2.4 version.
-Asser Ferno (Change Notify support)
-Shaggy (Dave Kleikamp) for innumerable small fs suggestions and some good cleanup
-Gunter Kukkukk (testing and suggestions for support of old servers)
-Igor Mammedov (DFS support)
-Jeff Layton (many, many fixes, as well as great work on the cifs Kerberos code)
-
-Test case and Bug Report contributors
--------------------------------------
-Thanks to those in the community who have submitted detailed bug reports
-and debug of problems they have found: Jochen Dolze, David Blaine,
-Rene Scharfe, Martin Josefsson, Alexander Wild, Anthony Liguori,
-Lars Muller, Urban Widmark, Massimiliano Ferrero, Howard Owen,
-Olaf Kirch, Kieron Briggs, Nick Millington and others. Also special
-mention to the Stanford Checker (SWAT) which pointed out many minor
-bugs in error paths. Valuable suggestions also have come from Al Viro
-and Dave Miller.
-
-And thanks to the IBM LTC and Power test teams and SuSE testers for
-finding multiple bugs during excellent stress test runs.
diff --git a/ANDROID_3.4.5/fs/cifs/CHANGES b/ANDROID_3.4.5/fs/cifs/CHANGES
deleted file mode 100644
index bc0025cd..00000000
--- a/ANDROID_3.4.5/fs/cifs/CHANGES
+++ /dev/null
@@ -1,1065 +0,0 @@
-Version 1.62
-------------
-Add sockopt=TCP_NODELAY mount option. EA (xattr) routines hardened
-to more strictly handle corrupt frames.
-
-Version 1.61
-------------
-Fix append problem to Samba servers (files opened with O_APPEND could
-have duplicated data). Fix oops in cifs_lookup. Workaround problem
-mounting to OS/400 Netserve. Fix oops in cifs_get_tcp_session.
-Disable use of server inode numbers when server only
-partially supports them (e.g. for one server querying inode numbers on
-FindFirst fails but QPathInfo queries works). Fix oops with dfs in
-cifs_put_smb_ses. Fix mmap to work on directio mounts (needed
-for OpenOffice when on forcedirectio mount e.g.)
-
-Version 1.60
--------------
-Fix memory leak in reconnect. Fix oops in DFS mount error path.
-Set s_maxbytes to smaller (the max that vfs can handle) so that
-sendfile will now work over cifs mounts again. Add noforcegid
-and noforceuid mount parameters. Fix small mem leak when using
-ntlmv2. Fix 2nd mount to same server but with different port to
-be allowed (rather than reusing the 1st port) - only when the
-user explicitly overrides the port on the 2nd mount.
-
-Version 1.59
-------------
-Client uses server inode numbers (which are persistent) rather than
-client generated ones by default (mount option "serverino" turned
-on by default if server supports it). Add forceuid and forcegid
-mount options (so that when negotiating unix extensions specifying
-which uid mounted does not immediately force the server's reported
-uids to be overridden). Add support for scope mount parm. Improve
-hard link detection to use same inode for both. Do not set
-read-only dos attribute on directories (for chmod) since Windows
-explorer special cases this attribute bit for directories for
-a different purpose.
-
-Version 1.58
-------------
-Guard against buffer overruns in various UCS-2 to UTF-8 string conversions
-when the UTF-8 string is composed of unusually long (more than 4 byte) converted
-characters. Add support for mounting root of a share which redirects immediately
-to DFS target. Convert string conversion functions from Unicode to more
-accurately mark string length before allocating memory (which may help the
-rare cases where a UTF-8 string is much larger than the UCS2 string that
-we converted from). Fix endianness of the vcnum field used during
-session setup to distinguish multiple mounts to same server from different
-userids. Raw NTLMSSP fixed (it requires /proc/fs/cifs/experimental
-flag to be set to 2, and mount must enable krb5 to turn on extended security).
-Performance of file create to Samba improved (posix create on lookup
-removes 1 of 2 network requests sent on file create)
-
-Version 1.57
-------------
-Improve support for multiple security contexts to the same server. We
-used to use the same "vcnumber" for all connections which could cause
-the server to treat subsequent connections, especially those that
-are authenticated as guest, as reconnections, invalidating the earlier
-user's smb session. This fix allows cifs to mount multiple times to the
-same server with different userids without risking invalidating earlier
-established security contexts. fsync now sends SMB Flush operation
-to better ensure that we wait for server to write all of the data to
-server disk (not just write it over the network). Add new mount
-parameter to allow user to disable sending the (slow) SMB flush on
-fsync if desired (fsync still flushes all cached write data to the server).
-Posix file open support added (turned off after one attempt if server
-fails to support it properly, as with Samba server versions prior to 3.3.2)
-Fix "redzone overwritten" bug in cifs_put_tcon (CIFSTcon may allocate too
-little memory for the "nativeFileSystem" field returned by the server
-during mount). Endian convert inode numbers if necessary (makes it easier
-to compare inode numbers on network files from big endian systems).
-
-Version 1.56
-------------
-Add "forcemandatorylock" mount option to allow user to use mandatory
-rather than posix (advisory) byte range locks, even though server would
-support posix byte range locks. Fix query of root inode when prefixpath
-specified and user does not have access to query information about the
-top of the share. Fix problem in 2.6.28 resolving DFS paths to
-Samba servers (worked to Windows). Fix rmdir so that pending search
-(readdir) requests do not get invalid results which include the now
-removed directory. Fix oops in cifs_dfs_ref.c when prefixpath is not reachable
-when using DFS. Add better file create support to servers which support
-the CIFS POSIX protocol extensions (this adds support for new flags
-on create, and improves semantics for write of locked ranges).
-
-Version 1.55
-------------
-Various fixes to make delete of open files behavior more predictable
-(when delete of an open file fails we mark the file as "delete-on-close"
-in a way that more servers accept, but only if we can first rename the
-file to a temporary name). Add experimental support for more safely
-handling fcntl(F_SETLEASE). Convert cifs to using blocking tcp
-sends, and also let tcp autotune the socket send and receive buffers.
-This reduces the number of EAGAIN errors returned by TCP/IP in
-high stress workloads (and the number of retries on socket writes
-when sending large SMBWriteX requests). Fix case in which a portion of
-data can in some cases not get written to the file on the server before the
-file is closed. Fix DFS parsing to properly handle path consumed field,
-and to handle certain codepage conversions better. Fix mount and
-umount race that can cause oops in mount or umount or reconnect.
-
-Version 1.54
-------------
-Fix premature write failure on congested networks (we would give up
-on EAGAIN from the socket too quickly on large writes).
-Cifs_mkdir and cifs_create now respect the setgid bit on parent dir.
-Fix endian problems in acl (mode from/to cifs acl) on bigendian
-architectures. Fix problems with preserving timestamps on copying open
-files (e.g. "cp -a") to Windows servers. For mkdir and create honor setgid bit
-on parent directory when server supports Unix Extensions but not POSIX
-create. Update cifs.upcall version to handle new Kerberos sec flags
-(this requires update of cifs.upcall program from Samba). Fix memory leak
-on dns_upcall (resolving DFS referralls). Fix plain text password
-authentication (requires setting SecurityFlags to 0x30030 to enable
-lanman and plain text though). Fix writes to be at correct offset when
-file is open with O_APPEND and file is on a directio (forcediretio) mount.
-Fix bug in rewinding readdir directory searches. Add nodfs mount option.
-
-Version 1.53
-------------
-DFS support added (Microsoft Distributed File System client support needed
-for referrals which enable a hierarchical name space among servers).
-Disable temporary caching of mode bits to servers which do not support
-storing of mode (e.g. Windows servers, when client mounts without cifsacl
-mount option) and add new "dynperm" mount option to enable temporary caching
-of mode (enable old behavior). Fix hang on mount caused when server crashes
-tcp session during negotiate protocol.
-
-Version 1.52
-------------
-Fix oops on second mount to server when null auth is used.
-Enable experimental Kerberos support. Return writebehind errors on flush
-and sync so that events like out of disk space get reported properly on
-cached files. Fix setxattr failure to certain Samba versions. Fix mount
-of second share to disconnected server session (autoreconnect on this).
-Add ability to modify cifs acls for handling chmod (when mounted with
-cifsacl flag). Fix prefixpath path separator so we can handle mounts
-with prefixpaths longer than one directory (one path component) when
-mounted to Windows servers. Fix slow file open when cifsacl
-enabled. Fix memory leak in FindNext when the SMB call returns -EBADF.
-
-
-Version 1.51
-------------
-Fix memory leak in statfs when mounted to very old servers (e.g.
-Windows 9x). Add new feature "POSIX open" which allows servers
-which support the current POSIX Extensions to provide better semantics
-(e.g. delete for open files opened with posix open). Take into
-account umask on posix mkdir not just older style mkdir. Add
-ability to mount to IPC$ share (which allows CIFS named pipes to be
-opened, read and written as if they were files). When 1st tree
-connect fails (e.g. due to signing negotiation failure) fix
-leak that causes cifsd not to stop and rmmod to fail to cleanup
-cifs_request_buffers pool. Fix problem with POSIX Open/Mkdir on
-bigendian architectures. Fix possible memory corruption when
-EAGAIN returned on kern_recvmsg. Return better error if server
-requires packet signing but client has disabled it. When mounted
-with cifsacl mount option - mode bits are approximated based
-on the contents of the ACL of the file or directory. When cifs
-mount helper is missing convert make sure that UNC name
-has backslash (not forward slash) between ip address of server
-and the share name.
-
-Version 1.50
-------------
-Fix NTLMv2 signing. NFS server mounted over cifs works (if cifs mount is
-done with "serverino" mount option). Add support for POSIX Unlink
-(helps with certain sharing violation cases when server such as
-Samba supports newer POSIX CIFS Protocol Extensions). Add "nounix"
-mount option to allow disabling the CIFS Unix Extensions for just
-that mount. Fix hang on spinlock in find_writable_file (race when
-reopening file after session crash). Byte range unlock request to
-windows server could unlock more bytes (on server copy of file)
-than intended if start of unlock request is well before start of
-a previous byte range lock that we issued.
-
-Version 1.49
-------------
-IPv6 support. Enable ipv6 addresses to be passed on mount (put the ipv6
-address after the "ip=" mount option, at least until mount.cifs is fixed to
-handle DNS host to ipv6 name translation). Accept override of uid or gid
-on mount even when Unix Extensions are negotiated (it used to be ignored
-when Unix Extensions were ignored). This allows users to override the
-default uid and gid for files when they are certain that the uids or
-gids on the server do not match those of the client. Make "sec=none"
-mount override username (so that null user connection is attempted)
-to match what documentation said. Support for very large reads, over 127K,
-available to some newer servers (such as Samba 3.0.26 and later but
-note that it also requires setting CIFSMaxBufSize at module install
-time to a larger value which may hurt performance in some cases).
-Make sign option force signing (or fail if server does not support it).
-
-Version 1.48
-------------
-Fix mtime bouncing around from local idea of last write times to remote time.
-Fix hang (in i_size_read) when simultaneous size update of same remote file
-on smp system corrupts sequence number. Do not reread unnecessarily partial page
-(which we are about to overwrite anyway) when writing out file opened rw.
-When DOS attribute of file on non-Unix server's file changes on the server side
-from read-only back to read-write, reflect this change in default file mode
-(we had been leaving a file's mode read-only until the inode were reloaded).
-Allow setting of attribute back to ATTR_NORMAL (removing readonly dos attribute
-when archive dos attribute not set and we are changing mode back to writeable
-on server which does not support the Unix Extensions). Remove read only dos
-attribute on chmod when adding any write permission (ie on any of
-user/group/other (not all of user/group/other ie 0222) when
-mounted to windows. Add support for POSIX MkDir (slight performance
-enhancement and eliminates the network race between the mkdir and set
-path info of the mode).
-
-
-Version 1.47
-------------
-Fix oops in list_del during mount caused by unaligned string.
-Fix file corruption which could occur on some large file
-copies caused by writepages page i/o completion bug.
-Seek to SEEK_END forces check for update of file size for non-cached
-files. Allow file size to be updated on remote extend of locally open,
-non-cached file. Fix reconnect to newer Samba servers (or other servers
-which support the CIFS Unix/POSIX extensions) so that we again tell the
-server the Unix/POSIX cifs capabilities which we support (SetFSInfo).
-Add experimental support for new POSIX Open/Mkdir (which returns
-stat information on the open, and allows setting the mode).
-
-Version 1.46
-------------
-Support deep tree mounts. Better support OS/2, Win9x (DOS) time stamps.
-Allow null user to be specified on mount ("username="). Do not return
-EINVAL on readdir when filldir fails due to overwritten blocksize
-(fixes FC problem). Return error in rename 2nd attempt retry (ie report
-if rename by handle also fails, after rename by path fails, we were
-not reporting whether the retry worked or not). Fix NTLMv2 to
-work to Windows servers (mount with option "sec=ntlmv2").
-
-Version 1.45
-------------
-Do not time out lockw calls when using posix extensions. Do not
-time out requests if server still responding reasonably fast
-on requests on other threads. Improve POSIX locking emulation,
-(lock cancel now works, and unlock of merged range works even
-to Windows servers now). Fix oops on mount to lanman servers
-(win9x, os/2 etc.) when null password. Do not send listxattr
-(SMB to query all EAs) if nouser_xattr specified. Fix SE Linux
-problem (instantiate inodes/dentries in right order for readdir).
-
-Version 1.44
-------------
-Rewritten sessionsetup support, including support for legacy SMB
-session setup needed for OS/2 and older servers such as Windows 95 and 98.
-Fix oops on ls to OS/2 servers. Add support for level 1 FindFirst
-so we can do search (ls etc.) to OS/2. Do not send NTCreateX
-or recent levels of FindFirst unless server says it supports NT SMBs
-(instead use legacy equivalents from LANMAN dialect). Fix to allow
-NTLMv2 authentication support (now can use stronger password hashing
-on mount if corresponding /proc/fs/cifs/SecurityFlags is set (0x4004).
-Allow override of global cifs security flags on mount via "sec=" option(s).
-
-Version 1.43
-------------
-POSIX locking to servers which support CIFS POSIX Extensions
-(disabled by default controlled by proc/fs/cifs/Experimental).
-Handle conversion of long share names (especially Asian languages)
-to Unicode during mount. Fix memory leak in sess struct on reconnect.
-Fix rare oops after acpi suspend. Fix O_TRUNC opens to overwrite on
-cifs open which helps rare case when setpathinfo fails or server does
-not support it.
-
-Version 1.42
-------------
-Fix slow oplock break when mounted to different servers at the same time and
-the tids match and we try to find matching fid on wrong server. Fix read
-looping when signing required by server (2.6.16 kernel only). Fix readdir
-vs. rename race which could cause each to hang. Return . and .. even
-if server does not. Allow searches to skip first three entries and
-begin at any location. Fix oops in find_writeable_file.
-
-Version 1.41
-------------
-Fix NTLMv2 security (can be enabled in /proc/fs/cifs) so customers can
-configure stronger authentication. Fix sfu symlinks so they can
-be followed (not just recognized). Fix wraparound of bcc on
-read responses when buffer size over 64K and also fix wrap of
-max smb buffer size when CIFSMaxBufSize over 64K. Fix oops in
-cifs_user_read and cifs_readpages (when EAGAIN on send of smb
-on socket is returned over and over). Add POSIX (advisory) byte range
-locking support (requires server with newest CIFS UNIX Extensions
-to the protocol implemented). Slow down negprot slightly in port 139
-RFC1001 case to give session_init time on buggy servers.
-
-Version 1.40
-------------
-Use fsuid (fsgid) more consistently instead of uid (gid). Improve performance
-of readpages by eliminating one extra memcpy. Allow update of file size
-from remote server even if file is open for write as long as mount is
-directio. Recognize share mode security and send NTLM encrypted password
-on tree connect if share mode negotiated.
-
-Version 1.39
-------------
-Defer close of a file handle slightly if pending writes depend on that handle
-(this reduces the EBADF bad file handle errors that can be logged under heavy
-stress on writes). Modify cifs Kconfig options to expose CONFIG_CIFS_STATS2
-Fix SFU style symlinks and mknod needed for servers which do not support the
-CIFS Unix Extensions. Fix setfacl/getfacl on bigendian. Timeout negative
-dentries so files that the client sees as deleted but that later get created
-on the server will be recognized. Add client side permission check on setattr.
-Timeout stuck requests better (where server has never responded or sent corrupt
-responses)
-
-Version 1.38
-------------
-Fix tcp socket retransmission timeouts (e.g. on ENOSPACE from the socket)
-to be smaller at first (but increasing) so large write performance performance
-over GigE is better. Do not hang thread on illegal byte range lock response
-from Windows (Windows can send an RFC1001 size which does not match smb size) by
-allowing an SMBs TCP length to be up to a few bytes longer than it should be.
-wsize and rsize can now be larger than negotiated buffer size if server
-supports large readx/writex, even when directio mount flag not specified.
-Write size will in many cases now be 16K instead of 4K which greatly helps
-file copy performance on lightly loaded networks. Fix oops in dnotify
-when experimental config flag enabled. Make cifsFYI more granular.
-
-Version 1.37
-------------
-Fix readdir caching when unlink removes file in current search buffer,
-and this is followed by a rewind search to just before the deleted entry.
-Do not attempt to set ctime unless atime and/or mtime change requested
-(most servers throw it away anyway). Fix length check of received smbs
-to be more accurate. Fix big endian problem with mapchars mount option,
-and with a field returned by statfs.
-
-Version 1.36
-------------
-Add support for mounting to older pre-CIFS servers such as Windows9x and ME.
-For these older servers, add option for passing netbios name of server in
-on mount (servernetbiosname). Add suspend support for power management, to
-avoid cifsd thread preventing software suspend from working.
-Add mount option for disabling the default behavior of sending byte range lock
-requests to the server (necessary for certain applications which break with
-mandatory lock behavior such as Evolution), and also mount option for
-requesting case insensitive matching for path based requests (requesting
-case sensitive is the default).
-
-Version 1.35
-------------
-Add writepage performance improvements. Fix path name conversions
-for long filenames on mounts which were done with "mapchars" mount option
-specified. Ensure multiplex ids do not collide. Fix case in which
-rmmod can oops if done soon after last unmount. Fix truncated
-search (readdir) output when resume filename was a long filename.
-Fix filename conversion when mapchars mount option was specified and
-filename was a long filename.
-
-Version 1.34
-------------
-Fix error mapping of the TOO_MANY_LINKS (hardlinks) case.
-Do not oops if root user kills cifs oplock kernel thread or
-kills the cifsd thread (NB: killing the cifs kernel threads is not
-recommended, unmount and rmmod cifs will kill them when they are
-no longer needed). Fix readdir to ASCII servers (ie older servers
-which do not support Unicode) and also require asterisk.
-Fix out of memory case in which data could be written one page
-off in the page cache.
-
-Version 1.33
-------------
-Fix caching problem, in which readdir of directory containing a file
-which was cached could cause the file's time stamp to be updated
-without invalidating the readahead data (so we could get stale
-file data on the client for that file even as the server copy changed).
-Cleanup response processing so cifsd can not loop when abnormally
-terminated.
-
-
-Version 1.32
-------------
-Fix oops in ls when Transact2 FindFirst (or FindNext) returns more than one
-transact response for an SMB request and search entry split across two frames.
-Add support for lsattr (getting ext2/ext3/reiserfs attr flags from the server)
-as new protocol extensions. Do not send Get/Set calls for POSIX ACLs
-unless server explicitly claims to support them in CIFS Unix extensions
-POSIX ACL capability bit. Fix packet signing when multiuser mounting with
-different users from the same client to the same server. Fix oops in
-cifs_close. Add mount option for remapping reserved characters in
-filenames (also allow recognizing files with created by SFU which have any
-of these seven reserved characters, except backslash, to be recognized).
-Fix invalid transact2 message (we were sometimes trying to interpret
-oplock breaks as SMB responses). Add ioctl for checking that the
-current uid matches the uid of the mounter (needed by umount.cifs).
-Reduce the number of large buffer allocations in cifs response processing
-(significantly reduces memory pressure under heavy stress with multiple
-processes accessing the same server at the same time).
-
-Version 1.31
-------------
-Fix updates of DOS attributes and time fields so that files on NT4 servers
-do not get marked delete on close. Display sizes of cifs buffer pools in
-cifs stats. Fix oops in unmount when cifsd thread being killed by
-shutdown. Add generic readv/writev and aio support. Report inode numbers
-consistently in readdir and lookup (when serverino mount option is
-specified use the inode number that the server reports - for both lookup
-and readdir, otherwise by default the locally generated inode number is used
-for inodes created in either path since servers are not always able to
-provide unique inode numbers when exporting multiple volumes from under one
-sharename).
-
-Version 1.30
-------------
-Allow new nouser_xattr mount parm to disable xattr support for user namespace.
-Do not flag user_xattr mount parm in dmesg. Retry failures setting file time
-(mostly affects NT4 servers) by retry with handle based network operation.
-Add new POSIX Query FS Info for returning statfs info more accurately.
-Handle passwords with multiple commas in them.
-
-Version 1.29
-------------
-Fix default mode in sysfs of cifs module parms. Remove old readdir routine.
-Fix capabilities flags for large readx so as to allow reads larger than 64K.
-
-Version 1.28
-------------
-Add module init parm for large SMB buffer size (to allow it to be changed
-from its default of 16K) which is especially useful for large file copy
-when mounting with the directio mount option. Fix oops after
-returning from mount when experimental ExtendedSecurity enabled and
-SpnegoNegotiated returning invalid error. Fix case to retry better when
-peek returns from 1 to 3 bytes on socket which should have more data.
-Fixed path based calls (such as cifs lookup) to handle path names
-longer than 530 (now can handle PATH_MAX). Fix pass through authentication
-from Samba server to DC (Samba required dummy LM password).
-
-Version 1.27
-------------
-Turn off DNOTIFY (directory change notification support) by default
-(unless built with the experimental flag) to fix hang with KDE
-file browser. Fix DNOTIFY flag mappings. Fix hang (in wait_event
-waiting on an SMB response) in SendReceive when session dies but
-reconnects quickly from another task. Add module init parms for
-minimum number of large and small network buffers in the buffer pools,
-and for the maximum number of simultaneous requests.
-
-Version 1.26
-------------
-Add setfacl support to allow setting of ACLs remotely to Samba 3.10 and later
-and other POSIX CIFS compliant servers. Fix error mapping for getfacl
-to EOPNOTSUPP when server does not support posix acls on the wire. Fix
-improperly zeroed buffer in CIFS Unix extensions set times call.
-
-Version 1.25
-------------
-Fix internationalization problem in cifs readdir with filenames that map to
-longer UTF-8 strings than the string on the wire was in Unicode. Add workaround
-for readdir to netapp servers. Fix search rewind (seek into readdir to return
-non-consecutive entries). Do not do readdir when server negotiates
-buffer size to small to fit filename. Add support for reading POSIX ACLs from
-the server (add also acl and noacl mount options).
-
-Version 1.24
-------------
-Optionally allow using server side inode numbers, rather than client generated
-ones by specifying mount option "serverino" - this is required for some apps
-to work which double check hardlinked files and have persistent inode numbers.
-
-Version 1.23
-------------
-Multiple bigendian fixes. On little endian systems (for reconnect after
-network failure) fix tcp session reconnect code so we do not try first
-to reconnect on reverse of port 445. Treat reparse points (NTFS junctions)
-as directories rather than symlinks because we can do follow link on them.
-
-Version 1.22
-------------
-Add config option to enable XATTR (extended attribute) support, mapping
-xattr names in the "user." namespace space to SMB/CIFS EAs. Lots of
-minor fixes pointed out by the Stanford SWAT checker (mostly missing
-or out of order NULL pointer checks in little used error paths).
-
-Version 1.21
-------------
-Add new mount parm to control whether mode check (generic_permission) is done
-on the client. If Unix extensions are enabled and the uids on the client
-and server do not match, client permission checks are meaningless on
-server uids that do not exist on the client (this does not affect the
-normal ACL check which occurs on the server). Fix default uid
-on mknod to match create and mkdir. Add optional mount parm to allow
-override of the default uid behavior (in which the server sets the uid
-and gid of newly created files). Normally for network filesystem mounts
-user want the server to set the uid/gid on newly created files (rather than
-using uid of the client processes you would in a local filesystem).
-
-Version 1.20
-------------
-Make transaction counts more consistent. Merge /proc/fs/cifs/SimultaneousOps
-info into /proc/fs/cifs/DebugData. Fix oops in rare oops in readdir
-(in build_wildcard_path_from_dentry). Fix mknod to pass type field
-(block/char/fifo) properly. Remove spurious mount warning log entry when
-credentials passed as mount argument. Set major/minor device number in
-inode for block and char devices when unix extensions enabled.
-
-Version 1.19
-------------
-Fix /proc/fs/cifs/Stats and DebugData display to handle larger
-amounts of return data. Properly limit requests to MAX_REQ (50
-is the usual maximum active multiplex SMB/CIFS requests per server).
-Do not kill cifsd (and thus hurt the other SMB session) when more than one
-session to the same server (but with different userids) exists and one
-of the two user's smb sessions is being removed while leaving the other.
-Do not loop reconnecting in cifsd demultiplex thread when admin
-kills the thread without going through unmount.
-
-Version 1.18
-------------
-Do not rename hardlinked files (since that should be a noop). Flush
-cached write behind data when reopening a file after session abend,
-except when already in write. Grab per socket sem during reconnect
-to avoid oops in sendmsg if overlapping with reconnect. Do not
-reset cached inode file size on readdir for files open for write on
-client.
-
-
-Version 1.17
-------------
-Update number of blocks in file so du command is happier (in Linux a fake
-blocksize of 512 is required for calculating number of blocks in inode).
-Fix prepare write of partial pages to read in data from server if possible.
-Fix race on tcpStatus field between unmount and reconnection code, causing
-cifsd process sometimes to hang around forever. Improve out of memory
-checks in cifs_filldir
-
-Version 1.16
-------------
-Fix incorrect file size in file handle based setattr on big endian hardware.
-Fix oops in build_path_from_dentry when out of memory. Add checks for invalid
-and closing file structs in writepage/partialpagewrite. Add statistics
-for each mounted share (new menuconfig option). Fix endianness problem in
-volume information displayed in /proc/fs/cifs/DebugData (only affects
-affects big endian architectures). Prevent renames while constructing
-path names for open, mkdir and rmdir.
-
-Version 1.15
-------------
-Change to mempools for alloc smb request buffers and multiplex structs
-to better handle low memory problems (and potential deadlocks).
-
-Version 1.14
-------------
-Fix incomplete listings of large directories on Samba servers when Unix
-extensions enabled. Fix oops when smb_buffer can not be allocated. Fix
-rename deadlock when writing out dirty pages at same time.
-
-Version 1.13
-------------
-Fix open of files in which O_CREATE can cause the mode to change in
-some cases. Fix case in which retry of write overlaps file close.
-Fix PPC64 build error. Reduce excessive stack usage in smb password
-hashing. Fix overwrite of Linux user's view of file mode to Windows servers.
-
-Version 1.12
-------------
-Fixes for large file copy, signal handling, socket retry, buffer
-allocation and low memory situations.
-
-Version 1.11
-------------
-Better port 139 support to Windows servers (RFC1001/RFC1002 Session_Initialize)
-also now allowing support for specifying client netbiosname. NT4 support added.
-
-Version 1.10
-------------
-Fix reconnection (and certain failed mounts) to properly wake up the
-blocked users thread so it does not seem hung (in some cases was blocked
-until the cifs receive timeout expired). Fix spurious error logging
-to kernel log when application with open network files killed.
-
-Version 1.09
-------------
-Fix /proc/fs module unload warning message (that could be logged
-to the kernel log). Fix intermittent failure in connectathon
-test7 (hardlink count not immediately refreshed in case in which
-inode metadata can be incorrectly kept cached when time near zero)
-
-Version 1.08
-------------
-Allow file_mode and dir_mode (specified at mount time) to be enforced
-locally (the server already enforced its own ACLs too) for servers
-that do not report the correct mode (do not support the
-CIFS Unix Extensions).
-
-Version 1.07
-------------
-Fix some small memory leaks in some unmount error paths. Fix major leak
-of cache pages in readpages causing multiple read oriented stress
-testcases (including fsx, and even large file copy) to fail over time.
-
-Version 1.06
-------------
-Send NTCreateX with ATTR_POSIX if Linux/Unix extensions negotiated with server.
-This allows files that differ only in case and improves performance of file
-creation and file open to such servers. Fix semaphore conflict which causes
-slow delete of open file to Samba (which unfortunately can cause an oplock
-break to self while vfs_unlink held i_sem) which can hang for 20 seconds.
-
-Version 1.05
-------------
-fixes to cifs_readpages for fsx test case
-
-Version 1.04
-------------
-Fix caching data integrity bug when extending file size especially when no
-oplock on file. Fix spurious logging of valid already parsed mount options
-that are parsed outside of the cifs vfs such as nosuid.
-
-
-Version 1.03
-------------
-Connect to server when port number override not specified, and tcp port
-unitialized. Reset search to restart at correct file when kernel routine
-filldir returns error during large directory searches (readdir).
-
-Version 1.02
-------------
-Fix caching problem when files opened by multiple clients in which
-page cache could contain stale data, and write through did
-not occur often enough while file was still open when read ahead
-(read oplock) not allowed. Treat "sep=" when first mount option
-as an override of comma as the default separator between mount
-options.
-
-Version 1.01
-------------
-Allow passwords longer than 16 bytes. Allow null password string.
-
-Version 1.00
-------------
-Gracefully clean up failed mounts when attempting to mount to servers such as
-Windows 98 that terminate tcp sessions during protocol negotiation. Handle
-embedded commas in mount parsing of passwords.
-
-Version 0.99
-------------
-Invalidate local inode cached pages on oplock break and when last file
-instance is closed so that the client does not continue using stale local
-copy rather than later modified server copy of file. Do not reconnect
-when server drops the tcp session prematurely before negotiate
-protocol response. Fix oops in reopen_file when dentry freed. Allow
-the support for CIFS Unix Extensions to be disabled via proc interface.
-
-Version 0.98
-------------
-Fix hang in commit_write during reconnection of open files under heavy load.
-Fix unload_nls oops in a mount failure path. Serialize writes to same socket
-which also fixes any possible races when cifs signatures are enabled in SMBs
-being sent out of signature sequence number order.
-
-Version 0.97
-------------
-Fix byte range locking bug (endian problem) causing bad offset and
-length.
-
-Version 0.96
-------------
-Fix oops (in send_sig) caused by CIFS unmount code trying to
-wake up the demultiplex thread after it had exited. Do not log
-error on harmless oplock release of closed handle.
-
-Version 0.95
-------------
-Fix unsafe global variable usage and password hash failure on gcc 3.3.1
-Fix problem reconnecting secondary mounts to same server after session
-failure. Fix invalid dentry - race in mkdir when directory gets created
-by another client between the lookup and mkdir.
-
-Version 0.94
-------------
-Fix to list processing in reopen_files. Fix reconnection when server hung
-but tcpip session still alive. Set proper timeout on socket read.
-
-Version 0.93
-------------
-Add missing mount options including iocharset. SMP fixes in write and open.
-Fix errors in reconnecting after TCP session failure. Fix module unloading
-of default nls codepage
-
-Version 0.92
-------------
-Active smb transactions should never go negative (fix double FreeXid). Fix
-list processing in file routines. Check return code on kmalloc in open.
-Fix spinlock usage for SMP.
-
-Version 0.91
-------------
-Fix oops in reopen_files when invalid dentry. drop dentry on server rename
-and on revalidate errors. Fix cases where pid is now tgid. Fix return code
-on create hard link when server does not support them.
-
-Version 0.90
-------------
-Fix scheduling while atomic error in getting inode info on newly created file.
-Fix truncate of existing files opened with O_CREAT but not O_TRUNC set.
-
-Version 0.89
-------------
-Fix oops on write to dead tcp session. Remove error log write for case when file open
-O_CREAT but not O_EXCL
-
-Version 0.88
-------------
-Fix non-POSIX behavior on rename of open file and delete of open file by taking
-advantage of trans2 SetFileInfo rename facility if available on target server.
-Retry on ENOSPC and EAGAIN socket errors.
-
-Version 0.87
-------------
-Fix oops on big endian readdir. Set blksize to be even power of two (2**blkbits) to fix
-allocation size miscalculation. After oplock token lost do not read through
-cache.
-
-Version 0.86
-------------
-Fix oops on empty file readahead. Fix for file size handling for locally cached files.
-
-Version 0.85
-------------
-Fix oops in mkdir when server fails to return inode info. Fix oops in reopen_files
-during auto reconnection to server after server recovered from failure.
-
-Version 0.84
-------------
-Finish support for Linux 2.5 open/create changes, which removes the
-redundant NTCreate/QPathInfo/close that was sent during file create.
-Enable oplock by default. Enable packet signing by default (needed to
-access many recent Windows servers)
-
-Version 0.83
-------------
-Fix oops when mounting to long server names caused by inverted parms to kmalloc.
-Fix MultiuserMount (/proc/fs/cifs configuration setting) so that when enabled
-we will choose a cifs user session (smb uid) that better matches the local
-uid if a) the mount uid does not match the current uid and b) we have another
-session to the same server (ip address) for a different mount which
-matches the current local uid.
-
-Version 0.82
-------------
-Add support for mknod of block or character devices. Fix oplock
-code (distributed caching) to properly send response to oplock
-break from server.
-
-Version 0.81
-------------
-Finish up CIFS packet digital signing for the default
-NTLM security case. This should help Windows 2003
-network interoperability since it is common for
-packet signing to be required now. Fix statfs (stat -f)
-which recently started returning errors due to
-invalid value (-1 instead of 0) being set in the
-struct kstatfs f_ffiles field.
-
-Version 0.80
------------
-Fix oops on stopping oplock thread when removing cifs when
-built as module.
-
-Version 0.79
-------------
-Fix mount options for ro (readonly), uid, gid and file and directory mode.
-
-Version 0.78
-------------
-Fix errors displayed on failed mounts to be more understandable.
-Fixed various incorrect or misleading smb to posix error code mappings.
-
-Version 0.77
-------------
-Fix display of NTFS DFS junctions to display as symlinks.
-They are the network equivalent. Fix oops in
-cifs_partialpagewrite caused by missing spinlock protection
-of openfile linked list. Allow writebehind caching errors to
-be returned to the application at file close.
-
-Version 0.76
-------------
-Clean up options displayed in /proc/mounts by show_options to
-be more consistent with other filesystems.
-
-Version 0.75
-------------
-Fix delete of readonly file to Windows servers. Reflect
-presence or absence of read only dos attribute in mode
-bits for servers that do not support CIFS Unix extensions.
-Fix shortened results on readdir of large directories to
-servers supporting CIFS Unix extensions (caused by
-incorrect resume key).
-
-Version 0.74
-------------
-Fix truncate bug (set file size) that could cause hangs e.g. running fsx
-
-Version 0.73
-------------
-unload nls if mount fails.
-
-Version 0.72
-------------
-Add resume key support to search (readdir) code to workaround
-Windows bug. Add /proc/fs/cifs/LookupCacheEnable which
-allows disabling caching of attribute information for
-lookups.
-
-Version 0.71
-------------
-Add more oplock handling (distributed caching code). Remove
-dead code. Remove excessive stack space utilization from
-symlink routines.
-
-Version 0.70
-------------
-Fix oops in get dfs referral (triggered when null path sent in to
-mount). Add support for overriding rsize at mount time.
-
-Version 0.69
-------------
-Fix buffer overrun in readdir which caused intermittent kernel oopses.
-Fix writepage code to release kmap on write data. Allow "-ip=" new
-mount option to be passed in on parameter distinct from the first part
-(server name portion of) the UNC name. Allow override of the
-tcp port of the target server via new mount option "-port="
-
-Version 0.68
-------------
-Fix search handle leak on rewind. Fix setuid and gid so that they are
-reflected in the local inode immediately. Cleanup of whitespace
-to make 2.4 and 2.5 versions more consistent.
-
-
-Version 0.67
-------------
-Fix signal sending so that captive thread (cifsd) exits on umount
-(which was causing the warning in kmem_cache_free of the request buffers
-at rmmod time). This had broken as a sideeffect of the recent global
-kernel change to daemonize. Fix memory leak in readdir code which
-showed up in "ls -R" (and applications that did search rewinding).
-
-Version 0.66
-------------
-Reconnect tids and fids after session reconnection (still do not
-reconnect byte range locks though). Fix problem caching
-lookup information for directory inodes, improving performance,
-especially in deep directory trees. Fix various build warnings.
-
-Version 0.65
-------------
-Finish fixes to commit write for caching/readahead consistency. fsx
-now works to Samba servers. Fix oops caused when readahead
-was interrupted by a signal.
-
-Version 0.64
-------------
-Fix data corruption (in partial page after truncate) that caused fsx to
-fail to Windows servers. Cleaned up some extraneous error logging in
-common error paths. Add generic sendfile support.
-
-Version 0.63
-------------
-Fix memory leak in AllocMidQEntry.
-Finish reconnection logic, so connection with server can be dropped
-(or server rebooted) and the cifs client will reconnect.
-
-Version 0.62
-------------
-Fix temporary socket leak when bad userid or password specified
-(or other SMBSessSetup failure). Increase maximum buffer size to slightly
-over 16K to allow negotiation of up to Samba and Windows server default read
-sizes. Add support for readpages
-
-Version 0.61
-------------
-Fix oops when username not passed in on mount. Extensive fixes and improvements
-to error logging (strip redundant newlines, change debug macros to ensure newline
-passed in and to be more consistent). Fix writepage wrong file handle problem,
-a readonly file handle could be incorrectly used to attempt to write out
-file updates through the page cache to multiply open files. This could cause
-the iozone benchmark to fail on the fwrite test. Fix bug mounting two different
-shares to the same Windows server when using different usernames
-(doing this to Samba servers worked but Windows was rejecting it) - now it is
-possible to use different userids when connecting to the same server from a
-Linux client. Fix oops when treeDisconnect called during unmount on
-previously freed socket.
-
-Version 0.60
-------------
-Fix oops in readpages caused by not setting address space operations in inode in
-rare code path.
-
-Version 0.59
-------------
-Includes support for deleting of open files and renaming over existing files (per POSIX
-requirement). Add readlink support for Windows junction points (directory symlinks).
-
-Version 0.58
-------------
-Changed read and write to go through pagecache. Added additional address space operations.
-Memory mapped operations now working.
-
-Version 0.57
-------------
-Added writepage code for additional memory mapping support. Fixed leak in xids causing
-the simultaneous operations counter (/proc/fs/cifs/SimultaneousOps) to increase on
-every stat call. Additional formatting cleanup.
-
-Version 0.56
-------------
-Fix bigendian bug in order of time conversion. Merge 2.5 to 2.4 version. Formatting cleanup.
-
-Version 0.55
-------------
-Fixes from Zwane Mwaikambo for adding missing return code checking in a few places.
-Also included a modified version of his fix to protect global list manipulation of
-the smb session and tree connection and mid related global variables.
-
-Version 0.54
-------------
-Fix problem with captive thread hanging around at unmount time. Adjust to 2.5.42-pre
-changes to superblock layout. Remove wasteful allocation of smb buffers (now the send
-buffer is reused for responses). Add more oplock handling. Additional minor cleanup.
-
-Version 0.53
-------------
-More stylistic updates to better match kernel style. Add additional statistics
-for filesystem which can be viewed via /proc/fs/cifs. Add more pieces of NTLMv2
-and CIFS Packet Signing enablement.
-
-Version 0.52
-------------
-Replace call to sleep_on with safer wait_on_event.
-Make stylistic changes to better match kernel style recommendations.
-Remove most typedef usage (except for the PDUs themselves).
-
-Version 0.51
-------------
-Update mount so the -unc mount option is no longer required (the ip address can be specified
-in a UNC style device name. Implementation of readpage/writepage started.
-
-Version 0.50
-------------
-Fix intermittent problem with incorrect smb header checking on badly
-fragmented tcp responses
-
-Version 0.49
-------------
-Fixes to setting of allocation size and file size.
-
-Version 0.48
-------------
-Various 2.5.38 fixes. Now works on 2.5.38
-
-Version 0.47
-------------
-Prepare for 2.5 kernel merge. Remove ifdefs.
-
-Version 0.46
-------------
-Socket buffer management fixes. Fix dual free.
-
-Version 0.45
-------------
-Various big endian fixes for hardlinks and symlinks and also for dfs.
-
-Version 0.44
-------------
-Various big endian fixes for servers with Unix extensions such as Samba
-
-Version 0.43
-------------
-Various FindNext fixes for incorrect filenames on large directory searches on big endian
-clients. basic posix file i/o tests now work on big endian machines, not just le
-
-Version 0.42
-------------
-SessionSetup and NegotiateProtocol now work from Big Endian machines.
-Various Big Endian fixes found during testing on the Linux on 390. Various fixes for compatibility with older
-versions of 2.4 kernel (now builds and works again on kernels at least as early as 2.4.7).
-
-Version 0.41
-------------
-Various minor fixes for Connectathon Posix "basic" file i/o test suite. Directory caching fixed so hardlinked
-files now return the correct number of links on fstat as they are repeatedly linked and unlinked.
-
-Version 0.40
-------------
-Implemented "Raw" (i.e. not encapsulated in SPNEGO) NTLMSSP (i.e. the Security Provider Interface used to negotiate
-session advanced session authentication). Raw NTLMSSP is preferred by Windows 2000 Professional and Windows XP.
-Began implementing support for SPNEGO encapsulation of NTLMSSP based session authentication blobs
-(which is the mechanism preferred by Windows 2000 server in the absence of Kerberos).
-
-Version 0.38
-------------
-Introduced optional mount helper utility mount.cifs and made coreq changes to cifs vfs to enable
-it. Fixed a few bugs in the DFS code (e.g. bcc two bytes too short and incorrect uid in PDU).
-
-Version 0.37
-------------
-Rewrote much of connection and mount/unmount logic to handle bugs with
-multiple uses to same share, multiple users to same server etc.
-
-Version 0.36
-------------
-Fixed major problem with dentry corruption (missing call to dput)
-
-Version 0.35
-------------
-Rewrite of readdir code to fix bug. Various fixes for bigendian machines.
-Begin adding oplock support. Multiusermount and oplockEnabled flags added to /proc/fs/cifs
-although corresponding function not fully implemented in the vfs yet
-
-Version 0.34
-------------
-Fixed dentry caching bug, misc. cleanup
-
-Version 0.33
-------------
-Fixed 2.5 support to handle build and configure changes as well as misc. 2.5 changes. Now can build
-on current 2.5 beta version (2.5.24) of the Linux kernel as well as on 2.4 Linux kernels.
-Support for STATUS codes (newer 32 bit NT error codes) added. DFS support begun to be added.
-
-Version 0.32
-------------
-Unix extensions (symlink, readlink, hardlink, chmod and some chgrp and chown) implemented
-and tested against Samba 2.2.5
-
-
-Version 0.31
-------------
-1) Fixed lockrange to be correct (it was one byte too short)
-
-2) Fixed GETLK (i.e. the fcntl call to test a range of bytes in a file to see if locked) to correctly
-show range as locked when there is a conflict with an existing lock.
-
-3) default file perms are now 2767 (indicating support for mandatory locks) instead of 777 for directories
-in most cases. Eventually will offer optional ability to query server for the correct perms.
-
-3) Fixed eventual trap when mounting twice to different shares on the same server when the first succeeded
-but the second one was invalid and failed (the second one was incorrectly disconnecting the tcp and smb
-session)
-
-4) Fixed error logging of valid mount options
-
-5) Removed logging of password field.
-
-6) Moved negotiate, treeDisconnect and uloggoffX (only tConx and SessSetup remain in connect.c) to cifssmb.c
-and cleaned them up and made them more consistent with other cifs functions.
-
-7) Server support for Unix extensions is now fully detected and FindFirst is implemented both ways
-(with or without Unix extensions) but FindNext and QueryPathInfo with the Unix extensions are not completed,
-nor is the symlink support using the Unix extensions
-
-8) Started adding the readlink and follow_link code
-
-Version 0.3
------------
-Initial drop
-
diff --git a/ANDROID_3.4.5/fs/cifs/Kconfig b/ANDROID_3.4.5/fs/cifs/Kconfig
deleted file mode 100644
index 2b243af7..00000000
--- a/ANDROID_3.4.5/fs/cifs/Kconfig
+++ /dev/null
@@ -1,160 +0,0 @@
-config CIFS
- tristate "CIFS support (advanced network filesystem, SMBFS successor)"
- depends on INET
- select NLS
- select CRYPTO
- select CRYPTO_MD4
- select CRYPTO_MD5
- select CRYPTO_HMAC
- select CRYPTO_ARC4
- select CRYPTO_ECB
- select CRYPTO_DES
- help
- This is the client VFS module for the Common Internet File System
- (CIFS) protocol which is the successor to the Server Message Block
- (SMB) protocol, the native file sharing mechanism for most early
- PC operating systems. The CIFS protocol is fully supported by
- file servers such as Windows 2000 (including Windows 2003, NT 4
- and Windows XP) as well by Samba (which provides excellent CIFS
- server support for Linux and many other operating systems). Limited
- support for OS/2 and Windows ME and similar servers is provided as
- well.
-
- The cifs module provides an advanced network file system
- client for mounting to CIFS compliant servers. It includes
- support for DFS (hierarchical name space), secure per-user
- session establishment via Kerberos or NTLM or NTLMv2,
- safe distributed caching (oplock), optional packet
- signing, Unicode and other internationalization improvements.
- If you need to mount to Samba or Windows from this machine, say Y.
-
-config CIFS_STATS
- bool "CIFS statistics"
- depends on CIFS
- help
- Enabling this option will cause statistics for each server share
- mounted by the cifs client to be displayed in /proc/fs/cifs/Stats
-
-config CIFS_STATS2
- bool "Extended statistics"
- depends on CIFS_STATS
- help
- Enabling this option will allow more detailed statistics on SMB
- request timing to be displayed in /proc/fs/cifs/DebugData and also
- allow optional logging of slow responses to dmesg (depending on the
- value of /proc/fs/cifs/cifsFYI, see fs/cifs/README for more details).
- These additional statistics may have a minor effect on performance
- and memory utilization.
-
- Unless you are a developer or are doing network performance analysis
- or tuning, say N.
-
-config CIFS_WEAK_PW_HASH
- bool "Support legacy servers which use weaker LANMAN security"
- depends on CIFS
- help
- Modern CIFS servers including Samba and most Windows versions
- (since 1997) support stronger NTLM (and even NTLMv2 and Kerberos)
- security mechanisms. These hash the password more securely
- than the mechanisms used in the older LANMAN version of the
- SMB protocol but LANMAN based authentication is needed to
- establish sessions with some old SMB servers.
-
- Enabling this option allows the cifs module to mount to older
- LANMAN based servers such as OS/2 and Windows 95, but such
- mounts may be less secure than mounts using NTLM or more recent
- security mechanisms if you are on a public network. Unless you
- have a need to access old SMB servers (and are on a private
- network) you probably want to say N. Even if this support
- is enabled in the kernel build, LANMAN authentication will not be
- used automatically. At runtime LANMAN mounts are disabled but
- can be set to required (or optional) either in
- /proc/fs/cifs (see fs/cifs/README for more detail) or via an
- option on the mount command. This support is disabled by
- default in order to reduce the possibility of a downgrade
- attack.
-
- If unsure, say N.
-
-config CIFS_UPCALL
- bool "Kerberos/SPNEGO advanced session setup"
- depends on CIFS && KEYS
- select DNS_RESOLVER
- help
- Enables an upcall mechanism for CIFS which accesses userspace helper
- utilities to provide SPNEGO packaged (RFC 4178) Kerberos tickets
- which are needed to mount to certain secure servers (for which more
- secure Kerberos authentication is required). If unsure, say N.
-
-config CIFS_XATTR
- bool "CIFS extended attributes"
- depends on CIFS
- help
- Extended attributes are name:value pairs associated with inodes by
- the kernel or by users (see the attr(5) manual page, or visit
- <http://acl.bestbits.at/> for details). CIFS maps the name of
- extended attributes beginning with the user namespace prefix
- to SMB/CIFS EAs. EAs are stored on Windows servers without the
- user namespace prefix, but their names are seen by Linux cifs clients
- prefaced by the user namespace prefix. The system namespace
- (used by some filesystems to store ACLs) is not supported at
- this time.
-
- If unsure, say N.
-
-config CIFS_POSIX
- bool "CIFS POSIX Extensions"
- depends on CIFS_XATTR
- help
- Enabling this option will cause the cifs client to attempt to
- negotiate a newer dialect with servers, such as Samba 3.0.5
- or later, that optionally can handle more POSIX like (rather
- than Windows like) file behavior. It also enables
- support for POSIX ACLs (getfacl and setfacl) to servers
- (such as Samba 3.10 and later) which can negotiate
- CIFS POSIX ACL support. If unsure, say N.
-
-config CIFS_DEBUG2
- bool "Enable additional CIFS debugging routines"
- depends on CIFS
- help
- Enabling this option adds a few more debugging routines
- to the cifs code which slightly increases the size of
- the cifs module and can cause additional logging of debug
- messages in some error paths, slowing performance. This
- option can be turned off unless you are debugging
- cifs problems. If unsure, say N.
-
-config CIFS_DFS_UPCALL
- bool "DFS feature support"
- depends on CIFS && KEYS
- select DNS_RESOLVER
- help
- Distributed File System (DFS) support is used to access shares
- transparently in an enterprise name space, even if the share
- moves to a different server. This feature also enables
- an upcall mechanism for CIFS which contacts userspace helper
- utilities to provide server name resolution (host names to
- IP addresses) which is needed for implicit mounts of DFS junction
- points. If unsure, say N.
-
-config CIFS_FSCACHE
- bool "Provide CIFS client caching support"
- depends on CIFS=m && FSCACHE || CIFS=y && FSCACHE=y
- help
- Makes CIFS FS-Cache capable. Say Y here if you want your CIFS data
- to be cached locally on disk through the general filesystem cache
- manager. If unsure, say N.
-
-config CIFS_ACL
- bool "Provide CIFS ACL support"
- depends on CIFS_XATTR && KEYS
- help
- Allows to fetch CIFS/NTFS ACL from the server. The DACL blob
- is handed over to the application/caller.
-
-config CIFS_NFSD_EXPORT
- bool "Allow nfsd to export CIFS file system (EXPERIMENTAL)"
- depends on CIFS && EXPERIMENTAL && BROKEN
- help
- Allows NFS server to export a CIFS mounted share (nfsd over cifs)
diff --git a/ANDROID_3.4.5/fs/cifs/Makefile b/ANDROID_3.4.5/fs/cifs/Makefile
deleted file mode 100644
index 005d524c..00000000
--- a/ANDROID_3.4.5/fs/cifs/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# Makefile for Linux CIFS VFS client
-#
-obj-$(CONFIG_CIFS) += cifs.o
-
-cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \
- link.o misc.o netmisc.o smbencrypt.o transport.o asn1.o \
- cifs_unicode.o nterr.o xattr.o cifsencrypt.o \
- readdir.o ioctl.o sess.o export.o
-
-cifs-$(CONFIG_CIFS_ACL) += cifsacl.o
-
-cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o
-
-cifs-$(CONFIG_CIFS_DFS_UPCALL) += dns_resolve.o cifs_dfs_ref.o
-
-cifs-$(CONFIG_CIFS_FSCACHE) += fscache.o cache.o
diff --git a/ANDROID_3.4.5/fs/cifs/README b/ANDROID_3.4.5/fs/cifs/README
deleted file mode 100644
index b7d782ba..00000000
--- a/ANDROID_3.4.5/fs/cifs/README
+++ /dev/null
@@ -1,758 +0,0 @@
-The CIFS VFS support for Linux supports many advanced network filesystem
-features such as hierarchical dfs like namespace, hardlinks, locking and more.
-It was designed to comply with the SNIA CIFS Technical Reference (which
-supersedes the 1992 X/Open SMB Standard) as well as to perform best practice
-practical interoperability with Windows 2000, Windows XP, Samba and equivalent
-servers. This code was developed in participation with the Protocol Freedom
-Information Foundation.
-
-Please see
- http://protocolfreedom.org/ and
- http://samba.org/samba/PFIF/
-for more details.
-
-
-For questions or bug reports please contact:
- sfrench@samba.org (sfrench@us.ibm.com)
-
-Build instructions:
-==================
-For Linux 2.4:
-1) Get the kernel source (e.g.from http://www.kernel.org)
-and download the cifs vfs source (see the project page
-at http://us1.samba.org/samba/Linux_CIFS_client.html)
-and change directory into the top of the kernel directory
-then patch the kernel (e.g. "patch -p1 < cifs_24.patch")
-to add the cifs vfs to your kernel configure options if
-it has not already been added (e.g. current SuSE and UL
-users do not need to apply the cifs_24.patch since the cifs vfs is
-already in the kernel configure menu) and then
-mkdir linux/fs/cifs and then copy the current cifs vfs files from
-the cifs download to your kernel build directory e.g.
-
- cp <cifs_download_dir>/fs/cifs/* to <kernel_download_dir>/fs/cifs
-
-2) make menuconfig (or make xconfig)
-3) select cifs from within the network filesystem choices
-4) save and exit
-5) make dep
-6) make modules (or "make" if CIFS VFS not to be built as a module)
-
-For Linux 2.6:
-1) Download the kernel (e.g. from http://www.kernel.org)
-and change directory into the top of the kernel directory tree
-(e.g. /usr/src/linux-2.5.73)
-2) make menuconfig (or make xconfig)
-3) select cifs from within the network filesystem choices
-4) save and exit
-5) make
-
-
-Installation instructions:
-=========================
-If you have built the CIFS vfs as module (successfully) simply
-type "make modules_install" (or if you prefer, manually copy the file to
-the modules directory e.g. /lib/modules/2.4.10-4GB/kernel/fs/cifs/cifs.o).
-
-If you have built the CIFS vfs into the kernel itself, follow the instructions
-for your distribution on how to install a new kernel (usually you
-would simply type "make install").
-
-If you do not have the utility mount.cifs (in the Samba 3.0 source tree and on
-the CIFS VFS web site) copy it to the same directory in which mount.smbfs and
-similar files reside (usually /sbin). Although the helper software is not
-required, mount.cifs is recommended. Eventually the Samba 3.0 utility program
-"net" may also be helpful since it may someday provide easier mount syntax for
-users who are used to Windows e.g.
- net use <mount point> <UNC name or cifs URL>
-Note that running the Winbind pam/nss module (logon service) on all of your
-Linux clients is useful in mapping Uids and Gids consistently across the
-domain to the proper network user. The mount.cifs mount helper can be
-trivially built from Samba 3.0 or later source e.g. by executing:
-
- gcc samba/source/client/mount.cifs.c -o mount.cifs
-
-If cifs is built as a module, then the size and number of network buffers
-and maximum number of simultaneous requests to one server can be configured.
-Changing these from their defaults is not recommended. By executing modinfo
- modinfo kernel/fs/cifs/cifs.ko
-on kernel/fs/cifs/cifs.ko the list of configuration changes that can be made
-at module initialization time (by running insmod cifs.ko) can be seen.
-
-Allowing User Mounts
-====================
-To permit users to mount and unmount over directories they own is possible
-with the cifs vfs. A way to enable such mounting is to mark the mount.cifs
-utility as suid (e.g. "chmod +s /sbin/mount.cifs). To enable users to
-umount shares they mount requires
-1) mount.cifs version 1.4 or later
-2) an entry for the share in /etc/fstab indicating that a user may
-unmount it e.g.
-//server/usersharename /mnt/username cifs user 0 0
-
-Note that when the mount.cifs utility is run suid (allowing user mounts),
-in order to reduce risks, the "nosuid" mount flag is passed in on mount to
-disallow execution of an suid program mounted on the remote target.
-When mount is executed as root, nosuid is not passed in by default,
-and execution of suid programs on the remote target would be enabled
-by default. This can be changed, as with nfs and other filesystems,
-by simply specifying "nosuid" among the mount options. For user mounts
-though to be able to pass the suid flag to mount requires rebuilding
-mount.cifs with the following flag:
-
- gcc samba/source/client/mount.cifs.c -DCIFS_ALLOW_USR_SUID -o mount.cifs
-
-There is a corresponding manual page for cifs mounting in the Samba 3.0 and
-later source tree in docs/manpages/mount.cifs.8
-
-Allowing User Unmounts
-======================
-To permit users to ummount directories that they have user mounted (see above),
-the utility umount.cifs may be used. It may be invoked directly, or if
-umount.cifs is placed in /sbin, umount can invoke the cifs umount helper
-(at least for most versions of the umount utility) for umount of cifs
-mounts, unless umount is invoked with -i (which will avoid invoking a umount
-helper). As with mount.cifs, to enable user unmounts umount.cifs must be marked
-as suid (e.g. "chmod +s /sbin/umount.cifs") or equivalent (some distributions
-allow adding entries to a file to the /etc/permissions file to achieve the
-equivalent suid effect). For this utility to succeed the target path
-must be a cifs mount, and the uid of the current user must match the uid
-of the user who mounted the resource.
-
-Also note that the customary way of allowing user mounts and unmounts is
-(instead of using mount.cifs and unmount.cifs as suid) to add a line
-to the file /etc/fstab for each //server/share you wish to mount, but
-this can become unwieldy when potential mount targets include many
-or unpredictable UNC names.
-
-Samba Considerations
-====================
-To get the maximum benefit from the CIFS VFS, we recommend using a server that
-supports the SNIA CIFS Unix Extensions standard (e.g. Samba 2.2.5 or later or
-Samba 3.0) but the CIFS vfs works fine with a wide variety of CIFS servers.
-Note that uid, gid and file permissions will display default values if you do
-not have a server that supports the Unix extensions for CIFS (such as Samba
-2.2.5 or later). To enable the Unix CIFS Extensions in the Samba server, add
-the line:
-
- unix extensions = yes
-
-to your smb.conf file on the server. Note that the following smb.conf settings
-are also useful (on the Samba server) when the majority of clients are Unix or
-Linux:
-
- case sensitive = yes
- delete readonly = yes
- ea support = yes
-
-Note that server ea support is required for supporting xattrs from the Linux
-cifs client, and that EA support is present in later versions of Samba (e.g.
-3.0.6 and later (also EA support works in all versions of Windows, at least to
-shares on NTFS filesystems). Extended Attribute (xattr) support is an optional
-feature of most Linux filesystems which may require enabling via
-make menuconfig. Client support for extended attributes (user xattr) can be
-disabled on a per-mount basis by specifying "nouser_xattr" on mount.
-
-The CIFS client can get and set POSIX ACLs (getfacl, setfacl) to Samba servers
-version 3.10 and later. Setting POSIX ACLs requires enabling both XATTR and
-then POSIX support in the CIFS configuration options when building the cifs
-module. POSIX ACL support can be disabled on a per mount basic by specifying
-"noacl" on mount.
-
-Some administrators may want to change Samba's smb.conf "map archive" and
-"create mask" parameters from the default. Unless the create mask is changed
-newly created files can end up with an unnecessarily restrictive default mode,
-which may not be what you want, although if the CIFS Unix extensions are
-enabled on the server and client, subsequent setattr calls (e.g. chmod) can
-fix the mode. Note that creating special devices (mknod) remotely
-may require specifying a mkdev function to Samba if you are not using
-Samba 3.0.6 or later. For more information on these see the manual pages
-("man smb.conf") on the Samba server system. Note that the cifs vfs,
-unlike the smbfs vfs, does not read the smb.conf on the client system
-(the few optional settings are passed in on mount via -o parameters instead).
-Note that Samba 2.2.7 or later includes a fix that allows the CIFS VFS to delete
-open files (required for strict POSIX compliance). Windows Servers already
-supported this feature. Samba server does not allow symlinks that refer to files
-outside of the share, so in Samba versions prior to 3.0.6, most symlinks to
-files with absolute paths (ie beginning with slash) such as:
- ln -s /mnt/foo bar
-would be forbidden. Samba 3.0.6 server or later includes the ability to create
-such symlinks safely by converting unsafe symlinks (ie symlinks to server
-files that are outside of the share) to a samba specific format on the server
-that is ignored by local server applications and non-cifs clients and that will
-not be traversed by the Samba server). This is opaque to the Linux client
-application using the cifs vfs. Absolute symlinks will work to Samba 3.0.5 or
-later, but only for remote clients using the CIFS Unix extensions, and will
-be invisbile to Windows clients and typically will not affect local
-applications running on the same server as Samba.
-
-Use instructions:
-================
-Once the CIFS VFS support is built into the kernel or installed as a module
-(cifs.o), you can use mount syntax like the following to access Samba or Windows
-servers:
-
- mount -t cifs //9.53.216.11/e$ /mnt -o user=myname,pass=mypassword
-
-Before -o the option -v may be specified to make the mount.cifs
-mount helper display the mount steps more verbosely.
-After -o the following commonly used cifs vfs specific options
-are supported:
-
- user=<username>
- pass=<password>
- domain=<domain name>
-
-Other cifs mount options are described below. Use of TCP names (in addition to
-ip addresses) is available if the mount helper (mount.cifs) is installed. If
-you do not trust the server to which are mounted, or if you do not have
-cifs signing enabled (and the physical network is insecure), consider use
-of the standard mount options "noexec" and "nosuid" to reduce the risk of
-running an altered binary on your local system (downloaded from a hostile server
-or altered by a hostile router).
-
-Although mounting using format corresponding to the CIFS URL specification is
-not possible in mount.cifs yet, it is possible to use an alternate format
-for the server and sharename (which is somewhat similar to NFS style mount
-syntax) instead of the more widely used UNC format (i.e. \\server\share):
- mount -t cifs tcp_name_of_server:share_name /mnt -o user=myname,pass=mypasswd
-
-When using the mount helper mount.cifs, passwords may be specified via alternate
-mechanisms, instead of specifying it after -o using the normal "pass=" syntax
-on the command line:
-1) By including it in a credential file. Specify credentials=filename as one
-of the mount options. Credential files contain two lines
- username=someuser
- password=your_password
-2) By specifying the password in the PASSWD environment variable (similarly
-the user name can be taken from the USER environment variable).
-3) By specifying the password in a file by name via PASSWD_FILE
-4) By specifying the password in a file by file descriptor via PASSWD_FD
-
-If no password is provided, mount.cifs will prompt for password entry
-
-Restrictions
-============
-Servers must support either "pure-TCP" (port 445 TCP/IP CIFS connections) or RFC
-1001/1002 support for "Netbios-Over-TCP/IP." This is not likely to be a
-problem as most servers support this.
-
-Valid filenames differ between Windows and Linux. Windows typically restricts
-filenames which contain certain reserved characters (e.g.the character :
-which is used to delimit the beginning of a stream name by Windows), while
-Linux allows a slightly wider set of valid characters in filenames. Windows
-servers can remap such characters when an explicit mapping is specified in
-the Server's registry. Samba starting with version 3.10 will allow such
-filenames (ie those which contain valid Linux characters, which normally
-would be forbidden for Windows/CIFS semantics) as long as the server is
-configured for Unix Extensions (and the client has not disabled
-/proc/fs/cifs/LinuxExtensionsEnabled).
-
-
-CIFS VFS Mount Options
-======================
-A partial list of the supported mount options follows:
- user The user name to use when trying to establish
- the CIFS session.
- password The user password. If the mount helper is
- installed, the user will be prompted for password
- if not supplied.
- ip The ip address of the target server
- unc The target server Universal Network Name (export) to
- mount.
- domain Set the SMB/CIFS workgroup name prepended to the
- username during CIFS session establishment
- forceuid Set the default uid for inodes to the uid
- passed in on mount. For mounts to servers
- which do support the CIFS Unix extensions, such as a
- properly configured Samba server, the server provides
- the uid, gid and mode so this parameter should not be
- specified unless the server and clients uid and gid
- numbering differ. If the server and client are in the
- same domain (e.g. running winbind or nss_ldap) and
- the server supports the Unix Extensions then the uid
- and gid can be retrieved from the server (and uid
- and gid would not have to be specifed on the mount.
- For servers which do not support the CIFS Unix
- extensions, the default uid (and gid) returned on lookup
- of existing files will be the uid (gid) of the person
- who executed the mount (root, except when mount.cifs
- is configured setuid for user mounts) unless the "uid="
- (gid) mount option is specified. Also note that permission
- checks (authorization checks) on accesses to a file occur
- at the server, but there are cases in which an administrator
- may want to restrict at the client as well. For those
- servers which do not report a uid/gid owner
- (such as Windows), permissions can also be checked at the
- client, and a crude form of client side permission checking
- can be enabled by specifying file_mode and dir_mode on
- the client. (default)
- forcegid (similar to above but for the groupid instead of uid) (default)
- noforceuid Fill in file owner information (uid) by requesting it from
- the server if possible. With this option, the value given in
- the uid= option (on mount) will only be used if the server
- can not support returning uids on inodes.
- noforcegid (similar to above but for the group owner, gid, instead of uid)
- uid Set the default uid for inodes, and indicate to the
- cifs kernel driver which local user mounted. If the server
- supports the unix extensions the default uid is
- not used to fill in the owner fields of inodes (files)
- unless the "forceuid" parameter is specified.
- gid Set the default gid for inodes (similar to above).
- file_mode If CIFS Unix extensions are not supported by the server
- this overrides the default mode for file inodes.
- fsc Enable local disk caching using FS-Cache (off by default). This
- option could be useful to improve performance on a slow link,
- heavily loaded server and/or network where reading from the
- disk is faster than reading from the server (over the network).
- This could also impact scalability positively as the
- number of calls to the server are reduced. However, local
- caching is not suitable for all workloads for e.g. read-once
- type workloads. So, you need to consider carefully your
- workload/scenario before using this option. Currently, local
- disk caching is functional for CIFS files opened as read-only.
- dir_mode If CIFS Unix extensions are not supported by the server
- this overrides the default mode for directory inodes.
- port attempt to contact the server on this tcp port, before
- trying the usual ports (port 445, then 139).
- iocharset Codepage used to convert local path names to and from
- Unicode. Unicode is used by default for network path
- names if the server supports it. If iocharset is
- not specified then the nls_default specified
- during the local client kernel build will be used.
- If server does not support Unicode, this parameter is
- unused.
- rsize default read size (usually 16K). The client currently
- can not use rsize larger than CIFSMaxBufSize. CIFSMaxBufSize
- defaults to 16K and may be changed (from 8K to the maximum
- kmalloc size allowed by your kernel) at module install time
- for cifs.ko. Setting CIFSMaxBufSize to a very large value
- will cause cifs to use more memory and may reduce performance
- in some cases. To use rsize greater than 127K (the original
- cifs protocol maximum) also requires that the server support
- a new Unix Capability flag (for very large read) which some
- newer servers (e.g. Samba 3.0.26 or later) do. rsize can be
- set from a minimum of 2048 to a maximum of 130048 (127K or
- CIFSMaxBufSize, whichever is smaller)
- wsize default write size (default 57344)
- maximum wsize currently allowed by CIFS is 57344 (fourteen
- 4096 byte pages)
- actimeo=n attribute cache timeout in seconds (default 1 second).
- After this timeout, the cifs client requests fresh attribute
- information from the server. This option allows to tune the
- attribute cache timeout to suit the workload needs. Shorter
- timeouts mean better the cache coherency, but increased number
- of calls to the server. Longer timeouts mean reduced number
- of calls to the server at the expense of less stricter cache
- coherency checks (i.e. incorrect attribute cache for a short
- period of time).
- rw mount the network share read-write (note that the
- server may still consider the share read-only)
- ro mount network share read-only
- version used to distinguish different versions of the
- mount helper utility (not typically needed)
- sep if first mount option (after the -o), overrides
- the comma as the separator between the mount
- parms. e.g.
- -o user=myname,password=mypassword,domain=mydom
- could be passed instead with period as the separator by
- -o sep=.user=myname.password=mypassword.domain=mydom
- this might be useful when comma is contained within username
- or password or domain. This option is less important
- when the cifs mount helper cifs.mount (version 1.1 or later)
- is used.
- nosuid Do not allow remote executables with the suid bit
- program to be executed. This is only meaningful for mounts
- to servers such as Samba which support the CIFS Unix Extensions.
- If you do not trust the servers in your network (your mount
- targets) it is recommended that you specify this option for
- greater security.
- exec Permit execution of binaries on the mount.
- noexec Do not permit execution of binaries on the mount.
- dev Recognize block devices on the remote mount.
- nodev Do not recognize devices on the remote mount.
- suid Allow remote files on this mountpoint with suid enabled to
- be executed (default for mounts when executed as root,
- nosuid is default for user mounts).
- credentials Although ignored by the cifs kernel component, it is used by
- the mount helper, mount.cifs. When mount.cifs is installed it
- opens and reads the credential file specified in order
- to obtain the userid and password arguments which are passed to
- the cifs vfs.
- guest Although ignored by the kernel component, the mount.cifs
- mount helper will not prompt the user for a password
- if guest is specified on the mount options. If no
- password is specified a null password will be used.
- perm Client does permission checks (vfs_permission check of uid
- and gid of the file against the mode and desired operation),
- Note that this is in addition to the normal ACL check on the
- target machine done by the server software.
- Client permission checking is enabled by default.
- noperm Client does not do permission checks. This can expose
- files on this mount to access by other users on the local
- client system. It is typically only needed when the server
- supports the CIFS Unix Extensions but the UIDs/GIDs on the
- client and server system do not match closely enough to allow
- access by the user doing the mount, but it may be useful with
- non CIFS Unix Extension mounts for cases in which the default
- mode is specified on the mount but is not to be enforced on the
- client (e.g. perhaps when MultiUserMount is enabled)
- Note that this does not affect the normal ACL check on the
- target machine done by the server software (of the server
- ACL against the user name provided at mount time).
- serverino Use server's inode numbers instead of generating automatically
- incrementing inode numbers on the client. Although this will
- make it easier to spot hardlinked files (as they will have
- the same inode numbers) and inode numbers may be persistent,
- note that the server does not guarantee that the inode numbers
- are unique if multiple server side mounts are exported under a
- single share (since inode numbers on the servers might not
- be unique if multiple filesystems are mounted under the same
- shared higher level directory). Note that some older
- (e.g. pre-Windows 2000) do not support returning UniqueIDs
- or the CIFS Unix Extensions equivalent and for those
- this mount option will have no effect. Exporting cifs mounts
- under nfsd requires this mount option on the cifs mount.
- This is now the default if server supports the
- required network operation.
- noserverino Client generates inode numbers (rather than using the actual one
- from the server). These inode numbers will vary after
- unmount or reboot which can confuse some applications,
- but not all server filesystems support unique inode
- numbers.
- setuids If the CIFS Unix extensions are negotiated with the server
- the client will attempt to set the effective uid and gid of
- the local process on newly created files, directories, and
- devices (create, mkdir, mknod). If the CIFS Unix Extensions
- are not negotiated, for newly created files and directories
- instead of using the default uid and gid specified on
- the mount, cache the new file's uid and gid locally which means
- that the uid for the file can change when the inode is
- reloaded (or the user remounts the share).
- nosetuids The client will not attempt to set the uid and gid on
- on newly created files, directories, and devices (create,
- mkdir, mknod) which will result in the server setting the
- uid and gid to the default (usually the server uid of the
- user who mounted the share). Letting the server (rather than
- the client) set the uid and gid is the default. If the CIFS
- Unix Extensions are not negotiated then the uid and gid for
- new files will appear to be the uid (gid) of the mounter or the
- uid (gid) parameter specified on the mount.
- netbiosname When mounting to servers via port 139, specifies the RFC1001
- source name to use to represent the client netbios machine
- name when doing the RFC1001 netbios session initialize.
- direct Do not do inode data caching on files opened on this mount.
- This precludes mmapping files on this mount. In some cases
- with fast networks and little or no caching benefits on the
- client (e.g. when the application is doing large sequential
- reads bigger than page size without rereading the same data)
- this can provide better performance than the default
- behavior which caches reads (readahead) and writes
- (writebehind) through the local Linux client pagecache
- if oplock (caching token) is granted and held. Note that
- direct allows write operations larger than page size
- to be sent to the server.
- strictcache Use for switching on strict cache mode. In this mode the
- client read from the cache all the time it has Oplock Level II,
- otherwise - read from the server. All written data are stored
- in the cache, but if the client doesn't have Exclusive Oplock,
- it writes the data to the server.
- rwpidforward Forward pid of a process who opened a file to any read or write
- operation on that file. This prevent applications like WINE
- from failing on read and write if we use mandatory brlock style.
- acl Allow setfacl and getfacl to manage posix ACLs if server
- supports them. (default)
- noacl Do not allow setfacl and getfacl calls on this mount
- user_xattr Allow getting and setting user xattrs (those attributes whose
- name begins with "user." or "os2.") as OS/2 EAs (extended
- attributes) to the server. This allows support of the
- setfattr and getfattr utilities. (default)
- nouser_xattr Do not allow getfattr/setfattr to get/set/list xattrs
- mapchars Translate six of the seven reserved characters (not backslash)
- *?<>|:
- to the remap range (above 0xF000), which also
- allows the CIFS client to recognize files created with
- such characters by Windows's POSIX emulation. This can
- also be useful when mounting to most versions of Samba
- (which also forbids creating and opening files
- whose names contain any of these seven characters).
- This has no effect if the server does not support
- Unicode on the wire.
- nomapchars Do not translate any of these seven characters (default).
- nocase Request case insensitive path name matching (case
- sensitive is the default if the server suports it).
- (mount option "ignorecase" is identical to "nocase")
- posixpaths If CIFS Unix extensions are supported, attempt to
- negotiate posix path name support which allows certain
- characters forbidden in typical CIFS filenames, without
- requiring remapping. (default)
- noposixpaths If CIFS Unix extensions are supported, do not request
- posix path name support (this may cause servers to
- reject creatingfile with certain reserved characters).
- nounix Disable the CIFS Unix Extensions for this mount (tree
- connection). This is rarely needed, but it may be useful
- in order to turn off multiple settings all at once (ie
- posix acls, posix locks, posix paths, symlink support
- and retrieving uids/gids/mode from the server) or to
- work around a bug in server which implement the Unix
- Extensions.
- nobrl Do not send byte range lock requests to the server.
- This is necessary for certain applications that break
- with cifs style mandatory byte range locks (and most
- cifs servers do not yet support requesting advisory
- byte range locks).
- forcemandatorylock Even if the server supports posix (advisory) byte range
- locking, send only mandatory lock requests. For some
- (presumably rare) applications, originally coded for
- DOS/Windows, which require Windows style mandatory byte range
- locking, they may be able to take advantage of this option,
- forcing the cifs client to only send mandatory locks
- even if the cifs server would support posix advisory locks.
- "forcemand" is accepted as a shorter form of this mount
- option.
- nostrictsync If this mount option is set, when an application does an
- fsync call then the cifs client does not send an SMB Flush
- to the server (to force the server to write all dirty data
- for this file immediately to disk), although cifs still sends
- all dirty (cached) file data to the server and waits for the
- server to respond to the write. Since SMB Flush can be
- very slow, and some servers may be reliable enough (to risk
- delaying slightly flushing the data to disk on the server),
- turning on this option may be useful to improve performance for
- applications that fsync too much, at a small risk of server
- crash. If this mount option is not set, by default cifs will
- send an SMB flush request (and wait for a response) on every
- fsync call.
- nodfs Disable DFS (global name space support) even if the
- server claims to support it. This can help work around
- a problem with parsing of DFS paths with Samba server
- versions 3.0.24 and 3.0.25.
- remount remount the share (often used to change from ro to rw mounts
- or vice versa)
- cifsacl Report mode bits (e.g. on stat) based on the Windows ACL for
- the file. (EXPERIMENTAL)
- servern Specify the server 's netbios name (RFC1001 name) to use
- when attempting to setup a session to the server.
- This is needed for mounting to some older servers (such
- as OS/2 or Windows 98 and Windows ME) since they do not
- support a default server name. A server name can be up
- to 15 characters long and is usually uppercased.
- sfu When the CIFS Unix Extensions are not negotiated, attempt to
- create device files and fifos in a format compatible with
- Services for Unix (SFU). In addition retrieve bits 10-12
- of the mode via the SETFILEBITS extended attribute (as
- SFU does). In the future the bottom 9 bits of the
- mode also will be emulated using queries of the security
- descriptor (ACL).
- mfsymlinks Enable support for Minshall+French symlinks
- (see http://wiki.samba.org/index.php/UNIX_Extensions#Minshall.2BFrench_symlinks)
- This option is ignored when specified together with the
- 'sfu' option. Minshall+French symlinks are used even if
- the server supports the CIFS Unix Extensions.
- sign Must use packet signing (helps avoid unwanted data modification
- by intermediate systems in the route). Note that signing
- does not work with lanman or plaintext authentication.
- seal Must seal (encrypt) all data on this mounted share before
- sending on the network. Requires support for Unix Extensions.
- Note that this differs from the sign mount option in that it
- causes encryption of data sent over this mounted share but other
- shares mounted to the same server are unaffected.
- locallease This option is rarely needed. Fcntl F_SETLEASE is
- used by some applications such as Samba and NFSv4 server to
- check to see whether a file is cacheable. CIFS has no way
- to explicitly request a lease, but can check whether a file
- is cacheable (oplocked). Unfortunately, even if a file
- is not oplocked, it could still be cacheable (ie cifs client
- could grant fcntl leases if no other local processes are using
- the file) for cases for example such as when the server does not
- support oplocks and the user is sure that the only updates to
- the file will be from this client. Specifying this mount option
- will allow the cifs client to check for leases (only) locally
- for files which are not oplocked instead of denying leases
- in that case. (EXPERIMENTAL)
- sec Security mode. Allowed values are:
- none attempt to connection as a null user (no name)
- krb5 Use Kerberos version 5 authentication
- krb5i Use Kerberos authentication and packet signing
- ntlm Use NTLM password hashing (default)
- ntlmi Use NTLM password hashing with signing (if
- /proc/fs/cifs/PacketSigningEnabled on or if
- server requires signing also can be the default)
- ntlmv2 Use NTLMv2 password hashing
- ntlmv2i Use NTLMv2 password hashing with packet signing
- lanman (if configured in kernel config) use older
- lanman hash
-hard Retry file operations if server is not responding
-soft Limit retries to unresponsive servers (usually only
- one retry) before returning an error. (default)
-
-The mount.cifs mount helper also accepts a few mount options before -o
-including:
-
- -S take password from stdin (equivalent to setting the environment
- variable "PASSWD_FD=0"
- -V print mount.cifs version
- -? display simple usage information
-
-With most 2.6 kernel versions of modutils, the version of the cifs kernel
-module can be displayed via modinfo.
-
-Misc /proc/fs/cifs Flags and Debug Info
-=======================================
-Informational pseudo-files:
-DebugData Displays information about active CIFS sessions and
- shares, features enabled as well as the cifs.ko
- version.
-Stats Lists summary resource usage information as well as per
- share statistics, if CONFIG_CIFS_STATS in enabled
- in the kernel configuration.
-
-Configuration pseudo-files:
-MultiuserMount If set to one, more than one CIFS session to
- the same server ip address can be established
- if more than one uid accesses the same mount
- point and if the uids user/password mapping
- information is available. (default is 0)
-PacketSigningEnabled If set to one, cifs packet signing is enabled
- and will be used if the server requires
- it. If set to two, cifs packet signing is
- required even if the server considers packet
- signing optional. (default 1)
-SecurityFlags Flags which control security negotiation and
- also packet signing. Authentication (may/must)
- flags (e.g. for NTLM and/or NTLMv2) may be combined with
- the signing flags. Specifying two different password
- hashing mechanisms (as "must use") on the other hand
- does not make much sense. Default flags are
- 0x07007
- (NTLM, NTLMv2 and packet signing allowed). The maximum
- allowable flags if you want to allow mounts to servers
- using weaker password hashes is 0x37037 (lanman,
- plaintext, ntlm, ntlmv2, signing allowed). Some
- SecurityFlags require the corresponding menuconfig
- options to be enabled (lanman and plaintext require
- CONFIG_CIFS_WEAK_PW_HASH for example). Enabling
- plaintext authentication currently requires also
- enabling lanman authentication in the security flags
- because the cifs module only supports sending
- laintext passwords using the older lanman dialect
- form of the session setup SMB. (e.g. for authentication
- using plain text passwords, set the SecurityFlags
- to 0x30030):
-
- may use packet signing 0x00001
- must use packet signing 0x01001
- may use NTLM (most common password hash) 0x00002
- must use NTLM 0x02002
- may use NTLMv2 0x00004
- must use NTLMv2 0x04004
- may use Kerberos security 0x00008
- must use Kerberos 0x08008
- may use lanman (weak) password hash 0x00010
- must use lanman password hash 0x10010
- may use plaintext passwords 0x00020
- must use plaintext passwords 0x20020
- (reserved for future packet encryption) 0x00040
-
-cifsFYI If set to non-zero value, additional debug information
- will be logged to the system error log. This field
- contains three flags controlling different classes of
- debugging entries. The maximum value it can be set
- to is 7 which enables all debugging points (default 0).
- Some debugging statements are not compiled into the
- cifs kernel unless CONFIG_CIFS_DEBUG2 is enabled in the
- kernel configuration. cifsFYI may be set to one or
- nore of the following flags (7 sets them all):
-
- log cifs informational messages 0x01
- log return codes from cifs entry points 0x02
- log slow responses (ie which take longer than 1 second)
- CONFIG_CIFS_STATS2 must be enabled in .config 0x04
-
-
-traceSMB If set to one, debug information is logged to the
- system error log with the start of smb requests
- and responses (default 0)
-LookupCacheEnable If set to one, inode information is kept cached
- for one second improving performance of lookups
- (default 1)
-OplockEnabled If set to one, safe distributed caching enabled.
- (default 1)
-LinuxExtensionsEnabled If set to one then the client will attempt to
- use the CIFS "UNIX" extensions which are optional
- protocol enhancements that allow CIFS servers
- to return accurate UID/GID information as well
- as support symbolic links. If you use servers
- such as Samba that support the CIFS Unix
- extensions but do not want to use symbolic link
- support and want to map the uid and gid fields
- to values supplied at mount (rather than the
- actual values, then set this to zero. (default 1)
-
-These experimental features and tracing can be enabled by changing flags in
-/proc/fs/cifs (after the cifs module has been installed or built into the
-kernel, e.g. insmod cifs). To enable a feature set it to 1 e.g. to enable
-tracing to the kernel message log type:
-
- echo 7 > /proc/fs/cifs/cifsFYI
-
-cifsFYI functions as a bit mask. Setting it to 1 enables additional kernel
-logging of various informational messages. 2 enables logging of non-zero
-SMB return codes while 4 enables logging of requests that take longer
-than one second to complete (except for byte range lock requests).
-Setting it to 4 requires defining CONFIG_CIFS_STATS2 manually in the
-source code (typically by setting it in the beginning of cifsglob.h),
-and setting it to seven enables all three. Finally, tracing
-the start of smb requests and responses can be enabled via:
-
- echo 1 > /proc/fs/cifs/traceSMB
-
-Per share (per client mount) statistics are available in /proc/fs/cifs/Stats
-if the kernel was configured with cifs statistics enabled. The statistics
-represent the number of successful (ie non-zero return code from the server)
-SMB responses to some of the more common commands (open, delete, mkdir etc.).
-Also recorded is the total bytes read and bytes written to the server for
-that share. Note that due to client caching effects this can be less than the
-number of bytes read and written by the application running on the client.
-The statistics for the number of total SMBs and oplock breaks are different in
-that they represent all for that share, not just those for which the server
-returned success.
-
-Also note that "cat /proc/fs/cifs/DebugData" will display information about
-the active sessions and the shares that are mounted.
-
-Enabling Kerberos (extended security) works but requires version 1.2 or later
-of the helper program cifs.upcall to be present and to be configured in the
-/etc/request-key.conf file. The cifs.upcall helper program is from the Samba
-project(http://www.samba.org). NTLM and NTLMv2 and LANMAN support do not
-require this helper. Note that NTLMv2 security (which does not require the
-cifs.upcall helper program), instead of using Kerberos, is sufficient for
-some use cases.
-
-DFS support allows transparent redirection to shares in an MS-DFS name space.
-In addition, DFS support for target shares which are specified as UNC
-names which begin with host names (rather than IP addresses) requires
-a user space helper (such as cifs.upcall) to be present in order to
-translate host names to ip address, and the user space helper must also
-be configured in the file /etc/request-key.conf. Samba, Windows servers and
-many NAS appliances support DFS as a way of constructing a global name
-space to ease network configuration and improve reliability.
-
-To use cifs Kerberos and DFS support, the Linux keyutils package should be
-installed and something like the following lines should be added to the
-/etc/request-key.conf file:
-
-create cifs.spnego * * /usr/local/sbin/cifs.upcall %k
-create dns_resolver * * /usr/local/sbin/cifs.upcall %k
-
-CIFS kernel module parameters
-=============================
-These module parameters can be specified or modified either during the time of
-module loading or during the runtime by using the interface
- /proc/module/cifs/parameters/<param>
-
-i.e. echo "value" > /sys/module/cifs/parameters/<param>
-
-1. enable_oplocks - Enable or disable oplocks. Oplocks are enabled by default.
- [Y/y/1]. To disable use any of [N/n/0].
-
diff --git a/ANDROID_3.4.5/fs/cifs/TODO b/ANDROID_3.4.5/fs/cifs/TODO
deleted file mode 100644
index 355abcdc..00000000
--- a/ANDROID_3.4.5/fs/cifs/TODO
+++ /dev/null
@@ -1,129 +0,0 @@
-Version 1.53 May 20, 2008
-
-A Partial List of Missing Features
-==================================
-
-Contributions are welcome. There are plenty of opportunities
-for visible, important contributions to this module. Here
-is a partial list of the known problems and missing features:
-
-a) Support for SecurityDescriptors(Windows/CIFS ACLs) for chmod/chgrp/chown
-so that these operations can be supported to Windows servers
-
-b) Mapping POSIX ACLs (and eventually NFSv4 ACLs) to CIFS
-SecurityDescriptors
-
-c) Better pam/winbind integration (e.g. to handle uid mapping
-better)
-
-d) Cleanup now unneeded SessSetup code in
-fs/cifs/connect.c and add back in NTLMSSP code if any servers
-need it
-
-e) fix NTLMv2 signing when two mounts with different users to same
-server.
-
-f) Directory entry caching relies on a 1 second timer, rather than
-using FindNotify or equivalent. - (started)
-
-g) quota support (needs minor kernel change since quota calls
-to make it to network filesystems or deviceless filesystems)
-
-h) investigate sync behavior (including syncpage) and check
-for proper behavior of intr/nointr
-
-i) improve support for very old servers (OS/2 and Win9x for example)
-Including support for changing the time remotely (utimes command).
-
-j) hook lower into the sockets api (as NFS/SunRPC does) to avoid the
-extra copy in/out of the socket buffers in some cases.
-
-k) Better optimize open (and pathbased setfilesize) to reduce the
-oplock breaks coming from windows srv. Piggyback identical file
-opens on top of each other by incrementing reference count rather
-than resending (helps reduce server resource utilization and avoid
-spurious oplock breaks).
-
-l) Improve performance of readpages by sending more than one read
-at a time when 8 pages or more are requested. In conjuntion
-add support for async_cifs_readpages.
-
-m) Add support for storing symlink info to Windows servers
-in the Extended Attribute format their SFU clients would recognize.
-
-n) Finish fcntl D_NOTIFY support so kde and gnome file list windows
-will autorefresh (partially complete by Asser). Needs minor kernel
-vfs change to support removing D_NOTIFY on a file.
-
-o) Add GUI tool to configure /proc/fs/cifs settings and for display of
-the CIFS statistics (started)
-
-p) implement support for security and trusted categories of xattrs
-(requires minor protocol extension) to enable better support for SELINUX
-
-q) Implement O_DIRECT flag on open (already supported on mount)
-
-r) Create UID mapping facility so server UIDs can be mapped on a per
-mount or a per server basis to client UIDs or nobody if no mapping
-exists. This is helpful when Unix extensions are negotiated to
-allow better permission checking when UIDs differ on the server
-and client. Add new protocol request to the CIFS protocol
-standard for asking the server for the corresponding name of a
-particular uid.
-
-s) Add support for CIFS Unix and also the newer POSIX extensions to the
-server side for Samba 4.
-
-t) In support for OS/2 (LANMAN 1.2 and LANMAN2.1 based SMB servers)
-need to add ability to set time to server (utimes command)
-
-u) DOS attrs - returned as pseudo-xattr in Samba format (check VFAT and NTFS for this too)
-
-v) mount check for unmatched uids
-
-w) Add support for new vfs entry point for fallocate
-
-x) Fix Samba 3 server to handle Linux kernel aio so dbench with lots of
-processes can proceed better in parallel (on the server)
-
-y) Fix Samba 3 to handle reads/writes over 127K (and remove the cifs mount
-restriction of wsize max being 127K)
-
-KNOWN BUGS (updated April 24, 2007)
-====================================
-See http://bugzilla.samba.org - search on product "CifsVFS" for
-current bug list.
-
-1) existing symbolic links (Windows reparse points) are recognized but
-can not be created remotely. They are implemented for Samba and those that
-support the CIFS Unix extensions, although earlier versions of Samba
-overly restrict the pathnames.
-2) follow_link and readdir code does not follow dfs junctions
-but recognizes them
-3) create of new files to FAT partitions on Windows servers can
-succeed but still return access denied (appears to be Windows
-server not cifs client problem) and has not been reproduced recently.
-NTFS partitions do not have this problem.
-4) Unix/POSIX capabilities are reset after reconnection, and affect
-a few fields in the tree connection but we do do not know which
-superblocks to apply these changes to. We should probably walk
-the list of superblocks to set these. Also need to check the
-flags on the second mount to the same share, and see if we
-can do the same trick that NFS does to remount duplicate shares.
-
-Misc testing to do
-==================
-1) check out max path names and max path name components against various server
-types. Try nested symlinks (8 deep). Return max path name in stat -f information
-
-2) Modify file portion of ltp so it can run against a mounted network
-share and run it against cifs vfs in automated fashion.
-
-3) Additional performance testing and optimization using iozone and similar -
-there are some easy changes that can be done to parallelize sequential writes,
-and when signing is disabled to request larger read sizes (larger than
-negotiated size) and send larger write sizes to modern servers.
-
-4) More exhaustively test against less common servers. More testing
-against Windows 9x, Windows ME servers.
-
diff --git a/ANDROID_3.4.5/fs/cifs/asn1.c b/ANDROID_3.4.5/fs/cifs/asn1.c
deleted file mode 100644
index cfd1ce34..00000000
--- a/ANDROID_3.4.5/fs/cifs/asn1.c
+++ /dev/null
@@ -1,666 +0,0 @@
-/*
- * The ASB.1/BER parsing code is derived from ip_nat_snmp_basic.c which was in
- * turn derived from the gxsnmp package by Gregory McLean & Jochen Friedrich
- *
- * Copyright (c) 2000 RP Internet (www.rpi.net.au).
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include "cifspdu.h"
-#include "cifsglob.h"
-#include "cifs_debug.h"
-#include "cifsproto.h"
-
-/*****************************************************************************
- *
- * Basic ASN.1 decoding routines (gxsnmp author Dirk Wisse)
- *
- *****************************************************************************/
-
-/* Class */
-#define ASN1_UNI 0 /* Universal */
-#define ASN1_APL 1 /* Application */
-#define ASN1_CTX 2 /* Context */
-#define ASN1_PRV 3 /* Private */
-
-/* Tag */
-#define ASN1_EOC 0 /* End Of Contents or N/A */
-#define ASN1_BOL 1 /* Boolean */
-#define ASN1_INT 2 /* Integer */
-#define ASN1_BTS 3 /* Bit String */
-#define ASN1_OTS 4 /* Octet String */
-#define ASN1_NUL 5 /* Null */
-#define ASN1_OJI 6 /* Object Identifier */
-#define ASN1_OJD 7 /* Object Description */
-#define ASN1_EXT 8 /* External */
-#define ASN1_ENUM 10 /* Enumerated */
-#define ASN1_SEQ 16 /* Sequence */
-#define ASN1_SET 17 /* Set */
-#define ASN1_NUMSTR 18 /* Numerical String */
-#define ASN1_PRNSTR 19 /* Printable String */
-#define ASN1_TEXSTR 20 /* Teletext String */
-#define ASN1_VIDSTR 21 /* Video String */
-#define ASN1_IA5STR 22 /* IA5 String */
-#define ASN1_UNITIM 23 /* Universal Time */
-#define ASN1_GENTIM 24 /* General Time */
-#define ASN1_GRASTR 25 /* Graphical String */
-#define ASN1_VISSTR 26 /* Visible String */
-#define ASN1_GENSTR 27 /* General String */
-
-/* Primitive / Constructed methods*/
-#define ASN1_PRI 0 /* Primitive */
-#define ASN1_CON 1 /* Constructed */
-
-/*
- * Error codes.
- */
-#define ASN1_ERR_NOERROR 0
-#define ASN1_ERR_DEC_EMPTY 2
-#define ASN1_ERR_DEC_EOC_MISMATCH 3
-#define ASN1_ERR_DEC_LENGTH_MISMATCH 4
-#define ASN1_ERR_DEC_BADVALUE 5
-
-#define SPNEGO_OID_LEN 7
-#define NTLMSSP_OID_LEN 10
-#define KRB5_OID_LEN 7
-#define KRB5U2U_OID_LEN 8
-#define MSKRB5_OID_LEN 7
-static unsigned long SPNEGO_OID[7] = { 1, 3, 6, 1, 5, 5, 2 };
-static unsigned long NTLMSSP_OID[10] = { 1, 3, 6, 1, 4, 1, 311, 2, 2, 10 };
-static unsigned long KRB5_OID[7] = { 1, 2, 840, 113554, 1, 2, 2 };
-static unsigned long KRB5U2U_OID[8] = { 1, 2, 840, 113554, 1, 2, 2, 3 };
-static unsigned long MSKRB5_OID[7] = { 1, 2, 840, 48018, 1, 2, 2 };
-
-/*
- * ASN.1 context.
- */
-struct asn1_ctx {
- int error; /* Error condition */
- unsigned char *pointer; /* Octet just to be decoded */
- unsigned char *begin; /* First octet */
- unsigned char *end; /* Octet after last octet */
-};
-
-/*
- * Octet string (not null terminated)
- */
-struct asn1_octstr {
- unsigned char *data;
- unsigned int len;
-};
-
-static void
-asn1_open(struct asn1_ctx *ctx, unsigned char *buf, unsigned int len)
-{
- ctx->begin = buf;
- ctx->end = buf + len;
- ctx->pointer = buf;
- ctx->error = ASN1_ERR_NOERROR;
-}
-
-static unsigned char
-asn1_octet_decode(struct asn1_ctx *ctx, unsigned char *ch)
-{
- if (ctx->pointer >= ctx->end) {
- ctx->error = ASN1_ERR_DEC_EMPTY;
- return 0;
- }
- *ch = *(ctx->pointer)++;
- return 1;
-}
-
-#if 0 /* will be needed later by spnego decoding/encoding of ntlmssp */
-static unsigned char
-asn1_enum_decode(struct asn1_ctx *ctx, __le32 *val)
-{
- unsigned char ch;
-
- if (ctx->pointer >= ctx->end) {
- ctx->error = ASN1_ERR_DEC_EMPTY;
- return 0;
- }
-
- ch = *(ctx->pointer)++; /* ch has 0xa, ptr points to length octet */
- if ((ch) == ASN1_ENUM) /* if ch value is ENUM, 0xa */
- *val = *(++(ctx->pointer)); /* value has enum value */
- else
- return 0;
-
- ctx->pointer++;
- return 1;
-}
-#endif
-
-static unsigned char
-asn1_tag_decode(struct asn1_ctx *ctx, unsigned int *tag)
-{
- unsigned char ch;
-
- *tag = 0;
-
- do {
- if (!asn1_octet_decode(ctx, &ch))
- return 0;
- *tag <<= 7;
- *tag |= ch & 0x7F;
- } while ((ch & 0x80) == 0x80);
- return 1;
-}
-
-static unsigned char
-asn1_id_decode(struct asn1_ctx *ctx,
- unsigned int *cls, unsigned int *con, unsigned int *tag)
-{
- unsigned char ch;
-
- if (!asn1_octet_decode(ctx, &ch))
- return 0;
-
- *cls = (ch & 0xC0) >> 6;
- *con = (ch & 0x20) >> 5;
- *tag = (ch & 0x1F);
-
- if (*tag == 0x1F) {
- if (!asn1_tag_decode(ctx, tag))
- return 0;
- }
- return 1;
-}
-
-static unsigned char
-asn1_length_decode(struct asn1_ctx *ctx, unsigned int *def, unsigned int *len)
-{
- unsigned char ch, cnt;
-
- if (!asn1_octet_decode(ctx, &ch))
- return 0;
-
- if (ch == 0x80)
- *def = 0;
- else {
- *def = 1;
-
- if (ch < 0x80)
- *len = ch;
- else {
- cnt = (unsigned char) (ch & 0x7F);
- *len = 0;
-
- while (cnt > 0) {
- if (!asn1_octet_decode(ctx, &ch))
- return 0;
- *len <<= 8;
- *len |= ch;
- cnt--;
- }
- }
- }
-
- /* don't trust len bigger than ctx buffer */
- if (*len > ctx->end - ctx->pointer)
- return 0;
-
- return 1;
-}
-
-static unsigned char
-asn1_header_decode(struct asn1_ctx *ctx,
- unsigned char **eoc,
- unsigned int *cls, unsigned int *con, unsigned int *tag)
-{
- unsigned int def = 0;
- unsigned int len = 0;
-
- if (!asn1_id_decode(ctx, cls, con, tag))
- return 0;
-
- if (!asn1_length_decode(ctx, &def, &len))
- return 0;
-
- /* primitive shall be definite, indefinite shall be constructed */
- if (*con == ASN1_PRI && !def)
- return 0;
-
- if (def)
- *eoc = ctx->pointer + len;
- else
- *eoc = NULL;
- return 1;
-}
-
-static unsigned char
-asn1_eoc_decode(struct asn1_ctx *ctx, unsigned char *eoc)
-{
- unsigned char ch;
-
- if (eoc == NULL) {
- if (!asn1_octet_decode(ctx, &ch))
- return 0;
-
- if (ch != 0x00) {
- ctx->error = ASN1_ERR_DEC_EOC_MISMATCH;
- return 0;
- }
-
- if (!asn1_octet_decode(ctx, &ch))
- return 0;
-
- if (ch != 0x00) {
- ctx->error = ASN1_ERR_DEC_EOC_MISMATCH;
- return 0;
- }
- return 1;
- } else {
- if (ctx->pointer != eoc) {
- ctx->error = ASN1_ERR_DEC_LENGTH_MISMATCH;
- return 0;
- }
- return 1;
- }
-}
-
-/* static unsigned char asn1_null_decode(struct asn1_ctx *ctx,
- unsigned char *eoc)
-{
- ctx->pointer = eoc;
- return 1;
-}
-
-static unsigned char asn1_long_decode(struct asn1_ctx *ctx,
- unsigned char *eoc, long *integer)
-{
- unsigned char ch;
- unsigned int len;
-
- if (!asn1_octet_decode(ctx, &ch))
- return 0;
-
- *integer = (signed char) ch;
- len = 1;
-
- while (ctx->pointer < eoc) {
- if (++len > sizeof(long)) {
- ctx->error = ASN1_ERR_DEC_BADVALUE;
- return 0;
- }
-
- if (!asn1_octet_decode(ctx, &ch))
- return 0;
-
- *integer <<= 8;
- *integer |= ch;
- }
- return 1;
-}
-
-static unsigned char asn1_uint_decode(struct asn1_ctx *ctx,
- unsigned char *eoc,
- unsigned int *integer)
-{
- unsigned char ch;
- unsigned int len;
-
- if (!asn1_octet_decode(ctx, &ch))
- return 0;
-
- *integer = ch;
- if (ch == 0)
- len = 0;
- else
- len = 1;
-
- while (ctx->pointer < eoc) {
- if (++len > sizeof(unsigned int)) {
- ctx->error = ASN1_ERR_DEC_BADVALUE;
- return 0;
- }
-
- if (!asn1_octet_decode(ctx, &ch))
- return 0;
-
- *integer <<= 8;
- *integer |= ch;
- }
- return 1;
-}
-
-static unsigned char asn1_ulong_decode(struct asn1_ctx *ctx,
- unsigned char *eoc,
- unsigned long *integer)
-{
- unsigned char ch;
- unsigned int len;
-
- if (!asn1_octet_decode(ctx, &ch))
- return 0;
-
- *integer = ch;
- if (ch == 0)
- len = 0;
- else
- len = 1;
-
- while (ctx->pointer < eoc) {
- if (++len > sizeof(unsigned long)) {
- ctx->error = ASN1_ERR_DEC_BADVALUE;
- return 0;
- }
-
- if (!asn1_octet_decode(ctx, &ch))
- return 0;
-
- *integer <<= 8;
- *integer |= ch;
- }
- return 1;
-}
-
-static unsigned char
-asn1_octets_decode(struct asn1_ctx *ctx,
- unsigned char *eoc,
- unsigned char **octets, unsigned int *len)
-{
- unsigned char *ptr;
-
- *len = 0;
-
- *octets = kmalloc(eoc - ctx->pointer, GFP_ATOMIC);
- if (*octets == NULL) {
- return 0;
- }
-
- ptr = *octets;
- while (ctx->pointer < eoc) {
- if (!asn1_octet_decode(ctx, (unsigned char *) ptr++)) {
- kfree(*octets);
- *octets = NULL;
- return 0;
- }
- (*len)++;
- }
- return 1;
-} */
-
-static unsigned char
-asn1_subid_decode(struct asn1_ctx *ctx, unsigned long *subid)
-{
- unsigned char ch;
-
- *subid = 0;
-
- do {
- if (!asn1_octet_decode(ctx, &ch))
- return 0;
-
- *subid <<= 7;
- *subid |= ch & 0x7F;
- } while ((ch & 0x80) == 0x80);
- return 1;
-}
-
-static int
-asn1_oid_decode(struct asn1_ctx *ctx,
- unsigned char *eoc, unsigned long **oid, unsigned int *len)
-{
- unsigned long subid;
- unsigned int size;
- unsigned long *optr;
-
- size = eoc - ctx->pointer + 1;
-
- /* first subid actually encodes first two subids */
- if (size < 2 || size > UINT_MAX/sizeof(unsigned long))
- return 0;
-
- *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC);
- if (*oid == NULL)
- return 0;
-
- optr = *oid;
-
- if (!asn1_subid_decode(ctx, &subid)) {
- kfree(*oid);
- *oid = NULL;
- return 0;
- }
-
- if (subid < 40) {
- optr[0] = 0;
- optr[1] = subid;
- } else if (subid < 80) {
- optr[0] = 1;
- optr[1] = subid - 40;
- } else {
- optr[0] = 2;
- optr[1] = subid - 80;
- }
-
- *len = 2;
- optr += 2;
-
- while (ctx->pointer < eoc) {
- if (++(*len) > size) {
- ctx->error = ASN1_ERR_DEC_BADVALUE;
- kfree(*oid);
- *oid = NULL;
- return 0;
- }
-
- if (!asn1_subid_decode(ctx, optr++)) {
- kfree(*oid);
- *oid = NULL;
- return 0;
- }
- }
- return 1;
-}
-
-static int
-compare_oid(unsigned long *oid1, unsigned int oid1len,
- unsigned long *oid2, unsigned int oid2len)
-{
- unsigned int i;
-
- if (oid1len != oid2len)
- return 0;
- else {
- for (i = 0; i < oid1len; i++) {
- if (oid1[i] != oid2[i])
- return 0;
- }
- return 1;
- }
-}
-
- /* BB check for endian conversion issues here */
-
-int
-decode_negTokenInit(unsigned char *security_blob, int length,
- struct TCP_Server_Info *server)
-{
- struct asn1_ctx ctx;
- unsigned char *end;
- unsigned char *sequence_end;
- unsigned long *oid = NULL;
- unsigned int cls, con, tag, oidlen, rc;
-
- /* cifs_dump_mem(" Received SecBlob ", security_blob, length); */
-
- asn1_open(&ctx, security_blob, length);
-
- /* GSSAPI header */
- if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
- cFYI(1, "Error decoding negTokenInit header");
- return 0;
- } else if ((cls != ASN1_APL) || (con != ASN1_CON)
- || (tag != ASN1_EOC)) {
- cFYI(1, "cls = %d con = %d tag = %d", cls, con, tag);
- return 0;
- }
-
- /* Check for SPNEGO OID -- remember to free obj->oid */
- rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag);
- if (rc) {
- if ((tag == ASN1_OJI) && (con == ASN1_PRI) &&
- (cls == ASN1_UNI)) {
- rc = asn1_oid_decode(&ctx, end, &oid, &oidlen);
- if (rc) {
- rc = compare_oid(oid, oidlen, SPNEGO_OID,
- SPNEGO_OID_LEN);
- kfree(oid);
- }
- } else
- rc = 0;
- }
-
- /* SPNEGO OID not present or garbled -- bail out */
- if (!rc) {
- cFYI(1, "Error decoding negTokenInit header");
- return 0;
- }
-
- /* SPNEGO */
- if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
- cFYI(1, "Error decoding negTokenInit");
- return 0;
- } else if ((cls != ASN1_CTX) || (con != ASN1_CON)
- || (tag != ASN1_EOC)) {
- cFYI(1, "cls = %d con = %d tag = %d end = %p (%d) exit 0",
- cls, con, tag, end, *end);
- return 0;
- }
-
- /* negTokenInit */
- if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
- cFYI(1, "Error decoding negTokenInit");
- return 0;
- } else if ((cls != ASN1_UNI) || (con != ASN1_CON)
- || (tag != ASN1_SEQ)) {
- cFYI(1, "cls = %d con = %d tag = %d end = %p (%d) exit 1",
- cls, con, tag, end, *end);
- return 0;
- }
-
- /* sequence */
- if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
- cFYI(1, "Error decoding 2nd part of negTokenInit");
- return 0;
- } else if ((cls != ASN1_CTX) || (con != ASN1_CON)
- || (tag != ASN1_EOC)) {
- cFYI(1, "cls = %d con = %d tag = %d end = %p (%d) exit 0",
- cls, con, tag, end, *end);
- return 0;
- }
-
- /* sequence of */
- if (asn1_header_decode
- (&ctx, &sequence_end, &cls, &con, &tag) == 0) {
- cFYI(1, "Error decoding 2nd part of negTokenInit");
- return 0;
- } else if ((cls != ASN1_UNI) || (con != ASN1_CON)
- || (tag != ASN1_SEQ)) {
- cFYI(1, "cls = %d con = %d tag = %d end = %p (%d) exit 1",
- cls, con, tag, end, *end);
- return 0;
- }
-
- /* list of security mechanisms */
- while (!asn1_eoc_decode(&ctx, sequence_end)) {
- rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag);
- if (!rc) {
- cFYI(1, "Error decoding negTokenInit hdr exit2");
- return 0;
- }
- if ((tag == ASN1_OJI) && (con == ASN1_PRI)) {
- if (asn1_oid_decode(&ctx, end, &oid, &oidlen)) {
-
- cFYI(1, "OID len = %d oid = 0x%lx 0x%lx "
- "0x%lx 0x%lx", oidlen, *oid,
- *(oid + 1), *(oid + 2), *(oid + 3));
-
- if (compare_oid(oid, oidlen, MSKRB5_OID,
- MSKRB5_OID_LEN))
- server->sec_mskerberos = true;
- else if (compare_oid(oid, oidlen, KRB5U2U_OID,
- KRB5U2U_OID_LEN))
- server->sec_kerberosu2u = true;
- else if (compare_oid(oid, oidlen, KRB5_OID,
- KRB5_OID_LEN))
- server->sec_kerberos = true;
- else if (compare_oid(oid, oidlen, NTLMSSP_OID,
- NTLMSSP_OID_LEN))
- server->sec_ntlmssp = true;
-
- kfree(oid);
- }
- } else {
- cFYI(1, "Should be an oid what is going on?");
- }
- }
-
- /* mechlistMIC */
- if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
- /* Check if we have reached the end of the blob, but with
- no mechListMic (e.g. NTLMSSP instead of KRB5) */
- if (ctx.error == ASN1_ERR_DEC_EMPTY)
- goto decode_negtoken_exit;
- cFYI(1, "Error decoding last part negTokenInit exit3");
- return 0;
- } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) {
- /* tag = 3 indicating mechListMIC */
- cFYI(1, "Exit 4 cls = %d con = %d tag = %d end = %p (%d)",
- cls, con, tag, end, *end);
- return 0;
- }
-
- /* sequence */
- if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
- cFYI(1, "Error decoding last part negTokenInit exit5");
- return 0;
- } else if ((cls != ASN1_UNI) || (con != ASN1_CON)
- || (tag != ASN1_SEQ)) {
- cFYI(1, "cls = %d con = %d tag = %d end = %p (%d)",
- cls, con, tag, end, *end);
- }
-
- /* sequence of */
- if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
- cFYI(1, "Error decoding last part negTokenInit exit 7");
- return 0;
- } else if ((cls != ASN1_CTX) || (con != ASN1_CON)) {
- cFYI(1, "Exit 8 cls = %d con = %d tag = %d end = %p (%d)",
- cls, con, tag, end, *end);
- return 0;
- }
-
- /* general string */
- if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
- cFYI(1, "Error decoding last part negTokenInit exit9");
- return 0;
- } else if ((cls != ASN1_UNI) || (con != ASN1_PRI)
- || (tag != ASN1_GENSTR)) {
- cFYI(1, "Exit10 cls = %d con = %d tag = %d end = %p (%d)",
- cls, con, tag, end, *end);
- return 0;
- }
- cFYI(1, "Need to call asn1_octets_decode() function for %s",
- ctx.pointer); /* is this UTF-8 or ASCII? */
-decode_negtoken_exit:
- return 1;
-}
diff --git a/ANDROID_3.4.5/fs/cifs/cache.c b/ANDROID_3.4.5/fs/cifs/cache.c
deleted file mode 100644
index 545509c3..00000000
--- a/ANDROID_3.4.5/fs/cifs/cache.c
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * fs/cifs/cache.c - CIFS filesystem cache index structure definitions
- *
- * Copyright (c) 2010 Novell, Inc.
- * Authors(s): Suresh Jayaraman (sjayaraman@suse.de>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include "fscache.h"
-#include "cifs_debug.h"
-
-/*
- * CIFS filesystem definition for FS-Cache
- */
-struct fscache_netfs cifs_fscache_netfs = {
- .name = "cifs",
- .version = 0,
-};
-
-/*
- * Register CIFS for caching with FS-Cache
- */
-int cifs_fscache_register(void)
-{
- return fscache_register_netfs(&cifs_fscache_netfs);
-}
-
-/*
- * Unregister CIFS for caching
- */
-void cifs_fscache_unregister(void)
-{
- fscache_unregister_netfs(&cifs_fscache_netfs);
-}
-
-/*
- * Key layout of CIFS server cache index object
- */
-struct cifs_server_key {
- uint16_t family; /* address family */
- __be16 port; /* IP port */
- union {
- struct in_addr ipv4_addr;
- struct in6_addr ipv6_addr;
- } addr[0];
-};
-
-/*
- * Server object keyed by {IPaddress,port,family} tuple
- */
-static uint16_t cifs_server_get_key(const void *cookie_netfs_data,
- void *buffer, uint16_t maxbuf)
-{
- const struct TCP_Server_Info *server = cookie_netfs_data;
- const struct sockaddr *sa = (struct sockaddr *) &server->dstaddr;
- const struct sockaddr_in *addr = (struct sockaddr_in *) sa;
- const struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) sa;
- struct cifs_server_key *key = buffer;
- uint16_t key_len = sizeof(struct cifs_server_key);
-
- memset(key, 0, key_len);
-
- /*
- * Should not be a problem as sin_family/sin6_family overlays
- * sa_family field
- */
- switch (sa->sa_family) {
- case AF_INET:
- key->family = sa->sa_family;
- key->port = addr->sin_port;
- key->addr[0].ipv4_addr = addr->sin_addr;
- key_len += sizeof(key->addr[0].ipv4_addr);
- break;
-
- case AF_INET6:
- key->family = sa->sa_family;
- key->port = addr6->sin6_port;
- key->addr[0].ipv6_addr = addr6->sin6_addr;
- key_len += sizeof(key->addr[0].ipv6_addr);
- break;
-
- default:
- cERROR(1, "Unknown network family '%d'", sa->sa_family);
- key_len = 0;
- break;
- }
-
- return key_len;
-}
-
-/*
- * Server object for FS-Cache
- */
-const struct fscache_cookie_def cifs_fscache_server_index_def = {
- .name = "CIFS.server",
- .type = FSCACHE_COOKIE_TYPE_INDEX,
- .get_key = cifs_server_get_key,
-};
-
-/*
- * Auxiliary data attached to CIFS superblock within the cache
- */
-struct cifs_fscache_super_auxdata {
- u64 resource_id; /* unique server resource id */
-};
-
-static char *extract_sharename(const char *treename)
-{
- const char *src;
- char *delim, *dst;
- int len;
-
- /* skip double chars at the beginning */
- src = treename + 2;
-
- /* share name is always preceded by '\\' now */
- delim = strchr(src, '\\');
- if (!delim)
- return ERR_PTR(-EINVAL);
- delim++;
- len = strlen(delim);
-
- /* caller has to free the memory */
- dst = kstrndup(delim, len, GFP_KERNEL);
- if (!dst)
- return ERR_PTR(-ENOMEM);
-
- return dst;
-}
-
-/*
- * Superblock object currently keyed by share name
- */
-static uint16_t cifs_super_get_key(const void *cookie_netfs_data, void *buffer,
- uint16_t maxbuf)
-{
- const struct cifs_tcon *tcon = cookie_netfs_data;
- char *sharename;
- uint16_t len;
-
- sharename = extract_sharename(tcon->treeName);
- if (IS_ERR(sharename)) {
- cFYI(1, "%s: couldn't extract sharename\n", __func__);
- sharename = NULL;
- return 0;
- }
-
- len = strlen(sharename);
- if (len > maxbuf)
- return 0;
-
- memcpy(buffer, sharename, len);
-
- kfree(sharename);
-
- return len;
-}
-
-static uint16_t
-cifs_fscache_super_get_aux(const void *cookie_netfs_data, void *buffer,
- uint16_t maxbuf)
-{
- struct cifs_fscache_super_auxdata auxdata;
- const struct cifs_tcon *tcon = cookie_netfs_data;
-
- memset(&auxdata, 0, sizeof(auxdata));
- auxdata.resource_id = tcon->resource_id;
-
- if (maxbuf > sizeof(auxdata))
- maxbuf = sizeof(auxdata);
-
- memcpy(buffer, &auxdata, maxbuf);
-
- return maxbuf;
-}
-
-static enum
-fscache_checkaux cifs_fscache_super_check_aux(void *cookie_netfs_data,
- const void *data,
- uint16_t datalen)
-{
- struct cifs_fscache_super_auxdata auxdata;
- const struct cifs_tcon *tcon = cookie_netfs_data;
-
- if (datalen != sizeof(auxdata))
- return FSCACHE_CHECKAUX_OBSOLETE;
-
- memset(&auxdata, 0, sizeof(auxdata));
- auxdata.resource_id = tcon->resource_id;
-
- if (memcmp(data, &auxdata, datalen) != 0)
- return FSCACHE_CHECKAUX_OBSOLETE;
-
- return FSCACHE_CHECKAUX_OKAY;
-}
-
-/*
- * Superblock object for FS-Cache
- */
-const struct fscache_cookie_def cifs_fscache_super_index_def = {
- .name = "CIFS.super",
- .type = FSCACHE_COOKIE_TYPE_INDEX,
- .get_key = cifs_super_get_key,
- .get_aux = cifs_fscache_super_get_aux,
- .check_aux = cifs_fscache_super_check_aux,
-};
-
-/*
- * Auxiliary data attached to CIFS inode within the cache
- */
-struct cifs_fscache_inode_auxdata {
- struct timespec last_write_time;
- struct timespec last_change_time;
- u64 eof;
-};
-
-static uint16_t cifs_fscache_inode_get_key(const void *cookie_netfs_data,
- void *buffer, uint16_t maxbuf)
-{
- const struct cifsInodeInfo *cifsi = cookie_netfs_data;
- uint16_t keylen;
-
- /* use the UniqueId as the key */
- keylen = sizeof(cifsi->uniqueid);
- if (keylen > maxbuf)
- keylen = 0;
- else
- memcpy(buffer, &cifsi->uniqueid, keylen);
-
- return keylen;
-}
-
-static void
-cifs_fscache_inode_get_attr(const void *cookie_netfs_data, uint64_t *size)
-{
- const struct cifsInodeInfo *cifsi = cookie_netfs_data;
-
- *size = cifsi->vfs_inode.i_size;
-}
-
-static uint16_t
-cifs_fscache_inode_get_aux(const void *cookie_netfs_data, void *buffer,
- uint16_t maxbuf)
-{
- struct cifs_fscache_inode_auxdata auxdata;
- const struct cifsInodeInfo *cifsi = cookie_netfs_data;
-
- memset(&auxdata, 0, sizeof(auxdata));
- auxdata.eof = cifsi->server_eof;
- auxdata.last_write_time = cifsi->vfs_inode.i_mtime;
- auxdata.last_change_time = cifsi->vfs_inode.i_ctime;
-
- if (maxbuf > sizeof(auxdata))
- maxbuf = sizeof(auxdata);
-
- memcpy(buffer, &auxdata, maxbuf);
-
- return maxbuf;
-}
-
-static enum
-fscache_checkaux cifs_fscache_inode_check_aux(void *cookie_netfs_data,
- const void *data,
- uint16_t datalen)
-{
- struct cifs_fscache_inode_auxdata auxdata;
- struct cifsInodeInfo *cifsi = cookie_netfs_data;
-
- if (datalen != sizeof(auxdata))
- return FSCACHE_CHECKAUX_OBSOLETE;
-
- memset(&auxdata, 0, sizeof(auxdata));
- auxdata.eof = cifsi->server_eof;
- auxdata.last_write_time = cifsi->vfs_inode.i_mtime;
- auxdata.last_change_time = cifsi->vfs_inode.i_ctime;
-
- if (memcmp(data, &auxdata, datalen) != 0)
- return FSCACHE_CHECKAUX_OBSOLETE;
-
- return FSCACHE_CHECKAUX_OKAY;
-}
-
-static void cifs_fscache_inode_now_uncached(void *cookie_netfs_data)
-{
- struct cifsInodeInfo *cifsi = cookie_netfs_data;
- struct pagevec pvec;
- pgoff_t first;
- int loop, nr_pages;
-
- pagevec_init(&pvec, 0);
- first = 0;
-
- cFYI(1, "%s: cifs inode 0x%p now uncached", __func__, cifsi);
-
- for (;;) {
- nr_pages = pagevec_lookup(&pvec,
- cifsi->vfs_inode.i_mapping, first,
- PAGEVEC_SIZE - pagevec_count(&pvec));
- if (!nr_pages)
- break;
-
- for (loop = 0; loop < nr_pages; loop++)
- ClearPageFsCache(pvec.pages[loop]);
-
- first = pvec.pages[nr_pages - 1]->index + 1;
-
- pvec.nr = nr_pages;
- pagevec_release(&pvec);
- cond_resched();
- }
-}
-
-const struct fscache_cookie_def cifs_fscache_inode_object_def = {
- .name = "CIFS.uniqueid",
- .type = FSCACHE_COOKIE_TYPE_DATAFILE,
- .get_key = cifs_fscache_inode_get_key,
- .get_attr = cifs_fscache_inode_get_attr,
- .get_aux = cifs_fscache_inode_get_aux,
- .check_aux = cifs_fscache_inode_check_aux,
- .now_uncached = cifs_fscache_inode_now_uncached,
-};
diff --git a/ANDROID_3.4.5/fs/cifs/cifs_debug.c b/ANDROID_3.4.5/fs/cifs/cifs_debug.c
deleted file mode 100644
index 27046462..00000000
--- a/ANDROID_3.4.5/fs/cifs/cifs_debug.c
+++ /dev/null
@@ -1,751 +0,0 @@
-/*
- * fs/cifs_debug.c
- *
- * Copyright (C) International Business Machines Corp., 2000,2005
- *
- * Modified by Steve French (sfrench@us.ibm.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <linux/fs.h>
-#include <linux/string.h>
-#include <linux/ctype.h>
-#include <linux/module.h>
-#include <linux/proc_fs.h>
-#include <asm/uaccess.h>
-#include "cifspdu.h"
-#include "cifsglob.h"
-#include "cifsproto.h"
-#include "cifs_debug.h"
-#include "cifsfs.h"
-
-void
-cifs_dump_mem(char *label, void *data, int length)
-{
- int i, j;
- int *intptr = data;
- char *charptr = data;
- char buf[10], line[80];
-
- printk(KERN_DEBUG "%s: dump of %d bytes of data at 0x%p\n",
- label, length, data);
- for (i = 0; i < length; i += 16) {
- line[0] = 0;
- for (j = 0; (j < 4) && (i + j * 4 < length); j++) {
- sprintf(buf, " %08x", intptr[i / 4 + j]);
- strcat(line, buf);
- }
- buf[0] = ' ';
- buf[2] = 0;
- for (j = 0; (j < 16) && (i + j < length); j++) {
- buf[1] = isprint(charptr[i + j]) ? charptr[i + j] : '.';
- strcat(line, buf);
- }
- printk(KERN_DEBUG "%s\n", line);
- }
-}
-
-#ifdef CONFIG_CIFS_DEBUG2
-void cifs_dump_detail(void *buf)
-{
- struct smb_hdr *smb = (struct smb_hdr *)buf;
-
- cERROR(1, "Cmd: %d Err: 0x%x Flags: 0x%x Flgs2: 0x%x Mid: %d Pid: %d",
- smb->Command, smb->Status.CifsError,
- smb->Flags, smb->Flags2, smb->Mid, smb->Pid);
- cERROR(1, "smb buf %p len %d", smb, smbCalcSize(smb));
-}
-
-void cifs_dump_mids(struct TCP_Server_Info *server)
-{
- struct list_head *tmp;
- struct mid_q_entry *mid_entry;
-
- if (server == NULL)
- return;
-
- cERROR(1, "Dump pending requests:");
- spin_lock(&GlobalMid_Lock);
- list_for_each(tmp, &server->pending_mid_q) {
- mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
- cERROR(1, "State: %d Cmd: %d Pid: %d Cbdata: %p Mid %llu",
- mid_entry->mid_state,
- le16_to_cpu(mid_entry->command),
- mid_entry->pid,
- mid_entry->callback_data,
- mid_entry->mid);
-#ifdef CONFIG_CIFS_STATS2
- cERROR(1, "IsLarge: %d buf: %p time rcv: %ld now: %ld",
- mid_entry->large_buf,
- mid_entry->resp_buf,
- mid_entry->when_received,
- jiffies);
-#endif /* STATS2 */
- cERROR(1, "IsMult: %d IsEnd: %d", mid_entry->multiRsp,
- mid_entry->multiEnd);
- if (mid_entry->resp_buf) {
- cifs_dump_detail(mid_entry->resp_buf);
- cifs_dump_mem("existing buf: ",
- mid_entry->resp_buf, 62);
- }
- }
- spin_unlock(&GlobalMid_Lock);
-}
-#endif /* CONFIG_CIFS_DEBUG2 */
-
-#ifdef CONFIG_PROC_FS
-static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
-{
- struct list_head *tmp1, *tmp2, *tmp3;
- struct mid_q_entry *mid_entry;
- struct TCP_Server_Info *server;
- struct cifs_ses *ses;
- struct cifs_tcon *tcon;
- int i, j;
- __u32 dev_type;
-
- seq_puts(m,
- "Display Internal CIFS Data Structures for Debugging\n"
- "---------------------------------------------------\n");
- seq_printf(m, "CIFS Version %s\n", CIFS_VERSION);
- seq_printf(m, "Features:");
-#ifdef CONFIG_CIFS_DFS_UPCALL
- seq_printf(m, " dfs");
-#endif
-#ifdef CONFIG_CIFS_FSCACHE
- seq_printf(m, " fscache");
-#endif
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
- seq_printf(m, " lanman");
-#endif
-#ifdef CONFIG_CIFS_POSIX
- seq_printf(m, " posix");
-#endif
-#ifdef CONFIG_CIFS_UPCALL
- seq_printf(m, " spnego");
-#endif
-#ifdef CONFIG_CIFS_XATTR
- seq_printf(m, " xattr");
-#endif
-#ifdef CONFIG_CIFS_ACL
- seq_printf(m, " acl");
-#endif
- seq_putc(m, '\n');
- seq_printf(m, "Active VFS Requests: %d\n", GlobalTotalActiveXid);
- seq_printf(m, "Servers:");
-
- i = 0;
- spin_lock(&cifs_tcp_ses_lock);
- list_for_each(tmp1, &cifs_tcp_ses_list) {
- server = list_entry(tmp1, struct TCP_Server_Info,
- tcp_ses_list);
- i++;
- list_for_each(tmp2, &server->smb_ses_list) {
- ses = list_entry(tmp2, struct cifs_ses,
- smb_ses_list);
- if ((ses->serverDomain == NULL) ||
- (ses->serverOS == NULL) ||
- (ses->serverNOS == NULL)) {
- seq_printf(m, "\n%d) entry for %s not fully "
- "displayed\n\t", i, ses->serverName);
- } else {
- seq_printf(m,
- "\n%d) Name: %s Domain: %s Uses: %d OS:"
- " %s\n\tNOS: %s\tCapability: 0x%x\n\tSMB"
- " session status: %d\t",
- i, ses->serverName, ses->serverDomain,
- ses->ses_count, ses->serverOS, ses->serverNOS,
- ses->capabilities, ses->status);
- }
- seq_printf(m, "TCP status: %d\n\tLocal Users To "
- "Server: %d SecMode: 0x%x Req On Wire: %d",
- server->tcpStatus, server->srv_count,
- server->sec_mode, in_flight(server));
-
-#ifdef CONFIG_CIFS_STATS2
- seq_printf(m, " In Send: %d In MaxReq Wait: %d",
- atomic_read(&server->in_send),
- atomic_read(&server->num_waiters));
-#endif
-
- seq_puts(m, "\n\tShares:");
- j = 0;
- list_for_each(tmp3, &ses->tcon_list) {
- tcon = list_entry(tmp3, struct cifs_tcon,
- tcon_list);
- ++j;
- dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType);
- seq_printf(m, "\n\t%d) %s Mounts: %d ", j,
- tcon->treeName, tcon->tc_count);
- if (tcon->nativeFileSystem) {
- seq_printf(m, "Type: %s ",
- tcon->nativeFileSystem);
- }
- seq_printf(m, "DevInfo: 0x%x Attributes: 0x%x"
- "\nPathComponentMax: %d Status: 0x%d",
- le32_to_cpu(tcon->fsDevInfo.DeviceCharacteristics),
- le32_to_cpu(tcon->fsAttrInfo.Attributes),
- le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength),
- tcon->tidStatus);
- if (dev_type == FILE_DEVICE_DISK)
- seq_puts(m, " type: DISK ");
- else if (dev_type == FILE_DEVICE_CD_ROM)
- seq_puts(m, " type: CDROM ");
- else
- seq_printf(m, " type: %d ", dev_type);
-
- if (tcon->need_reconnect)
- seq_puts(m, "\tDISCONNECTED ");
- seq_putc(m, '\n');
- }
-
- seq_puts(m, "\n\tMIDs:\n");
-
- spin_lock(&GlobalMid_Lock);
- list_for_each(tmp3, &server->pending_mid_q) {
- mid_entry = list_entry(tmp3, struct mid_q_entry,
- qhead);
- seq_printf(m, "\tState: %d com: %d pid:"
- " %d cbdata: %p mid %llu\n",
- mid_entry->mid_state,
- le16_to_cpu(mid_entry->command),
- mid_entry->pid,
- mid_entry->callback_data,
- mid_entry->mid);
- }
- spin_unlock(&GlobalMid_Lock);
- }
- }
- spin_unlock(&cifs_tcp_ses_lock);
- seq_putc(m, '\n');
-
- /* BB add code to dump additional info such as TCP session info now */
- return 0;
-}
-
-static int cifs_debug_data_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, cifs_debug_data_proc_show, NULL);
-}
-
-static const struct file_operations cifs_debug_data_proc_fops = {
- .owner = THIS_MODULE,
- .open = cifs_debug_data_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-#ifdef CONFIG_CIFS_STATS
-static ssize_t cifs_stats_proc_write(struct file *file,
- const char __user *buffer, size_t count, loff_t *ppos)
-{
- char c;
- int rc;
- struct list_head *tmp1, *tmp2, *tmp3;
- struct TCP_Server_Info *server;
- struct cifs_ses *ses;
- struct cifs_tcon *tcon;
-
- rc = get_user(c, buffer);
- if (rc)
- return rc;
-
- if (c == '1' || c == 'y' || c == 'Y' || c == '0') {
-#ifdef CONFIG_CIFS_STATS2
- atomic_set(&totBufAllocCount, 0);
- atomic_set(&totSmBufAllocCount, 0);
-#endif /* CONFIG_CIFS_STATS2 */
- spin_lock(&cifs_tcp_ses_lock);
- list_for_each(tmp1, &cifs_tcp_ses_list) {
- server = list_entry(tmp1, struct TCP_Server_Info,
- tcp_ses_list);
- list_for_each(tmp2, &server->smb_ses_list) {
- ses = list_entry(tmp2, struct cifs_ses,
- smb_ses_list);
- list_for_each(tmp3, &ses->tcon_list) {
- tcon = list_entry(tmp3,
- struct cifs_tcon,
- tcon_list);
- atomic_set(&tcon->num_smbs_sent, 0);
- atomic_set(&tcon->num_writes, 0);
- atomic_set(&tcon->num_reads, 0);
- atomic_set(&tcon->num_oplock_brks, 0);
- atomic_set(&tcon->num_opens, 0);
- atomic_set(&tcon->num_posixopens, 0);
- atomic_set(&tcon->num_posixmkdirs, 0);
- atomic_set(&tcon->num_closes, 0);
- atomic_set(&tcon->num_deletes, 0);
- atomic_set(&tcon->num_mkdirs, 0);
- atomic_set(&tcon->num_rmdirs, 0);
- atomic_set(&tcon->num_renames, 0);
- atomic_set(&tcon->num_t2renames, 0);
- atomic_set(&tcon->num_ffirst, 0);
- atomic_set(&tcon->num_fnext, 0);
- atomic_set(&tcon->num_fclose, 0);
- atomic_set(&tcon->num_hardlinks, 0);
- atomic_set(&tcon->num_symlinks, 0);
- atomic_set(&tcon->num_locks, 0);
- }
- }
- }
- spin_unlock(&cifs_tcp_ses_lock);
- }
-
- return count;
-}
-
-static int cifs_stats_proc_show(struct seq_file *m, void *v)
-{
- int i;
- struct list_head *tmp1, *tmp2, *tmp3;
- struct TCP_Server_Info *server;
- struct cifs_ses *ses;
- struct cifs_tcon *tcon;
-
- seq_printf(m,
- "Resources in use\nCIFS Session: %d\n",
- sesInfoAllocCount.counter);
- seq_printf(m, "Share (unique mount targets): %d\n",
- tconInfoAllocCount.counter);
- seq_printf(m, "SMB Request/Response Buffer: %d Pool size: %d\n",
- bufAllocCount.counter,
- cifs_min_rcv + tcpSesAllocCount.counter);
- seq_printf(m, "SMB Small Req/Resp Buffer: %d Pool size: %d\n",
- smBufAllocCount.counter, cifs_min_small);
-#ifdef CONFIG_CIFS_STATS2
- seq_printf(m, "Total Large %d Small %d Allocations\n",
- atomic_read(&totBufAllocCount),
- atomic_read(&totSmBufAllocCount));
-#endif /* CONFIG_CIFS_STATS2 */
-
- seq_printf(m, "Operations (MIDs): %d\n", atomic_read(&midCount));
- seq_printf(m,
- "\n%d session %d share reconnects\n",
- tcpSesReconnectCount.counter, tconInfoReconnectCount.counter);
-
- seq_printf(m,
- "Total vfs operations: %d maximum at one time: %d\n",
- GlobalCurrentXid, GlobalMaxActiveXid);
-
- i = 0;
- spin_lock(&cifs_tcp_ses_lock);
- list_for_each(tmp1, &cifs_tcp_ses_list) {
- server = list_entry(tmp1, struct TCP_Server_Info,
- tcp_ses_list);
- list_for_each(tmp2, &server->smb_ses_list) {
- ses = list_entry(tmp2, struct cifs_ses,
- smb_ses_list);
- list_for_each(tmp3, &ses->tcon_list) {
- tcon = list_entry(tmp3,
- struct cifs_tcon,
- tcon_list);
- i++;
- seq_printf(m, "\n%d) %s", i, tcon->treeName);
- if (tcon->need_reconnect)
- seq_puts(m, "\tDISCONNECTED ");
- seq_printf(m, "\nSMBs: %d Oplock Breaks: %d",
- atomic_read(&tcon->num_smbs_sent),
- atomic_read(&tcon->num_oplock_brks));
- seq_printf(m, "\nReads: %d Bytes: %lld",
- atomic_read(&tcon->num_reads),
- (long long)(tcon->bytes_read));
- seq_printf(m, "\nWrites: %d Bytes: %lld",
- atomic_read(&tcon->num_writes),
- (long long)(tcon->bytes_written));
- seq_printf(m, "\nFlushes: %d",
- atomic_read(&tcon->num_flushes));
- seq_printf(m, "\nLocks: %d HardLinks: %d "
- "Symlinks: %d",
- atomic_read(&tcon->num_locks),
- atomic_read(&tcon->num_hardlinks),
- atomic_read(&tcon->num_symlinks));
- seq_printf(m, "\nOpens: %d Closes: %d "
- "Deletes: %d",
- atomic_read(&tcon->num_opens),
- atomic_read(&tcon->num_closes),
- atomic_read(&tcon->num_deletes));
- seq_printf(m, "\nPosix Opens: %d "
- "Posix Mkdirs: %d",
- atomic_read(&tcon->num_posixopens),
- atomic_read(&tcon->num_posixmkdirs));
- seq_printf(m, "\nMkdirs: %d Rmdirs: %d",
- atomic_read(&tcon->num_mkdirs),
- atomic_read(&tcon->num_rmdirs));
- seq_printf(m, "\nRenames: %d T2 Renames %d",
- atomic_read(&tcon->num_renames),
- atomic_read(&tcon->num_t2renames));
- seq_printf(m, "\nFindFirst: %d FNext %d "
- "FClose %d",
- atomic_read(&tcon->num_ffirst),
- atomic_read(&tcon->num_fnext),
- atomic_read(&tcon->num_fclose));
- }
- }
- }
- spin_unlock(&cifs_tcp_ses_lock);
-
- seq_putc(m, '\n');
- return 0;
-}
-
-static int cifs_stats_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, cifs_stats_proc_show, NULL);
-}
-
-static const struct file_operations cifs_stats_proc_fops = {
- .owner = THIS_MODULE,
- .open = cifs_stats_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- .write = cifs_stats_proc_write,
-};
-#endif /* STATS */
-
-static struct proc_dir_entry *proc_fs_cifs;
-static const struct file_operations cifsFYI_proc_fops;
-static const struct file_operations cifs_lookup_cache_proc_fops;
-static const struct file_operations traceSMB_proc_fops;
-static const struct file_operations cifs_multiuser_mount_proc_fops;
-static const struct file_operations cifs_security_flags_proc_fops;
-static const struct file_operations cifs_linux_ext_proc_fops;
-
-void
-cifs_proc_init(void)
-{
- proc_fs_cifs = proc_mkdir("fs/cifs", NULL);
- if (proc_fs_cifs == NULL)
- return;
-
- proc_create("DebugData", 0, proc_fs_cifs, &cifs_debug_data_proc_fops);
-
-#ifdef CONFIG_CIFS_STATS
- proc_create("Stats", 0, proc_fs_cifs, &cifs_stats_proc_fops);
-#endif /* STATS */
- proc_create("cifsFYI", 0, proc_fs_cifs, &cifsFYI_proc_fops);
- proc_create("traceSMB", 0, proc_fs_cifs, &traceSMB_proc_fops);
- proc_create("LinuxExtensionsEnabled", 0, proc_fs_cifs,
- &cifs_linux_ext_proc_fops);
- proc_create("MultiuserMount", 0, proc_fs_cifs,
- &cifs_multiuser_mount_proc_fops);
- proc_create("SecurityFlags", 0, proc_fs_cifs,
- &cifs_security_flags_proc_fops);
- proc_create("LookupCacheEnabled", 0, proc_fs_cifs,
- &cifs_lookup_cache_proc_fops);
-}
-
-void
-cifs_proc_clean(void)
-{
- if (proc_fs_cifs == NULL)
- return;
-
- remove_proc_entry("DebugData", proc_fs_cifs);
- remove_proc_entry("cifsFYI", proc_fs_cifs);
- remove_proc_entry("traceSMB", proc_fs_cifs);
-#ifdef CONFIG_CIFS_STATS
- remove_proc_entry("Stats", proc_fs_cifs);
-#endif
- remove_proc_entry("MultiuserMount", proc_fs_cifs);
- remove_proc_entry("SecurityFlags", proc_fs_cifs);
- remove_proc_entry("LinuxExtensionsEnabled", proc_fs_cifs);
- remove_proc_entry("LookupCacheEnabled", proc_fs_cifs);
- remove_proc_entry("fs/cifs", NULL);
-}
-
-static int cifsFYI_proc_show(struct seq_file *m, void *v)
-{
- seq_printf(m, "%d\n", cifsFYI);
- return 0;
-}
-
-static int cifsFYI_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, cifsFYI_proc_show, NULL);
-}
-
-static ssize_t cifsFYI_proc_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *ppos)
-{
- char c;
- int rc;
-
- rc = get_user(c, buffer);
- if (rc)
- return rc;
- if (c == '0' || c == 'n' || c == 'N')
- cifsFYI = 0;
- else if (c == '1' || c == 'y' || c == 'Y')
- cifsFYI = 1;
- else if ((c > '1') && (c <= '9'))
- cifsFYI = (int) (c - '0'); /* see cifs_debug.h for meanings */
-
- return count;
-}
-
-static const struct file_operations cifsFYI_proc_fops = {
- .owner = THIS_MODULE,
- .open = cifsFYI_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- .write = cifsFYI_proc_write,
-};
-
-static int cifs_linux_ext_proc_show(struct seq_file *m, void *v)
-{
- seq_printf(m, "%d\n", linuxExtEnabled);
- return 0;
-}
-
-static int cifs_linux_ext_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, cifs_linux_ext_proc_show, NULL);
-}
-
-static ssize_t cifs_linux_ext_proc_write(struct file *file,
- const char __user *buffer, size_t count, loff_t *ppos)
-{
- char c;
- int rc;
-
- rc = get_user(c, buffer);
- if (rc)
- return rc;
- if (c == '0' || c == 'n' || c == 'N')
- linuxExtEnabled = 0;
- else if (c == '1' || c == 'y' || c == 'Y')
- linuxExtEnabled = 1;
-
- return count;
-}
-
-static const struct file_operations cifs_linux_ext_proc_fops = {
- .owner = THIS_MODULE,
- .open = cifs_linux_ext_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- .write = cifs_linux_ext_proc_write,
-};
-
-static int cifs_lookup_cache_proc_show(struct seq_file *m, void *v)
-{
- seq_printf(m, "%d\n", lookupCacheEnabled);
- return 0;
-}
-
-static int cifs_lookup_cache_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, cifs_lookup_cache_proc_show, NULL);
-}
-
-static ssize_t cifs_lookup_cache_proc_write(struct file *file,
- const char __user *buffer, size_t count, loff_t *ppos)
-{
- char c;
- int rc;
-
- rc = get_user(c, buffer);
- if (rc)
- return rc;
- if (c == '0' || c == 'n' || c == 'N')
- lookupCacheEnabled = 0;
- else if (c == '1' || c == 'y' || c == 'Y')
- lookupCacheEnabled = 1;
-
- return count;
-}
-
-static const struct file_operations cifs_lookup_cache_proc_fops = {
- .owner = THIS_MODULE,
- .open = cifs_lookup_cache_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- .write = cifs_lookup_cache_proc_write,
-};
-
-static int traceSMB_proc_show(struct seq_file *m, void *v)
-{
- seq_printf(m, "%d\n", traceSMB);
- return 0;
-}
-
-static int traceSMB_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, traceSMB_proc_show, NULL);
-}
-
-static ssize_t traceSMB_proc_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *ppos)
-{
- char c;
- int rc;
-
- rc = get_user(c, buffer);
- if (rc)
- return rc;
- if (c == '0' || c == 'n' || c == 'N')
- traceSMB = 0;
- else if (c == '1' || c == 'y' || c == 'Y')
- traceSMB = 1;
-
- return count;
-}
-
-static const struct file_operations traceSMB_proc_fops = {
- .owner = THIS_MODULE,
- .open = traceSMB_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- .write = traceSMB_proc_write,
-};
-
-static int cifs_multiuser_mount_proc_show(struct seq_file *m, void *v)
-{
- seq_printf(m, "%d\n", multiuser_mount);
- return 0;
-}
-
-static int cifs_multiuser_mount_proc_open(struct inode *inode, struct file *fh)
-{
- return single_open(fh, cifs_multiuser_mount_proc_show, NULL);
-}
-
-static ssize_t cifs_multiuser_mount_proc_write(struct file *file,
- const char __user *buffer, size_t count, loff_t *ppos)
-{
- char c;
- int rc;
- static bool warned;
-
- rc = get_user(c, buffer);
- if (rc)
- return rc;
- if (c == '0' || c == 'n' || c == 'N')
- multiuser_mount = 0;
- else if (c == '1' || c == 'y' || c == 'Y') {
- multiuser_mount = 1;
- if (!warned) {
- warned = true;
- printk(KERN_WARNING "CIFS VFS: The legacy multiuser "
- "mount code is scheduled to be deprecated in "
- "3.5. Please switch to using the multiuser "
- "mount option.");
- }
- }
-
- return count;
-}
-
-static const struct file_operations cifs_multiuser_mount_proc_fops = {
- .owner = THIS_MODULE,
- .open = cifs_multiuser_mount_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- .write = cifs_multiuser_mount_proc_write,
-};
-
-static int cifs_security_flags_proc_show(struct seq_file *m, void *v)
-{
- seq_printf(m, "0x%x\n", global_secflags);
- return 0;
-}
-
-static int cifs_security_flags_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, cifs_security_flags_proc_show, NULL);
-}
-
-static ssize_t cifs_security_flags_proc_write(struct file *file,
- const char __user *buffer, size_t count, loff_t *ppos)
-{
- unsigned int flags;
- char flags_string[12];
- char c;
-
- if ((count < 1) || (count > 11))
- return -EINVAL;
-
- memset(flags_string, 0, 12);
-
- if (copy_from_user(flags_string, buffer, count))
- return -EFAULT;
-
- if (count < 3) {
- /* single char or single char followed by null */
- c = flags_string[0];
- if (c == '0' || c == 'n' || c == 'N') {
- global_secflags = CIFSSEC_DEF; /* default */
- return count;
- } else if (c == '1' || c == 'y' || c == 'Y') {
- global_secflags = CIFSSEC_MAX;
- return count;
- } else if (!isdigit(c)) {
- cERROR(1, "invalid flag %c", c);
- return -EINVAL;
- }
- }
- /* else we have a number */
-
- flags = simple_strtoul(flags_string, NULL, 0);
-
- cFYI(1, "sec flags 0x%x", flags);
-
- if (flags <= 0) {
- cERROR(1, "invalid security flags %s", flags_string);
- return -EINVAL;
- }
-
- if (flags & ~CIFSSEC_MASK) {
- cERROR(1, "attempt to set unsupported security flags 0x%x",
- flags & ~CIFSSEC_MASK);
- return -EINVAL;
- }
- /* flags look ok - update the global security flags for cifs module */
- global_secflags = flags;
- if (global_secflags & CIFSSEC_MUST_SIGN) {
- /* requiring signing implies signing is allowed */
- global_secflags |= CIFSSEC_MAY_SIGN;
- cFYI(1, "packet signing now required");
- } else if ((global_secflags & CIFSSEC_MAY_SIGN) == 0) {
- cFYI(1, "packet signing disabled");
- }
- /* BB should we turn on MAY flags for other MUST options? */
- return count;
-}
-
-static const struct file_operations cifs_security_flags_proc_fops = {
- .owner = THIS_MODULE,
- .open = cifs_security_flags_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- .write = cifs_security_flags_proc_write,
-};
-#else
-inline void cifs_proc_init(void)
-{
-}
-
-inline void cifs_proc_clean(void)
-{
-}
-#endif /* PROC_FS */
diff --git a/ANDROID_3.4.5/fs/cifs/cifs_debug.h b/ANDROID_3.4.5/fs/cifs/cifs_debug.h
deleted file mode 100644
index 566e0ae8..00000000
--- a/ANDROID_3.4.5/fs/cifs/cifs_debug.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- *
- * Copyright (c) International Business Machines Corp., 2000,2002
- * Modified by Steve French (sfrench@us.ibm.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
-*/
-#define CIFS_DEBUG /* BB temporary */
-
-#ifndef _H_CIFS_DEBUG
-#define _H_CIFS_DEBUG
-
-void cifs_dump_mem(char *label, void *data, int length);
-#ifdef CONFIG_CIFS_DEBUG2
-#define DBG2 2
-void cifs_dump_detail(void *);
-void cifs_dump_mids(struct TCP_Server_Info *);
-#else
-#define DBG2 0
-#endif
-extern int traceSMB; /* flag which enables the function below */
-void dump_smb(void *, int);
-#define CIFS_INFO 0x01
-#define CIFS_RC 0x02
-#define CIFS_TIMER 0x04
-
-/*
- * debug ON
- * --------
- */
-#ifdef CIFS_DEBUG
-
-/* information message: e.g., configuration, major event */
-extern int cifsFYI;
-#define cifsfyi(fmt, arg...) \
-do { \
- if (cifsFYI & CIFS_INFO) \
- printk(KERN_DEBUG "%s: " fmt "\n", __FILE__, ##arg); \
-} while (0)
-
-#define cFYI(set, fmt, arg...) \
-do { \
- if (set) \
- cifsfyi(fmt, ##arg); \
-} while (0)
-
-#define cifswarn(fmt, arg...) \
- printk(KERN_WARNING fmt "\n", ##arg)
-
-/* debug event message: */
-extern int cifsERROR;
-
-#define cEVENT(fmt, arg...) \
-do { \
- if (cifsERROR) \
- printk(KERN_EVENT "%s: " fmt "\n", __FILE__, ##arg); \
-} while (0)
-
-/* error event message: e.g., i/o error */
-#define cifserror(fmt, arg...) \
-do { \
- if (cifsERROR) \
- printk(KERN_ERR "CIFS VFS: " fmt "\n", ##arg); \
-} while (0)
-
-#define cERROR(set, fmt, arg...) \
-do { \
- if (set) \
- cifserror(fmt, ##arg); \
-} while (0)
-
-/*
- * debug OFF
- * ---------
- */
-#else /* _CIFS_DEBUG */
-#define cERROR(set, fmt, arg...)
-#define cEVENT(fmt, arg...)
-#define cFYI(set, fmt, arg...)
-#define cifserror(fmt, arg...)
-#endif /* _CIFS_DEBUG */
-
-#endif /* _H_CIFS_DEBUG */
diff --git a/ANDROID_3.4.5/fs/cifs/cifs_dfs_ref.c b/ANDROID_3.4.5/fs/cifs/cifs_dfs_ref.c
deleted file mode 100644
index 6873bb63..00000000
--- a/ANDROID_3.4.5/fs/cifs/cifs_dfs_ref.c
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * Contains the CIFS DFS referral mounting routines used for handling
- * traversal via DFS junction point
- *
- * Copyright (c) 2007 Igor Mammedov
- * Copyright (C) International Business Machines Corp., 2008
- * Author(s): Igor Mammedov (niallain@gmail.com)
- * Steve French (sfrench@us.ibm.com)
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <linux/dcache.h>
-#include <linux/mount.h>
-#include <linux/namei.h>
-#include <linux/slab.h>
-#include <linux/vfs.h>
-#include <linux/fs.h>
-#include "cifsglob.h"
-#include "cifsproto.h"
-#include "cifsfs.h"
-#include "dns_resolve.h"
-#include "cifs_debug.h"
-
-static LIST_HEAD(cifs_dfs_automount_list);
-
-static void cifs_dfs_expire_automounts(struct work_struct *work);
-static DECLARE_DELAYED_WORK(cifs_dfs_automount_task,
- cifs_dfs_expire_automounts);
-static int cifs_dfs_mountpoint_expiry_timeout = 500 * HZ;
-
-static void cifs_dfs_expire_automounts(struct work_struct *work)
-{
- struct list_head *list = &cifs_dfs_automount_list;
-
- mark_mounts_for_expiry(list);
- if (!list_empty(list))
- schedule_delayed_work(&cifs_dfs_automount_task,
- cifs_dfs_mountpoint_expiry_timeout);
-}
-
-void cifs_dfs_release_automount_timer(void)
-{
- BUG_ON(!list_empty(&cifs_dfs_automount_list));
- cancel_delayed_work_sync(&cifs_dfs_automount_task);
-}
-
-/**
- * cifs_get_share_name - extracts share name from UNC
- * @node_name: pointer to UNC string
- *
- * Extracts sharename form full UNC.
- * i.e. strips from UNC trailing path that is not part of share
- * name and fixup missing '\' in the beginning of DFS node refferal
- * if necessary.
- * Returns pointer to share name on success or ERR_PTR on error.
- * Caller is responsible for freeing returned string.
- */
-static char *cifs_get_share_name(const char *node_name)
-{
- int len;
- char *UNC;
- char *pSep;
-
- len = strlen(node_name);
- UNC = kmalloc(len+2 /*for term null and additional \ if it's missed */,
- GFP_KERNEL);
- if (!UNC)
- return ERR_PTR(-ENOMEM);
-
- /* get share name and server name */
- if (node_name[1] != '\\') {
- UNC[0] = '\\';
- strncpy(UNC+1, node_name, len);
- len++;
- UNC[len] = 0;
- } else {
- strncpy(UNC, node_name, len);
- UNC[len] = 0;
- }
-
- /* find server name end */
- pSep = memchr(UNC+2, '\\', len-2);
- if (!pSep) {
- cERROR(1, "%s: no server name end in node name: %s",
- __func__, node_name);
- kfree(UNC);
- return ERR_PTR(-EINVAL);
- }
-
- /* find sharename end */
- pSep++;
- pSep = memchr(UNC+(pSep-UNC), '\\', len-(pSep-UNC));
- if (pSep) {
- /* trim path up to sharename end
- * now we have share name in UNC */
- *pSep = 0;
- }
-
- return UNC;
-}
-
-
-/**
- * cifs_compose_mount_options - creates mount options for refferral
- * @sb_mountdata: parent/root DFS mount options (template)
- * @fullpath: full path in UNC format
- * @ref: server's referral
- * @devname: pointer for saving device name
- *
- * creates mount options for submount based on template options sb_mountdata
- * and replacing unc,ip,prefixpath options with ones we've got form ref_unc.
- *
- * Returns: pointer to new mount options or ERR_PTR.
- * Caller is responcible for freeing retunrned value if it is not error.
- */
-char *cifs_compose_mount_options(const char *sb_mountdata,
- const char *fullpath,
- const struct dfs_info3_param *ref,
- char **devname)
-{
- int rc;
- char *mountdata = NULL;
- int md_len;
- char *tkn_e;
- char *srvIP = NULL;
- char sep = ',';
- int off, noff;
-
- if (sb_mountdata == NULL)
- return ERR_PTR(-EINVAL);
-
- *devname = cifs_get_share_name(ref->node_name);
- if (IS_ERR(*devname)) {
- rc = PTR_ERR(*devname);
- *devname = NULL;
- goto compose_mount_options_err;
- }
-
- rc = dns_resolve_server_name_to_ip(*devname, &srvIP);
- if (rc < 0) {
- cFYI(1, "%s: Failed to resolve server part of %s to IP: %d",
- __func__, *devname, rc);
- goto compose_mount_options_err;
- }
-
- /* md_len = strlen(...) + 12 for 'sep+prefixpath='
- * assuming that we have 'unc=' and 'ip=' in
- * the original sb_mountdata
- */
- md_len = strlen(sb_mountdata) + rc + strlen(ref->node_name) + 12;
- mountdata = kzalloc(md_len+1, GFP_KERNEL);
- if (mountdata == NULL) {
- rc = -ENOMEM;
- goto compose_mount_options_err;
- }
-
- /* copy all options except of unc,ip,prefixpath */
- off = 0;
- if (strncmp(sb_mountdata, "sep=", 4) == 0) {
- sep = sb_mountdata[4];
- strncpy(mountdata, sb_mountdata, 5);
- off += 5;
- }
-
- do {
- tkn_e = strchr(sb_mountdata + off, sep);
- if (tkn_e == NULL)
- noff = strlen(sb_mountdata + off);
- else
- noff = tkn_e - (sb_mountdata + off) + 1;
-
- if (strnicmp(sb_mountdata + off, "unc=", 4) == 0) {
- off += noff;
- continue;
- }
- if (strnicmp(sb_mountdata + off, "ip=", 3) == 0) {
- off += noff;
- continue;
- }
- if (strnicmp(sb_mountdata + off, "prefixpath=", 11) == 0) {
- off += noff;
- continue;
- }
- strncat(mountdata, sb_mountdata + off, noff);
- off += noff;
- } while (tkn_e);
- strcat(mountdata, sb_mountdata + off);
- mountdata[md_len] = '\0';
-
- /* copy new IP and ref share name */
- if (mountdata[strlen(mountdata) - 1] != sep)
- strncat(mountdata, &sep, 1);
- strcat(mountdata, "ip=");
- strcat(mountdata, srvIP);
- strncat(mountdata, &sep, 1);
- strcat(mountdata, "unc=");
- strcat(mountdata, *devname);
-
- /* find & copy prefixpath */
- tkn_e = strchr(ref->node_name + 2, '\\');
- if (tkn_e == NULL) {
- /* invalid unc, missing share name*/
- rc = -EINVAL;
- goto compose_mount_options_err;
- }
-
- tkn_e = strchr(tkn_e + 1, '\\');
- if (tkn_e || (strlen(fullpath) - ref->path_consumed)) {
- strncat(mountdata, &sep, 1);
- strcat(mountdata, "prefixpath=");
- if (tkn_e)
- strcat(mountdata, tkn_e + 1);
- strcat(mountdata, fullpath + ref->path_consumed);
- }
-
- /*cFYI(1, "%s: parent mountdata: %s", __func__,sb_mountdata);*/
- /*cFYI(1, "%s: submount mountdata: %s", __func__, mountdata );*/
-
-compose_mount_options_out:
- kfree(srvIP);
- return mountdata;
-
-compose_mount_options_err:
- kfree(mountdata);
- mountdata = ERR_PTR(rc);
- goto compose_mount_options_out;
-}
-
-/**
- * cifs_dfs_do_refmount - mounts specified path using provided refferal
- * @cifs_sb: parent/root superblock
- * @fullpath: full path in UNC format
- * @ref: server's referral
- */
-static struct vfsmount *cifs_dfs_do_refmount(struct cifs_sb_info *cifs_sb,
- const char *fullpath, const struct dfs_info3_param *ref)
-{
- struct vfsmount *mnt;
- char *mountdata;
- char *devname = NULL;
-
- /* strip first '\' from fullpath */
- mountdata = cifs_compose_mount_options(cifs_sb->mountdata,
- fullpath + 1, ref, &devname);
-
- if (IS_ERR(mountdata))
- return (struct vfsmount *)mountdata;
-
- mnt = vfs_kern_mount(&cifs_fs_type, 0, devname, mountdata);
- kfree(mountdata);
- kfree(devname);
- return mnt;
-
-}
-
-static void dump_referral(const struct dfs_info3_param *ref)
-{
- cFYI(1, "DFS: ref path: %s", ref->path_name);
- cFYI(1, "DFS: node path: %s", ref->node_name);
- cFYI(1, "DFS: fl: %hd, srv_type: %hd", ref->flags, ref->server_type);
- cFYI(1, "DFS: ref_flags: %hd, path_consumed: %hd", ref->ref_flag,
- ref->path_consumed);
-}
-
-/*
- * Create a vfsmount that we can automount
- */
-static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt)
-{
- struct dfs_info3_param *referrals = NULL;
- unsigned int num_referrals = 0;
- struct cifs_sb_info *cifs_sb;
- struct cifs_ses *ses;
- char *full_path;
- int xid, i;
- int rc;
- struct vfsmount *mnt;
- struct tcon_link *tlink;
-
- cFYI(1, "in %s", __func__);
- BUG_ON(IS_ROOT(mntpt));
-
- /*
- * The MSDFS spec states that paths in DFS referral requests and
- * responses must be prefixed by a single '\' character instead of
- * the double backslashes usually used in the UNC. This function
- * gives us the latter, so we must adjust the result.
- */
- mnt = ERR_PTR(-ENOMEM);
- full_path = build_path_from_dentry(mntpt);
- if (full_path == NULL)
- goto cdda_exit;
-
- cifs_sb = CIFS_SB(mntpt->d_inode->i_sb);
- tlink = cifs_sb_tlink(cifs_sb);
- if (IS_ERR(tlink)) {
- mnt = ERR_CAST(tlink);
- goto free_full_path;
- }
- ses = tlink_tcon(tlink)->ses;
-
- xid = GetXid();
- rc = get_dfs_path(xid, ses, full_path + 1, cifs_sb->local_nls,
- &num_referrals, &referrals,
- cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
- FreeXid(xid);
-
- cifs_put_tlink(tlink);
-
- mnt = ERR_PTR(-ENOENT);
- for (i = 0; i < num_referrals; i++) {
- int len;
- dump_referral(referrals + i);
- /* connect to a node */
- len = strlen(referrals[i].node_name);
- if (len < 2) {
- cERROR(1, "%s: Net Address path too short: %s",
- __func__, referrals[i].node_name);
- mnt = ERR_PTR(-EINVAL);
- break;
- }
- mnt = cifs_dfs_do_refmount(cifs_sb,
- full_path, referrals + i);
- cFYI(1, "%s: cifs_dfs_do_refmount:%s , mnt:%p", __func__,
- referrals[i].node_name, mnt);
- if (!IS_ERR(mnt))
- goto success;
- }
-
- /* no valid submounts were found; return error from get_dfs_path() by
- * preference */
- if (rc != 0)
- mnt = ERR_PTR(rc);
-
-success:
- free_dfs_info_array(referrals, num_referrals);
-free_full_path:
- kfree(full_path);
-cdda_exit:
- cFYI(1, "leaving %s" , __func__);
- return mnt;
-}
-
-/*
- * Attempt to automount the referral
- */
-struct vfsmount *cifs_dfs_d_automount(struct path *path)
-{
- struct vfsmount *newmnt;
-
- cFYI(1, "in %s", __func__);
-
- newmnt = cifs_dfs_do_automount(path->dentry);
- if (IS_ERR(newmnt)) {
- cFYI(1, "leaving %s [automount failed]" , __func__);
- return newmnt;
- }
-
- mntget(newmnt); /* prevent immediate expiration */
- mnt_set_expiry(newmnt, &cifs_dfs_automount_list);
- schedule_delayed_work(&cifs_dfs_automount_task,
- cifs_dfs_mountpoint_expiry_timeout);
- cFYI(1, "leaving %s [ok]" , __func__);
- return newmnt;
-}
-
-const struct inode_operations cifs_dfs_referral_inode_operations = {
-};
diff --git a/ANDROID_3.4.5/fs/cifs/cifs_fs_sb.h b/ANDROID_3.4.5/fs/cifs/cifs_fs_sb.h
deleted file mode 100644
index c865bfdf..00000000
--- a/ANDROID_3.4.5/fs/cifs/cifs_fs_sb.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * fs/cifs/cifs_fs_sb.h
- *
- * Copyright (c) International Business Machines Corp., 2002,2004
- * Author(s): Steve French (sfrench@us.ibm.com)
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- */
-#include <linux/rbtree.h>
-
-#ifndef _CIFS_FS_SB_H
-#define _CIFS_FS_SB_H
-
-#include <linux/backing-dev.h>
-
-#define CIFS_MOUNT_NO_PERM 1 /* do not do client vfs_perm check */
-#define CIFS_MOUNT_SET_UID 2 /* set current's euid in create etc. */
-#define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */
-#define CIFS_MOUNT_DIRECT_IO 8 /* do not write nor read through page cache */
-#define CIFS_MOUNT_NO_XATTR 0x10 /* if set - disable xattr support */
-#define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20 /* remap illegal chars in filenames */
-#define CIFS_MOUNT_POSIX_PATHS 0x40 /* Negotiate posix pathnames if possible*/
-#define CIFS_MOUNT_UNX_EMUL 0x80 /* Network compat with SFUnix emulation */
-#define CIFS_MOUNT_NO_BRL 0x100 /* No sending byte range locks to srv */
-#define CIFS_MOUNT_CIFS_ACL 0x200 /* send ACL requests to non-POSIX srv */
-#define CIFS_MOUNT_OVERR_UID 0x400 /* override uid returned from server */
-#define CIFS_MOUNT_OVERR_GID 0x800 /* override gid returned from server */
-#define CIFS_MOUNT_DYNPERM 0x1000 /* allow in-memory only mode setting */
-#define CIFS_MOUNT_NOPOSIXBRL 0x2000 /* mandatory not posix byte range lock */
-#define CIFS_MOUNT_NOSSYNC 0x4000 /* don't do slow SMBflush on every sync*/
-#define CIFS_MOUNT_FSCACHE 0x8000 /* local caching enabled */
-#define CIFS_MOUNT_MF_SYMLINKS 0x10000 /* Minshall+French Symlinks enabled */
-#define CIFS_MOUNT_MULTIUSER 0x20000 /* multiuser mount */
-#define CIFS_MOUNT_STRICT_IO 0x40000 /* strict cache mode */
-#define CIFS_MOUNT_RWPIDFORWARD 0x80000 /* use pid forwarding for rw */
-#define CIFS_MOUNT_POSIXACL 0x100000 /* mirror of MS_POSIXACL in mnt_cifs_flags */
-#define CIFS_MOUNT_CIFS_BACKUPUID 0x200000 /* backup intent bit for a user */
-#define CIFS_MOUNT_CIFS_BACKUPGID 0x400000 /* backup intent bit for a group */
-
-struct cifs_sb_info {
- struct rb_root tlink_tree;
- spinlock_t tlink_tree_lock;
- struct tcon_link *master_tlink;
- struct nls_table *local_nls;
- unsigned int rsize;
- unsigned int wsize;
- unsigned long actimeo; /* attribute cache timeout (jiffies) */
- atomic_t active;
- uid_t mnt_uid;
- gid_t mnt_gid;
- uid_t mnt_backupuid;
- gid_t mnt_backupgid;
- umode_t mnt_file_mode;
- umode_t mnt_dir_mode;
- unsigned int mnt_cifs_flags;
- char *mountdata; /* options received at mount time or via DFS refs */
- struct backing_dev_info bdi;
- struct delayed_work prune_tlinks;
-};
-#endif /* _CIFS_FS_SB_H */
diff --git a/ANDROID_3.4.5/fs/cifs/cifs_spnego.c b/ANDROID_3.4.5/fs/cifs/cifs_spnego.c
deleted file mode 100644
index e622863b..00000000
--- a/ANDROID_3.4.5/fs/cifs/cifs_spnego.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * fs/cifs/cifs_spnego.c -- SPNEGO upcall management for CIFS
- *
- * Copyright (c) 2007 Red Hat, Inc.
- * Author(s): Jeff Layton (jlayton@redhat.com)
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/list.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <keys/user-type.h>
-#include <linux/key-type.h>
-#include <linux/inet.h>
-#include "cifsglob.h"
-#include "cifs_spnego.h"
-#include "cifs_debug.h"
-
-/* create a new cifs key */
-static int
-cifs_spnego_key_instantiate(struct key *key, const void *data, size_t datalen)
-{
- char *payload;
- int ret;
-
- ret = -ENOMEM;
- payload = kmalloc(datalen, GFP_KERNEL);
- if (!payload)
- goto error;
-
- /* attach the data */
- memcpy(payload, data, datalen);
- key->payload.data = payload;
- ret = 0;
-
-error:
- return ret;
-}
-
-static void
-cifs_spnego_key_destroy(struct key *key)
-{
- kfree(key->payload.data);
-}
-
-
-/*
- * keytype for CIFS spnego keys
- */
-struct key_type cifs_spnego_key_type = {
- .name = "cifs.spnego",
- .instantiate = cifs_spnego_key_instantiate,
- .match = user_match,
- .destroy = cifs_spnego_key_destroy,
- .describe = user_describe,
-};
-
-/* length of longest version string e.g. strlen("ver=0xFF") */
-#define MAX_VER_STR_LEN 8
-
-/* length of longest security mechanism name, eg in future could have
- * strlen(";sec=ntlmsspi") */
-#define MAX_MECH_STR_LEN 13
-
-/* strlen of "host=" */
-#define HOST_KEY_LEN 5
-
-/* strlen of ";ip4=" or ";ip6=" */
-#define IP_KEY_LEN 5
-
-/* strlen of ";uid=0x" */
-#define UID_KEY_LEN 7
-
-/* strlen of ";creduid=0x" */
-#define CREDUID_KEY_LEN 11
-
-/* strlen of ";user=" */
-#define USER_KEY_LEN 6
-
-/* strlen of ";pid=0x" */
-#define PID_KEY_LEN 7
-
-/* get a key struct with a SPNEGO security blob, suitable for session setup */
-struct key *
-cifs_get_spnego_key(struct cifs_ses *sesInfo)
-{
- struct TCP_Server_Info *server = sesInfo->server;
- struct sockaddr_in *sa = (struct sockaddr_in *) &server->dstaddr;
- struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) &server->dstaddr;
- char *description, *dp;
- size_t desc_len;
- struct key *spnego_key;
- const char *hostname = server->hostname;
-
- /* length of fields (with semicolons): ver=0xyz ip4=ipaddress
- host=hostname sec=mechanism uid=0xFF user=username */
- desc_len = MAX_VER_STR_LEN +
- HOST_KEY_LEN + strlen(hostname) +
- IP_KEY_LEN + INET6_ADDRSTRLEN +
- MAX_MECH_STR_LEN +
- UID_KEY_LEN + (sizeof(uid_t) * 2) +
- CREDUID_KEY_LEN + (sizeof(uid_t) * 2) +
- PID_KEY_LEN + (sizeof(pid_t) * 2) + 1;
-
- if (sesInfo->user_name)
- desc_len += USER_KEY_LEN + strlen(sesInfo->user_name);
-
- spnego_key = ERR_PTR(-ENOMEM);
- description = kzalloc(desc_len, GFP_KERNEL);
- if (description == NULL)
- goto out;
-
- dp = description;
- /* start with version and hostname portion of UNC string */
- spnego_key = ERR_PTR(-EINVAL);
- sprintf(dp, "ver=0x%x;host=%s;", CIFS_SPNEGO_UPCALL_VERSION,
- hostname);
- dp = description + strlen(description);
-
- /* add the server address */
- if (server->dstaddr.ss_family == AF_INET)
- sprintf(dp, "ip4=%pI4", &sa->sin_addr);
- else if (server->dstaddr.ss_family == AF_INET6)
- sprintf(dp, "ip6=%pI6", &sa6->sin6_addr);
- else
- goto out;
-
- dp = description + strlen(description);
-
- /* for now, only sec=krb5 and sec=mskrb5 are valid */
- if (server->sec_kerberos)
- sprintf(dp, ";sec=krb5");
- else if (server->sec_mskerberos)
- sprintf(dp, ";sec=mskrb5");
- else
- goto out;
-
- dp = description + strlen(description);
- sprintf(dp, ";uid=0x%x", sesInfo->linux_uid);
-
- dp = description + strlen(description);
- sprintf(dp, ";creduid=0x%x", sesInfo->cred_uid);
-
- if (sesInfo->user_name) {
- dp = description + strlen(description);
- sprintf(dp, ";user=%s", sesInfo->user_name);
- }
-
- dp = description + strlen(description);
- sprintf(dp, ";pid=0x%x", current->pid);
-
- cFYI(1, "key description = %s", description);
- spnego_key = request_key(&cifs_spnego_key_type, description, "");
-
-#ifdef CONFIG_CIFS_DEBUG2
- if (cifsFYI && !IS_ERR(spnego_key)) {
- struct cifs_spnego_msg *msg = spnego_key->payload.data;
- cifs_dump_mem("SPNEGO reply blob:", msg->data, min(1024U,
- msg->secblob_len + msg->sesskey_len));
- }
-#endif /* CONFIG_CIFS_DEBUG2 */
-
-out:
- kfree(description);
- return spnego_key;
-}
diff --git a/ANDROID_3.4.5/fs/cifs/cifs_spnego.h b/ANDROID_3.4.5/fs/cifs/cifs_spnego.h
deleted file mode 100644
index 31bef9ee..00000000
--- a/ANDROID_3.4.5/fs/cifs/cifs_spnego.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * fs/cifs/cifs_spnego.h -- SPNEGO upcall management for CIFS
- *
- * Copyright (c) 2007 Red Hat, Inc.
- * Author(s): Jeff Layton (jlayton@redhat.com)
- * Steve French (sfrench@us.ibm.com)
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _CIFS_SPNEGO_H
-#define _CIFS_SPNEGO_H
-
-#define CIFS_SPNEGO_UPCALL_VERSION 2
-
-/*
- * The version field should always be set to CIFS_SPNEGO_UPCALL_VERSION.
- * The flags field is for future use. The request-key callout should set
- * sesskey_len and secblob_len, and then concatenate the SessKey+SecBlob
- * and stuff it in the data field.
- */
-struct cifs_spnego_msg {
- uint32_t version;
- uint32_t flags;
- uint32_t sesskey_len;
- uint32_t secblob_len;
- uint8_t data[1];
-};
-
-#ifdef __KERNEL__
-extern struct key_type cifs_spnego_key_type;
-extern struct key *cifs_get_spnego_key(struct cifs_ses *sesInfo);
-#endif /* KERNEL */
-
-#endif /* _CIFS_SPNEGO_H */
diff --git a/ANDROID_3.4.5/fs/cifs/cifs_unicode.c b/ANDROID_3.4.5/fs/cifs/cifs_unicode.c
deleted file mode 100644
index fbb9da95..00000000
--- a/ANDROID_3.4.5/fs/cifs/cifs_unicode.c
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * fs/cifs/cifs_unicode.c
- *
- * Copyright (c) International Business Machines Corp., 2000,2009
- * Modified by Steve French (sfrench@us.ibm.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include "cifs_unicode.h"
-#include "cifs_uniupr.h"
-#include "cifspdu.h"
-#include "cifsglob.h"
-#include "cifs_debug.h"
-
-/*
- * cifs_utf16_bytes - how long will a string be after conversion?
- * @utf16 - pointer to input string
- * @maxbytes - don't go past this many bytes of input string
- * @codepage - destination codepage
- *
- * Walk a utf16le string and return the number of bytes that the string will
- * be after being converted to the given charset, not including any null
- * termination required. Don't walk past maxbytes in the source buffer.
- */
-int
-cifs_utf16_bytes(const __le16 *from, int maxbytes,
- const struct nls_table *codepage)
-{
- int i;
- int charlen, outlen = 0;
- int maxwords = maxbytes / 2;
- char tmp[NLS_MAX_CHARSET_SIZE];
- __u16 ftmp;
-
- for (i = 0; i < maxwords; i++) {
- ftmp = get_unaligned_le16(&from[i]);
- if (ftmp == 0)
- break;
-
- charlen = codepage->uni2char(ftmp, tmp, NLS_MAX_CHARSET_SIZE);
- if (charlen > 0)
- outlen += charlen;
- else
- outlen++;
- }
-
- return outlen;
-}
-
-/*
- * cifs_mapchar - convert a host-endian char to proper char in codepage
- * @target - where converted character should be copied
- * @src_char - 2 byte host-endian source character
- * @cp - codepage to which character should be converted
- * @mapchar - should character be mapped according to mapchars mount option?
- *
- * This function handles the conversion of a single character. It is the
- * responsibility of the caller to ensure that the target buffer is large
- * enough to hold the result of the conversion (at least NLS_MAX_CHARSET_SIZE).
- */
-static int
-cifs_mapchar(char *target, const __u16 src_char, const struct nls_table *cp,
- bool mapchar)
-{
- int len = 1;
-
- if (!mapchar)
- goto cp_convert;
-
- /*
- * BB: Cannot handle remapping UNI_SLASH until all the calls to
- * build_path_from_dentry are modified, as they use slash as
- * separator.
- */
- switch (src_char) {
- case UNI_COLON:
- *target = ':';
- break;
- case UNI_ASTERISK:
- *target = '*';
- break;
- case UNI_QUESTION:
- *target = '?';
- break;
- case UNI_PIPE:
- *target = '|';
- break;
- case UNI_GRTRTHAN:
- *target = '>';
- break;
- case UNI_LESSTHAN:
- *target = '<';
- break;
- default:
- goto cp_convert;
- }
-
-out:
- return len;
-
-cp_convert:
- len = cp->uni2char(src_char, target, NLS_MAX_CHARSET_SIZE);
- if (len <= 0) {
- *target = '?';
- len = 1;
- }
- goto out;
-}
-
-/*
- * cifs_from_utf16 - convert utf16le string to local charset
- * @to - destination buffer
- * @from - source buffer
- * @tolen - destination buffer size (in bytes)
- * @fromlen - source buffer size (in bytes)
- * @codepage - codepage to which characters should be converted
- * @mapchar - should characters be remapped according to the mapchars option?
- *
- * Convert a little-endian utf16le string (as sent by the server) to a string
- * in the provided codepage. The tolen and fromlen parameters are to ensure
- * that the code doesn't walk off of the end of the buffer (which is always
- * a danger if the alignment of the source buffer is off). The destination
- * string is always properly null terminated and fits in the destination
- * buffer. Returns the length of the destination string in bytes (including
- * null terminator).
- *
- * Note that some windows versions actually send multiword UTF-16 characters
- * instead of straight UTF16-2. The linux nls routines however aren't able to
- * deal with those characters properly. In the event that we get some of
- * those characters, they won't be translated properly.
- */
-int
-cifs_from_utf16(char *to, const __le16 *from, int tolen, int fromlen,
- const struct nls_table *codepage, bool mapchar)
-{
- int i, charlen, safelen;
- int outlen = 0;
- int nullsize = nls_nullsize(codepage);
- int fromwords = fromlen / 2;
- char tmp[NLS_MAX_CHARSET_SIZE];
- __u16 ftmp;
-
- /*
- * because the chars can be of varying widths, we need to take care
- * not to overflow the destination buffer when we get close to the
- * end of it. Until we get to this offset, we don't need to check
- * for overflow however.
- */
- safelen = tolen - (NLS_MAX_CHARSET_SIZE + nullsize);
-
- for (i = 0; i < fromwords; i++) {
- ftmp = get_unaligned_le16(&from[i]);
- if (ftmp == 0)
- break;
-
- /*
- * check to see if converting this character might make the
- * conversion bleed into the null terminator
- */
- if (outlen >= safelen) {
- charlen = cifs_mapchar(tmp, ftmp, codepage, mapchar);
- if ((outlen + charlen) > (tolen - nullsize))
- break;
- }
-
- /* put converted char into 'to' buffer */
- charlen = cifs_mapchar(&to[outlen], ftmp, codepage, mapchar);
- outlen += charlen;
- }
-
- /* properly null-terminate string */
- for (i = 0; i < nullsize; i++)
- to[outlen++] = 0;
-
- return outlen;
-}
-
-/*
- * NAME: cifs_strtoUTF16()
- *
- * FUNCTION: Convert character string to unicode string
- *
- */
-int
-cifs_strtoUTF16(__le16 *to, const char *from, int len,
- const struct nls_table *codepage)
-{
- int charlen;
- int i;
- wchar_t wchar_to; /* needed to quiet sparse */
-
- for (i = 0; len && *from; i++, from += charlen, len -= charlen) {
- charlen = codepage->char2uni(from, len, &wchar_to);
- if (charlen < 1) {
- cERROR(1, "strtoUTF16: char2uni of 0x%x returned %d",
- *from, charlen);
- /* A question mark */
- wchar_to = 0x003f;
- charlen = 1;
- }
- put_unaligned_le16(wchar_to, &to[i]);
- }
-
- put_unaligned_le16(0, &to[i]);
- return i;
-}
-
-/*
- * cifs_strndup_from_utf16 - copy a string from wire format to the local
- * codepage
- * @src - source string
- * @maxlen - don't walk past this many bytes in the source string
- * @is_unicode - is this a unicode string?
- * @codepage - destination codepage
- *
- * Take a string given by the server, convert it to the local codepage and
- * put it in a new buffer. Returns a pointer to the new string or NULL on
- * error.
- */
-char *
-cifs_strndup_from_utf16(const char *src, const int maxlen,
- const bool is_unicode, const struct nls_table *codepage)
-{
- int len;
- char *dst;
-
- if (is_unicode) {
- len = cifs_utf16_bytes((__le16 *) src, maxlen, codepage);
- len += nls_nullsize(codepage);
- dst = kmalloc(len, GFP_KERNEL);
- if (!dst)
- return NULL;
- cifs_from_utf16(dst, (__le16 *) src, len, maxlen, codepage,
- false);
- } else {
- len = strnlen(src, maxlen);
- len++;
- dst = kmalloc(len, GFP_KERNEL);
- if (!dst)
- return NULL;
- strlcpy(dst, src, len);
- }
-
- return dst;
-}
-
-/*
- * Convert 16 bit Unicode pathname to wire format from string in current code
- * page. Conversion may involve remapping up the six characters that are
- * only legal in POSIX-like OS (if they are present in the string). Path
- * names are little endian 16 bit Unicode on the wire
- */
-int
-cifsConvertToUTF16(__le16 *target, const char *source, int srclen,
- const struct nls_table *cp, int mapChars)
-{
- int i, j, charlen;
- char src_char;
- __le16 dst_char;
- wchar_t tmp;
-
- if (!mapChars)
- return cifs_strtoUTF16(target, source, PATH_MAX, cp);
-
- for (i = 0, j = 0; i < srclen; j++) {
- src_char = source[i];
- charlen = 1;
- switch (src_char) {
- case 0:
- put_unaligned(0, &target[j]);
- goto ctoUTF16_out;
- case ':':
- dst_char = cpu_to_le16(UNI_COLON);
- break;
- case '*':
- dst_char = cpu_to_le16(UNI_ASTERISK);
- break;
- case '?':
- dst_char = cpu_to_le16(UNI_QUESTION);
- break;
- case '<':
- dst_char = cpu_to_le16(UNI_LESSTHAN);
- break;
- case '>':
- dst_char = cpu_to_le16(UNI_GRTRTHAN);
- break;
- case '|':
- dst_char = cpu_to_le16(UNI_PIPE);
- break;
- /*
- * FIXME: We can not handle remapping backslash (UNI_SLASH)
- * until all the calls to build_path_from_dentry are modified,
- * as they use backslash as separator.
- */
- default:
- charlen = cp->char2uni(source + i, srclen - i, &tmp);
- dst_char = cpu_to_le16(tmp);
-
- /*
- * if no match, use question mark, which at least in
- * some cases serves as wild card
- */
- if (charlen < 1) {
- dst_char = cpu_to_le16(0x003f);
- charlen = 1;
- }
- }
- /*
- * character may take more than one byte in the source string,
- * but will take exactly two bytes in the target string
- */
- i += charlen;
- put_unaligned(dst_char, &target[j]);
- }
-
-ctoUTF16_out:
- return i;
-}
-
diff --git a/ANDROID_3.4.5/fs/cifs/cifs_unicode.h b/ANDROID_3.4.5/fs/cifs/cifs_unicode.h
deleted file mode 100644
index a513a546..00000000
--- a/ANDROID_3.4.5/fs/cifs/cifs_unicode.h
+++ /dev/null
@@ -1,383 +0,0 @@
-/*
- * cifs_unicode: Unicode kernel case support
- *
- * Function:
- * Convert a unicode character to upper or lower case using
- * compressed tables.
- *
- * Copyright (c) International Business Machines Corp., 2000,2009
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- *
- * Notes:
- * These APIs are based on the C library functions. The semantics
- * should match the C functions but with expanded size operands.
- *
- * The upper/lower functions are based on a table created by mkupr.
- * This is a compressed table of upper and lower case conversion.
- *
- */
-#ifndef _CIFS_UNICODE_H
-#define _CIFS_UNICODE_H
-
-#include <asm/byteorder.h>
-#include <linux/types.h>
-#include <linux/nls.h>
-
-#define UNIUPR_NOLOWER /* Example to not expand lower case tables */
-
-/*
- * Windows maps these to the user defined 16 bit Unicode range since they are
- * reserved symbols (along with \ and /), otherwise illegal to store
- * in filenames in NTFS
- */
-#define UNI_ASTERISK (__u16) ('*' + 0xF000)
-#define UNI_QUESTION (__u16) ('?' + 0xF000)
-#define UNI_COLON (__u16) (':' + 0xF000)
-#define UNI_GRTRTHAN (__u16) ('>' + 0xF000)
-#define UNI_LESSTHAN (__u16) ('<' + 0xF000)
-#define UNI_PIPE (__u16) ('|' + 0xF000)
-#define UNI_SLASH (__u16) ('\\' + 0xF000)
-
-/* Just define what we want from uniupr.h. We don't want to define the tables
- * in each source file.
- */
-#ifndef UNICASERANGE_DEFINED
-struct UniCaseRange {
- wchar_t start;
- wchar_t end;
- signed char *table;
-};
-#endif /* UNICASERANGE_DEFINED */
-
-#ifndef UNIUPR_NOUPPER
-extern signed char CifsUniUpperTable[512];
-extern const struct UniCaseRange CifsUniUpperRange[];
-#endif /* UNIUPR_NOUPPER */
-
-#ifndef UNIUPR_NOLOWER
-extern signed char CifsUniLowerTable[512];
-extern const struct UniCaseRange CifsUniLowerRange[];
-#endif /* UNIUPR_NOLOWER */
-
-#ifdef __KERNEL__
-int cifs_from_utf16(char *to, const __le16 *from, int tolen, int fromlen,
- const struct nls_table *codepage, bool mapchar);
-int cifs_utf16_bytes(const __le16 *from, int maxbytes,
- const struct nls_table *codepage);
-int cifs_strtoUTF16(__le16 *, const char *, int, const struct nls_table *);
-char *cifs_strndup_from_utf16(const char *src, const int maxlen,
- const bool is_unicode,
- const struct nls_table *codepage);
-extern int cifsConvertToUTF16(__le16 *target, const char *source, int maxlen,
- const struct nls_table *cp, int mapChars);
-
-#endif
-
-/*
- * UniStrcat: Concatenate the second string to the first
- *
- * Returns:
- * Address of the first string
- */
-static inline wchar_t *
-UniStrcat(wchar_t *ucs1, const wchar_t *ucs2)
-{
- wchar_t *anchor = ucs1; /* save a pointer to start of ucs1 */
-
- while (*ucs1++) ; /* To end of first string */
- ucs1--; /* Return to the null */
- while ((*ucs1++ = *ucs2++)) ; /* copy string 2 over */
- return anchor;
-}
-
-/*
- * UniStrchr: Find a character in a string
- *
- * Returns:
- * Address of first occurrence of character in string
- * or NULL if the character is not in the string
- */
-static inline wchar_t *
-UniStrchr(const wchar_t *ucs, wchar_t uc)
-{
- while ((*ucs != uc) && *ucs)
- ucs++;
-
- if (*ucs == uc)
- return (wchar_t *) ucs;
- return NULL;
-}
-
-/*
- * UniStrcmp: Compare two strings
- *
- * Returns:
- * < 0: First string is less than second
- * = 0: Strings are equal
- * > 0: First string is greater than second
- */
-static inline int
-UniStrcmp(const wchar_t *ucs1, const wchar_t *ucs2)
-{
- while ((*ucs1 == *ucs2) && *ucs1) {
- ucs1++;
- ucs2++;
- }
- return (int) *ucs1 - (int) *ucs2;
-}
-
-/*
- * UniStrcpy: Copy a string
- */
-static inline wchar_t *
-UniStrcpy(wchar_t *ucs1, const wchar_t *ucs2)
-{
- wchar_t *anchor = ucs1; /* save the start of result string */
-
- while ((*ucs1++ = *ucs2++)) ;
- return anchor;
-}
-
-/*
- * UniStrlen: Return the length of a string (in 16 bit Unicode chars not bytes)
- */
-static inline size_t
-UniStrlen(const wchar_t *ucs1)
-{
- int i = 0;
-
- while (*ucs1++)
- i++;
- return i;
-}
-
-/*
- * UniStrnlen: Return the length (in 16 bit Unicode chars not bytes) of a
- * string (length limited)
- */
-static inline size_t
-UniStrnlen(const wchar_t *ucs1, int maxlen)
-{
- int i = 0;
-
- while (*ucs1++) {
- i++;
- if (i >= maxlen)
- break;
- }
- return i;
-}
-
-/*
- * UniStrncat: Concatenate length limited string
- */
-static inline wchar_t *
-UniStrncat(wchar_t *ucs1, const wchar_t *ucs2, size_t n)
-{
- wchar_t *anchor = ucs1; /* save pointer to string 1 */
-
- while (*ucs1++) ;
- ucs1--; /* point to null terminator of s1 */
- while (n-- && (*ucs1 = *ucs2)) { /* copy s2 after s1 */
- ucs1++;
- ucs2++;
- }
- *ucs1 = 0; /* Null terminate the result */
- return (anchor);
-}
-
-/*
- * UniStrncmp: Compare length limited string
- */
-static inline int
-UniStrncmp(const wchar_t *ucs1, const wchar_t *ucs2, size_t n)
-{
- if (!n)
- return 0; /* Null strings are equal */
- while ((*ucs1 == *ucs2) && *ucs1 && --n) {
- ucs1++;
- ucs2++;
- }
- return (int) *ucs1 - (int) *ucs2;
-}
-
-/*
- * UniStrncmp_le: Compare length limited string - native to little-endian
- */
-static inline int
-UniStrncmp_le(const wchar_t *ucs1, const wchar_t *ucs2, size_t n)
-{
- if (!n)
- return 0; /* Null strings are equal */
- while ((*ucs1 == __le16_to_cpu(*ucs2)) && *ucs1 && --n) {
- ucs1++;
- ucs2++;
- }
- return (int) *ucs1 - (int) __le16_to_cpu(*ucs2);
-}
-
-/*
- * UniStrncpy: Copy length limited string with pad
- */
-static inline wchar_t *
-UniStrncpy(wchar_t *ucs1, const wchar_t *ucs2, size_t n)
-{
- wchar_t *anchor = ucs1;
-
- while (n-- && *ucs2) /* Copy the strings */
- *ucs1++ = *ucs2++;
-
- n++;
- while (n--) /* Pad with nulls */
- *ucs1++ = 0;
- return anchor;
-}
-
-/*
- * UniStrncpy_le: Copy length limited string with pad to little-endian
- */
-static inline wchar_t *
-UniStrncpy_le(wchar_t *ucs1, const wchar_t *ucs2, size_t n)
-{
- wchar_t *anchor = ucs1;
-
- while (n-- && *ucs2) /* Copy the strings */
- *ucs1++ = __le16_to_cpu(*ucs2++);
-
- n++;
- while (n--) /* Pad with nulls */
- *ucs1++ = 0;
- return anchor;
-}
-
-/*
- * UniStrstr: Find a string in a string
- *
- * Returns:
- * Address of first match found
- * NULL if no matching string is found
- */
-static inline wchar_t *
-UniStrstr(const wchar_t *ucs1, const wchar_t *ucs2)
-{
- const wchar_t *anchor1 = ucs1;
- const wchar_t *anchor2 = ucs2;
-
- while (*ucs1) {
- if (*ucs1 == *ucs2) {
- /* Partial match found */
- ucs1++;
- ucs2++;
- } else {
- if (!*ucs2) /* Match found */
- return (wchar_t *) anchor1;
- ucs1 = ++anchor1; /* No match */
- ucs2 = anchor2;
- }
- }
-
- if (!*ucs2) /* Both end together */
- return (wchar_t *) anchor1; /* Match found */
- return NULL; /* No match */
-}
-
-#ifndef UNIUPR_NOUPPER
-/*
- * UniToupper: Convert a unicode character to upper case
- */
-static inline wchar_t
-UniToupper(register wchar_t uc)
-{
- register const struct UniCaseRange *rp;
-
- if (uc < sizeof(CifsUniUpperTable)) {
- /* Latin characters */
- return uc + CifsUniUpperTable[uc]; /* Use base tables */
- } else {
- rp = CifsUniUpperRange; /* Use range tables */
- while (rp->start) {
- if (uc < rp->start) /* Before start of range */
- return uc; /* Uppercase = input */
- if (uc <= rp->end) /* In range */
- return uc + rp->table[uc - rp->start];
- rp++; /* Try next range */
- }
- }
- return uc; /* Past last range */
-}
-
-/*
- * UniStrupr: Upper case a unicode string
- */
-static inline wchar_t *
-UniStrupr(register wchar_t *upin)
-{
- register wchar_t *up;
-
- up = upin;
- while (*up) { /* For all characters */
- *up = UniToupper(*up);
- up++;
- }
- return upin; /* Return input pointer */
-}
-#endif /* UNIUPR_NOUPPER */
-
-#ifndef UNIUPR_NOLOWER
-/*
- * UniTolower: Convert a unicode character to lower case
- */
-static inline wchar_t
-UniTolower(register wchar_t uc)
-{
- register const struct UniCaseRange *rp;
-
- if (uc < sizeof(CifsUniLowerTable)) {
- /* Latin characters */
- return uc + CifsUniLowerTable[uc]; /* Use base tables */
- } else {
- rp = CifsUniLowerRange; /* Use range tables */
- while (rp->start) {
- if (uc < rp->start) /* Before start of range */
- return uc; /* Uppercase = input */
- if (uc <= rp->end) /* In range */
- return uc + rp->table[uc - rp->start];
- rp++; /* Try next range */
- }
- }
- return uc; /* Past last range */
-}
-
-/*
- * UniStrlwr: Lower case a unicode string
- */
-static inline wchar_t *
-UniStrlwr(register wchar_t *upin)
-{
- register wchar_t *up;
-
- up = upin;
- while (*up) { /* For all characters */
- *up = UniTolower(*up);
- up++;
- }
- return upin; /* Return input pointer */
-}
-
-#endif
-
-#endif /* _CIFS_UNICODE_H */
diff --git a/ANDROID_3.4.5/fs/cifs/cifs_uniupr.h b/ANDROID_3.4.5/fs/cifs/cifs_uniupr.h
deleted file mode 100644
index 0ac7c5a8..00000000
--- a/ANDROID_3.4.5/fs/cifs/cifs_uniupr.h
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Copyright (c) International Business Machines Corp., 2000,2002
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- * uniupr.h - Unicode compressed case ranges
- *
-*/
-
-#ifndef UNIUPR_NOUPPER
-/*
- * Latin upper case
- */
-signed char CifsUniUpperTable[512] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 000-00f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 010-01f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 020-02f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 030-03f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 040-04f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 050-05f */
- 0, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, /* 060-06f */
- -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, 0, 0, 0, 0, 0, /* 070-07f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 080-08f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 090-09f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0a0-0af */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0b0-0bf */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0c0-0cf */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0d0-0df */
- -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, /* 0e0-0ef */
- -32, -32, -32, -32, -32, -32, -32, 0, -32, -32, -32, -32, -32, -32, -32, 121, /* 0f0-0ff */
- 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 100-10f */
- 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 110-11f */
- 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 120-12f */
- 0, 0, 0, -1, 0, -1, 0, -1, 0, 0, -1, 0, -1, 0, -1, 0, /* 130-13f */
- -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, 0, -1, 0, -1, 0, -1, /* 140-14f */
- 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 150-15f */
- 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 160-16f */
- 0, -1, 0, -1, 0, -1, 0, -1, 0, 0, -1, 0, -1, 0, -1, 0, /* 170-17f */
- 0, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, /* 180-18f */
- 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, /* 190-19f */
- 0, -1, 0, -1, 0, -1, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, /* 1a0-1af */
- -1, 0, 0, 0, -1, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, /* 1b0-1bf */
- 0, 0, 0, 0, 0, -1, -2, 0, -1, -2, 0, -1, -2, 0, -1, 0, /* 1c0-1cf */
- -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -79, 0, -1, /* 1d0-1df */
- 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1e0-1ef */
- 0, 0, -1, -2, 0, -1, 0, 0, 0, -1, 0, -1, 0, -1, 0, -1, /* 1f0-1ff */
-};
-
-/* Upper case range - Greek */
-static signed char UniCaseRangeU03a0[47] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -38, -37, -37, -37, /* 3a0-3af */
- 0, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, /* 3b0-3bf */
- -32, -32, -31, -32, -32, -32, -32, -32, -32, -32, -32, -32, -64,
- -63, -63,
-};
-
-/* Upper case range - Cyrillic */
-static signed char UniCaseRangeU0430[48] = {
- -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, /* 430-43f */
- -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, /* 440-44f */
- 0, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, -80, 0, -80, -80, /* 450-45f */
-};
-
-/* Upper case range - Extended cyrillic */
-static signed char UniCaseRangeU0490[61] = {
- 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 490-49f */
- 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 4a0-4af */
- 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 4b0-4bf */
- 0, 0, -1, 0, -1, 0, 0, 0, -1, 0, 0, 0, -1,
-};
-
-/* Upper case range - Extended latin and greek */
-static signed char UniCaseRangeU1e00[509] = {
- 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1e00-1e0f */
- 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1e10-1e1f */
- 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1e20-1e2f */
- 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1e30-1e3f */
- 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1e40-1e4f */
- 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1e50-1e5f */
- 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1e60-1e6f */
- 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1e70-1e7f */
- 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1e80-1e8f */
- 0, -1, 0, -1, 0, -1, 0, 0, 0, 0, 0, -59, 0, -1, 0, -1, /* 1e90-1e9f */
- 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1ea0-1eaf */
- 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1eb0-1ebf */
- 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1ec0-1ecf */
- 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1ed0-1edf */
- 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, /* 1ee0-1eef */
- 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, 0, 0, 0, 0, 0, /* 1ef0-1eff */
- 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, /* 1f00-1f0f */
- 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1f10-1f1f */
- 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, /* 1f20-1f2f */
- 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, /* 1f30-1f3f */
- 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1f40-1f4f */
- 0, 8, 0, 8, 0, 8, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, /* 1f50-1f5f */
- 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, /* 1f60-1f6f */
- 74, 74, 86, 86, 86, 86, 100, 100, 0, 0, 112, 112, 126, 126, 0, 0, /* 1f70-1f7f */
- 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, /* 1f80-1f8f */
- 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, /* 1f90-1f9f */
- 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, /* 1fa0-1faf */
- 8, 8, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1fb0-1fbf */
- 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1fc0-1fcf */
- 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1fd0-1fdf */
- 8, 8, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1fe0-1fef */
- 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-};
-
-/* Upper case range - Wide latin */
-static signed char UniCaseRangeUff40[27] = {
- 0, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, /* ff40-ff4f */
- -32, -32, -32, -32, -32, -32, -32, -32, -32, -32, -32,
-};
-
-/*
- * Upper Case Range
- */
-const struct UniCaseRange CifsUniUpperRange[] = {
- {0x03a0, 0x03ce, UniCaseRangeU03a0},
- {0x0430, 0x045f, UniCaseRangeU0430},
- {0x0490, 0x04cc, UniCaseRangeU0490},
- {0x1e00, 0x1ffc, UniCaseRangeU1e00},
- {0xff40, 0xff5a, UniCaseRangeUff40},
- {0}
-};
-#endif
-
-#ifndef UNIUPR_NOLOWER
-/*
- * Latin lower case
- */
-signed char CifsUniLowerTable[512] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 000-00f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 010-01f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 020-02f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 030-03f */
- 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, /* 040-04f */
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 0, 0, 0, 0, 0, /* 050-05f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 060-06f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 070-07f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 080-08f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 090-09f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0a0-0af */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0b0-0bf */
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, /* 0c0-0cf */
- 32, 32, 32, 32, 32, 32, 32, 0, 32, 32, 32, 32, 32, 32, 32, 0, /* 0d0-0df */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0e0-0ef */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0f0-0ff */
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, /* 100-10f */
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, /* 110-11f */
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, /* 120-12f */
- 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, /* 130-13f */
- 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, /* 140-14f */
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, /* 150-15f */
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, /* 160-16f */
- 1, 0, 1, 0, 1, 0, 1, 0, -121, 1, 0, 1, 0, 1, 0, 0, /* 170-17f */
- 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 79, 0, /* 180-18f */
- 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, /* 190-19f */
- 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, /* 1a0-1af */
- 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, /* 1b0-1bf */
- 0, 0, 0, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 1, 0, 1, /* 1c0-1cf */
- 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, /* 1d0-1df */
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, /* 1e0-1ef */
- 0, 2, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, /* 1f0-1ff */
-};
-
-/* Lower case range - Greek */
-static signed char UniCaseRangeL0380[44] = {
- 0, 0, 0, 0, 0, 0, 38, 0, 37, 37, 37, 0, 64, 0, 63, 63, /* 380-38f */
- 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, /* 390-39f */
- 32, 32, 0, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-};
-
-/* Lower case range - Cyrillic */
-static signed char UniCaseRangeL0400[48] = {
- 0, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 0, 80, 80, /* 400-40f */
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, /* 410-41f */
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, /* 420-42f */
-};
-
-/* Lower case range - Extended cyrillic */
-static signed char UniCaseRangeL0490[60] = {
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, /* 490-49f */
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, /* 4a0-4af */
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, /* 4b0-4bf */
- 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1,
-};
-
-/* Lower case range - Extended latin and greek */
-static signed char UniCaseRangeL1e00[504] = {
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, /* 1e00-1e0f */
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, /* 1e10-1e1f */
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, /* 1e20-1e2f */
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, /* 1e30-1e3f */
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, /* 1e40-1e4f */
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, /* 1e50-1e5f */
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, /* 1e60-1e6f */
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, /* 1e70-1e7f */
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, /* 1e80-1e8f */
- 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, /* 1e90-1e9f */
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, /* 1ea0-1eaf */
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, /* 1eb0-1ebf */
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, /* 1ec0-1ecf */
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, /* 1ed0-1edf */
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, /* 1ee0-1eef */
- 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, /* 1ef0-1eff */
- 0, 0, 0, 0, 0, 0, 0, 0, -8, -8, -8, -8, -8, -8, -8, -8, /* 1f00-1f0f */
- 0, 0, 0, 0, 0, 0, 0, 0, -8, -8, -8, -8, -8, -8, 0, 0, /* 1f10-1f1f */
- 0, 0, 0, 0, 0, 0, 0, 0, -8, -8, -8, -8, -8, -8, -8, -8, /* 1f20-1f2f */
- 0, 0, 0, 0, 0, 0, 0, 0, -8, -8, -8, -8, -8, -8, -8, -8, /* 1f30-1f3f */
- 0, 0, 0, 0, 0, 0, 0, 0, -8, -8, -8, -8, -8, -8, 0, 0, /* 1f40-1f4f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, -8, 0, -8, 0, -8, 0, -8, /* 1f50-1f5f */
- 0, 0, 0, 0, 0, 0, 0, 0, -8, -8, -8, -8, -8, -8, -8, -8, /* 1f60-1f6f */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1f70-1f7f */
- 0, 0, 0, 0, 0, 0, 0, 0, -8, -8, -8, -8, -8, -8, -8, -8, /* 1f80-1f8f */
- 0, 0, 0, 0, 0, 0, 0, 0, -8, -8, -8, -8, -8, -8, -8, -8, /* 1f90-1f9f */
- 0, 0, 0, 0, 0, 0, 0, 0, -8, -8, -8, -8, -8, -8, -8, -8, /* 1fa0-1faf */
- 0, 0, 0, 0, 0, 0, 0, 0, -8, -8, -74, -74, -9, 0, 0, 0, /* 1fb0-1fbf */
- 0, 0, 0, 0, 0, 0, 0, 0, -86, -86, -86, -86, -9, 0, 0, 0, /* 1fc0-1fcf */
- 0, 0, 0, 0, 0, 0, 0, 0, -8, -8, -100, -100, 0, 0, 0, 0, /* 1fd0-1fdf */
- 0, 0, 0, 0, 0, 0, 0, 0, -8, -8, -112, -112, -7, 0, 0, 0, /* 1fe0-1fef */
- 0, 0, 0, 0, 0, 0, 0, 0,
-};
-
-/* Lower case range - Wide latin */
-static signed char UniCaseRangeLff20[27] = {
- 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, /* ff20-ff2f */
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-};
-
-/*
- * Lower Case Range
- */
-const struct UniCaseRange CifsUniLowerRange[] = {
- {0x0380, 0x03ab, UniCaseRangeL0380},
- {0x0400, 0x042f, UniCaseRangeL0400},
- {0x0490, 0x04cb, UniCaseRangeL0490},
- {0x1e00, 0x1ff7, UniCaseRangeL1e00},
- {0xff20, 0xff3a, UniCaseRangeLff20},
- {0}
-};
-#endif
diff --git a/ANDROID_3.4.5/fs/cifs/cifsacl.c b/ANDROID_3.4.5/fs/cifs/cifsacl.c
deleted file mode 100644
index 3cc1b251..00000000
--- a/ANDROID_3.4.5/fs/cifs/cifsacl.c
+++ /dev/null
@@ -1,1354 +0,0 @@
-/*
- * fs/cifs/cifsacl.c
- *
- * Copyright (C) International Business Machines Corp., 2007,2008
- * Author(s): Steve French (sfrench@us.ibm.com)
- *
- * Contains the routines for mapping CIFS/NTFS ACLs
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/keyctl.h>
-#include <linux/key-type.h>
-#include <keys/user-type.h>
-#include "cifspdu.h"
-#include "cifsglob.h"
-#include "cifsacl.h"
-#include "cifsproto.h"
-#include "cifs_debug.h"
-
-/* security id for everyone/world system group */
-static const struct cifs_sid sid_everyone = {
- 1, 1, {0, 0, 0, 0, 0, 1}, {0} };
-/* security id for Authenticated Users system group */
-static const struct cifs_sid sid_authusers = {
- 1, 1, {0, 0, 0, 0, 0, 5}, {__constant_cpu_to_le32(11)} };
-/* group users */
-static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} };
-
-const struct cred *root_cred;
-
-static void
-shrink_idmap_tree(struct rb_root *root, int nr_to_scan, int *nr_rem,
- int *nr_del)
-{
- struct rb_node *node;
- struct rb_node *tmp;
- struct cifs_sid_id *psidid;
-
- node = rb_first(root);
- while (node) {
- tmp = node;
- node = rb_next(tmp);
- psidid = rb_entry(tmp, struct cifs_sid_id, rbnode);
- if (nr_to_scan == 0 || *nr_del == nr_to_scan)
- ++(*nr_rem);
- else {
- if (time_after(jiffies, psidid->time + SID_MAP_EXPIRE)
- && psidid->refcount == 0) {
- rb_erase(tmp, root);
- ++(*nr_del);
- } else
- ++(*nr_rem);
- }
- }
-}
-
-/*
- * Run idmap cache shrinker.
- */
-static int
-cifs_idmap_shrinker(struct shrinker *shrink, struct shrink_control *sc)
-{
- int nr_to_scan = sc->nr_to_scan;
- int nr_del = 0;
- int nr_rem = 0;
- struct rb_root *root;
-
- root = &uidtree;
- spin_lock(&siduidlock);
- shrink_idmap_tree(root, nr_to_scan, &nr_rem, &nr_del);
- spin_unlock(&siduidlock);
-
- root = &gidtree;
- spin_lock(&sidgidlock);
- shrink_idmap_tree(root, nr_to_scan, &nr_rem, &nr_del);
- spin_unlock(&sidgidlock);
-
- root = &siduidtree;
- spin_lock(&uidsidlock);
- shrink_idmap_tree(root, nr_to_scan, &nr_rem, &nr_del);
- spin_unlock(&uidsidlock);
-
- root = &sidgidtree;
- spin_lock(&gidsidlock);
- shrink_idmap_tree(root, nr_to_scan, &nr_rem, &nr_del);
- spin_unlock(&gidsidlock);
-
- return nr_rem;
-}
-
-static void
-sid_rb_insert(struct rb_root *root, unsigned long cid,
- struct cifs_sid_id **psidid, char *typestr)
-{
- char *strptr;
- struct rb_node *node = root->rb_node;
- struct rb_node *parent = NULL;
- struct rb_node **linkto = &(root->rb_node);
- struct cifs_sid_id *lsidid;
-
- while (node) {
- lsidid = rb_entry(node, struct cifs_sid_id, rbnode);
- parent = node;
- if (cid > lsidid->id) {
- linkto = &(node->rb_left);
- node = node->rb_left;
- }
- if (cid < lsidid->id) {
- linkto = &(node->rb_right);
- node = node->rb_right;
- }
- }
-
- (*psidid)->id = cid;
- (*psidid)->time = jiffies - (SID_MAP_RETRY + 1);
- (*psidid)->refcount = 0;
-
- sprintf((*psidid)->sidstr, "%s", typestr);
- strptr = (*psidid)->sidstr + strlen((*psidid)->sidstr);
- sprintf(strptr, "%ld", cid);
-
- clear_bit(SID_ID_PENDING, &(*psidid)->state);
- clear_bit(SID_ID_MAPPED, &(*psidid)->state);
-
- rb_link_node(&(*psidid)->rbnode, parent, linkto);
- rb_insert_color(&(*psidid)->rbnode, root);
-}
-
-static struct cifs_sid_id *
-sid_rb_search(struct rb_root *root, unsigned long cid)
-{
- struct rb_node *node = root->rb_node;
- struct cifs_sid_id *lsidid;
-
- while (node) {
- lsidid = rb_entry(node, struct cifs_sid_id, rbnode);
- if (cid > lsidid->id)
- node = node->rb_left;
- else if (cid < lsidid->id)
- node = node->rb_right;
- else /* node found */
- return lsidid;
- }
-
- return NULL;
-}
-
-static struct shrinker cifs_shrinker = {
- .shrink = cifs_idmap_shrinker,
- .seeks = DEFAULT_SEEKS,
-};
-
-static int
-cifs_idmap_key_instantiate(struct key *key, const void *data, size_t datalen)
-{
- char *payload;
-
- payload = kmalloc(datalen, GFP_KERNEL);
- if (!payload)
- return -ENOMEM;
-
- memcpy(payload, data, datalen);
- key->payload.data = payload;
- key->datalen = datalen;
- return 0;
-}
-
-static inline void
-cifs_idmap_key_destroy(struct key *key)
-{
- kfree(key->payload.data);
-}
-
-struct key_type cifs_idmap_key_type = {
- .name = "cifs.idmap",
- .instantiate = cifs_idmap_key_instantiate,
- .destroy = cifs_idmap_key_destroy,
- .describe = user_describe,
- .match = user_match,
-};
-
-static void
-sid_to_str(struct cifs_sid *sidptr, char *sidstr)
-{
- int i;
- unsigned long saval;
- char *strptr;
-
- strptr = sidstr;
-
- sprintf(strptr, "%s", "S");
- strptr = sidstr + strlen(sidstr);
-
- sprintf(strptr, "-%d", sidptr->revision);
- strptr = sidstr + strlen(sidstr);
-
- for (i = 0; i < 6; ++i) {
- if (sidptr->authority[i]) {
- sprintf(strptr, "-%d", sidptr->authority[i]);
- strptr = sidstr + strlen(sidstr);
- }
- }
-
- for (i = 0; i < sidptr->num_subauth; ++i) {
- saval = le32_to_cpu(sidptr->sub_auth[i]);
- sprintf(strptr, "-%ld", saval);
- strptr = sidstr + strlen(sidstr);
- }
-}
-
-static void
-id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr,
- struct cifs_sid_id **psidid, char *typestr)
-{
- int rc;
- char *strptr;
- struct rb_node *node = root->rb_node;
- struct rb_node *parent = NULL;
- struct rb_node **linkto = &(root->rb_node);
- struct cifs_sid_id *lsidid;
-
- while (node) {
- lsidid = rb_entry(node, struct cifs_sid_id, rbnode);
- parent = node;
- rc = compare_sids(sidptr, &((lsidid)->sid));
- if (rc > 0) {
- linkto = &(node->rb_left);
- node = node->rb_left;
- } else if (rc < 0) {
- linkto = &(node->rb_right);
- node = node->rb_right;
- }
- }
-
- memcpy(&(*psidid)->sid, sidptr, sizeof(struct cifs_sid));
- (*psidid)->time = jiffies - (SID_MAP_RETRY + 1);
- (*psidid)->refcount = 0;
-
- sprintf((*psidid)->sidstr, "%s", typestr);
- strptr = (*psidid)->sidstr + strlen((*psidid)->sidstr);
- sid_to_str(&(*psidid)->sid, strptr);
-
- clear_bit(SID_ID_PENDING, &(*psidid)->state);
- clear_bit(SID_ID_MAPPED, &(*psidid)->state);
-
- rb_link_node(&(*psidid)->rbnode, parent, linkto);
- rb_insert_color(&(*psidid)->rbnode, root);
-}
-
-static struct cifs_sid_id *
-id_rb_search(struct rb_root *root, struct cifs_sid *sidptr)
-{
- int rc;
- struct rb_node *node = root->rb_node;
- struct cifs_sid_id *lsidid;
-
- while (node) {
- lsidid = rb_entry(node, struct cifs_sid_id, rbnode);
- rc = compare_sids(sidptr, &((lsidid)->sid));
- if (rc > 0) {
- node = node->rb_left;
- } else if (rc < 0) {
- node = node->rb_right;
- } else /* node found */
- return lsidid;
- }
-
- return NULL;
-}
-
-static int
-sidid_pending_wait(void *unused)
-{
- schedule();
- return signal_pending(current) ? -ERESTARTSYS : 0;
-}
-
-static int
-id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid)
-{
- int rc = 0;
- struct key *sidkey;
- const struct cred *saved_cred;
- struct cifs_sid *lsid;
- struct cifs_sid_id *psidid, *npsidid;
- struct rb_root *cidtree;
- spinlock_t *cidlock;
-
- if (sidtype == SIDOWNER) {
- cidlock = &siduidlock;
- cidtree = &uidtree;
- } else if (sidtype == SIDGROUP) {
- cidlock = &sidgidlock;
- cidtree = &gidtree;
- } else
- return -EINVAL;
-
- spin_lock(cidlock);
- psidid = sid_rb_search(cidtree, cid);
-
- if (!psidid) { /* node does not exist, allocate one & attempt adding */
- spin_unlock(cidlock);
- npsidid = kzalloc(sizeof(struct cifs_sid_id), GFP_KERNEL);
- if (!npsidid)
- return -ENOMEM;
-
- npsidid->sidstr = kmalloc(SIDLEN, GFP_KERNEL);
- if (!npsidid->sidstr) {
- kfree(npsidid);
- return -ENOMEM;
- }
-
- spin_lock(cidlock);
- psidid = sid_rb_search(cidtree, cid);
- if (psidid) { /* node happened to get inserted meanwhile */
- ++psidid->refcount;
- spin_unlock(cidlock);
- kfree(npsidid->sidstr);
- kfree(npsidid);
- } else {
- psidid = npsidid;
- sid_rb_insert(cidtree, cid, &psidid,
- sidtype == SIDOWNER ? "oi:" : "gi:");
- ++psidid->refcount;
- spin_unlock(cidlock);
- }
- } else {
- ++psidid->refcount;
- spin_unlock(cidlock);
- }
-
- /*
- * If we are here, it is safe to access psidid and its fields
- * since a reference was taken earlier while holding the spinlock.
- * A reference on the node is put without holding the spinlock
- * and it is OK to do so in this case, shrinker will not erase
- * this node until all references are put and we do not access
- * any fields of the node after a reference is put .
- */
- if (test_bit(SID_ID_MAPPED, &psidid->state)) {
- memcpy(ssid, &psidid->sid, sizeof(struct cifs_sid));
- psidid->time = jiffies; /* update ts for accessing */
- goto id_sid_out;
- }
-
- if (time_after(psidid->time + SID_MAP_RETRY, jiffies)) {
- rc = -EINVAL;
- goto id_sid_out;
- }
-
- if (!test_and_set_bit(SID_ID_PENDING, &psidid->state)) {
- saved_cred = override_creds(root_cred);
- sidkey = request_key(&cifs_idmap_key_type, psidid->sidstr, "");
- if (IS_ERR(sidkey)) {
- rc = -EINVAL;
- cFYI(1, "%s: Can't map and id to a SID", __func__);
- } else {
- lsid = (struct cifs_sid *)sidkey->payload.data;
- memcpy(&psidid->sid, lsid,
- sidkey->datalen < sizeof(struct cifs_sid) ?
- sidkey->datalen : sizeof(struct cifs_sid));
- memcpy(ssid, &psidid->sid,
- sidkey->datalen < sizeof(struct cifs_sid) ?
- sidkey->datalen : sizeof(struct cifs_sid));
- set_bit(SID_ID_MAPPED, &psidid->state);
- key_put(sidkey);
- kfree(psidid->sidstr);
- }
- psidid->time = jiffies; /* update ts for accessing */
- revert_creds(saved_cred);
- clear_bit(SID_ID_PENDING, &psidid->state);
- wake_up_bit(&psidid->state, SID_ID_PENDING);
- } else {
- rc = wait_on_bit(&psidid->state, SID_ID_PENDING,
- sidid_pending_wait, TASK_INTERRUPTIBLE);
- if (rc) {
- cFYI(1, "%s: sidid_pending_wait interrupted %d",
- __func__, rc);
- --psidid->refcount;
- return rc;
- }
- if (test_bit(SID_ID_MAPPED, &psidid->state))
- memcpy(ssid, &psidid->sid, sizeof(struct cifs_sid));
- else
- rc = -EINVAL;
- }
-id_sid_out:
- --psidid->refcount;
- return rc;
-}
-
-static int
-sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
- struct cifs_fattr *fattr, uint sidtype)
-{
- int rc;
- unsigned long cid;
- struct key *idkey;
- const struct cred *saved_cred;
- struct cifs_sid_id *psidid, *npsidid;
- struct rb_root *cidtree;
- spinlock_t *cidlock;
-
- if (sidtype == SIDOWNER) {
- cid = cifs_sb->mnt_uid; /* default uid, in case upcall fails */
- cidlock = &siduidlock;
- cidtree = &uidtree;
- } else if (sidtype == SIDGROUP) {
- cid = cifs_sb->mnt_gid; /* default gid, in case upcall fails */
- cidlock = &sidgidlock;
- cidtree = &gidtree;
- } else
- return -ENOENT;
-
- spin_lock(cidlock);
- psidid = id_rb_search(cidtree, psid);
-
- if (!psidid) { /* node does not exist, allocate one & attempt adding */
- spin_unlock(cidlock);
- npsidid = kzalloc(sizeof(struct cifs_sid_id), GFP_KERNEL);
- if (!npsidid)
- return -ENOMEM;
-
- npsidid->sidstr = kmalloc(SIDLEN, GFP_KERNEL);
- if (!npsidid->sidstr) {
- kfree(npsidid);
- return -ENOMEM;
- }
-
- spin_lock(cidlock);
- psidid = id_rb_search(cidtree, psid);
- if (psidid) { /* node happened to get inserted meanwhile */
- ++psidid->refcount;
- spin_unlock(cidlock);
- kfree(npsidid->sidstr);
- kfree(npsidid);
- } else {
- psidid = npsidid;
- id_rb_insert(cidtree, psid, &psidid,
- sidtype == SIDOWNER ? "os:" : "gs:");
- ++psidid->refcount;
- spin_unlock(cidlock);
- }
- } else {
- ++psidid->refcount;
- spin_unlock(cidlock);
- }
-
- /*
- * If we are here, it is safe to access psidid and its fields
- * since a reference was taken earlier while holding the spinlock.
- * A reference on the node is put without holding the spinlock
- * and it is OK to do so in this case, shrinker will not erase
- * this node until all references are put and we do not access
- * any fields of the node after a reference is put .
- */
- if (test_bit(SID_ID_MAPPED, &psidid->state)) {
- cid = psidid->id;
- psidid->time = jiffies; /* update ts for accessing */
- goto sid_to_id_out;
- }
-
- if (time_after(psidid->time + SID_MAP_RETRY, jiffies))
- goto sid_to_id_out;
-
- if (!test_and_set_bit(SID_ID_PENDING, &psidid->state)) {
- saved_cred = override_creds(root_cred);
- idkey = request_key(&cifs_idmap_key_type, psidid->sidstr, "");
- if (IS_ERR(idkey))
- cFYI(1, "%s: Can't map SID to an id", __func__);
- else {
- cid = *(unsigned long *)idkey->payload.value;
- psidid->id = cid;
- set_bit(SID_ID_MAPPED, &psidid->state);
- key_put(idkey);
- kfree(psidid->sidstr);
- }
- revert_creds(saved_cred);
- psidid->time = jiffies; /* update ts for accessing */
- clear_bit(SID_ID_PENDING, &psidid->state);
- wake_up_bit(&psidid->state, SID_ID_PENDING);
- } else {
- rc = wait_on_bit(&psidid->state, SID_ID_PENDING,
- sidid_pending_wait, TASK_INTERRUPTIBLE);
- if (rc) {
- cFYI(1, "%s: sidid_pending_wait interrupted %d",
- __func__, rc);
- --psidid->refcount; /* decremented without spinlock */
- return rc;
- }
- if (test_bit(SID_ID_MAPPED, &psidid->state))
- cid = psidid->id;
- }
-
-sid_to_id_out:
- --psidid->refcount; /* decremented without spinlock */
- if (sidtype == SIDOWNER)
- fattr->cf_uid = cid;
- else
- fattr->cf_gid = cid;
-
- return 0;
-}
-
-int
-init_cifs_idmap(void)
-{
- struct cred *cred;
- struct key *keyring;
- int ret;
-
- cFYI(1, "Registering the %s key type\n", cifs_idmap_key_type.name);
-
- /* create an override credential set with a special thread keyring in
- * which requests are cached
- *
- * this is used to prevent malicious redirections from being installed
- * with add_key().
- */
- cred = prepare_kernel_cred(NULL);
- if (!cred)
- return -ENOMEM;
-
- keyring = key_alloc(&key_type_keyring, ".cifs_idmap", 0, 0, cred,
- (KEY_POS_ALL & ~KEY_POS_SETATTR) |
- KEY_USR_VIEW | KEY_USR_READ,
- KEY_ALLOC_NOT_IN_QUOTA);
- if (IS_ERR(keyring)) {
- ret = PTR_ERR(keyring);
- goto failed_put_cred;
- }
-
- ret = key_instantiate_and_link(keyring, NULL, 0, NULL, NULL);
- if (ret < 0)
- goto failed_put_key;
-
- ret = register_key_type(&cifs_idmap_key_type);
- if (ret < 0)
- goto failed_put_key;
-
- /* instruct request_key() to use this special keyring as a cache for
- * the results it looks up */
- set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
- cred->thread_keyring = keyring;
- cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
- root_cred = cred;
-
- spin_lock_init(&siduidlock);
- uidtree = RB_ROOT;
- spin_lock_init(&sidgidlock);
- gidtree = RB_ROOT;
-
- spin_lock_init(&uidsidlock);
- siduidtree = RB_ROOT;
- spin_lock_init(&gidsidlock);
- sidgidtree = RB_ROOT;
- register_shrinker(&cifs_shrinker);
-
- cFYI(1, "cifs idmap keyring: %d\n", key_serial(keyring));
- return 0;
-
-failed_put_key:
- key_put(keyring);
-failed_put_cred:
- put_cred(cred);
- return ret;
-}
-
-void
-exit_cifs_idmap(void)
-{
- key_revoke(root_cred->thread_keyring);
- unregister_key_type(&cifs_idmap_key_type);
- put_cred(root_cred);
- unregister_shrinker(&cifs_shrinker);
- cFYI(1, "Unregistered %s key type\n", cifs_idmap_key_type.name);
-}
-
-void
-cifs_destroy_idmaptrees(void)
-{
- struct rb_root *root;
- struct rb_node *node;
-
- root = &uidtree;
- spin_lock(&siduidlock);
- while ((node = rb_first(root)))
- rb_erase(node, root);
- spin_unlock(&siduidlock);
-
- root = &gidtree;
- spin_lock(&sidgidlock);
- while ((node = rb_first(root)))
- rb_erase(node, root);
- spin_unlock(&sidgidlock);
-
- root = &siduidtree;
- spin_lock(&uidsidlock);
- while ((node = rb_first(root)))
- rb_erase(node, root);
- spin_unlock(&uidsidlock);
-
- root = &sidgidtree;
- spin_lock(&gidsidlock);
- while ((node = rb_first(root)))
- rb_erase(node, root);
- spin_unlock(&gidsidlock);
-}
-
-/* if the two SIDs (roughly equivalent to a UUID for a user or group) are
- the same returns 1, if they do not match returns 0 */
-int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
-{
- int i;
- int num_subauth, num_sat, num_saw;
-
- if ((!ctsid) || (!cwsid))
- return 1;
-
- /* compare the revision */
- if (ctsid->revision != cwsid->revision) {
- if (ctsid->revision > cwsid->revision)
- return 1;
- else
- return -1;
- }
-
- /* compare all of the six auth values */
- for (i = 0; i < 6; ++i) {
- if (ctsid->authority[i] != cwsid->authority[i]) {
- if (ctsid->authority[i] > cwsid->authority[i])
- return 1;
- else
- return -1;
- }
- }
-
- /* compare all of the subauth values if any */
- num_sat = ctsid->num_subauth;
- num_saw = cwsid->num_subauth;
- num_subauth = num_sat < num_saw ? num_sat : num_saw;
- if (num_subauth) {
- for (i = 0; i < num_subauth; ++i) {
- if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
- if (le32_to_cpu(ctsid->sub_auth[i]) >
- le32_to_cpu(cwsid->sub_auth[i]))
- return 1;
- else
- return -1;
- }
- }
- }
-
- return 0; /* sids compare/match */
-}
-
-
-/* copy ntsd, owner sid, and group sid from a security descriptor to another */
-static void copy_sec_desc(const struct cifs_ntsd *pntsd,
- struct cifs_ntsd *pnntsd, __u32 sidsoffset)
-{
- int i;
-
- struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
- struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
-
- /* copy security descriptor control portion */
- pnntsd->revision = pntsd->revision;
- pnntsd->type = pntsd->type;
- pnntsd->dacloffset = cpu_to_le32(sizeof(struct cifs_ntsd));
- pnntsd->sacloffset = 0;
- pnntsd->osidoffset = cpu_to_le32(sidsoffset);
- pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct cifs_sid));
-
- /* copy owner sid */
- owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
- le32_to_cpu(pntsd->osidoffset));
- nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
-
- nowner_sid_ptr->revision = owner_sid_ptr->revision;
- nowner_sid_ptr->num_subauth = owner_sid_ptr->num_subauth;
- for (i = 0; i < 6; i++)
- nowner_sid_ptr->authority[i] = owner_sid_ptr->authority[i];
- for (i = 0; i < 5; i++)
- nowner_sid_ptr->sub_auth[i] = owner_sid_ptr->sub_auth[i];
-
- /* copy group sid */
- group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
- le32_to_cpu(pntsd->gsidoffset));
- ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
- sizeof(struct cifs_sid));
-
- ngroup_sid_ptr->revision = group_sid_ptr->revision;
- ngroup_sid_ptr->num_subauth = group_sid_ptr->num_subauth;
- for (i = 0; i < 6; i++)
- ngroup_sid_ptr->authority[i] = group_sid_ptr->authority[i];
- for (i = 0; i < 5; i++)
- ngroup_sid_ptr->sub_auth[i] = group_sid_ptr->sub_auth[i];
-
- return;
-}
-
-
-/*
- change posix mode to reflect permissions
- pmode is the existing mode (we only want to overwrite part of this
- bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
-*/
-static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
- umode_t *pbits_to_set)
-{
- __u32 flags = le32_to_cpu(ace_flags);
- /* the order of ACEs is important. The canonical order is to begin with
- DENY entries followed by ALLOW, otherwise an allow entry could be
- encountered first, making the subsequent deny entry like "dead code"
- which would be superflous since Windows stops when a match is made
- for the operation you are trying to perform for your user */
-
- /* For deny ACEs we change the mask so that subsequent allow access
- control entries do not turn on the bits we are denying */
- if (type == ACCESS_DENIED) {
- if (flags & GENERIC_ALL)
- *pbits_to_set &= ~S_IRWXUGO;
-
- if ((flags & GENERIC_WRITE) ||
- ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
- *pbits_to_set &= ~S_IWUGO;
- if ((flags & GENERIC_READ) ||
- ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
- *pbits_to_set &= ~S_IRUGO;
- if ((flags & GENERIC_EXECUTE) ||
- ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
- *pbits_to_set &= ~S_IXUGO;
- return;
- } else if (type != ACCESS_ALLOWED) {
- cERROR(1, "unknown access control type %d", type);
- return;
- }
- /* else ACCESS_ALLOWED type */
-
- if (flags & GENERIC_ALL) {
- *pmode |= (S_IRWXUGO & (*pbits_to_set));
- cFYI(DBG2, "all perms");
- return;
- }
- if ((flags & GENERIC_WRITE) ||
- ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
- *pmode |= (S_IWUGO & (*pbits_to_set));
- if ((flags & GENERIC_READ) ||
- ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
- *pmode |= (S_IRUGO & (*pbits_to_set));
- if ((flags & GENERIC_EXECUTE) ||
- ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
- *pmode |= (S_IXUGO & (*pbits_to_set));
-
- cFYI(DBG2, "access flags 0x%x mode now 0x%x", flags, *pmode);
- return;
-}
-
-/*
- Generate access flags to reflect permissions mode is the existing mode.
- This function is called for every ACE in the DACL whose SID matches
- with either owner or group or everyone.
-*/
-
-static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
- __u32 *pace_flags)
-{
- /* reset access mask */
- *pace_flags = 0x0;
-
- /* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
- mode &= bits_to_use;
-
- /* check for R/W/X UGO since we do not know whose flags
- is this but we have cleared all the bits sans RWX for
- either user or group or other as per bits_to_use */
- if (mode & S_IRUGO)
- *pace_flags |= SET_FILE_READ_RIGHTS;
- if (mode & S_IWUGO)
- *pace_flags |= SET_FILE_WRITE_RIGHTS;
- if (mode & S_IXUGO)
- *pace_flags |= SET_FILE_EXEC_RIGHTS;
-
- cFYI(DBG2, "mode: 0x%x, access flags now 0x%x", mode, *pace_flags);
- return;
-}
-
-static __u16 fill_ace_for_sid(struct cifs_ace *pntace,
- const struct cifs_sid *psid, __u64 nmode, umode_t bits)
-{
- int i;
- __u16 size = 0;
- __u32 access_req = 0;
-
- pntace->type = ACCESS_ALLOWED;
- pntace->flags = 0x0;
- mode_to_access_flags(nmode, bits, &access_req);
- if (!access_req)
- access_req = SET_MINIMUM_RIGHTS;
- pntace->access_req = cpu_to_le32(access_req);
-
- pntace->sid.revision = psid->revision;
- pntace->sid.num_subauth = psid->num_subauth;
- for (i = 0; i < 6; i++)
- pntace->sid.authority[i] = psid->authority[i];
- for (i = 0; i < psid->num_subauth; i++)
- pntace->sid.sub_auth[i] = psid->sub_auth[i];
-
- size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
- pntace->size = cpu_to_le16(size);
-
- return size;
-}
-
-
-#ifdef CONFIG_CIFS_DEBUG2
-static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
-{
- int num_subauth;
-
- /* validate that we do not go past end of acl */
-
- if (le16_to_cpu(pace->size) < 16) {
- cERROR(1, "ACE too small %d", le16_to_cpu(pace->size));
- return;
- }
-
- if (end_of_acl < (char *)pace + le16_to_cpu(pace->size)) {
- cERROR(1, "ACL too small to parse ACE");
- return;
- }
-
- num_subauth = pace->sid.num_subauth;
- if (num_subauth) {
- int i;
- cFYI(1, "ACE revision %d num_auth %d type %d flags %d size %d",
- pace->sid.revision, pace->sid.num_subauth, pace->type,
- pace->flags, le16_to_cpu(pace->size));
- for (i = 0; i < num_subauth; ++i) {
- cFYI(1, "ACE sub_auth[%d]: 0x%x", i,
- le32_to_cpu(pace->sid.sub_auth[i]));
- }
-
- /* BB add length check to make sure that we do not have huge
- num auths and therefore go off the end */
- }
-
- return;
-}
-#endif
-
-
-static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
- struct cifs_sid *pownersid, struct cifs_sid *pgrpsid,
- struct cifs_fattr *fattr)
-{
- int i;
- int num_aces = 0;
- int acl_size;
- char *acl_base;
- struct cifs_ace **ppace;
-
- /* BB need to add parm so we can store the SID BB */
-
- if (!pdacl) {
- /* no DACL in the security descriptor, set
- all the permissions for user/group/other */
- fattr->cf_mode |= S_IRWXUGO;
- return;
- }
-
- /* validate that we do not go past end of acl */
- if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
- cERROR(1, "ACL too small to parse DACL");
- return;
- }
-
- cFYI(DBG2, "DACL revision %d size %d num aces %d",
- le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size),
- le32_to_cpu(pdacl->num_aces));
-
- /* reset rwx permissions for user/group/other.
- Also, if num_aces is 0 i.e. DACL has no ACEs,
- user/group/other have no permissions */
- fattr->cf_mode &= ~(S_IRWXUGO);
-
- acl_base = (char *)pdacl;
- acl_size = sizeof(struct cifs_acl);
-
- num_aces = le32_to_cpu(pdacl->num_aces);
- if (num_aces > 0) {
- umode_t user_mask = S_IRWXU;
- umode_t group_mask = S_IRWXG;
- umode_t other_mask = S_IRWXU | S_IRWXG | S_IRWXO;
-
- if (num_aces > ULONG_MAX / sizeof(struct cifs_ace *))
- return;
- ppace = kmalloc(num_aces * sizeof(struct cifs_ace *),
- GFP_KERNEL);
- if (!ppace) {
- cERROR(1, "DACL memory allocation error");
- return;
- }
-
- for (i = 0; i < num_aces; ++i) {
- ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
-#ifdef CONFIG_CIFS_DEBUG2
- dump_ace(ppace[i], end_of_acl);
-#endif
- if (compare_sids(&(ppace[i]->sid), pownersid) == 0)
- access_flags_to_mode(ppace[i]->access_req,
- ppace[i]->type,
- &fattr->cf_mode,
- &user_mask);
- if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0)
- access_flags_to_mode(ppace[i]->access_req,
- ppace[i]->type,
- &fattr->cf_mode,
- &group_mask);
- if (compare_sids(&(ppace[i]->sid), &sid_everyone) == 0)
- access_flags_to_mode(ppace[i]->access_req,
- ppace[i]->type,
- &fattr->cf_mode,
- &other_mask);
- if (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0)
- access_flags_to_mode(ppace[i]->access_req,
- ppace[i]->type,
- &fattr->cf_mode,
- &other_mask);
-
-
-/* memcpy((void *)(&(cifscred->aces[i])),
- (void *)ppace[i],
- sizeof(struct cifs_ace)); */
-
- acl_base = (char *)ppace[i];
- acl_size = le16_to_cpu(ppace[i]->size);
- }
-
- kfree(ppace);
- }
-
- return;
-}
-
-
-static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
- struct cifs_sid *pgrpsid, __u64 nmode)
-{
- u16 size = 0;
- struct cifs_acl *pnndacl;
-
- pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl));
-
- size += fill_ace_for_sid((struct cifs_ace *) ((char *)pnndacl + size),
- pownersid, nmode, S_IRWXU);
- size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
- pgrpsid, nmode, S_IRWXG);
- size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
- &sid_everyone, nmode, S_IRWXO);
-
- pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl));
- pndacl->num_aces = cpu_to_le32(3);
-
- return 0;
-}
-
-
-static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
-{
- /* BB need to add parm so we can store the SID BB */
-
- /* validate that we do not go past end of ACL - sid must be at least 8
- bytes long (assuming no sub-auths - e.g. the null SID */
- if (end_of_acl < (char *)psid + 8) {
- cERROR(1, "ACL too small to parse SID %p", psid);
- return -EINVAL;
- }
-
- if (psid->num_subauth) {
-#ifdef CONFIG_CIFS_DEBUG2
- int i;
- cFYI(1, "SID revision %d num_auth %d",
- psid->revision, psid->num_subauth);
-
- for (i = 0; i < psid->num_subauth; i++) {
- cFYI(1, "SID sub_auth[%d]: 0x%x ", i,
- le32_to_cpu(psid->sub_auth[i]));
- }
-
- /* BB add length check to make sure that we do not have huge
- num auths and therefore go off the end */
- cFYI(1, "RID 0x%x",
- le32_to_cpu(psid->sub_auth[psid->num_subauth-1]));
-#endif
- }
-
- return 0;
-}
-
-
-/* Convert CIFS ACL to POSIX form */
-static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
- struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr)
-{
- int rc = 0;
- struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
- struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
- char *end_of_acl = ((char *)pntsd) + acl_len;
- __u32 dacloffset;
-
- if (pntsd == NULL)
- return -EIO;
-
- owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
- le32_to_cpu(pntsd->osidoffset));
- group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
- le32_to_cpu(pntsd->gsidoffset));
- dacloffset = le32_to_cpu(pntsd->dacloffset);
- dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
- cFYI(DBG2, "revision %d type 0x%x ooffset 0x%x goffset 0x%x "
- "sacloffset 0x%x dacloffset 0x%x",
- pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
- le32_to_cpu(pntsd->gsidoffset),
- le32_to_cpu(pntsd->sacloffset), dacloffset);
-/* cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
- rc = parse_sid(owner_sid_ptr, end_of_acl);
- if (rc) {
- cFYI(1, "%s: Error %d parsing Owner SID", __func__, rc);
- return rc;
- }
- rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
- if (rc) {
- cFYI(1, "%s: Error %d mapping Owner SID to uid", __func__, rc);
- return rc;
- }
-
- rc = parse_sid(group_sid_ptr, end_of_acl);
- if (rc) {
- cFYI(1, "%s: Error %d mapping Owner SID to gid", __func__, rc);
- return rc;
- }
- rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
- if (rc) {
- cFYI(1, "%s: Error %d mapping Group SID to gid", __func__, rc);
- return rc;
- }
-
- if (dacloffset)
- parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
- group_sid_ptr, fattr);
- else
- cFYI(1, "no ACL"); /* BB grant all or default perms? */
-
- return rc;
-}
-
-/* Convert permission bits from mode to equivalent CIFS ACL */
-static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
- __u32 secdesclen, __u64 nmode, uid_t uid, gid_t gid, int *aclflag)
-{
- int rc = 0;
- __u32 dacloffset;
- __u32 ndacloffset;
- __u32 sidsoffset;
- struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
- struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
- struct cifs_acl *dacl_ptr = NULL; /* no need for SACL ptr */
- struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
-
- if (nmode != NO_CHANGE_64) { /* chmod */
- owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
- le32_to_cpu(pntsd->osidoffset));
- group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
- le32_to_cpu(pntsd->gsidoffset));
- dacloffset = le32_to_cpu(pntsd->dacloffset);
- dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
- ndacloffset = sizeof(struct cifs_ntsd);
- ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
- ndacl_ptr->revision = dacl_ptr->revision;
- ndacl_ptr->size = 0;
- ndacl_ptr->num_aces = 0;
-
- rc = set_chmod_dacl(ndacl_ptr, owner_sid_ptr, group_sid_ptr,
- nmode);
- sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
- /* copy sec desc control portion & owner and group sids */
- copy_sec_desc(pntsd, pnntsd, sidsoffset);
- *aclflag = CIFS_ACL_DACL;
- } else {
- memcpy(pnntsd, pntsd, secdesclen);
- if (uid != NO_CHANGE_32) { /* chown */
- owner_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
- le32_to_cpu(pnntsd->osidoffset));
- nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid),
- GFP_KERNEL);
- if (!nowner_sid_ptr)
- return -ENOMEM;
- rc = id_to_sid(uid, SIDOWNER, nowner_sid_ptr);
- if (rc) {
- cFYI(1, "%s: Mapping error %d for owner id %d",
- __func__, rc, uid);
- kfree(nowner_sid_ptr);
- return rc;
- }
- memcpy(owner_sid_ptr, nowner_sid_ptr,
- sizeof(struct cifs_sid));
- kfree(nowner_sid_ptr);
- *aclflag = CIFS_ACL_OWNER;
- }
- if (gid != NO_CHANGE_32) { /* chgrp */
- group_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
- le32_to_cpu(pnntsd->gsidoffset));
- ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid),
- GFP_KERNEL);
- if (!ngroup_sid_ptr)
- return -ENOMEM;
- rc = id_to_sid(gid, SIDGROUP, ngroup_sid_ptr);
- if (rc) {
- cFYI(1, "%s: Mapping error %d for group id %d",
- __func__, rc, gid);
- kfree(ngroup_sid_ptr);
- return rc;
- }
- memcpy(group_sid_ptr, ngroup_sid_ptr,
- sizeof(struct cifs_sid));
- kfree(ngroup_sid_ptr);
- *aclflag = CIFS_ACL_GROUP;
- }
- }
-
- return rc;
-}
-
-static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
- __u16 fid, u32 *pacllen)
-{
- struct cifs_ntsd *pntsd = NULL;
- int xid, rc;
- struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
-
- if (IS_ERR(tlink))
- return ERR_CAST(tlink);
-
- xid = GetXid();
- rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), fid, &pntsd, pacllen);
- FreeXid(xid);
-
- cifs_put_tlink(tlink);
-
- cFYI(1, "%s: rc = %d ACL len %d", __func__, rc, *pacllen);
- if (rc)
- return ERR_PTR(rc);
- return pntsd;
-}
-
-static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
- const char *path, u32 *pacllen)
-{
- struct cifs_ntsd *pntsd = NULL;
- int oplock = 0;
- int xid, rc, create_options = 0;
- __u16 fid;
- struct cifs_tcon *tcon;
- struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
-
- if (IS_ERR(tlink))
- return ERR_CAST(tlink);
-
- tcon = tlink_tcon(tlink);
- xid = GetXid();
-
- if (backup_cred(cifs_sb))
- create_options |= CREATE_OPEN_BACKUP_INTENT;
-
- rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL,
- create_options, &fid, &oplock, NULL, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
- if (!rc) {
- rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen);
- CIFSSMBClose(xid, tcon, fid);
- }
-
- cifs_put_tlink(tlink);
- FreeXid(xid);
-
- cFYI(1, "%s: rc = %d ACL len %d", __func__, rc, *pacllen);
- if (rc)
- return ERR_PTR(rc);
- return pntsd;
-}
-
-/* Retrieve an ACL from the server */
-struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
- struct inode *inode, const char *path,
- u32 *pacllen)
-{
- struct cifs_ntsd *pntsd = NULL;
- struct cifsFileInfo *open_file = NULL;
-
- if (inode)
- open_file = find_readable_file(CIFS_I(inode), true);
- if (!open_file)
- return get_cifs_acl_by_path(cifs_sb, path, pacllen);
-
- pntsd = get_cifs_acl_by_fid(cifs_sb, open_file->netfid, pacllen);
- cifsFileInfo_put(open_file);
- return pntsd;
-}
-
- /* Set an ACL on the server */
-int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
- struct inode *inode, const char *path, int aclflag)
-{
- int oplock = 0;
- int xid, rc, access_flags, create_options = 0;
- __u16 fid;
- struct cifs_tcon *tcon;
- struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
- struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
-
- if (IS_ERR(tlink))
- return PTR_ERR(tlink);
-
- tcon = tlink_tcon(tlink);
- xid = GetXid();
-
- if (backup_cred(cifs_sb))
- create_options |= CREATE_OPEN_BACKUP_INTENT;
-
- if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
- access_flags = WRITE_OWNER;
- else
- access_flags = WRITE_DAC;
-
- rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, access_flags,
- create_options, &fid, &oplock, NULL, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
- if (rc) {
- cERROR(1, "Unable to open file to set ACL");
- goto out;
- }
-
- rc = CIFSSMBSetCIFSACL(xid, tcon, fid, pnntsd, acllen, aclflag);
- cFYI(DBG2, "SetCIFSACL rc = %d", rc);
-
- CIFSSMBClose(xid, tcon, fid);
-out:
- FreeXid(xid);
- cifs_put_tlink(tlink);
- return rc;
-}
-
-/* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */
-int
-cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
- struct inode *inode, const char *path, const __u16 *pfid)
-{
- struct cifs_ntsd *pntsd = NULL;
- u32 acllen = 0;
- int rc = 0;
-
- cFYI(DBG2, "converting ACL to mode for %s", path);
-
- if (pfid)
- pntsd = get_cifs_acl_by_fid(cifs_sb, *pfid, &acllen);
- else
- pntsd = get_cifs_acl(cifs_sb, inode, path, &acllen);
-
- /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
- if (IS_ERR(pntsd)) {
- rc = PTR_ERR(pntsd);
- cERROR(1, "%s: error %d getting sec desc", __func__, rc);
- } else {
- rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr);
- kfree(pntsd);
- if (rc)
- cERROR(1, "parse sec desc failed rc = %d", rc);
- }
-
- return rc;
-}
-
-/* Convert mode bits to an ACL so we can update the ACL on the server */
-int
-id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
- uid_t uid, gid_t gid)
-{
- int rc = 0;
- int aclflag = CIFS_ACL_DACL; /* default flag to set */
- __u32 secdesclen = 0;
- struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
- struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
-
- cFYI(DBG2, "set ACL from mode for %s", path);
-
- /* Get the security descriptor */
- pntsd = get_cifs_acl(CIFS_SB(inode->i_sb), inode, path, &secdesclen);
-
- /* Add three ACEs for owner, group, everyone getting rid of
- other ACEs as chmod disables ACEs and set the security descriptor */
-
- if (IS_ERR(pntsd)) {
- rc = PTR_ERR(pntsd);
- cERROR(1, "%s: error %d getting sec desc", __func__, rc);
- } else {
- /* allocate memory for the smb header,
- set security descriptor request security descriptor
- parameters, and secuirty descriptor itself */
-
- secdesclen = secdesclen < DEFSECDESCLEN ?
- DEFSECDESCLEN : secdesclen;
- pnntsd = kmalloc(secdesclen, GFP_KERNEL);
- if (!pnntsd) {
- cERROR(1, "Unable to allocate security descriptor");
- kfree(pntsd);
- return -ENOMEM;
- }
-
- rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid,
- &aclflag);
-
- cFYI(DBG2, "build_sec_desc rc: %d", rc);
-
- if (!rc) {
- /* Set the security descriptor */
- rc = set_cifs_acl(pnntsd, secdesclen, inode,
- path, aclflag);
- cFYI(DBG2, "set_cifs_acl rc: %d", rc);
- }
-
- kfree(pnntsd);
- kfree(pntsd);
- }
-
- return rc;
-}
diff --git a/ANDROID_3.4.5/fs/cifs/cifsacl.h b/ANDROID_3.4.5/fs/cifs/cifsacl.h
deleted file mode 100644
index 5c902c7c..00000000
--- a/ANDROID_3.4.5/fs/cifs/cifsacl.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * fs/cifs/cifsacl.h
- *
- * Copyright (c) International Business Machines Corp., 2007
- * Author(s): Steve French (sfrench@us.ibm.com)
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _CIFSACL_H
-#define _CIFSACL_H
-
-
-#define NUM_AUTHS 6 /* number of authority fields */
-#define NUM_SUBAUTHS 5 /* number of sub authority fields */
-#define NUM_WK_SIDS 7 /* number of well known sids */
-#define SIDNAMELENGTH 20 /* long enough for the ones we care about */
-#define DEFSECDESCLEN 192 /* sec desc len contaiting a dacl with three aces */
-
-#define READ_BIT 0x4
-#define WRITE_BIT 0x2
-#define EXEC_BIT 0x1
-
-#define UBITSHIFT 6
-#define GBITSHIFT 3
-
-#define ACCESS_ALLOWED 0
-#define ACCESS_DENIED 1
-
-#define SIDOWNER 1
-#define SIDGROUP 2
-#define SIDLEN 150 /* S- 1 revision- 6 authorities- max 5 sub authorities */
-
-#define SID_ID_MAPPED 0
-#define SID_ID_PENDING 1
-#define SID_MAP_EXPIRE (3600 * HZ) /* map entry expires after one hour */
-#define SID_MAP_RETRY (300 * HZ) /* wait 5 minutes for next attempt to map */
-
-struct cifs_ntsd {
- __le16 revision; /* revision level */
- __le16 type;
- __le32 osidoffset;
- __le32 gsidoffset;
- __le32 sacloffset;
- __le32 dacloffset;
-} __attribute__((packed));
-
-struct cifs_sid {
- __u8 revision; /* revision level */
- __u8 num_subauth;
- __u8 authority[6];
- __le32 sub_auth[5]; /* sub_auth[num_subauth] */
-} __attribute__((packed));
-
-struct cifs_acl {
- __le16 revision; /* revision level */
- __le16 size;
- __le32 num_aces;
-} __attribute__((packed));
-
-struct cifs_ace {
- __u8 type;
- __u8 flags;
- __le16 size;
- __le32 access_req;
- struct cifs_sid sid; /* ie UUID of user or group who gets these perms */
-} __attribute__((packed));
-
-struct cifs_wksid {
- struct cifs_sid cifssid;
- char sidname[SIDNAMELENGTH];
-} __attribute__((packed));
-
-struct cifs_sid_id {
- unsigned int refcount; /* increment with spinlock, decrement without */
- unsigned long id;
- unsigned long time;
- unsigned long state;
- char *sidstr;
- struct rb_node rbnode;
- struct cifs_sid sid;
-};
-
-#ifdef __KERNEL__
-extern struct key_type cifs_idmap_key_type;
-extern const struct cred *root_cred;
-#endif /* KERNEL */
-
-extern int compare_sids(const struct cifs_sid *, const struct cifs_sid *);
-
-#endif /* _CIFSACL_H */
diff --git a/ANDROID_3.4.5/fs/cifs/cifsencrypt.c b/ANDROID_3.4.5/fs/cifs/cifsencrypt.c
deleted file mode 100644
index 63c460e5..00000000
--- a/ANDROID_3.4.5/fs/cifs/cifsencrypt.c
+++ /dev/null
@@ -1,754 +0,0 @@
-/*
- * fs/cifs/cifsencrypt.c
- *
- * Copyright (C) International Business Machines Corp., 2005,2006
- * Author(s): Steve French (sfrench@us.ibm.com)
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include "cifspdu.h"
-#include "cifsglob.h"
-#include "cifs_debug.h"
-#include "cifs_unicode.h"
-#include "cifsproto.h"
-#include "ntlmssp.h"
-#include <linux/ctype.h>
-#include <linux/random.h>
-
-/*
- * Calculate and return the CIFS signature based on the mac key and SMB PDU.
- * The 16 byte signature must be allocated by the caller. Note we only use the
- * 1st eight bytes and that the smb header signature field on input contains
- * the sequence number before this function is called. Also, this function
- * should be called with the server->srv_mutex held.
- */
-static int cifs_calc_signature(const struct kvec *iov, int n_vec,
- struct TCP_Server_Info *server, char *signature)
-{
- int i;
- int rc;
-
- if (iov == NULL || signature == NULL || server == NULL)
- return -EINVAL;
-
- if (!server->secmech.sdescmd5) {
- cERROR(1, "%s: Can't generate signature\n", __func__);
- return -1;
- }
-
- rc = crypto_shash_init(&server->secmech.sdescmd5->shash);
- if (rc) {
- cERROR(1, "%s: Could not init md5\n", __func__);
- return rc;
- }
-
- rc = crypto_shash_update(&server->secmech.sdescmd5->shash,
- server->session_key.response, server->session_key.len);
- if (rc) {
- cERROR(1, "%s: Could not update with response\n", __func__);
- return rc;
- }
-
- for (i = 0; i < n_vec; i++) {
- if (iov[i].iov_len == 0)
- continue;
- if (iov[i].iov_base == NULL) {
- cERROR(1, "null iovec entry");
- return -EIO;
- }
- /* The first entry includes a length field (which does not get
- signed that occupies the first 4 bytes before the header */
- if (i == 0) {
- if (iov[0].iov_len <= 8) /* cmd field at offset 9 */
- break; /* nothing to sign or corrupt header */
- rc =
- crypto_shash_update(&server->secmech.sdescmd5->shash,
- iov[i].iov_base + 4, iov[i].iov_len - 4);
- } else {
- rc =
- crypto_shash_update(&server->secmech.sdescmd5->shash,
- iov[i].iov_base, iov[i].iov_len);
- }
- if (rc) {
- cERROR(1, "%s: Could not update with payload\n",
- __func__);
- return rc;
- }
- }
-
- rc = crypto_shash_final(&server->secmech.sdescmd5->shash, signature);
- if (rc)
- cERROR(1, "%s: Could not generate md5 hash\n", __func__);
-
- return rc;
-}
-
-/* must be called with server->srv_mutex held */
-int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
- __u32 *pexpected_response_sequence_number)
-{
- int rc = 0;
- char smb_signature[20];
- struct smb_hdr *cifs_pdu = (struct smb_hdr *)iov[0].iov_base;
-
- if ((cifs_pdu == NULL) || (server == NULL))
- return -EINVAL;
-
- if (!(cifs_pdu->Flags2 & SMBFLG2_SECURITY_SIGNATURE) ||
- server->tcpStatus == CifsNeedNegotiate)
- return rc;
-
- if (!server->session_estab) {
- memcpy(cifs_pdu->Signature.SecuritySignature, "BSRSPYL", 8);
- return rc;
- }
-
- cifs_pdu->Signature.Sequence.SequenceNumber =
- cpu_to_le32(server->sequence_number);
- cifs_pdu->Signature.Sequence.Reserved = 0;
-
- *pexpected_response_sequence_number = server->sequence_number++;
- server->sequence_number++;
-
- rc = cifs_calc_signature(iov, n_vec, server, smb_signature);
- if (rc)
- memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
- else
- memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8);
-
- return rc;
-}
-
-/* must be called with server->srv_mutex held */
-int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
- __u32 *pexpected_response_sequence_number)
-{
- struct kvec iov;
-
- iov.iov_base = cifs_pdu;
- iov.iov_len = be32_to_cpu(cifs_pdu->smb_buf_length) + 4;
-
- return cifs_sign_smb2(&iov, 1, server,
- pexpected_response_sequence_number);
-}
-
-int cifs_verify_signature(struct kvec *iov, unsigned int nr_iov,
- struct TCP_Server_Info *server,
- __u32 expected_sequence_number)
-{
- unsigned int rc;
- char server_response_sig[8];
- char what_we_think_sig_should_be[20];
- struct smb_hdr *cifs_pdu = (struct smb_hdr *)iov[0].iov_base;
-
- if (cifs_pdu == NULL || server == NULL)
- return -EINVAL;
-
- if (!server->session_estab)
- return 0;
-
- if (cifs_pdu->Command == SMB_COM_LOCKING_ANDX) {
- struct smb_com_lock_req *pSMB =
- (struct smb_com_lock_req *)cifs_pdu;
- if (pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE)
- return 0;
- }
-
- /* BB what if signatures are supposed to be on for session but
- server does not send one? BB */
-
- /* Do not need to verify session setups with signature "BSRSPYL " */
- if (memcmp(cifs_pdu->Signature.SecuritySignature, "BSRSPYL ", 8) == 0)
- cFYI(1, "dummy signature received for smb command 0x%x",
- cifs_pdu->Command);
-
- /* save off the origiginal signature so we can modify the smb and check
- its signature against what the server sent */
- memcpy(server_response_sig, cifs_pdu->Signature.SecuritySignature, 8);
-
- cifs_pdu->Signature.Sequence.SequenceNumber =
- cpu_to_le32(expected_sequence_number);
- cifs_pdu->Signature.Sequence.Reserved = 0;
-
- mutex_lock(&server->srv_mutex);
- rc = cifs_calc_signature(iov, nr_iov, server,
- what_we_think_sig_should_be);
- mutex_unlock(&server->srv_mutex);
-
- if (rc)
- return rc;
-
-/* cifs_dump_mem("what we think it should be: ",
- what_we_think_sig_should_be, 16); */
-
- if (memcmp(server_response_sig, what_we_think_sig_should_be, 8))
- return -EACCES;
- else
- return 0;
-
-}
-
-/* first calculate 24 bytes ntlm response and then 16 byte session key */
-int setup_ntlm_response(struct cifs_ses *ses, const struct nls_table *nls_cp)
-{
- int rc = 0;
- unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE;
- char temp_key[CIFS_SESS_KEY_SIZE];
-
- if (!ses)
- return -EINVAL;
-
- ses->auth_key.response = kmalloc(temp_len, GFP_KERNEL);
- if (!ses->auth_key.response) {
- cERROR(1, "NTLM can't allocate (%u bytes) memory", temp_len);
- return -ENOMEM;
- }
- ses->auth_key.len = temp_len;
-
- rc = SMBNTencrypt(ses->password, ses->server->cryptkey,
- ses->auth_key.response + CIFS_SESS_KEY_SIZE, nls_cp);
- if (rc) {
- cFYI(1, "%s Can't generate NTLM response, error: %d",
- __func__, rc);
- return rc;
- }
-
- rc = E_md4hash(ses->password, temp_key, nls_cp);
- if (rc) {
- cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc);
- return rc;
- }
-
- rc = mdfour(ses->auth_key.response, temp_key, CIFS_SESS_KEY_SIZE);
- if (rc)
- cFYI(1, "%s Can't generate NTLM session key, error: %d",
- __func__, rc);
-
- return rc;
-}
-
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
-int calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
- char *lnm_session_key)
-{
- int i;
- int rc;
- char password_with_pad[CIFS_ENCPWD_SIZE];
-
- memset(password_with_pad, 0, CIFS_ENCPWD_SIZE);
- if (password)
- strncpy(password_with_pad, password, CIFS_ENCPWD_SIZE);
-
- if (!encrypt && global_secflags & CIFSSEC_MAY_PLNTXT) {
- memset(lnm_session_key, 0, CIFS_SESS_KEY_SIZE);
- memcpy(lnm_session_key, password_with_pad,
- CIFS_ENCPWD_SIZE);
- return 0;
- }
-
- /* calculate old style session key */
- /* calling toupper is less broken than repeatedly
- calling nls_toupper would be since that will never
- work for UTF8, but neither handles multibyte code pages
- but the only alternative would be converting to UCS-16 (Unicode)
- (using a routine something like UniStrupr) then
- uppercasing and then converting back from Unicode - which
- would only worth doing it if we knew it were utf8. Basically
- utf8 and other multibyte codepages each need their own strupper
- function since a byte at a time will ont work. */
-
- for (i = 0; i < CIFS_ENCPWD_SIZE; i++)
- password_with_pad[i] = toupper(password_with_pad[i]);
-
- rc = SMBencrypt(password_with_pad, cryptkey, lnm_session_key);
-
- return rc;
-}
-#endif /* CIFS_WEAK_PW_HASH */
-
-/* Build a proper attribute value/target info pairs blob.
- * Fill in netbios and dns domain name and workstation name
- * and client time (total five av pairs and + one end of fields indicator.
- * Allocate domain name which gets freed when session struct is deallocated.
- */
-static int
-build_avpair_blob(struct cifs_ses *ses, const struct nls_table *nls_cp)
-{
- unsigned int dlen;
- unsigned int size = 2 * sizeof(struct ntlmssp2_name);
- char *defdmname = "WORKGROUP";
- unsigned char *blobptr;
- struct ntlmssp2_name *attrptr;
-
- if (!ses->domainName) {
- ses->domainName = kstrdup(defdmname, GFP_KERNEL);
- if (!ses->domainName)
- return -ENOMEM;
- }
-
- dlen = strlen(ses->domainName);
-
- /*
- * The length of this blob is two times the size of a
- * structure (av pair) which holds name/size
- * ( for NTLMSSP_AV_NB_DOMAIN_NAME followed by NTLMSSP_AV_EOL ) +
- * unicode length of a netbios domain name
- */
- ses->auth_key.len = size + 2 * dlen;
- ses->auth_key.response = kzalloc(ses->auth_key.len, GFP_KERNEL);
- if (!ses->auth_key.response) {
- ses->auth_key.len = 0;
- cERROR(1, "Challenge target info allocation failure");
- return -ENOMEM;
- }
-
- blobptr = ses->auth_key.response;
- attrptr = (struct ntlmssp2_name *) blobptr;
-
- /*
- * As defined in MS-NTLM 3.3.2, just this av pair field
- * is sufficient as part of the temp
- */
- attrptr->type = cpu_to_le16(NTLMSSP_AV_NB_DOMAIN_NAME);
- attrptr->length = cpu_to_le16(2 * dlen);
- blobptr = (unsigned char *)attrptr + sizeof(struct ntlmssp2_name);
- cifs_strtoUTF16((__le16 *)blobptr, ses->domainName, dlen, nls_cp);
-
- return 0;
-}
-
-/* Server has provided av pairs/target info in the type 2 challenge
- * packet and we have plucked it and stored within smb session.
- * We parse that blob here to find netbios domain name to be used
- * as part of ntlmv2 authentication (in Target String), if not already
- * specified on the command line.
- * If this function returns without any error but without fetching
- * domain name, authentication may fail against some server but
- * may not fail against other (those who are not very particular
- * about target string i.e. for some, just user name might suffice.
- */
-static int
-find_domain_name(struct cifs_ses *ses, const struct nls_table *nls_cp)
-{
- unsigned int attrsize;
- unsigned int type;
- unsigned int onesize = sizeof(struct ntlmssp2_name);
- unsigned char *blobptr;
- unsigned char *blobend;
- struct ntlmssp2_name *attrptr;
-
- if (!ses->auth_key.len || !ses->auth_key.response)
- return 0;
-
- blobptr = ses->auth_key.response;
- blobend = blobptr + ses->auth_key.len;
-
- while (blobptr + onesize < blobend) {
- attrptr = (struct ntlmssp2_name *) blobptr;
- type = le16_to_cpu(attrptr->type);
- if (type == NTLMSSP_AV_EOL)
- break;
- blobptr += 2; /* advance attr type */
- attrsize = le16_to_cpu(attrptr->length);
- blobptr += 2; /* advance attr size */
- if (blobptr + attrsize > blobend)
- break;
- if (type == NTLMSSP_AV_NB_DOMAIN_NAME) {
- if (!attrsize)
- break;
- if (!ses->domainName) {
- ses->domainName =
- kmalloc(attrsize + 1, GFP_KERNEL);
- if (!ses->domainName)
- return -ENOMEM;
- cifs_from_utf16(ses->domainName,
- (__le16 *)blobptr, attrsize, attrsize,
- nls_cp, false);
- break;
- }
- }
- blobptr += attrsize; /* advance attr value */
- }
-
- return 0;
-}
-
-static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
- const struct nls_table *nls_cp)
-{
- int rc = 0;
- int len;
- char nt_hash[CIFS_NTHASH_SIZE];
- wchar_t *user;
- wchar_t *domain;
- wchar_t *server;
-
- if (!ses->server->secmech.sdeschmacmd5) {
- cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n");
- return -1;
- }
-
- /* calculate md4 hash of password */
- E_md4hash(ses->password, nt_hash, nls_cp);
-
- rc = crypto_shash_setkey(ses->server->secmech.hmacmd5, nt_hash,
- CIFS_NTHASH_SIZE);
- if (rc) {
- cERROR(1, "%s: Could not set NT Hash as a key", __func__);
- return rc;
- }
-
- rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
- if (rc) {
- cERROR(1, "calc_ntlmv2_hash: could not init hmacmd5\n");
- return rc;
- }
-
- /* convert ses->user_name to unicode and uppercase */
- len = ses->user_name ? strlen(ses->user_name) : 0;
- user = kmalloc(2 + (len * 2), GFP_KERNEL);
- if (user == NULL) {
- cERROR(1, "calc_ntlmv2_hash: user mem alloc failure\n");
- rc = -ENOMEM;
- return rc;
- }
-
- if (len) {
- len = cifs_strtoUTF16((__le16 *)user, ses->user_name, len, nls_cp);
- UniStrupr(user);
- } else {
- memset(user, '\0', 2);
- }
-
- rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
- (char *)user, 2 * len);
- kfree(user);
- if (rc) {
- cERROR(1, "%s: Could not update with user\n", __func__);
- return rc;
- }
-
- /* convert ses->domainName to unicode and uppercase */
- if (ses->domainName) {
- len = strlen(ses->domainName);
-
- domain = kmalloc(2 + (len * 2), GFP_KERNEL);
- if (domain == NULL) {
- cERROR(1, "calc_ntlmv2_hash: domain mem alloc failure");
- rc = -ENOMEM;
- return rc;
- }
- len = cifs_strtoUTF16((__le16 *)domain, ses->domainName, len,
- nls_cp);
- rc =
- crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
- (char *)domain, 2 * len);
- kfree(domain);
- if (rc) {
- cERROR(1, "%s: Could not update with domain\n",
- __func__);
- return rc;
- }
- } else if (ses->serverName) {
- len = strlen(ses->serverName);
-
- server = kmalloc(2 + (len * 2), GFP_KERNEL);
- if (server == NULL) {
- cERROR(1, "calc_ntlmv2_hash: server mem alloc failure");
- rc = -ENOMEM;
- return rc;
- }
- len = cifs_strtoUTF16((__le16 *)server, ses->serverName, len,
- nls_cp);
- rc =
- crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
- (char *)server, 2 * len);
- kfree(server);
- if (rc) {
- cERROR(1, "%s: Could not update with server\n",
- __func__);
- return rc;
- }
- }
-
- rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
- ntlmv2_hash);
- if (rc)
- cERROR(1, "%s: Could not generate md5 hash\n", __func__);
-
- return rc;
-}
-
-static int
-CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash)
-{
- int rc;
- unsigned int offset = CIFS_SESS_KEY_SIZE + 8;
-
- if (!ses->server->secmech.sdeschmacmd5) {
- cERROR(1, "calc_ntlmv2_hash: can't generate ntlmv2 hash\n");
- return -1;
- }
-
- rc = crypto_shash_setkey(ses->server->secmech.hmacmd5,
- ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
- if (rc) {
- cERROR(1, "%s: Could not set NTLMV2 Hash as a key", __func__);
- return rc;
- }
-
- rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
- if (rc) {
- cERROR(1, "CalcNTLMv2_response: could not init hmacmd5");
- return rc;
- }
-
- if (ses->server->secType == RawNTLMSSP)
- memcpy(ses->auth_key.response + offset,
- ses->ntlmssp->cryptkey, CIFS_SERVER_CHALLENGE_SIZE);
- else
- memcpy(ses->auth_key.response + offset,
- ses->server->cryptkey, CIFS_SERVER_CHALLENGE_SIZE);
- rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
- ses->auth_key.response + offset, ses->auth_key.len - offset);
- if (rc) {
- cERROR(1, "%s: Could not update with response\n", __func__);
- return rc;
- }
-
- rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
- ses->auth_key.response + CIFS_SESS_KEY_SIZE);
- if (rc)
- cERROR(1, "%s: Could not generate md5 hash\n", __func__);
-
- return rc;
-}
-
-
-int
-setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
-{
- int rc;
- int baselen;
- unsigned int tilen;
- struct ntlmv2_resp *buf;
- char ntlmv2_hash[16];
- unsigned char *tiblob = NULL; /* target info blob */
-
- if (ses->server->secType == RawNTLMSSP) {
- if (!ses->domainName) {
- rc = find_domain_name(ses, nls_cp);
- if (rc) {
- cERROR(1, "error %d finding domain name", rc);
- goto setup_ntlmv2_rsp_ret;
- }
- }
- } else {
- rc = build_avpair_blob(ses, nls_cp);
- if (rc) {
- cERROR(1, "error %d building av pair blob", rc);
- goto setup_ntlmv2_rsp_ret;
- }
- }
-
- baselen = CIFS_SESS_KEY_SIZE + sizeof(struct ntlmv2_resp);
- tilen = ses->auth_key.len;
- tiblob = ses->auth_key.response;
-
- ses->auth_key.response = kmalloc(baselen + tilen, GFP_KERNEL);
- if (!ses->auth_key.response) {
- rc = ENOMEM;
- ses->auth_key.len = 0;
- cERROR(1, "%s: Can't allocate auth blob", __func__);
- goto setup_ntlmv2_rsp_ret;
- }
- ses->auth_key.len += baselen;
-
- buf = (struct ntlmv2_resp *)
- (ses->auth_key.response + CIFS_SESS_KEY_SIZE);
- buf->blob_signature = cpu_to_le32(0x00000101);
- buf->reserved = 0;
- buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
- get_random_bytes(&buf->client_chal, sizeof(buf->client_chal));
- buf->reserved2 = 0;
-
- memcpy(ses->auth_key.response + baselen, tiblob, tilen);
-
- /* calculate ntlmv2_hash */
- rc = calc_ntlmv2_hash(ses, ntlmv2_hash, nls_cp);
- if (rc) {
- cERROR(1, "could not get v2 hash rc %d", rc);
- goto setup_ntlmv2_rsp_ret;
- }
-
- /* calculate first part of the client response (CR1) */
- rc = CalcNTLMv2_response(ses, ntlmv2_hash);
- if (rc) {
- cERROR(1, "Could not calculate CR1 rc: %d", rc);
- goto setup_ntlmv2_rsp_ret;
- }
-
- /* now calculate the session key for NTLMv2 */
- rc = crypto_shash_setkey(ses->server->secmech.hmacmd5,
- ntlmv2_hash, CIFS_HMAC_MD5_HASH_SIZE);
- if (rc) {
- cERROR(1, "%s: Could not set NTLMV2 Hash as a key", __func__);
- goto setup_ntlmv2_rsp_ret;
- }
-
- rc = crypto_shash_init(&ses->server->secmech.sdeschmacmd5->shash);
- if (rc) {
- cERROR(1, "%s: Could not init hmacmd5\n", __func__);
- goto setup_ntlmv2_rsp_ret;
- }
-
- rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
- ses->auth_key.response + CIFS_SESS_KEY_SIZE,
- CIFS_HMAC_MD5_HASH_SIZE);
- if (rc) {
- cERROR(1, "%s: Could not update with response\n", __func__);
- goto setup_ntlmv2_rsp_ret;
- }
-
- rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
- ses->auth_key.response);
- if (rc)
- cERROR(1, "%s: Could not generate md5 hash\n", __func__);
-
-setup_ntlmv2_rsp_ret:
- kfree(tiblob);
-
- return rc;
-}
-
-int
-calc_seckey(struct cifs_ses *ses)
-{
- int rc;
- struct crypto_blkcipher *tfm_arc4;
- struct scatterlist sgin, sgout;
- struct blkcipher_desc desc;
- unsigned char sec_key[CIFS_SESS_KEY_SIZE]; /* a nonce */
-
- get_random_bytes(sec_key, CIFS_SESS_KEY_SIZE);
-
- tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(tfm_arc4)) {
- rc = PTR_ERR(tfm_arc4);
- cERROR(1, "could not allocate crypto API arc4\n");
- return rc;
- }
-
- desc.tfm = tfm_arc4;
-
- rc = crypto_blkcipher_setkey(tfm_arc4, ses->auth_key.response,
- CIFS_SESS_KEY_SIZE);
- if (rc) {
- cERROR(1, "%s: Could not set response as a key", __func__);
- return rc;
- }
-
- sg_init_one(&sgin, sec_key, CIFS_SESS_KEY_SIZE);
- sg_init_one(&sgout, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
-
- rc = crypto_blkcipher_encrypt(&desc, &sgout, &sgin, CIFS_CPHTXT_SIZE);
- if (rc) {
- cERROR(1, "could not encrypt session key rc: %d\n", rc);
- crypto_free_blkcipher(tfm_arc4);
- return rc;
- }
-
- /* make secondary_key/nonce as session key */
- memcpy(ses->auth_key.response, sec_key, CIFS_SESS_KEY_SIZE);
- /* and make len as that of session key only */
- ses->auth_key.len = CIFS_SESS_KEY_SIZE;
-
- crypto_free_blkcipher(tfm_arc4);
-
- return rc;
-}
-
-void
-cifs_crypto_shash_release(struct TCP_Server_Info *server)
-{
- if (server->secmech.md5)
- crypto_free_shash(server->secmech.md5);
-
- if (server->secmech.hmacmd5)
- crypto_free_shash(server->secmech.hmacmd5);
-
- kfree(server->secmech.sdeschmacmd5);
-
- kfree(server->secmech.sdescmd5);
-}
-
-int
-cifs_crypto_shash_allocate(struct TCP_Server_Info *server)
-{
- int rc;
- unsigned int size;
-
- server->secmech.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0);
- if (IS_ERR(server->secmech.hmacmd5)) {
- cERROR(1, "could not allocate crypto hmacmd5\n");
- return PTR_ERR(server->secmech.hmacmd5);
- }
-
- server->secmech.md5 = crypto_alloc_shash("md5", 0, 0);
- if (IS_ERR(server->secmech.md5)) {
- cERROR(1, "could not allocate crypto md5\n");
- rc = PTR_ERR(server->secmech.md5);
- goto crypto_allocate_md5_fail;
- }
-
- size = sizeof(struct shash_desc) +
- crypto_shash_descsize(server->secmech.hmacmd5);
- server->secmech.sdeschmacmd5 = kmalloc(size, GFP_KERNEL);
- if (!server->secmech.sdeschmacmd5) {
- cERROR(1, "cifs_crypto_shash_allocate: can't alloc hmacmd5\n");
- rc = -ENOMEM;
- goto crypto_allocate_hmacmd5_sdesc_fail;
- }
- server->secmech.sdeschmacmd5->shash.tfm = server->secmech.hmacmd5;
- server->secmech.sdeschmacmd5->shash.flags = 0x0;
-
-
- size = sizeof(struct shash_desc) +
- crypto_shash_descsize(server->secmech.md5);
- server->secmech.sdescmd5 = kmalloc(size, GFP_KERNEL);
- if (!server->secmech.sdescmd5) {
- cERROR(1, "cifs_crypto_shash_allocate: can't alloc md5\n");
- rc = -ENOMEM;
- goto crypto_allocate_md5_sdesc_fail;
- }
- server->secmech.sdescmd5->shash.tfm = server->secmech.md5;
- server->secmech.sdescmd5->shash.flags = 0x0;
-
- return 0;
-
-crypto_allocate_md5_sdesc_fail:
- kfree(server->secmech.sdeschmacmd5);
-
-crypto_allocate_hmacmd5_sdesc_fail:
- crypto_free_shash(server->secmech.md5);
-
-crypto_allocate_md5_fail:
- crypto_free_shash(server->secmech.hmacmd5);
-
- return rc;
-}
diff --git a/ANDROID_3.4.5/fs/cifs/cifsfs.c b/ANDROID_3.4.5/fs/cifs/cifsfs.c
deleted file mode 100644
index 541ef81f..00000000
--- a/ANDROID_3.4.5/fs/cifs/cifsfs.c
+++ /dev/null
@@ -1,1211 +0,0 @@
-/*
- * fs/cifs/cifsfs.c
- *
- * Copyright (C) International Business Machines Corp., 2002,2008
- * Author(s): Steve French (sfrench@us.ibm.com)
- *
- * Common Internet FileSystem (CIFS) client
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* Note that BB means BUGBUG (ie something to fix eventually) */
-
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/mount.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-#include <linux/list.h>
-#include <linux/seq_file.h>
-#include <linux/vfs.h>
-#include <linux/mempool.h>
-#include <linux/delay.h>
-#include <linux/kthread.h>
-#include <linux/freezer.h>
-#include <linux/namei.h>
-#include <net/ipv6.h>
-#include "cifsfs.h"
-#include "cifspdu.h"
-#define DECLARE_GLOBALS_HERE
-#include "cifsglob.h"
-#include "cifsproto.h"
-#include "cifs_debug.h"
-#include "cifs_fs_sb.h"
-#include <linux/mm.h>
-#include <linux/key-type.h>
-#include "cifs_spnego.h"
-#include "fscache.h"
-#define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDUs */
-
-int cifsFYI = 0;
-int cifsERROR = 1;
-int traceSMB = 0;
-bool enable_oplocks = true;
-unsigned int linuxExtEnabled = 1;
-unsigned int lookupCacheEnabled = 1;
-unsigned int multiuser_mount = 0;
-unsigned int global_secflags = CIFSSEC_DEF;
-/* unsigned int ntlmv2_support = 0; */
-unsigned int sign_CIFS_PDUs = 1;
-static const struct super_operations cifs_super_ops;
-unsigned int CIFSMaxBufSize = CIFS_MAX_MSGSIZE;
-module_param(CIFSMaxBufSize, int, 0);
-MODULE_PARM_DESC(CIFSMaxBufSize, "Network buffer size (not including header). "
- "Default: 16384 Range: 8192 to 130048");
-unsigned int cifs_min_rcv = CIFS_MIN_RCV_POOL;
-module_param(cifs_min_rcv, int, 0);
-MODULE_PARM_DESC(cifs_min_rcv, "Network buffers in pool. Default: 4 Range: "
- "1 to 64");
-unsigned int cifs_min_small = 30;
-module_param(cifs_min_small, int, 0);
-MODULE_PARM_DESC(cifs_min_small, "Small network buffers in pool. Default: 30 "
- "Range: 2 to 256");
-unsigned int cifs_max_pending = CIFS_MAX_REQ;
-module_param(cifs_max_pending, int, 0444);
-MODULE_PARM_DESC(cifs_max_pending, "Simultaneous requests to server. "
- "Default: 32767 Range: 2 to 32767.");
-module_param(enable_oplocks, bool, 0644);
-MODULE_PARM_DESC(enable_oplocks, "Enable or disable oplocks (bool). Default:"
- "y/Y/1");
-
-extern mempool_t *cifs_sm_req_poolp;
-extern mempool_t *cifs_req_poolp;
-extern mempool_t *cifs_mid_poolp;
-
-struct workqueue_struct *cifsiod_wq;
-
-static int
-cifs_read_super(struct super_block *sb)
-{
- struct inode *inode;
- struct cifs_sb_info *cifs_sb;
- int rc = 0;
-
- cifs_sb = CIFS_SB(sb);
-
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIXACL)
- sb->s_flags |= MS_POSIXACL;
-
- if (cifs_sb_master_tcon(cifs_sb)->ses->capabilities & CAP_LARGE_FILES)
- sb->s_maxbytes = MAX_LFS_FILESIZE;
- else
- sb->s_maxbytes = MAX_NON_LFS;
-
- /* BB FIXME fix time_gran to be larger for LANMAN sessions */
- sb->s_time_gran = 100;
-
- sb->s_magic = CIFS_MAGIC_NUMBER;
- sb->s_op = &cifs_super_ops;
- sb->s_bdi = &cifs_sb->bdi;
- sb->s_blocksize = CIFS_MAX_MSGSIZE;
- sb->s_blocksize_bits = 14; /* default 2**14 = CIFS_MAX_MSGSIZE */
- inode = cifs_root_iget(sb);
-
- if (IS_ERR(inode)) {
- rc = PTR_ERR(inode);
- goto out_no_root;
- }
-
- sb->s_root = d_make_root(inode);
- if (!sb->s_root) {
- rc = -ENOMEM;
- goto out_no_root;
- }
-
- /* do that *after* d_alloc_root() - we want NULL ->d_op for root here */
- if (cifs_sb_master_tcon(cifs_sb)->nocase)
- sb->s_d_op = &cifs_ci_dentry_ops;
- else
- sb->s_d_op = &cifs_dentry_ops;
-
-#ifdef CONFIG_CIFS_NFSD_EXPORT
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
- cFYI(1, "export ops supported");
- sb->s_export_op = &cifs_export_ops;
- }
-#endif /* CONFIG_CIFS_NFSD_EXPORT */
-
- return 0;
-
-out_no_root:
- cERROR(1, "cifs_read_super: get root inode failed");
- return rc;
-}
-
-static void cifs_kill_sb(struct super_block *sb)
-{
- struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
- kill_anon_super(sb);
- cifs_umount(cifs_sb);
-}
-
-static int
-cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
-{
- struct super_block *sb = dentry->d_sb;
- struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
- struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
- int rc = -EOPNOTSUPP;
- int xid;
-
- xid = GetXid();
-
- buf->f_type = CIFS_MAGIC_NUMBER;
-
- /*
- * PATH_MAX may be too long - it would presumably be total path,
- * but note that some servers (includinng Samba 3) have a shorter
- * maximum path.
- *
- * Instead could get the real value via SMB_QUERY_FS_ATTRIBUTE_INFO.
- */
- buf->f_namelen = PATH_MAX;
- buf->f_files = 0; /* undefined */
- buf->f_ffree = 0; /* unlimited */
-
- /*
- * We could add a second check for a QFS Unix capability bit
- */
- if ((tcon->ses->capabilities & CAP_UNIX) &&
- (CIFS_POSIX_EXTENSIONS & le64_to_cpu(tcon->fsUnixInfo.Capability)))
- rc = CIFSSMBQFSPosixInfo(xid, tcon, buf);
-
- /*
- * Only need to call the old QFSInfo if failed on newer one,
- * e.g. by OS/2.
- **/
- if (rc && (tcon->ses->capabilities & CAP_NT_SMBS))
- rc = CIFSSMBQFSInfo(xid, tcon, buf);
-
- /*
- * Some old Windows servers also do not support level 103, retry with
- * older level one if old server failed the previous call or we
- * bypassed it because we detected that this was an older LANMAN sess
- */
- if (rc)
- rc = SMBOldQFSInfo(xid, tcon, buf);
-
- FreeXid(xid);
- return 0;
-}
-
-static int cifs_permission(struct inode *inode, int mask)
-{
- struct cifs_sb_info *cifs_sb;
-
- cifs_sb = CIFS_SB(inode->i_sb);
-
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) {
- if ((mask & MAY_EXEC) && !execute_ok(inode))
- return -EACCES;
- else
- return 0;
- } else /* file mode might have been restricted at mount time
- on the client (above and beyond ACL on servers) for
- servers which do not support setting and viewing mode bits,
- so allowing client to check permissions is useful */
- return generic_permission(inode, mask);
-}
-
-static struct kmem_cache *cifs_inode_cachep;
-static struct kmem_cache *cifs_req_cachep;
-static struct kmem_cache *cifs_mid_cachep;
-static struct kmem_cache *cifs_sm_req_cachep;
-mempool_t *cifs_sm_req_poolp;
-mempool_t *cifs_req_poolp;
-mempool_t *cifs_mid_poolp;
-
-static struct inode *
-cifs_alloc_inode(struct super_block *sb)
-{
- struct cifsInodeInfo *cifs_inode;
- cifs_inode = kmem_cache_alloc(cifs_inode_cachep, GFP_KERNEL);
- if (!cifs_inode)
- return NULL;
- cifs_inode->cifsAttrs = 0x20; /* default */
- cifs_inode->time = 0;
- /* Until the file is open and we have gotten oplock
- info back from the server, can not assume caching of
- file data or metadata */
- cifs_set_oplock_level(cifs_inode, 0);
- cifs_inode->delete_pending = false;
- cifs_inode->invalid_mapping = false;
- cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */
- cifs_inode->server_eof = 0;
- cifs_inode->uniqueid = 0;
- cifs_inode->createtime = 0;
-
- /* Can not set i_flags here - they get immediately overwritten
- to zero by the VFS */
-/* cifs_inode->vfs_inode.i_flags = S_NOATIME | S_NOCMTIME;*/
- INIT_LIST_HEAD(&cifs_inode->openFileList);
- return &cifs_inode->vfs_inode;
-}
-
-static void cifs_i_callback(struct rcu_head *head)
-{
- struct inode *inode = container_of(head, struct inode, i_rcu);
- INIT_LIST_HEAD(&inode->i_dentry);
- kmem_cache_free(cifs_inode_cachep, CIFS_I(inode));
-}
-
-static void
-cifs_destroy_inode(struct inode *inode)
-{
- call_rcu(&inode->i_rcu, cifs_i_callback);
-}
-
-static void
-cifs_evict_inode(struct inode *inode)
-{
- truncate_inode_pages(&inode->i_data, 0);
- end_writeback(inode);
- cifs_fscache_release_inode_cookie(inode);
-}
-
-static void
-cifs_show_address(struct seq_file *s, struct TCP_Server_Info *server)
-{
- struct sockaddr_in *sa = (struct sockaddr_in *) &server->dstaddr;
- struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *) &server->dstaddr;
-
- seq_printf(s, ",addr=");
-
- switch (server->dstaddr.ss_family) {
- case AF_INET:
- seq_printf(s, "%pI4", &sa->sin_addr.s_addr);
- break;
- case AF_INET6:
- seq_printf(s, "%pI6", &sa6->sin6_addr.s6_addr);
- if (sa6->sin6_scope_id)
- seq_printf(s, "%%%u", sa6->sin6_scope_id);
- break;
- default:
- seq_printf(s, "(unknown)");
- }
-}
-
-static void
-cifs_show_security(struct seq_file *s, struct TCP_Server_Info *server)
-{
- seq_printf(s, ",sec=");
-
- switch (server->secType) {
- case LANMAN:
- seq_printf(s, "lanman");
- break;
- case NTLMv2:
- seq_printf(s, "ntlmv2");
- break;
- case NTLM:
- seq_printf(s, "ntlm");
- break;
- case Kerberos:
- seq_printf(s, "krb5");
- break;
- case RawNTLMSSP:
- seq_printf(s, "ntlmssp");
- break;
- default:
- /* shouldn't ever happen */
- seq_printf(s, "unknown");
- break;
- }
-
- if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
- seq_printf(s, "i");
-}
-
-/*
- * cifs_show_options() is for displaying mount options in /proc/mounts.
- * Not all settable options are displayed but most of the important
- * ones are.
- */
-static int
-cifs_show_options(struct seq_file *s, struct dentry *root)
-{
- struct cifs_sb_info *cifs_sb = CIFS_SB(root->d_sb);
- struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
- struct sockaddr *srcaddr;
- srcaddr = (struct sockaddr *)&tcon->ses->server->srcaddr;
-
- cifs_show_security(s, tcon->ses->server);
-
- seq_printf(s, ",unc=%s", tcon->treeName);
-
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)
- seq_printf(s, ",multiuser");
- else if (tcon->ses->user_name)
- seq_printf(s, ",username=%s", tcon->ses->user_name);
-
- if (tcon->ses->domainName)
- seq_printf(s, ",domain=%s", tcon->ses->domainName);
-
- if (srcaddr->sa_family != AF_UNSPEC) {
- struct sockaddr_in *saddr4;
- struct sockaddr_in6 *saddr6;
- saddr4 = (struct sockaddr_in *)srcaddr;
- saddr6 = (struct sockaddr_in6 *)srcaddr;
- if (srcaddr->sa_family == AF_INET6)
- seq_printf(s, ",srcaddr=%pI6c",
- &saddr6->sin6_addr);
- else if (srcaddr->sa_family == AF_INET)
- seq_printf(s, ",srcaddr=%pI4",
- &saddr4->sin_addr.s_addr);
- else
- seq_printf(s, ",srcaddr=BAD-AF:%i",
- (int)(srcaddr->sa_family));
- }
-
- seq_printf(s, ",uid=%u", cifs_sb->mnt_uid);
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
- seq_printf(s, ",forceuid");
- else
- seq_printf(s, ",noforceuid");
-
- seq_printf(s, ",gid=%u", cifs_sb->mnt_gid);
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
- seq_printf(s, ",forcegid");
- else
- seq_printf(s, ",noforcegid");
-
- cifs_show_address(s, tcon->ses->server);
-
- if (!tcon->unix_ext)
- seq_printf(s, ",file_mode=0%ho,dir_mode=0%ho",
- cifs_sb->mnt_file_mode,
- cifs_sb->mnt_dir_mode);
- if (tcon->seal)
- seq_printf(s, ",seal");
- if (tcon->nocase)
- seq_printf(s, ",nocase");
- if (tcon->retry)
- seq_printf(s, ",hard");
- if (tcon->unix_ext)
- seq_printf(s, ",unix");
- else
- seq_printf(s, ",nounix");
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
- seq_printf(s, ",posixpaths");
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)
- seq_printf(s, ",setuids");
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
- seq_printf(s, ",serverino");
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
- seq_printf(s, ",rwpidforward");
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL)
- seq_printf(s, ",forcemand");
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
- seq_printf(s, ",directio");
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
- seq_printf(s, ",nouser_xattr");
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR)
- seq_printf(s, ",mapchars");
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
- seq_printf(s, ",sfu");
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
- seq_printf(s, ",nobrl");
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
- seq_printf(s, ",cifsacl");
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
- seq_printf(s, ",dynperm");
- if (root->d_sb->s_flags & MS_POSIXACL)
- seq_printf(s, ",acl");
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
- seq_printf(s, ",mfsymlinks");
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE)
- seq_printf(s, ",fsc");
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC)
- seq_printf(s, ",nostrictsync");
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
- seq_printf(s, ",noperm");
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO)
- seq_printf(s, ",strictcache");
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPUID)
- seq_printf(s, ",backupuid=%u", cifs_sb->mnt_backupuid);
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPGID)
- seq_printf(s, ",backupgid=%u", cifs_sb->mnt_backupgid);
-
- seq_printf(s, ",rsize=%u", cifs_sb->rsize);
- seq_printf(s, ",wsize=%u", cifs_sb->wsize);
- /* convert actimeo and display it in seconds */
- seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ);
-
- return 0;
-}
-
-static void cifs_umount_begin(struct super_block *sb)
-{
- struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
- struct cifs_tcon *tcon;
-
- if (cifs_sb == NULL)
- return;
-
- tcon = cifs_sb_master_tcon(cifs_sb);
-
- spin_lock(&cifs_tcp_ses_lock);
- if ((tcon->tc_count > 1) || (tcon->tidStatus == CifsExiting)) {
- /* we have other mounts to same share or we have
- already tried to force umount this and woken up
- all waiting network requests, nothing to do */
- spin_unlock(&cifs_tcp_ses_lock);
- return;
- } else if (tcon->tc_count == 1)
- tcon->tidStatus = CifsExiting;
- spin_unlock(&cifs_tcp_ses_lock);
-
- /* cancel_brl_requests(tcon); */ /* BB mark all brl mids as exiting */
- /* cancel_notify_requests(tcon); */
- if (tcon->ses && tcon->ses->server) {
- cFYI(1, "wake up tasks now - umount begin not complete");
- wake_up_all(&tcon->ses->server->request_q);
- wake_up_all(&tcon->ses->server->response_q);
- msleep(1); /* yield */
- /* we have to kick the requests once more */
- wake_up_all(&tcon->ses->server->response_q);
- msleep(1);
- }
-
- return;
-}
-
-#ifdef CONFIG_CIFS_STATS2
-static int cifs_show_stats(struct seq_file *s, struct dentry *root)
-{
- /* BB FIXME */
- return 0;
-}
-#endif
-
-static int cifs_remount(struct super_block *sb, int *flags, char *data)
-{
- *flags |= MS_NODIRATIME;
- return 0;
-}
-
-static int cifs_drop_inode(struct inode *inode)
-{
- struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
-
- /* no serverino => unconditional eviction */
- return !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) ||
- generic_drop_inode(inode);
-}
-
-static const struct super_operations cifs_super_ops = {
- .statfs = cifs_statfs,
- .alloc_inode = cifs_alloc_inode,
- .destroy_inode = cifs_destroy_inode,
- .drop_inode = cifs_drop_inode,
- .evict_inode = cifs_evict_inode,
-/* .delete_inode = cifs_delete_inode, */ /* Do not need above
- function unless later we add lazy close of inodes or unless the
- kernel forgets to call us with the same number of releases (closes)
- as opens */
- .show_options = cifs_show_options,
- .umount_begin = cifs_umount_begin,
- .remount_fs = cifs_remount,
-#ifdef CONFIG_CIFS_STATS2
- .show_stats = cifs_show_stats,
-#endif
-};
-
-/*
- * Get root dentry from superblock according to prefix path mount option.
- * Return dentry with refcount + 1 on success and NULL otherwise.
- */
-static struct dentry *
-cifs_get_root(struct smb_vol *vol, struct super_block *sb)
-{
- struct dentry *dentry;
- struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
- char *full_path = NULL;
- char *s, *p;
- char sep;
-
- full_path = cifs_build_path_to_root(vol, cifs_sb,
- cifs_sb_master_tcon(cifs_sb));
- if (full_path == NULL)
- return ERR_PTR(-ENOMEM);
-
- cFYI(1, "Get root dentry for %s", full_path);
-
- sep = CIFS_DIR_SEP(cifs_sb);
- dentry = dget(sb->s_root);
- p = s = full_path;
-
- do {
- struct inode *dir = dentry->d_inode;
- struct dentry *child;
-
- if (!dir) {
- dput(dentry);
- dentry = ERR_PTR(-ENOENT);
- break;
- }
-
- /* skip separators */
- while (*s == sep)
- s++;
- if (!*s)
- break;
- p = s++;
- /* next separator */
- while (*s && *s != sep)
- s++;
-
- mutex_lock(&dir->i_mutex);
- child = lookup_one_len(p, dentry, s - p);
- mutex_unlock(&dir->i_mutex);
- dput(dentry);
- dentry = child;
- } while (!IS_ERR(dentry));
- kfree(full_path);
- return dentry;
-}
-
-static int cifs_set_super(struct super_block *sb, void *data)
-{
- struct cifs_mnt_data *mnt_data = data;
- sb->s_fs_info = mnt_data->cifs_sb;
- return set_anon_super(sb, NULL);
-}
-
-static struct dentry *
-cifs_do_mount(struct file_system_type *fs_type,
- int flags, const char *dev_name, void *data)
-{
- int rc;
- struct super_block *sb;
- struct cifs_sb_info *cifs_sb;
- struct smb_vol *volume_info;
- struct cifs_mnt_data mnt_data;
- struct dentry *root;
-
- cFYI(1, "Devname: %s flags: %d ", dev_name, flags);
-
- volume_info = cifs_get_volume_info((char *)data, dev_name);
- if (IS_ERR(volume_info))
- return ERR_CAST(volume_info);
-
- cifs_sb = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL);
- if (cifs_sb == NULL) {
- root = ERR_PTR(-ENOMEM);
- goto out_nls;
- }
-
- cifs_sb->mountdata = kstrndup(data, PAGE_SIZE, GFP_KERNEL);
- if (cifs_sb->mountdata == NULL) {
- root = ERR_PTR(-ENOMEM);
- goto out_cifs_sb;
- }
-
- cifs_setup_cifs_sb(volume_info, cifs_sb);
-
- rc = cifs_mount(cifs_sb, volume_info);
- if (rc) {
- if (!(flags & MS_SILENT))
- cERROR(1, "cifs_mount failed w/return code = %d", rc);
- root = ERR_PTR(rc);
- goto out_mountdata;
- }
-
- mnt_data.vol = volume_info;
- mnt_data.cifs_sb = cifs_sb;
- mnt_data.flags = flags;
-
- sb = sget(fs_type, cifs_match_super, cifs_set_super, &mnt_data);
- if (IS_ERR(sb)) {
- root = ERR_CAST(sb);
- cifs_umount(cifs_sb);
- goto out;
- }
-
- if (sb->s_root) {
- cFYI(1, "Use existing superblock");
- cifs_umount(cifs_sb);
- } else {
- sb->s_flags = flags;
- /* BB should we make this contingent on mount parm? */
- sb->s_flags |= MS_NODIRATIME | MS_NOATIME;
-
- rc = cifs_read_super(sb);
- if (rc) {
- root = ERR_PTR(rc);
- goto out_super;
- }
-
- sb->s_flags |= MS_ACTIVE;
- }
-
- root = cifs_get_root(volume_info, sb);
- if (IS_ERR(root))
- goto out_super;
-
- cFYI(1, "dentry root is: %p", root);
- goto out;
-
-out_super:
- deactivate_locked_super(sb);
-out:
- cifs_cleanup_volume_info(volume_info);
- return root;
-
-out_mountdata:
- kfree(cifs_sb->mountdata);
-out_cifs_sb:
- kfree(cifs_sb);
-out_nls:
- unload_nls(volume_info->local_nls);
- goto out;
-}
-
-static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
- unsigned long nr_segs, loff_t pos)
-{
- struct inode *inode = iocb->ki_filp->f_path.dentry->d_inode;
- ssize_t written;
- int rc;
-
- written = generic_file_aio_write(iocb, iov, nr_segs, pos);
-
- if (CIFS_I(inode)->clientCanCacheAll)
- return written;
-
- rc = filemap_fdatawrite(inode->i_mapping);
- if (rc)
- cFYI(1, "cifs_file_aio_write: %d rc on %p inode", rc, inode);
-
- return written;
-}
-
-static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
-{
- /*
- * origin == SEEK_END || SEEK_DATA || SEEK_HOLE => we must revalidate
- * the cached file length
- */
- if (origin != SEEK_SET && origin != SEEK_CUR) {
- int rc;
- struct inode *inode = file->f_path.dentry->d_inode;
-
- /*
- * We need to be sure that all dirty pages are written and the
- * server has the newest file length.
- */
- if (!CIFS_I(inode)->clientCanCacheRead && inode->i_mapping &&
- inode->i_mapping->nrpages != 0) {
- rc = filemap_fdatawait(inode->i_mapping);
- if (rc) {
- mapping_set_error(inode->i_mapping, rc);
- return rc;
- }
- }
- /*
- * Some applications poll for the file length in this strange
- * way so we must seek to end on non-oplocked files by
- * setting the revalidate time to zero.
- */
- CIFS_I(inode)->time = 0;
-
- rc = cifs_revalidate_file_attr(file);
- if (rc < 0)
- return (loff_t)rc;
- }
- return generic_file_llseek(file, offset, origin);
-}
-
-static int cifs_setlease(struct file *file, long arg, struct file_lock **lease)
-{
- /* note that this is called by vfs setlease with lock_flocks held
- to protect *lease from going away */
- struct inode *inode = file->f_path.dentry->d_inode;
- struct cifsFileInfo *cfile = file->private_data;
-
- if (!(S_ISREG(inode->i_mode)))
- return -EINVAL;
-
- /* check if file is oplocked */
- if (((arg == F_RDLCK) &&
- (CIFS_I(inode)->clientCanCacheRead)) ||
- ((arg == F_WRLCK) &&
- (CIFS_I(inode)->clientCanCacheAll)))
- return generic_setlease(file, arg, lease);
- else if (tlink_tcon(cfile->tlink)->local_lease &&
- !CIFS_I(inode)->clientCanCacheRead)
- /* If the server claims to support oplock on this
- file, then we still need to check oplock even
- if the local_lease mount option is set, but there
- are servers which do not support oplock for which
- this mount option may be useful if the user
- knows that the file won't be changed on the server
- by anyone else */
- return generic_setlease(file, arg, lease);
- else
- return -EAGAIN;
-}
-
-struct file_system_type cifs_fs_type = {
- .owner = THIS_MODULE,
- .name = "cifs",
- .mount = cifs_do_mount,
- .kill_sb = cifs_kill_sb,
- /* .fs_flags */
-};
-const struct inode_operations cifs_dir_inode_ops = {
- .create = cifs_create,
- .lookup = cifs_lookup,
- .getattr = cifs_getattr,
- .unlink = cifs_unlink,
- .link = cifs_hardlink,
- .mkdir = cifs_mkdir,
- .rmdir = cifs_rmdir,
- .rename = cifs_rename,
- .permission = cifs_permission,
-/* revalidate:cifs_revalidate, */
- .setattr = cifs_setattr,
- .symlink = cifs_symlink,
- .mknod = cifs_mknod,
-#ifdef CONFIG_CIFS_XATTR
- .setxattr = cifs_setxattr,
- .getxattr = cifs_getxattr,
- .listxattr = cifs_listxattr,
- .removexattr = cifs_removexattr,
-#endif
-};
-
-const struct inode_operations cifs_file_inode_ops = {
-/* revalidate:cifs_revalidate, */
- .setattr = cifs_setattr,
- .getattr = cifs_getattr, /* do we need this anymore? */
- .rename = cifs_rename,
- .permission = cifs_permission,
-#ifdef CONFIG_CIFS_XATTR
- .setxattr = cifs_setxattr,
- .getxattr = cifs_getxattr,
- .listxattr = cifs_listxattr,
- .removexattr = cifs_removexattr,
-#endif
-};
-
-const struct inode_operations cifs_symlink_inode_ops = {
- .readlink = generic_readlink,
- .follow_link = cifs_follow_link,
- .put_link = cifs_put_link,
- .permission = cifs_permission,
- /* BB add the following two eventually */
- /* revalidate: cifs_revalidate,
- setattr: cifs_notify_change, *//* BB do we need notify change */
-#ifdef CONFIG_CIFS_XATTR
- .setxattr = cifs_setxattr,
- .getxattr = cifs_getxattr,
- .listxattr = cifs_listxattr,
- .removexattr = cifs_removexattr,
-#endif
-};
-
-const struct file_operations cifs_file_ops = {
- .read = do_sync_read,
- .write = do_sync_write,
- .aio_read = generic_file_aio_read,
- .aio_write = cifs_file_aio_write,
- .open = cifs_open,
- .release = cifs_close,
- .lock = cifs_lock,
- .fsync = cifs_fsync,
- .flush = cifs_flush,
- .mmap = cifs_file_mmap,
- .splice_read = generic_file_splice_read,
- .llseek = cifs_llseek,
-#ifdef CONFIG_CIFS_POSIX
- .unlocked_ioctl = cifs_ioctl,
-#endif /* CONFIG_CIFS_POSIX */
- .setlease = cifs_setlease,
-};
-
-const struct file_operations cifs_file_strict_ops = {
- .read = do_sync_read,
- .write = do_sync_write,
- .aio_read = cifs_strict_readv,
- .aio_write = cifs_strict_writev,
- .open = cifs_open,
- .release = cifs_close,
- .lock = cifs_lock,
- .fsync = cifs_strict_fsync,
- .flush = cifs_flush,
- .mmap = cifs_file_strict_mmap,
- .splice_read = generic_file_splice_read,
- .llseek = cifs_llseek,
-#ifdef CONFIG_CIFS_POSIX
- .unlocked_ioctl = cifs_ioctl,
-#endif /* CONFIG_CIFS_POSIX */
- .setlease = cifs_setlease,
-};
-
-const struct file_operations cifs_file_direct_ops = {
- /* BB reevaluate whether they can be done with directio, no cache */
- .read = do_sync_read,
- .write = do_sync_write,
- .aio_read = cifs_user_readv,
- .aio_write = cifs_user_writev,
- .open = cifs_open,
- .release = cifs_close,
- .lock = cifs_lock,
- .fsync = cifs_fsync,
- .flush = cifs_flush,
- .mmap = cifs_file_mmap,
- .splice_read = generic_file_splice_read,
-#ifdef CONFIG_CIFS_POSIX
- .unlocked_ioctl = cifs_ioctl,
-#endif /* CONFIG_CIFS_POSIX */
- .llseek = cifs_llseek,
- .setlease = cifs_setlease,
-};
-
-const struct file_operations cifs_file_nobrl_ops = {
- .read = do_sync_read,
- .write = do_sync_write,
- .aio_read = generic_file_aio_read,
- .aio_write = cifs_file_aio_write,
- .open = cifs_open,
- .release = cifs_close,
- .fsync = cifs_fsync,
- .flush = cifs_flush,
- .mmap = cifs_file_mmap,
- .splice_read = generic_file_splice_read,
- .llseek = cifs_llseek,
-#ifdef CONFIG_CIFS_POSIX
- .unlocked_ioctl = cifs_ioctl,
-#endif /* CONFIG_CIFS_POSIX */
- .setlease = cifs_setlease,
-};
-
-const struct file_operations cifs_file_strict_nobrl_ops = {
- .read = do_sync_read,
- .write = do_sync_write,
- .aio_read = cifs_strict_readv,
- .aio_write = cifs_strict_writev,
- .open = cifs_open,
- .release = cifs_close,
- .fsync = cifs_strict_fsync,
- .flush = cifs_flush,
- .mmap = cifs_file_strict_mmap,
- .splice_read = generic_file_splice_read,
- .llseek = cifs_llseek,
-#ifdef CONFIG_CIFS_POSIX
- .unlocked_ioctl = cifs_ioctl,
-#endif /* CONFIG_CIFS_POSIX */
- .setlease = cifs_setlease,
-};
-
-const struct file_operations cifs_file_direct_nobrl_ops = {
- /* BB reevaluate whether they can be done with directio, no cache */
- .read = do_sync_read,
- .write = do_sync_write,
- .aio_read = cifs_user_readv,
- .aio_write = cifs_user_writev,
- .open = cifs_open,
- .release = cifs_close,
- .fsync = cifs_fsync,
- .flush = cifs_flush,
- .mmap = cifs_file_mmap,
- .splice_read = generic_file_splice_read,
-#ifdef CONFIG_CIFS_POSIX
- .unlocked_ioctl = cifs_ioctl,
-#endif /* CONFIG_CIFS_POSIX */
- .llseek = cifs_llseek,
- .setlease = cifs_setlease,
-};
-
-const struct file_operations cifs_dir_ops = {
- .readdir = cifs_readdir,
- .release = cifs_closedir,
- .read = generic_read_dir,
- .unlocked_ioctl = cifs_ioctl,
- .llseek = generic_file_llseek,
-};
-
-static void
-cifs_init_once(void *inode)
-{
- struct cifsInodeInfo *cifsi = inode;
-
- inode_init_once(&cifsi->vfs_inode);
- INIT_LIST_HEAD(&cifsi->llist);
- mutex_init(&cifsi->lock_mutex);
-}
-
-static int
-cifs_init_inodecache(void)
-{
- cifs_inode_cachep = kmem_cache_create("cifs_inode_cache",
- sizeof(struct cifsInodeInfo),
- 0, (SLAB_RECLAIM_ACCOUNT|
- SLAB_MEM_SPREAD),
- cifs_init_once);
- if (cifs_inode_cachep == NULL)
- return -ENOMEM;
-
- return 0;
-}
-
-static void
-cifs_destroy_inodecache(void)
-{
- kmem_cache_destroy(cifs_inode_cachep);
-}
-
-static int
-cifs_init_request_bufs(void)
-{
- if (CIFSMaxBufSize < 8192) {
- /* Buffer size can not be smaller than 2 * PATH_MAX since maximum
- Unicode path name has to fit in any SMB/CIFS path based frames */
- CIFSMaxBufSize = 8192;
- } else if (CIFSMaxBufSize > 1024*127) {
- CIFSMaxBufSize = 1024 * 127;
- } else {
- CIFSMaxBufSize &= 0x1FE00; /* Round size to even 512 byte mult*/
- }
-/* cERROR(1, "CIFSMaxBufSize %d 0x%x",CIFSMaxBufSize,CIFSMaxBufSize); */
- cifs_req_cachep = kmem_cache_create("cifs_request",
- CIFSMaxBufSize +
- MAX_CIFS_HDR_SIZE, 0,
- SLAB_HWCACHE_ALIGN, NULL);
- if (cifs_req_cachep == NULL)
- return -ENOMEM;
-
- if (cifs_min_rcv < 1)
- cifs_min_rcv = 1;
- else if (cifs_min_rcv > 64) {
- cifs_min_rcv = 64;
- cERROR(1, "cifs_min_rcv set to maximum (64)");
- }
-
- cifs_req_poolp = mempool_create_slab_pool(cifs_min_rcv,
- cifs_req_cachep);
-
- if (cifs_req_poolp == NULL) {
- kmem_cache_destroy(cifs_req_cachep);
- return -ENOMEM;
- }
- /* MAX_CIFS_SMALL_BUFFER_SIZE bytes is enough for most SMB responses and
- almost all handle based requests (but not write response, nor is it
- sufficient for path based requests). A smaller size would have
- been more efficient (compacting multiple slab items on one 4k page)
- for the case in which debug was on, but this larger size allows
- more SMBs to use small buffer alloc and is still much more
- efficient to alloc 1 per page off the slab compared to 17K (5page)
- alloc of large cifs buffers even when page debugging is on */
- cifs_sm_req_cachep = kmem_cache_create("cifs_small_rq",
- MAX_CIFS_SMALL_BUFFER_SIZE, 0, SLAB_HWCACHE_ALIGN,
- NULL);
- if (cifs_sm_req_cachep == NULL) {
- mempool_destroy(cifs_req_poolp);
- kmem_cache_destroy(cifs_req_cachep);
- return -ENOMEM;
- }
-
- if (cifs_min_small < 2)
- cifs_min_small = 2;
- else if (cifs_min_small > 256) {
- cifs_min_small = 256;
- cFYI(1, "cifs_min_small set to maximum (256)");
- }
-
- cifs_sm_req_poolp = mempool_create_slab_pool(cifs_min_small,
- cifs_sm_req_cachep);
-
- if (cifs_sm_req_poolp == NULL) {
- mempool_destroy(cifs_req_poolp);
- kmem_cache_destroy(cifs_req_cachep);
- kmem_cache_destroy(cifs_sm_req_cachep);
- return -ENOMEM;
- }
-
- return 0;
-}
-
-static void
-cifs_destroy_request_bufs(void)
-{
- mempool_destroy(cifs_req_poolp);
- kmem_cache_destroy(cifs_req_cachep);
- mempool_destroy(cifs_sm_req_poolp);
- kmem_cache_destroy(cifs_sm_req_cachep);
-}
-
-static int
-cifs_init_mids(void)
-{
- cifs_mid_cachep = kmem_cache_create("cifs_mpx_ids",
- sizeof(struct mid_q_entry), 0,
- SLAB_HWCACHE_ALIGN, NULL);
- if (cifs_mid_cachep == NULL)
- return -ENOMEM;
-
- /* 3 is a reasonable minimum number of simultaneous operations */
- cifs_mid_poolp = mempool_create_slab_pool(3, cifs_mid_cachep);
- if (cifs_mid_poolp == NULL) {
- kmem_cache_destroy(cifs_mid_cachep);
- return -ENOMEM;
- }
-
- return 0;
-}
-
-static void
-cifs_destroy_mids(void)
-{
- mempool_destroy(cifs_mid_poolp);
- kmem_cache_destroy(cifs_mid_cachep);
-}
-
-static int __init
-init_cifs(void)
-{
- int rc = 0;
- cifs_proc_init();
- INIT_LIST_HEAD(&cifs_tcp_ses_list);
-#ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* unused temporarily */
- INIT_LIST_HEAD(&GlobalDnotifyReqList);
- INIT_LIST_HEAD(&GlobalDnotifyRsp_Q);
-#endif /* was needed for dnotify, and will be needed for inotify when VFS fix */
-/*
- * Initialize Global counters
- */
- atomic_set(&sesInfoAllocCount, 0);
- atomic_set(&tconInfoAllocCount, 0);
- atomic_set(&tcpSesAllocCount, 0);
- atomic_set(&tcpSesReconnectCount, 0);
- atomic_set(&tconInfoReconnectCount, 0);
-
- atomic_set(&bufAllocCount, 0);
- atomic_set(&smBufAllocCount, 0);
-#ifdef CONFIG_CIFS_STATS2
- atomic_set(&totBufAllocCount, 0);
- atomic_set(&totSmBufAllocCount, 0);
-#endif /* CONFIG_CIFS_STATS2 */
-
- atomic_set(&midCount, 0);
- GlobalCurrentXid = 0;
- GlobalTotalActiveXid = 0;
- GlobalMaxActiveXid = 0;
- spin_lock_init(&cifs_tcp_ses_lock);
- spin_lock_init(&cifs_file_list_lock);
- spin_lock_init(&GlobalMid_Lock);
-
- if (cifs_max_pending < 2) {
- cifs_max_pending = 2;
- cFYI(1, "cifs_max_pending set to min of 2");
- } else if (cifs_max_pending > CIFS_MAX_REQ) {
- cifs_max_pending = CIFS_MAX_REQ;
- cFYI(1, "cifs_max_pending set to max of %u", CIFS_MAX_REQ);
- }
-
- cifsiod_wq = alloc_workqueue("cifsiod", WQ_FREEZABLE|WQ_MEM_RECLAIM, 0);
- if (!cifsiod_wq) {
- rc = -ENOMEM;
- goto out_clean_proc;
- }
-
- rc = cifs_fscache_register();
- if (rc)
- goto out_destroy_wq;
-
- rc = cifs_init_inodecache();
- if (rc)
- goto out_unreg_fscache;
-
- rc = cifs_init_mids();
- if (rc)
- goto out_destroy_inodecache;
-
- rc = cifs_init_request_bufs();
- if (rc)
- goto out_destroy_mids;
-
-#ifdef CONFIG_CIFS_UPCALL
- rc = register_key_type(&cifs_spnego_key_type);
- if (rc)
- goto out_destroy_request_bufs;
-#endif /* CONFIG_CIFS_UPCALL */
-
-#ifdef CONFIG_CIFS_ACL
- rc = init_cifs_idmap();
- if (rc)
- goto out_register_key_type;
-#endif /* CONFIG_CIFS_ACL */
-
- rc = register_filesystem(&cifs_fs_type);
- if (rc)
- goto out_init_cifs_idmap;
-
- return 0;
-
-out_init_cifs_idmap:
-#ifdef CONFIG_CIFS_ACL
- exit_cifs_idmap();
-out_register_key_type:
-#endif
-#ifdef CONFIG_CIFS_UPCALL
- unregister_key_type(&cifs_spnego_key_type);
-out_destroy_request_bufs:
-#endif
- cifs_destroy_request_bufs();
-out_destroy_mids:
- cifs_destroy_mids();
-out_destroy_inodecache:
- cifs_destroy_inodecache();
-out_unreg_fscache:
- cifs_fscache_unregister();
-out_destroy_wq:
- destroy_workqueue(cifsiod_wq);
-out_clean_proc:
- cifs_proc_clean();
- return rc;
-}
-
-static void __exit
-exit_cifs(void)
-{
- cFYI(DBG2, "exit_cifs");
- unregister_filesystem(&cifs_fs_type);
- cifs_dfs_release_automount_timer();
-#ifdef CONFIG_CIFS_ACL
- cifs_destroy_idmaptrees();
- exit_cifs_idmap();
-#endif
-#ifdef CONFIG_CIFS_UPCALL
- unregister_key_type(&cifs_spnego_key_type);
-#endif
- cifs_destroy_request_bufs();
- cifs_destroy_mids();
- cifs_destroy_inodecache();
- cifs_fscache_unregister();
- destroy_workqueue(cifsiod_wq);
- cifs_proc_clean();
-}
-
-MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>");
-MODULE_LICENSE("GPL"); /* combination of LGPL + GPL source behaves as GPL */
-MODULE_DESCRIPTION
- ("VFS to access servers complying with the SNIA CIFS Specification "
- "e.g. Samba and Windows");
-MODULE_VERSION(CIFS_VERSION);
-module_init(init_cifs)
-module_exit(exit_cifs)
diff --git a/ANDROID_3.4.5/fs/cifs/cifsfs.h b/ANDROID_3.4.5/fs/cifs/cifsfs.h
deleted file mode 100644
index 65365358..00000000
--- a/ANDROID_3.4.5/fs/cifs/cifsfs.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * fs/cifs/cifsfs.h
- *
- * Copyright (c) International Business Machines Corp., 2002, 2007
- * Author(s): Steve French (sfrench@us.ibm.com)
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _CIFSFS_H
-#define _CIFSFS_H
-
-#define ROOT_I 2
-
-/*
- * ino_t is 32-bits on 32-bit arch. We have to squash the 64-bit value down
- * so that it will fit.
- */
-static inline ino_t
-cifs_uniqueid_to_ino_t(u64 fileid)
-{
- ino_t ino = (ino_t) fileid;
- if (sizeof(ino_t) < sizeof(u64))
- ino ^= fileid >> (sizeof(u64)-sizeof(ino_t)) * 8;
- return ino;
-}
-
-extern struct file_system_type cifs_fs_type;
-extern const struct address_space_operations cifs_addr_ops;
-extern const struct address_space_operations cifs_addr_ops_smallbuf;
-
-/* Functions related to inodes */
-extern const struct inode_operations cifs_dir_inode_ops;
-extern struct inode *cifs_root_iget(struct super_block *);
-extern int cifs_create(struct inode *, struct dentry *, umode_t,
- struct nameidata *);
-extern struct dentry *cifs_lookup(struct inode *, struct dentry *,
- struct nameidata *);
-extern int cifs_unlink(struct inode *dir, struct dentry *dentry);
-extern int cifs_hardlink(struct dentry *, struct inode *, struct dentry *);
-extern int cifs_mknod(struct inode *, struct dentry *, umode_t, dev_t);
-extern int cifs_mkdir(struct inode *, struct dentry *, umode_t);
-extern int cifs_rmdir(struct inode *, struct dentry *);
-extern int cifs_rename(struct inode *, struct dentry *, struct inode *,
- struct dentry *);
-extern int cifs_revalidate_file_attr(struct file *filp);
-extern int cifs_revalidate_dentry_attr(struct dentry *);
-extern int cifs_revalidate_file(struct file *filp);
-extern int cifs_revalidate_dentry(struct dentry *);
-extern int cifs_invalidate_mapping(struct inode *inode);
-extern int cifs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
-extern int cifs_setattr(struct dentry *, struct iattr *);
-
-extern const struct inode_operations cifs_file_inode_ops;
-extern const struct inode_operations cifs_symlink_inode_ops;
-extern const struct inode_operations cifs_dfs_referral_inode_operations;
-
-
-/* Functions related to files and directories */
-extern const struct file_operations cifs_file_ops;
-extern const struct file_operations cifs_file_direct_ops; /* if directio mnt */
-extern const struct file_operations cifs_file_strict_ops; /* if strictio mnt */
-extern const struct file_operations cifs_file_nobrl_ops; /* no brlocks */
-extern const struct file_operations cifs_file_direct_nobrl_ops;
-extern const struct file_operations cifs_file_strict_nobrl_ops;
-extern int cifs_open(struct inode *inode, struct file *file);
-extern int cifs_close(struct inode *inode, struct file *file);
-extern int cifs_closedir(struct inode *inode, struct file *file);
-extern ssize_t cifs_user_readv(struct kiocb *iocb, const struct iovec *iov,
- unsigned long nr_segs, loff_t pos);
-extern ssize_t cifs_strict_readv(struct kiocb *iocb, const struct iovec *iov,
- unsigned long nr_segs, loff_t pos);
-extern ssize_t cifs_user_writev(struct kiocb *iocb, const struct iovec *iov,
- unsigned long nr_segs, loff_t pos);
-extern ssize_t cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov,
- unsigned long nr_segs, loff_t pos);
-extern int cifs_lock(struct file *, int, struct file_lock *);
-extern int cifs_fsync(struct file *, loff_t, loff_t, int);
-extern int cifs_strict_fsync(struct file *, loff_t, loff_t, int);
-extern int cifs_flush(struct file *, fl_owner_t id);
-extern int cifs_file_mmap(struct file * , struct vm_area_struct *);
-extern int cifs_file_strict_mmap(struct file * , struct vm_area_struct *);
-extern const struct file_operations cifs_dir_ops;
-extern int cifs_dir_open(struct inode *inode, struct file *file);
-extern int cifs_readdir(struct file *file, void *direntry, filldir_t filldir);
-
-/* Functions related to dir entries */
-extern const struct dentry_operations cifs_dentry_ops;
-extern const struct dentry_operations cifs_ci_dentry_ops;
-
-#ifdef CONFIG_CIFS_DFS_UPCALL
-extern struct vfsmount *cifs_dfs_d_automount(struct path *path);
-#else
-#define cifs_dfs_d_automount NULL
-#endif
-
-/* Functions related to symlinks */
-extern void *cifs_follow_link(struct dentry *direntry, struct nameidata *nd);
-extern void cifs_put_link(struct dentry *direntry,
- struct nameidata *nd, void *);
-extern int cifs_readlink(struct dentry *direntry, char __user *buffer,
- int buflen);
-extern int cifs_symlink(struct inode *inode, struct dentry *direntry,
- const char *symname);
-extern int cifs_removexattr(struct dentry *, const char *);
-extern int cifs_setxattr(struct dentry *, const char *, const void *,
- size_t, int);
-extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t);
-extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
-extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
-
-#ifdef CONFIG_CIFS_NFSD_EXPORT
-extern const struct export_operations cifs_export_ops;
-#endif /* CONFIG_CIFS_NFSD_EXPORT */
-
-#define CIFS_VERSION "1.78"
-#endif /* _CIFSFS_H */
diff --git a/ANDROID_3.4.5/fs/cifs/cifsglob.h b/ANDROID_3.4.5/fs/cifs/cifsglob.h
deleted file mode 100644
index 73fea285..00000000
--- a/ANDROID_3.4.5/fs/cifs/cifsglob.h
+++ /dev/null
@@ -1,1078 +0,0 @@
-/*
- * fs/cifs/cifsglob.h
- *
- * Copyright (C) International Business Machines Corp., 2002,2008
- * Author(s): Steve French (sfrench@us.ibm.com)
- * Jeremy Allison (jra@samba.org)
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- */
-#ifndef _CIFS_GLOB_H
-#define _CIFS_GLOB_H
-
-#include <linux/in.h>
-#include <linux/in6.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
-#include "cifs_fs_sb.h"
-#include "cifsacl.h"
-#include <crypto/internal/hash.h>
-#include <linux/scatterlist.h>
-
-/*
- * The sizes of various internal tables and strings
- */
-#define MAX_UID_INFO 16
-#define MAX_SES_INFO 2
-#define MAX_TCON_INFO 4
-
-#define MAX_TREE_SIZE (2 + MAX_SERVER_SIZE + 1 + MAX_SHARE_SIZE + 1)
-#define MAX_SERVER_SIZE 15
-#define MAX_SHARE_SIZE 80
-#define MAX_USERNAME_SIZE 256 /* reasonable maximum for current servers */
-#define MAX_PASSWORD_SIZE 512 /* max for windows seems to be 256 wide chars */
-
-#define CIFS_MIN_RCV_POOL 4
-
-#define MAX_REOPEN_ATT 5 /* these many maximum attempts to reopen a file */
-/*
- * default attribute cache timeout (jiffies)
- */
-#define CIFS_DEF_ACTIMEO (1 * HZ)
-
-/*
- * max attribute cache timeout (jiffies) - 2^30
- */
-#define CIFS_MAX_ACTIMEO (1 << 30)
-
-/*
- * MAX_REQ is the maximum number of requests that WE will send
- * on one socket concurrently.
- */
-#define CIFS_MAX_REQ 32767
-
-#define RFC1001_NAME_LEN 15
-#define RFC1001_NAME_LEN_WITH_NULL (RFC1001_NAME_LEN + 1)
-
-/* currently length of NIP6_FMT */
-#define SERVER_NAME_LENGTH 40
-#define SERVER_NAME_LEN_WITH_NULL (SERVER_NAME_LENGTH + 1)
-
-/* used to define string lengths for reversing unicode strings */
-/* (256+1)*2 = 514 */
-/* (max path length + 1 for null) * 2 for unicode */
-#define MAX_NAME 514
-
-#include "cifspdu.h"
-
-#ifndef XATTR_DOS_ATTRIB
-#define XATTR_DOS_ATTRIB "user.DOSATTRIB"
-#endif
-
-/*
- * CIFS vfs client Status information (based on what we know.)
- */
-
-/* associated with each tcp and smb session */
-enum statusEnum {
- CifsNew = 0,
- CifsGood,
- CifsExiting,
- CifsNeedReconnect,
- CifsNeedNegotiate
-};
-
-enum securityEnum {
- LANMAN = 0, /* Legacy LANMAN auth */
- NTLM, /* Legacy NTLM012 auth with NTLM hash */
- NTLMv2, /* Legacy NTLM auth with NTLMv2 hash */
- RawNTLMSSP, /* NTLMSSP without SPNEGO, NTLMv2 hash */
-/* NTLMSSP, */ /* can use rawNTLMSSP instead of NTLMSSP via SPNEGO */
- Kerberos, /* Kerberos via SPNEGO */
-};
-
-enum protocolEnum {
- TCP = 0,
- SCTP
- /* Netbios frames protocol not supported at this time */
-};
-
-struct session_key {
- unsigned int len;
- char *response;
-};
-
-/* crypto security descriptor definition */
-struct sdesc {
- struct shash_desc shash;
- char ctx[];
-};
-
-/* crypto hashing related structure/fields, not specific to a sec mech */
-struct cifs_secmech {
- struct crypto_shash *hmacmd5; /* hmac-md5 hash function */
- struct crypto_shash *md5; /* md5 hash function */
- struct sdesc *sdeschmacmd5; /* ctxt to generate ntlmv2 hash, CR1 */
- struct sdesc *sdescmd5; /* ctxt to generate cifs/smb signature */
-};
-
-/* per smb session structure/fields */
-struct ntlmssp_auth {
- __u32 client_flags; /* sent by client in type 1 ntlmsssp exchange */
- __u32 server_flags; /* sent by server in type 2 ntlmssp exchange */
- unsigned char ciphertext[CIFS_CPHTXT_SIZE]; /* sent to server */
- char cryptkey[CIFS_CRYPTO_KEY_SIZE]; /* used by ntlmssp */
-};
-
-struct cifs_cred {
- int uid;
- int gid;
- int mode;
- int cecount;
- struct cifs_sid osid;
- struct cifs_sid gsid;
- struct cifs_ntace *ntaces;
- struct cifs_ace *aces;
-};
-
-/*
- *****************************************************************
- * Except the CIFS PDUs themselves all the
- * globally interesting structs should go here
- *****************************************************************
- */
-
-struct smb_vol {
- char *username;
- char *password;
- char *domainname;
- char *UNC;
- char *UNCip;
- char *iocharset; /* local code page for mapping to and from Unicode */
- char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */
- char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */
- uid_t cred_uid;
- uid_t linux_uid;
- gid_t linux_gid;
- uid_t backupuid;
- gid_t backupgid;
- umode_t file_mode;
- umode_t dir_mode;
- unsigned secFlg;
- bool retry:1;
- bool intr:1;
- bool setuids:1;
- bool override_uid:1;
- bool override_gid:1;
- bool dynperm:1;
- bool noperm:1;
- bool no_psx_acl:1; /* set if posix acl support should be disabled */
- bool cifs_acl:1;
- bool backupuid_specified; /* mount option backupuid is specified */
- bool backupgid_specified; /* mount option backupgid is specified */
- bool no_xattr:1; /* set if xattr (EA) support should be disabled*/
- bool server_ino:1; /* use inode numbers from server ie UniqueId */
- bool direct_io:1;
- bool strict_io:1; /* strict cache behavior */
- bool remap:1; /* set to remap seven reserved chars in filenames */
- bool posix_paths:1; /* unset to not ask for posix pathnames. */
- bool no_linux_ext:1;
- bool sfu_emul:1;
- bool nullauth:1; /* attempt to authenticate with null user */
- bool nocase:1; /* request case insensitive filenames */
- bool nobrl:1; /* disable sending byte range locks to srv */
- bool mand_lock:1; /* send mandatory not posix byte range lock reqs */
- bool seal:1; /* request transport encryption on share */
- bool nodfs:1; /* Do not request DFS, even if available */
- bool local_lease:1; /* check leases only on local system, not remote */
- bool noblocksnd:1;
- bool noautotune:1;
- bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
- bool fsc:1; /* enable fscache */
- bool mfsymlinks:1; /* use Minshall+French Symlinks */
- bool multiuser:1;
- bool rwpidforward:1; /* pid forward for read/write operations */
- unsigned int rsize;
- unsigned int wsize;
- bool sockopt_tcp_nodelay:1;
- unsigned short int port;
- unsigned long actimeo; /* attribute cache timeout (jiffies) */
- char *prepath;
- struct sockaddr_storage srcaddr; /* allow binding to a local IP */
- struct nls_table *local_nls;
-};
-
-#define CIFS_MOUNT_MASK (CIFS_MOUNT_NO_PERM | CIFS_MOUNT_SET_UID | \
- CIFS_MOUNT_SERVER_INUM | CIFS_MOUNT_DIRECT_IO | \
- CIFS_MOUNT_NO_XATTR | CIFS_MOUNT_MAP_SPECIAL_CHR | \
- CIFS_MOUNT_UNX_EMUL | CIFS_MOUNT_NO_BRL | \
- CIFS_MOUNT_CIFS_ACL | CIFS_MOUNT_OVERR_UID | \
- CIFS_MOUNT_OVERR_GID | CIFS_MOUNT_DYNPERM | \
- CIFS_MOUNT_NOPOSIXBRL | CIFS_MOUNT_NOSSYNC | \
- CIFS_MOUNT_FSCACHE | CIFS_MOUNT_MF_SYMLINKS | \
- CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_STRICT_IO | \
- CIFS_MOUNT_CIFS_BACKUPUID | CIFS_MOUNT_CIFS_BACKUPGID)
-
-#define CIFS_MS_MASK (MS_RDONLY | MS_MANDLOCK | MS_NOEXEC | MS_NOSUID | \
- MS_NODEV | MS_SYNCHRONOUS)
-
-struct cifs_mnt_data {
- struct cifs_sb_info *cifs_sb;
- struct smb_vol *vol;
- int flags;
-};
-
-static inline unsigned int
-get_rfc1002_length(void *buf)
-{
- return be32_to_cpu(*((__be32 *)buf));
-}
-
-struct TCP_Server_Info {
- struct list_head tcp_ses_list;
- struct list_head smb_ses_list;
- int srv_count; /* reference counter */
- /* 15 character server name + 0x20 16th byte indicating type = srv */
- char server_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL];
- enum statusEnum tcpStatus; /* what we think the status is */
- char *hostname; /* hostname portion of UNC string */
- struct socket *ssocket;
- struct sockaddr_storage dstaddr;
- struct sockaddr_storage srcaddr; /* locally bind to this IP */
-#ifdef CONFIG_NET_NS
- struct net *net;
-#endif
- wait_queue_head_t response_q;
- wait_queue_head_t request_q; /* if more than maxmpx to srvr must block*/
- struct list_head pending_mid_q;
- bool noblocksnd; /* use blocking sendmsg */
- bool noautotune; /* do not autotune send buf sizes */
- bool tcp_nodelay;
- int credits; /* send no more requests at once */
- unsigned int in_flight; /* number of requests on the wire to server */
- spinlock_t req_lock; /* protect the two values above */
- struct mutex srv_mutex;
- struct task_struct *tsk;
- char server_GUID[16];
- char sec_mode;
- bool session_estab; /* mark when very first sess is established */
- u16 dialect; /* dialect index that server chose */
- enum securityEnum secType;
- bool oplocks:1; /* enable oplocks */
- unsigned int maxReq; /* Clients should submit no more */
- /* than maxReq distinct unanswered SMBs to the server when using */
- /* multiplexed reads or writes */
- unsigned int maxBuf; /* maxBuf specifies the maximum */
- /* message size the server can send or receive for non-raw SMBs */
- /* maxBuf is returned by SMB NegotiateProtocol so maxBuf is only 0 */
- /* when socket is setup (and during reconnect) before NegProt sent */
- unsigned int max_rw; /* maxRw specifies the maximum */
- /* message size the server can send or receive for */
- /* SMB_COM_WRITE_RAW or SMB_COM_READ_RAW. */
- unsigned int max_vcs; /* maximum number of smb sessions, at least
- those that can be specified uniquely with
- vcnumbers */
- int capabilities; /* allow selective disabling of caps by smb sess */
- int timeAdj; /* Adjust for difference in server time zone in sec */
- __u64 CurrentMid; /* multiplex id - rotating counter */
- char cryptkey[CIFS_CRYPTO_KEY_SIZE]; /* used by ntlm, ntlmv2 etc */
- /* 16th byte of RFC1001 workstation name is always null */
- char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL];
- __u32 sequence_number; /* for signing, protected by srv_mutex */
- struct session_key session_key;
- unsigned long lstrp; /* when we got last response from this server */
- struct cifs_secmech secmech; /* crypto sec mech functs, descriptors */
- /* extended security flavors that server supports */
- bool sec_ntlmssp; /* supports NTLMSSP */
- bool sec_kerberosu2u; /* supports U2U Kerberos */
- bool sec_kerberos; /* supports plain Kerberos */
- bool sec_mskerberos; /* supports legacy MS Kerberos */
- bool large_buf; /* is current buffer large? */
- struct delayed_work echo; /* echo ping workqueue job */
- struct kvec *iov; /* reusable kvec array for receives */
- unsigned int nr_iov; /* number of kvecs in array */
- char *smallbuf; /* pointer to current "small" buffer */
- char *bigbuf; /* pointer to current "big" buffer */
- unsigned int total_read; /* total amount of data read in this pass */
-#ifdef CONFIG_CIFS_FSCACHE
- struct fscache_cookie *fscache; /* client index cache cookie */
-#endif
-#ifdef CONFIG_CIFS_STATS2
- atomic_t in_send; /* requests trying to send */
- atomic_t num_waiters; /* blocked waiting to get in sendrecv */
-#endif
-};
-
-static inline unsigned int
-in_flight(struct TCP_Server_Info *server)
-{
- unsigned int num;
- spin_lock(&server->req_lock);
- num = server->in_flight;
- spin_unlock(&server->req_lock);
- return num;
-}
-
-static inline int*
-get_credits_field(struct TCP_Server_Info *server)
-{
- /*
- * This will change to switch statement when we reserve slots for echos
- * and oplock breaks.
- */
- return &server->credits;
-}
-
-static inline bool
-has_credits(struct TCP_Server_Info *server, int *credits)
-{
- int num;
- spin_lock(&server->req_lock);
- num = *credits;
- spin_unlock(&server->req_lock);
- return num > 0;
-}
-
-static inline size_t
-header_size(void)
-{
- return sizeof(struct smb_hdr);
-}
-
-static inline size_t
-max_header_size(void)
-{
- return MAX_CIFS_HDR_SIZE;
-}
-
-/*
- * Macros to allow the TCP_Server_Info->net field and related code to drop out
- * when CONFIG_NET_NS isn't set.
- */
-
-#ifdef CONFIG_NET_NS
-
-static inline struct net *cifs_net_ns(struct TCP_Server_Info *srv)
-{
- return srv->net;
-}
-
-static inline void cifs_set_net_ns(struct TCP_Server_Info *srv, struct net *net)
-{
- srv->net = net;
-}
-
-#else
-
-static inline struct net *cifs_net_ns(struct TCP_Server_Info *srv)
-{
- return &init_net;
-}
-
-static inline void cifs_set_net_ns(struct TCP_Server_Info *srv, struct net *net)
-{
-}
-
-#endif
-
-/*
- * Session structure. One of these for each uid session with a particular host
- */
-struct cifs_ses {
- struct list_head smb_ses_list;
- struct list_head tcon_list;
- struct mutex session_mutex;
- struct TCP_Server_Info *server; /* pointer to server info */
- int ses_count; /* reference counter */
- enum statusEnum status;
- unsigned overrideSecFlg; /* if non-zero override global sec flags */
- __u16 ipc_tid; /* special tid for connection to IPC share */
- __u16 flags;
- __u16 vcnum;
- char *serverOS; /* name of operating system underlying server */
- char *serverNOS; /* name of network operating system of server */
- char *serverDomain; /* security realm of server */
- int Suid; /* remote smb uid */
- uid_t linux_uid; /* overriding owner of files on the mount */
- uid_t cred_uid; /* owner of credentials */
- int capabilities;
- char serverName[SERVER_NAME_LEN_WITH_NULL * 2]; /* BB make bigger for
- TCP names - will ipv6 and sctp addresses fit? */
- char *user_name; /* must not be null except during init of sess
- and after mount option parsing we fill it */
- char *domainName;
- char *password;
- struct session_key auth_key;
- struct ntlmssp_auth *ntlmssp; /* ciphertext, flags, server challenge */
- bool need_reconnect:1; /* connection reset, uid now invalid */
-};
-/* no more than one of the following three session flags may be set */
-#define CIFS_SES_NT4 1
-#define CIFS_SES_OS2 2
-#define CIFS_SES_W9X 4
-/* following flag is set for old servers such as OS2 (and Win95?)
- which do not negotiate NTLM or POSIX dialects, but instead
- negotiate one of the older LANMAN dialects */
-#define CIFS_SES_LANMAN 8
-/*
- * there is one of these for each connection to a resource on a particular
- * session
- */
-struct cifs_tcon {
- struct list_head tcon_list;
- int tc_count;
- struct list_head openFileList;
- struct cifs_ses *ses; /* pointer to session associated with */
- char treeName[MAX_TREE_SIZE + 1]; /* UNC name of resource in ASCII */
- char *nativeFileSystem;
- char *password; /* for share-level security */
- __u16 tid; /* The 2 byte tree id */
- __u16 Flags; /* optional support bits */
- enum statusEnum tidStatus;
-#ifdef CONFIG_CIFS_STATS
- atomic_t num_smbs_sent;
- atomic_t num_writes;
- atomic_t num_reads;
- atomic_t num_flushes;
- atomic_t num_oplock_brks;
- atomic_t num_opens;
- atomic_t num_closes;
- atomic_t num_deletes;
- atomic_t num_mkdirs;
- atomic_t num_posixopens;
- atomic_t num_posixmkdirs;
- atomic_t num_rmdirs;
- atomic_t num_renames;
- atomic_t num_t2renames;
- atomic_t num_ffirst;
- atomic_t num_fnext;
- atomic_t num_fclose;
- atomic_t num_hardlinks;
- atomic_t num_symlinks;
- atomic_t num_locks;
- atomic_t num_acl_get;
- atomic_t num_acl_set;
-#ifdef CONFIG_CIFS_STATS2
- unsigned long long time_writes;
- unsigned long long time_reads;
- unsigned long long time_opens;
- unsigned long long time_deletes;
- unsigned long long time_closes;
- unsigned long long time_mkdirs;
- unsigned long long time_rmdirs;
- unsigned long long time_renames;
- unsigned long long time_t2renames;
- unsigned long long time_ffirst;
- unsigned long long time_fnext;
- unsigned long long time_fclose;
-#endif /* CONFIG_CIFS_STATS2 */
- __u64 bytes_read;
- __u64 bytes_written;
- spinlock_t stat_lock;
-#endif /* CONFIG_CIFS_STATS */
- FILE_SYSTEM_DEVICE_INFO fsDevInfo;
- FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if fs name truncated */
- FILE_SYSTEM_UNIX_INFO fsUnixInfo;
- bool ipc:1; /* set if connection to IPC$ eg for RPC/PIPES */
- bool retry:1;
- bool nocase:1;
- bool seal:1; /* transport encryption for this mounted share */
- bool unix_ext:1; /* if false disable Linux extensions to CIFS protocol
- for this mount even if server would support */
- bool local_lease:1; /* check leases (only) on local system not remote */
- bool broken_posix_open; /* e.g. Samba server versions < 3.3.2, 3.2.9 */
- bool need_reconnect:1; /* connection reset, tid now invalid */
-#ifdef CONFIG_CIFS_FSCACHE
- u64 resource_id; /* server resource id */
- struct fscache_cookie *fscache; /* cookie for share */
-#endif
- /* BB add field for back pointer to sb struct(s)? */
-};
-
-/*
- * This is a refcounted and timestamped container for a tcon pointer. The
- * container holds a tcon reference. It is considered safe to free one of
- * these when the tl_count goes to 0. The tl_time is the time of the last
- * "get" on the container.
- */
-struct tcon_link {
- struct rb_node tl_rbnode;
- uid_t tl_uid;
- unsigned long tl_flags;
-#define TCON_LINK_MASTER 0
-#define TCON_LINK_PENDING 1
-#define TCON_LINK_IN_TREE 2
- unsigned long tl_time;
- atomic_t tl_count;
- struct cifs_tcon *tl_tcon;
-};
-
-extern struct tcon_link *cifs_sb_tlink(struct cifs_sb_info *cifs_sb);
-
-static inline struct cifs_tcon *
-tlink_tcon(struct tcon_link *tlink)
-{
- return tlink->tl_tcon;
-}
-
-extern void cifs_put_tlink(struct tcon_link *tlink);
-
-static inline struct tcon_link *
-cifs_get_tlink(struct tcon_link *tlink)
-{
- if (tlink && !IS_ERR(tlink))
- atomic_inc(&tlink->tl_count);
- return tlink;
-}
-
-/* This function is always expected to succeed */
-extern struct cifs_tcon *cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb);
-
-/*
- * This info hangs off the cifsFileInfo structure, pointed to by llist.
- * This is used to track byte stream locks on the file
- */
-struct cifsLockInfo {
- struct list_head llist; /* pointer to next cifsLockInfo */
- struct list_head blist; /* pointer to locks blocked on this */
- wait_queue_head_t block_q;
- __u64 offset;
- __u64 length;
- __u32 pid;
- __u8 type;
- __u16 netfid;
-};
-
-/*
- * One of these for each open instance of a file
- */
-struct cifs_search_info {
- loff_t index_of_last_entry;
- __u16 entries_in_buffer;
- __u16 info_level;
- __u32 resume_key;
- char *ntwrk_buf_start;
- char *srch_entries_start;
- char *last_entry;
- const char *presume_name;
- unsigned int resume_name_len;
- bool endOfSearch:1;
- bool emptyDir:1;
- bool unicode:1;
- bool smallBuf:1; /* so we know which buf_release function to call */
-};
-
-struct cifsFileInfo {
- struct list_head tlist; /* pointer to next fid owned by tcon */
- struct list_head flist; /* next fid (file instance) for this inode */
- unsigned int uid; /* allows finding which FileInfo structure */
- __u32 pid; /* process id who opened file */
- __u16 netfid; /* file id from remote */
- /* BB add lock scope info here if needed */ ;
- /* lock scope id (0 if none) */
- struct dentry *dentry;
- unsigned int f_flags;
- struct tcon_link *tlink;
- bool invalidHandle:1; /* file closed via session abend */
- bool oplock_break_cancelled:1;
- int count; /* refcount protected by cifs_file_list_lock */
- struct mutex fh_mutex; /* prevents reopen race after dead ses*/
- struct cifs_search_info srch_inf;
- struct work_struct oplock_break; /* work for oplock breaks */
-};
-
-struct cifs_io_parms {
- __u16 netfid;
- __u32 pid;
- __u64 offset;
- unsigned int length;
- struct cifs_tcon *tcon;
-};
-
-/*
- * Take a reference on the file private data. Must be called with
- * cifs_file_list_lock held.
- */
-static inline
-struct cifsFileInfo *cifsFileInfo_get(struct cifsFileInfo *cifs_file)
-{
- ++cifs_file->count;
- return cifs_file;
-}
-
-void cifsFileInfo_put(struct cifsFileInfo *cifs_file);
-
-/*
- * One of these for each file inode
- */
-
-struct cifsInodeInfo {
- struct list_head llist; /* brlocks for this inode */
- bool can_cache_brlcks;
- struct mutex lock_mutex; /* protect two fields above */
- /* BB add in lists for dirty pages i.e. write caching info for oplock */
- struct list_head openFileList;
- __u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */
- bool clientCanCacheRead; /* read oplock */
- bool clientCanCacheAll; /* read and writebehind oplock */
- bool delete_pending; /* DELETE_ON_CLOSE is set */
- bool invalid_mapping; /* pagecache is invalid */
- unsigned long time; /* jiffies of last update of inode */
- u64 server_eof; /* current file size on server -- protected by i_lock */
- u64 uniqueid; /* server inode number */
- u64 createtime; /* creation time on server */
-#ifdef CONFIG_CIFS_FSCACHE
- struct fscache_cookie *fscache;
-#endif
- struct inode vfs_inode;
-};
-
-static inline struct cifsInodeInfo *
-CIFS_I(struct inode *inode)
-{
- return container_of(inode, struct cifsInodeInfo, vfs_inode);
-}
-
-static inline struct cifs_sb_info *
-CIFS_SB(struct super_block *sb)
-{
- return sb->s_fs_info;
-}
-
-static inline char CIFS_DIR_SEP(const struct cifs_sb_info *cifs_sb)
-{
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
- return '/';
- else
- return '\\';
-}
-
-static inline void
-convert_delimiter(char *path, char delim)
-{
- int i;
- char old_delim;
-
- if (path == NULL)
- return;
-
- if (delim == '/')
- old_delim = '\\';
- else
- old_delim = '/';
-
- for (i = 0; path[i] != '\0'; i++) {
- if (path[i] == old_delim)
- path[i] = delim;
- }
-}
-
-#ifdef CONFIG_CIFS_STATS
-#define cifs_stats_inc atomic_inc
-
-static inline void cifs_stats_bytes_written(struct cifs_tcon *tcon,
- unsigned int bytes)
-{
- if (bytes) {
- spin_lock(&tcon->stat_lock);
- tcon->bytes_written += bytes;
- spin_unlock(&tcon->stat_lock);
- }
-}
-
-static inline void cifs_stats_bytes_read(struct cifs_tcon *tcon,
- unsigned int bytes)
-{
- spin_lock(&tcon->stat_lock);
- tcon->bytes_read += bytes;
- spin_unlock(&tcon->stat_lock);
-}
-#else
-
-#define cifs_stats_inc(field) do {} while (0)
-#define cifs_stats_bytes_written(tcon, bytes) do {} while (0)
-#define cifs_stats_bytes_read(tcon, bytes) do {} while (0)
-
-#endif
-
-struct mid_q_entry;
-
-/*
- * This is the prototype for the mid receive function. This function is for
- * receiving the rest of the SMB frame, starting with the WordCount (which is
- * just after the MID in struct smb_hdr). Note:
- *
- * - This will be called by cifsd, with no locks held.
- * - The mid will still be on the pending_mid_q.
- * - mid->resp_buf will point to the current buffer.
- *
- * Returns zero on a successful receive, or an error. The receive state in
- * the TCP_Server_Info will also be updated.
- */
-typedef int (mid_receive_t)(struct TCP_Server_Info *server,
- struct mid_q_entry *mid);
-
-/*
- * This is the prototype for the mid callback function. This is called once the
- * mid has been received off of the socket. When creating one, take special
- * care to avoid deadlocks. Things to bear in mind:
- *
- * - it will be called by cifsd, with no locks held
- * - the mid will be removed from any lists
- */
-typedef void (mid_callback_t)(struct mid_q_entry *mid);
-
-/* one of these for every pending CIFS request to the server */
-struct mid_q_entry {
- struct list_head qhead; /* mids waiting on reply from this server */
- __u64 mid; /* multiplex id */
- __u32 pid; /* process id */
- __u32 sequence_number; /* for CIFS signing */
- unsigned long when_alloc; /* when mid was created */
-#ifdef CONFIG_CIFS_STATS2
- unsigned long when_sent; /* time when smb send finished */
- unsigned long when_received; /* when demux complete (taken off wire) */
-#endif
- mid_receive_t *receive; /* call receive callback */
- mid_callback_t *callback; /* call completion callback */
- void *callback_data; /* general purpose pointer for callback */
- void *resp_buf; /* pointer to received SMB header */
- int mid_state; /* wish this were enum but can not pass to wait_event */
- __le16 command; /* smb command code */
- bool large_buf:1; /* if valid response, is pointer to large buf */
- bool multiRsp:1; /* multiple trans2 responses for one request */
- bool multiEnd:1; /* both received */
-};
-
-/* Make code in transport.c a little cleaner by moving
- update of optional stats into function below */
-#ifdef CONFIG_CIFS_STATS2
-
-static inline void cifs_in_send_inc(struct TCP_Server_Info *server)
-{
- atomic_inc(&server->in_send);
-}
-
-static inline void cifs_in_send_dec(struct TCP_Server_Info *server)
-{
- atomic_dec(&server->in_send);
-}
-
-static inline void cifs_num_waiters_inc(struct TCP_Server_Info *server)
-{
- atomic_inc(&server->num_waiters);
-}
-
-static inline void cifs_num_waiters_dec(struct TCP_Server_Info *server)
-{
- atomic_dec(&server->num_waiters);
-}
-
-static inline void cifs_save_when_sent(struct mid_q_entry *mid)
-{
- mid->when_sent = jiffies;
-}
-#else
-static inline void cifs_in_send_inc(struct TCP_Server_Info *server)
-{
-}
-static inline void cifs_in_send_dec(struct TCP_Server_Info *server)
-{
-}
-
-static inline void cifs_num_waiters_inc(struct TCP_Server_Info *server)
-{
-}
-
-static inline void cifs_num_waiters_dec(struct TCP_Server_Info *server)
-{
-}
-
-static inline void cifs_save_when_sent(struct mid_q_entry *mid)
-{
-}
-#endif
-
-/* for pending dnotify requests */
-struct dir_notify_req {
- struct list_head lhead;
- __le16 Pid;
- __le16 PidHigh;
- __u16 Mid;
- __u16 Tid;
- __u16 Uid;
- __u16 netfid;
- __u32 filter; /* CompletionFilter (for multishot) */
- int multishot;
- struct file *pfile;
-};
-
-struct dfs_info3_param {
- int flags; /* DFSREF_REFERRAL_SERVER, DFSREF_STORAGE_SERVER*/
- int path_consumed;
- int server_type;
- int ref_flag;
- char *path_name;
- char *node_name;
-};
-
-/*
- * common struct for holding inode info when searching for or updating an
- * inode with new info
- */
-
-#define CIFS_FATTR_DFS_REFERRAL 0x1
-#define CIFS_FATTR_DELETE_PENDING 0x2
-#define CIFS_FATTR_NEED_REVAL 0x4
-#define CIFS_FATTR_INO_COLLISION 0x8
-
-struct cifs_fattr {
- u32 cf_flags;
- u32 cf_cifsattrs;
- u64 cf_uniqueid;
- u64 cf_eof;
- u64 cf_bytes;
- u64 cf_createtime;
- uid_t cf_uid;
- gid_t cf_gid;
- umode_t cf_mode;
- dev_t cf_rdev;
- unsigned int cf_nlink;
- unsigned int cf_dtype;
- struct timespec cf_atime;
- struct timespec cf_mtime;
- struct timespec cf_ctime;
-};
-
-static inline void free_dfs_info_param(struct dfs_info3_param *param)
-{
- if (param) {
- kfree(param->path_name);
- kfree(param->node_name);
- kfree(param);
- }
-}
-
-static inline void free_dfs_info_array(struct dfs_info3_param *param,
- int number_of_items)
-{
- int i;
- if ((number_of_items == 0) || (param == NULL))
- return;
- for (i = 0; i < number_of_items; i++) {
- kfree(param[i].path_name);
- kfree(param[i].node_name);
- }
- kfree(param);
-}
-
-#define MID_FREE 0
-#define MID_REQUEST_ALLOCATED 1
-#define MID_REQUEST_SUBMITTED 2
-#define MID_RESPONSE_RECEIVED 4
-#define MID_RETRY_NEEDED 8 /* session closed while this request out */
-#define MID_RESPONSE_MALFORMED 0x10
-#define MID_SHUTDOWN 0x20
-
-/* Types of response buffer returned from SendReceive2 */
-#define CIFS_NO_BUFFER 0 /* Response buffer not returned */
-#define CIFS_SMALL_BUFFER 1
-#define CIFS_LARGE_BUFFER 2
-#define CIFS_IOVEC 4 /* array of response buffers */
-
-/* Type of Request to SendReceive2 */
-#define CIFS_BLOCKING_OP 1 /* operation can block */
-#define CIFS_ASYNC_OP 2 /* do not wait for response */
-#define CIFS_TIMEOUT_MASK 0x003 /* only one of above set in req */
-#define CIFS_LOG_ERROR 0x010 /* log NT STATUS if non-zero */
-#define CIFS_LARGE_BUF_OP 0x020 /* large request buffer */
-#define CIFS_NO_RESP 0x040 /* no response buffer required */
-
-/* Security Flags: indicate type of session setup needed */
-#define CIFSSEC_MAY_SIGN 0x00001
-#define CIFSSEC_MAY_NTLM 0x00002
-#define CIFSSEC_MAY_NTLMV2 0x00004
-#define CIFSSEC_MAY_KRB5 0x00008
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
-#define CIFSSEC_MAY_LANMAN 0x00010
-#define CIFSSEC_MAY_PLNTXT 0x00020
-#else
-#define CIFSSEC_MAY_LANMAN 0
-#define CIFSSEC_MAY_PLNTXT 0
-#endif /* weak passwords */
-#define CIFSSEC_MAY_SEAL 0x00040 /* not supported yet */
-#define CIFSSEC_MAY_NTLMSSP 0x00080 /* raw ntlmssp with ntlmv2 */
-
-#define CIFSSEC_MUST_SIGN 0x01001
-/* note that only one of the following can be set so the
-result of setting MUST flags more than once will be to
-require use of the stronger protocol */
-#define CIFSSEC_MUST_NTLM 0x02002
-#define CIFSSEC_MUST_NTLMV2 0x04004
-#define CIFSSEC_MUST_KRB5 0x08008
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
-#define CIFSSEC_MUST_LANMAN 0x10010
-#define CIFSSEC_MUST_PLNTXT 0x20020
-#ifdef CONFIG_CIFS_UPCALL
-#define CIFSSEC_MASK 0xBF0BF /* allows weak security but also krb5 */
-#else
-#define CIFSSEC_MASK 0xB70B7 /* current flags supported if weak */
-#endif /* UPCALL */
-#else /* do not allow weak pw hash */
-#define CIFSSEC_MUST_LANMAN 0
-#define CIFSSEC_MUST_PLNTXT 0
-#ifdef CONFIG_CIFS_UPCALL
-#define CIFSSEC_MASK 0x8F08F /* flags supported if no weak allowed */
-#else
-#define CIFSSEC_MASK 0x87087 /* flags supported if no weak allowed */
-#endif /* UPCALL */
-#endif /* WEAK_PW_HASH */
-#define CIFSSEC_MUST_SEAL 0x40040 /* not supported yet */
-#define CIFSSEC_MUST_NTLMSSP 0x80080 /* raw ntlmssp with ntlmv2 */
-
-#define CIFSSEC_DEF (CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2)
-#define CIFSSEC_MAX (CIFSSEC_MUST_SIGN | CIFSSEC_MUST_NTLMV2)
-#define CIFSSEC_AUTH_MASK (CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_LANMAN | CIFSSEC_MAY_PLNTXT | CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP)
-/*
- *****************************************************************
- * All constants go here
- *****************************************************************
- */
-
-#define UID_HASH (16)
-
-/*
- * Note that ONE module should define _DECLARE_GLOBALS_HERE to cause the
- * following to be declared.
- */
-
-/****************************************************************************
- * Locking notes. All updates to global variables and lists should be
- * protected by spinlocks or semaphores.
- *
- * Spinlocks
- * ---------
- * GlobalMid_Lock protects:
- * list operations on pending_mid_q and oplockQ
- * updates to XID counters, multiplex id and SMB sequence numbers
- * cifs_file_list_lock protects:
- * list operations on tcp and SMB session lists and tCon lists
- * f_owner.lock protects certain per file struct operations
- * mapping->page_lock protects certain per page operations
- *
- * Semaphores
- * ----------
- * sesSem operations on smb session
- * tconSem operations on tree connection
- * fh_sem file handle reconnection operations
- *
- ****************************************************************************/
-
-#ifdef DECLARE_GLOBALS_HERE
-#define GLOBAL_EXTERN
-#else
-#define GLOBAL_EXTERN extern
-#endif
-
-/*
- * the list of TCP_Server_Info structures, ie each of the sockets
- * connecting our client to a distinct server (ip address), is
- * chained together by cifs_tcp_ses_list. The list of all our SMB
- * sessions (and from that the tree connections) can be found
- * by iterating over cifs_tcp_ses_list
- */
-GLOBAL_EXTERN struct list_head cifs_tcp_ses_list;
-
-/*
- * This lock protects the cifs_tcp_ses_list, the list of smb sessions per
- * tcp session, and the list of tcon's per smb session. It also protects
- * the reference counters for the server, smb session, and tcon. Finally,
- * changes to the tcon->tidStatus should be done while holding this lock.
- */
-GLOBAL_EXTERN spinlock_t cifs_tcp_ses_lock;
-
-/*
- * This lock protects the cifs_file->llist and cifs_file->flist
- * list operations, and updates to some flags (cifs_file->invalidHandle)
- * It will be moved to either use the tcon->stat_lock or equivalent later.
- * If cifs_tcp_ses_lock and the lock below are both needed to be held, then
- * the cifs_tcp_ses_lock must be grabbed first and released last.
- */
-GLOBAL_EXTERN spinlock_t cifs_file_list_lock;
-
-#ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* unused temporarily */
-/* Outstanding dir notify requests */
-GLOBAL_EXTERN struct list_head GlobalDnotifyReqList;
-/* DirNotify response queue */
-GLOBAL_EXTERN struct list_head GlobalDnotifyRsp_Q;
-#endif /* was needed for dnotify, and will be needed for inotify when VFS fix */
-
-/*
- * Global transaction id (XID) information
- */
-GLOBAL_EXTERN unsigned int GlobalCurrentXid; /* protected by GlobalMid_Sem */
-GLOBAL_EXTERN unsigned int GlobalTotalActiveXid; /* prot by GlobalMid_Sem */
-GLOBAL_EXTERN unsigned int GlobalMaxActiveXid; /* prot by GlobalMid_Sem */
-GLOBAL_EXTERN spinlock_t GlobalMid_Lock; /* protects above & list operations */
- /* on midQ entries */
-/*
- * Global counters, updated atomically
- */
-GLOBAL_EXTERN atomic_t sesInfoAllocCount;
-GLOBAL_EXTERN atomic_t tconInfoAllocCount;
-GLOBAL_EXTERN atomic_t tcpSesAllocCount;
-GLOBAL_EXTERN atomic_t tcpSesReconnectCount;
-GLOBAL_EXTERN atomic_t tconInfoReconnectCount;
-
-/* Various Debug counters */
-GLOBAL_EXTERN atomic_t bufAllocCount; /* current number allocated */
-#ifdef CONFIG_CIFS_STATS2
-GLOBAL_EXTERN atomic_t totBufAllocCount; /* total allocated over all time */
-GLOBAL_EXTERN atomic_t totSmBufAllocCount;
-#endif
-GLOBAL_EXTERN atomic_t smBufAllocCount;
-GLOBAL_EXTERN atomic_t midCount;
-
-/* Misc globals */
-GLOBAL_EXTERN unsigned int multiuser_mount; /* if enabled allows new sessions
- to be established on existing mount if we
- have the uid/password or Kerberos credential
- or equivalent for current user */
-/* enable or disable oplocks */
-GLOBAL_EXTERN bool enable_oplocks;
-GLOBAL_EXTERN unsigned int lookupCacheEnabled;
-GLOBAL_EXTERN unsigned int global_secflags; /* if on, session setup sent
- with more secure ntlmssp2 challenge/resp */
-GLOBAL_EXTERN unsigned int sign_CIFS_PDUs; /* enable smb packet signing */
-GLOBAL_EXTERN unsigned int linuxExtEnabled;/*enable Linux/Unix CIFS extensions*/
-GLOBAL_EXTERN unsigned int CIFSMaxBufSize; /* max size not including hdr */
-GLOBAL_EXTERN unsigned int cifs_min_rcv; /* min size of big ntwrk buf pool */
-GLOBAL_EXTERN unsigned int cifs_min_small; /* min size of small buf pool */
-GLOBAL_EXTERN unsigned int cifs_max_pending; /* MAX requests at once to server*/
-
-#ifdef CONFIG_CIFS_ACL
-GLOBAL_EXTERN struct rb_root uidtree;
-GLOBAL_EXTERN struct rb_root gidtree;
-GLOBAL_EXTERN spinlock_t siduidlock;
-GLOBAL_EXTERN spinlock_t sidgidlock;
-GLOBAL_EXTERN struct rb_root siduidtree;
-GLOBAL_EXTERN struct rb_root sidgidtree;
-GLOBAL_EXTERN spinlock_t uidsidlock;
-GLOBAL_EXTERN spinlock_t gidsidlock;
-#endif /* CONFIG_CIFS_ACL */
-
-void cifs_oplock_break(struct work_struct *work);
-
-extern const struct slow_work_ops cifs_oplock_break_ops;
-extern struct workqueue_struct *cifsiod_wq;
-
-#endif /* _CIFS_GLOB_H */
diff --git a/ANDROID_3.4.5/fs/cifs/cifspdu.h b/ANDROID_3.4.5/fs/cifs/cifspdu.h
deleted file mode 100644
index 3fb03e2c..00000000
--- a/ANDROID_3.4.5/fs/cifs/cifspdu.h
+++ /dev/null
@@ -1,2669 +0,0 @@
-/*
- * fs/cifs/cifspdu.h
- *
- * Copyright (c) International Business Machines Corp., 2002,2009
- * Author(s): Steve French (sfrench@us.ibm.com)
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _CIFSPDU_H
-#define _CIFSPDU_H
-
-#include <net/sock.h>
-#include <asm/unaligned.h>
-#include "smbfsctl.h"
-
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
-#define LANMAN_PROT 0
-#define LANMAN2_PROT 1
-#define CIFS_PROT 2
-#else
-#define CIFS_PROT 0
-#endif
-#define POSIX_PROT (CIFS_PROT+1)
-#define BAD_PROT 0xFFFF
-
-/* SMB command codes:
- * Note some commands have minimal (wct=0,bcc=0), or uninteresting, responses
- * (ie which include no useful data other than the SMB error code itself).
- * This can allow us to avoid response buffer allocations and copy in some cases
- */
-#define SMB_COM_CREATE_DIRECTORY 0x00 /* trivial response */
-#define SMB_COM_DELETE_DIRECTORY 0x01 /* trivial response */
-#define SMB_COM_CLOSE 0x04 /* triv req/rsp, timestamp ignored */
-#define SMB_COM_FLUSH 0x05 /* triv req/rsp */
-#define SMB_COM_DELETE 0x06 /* trivial response */
-#define SMB_COM_RENAME 0x07 /* trivial response */
-#define SMB_COM_QUERY_INFORMATION 0x08 /* aka getattr */
-#define SMB_COM_SETATTR 0x09 /* trivial response */
-#define SMB_COM_LOCKING_ANDX 0x24 /* trivial response */
-#define SMB_COM_COPY 0x29 /* trivial rsp, fail filename ignrd*/
-#define SMB_COM_ECHO 0x2B /* echo request */
-#define SMB_COM_OPEN_ANDX 0x2D /* Legacy open for old servers */
-#define SMB_COM_READ_ANDX 0x2E
-#define SMB_COM_WRITE_ANDX 0x2F
-#define SMB_COM_TRANSACTION2 0x32
-#define SMB_COM_TRANSACTION2_SECONDARY 0x33
-#define SMB_COM_FIND_CLOSE2 0x34 /* trivial response */
-#define SMB_COM_TREE_DISCONNECT 0x71 /* trivial response */
-#define SMB_COM_NEGOTIATE 0x72
-#define SMB_COM_SESSION_SETUP_ANDX 0x73
-#define SMB_COM_LOGOFF_ANDX 0x74 /* trivial response */
-#define SMB_COM_TREE_CONNECT_ANDX 0x75
-#define SMB_COM_NT_TRANSACT 0xA0
-#define SMB_COM_NT_TRANSACT_SECONDARY 0xA1
-#define SMB_COM_NT_CREATE_ANDX 0xA2
-#define SMB_COM_NT_CANCEL 0xA4 /* no response */
-#define SMB_COM_NT_RENAME 0xA5 /* trivial response */
-
-/* Transact2 subcommand codes */
-#define TRANS2_OPEN 0x00
-#define TRANS2_FIND_FIRST 0x01
-#define TRANS2_FIND_NEXT 0x02
-#define TRANS2_QUERY_FS_INFORMATION 0x03
-#define TRANS2_SET_FS_INFORMATION 0x04
-#define TRANS2_QUERY_PATH_INFORMATION 0x05
-#define TRANS2_SET_PATH_INFORMATION 0x06
-#define TRANS2_QUERY_FILE_INFORMATION 0x07
-#define TRANS2_SET_FILE_INFORMATION 0x08
-#define TRANS2_GET_DFS_REFERRAL 0x10
-#define TRANS2_REPORT_DFS_INCOSISTENCY 0x11
-
-/* SMB Transact (Named Pipe) subcommand codes */
-#define TRANS_SET_NMPIPE_STATE 0x0001
-#define TRANS_RAW_READ_NMPIPE 0x0011
-#define TRANS_QUERY_NMPIPE_STATE 0x0021
-#define TRANS_QUERY_NMPIPE_INFO 0x0022
-#define TRANS_PEEK_NMPIPE 0x0023
-#define TRANS_TRANSACT_NMPIPE 0x0026
-#define TRANS_RAW_WRITE_NMPIPE 0x0031
-#define TRANS_READ_NMPIPE 0x0036
-#define TRANS_WRITE_NMPIPE 0x0037
-#define TRANS_WAIT_NMPIPE 0x0053
-#define TRANS_CALL_NMPIPE 0x0054
-
-/* NT Transact subcommand codes */
-#define NT_TRANSACT_CREATE 0x01
-#define NT_TRANSACT_IOCTL 0x02
-#define NT_TRANSACT_SET_SECURITY_DESC 0x03
-#define NT_TRANSACT_NOTIFY_CHANGE 0x04
-#define NT_TRANSACT_RENAME 0x05
-#define NT_TRANSACT_QUERY_SECURITY_DESC 0x06
-#define NT_TRANSACT_GET_USER_QUOTA 0x07
-#define NT_TRANSACT_SET_USER_QUOTA 0x08
-
-#define MAX_CIFS_SMALL_BUFFER_SIZE 448 /* big enough for most */
-/* future chained NTCreateXReadX bigger, but for time being NTCreateX biggest */
-/* among the requests (NTCreateX response is bigger with wct of 34) */
-#define MAX_CIFS_HDR_SIZE 0x58 /* 4 len + 32 hdr + (2*24 wct) + 2 bct + 2 pad */
-#define CIFS_SMALL_PATH 120 /* allows for (448-88)/3 */
-
-/* internal cifs vfs structures */
-/*****************************************************************
- * All constants go here
- *****************************************************************
- */
-
-/*
- * Starting value for maximum SMB size negotiation
- */
-#define CIFS_MAX_MSGSIZE (4*4096)
-
-/*
- * Size of encrypted user password in bytes
- */
-#define CIFS_ENCPWD_SIZE (16)
-
-/*
- * Size of the crypto key returned on the negotiate SMB in bytes
- */
-#define CIFS_CRYPTO_KEY_SIZE (8)
-
-/*
- * Size of the ntlm client response
- */
-#define CIFS_AUTH_RESP_SIZE (24)
-
-/*
- * Size of the session key (crypto key encrypted with the password
- */
-#define CIFS_SESS_KEY_SIZE (16)
-
-#define CIFS_CLIENT_CHALLENGE_SIZE (8)
-#define CIFS_SERVER_CHALLENGE_SIZE (8)
-#define CIFS_HMAC_MD5_HASH_SIZE (16)
-#define CIFS_CPHTXT_SIZE (16)
-#define CIFS_NTHASH_SIZE (16)
-
-/*
- * Maximum user name length
- */
-#define CIFS_UNLEN (20)
-
-/*
- * Flags on SMB open
- */
-#define SMBOPEN_WRITE_THROUGH 0x4000
-#define SMBOPEN_DENY_ALL 0x0010
-#define SMBOPEN_DENY_WRITE 0x0020
-#define SMBOPEN_DENY_READ 0x0030
-#define SMBOPEN_DENY_NONE 0x0040
-#define SMBOPEN_READ 0x0000
-#define SMBOPEN_WRITE 0x0001
-#define SMBOPEN_READWRITE 0x0002
-#define SMBOPEN_EXECUTE 0x0003
-
-#define SMBOPEN_OCREATE 0x0010
-#define SMBOPEN_OTRUNC 0x0002
-#define SMBOPEN_OAPPEND 0x0001
-
-/*
- * SMB flag definitions
- */
-#define SMBFLG_EXTD_LOCK 0x01 /* server supports lock-read write-unlock smb */
-#define SMBFLG_RCV_POSTED 0x02 /* obsolete */
-#define SMBFLG_RSVD 0x04
-#define SMBFLG_CASELESS 0x08 /* all pathnames treated as caseless (off
- implies case sensitive file handling request) */
-#define SMBFLG_CANONICAL_PATH_FORMAT 0x10 /* obsolete */
-#define SMBFLG_OLD_OPLOCK 0x20 /* obsolete */
-#define SMBFLG_OLD_OPLOCK_NOTIFY 0x40 /* obsolete */
-#define SMBFLG_RESPONSE 0x80 /* this PDU is a response from server */
-
-/*
- * SMB flag2 definitions
- */
-#define SMBFLG2_KNOWS_LONG_NAMES cpu_to_le16(1) /* can send long (non-8.3)
- path names in response */
-#define SMBFLG2_KNOWS_EAS cpu_to_le16(2)
-#define SMBFLG2_SECURITY_SIGNATURE cpu_to_le16(4)
-#define SMBFLG2_COMPRESSED (8)
-#define SMBFLG2_SECURITY_SIGNATURE_REQUIRED (0x10)
-#define SMBFLG2_IS_LONG_NAME cpu_to_le16(0x40)
-#define SMBFLG2_REPARSE_PATH (0x400)
-#define SMBFLG2_EXT_SEC cpu_to_le16(0x800)
-#define SMBFLG2_DFS cpu_to_le16(0x1000)
-#define SMBFLG2_PAGING_IO cpu_to_le16(0x2000)
-#define SMBFLG2_ERR_STATUS cpu_to_le16(0x4000)
-#define SMBFLG2_UNICODE cpu_to_le16(0x8000)
-
-/*
- * These are the file access permission bits defined in CIFS for the
- * NTCreateAndX as well as the level 0x107
- * TRANS2_QUERY_PATH_INFORMATION API. The level 0x107, SMB_QUERY_FILE_ALL_INFO
- * responds with the AccessFlags.
- * The AccessFlags specifies the access permissions a caller has to the
- * file and can have any suitable combination of the following values:
- */
-
-#define FILE_READ_DATA 0x00000001 /* Data can be read from the file */
-#define FILE_WRITE_DATA 0x00000002 /* Data can be written to the file */
-#define FILE_APPEND_DATA 0x00000004 /* Data can be appended to the file */
-#define FILE_READ_EA 0x00000008 /* Extended attributes associated */
- /* with the file can be read */
-#define FILE_WRITE_EA 0x00000010 /* Extended attributes associated */
- /* with the file can be written */
-#define FILE_EXECUTE 0x00000020 /*Data can be read into memory from */
- /* the file using system paging I/O */
-#define FILE_DELETE_CHILD 0x00000040
-#define FILE_READ_ATTRIBUTES 0x00000080 /* Attributes associated with the */
- /* file can be read */
-#define FILE_WRITE_ATTRIBUTES 0x00000100 /* Attributes associated with the */
- /* file can be written */
-#define DELETE 0x00010000 /* The file can be deleted */
-#define READ_CONTROL 0x00020000 /* The access control list and */
- /* ownership associated with the */
- /* file can be read */
-#define WRITE_DAC 0x00040000 /* The access control list and */
- /* ownership associated with the */
- /* file can be written. */
-#define WRITE_OWNER 0x00080000 /* Ownership information associated */
- /* with the file can be written */
-#define SYNCHRONIZE 0x00100000 /* The file handle can waited on to */
- /* synchronize with the completion */
- /* of an input/output request */
-#define GENERIC_ALL 0x10000000
-#define GENERIC_EXECUTE 0x20000000
-#define GENERIC_WRITE 0x40000000
-#define GENERIC_READ 0x80000000
- /* In summary - Relevant file */
- /* access flags from CIFS are */
- /* file_read_data, file_write_data */
- /* file_execute, file_read_attributes*/
- /* write_dac, and delete. */
-
-#define FILE_READ_RIGHTS (FILE_READ_DATA | FILE_READ_EA | FILE_READ_ATTRIBUTES)
-#define FILE_WRITE_RIGHTS (FILE_WRITE_DATA | FILE_APPEND_DATA \
- | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES)
-#define FILE_EXEC_RIGHTS (FILE_EXECUTE)
-
-#define SET_FILE_READ_RIGHTS (FILE_READ_DATA | FILE_READ_EA | FILE_WRITE_EA \
- | FILE_READ_ATTRIBUTES \
- | FILE_WRITE_ATTRIBUTES \
- | DELETE | READ_CONTROL | WRITE_DAC \
- | WRITE_OWNER | SYNCHRONIZE)
-#define SET_FILE_WRITE_RIGHTS (FILE_WRITE_DATA | FILE_APPEND_DATA \
- | FILE_READ_EA | FILE_WRITE_EA \
- | FILE_DELETE_CHILD | FILE_READ_ATTRIBUTES \
- | FILE_WRITE_ATTRIBUTES \
- | DELETE | READ_CONTROL | WRITE_DAC \
- | WRITE_OWNER | SYNCHRONIZE)
-#define SET_FILE_EXEC_RIGHTS (FILE_READ_EA | FILE_WRITE_EA | FILE_EXECUTE \
- | FILE_READ_ATTRIBUTES \
- | FILE_WRITE_ATTRIBUTES \
- | DELETE | READ_CONTROL | WRITE_DAC \
- | WRITE_OWNER | SYNCHRONIZE)
-
-#define SET_MINIMUM_RIGHTS (FILE_READ_EA | FILE_READ_ATTRIBUTES \
- | READ_CONTROL | SYNCHRONIZE)
-
-
-/*
- * Invalid readdir handle
- */
-#define CIFS_NO_HANDLE 0xFFFF
-
-#define NO_CHANGE_64 0xFFFFFFFFFFFFFFFFULL
-#define NO_CHANGE_32 0xFFFFFFFFUL
-
-/* IPC$ in ASCII */
-#define CIFS_IPC_RESOURCE "\x49\x50\x43\x24"
-
-/* IPC$ in Unicode */
-#define CIFS_IPC_UNICODE_RESOURCE "\x00\x49\x00\x50\x00\x43\x00\x24\x00\x00"
-
-/* Unicode Null terminate 2 bytes of 0 */
-#define UNICODE_NULL "\x00\x00"
-#define ASCII_NULL 0x00
-
-/*
- * Server type values (returned on EnumServer API
- */
-#define CIFS_SV_TYPE_DC 0x00000008
-#define CIFS_SV_TYPE_BACKDC 0x00000010
-
-/*
- * Alias type flags (From EnumAlias API call
- */
-#define CIFS_ALIAS_TYPE_FILE 0x0001
-#define CIFS_SHARE_TYPE_FILE 0x0000
-
-/*
- * File Attribute flags
- */
-#define ATTR_READONLY 0x0001
-#define ATTR_HIDDEN 0x0002
-#define ATTR_SYSTEM 0x0004
-#define ATTR_VOLUME 0x0008
-#define ATTR_DIRECTORY 0x0010
-#define ATTR_ARCHIVE 0x0020
-#define ATTR_DEVICE 0x0040
-#define ATTR_NORMAL 0x0080
-#define ATTR_TEMPORARY 0x0100
-#define ATTR_SPARSE 0x0200
-#define ATTR_REPARSE 0x0400
-#define ATTR_COMPRESSED 0x0800
-#define ATTR_OFFLINE 0x1000 /* ie file not immediately available -
- on offline storage */
-#define ATTR_NOT_CONTENT_INDEXED 0x2000
-#define ATTR_ENCRYPTED 0x4000
-#define ATTR_POSIX_SEMANTICS 0x01000000
-#define ATTR_BACKUP_SEMANTICS 0x02000000
-#define ATTR_DELETE_ON_CLOSE 0x04000000
-#define ATTR_SEQUENTIAL_SCAN 0x08000000
-#define ATTR_RANDOM_ACCESS 0x10000000
-#define ATTR_NO_BUFFERING 0x20000000
-#define ATTR_WRITE_THROUGH 0x80000000
-
-/* ShareAccess flags */
-#define FILE_NO_SHARE 0x00000000
-#define FILE_SHARE_READ 0x00000001
-#define FILE_SHARE_WRITE 0x00000002
-#define FILE_SHARE_DELETE 0x00000004
-#define FILE_SHARE_ALL 0x00000007
-
-/* CreateDisposition flags, similar to CreateAction as well */
-#define FILE_SUPERSEDE 0x00000000
-#define FILE_OPEN 0x00000001
-#define FILE_CREATE 0x00000002
-#define FILE_OPEN_IF 0x00000003
-#define FILE_OVERWRITE 0x00000004
-#define FILE_OVERWRITE_IF 0x00000005
-
-/* CreateOptions */
-#define CREATE_NOT_FILE 0x00000001 /* if set must not be file */
-#define CREATE_WRITE_THROUGH 0x00000002
-#define CREATE_SEQUENTIAL 0x00000004
-#define CREATE_NO_BUFFER 0x00000008 /* should not buffer on srv */
-#define CREATE_SYNC_ALERT 0x00000010 /* MBZ */
-#define CREATE_ASYNC_ALERT 0x00000020 /* MBZ */
-#define CREATE_NOT_DIR 0x00000040 /* if set must not be directory */
-#define CREATE_TREE_CONNECTION 0x00000080 /* should be zero */
-#define CREATE_COMPLETE_IF_OPLK 0x00000100 /* should be zero */
-#define CREATE_NO_EA_KNOWLEDGE 0x00000200
-#define CREATE_EIGHT_DOT_THREE 0x00000400 /* doc says this is obsolete
- "open for recovery" flag should
- be zero in any case */
-#define CREATE_OPEN_FOR_RECOVERY 0x00000400
-#define CREATE_RANDOM_ACCESS 0x00000800
-#define CREATE_DELETE_ON_CLOSE 0x00001000
-#define CREATE_OPEN_BY_ID 0x00002000
-#define CREATE_OPEN_BACKUP_INTENT 0x00004000
-#define CREATE_NO_COMPRESSION 0x00008000
-#define CREATE_RESERVE_OPFILTER 0x00100000 /* should be zero */
-#define OPEN_REPARSE_POINT 0x00200000
-#define OPEN_NO_RECALL 0x00400000
-#define OPEN_FREE_SPACE_QUERY 0x00800000 /* should be zero */
-#define CREATE_OPTIONS_MASK 0x007FFFFF
-#define CREATE_OPTION_READONLY 0x10000000
-#define CREATE_OPTION_SPECIAL 0x20000000 /* system. NB not sent over wire */
-
-/* ImpersonationLevel flags */
-#define SECURITY_ANONYMOUS 0
-#define SECURITY_IDENTIFICATION 1
-#define SECURITY_IMPERSONATION 2
-#define SECURITY_DELEGATION 3
-
-/* SecurityFlags */
-#define SECURITY_CONTEXT_TRACKING 0x01
-#define SECURITY_EFFECTIVE_ONLY 0x02
-
-/*
- * Default PID value, used in all SMBs where the PID is not important
- */
-#define CIFS_DFT_PID 0x1234
-
-/*
- * We use the same routine for Copy and Move SMBs. This flag is used to
- * distinguish
- */
-#define CIFS_COPY_OP 1
-#define CIFS_RENAME_OP 2
-
-#define GETU16(var) (*((__u16 *)var)) /* BB check for endian issues */
-#define GETU32(var) (*((__u32 *)var)) /* BB check for endian issues */
-
-struct smb_hdr {
- __be32 smb_buf_length; /* BB length is only two (rarely three) bytes,
- with one or two byte "type" preceding it that will be
- zero - we could mask the type byte off */
- __u8 Protocol[4];
- __u8 Command;
- union {
- struct {
- __u8 ErrorClass;
- __u8 Reserved;
- __le16 Error;
- } __attribute__((packed)) DosError;
- __le32 CifsError;
- } __attribute__((packed)) Status;
- __u8 Flags;
- __le16 Flags2; /* note: le */
- __le16 PidHigh;
- union {
- struct {
- __le32 SequenceNumber; /* le */
- __u32 Reserved; /* zero */
- } __attribute__((packed)) Sequence;
- __u8 SecuritySignature[8]; /* le */
- } __attribute__((packed)) Signature;
- __u8 pad[2];
- __u16 Tid;
- __le16 Pid;
- __u16 Uid;
- __u16 Mid;
- __u8 WordCount;
-} __attribute__((packed));
-
-/* given a pointer to an smb_hdr, retrieve a void pointer to the ByteCount */
-static inline void *
-BCC(struct smb_hdr *smb)
-{
- return (void *)smb + sizeof(*smb) + 2 * smb->WordCount;
-}
-
-/* given a pointer to an smb_hdr retrieve the pointer to the byte area */
-#define pByteArea(smb_var) (BCC(smb_var) + 2)
-
-/* get the unconverted ByteCount for a SMB packet and return it */
-static inline __u16
-get_bcc(struct smb_hdr *hdr)
-{
- __le16 *bc_ptr = (__le16 *)BCC(hdr);
-
- return get_unaligned_le16(bc_ptr);
-}
-
-/* set the ByteCount for a SMB packet in little-endian */
-static inline void
-put_bcc(__u16 count, struct smb_hdr *hdr)
-{
- __le16 *bc_ptr = (__le16 *)BCC(hdr);
-
- put_unaligned_le16(count, bc_ptr);
-}
-
-/*
- * Computer Name Length (since Netbios name was length 16 with last byte 0x20)
- * No longer as important, now that TCP names are more commonly used to
- * resolve hosts.
- */
-#define CNLEN 15
-
-/*
- * Share Name Length (SNLEN)
- * Note: This length was limited by the SMB used to get
- * the Share info. NetShareEnum only returned 13
- * chars, including the null termination.
- * This was removed because it no longer is limiting.
- */
-
-/*
- * Comment Length
- */
-#define MAXCOMMENTLEN 40
-
-/*
- * The OS/2 maximum path name
- */
-#define MAX_PATHCONF 256
-
-/*
- * SMB frame definitions (following must be packed structs)
- * See the SNIA CIFS Specification for details.
- *
- * The Naming convention is the lower case version of the
- * smb command code name for the struct and this is typedef to the
- * uppercase version of the same name with the prefix SMB_ removed
- * for brevity. Although typedefs are not commonly used for
- * structure definitions in the Linux kernel, their use in the
- * CIFS standards document, which this code is based on, may
- * make this one of the cases where typedefs for structures make
- * sense to improve readability for readers of the standards doc.
- * Typedefs can always be removed later if they are too distracting
- * and they are only used for the CIFSs PDUs themselves, not
- * internal cifs vfs structures
- *
- */
-
-typedef struct negotiate_req {
- struct smb_hdr hdr; /* wct = 0 */
- __le16 ByteCount;
- unsigned char DialectsArray[1];
-} __attribute__((packed)) NEGOTIATE_REQ;
-
-/* Dialect index is 13 for LANMAN */
-
-#define MIN_TZ_ADJ (15 * 60) /* minimum grid for timezones in seconds */
-
-typedef struct lanman_neg_rsp {
- struct smb_hdr hdr; /* wct = 13 */
- __le16 DialectIndex;
- __le16 SecurityMode;
- __le16 MaxBufSize;
- __le16 MaxMpxCount;
- __le16 MaxNumberVcs;
- __le16 RawMode;
- __le32 SessionKey;
- struct {
- __le16 Time;
- __le16 Date;
- } __attribute__((packed)) SrvTime;
- __le16 ServerTimeZone;
- __le16 EncryptionKeyLength;
- __le16 Reserved;
- __u16 ByteCount;
- unsigned char EncryptionKey[1];
-} __attribute__((packed)) LANMAN_NEG_RSP;
-
-#define READ_RAW_ENABLE 1
-#define WRITE_RAW_ENABLE 2
-#define RAW_ENABLE (READ_RAW_ENABLE | WRITE_RAW_ENABLE)
-
-typedef struct negotiate_rsp {
- struct smb_hdr hdr; /* wct = 17 */
- __le16 DialectIndex; /* 0xFFFF = no dialect acceptable */
- __u8 SecurityMode;
- __le16 MaxMpxCount;
- __le16 MaxNumberVcs;
- __le32 MaxBufferSize;
- __le32 MaxRawSize;
- __le32 SessionKey;
- __le32 Capabilities; /* see below */
- __le32 SystemTimeLow;
- __le32 SystemTimeHigh;
- __le16 ServerTimeZone;
- __u8 EncryptionKeyLength;
- __u16 ByteCount;
- union {
- unsigned char EncryptionKey[1]; /* cap extended security off */
- /* followed by Domain name - if extended security is off */
- /* followed by 16 bytes of server GUID */
- /* then security blob if cap_extended_security negotiated */
- struct {
- unsigned char GUID[16];
- unsigned char SecurityBlob[1];
- } __attribute__((packed)) extended_response;
- } __attribute__((packed)) u;
-} __attribute__((packed)) NEGOTIATE_RSP;
-
-/* SecurityMode bits */
-#define SECMODE_USER 0x01 /* off indicates share level security */
-#define SECMODE_PW_ENCRYPT 0x02
-#define SECMODE_SIGN_ENABLED 0x04 /* SMB security signatures enabled */
-#define SECMODE_SIGN_REQUIRED 0x08 /* SMB security signatures required */
-
-/* Negotiate response Capabilities */
-#define CAP_RAW_MODE 0x00000001
-#define CAP_MPX_MODE 0x00000002
-#define CAP_UNICODE 0x00000004
-#define CAP_LARGE_FILES 0x00000008
-#define CAP_NT_SMBS 0x00000010 /* implies CAP_NT_FIND */
-#define CAP_RPC_REMOTE_APIS 0x00000020
-#define CAP_STATUS32 0x00000040
-#define CAP_LEVEL_II_OPLOCKS 0x00000080
-#define CAP_LOCK_AND_READ 0x00000100
-#define CAP_NT_FIND 0x00000200
-#define CAP_DFS 0x00001000
-#define CAP_INFOLEVEL_PASSTHRU 0x00002000
-#define CAP_LARGE_READ_X 0x00004000
-#define CAP_LARGE_WRITE_X 0x00008000
-#define CAP_LWIO 0x00010000 /* support fctl_srv_req_resume_key */
-#define CAP_UNIX 0x00800000
-#define CAP_COMPRESSED_DATA 0x02000000
-#define CAP_DYNAMIC_REAUTH 0x20000000
-#define CAP_PERSISTENT_HANDLES 0x40000000
-#define CAP_EXTENDED_SECURITY 0x80000000
-
-typedef union smb_com_session_setup_andx {
- struct { /* request format */
- struct smb_hdr hdr; /* wct = 12 */
- __u8 AndXCommand;
- __u8 AndXReserved;
- __le16 AndXOffset;
- __le16 MaxBufferSize;
- __le16 MaxMpxCount;
- __le16 VcNumber;
- __u32 SessionKey;
- __le16 SecurityBlobLength;
- __u32 Reserved;
- __le32 Capabilities; /* see below */
- __le16 ByteCount;
- unsigned char SecurityBlob[1]; /* followed by */
- /* STRING NativeOS */
- /* STRING NativeLanMan */
- } __attribute__((packed)) req; /* NTLM request format (with
- extended security */
-
- struct { /* request format */
- struct smb_hdr hdr; /* wct = 13 */
- __u8 AndXCommand;
- __u8 AndXReserved;
- __le16 AndXOffset;
- __le16 MaxBufferSize;
- __le16 MaxMpxCount;
- __le16 VcNumber;
- __u32 SessionKey;
- __le16 CaseInsensitivePasswordLength; /* ASCII password len */
- __le16 CaseSensitivePasswordLength; /* Unicode password length*/
- __u32 Reserved; /* see below */
- __le32 Capabilities;
- __le16 ByteCount;
- unsigned char CaseInsensitivePassword[1]; /* followed by: */
- /* unsigned char * CaseSensitivePassword; */
- /* STRING AccountName */
- /* STRING PrimaryDomain */
- /* STRING NativeOS */
- /* STRING NativeLanMan */
- } __attribute__((packed)) req_no_secext; /* NTLM request format (without
- extended security */
-
- struct { /* default (NTLM) response format */
- struct smb_hdr hdr; /* wct = 4 */
- __u8 AndXCommand;
- __u8 AndXReserved;
- __le16 AndXOffset;
- __le16 Action; /* see below */
- __le16 SecurityBlobLength;
- __u16 ByteCount;
- unsigned char SecurityBlob[1]; /* followed by */
-/* unsigned char * NativeOS; */
-/* unsigned char * NativeLanMan; */
-/* unsigned char * PrimaryDomain; */
- } __attribute__((packed)) resp; /* NTLM response
- (with or without extended sec) */
-
- struct { /* request format */
- struct smb_hdr hdr; /* wct = 10 */
- __u8 AndXCommand;
- __u8 AndXReserved;
- __le16 AndXOffset;
- __le16 MaxBufferSize;
- __le16 MaxMpxCount;
- __le16 VcNumber;
- __u32 SessionKey;
- __le16 PasswordLength;
- __u32 Reserved; /* encrypt key len and offset */
- __le16 ByteCount;
- unsigned char AccountPassword[1]; /* followed by */
- /* STRING AccountName */
- /* STRING PrimaryDomain */
- /* STRING NativeOS */
- /* STRING NativeLanMan */
- } __attribute__((packed)) old_req; /* pre-NTLM (LANMAN2.1) req format */
-
- struct { /* default (NTLM) response format */
- struct smb_hdr hdr; /* wct = 3 */
- __u8 AndXCommand;
- __u8 AndXReserved;
- __le16 AndXOffset;
- __le16 Action; /* see below */
- __u16 ByteCount;
- unsigned char NativeOS[1]; /* followed by */
-/* unsigned char * NativeLanMan; */
-/* unsigned char * PrimaryDomain; */
- } __attribute__((packed)) old_resp; /* pre-NTLM (LANMAN2.1) response */
-} __attribute__((packed)) SESSION_SETUP_ANDX;
-
-/* format of NLTMv2 Response ie "case sensitive password" hash when NTLMv2 */
-
-#define NTLMSSP_SERVER_TYPE 1
-#define NTLMSSP_DOMAIN_TYPE 2
-#define NTLMSSP_FQ_DOMAIN_TYPE 3
-#define NTLMSSP_DNS_DOMAIN_TYPE 4
-#define NTLMSSP_DNS_PARENT_TYPE 5
-
-struct ntlmssp2_name {
- __le16 type;
- __le16 length;
-/* char name[length]; */
-} __attribute__((packed));
-
-struct ntlmv2_resp {
- char ntlmv2_hash[CIFS_ENCPWD_SIZE];
- __le32 blob_signature;
- __u32 reserved;
- __le64 time;
- __u64 client_chal; /* random */
- __u32 reserved2;
- /* array of name entries could follow ending in minimum 4 byte struct */
-} __attribute__((packed));
-
-
-#define CIFS_NETWORK_OPSYS "CIFS VFS Client for Linux"
-
-/* Capabilities bits (for NTLM SessSetup request) */
-#define CAP_UNICODE 0x00000004
-#define CAP_LARGE_FILES 0x00000008
-#define CAP_NT_SMBS 0x00000010
-#define CAP_STATUS32 0x00000040
-#define CAP_LEVEL_II_OPLOCKS 0x00000080
-#define CAP_NT_FIND 0x00000200 /* reserved should be zero
- (because NT_SMBs implies the same thing?) */
-#define CAP_BULK_TRANSFER 0x20000000
-#define CAP_EXTENDED_SECURITY 0x80000000
-
-/* Action bits */
-#define GUEST_LOGIN 1
-
-typedef struct smb_com_tconx_req {
- struct smb_hdr hdr; /* wct = 4 */
- __u8 AndXCommand;
- __u8 AndXReserved;
- __le16 AndXOffset;
- __le16 Flags; /* see below */
- __le16 PasswordLength;
- __le16 ByteCount;
- unsigned char Password[1]; /* followed by */
-/* STRING Path *//* \\server\share name */
- /* STRING Service */
-} __attribute__((packed)) TCONX_REQ;
-
-typedef struct smb_com_tconx_rsp {
- struct smb_hdr hdr; /* wct = 3 , not extended response */
- __u8 AndXCommand;
- __u8 AndXReserved;
- __le16 AndXOffset;
- __le16 OptionalSupport; /* see below */
- __u16 ByteCount;
- unsigned char Service[1]; /* always ASCII, not Unicode */
- /* STRING NativeFileSystem */
-} __attribute__((packed)) TCONX_RSP;
-
-typedef struct smb_com_tconx_rsp_ext {
- struct smb_hdr hdr; /* wct = 7, extended response */
- __u8 AndXCommand;
- __u8 AndXReserved;
- __le16 AndXOffset;
- __le16 OptionalSupport; /* see below */
- __le32 MaximalShareAccessRights;
- __le32 GuestMaximalShareAccessRights;
- __u16 ByteCount;
- unsigned char Service[1]; /* always ASCII, not Unicode */
- /* STRING NativeFileSystem */
-} __attribute__((packed)) TCONX_RSP_EXT;
-
-
-/* tree connect Flags */
-#define DISCONNECT_TID 0x0001
-#define TCON_EXTENDED_SIGNATURES 0x0004
-#define TCON_EXTENDED_SECINFO 0x0008
-
-/* OptionalSupport bits */
-#define SMB_SUPPORT_SEARCH_BITS 0x0001 /* "must have" directory search bits
- (exclusive searches supported) */
-#define SMB_SHARE_IS_IN_DFS 0x0002
-#define SMB_CSC_MASK 0x000C
-/* CSC flags defined as follows */
-#define SMB_CSC_CACHE_MANUAL_REINT 0x0000
-#define SMB_CSC_CACHE_AUTO_REINT 0x0004
-#define SMB_CSC_CACHE_VDO 0x0008
-#define SMB_CSC_NO_CACHING 0x000C
-#define SMB_UNIQUE_FILE_NAME 0x0010
-#define SMB_EXTENDED_SIGNATURES 0x0020
-
-/* services
- *
- * A: ie disk
- * LPT1: ie printer
- * IPC ie named pipe
- * COMM
- * ????? ie any type
- *
- */
-
-typedef struct smb_com_echo_req {
- struct smb_hdr hdr;
- __le16 EchoCount;
- __le16 ByteCount;
- char Data[1];
-} __attribute__((packed)) ECHO_REQ;
-
-typedef struct smb_com_echo_rsp {
- struct smb_hdr hdr;
- __le16 SequenceNumber;
- __le16 ByteCount;
- char Data[1];
-} __attribute__((packed)) ECHO_RSP;
-
-typedef struct smb_com_logoff_andx_req {
- struct smb_hdr hdr; /* wct = 2 */
- __u8 AndXCommand;
- __u8 AndXReserved;
- __u16 AndXOffset;
- __u16 ByteCount;
-} __attribute__((packed)) LOGOFF_ANDX_REQ;
-
-typedef struct smb_com_logoff_andx_rsp {
- struct smb_hdr hdr; /* wct = 2 */
- __u8 AndXCommand;
- __u8 AndXReserved;
- __u16 AndXOffset;
- __u16 ByteCount;
-} __attribute__((packed)) LOGOFF_ANDX_RSP;
-
-typedef union smb_com_tree_disconnect { /* as an altetnative can use flag on
- tree_connect PDU to effect disconnect */
- /* tdis is probably simplest SMB PDU */
- struct {
- struct smb_hdr hdr; /* wct = 0 */
- __u16 ByteCount; /* bcc = 0 */
- } __attribute__((packed)) req;
- struct {
- struct smb_hdr hdr; /* wct = 0 */
- __u16 ByteCount; /* bcc = 0 */
- } __attribute__((packed)) resp;
-} __attribute__((packed)) TREE_DISCONNECT;
-
-typedef struct smb_com_close_req {
- struct smb_hdr hdr; /* wct = 3 */
- __u16 FileID;
- __u32 LastWriteTime; /* should be zero or -1 */
- __u16 ByteCount; /* 0 */
-} __attribute__((packed)) CLOSE_REQ;
-
-typedef struct smb_com_close_rsp {
- struct smb_hdr hdr; /* wct = 0 */
- __u16 ByteCount; /* bct = 0 */
-} __attribute__((packed)) CLOSE_RSP;
-
-typedef struct smb_com_flush_req {
- struct smb_hdr hdr; /* wct = 1 */
- __u16 FileID;
- __u16 ByteCount; /* 0 */
-} __attribute__((packed)) FLUSH_REQ;
-
-typedef struct smb_com_findclose_req {
- struct smb_hdr hdr; /* wct = 1 */
- __u16 FileID;
- __u16 ByteCount; /* 0 */
-} __attribute__((packed)) FINDCLOSE_REQ;
-
-/* OpenFlags */
-#define REQ_MORE_INFO 0x00000001 /* legacy (OPEN_AND_X) only */
-#define REQ_OPLOCK 0x00000002
-#define REQ_BATCHOPLOCK 0x00000004
-#define REQ_OPENDIRONLY 0x00000008
-#define REQ_EXTENDED_INFO 0x00000010
-
-/* File type */
-#define DISK_TYPE 0x0000
-#define BYTE_PIPE_TYPE 0x0001
-#define MESSAGE_PIPE_TYPE 0x0002
-#define PRINTER_TYPE 0x0003
-#define COMM_DEV_TYPE 0x0004
-#define UNKNOWN_TYPE 0xFFFF
-
-/* Device Type or File Status Flags */
-#define NO_EAS 0x0001
-#define NO_SUBSTREAMS 0x0002
-#define NO_REPARSETAG 0x0004
-/* following flags can apply if pipe */
-#define ICOUNT_MASK 0x00FF
-#define PIPE_READ_MODE 0x0100
-#define NAMED_PIPE_TYPE 0x0400
-#define PIPE_END_POINT 0x4000
-#define BLOCKING_NAMED_PIPE 0x8000
-
-typedef struct smb_com_open_req { /* also handles create */
- struct smb_hdr hdr; /* wct = 24 */
- __u8 AndXCommand;
- __u8 AndXReserved;
- __le16 AndXOffset;
- __u8 Reserved; /* Must Be Zero */
- __le16 NameLength;
- __le32 OpenFlags;
- __u32 RootDirectoryFid;
- __le32 DesiredAccess;
- __le64 AllocationSize;
- __le32 FileAttributes;
- __le32 ShareAccess;
- __le32 CreateDisposition;
- __le32 CreateOptions;
- __le32 ImpersonationLevel;
- __u8 SecurityFlags;
- __le16 ByteCount;
- char fileName[1];
-} __attribute__((packed)) OPEN_REQ;
-
-/* open response: oplock levels */
-#define OPLOCK_NONE 0
-#define OPLOCK_EXCLUSIVE 1
-#define OPLOCK_BATCH 2
-#define OPLOCK_READ 3 /* level 2 oplock */
-
-/* open response for CreateAction shifted left */
-#define CIFS_CREATE_ACTION 0x20000 /* file created */
-
-typedef struct smb_com_open_rsp {
- struct smb_hdr hdr; /* wct = 34 BB */
- __u8 AndXCommand;
- __u8 AndXReserved;
- __le16 AndXOffset;
- __u8 OplockLevel;
- __u16 Fid;
- __le32 CreateAction;
- __le64 CreationTime;
- __le64 LastAccessTime;
- __le64 LastWriteTime;
- __le64 ChangeTime;
- __le32 FileAttributes;
- __le64 AllocationSize;
- __le64 EndOfFile;
- __le16 FileType;
- __le16 DeviceState;
- __u8 DirectoryFlag;
- __u16 ByteCount; /* bct = 0 */
-} __attribute__((packed)) OPEN_RSP;
-
-typedef struct smb_com_open_rsp_ext {
- struct smb_hdr hdr; /* wct = 42 but meaningless due to MS bug? */
- __u8 AndXCommand;
- __u8 AndXReserved;
- __le16 AndXOffset;
- __u8 OplockLevel;
- __u16 Fid;
- __le32 CreateAction;
- __le64 CreationTime;
- __le64 LastAccessTime;
- __le64 LastWriteTime;
- __le64 ChangeTime;
- __le32 FileAttributes;
- __le64 AllocationSize;
- __le64 EndOfFile;
- __le16 FileType;
- __le16 DeviceState;
- __u8 DirectoryFlag;
- __u8 VolumeGUID[16];
- __u64 FileId; /* note no endian conversion - is opaque UniqueID */
- __le32 MaximalAccessRights;
- __le32 GuestMaximalAccessRights;
- __u16 ByteCount; /* bct = 0 */
-} __attribute__((packed)) OPEN_RSP_EXT;
-
-
-/* format of legacy open request */
-typedef struct smb_com_openx_req {
- struct smb_hdr hdr; /* wct = 15 */
- __u8 AndXCommand;
- __u8 AndXReserved;
- __le16 AndXOffset;
- __le16 OpenFlags;
- __le16 Mode;
- __le16 Sattr; /* search attributes */
- __le16 FileAttributes; /* dos attrs */
- __le32 CreateTime; /* os2 format */
- __le16 OpenFunction;
- __le32 EndOfFile;
- __le32 Timeout;
- __le32 Reserved;
- __le16 ByteCount; /* file name follows */
- char fileName[1];
-} __attribute__((packed)) OPENX_REQ;
-
-typedef struct smb_com_openx_rsp {
- struct smb_hdr hdr; /* wct = 15 */
- __u8 AndXCommand;
- __u8 AndXReserved;
- __le16 AndXOffset;
- __u16 Fid;
- __le16 FileAttributes;
- __le32 LastWriteTime; /* os2 format */
- __le32 EndOfFile;
- __le16 Access;
- __le16 FileType;
- __le16 IPCState;
- __le16 Action;
- __u32 FileId;
- __u16 Reserved;
- __u16 ByteCount;
-} __attribute__((packed)) OPENX_RSP;
-
-/* For encoding of POSIX Open Request - see trans2 function 0x209 data struct */
-
-/* Legacy write request for older servers */
-typedef struct smb_com_writex_req {
- struct smb_hdr hdr; /* wct = 12 */
- __u8 AndXCommand;
- __u8 AndXReserved;
- __le16 AndXOffset;
- __u16 Fid;
- __le32 OffsetLow;
- __u32 Reserved; /* Timeout */
- __le16 WriteMode; /* 1 = write through */
- __le16 Remaining;
- __le16 Reserved2;
- __le16 DataLengthLow;
- __le16 DataOffset;
- __le16 ByteCount;
- __u8 Pad; /* BB check for whether padded to DWORD
- boundary and optimum performance here */
- char Data[0];
-} __attribute__((packed)) WRITEX_REQ;
-
-typedef struct smb_com_write_req {
- struct smb_hdr hdr; /* wct = 14 */
- __u8 AndXCommand;
- __u8 AndXReserved;
- __le16 AndXOffset;
- __u16 Fid;
- __le32 OffsetLow;
- __u32 Reserved;
- __le16 WriteMode;
- __le16 Remaining;
- __le16 DataLengthHigh;
- __le16 DataLengthLow;
- __le16 DataOffset;
- __le32 OffsetHigh;
- __le16 ByteCount;
- __u8 Pad; /* BB check for whether padded to DWORD
- boundary and optimum performance here */
- char Data[0];
-} __attribute__((packed)) WRITE_REQ;
-
-typedef struct smb_com_write_rsp {
- struct smb_hdr hdr; /* wct = 6 */
- __u8 AndXCommand;
- __u8 AndXReserved;
- __le16 AndXOffset;
- __le16 Count;
- __le16 Remaining;
- __le16 CountHigh;
- __u16 Reserved;
- __u16 ByteCount;
-} __attribute__((packed)) WRITE_RSP;
-
-/* legacy read request for older servers */
-typedef struct smb_com_readx_req {
- struct smb_hdr hdr; /* wct = 10 */
- __u8 AndXCommand;
- __u8 AndXReserved;
- __le16 AndXOffset;
- __u16 Fid;
- __le32 OffsetLow;
- __le16 MaxCount;
- __le16 MinCount; /* obsolete */
- __le32 Reserved;
- __le16 Remaining;
- __le16 ByteCount;
-} __attribute__((packed)) READX_REQ;
-
-typedef struct smb_com_read_req {
- struct smb_hdr hdr; /* wct = 12 */
- __u8 AndXCommand;
- __u8 AndXReserved;
- __le16 AndXOffset;
- __u16 Fid;
- __le32 OffsetLow;
- __le16 MaxCount;
- __le16 MinCount; /* obsolete */
- __le32 MaxCountHigh;
- __le16 Remaining;
- __le32 OffsetHigh;
- __le16 ByteCount;
-} __attribute__((packed)) READ_REQ;
-
-typedef struct smb_com_read_rsp {
- struct smb_hdr hdr; /* wct = 12 */
- __u8 AndXCommand;
- __u8 AndXReserved;
- __le16 AndXOffset;
- __le16 Remaining;
- __le16 DataCompactionMode;
- __le16 Reserved;
- __le16 DataLength;
- __le16 DataOffset;
- __le16 DataLengthHigh;
- __u64 Reserved2;
- __u16 ByteCount;
- /* read response data immediately follows */
-} __attribute__((packed)) READ_RSP;
-
-typedef struct locking_andx_range {
- __le16 Pid;
- __le16 Pad;
- __le32 OffsetHigh;
- __le32 OffsetLow;
- __le32 LengthHigh;
- __le32 LengthLow;
-} __attribute__((packed)) LOCKING_ANDX_RANGE;
-
-#define LOCKING_ANDX_SHARED_LOCK 0x01
-#define LOCKING_ANDX_OPLOCK_RELEASE 0x02
-#define LOCKING_ANDX_CHANGE_LOCKTYPE 0x04
-#define LOCKING_ANDX_CANCEL_LOCK 0x08
-#define LOCKING_ANDX_LARGE_FILES 0x10 /* always on for us */
-
-typedef struct smb_com_lock_req {
- struct smb_hdr hdr; /* wct = 8 */
- __u8 AndXCommand;
- __u8 AndXReserved;
- __le16 AndXOffset;
- __u16 Fid;
- __u8 LockType;
- __u8 OplockLevel;
- __le32 Timeout;
- __le16 NumberOfUnlocks;
- __le16 NumberOfLocks;
- __le16 ByteCount;
- LOCKING_ANDX_RANGE Locks[1];
-} __attribute__((packed)) LOCK_REQ;
-
-/* lock type */
-#define CIFS_RDLCK 0
-#define CIFS_WRLCK 1
-#define CIFS_UNLCK 2
-typedef struct cifs_posix_lock {
- __le16 lock_type; /* 0 = Read, 1 = Write, 2 = Unlock */
- __le16 lock_flags; /* 1 = Wait (only valid for setlock) */
- __le32 pid;
- __le64 start;
- __le64 length;
- /* BB what about additional owner info to identify network client */
-} __attribute__((packed)) CIFS_POSIX_LOCK;
-
-typedef struct smb_com_lock_rsp {
- struct smb_hdr hdr; /* wct = 2 */
- __u8 AndXCommand;
- __u8 AndXReserved;
- __le16 AndXOffset;
- __u16 ByteCount;
-} __attribute__((packed)) LOCK_RSP;
-
-typedef struct smb_com_rename_req {
- struct smb_hdr hdr; /* wct = 1 */
- __le16 SearchAttributes; /* target file attributes */
- __le16 ByteCount;
- __u8 BufferFormat; /* 4 = ASCII or Unicode */
- unsigned char OldFileName[1];
- /* followed by __u8 BufferFormat2 */
- /* followed by NewFileName */
-} __attribute__((packed)) RENAME_REQ;
-
- /* copy request flags */
-#define COPY_MUST_BE_FILE 0x0001
-#define COPY_MUST_BE_DIR 0x0002
-#define COPY_TARGET_MODE_ASCII 0x0004 /* if not set, binary */
-#define COPY_SOURCE_MODE_ASCII 0x0008 /* if not set, binary */
-#define COPY_VERIFY_WRITES 0x0010
-#define COPY_TREE 0x0020
-
-typedef struct smb_com_copy_req {
- struct smb_hdr hdr; /* wct = 3 */
- __u16 Tid2;
- __le16 OpenFunction;
- __le16 Flags;
- __le16 ByteCount;
- __u8 BufferFormat; /* 4 = ASCII or Unicode */
- unsigned char OldFileName[1];
- /* followed by __u8 BufferFormat2 */
- /* followed by NewFileName string */
-} __attribute__((packed)) COPY_REQ;
-
-typedef struct smb_com_copy_rsp {
- struct smb_hdr hdr; /* wct = 1 */
- __le16 CopyCount; /* number of files copied */
- __u16 ByteCount; /* may be zero */
- __u8 BufferFormat; /* 0x04 - only present if errored file follows */
- unsigned char ErrorFileName[1]; /* only present if error in copy */
-} __attribute__((packed)) COPY_RSP;
-
-#define CREATE_HARD_LINK 0x103
-#define MOVEFILE_COPY_ALLOWED 0x0002
-#define MOVEFILE_REPLACE_EXISTING 0x0001
-
-typedef struct smb_com_nt_rename_req { /* A5 - also used for create hardlink */
- struct smb_hdr hdr; /* wct = 4 */
- __le16 SearchAttributes; /* target file attributes */
- __le16 Flags; /* spec says Information Level */
- __le32 ClusterCount;
- __le16 ByteCount;
- __u8 BufferFormat; /* 4 = ASCII or Unicode */
- unsigned char OldFileName[1];
- /* followed by __u8 BufferFormat2 */
- /* followed by NewFileName */
-} __attribute__((packed)) NT_RENAME_REQ;
-
-typedef struct smb_com_rename_rsp {
- struct smb_hdr hdr; /* wct = 0 */
- __u16 ByteCount; /* bct = 0 */
-} __attribute__((packed)) RENAME_RSP;
-
-typedef struct smb_com_delete_file_req {
- struct smb_hdr hdr; /* wct = 1 */
- __le16 SearchAttributes;
- __le16 ByteCount;
- __u8 BufferFormat; /* 4 = ASCII */
- unsigned char fileName[1];
-} __attribute__((packed)) DELETE_FILE_REQ;
-
-typedef struct smb_com_delete_file_rsp {
- struct smb_hdr hdr; /* wct = 0 */
- __u16 ByteCount; /* bct = 0 */
-} __attribute__((packed)) DELETE_FILE_RSP;
-
-typedef struct smb_com_delete_directory_req {
- struct smb_hdr hdr; /* wct = 0 */
- __le16 ByteCount;
- __u8 BufferFormat; /* 4 = ASCII */
- unsigned char DirName[1];
-} __attribute__((packed)) DELETE_DIRECTORY_REQ;
-
-typedef struct smb_com_delete_directory_rsp {
- struct smb_hdr hdr; /* wct = 0 */
- __u16 ByteCount; /* bct = 0 */
-} __attribute__((packed)) DELETE_DIRECTORY_RSP;
-
-typedef struct smb_com_create_directory_req {
- struct smb_hdr hdr; /* wct = 0 */
- __le16 ByteCount;
- __u8 BufferFormat; /* 4 = ASCII */
- unsigned char DirName[1];
-} __attribute__((packed)) CREATE_DIRECTORY_REQ;
-
-typedef struct smb_com_create_directory_rsp {
- struct smb_hdr hdr; /* wct = 0 */
- __u16 ByteCount; /* bct = 0 */
-} __attribute__((packed)) CREATE_DIRECTORY_RSP;
-
-typedef struct smb_com_query_information_req {
- struct smb_hdr hdr; /* wct = 0 */
- __le16 ByteCount; /* 1 + namelen + 1 */
- __u8 BufferFormat; /* 4 = ASCII */
- unsigned char FileName[1];
-} __attribute__((packed)) QUERY_INFORMATION_REQ;
-
-typedef struct smb_com_query_information_rsp {
- struct smb_hdr hdr; /* wct = 10 */
- __le16 attr;
- __le32 last_write_time;
- __le32 size;
- __u16 reserved[5];
- __le16 ByteCount; /* bcc = 0 */
-} __attribute__((packed)) QUERY_INFORMATION_RSP;
-
-typedef struct smb_com_setattr_req {
- struct smb_hdr hdr; /* wct = 8 */
- __le16 attr;
- __le16 time_low;
- __le16 time_high;
- __le16 reserved[5]; /* must be zero */
- __u16 ByteCount;
- __u8 BufferFormat; /* 4 = ASCII */
- unsigned char fileName[1];
-} __attribute__((packed)) SETATTR_REQ;
-
-typedef struct smb_com_setattr_rsp {
- struct smb_hdr hdr; /* wct = 0 */
- __u16 ByteCount; /* bct = 0 */
-} __attribute__((packed)) SETATTR_RSP;
-
-/* empty wct response to setattr */
-
-/*******************************************************/
-/* NT Transact structure definitions follow */
-/* Currently only ioctl, acl (get security descriptor) */
-/* and notify are implemented */
-/*******************************************************/
-typedef struct smb_com_ntransact_req {
- struct smb_hdr hdr; /* wct >= 19 */
- __u8 MaxSetupCount;
- __u16 Reserved;
- __le32 TotalParameterCount;
- __le32 TotalDataCount;
- __le32 MaxParameterCount;
- __le32 MaxDataCount;
- __le32 ParameterCount;
- __le32 ParameterOffset;
- __le32 DataCount;
- __le32 DataOffset;
- __u8 SetupCount; /* four setup words follow subcommand */
- /* SNIA spec incorrectly included spurious pad here */
- __le16 SubCommand; /* 2 = IOCTL/FSCTL */
- /* SetupCount words follow then */
- __le16 ByteCount;
- __u8 Pad[3];
- __u8 Parms[0];
-} __attribute__((packed)) NTRANSACT_REQ;
-
-typedef struct smb_com_ntransact_rsp {
- struct smb_hdr hdr; /* wct = 18 */
- __u8 Reserved[3];
- __le32 TotalParameterCount;
- __le32 TotalDataCount;
- __le32 ParameterCount;
- __le32 ParameterOffset;
- __le32 ParameterDisplacement;
- __le32 DataCount;
- __le32 DataOffset;
- __le32 DataDisplacement;
- __u8 SetupCount; /* 0 */
- __u16 ByteCount;
- /* __u8 Pad[3]; */
- /* parms and data follow */
-} __attribute__((packed)) NTRANSACT_RSP;
-
-typedef struct smb_com_transaction_ioctl_req {
- struct smb_hdr hdr; /* wct = 23 */
- __u8 MaxSetupCount;
- __u16 Reserved;
- __le32 TotalParameterCount;
- __le32 TotalDataCount;
- __le32 MaxParameterCount;
- __le32 MaxDataCount;
- __le32 ParameterCount;
- __le32 ParameterOffset;
- __le32 DataCount;
- __le32 DataOffset;
- __u8 SetupCount; /* four setup words follow subcommand */
- /* SNIA spec incorrectly included spurious pad here */
- __le16 SubCommand; /* 2 = IOCTL/FSCTL */
- __le32 FunctionCode;
- __u16 Fid;
- __u8 IsFsctl; /* 1 = File System Control 0 = device control (IOCTL) */
- __u8 IsRootFlag; /* 1 = apply command to root of share (must be DFS) */
- __le16 ByteCount;
- __u8 Pad[3];
- __u8 Data[1];
-} __attribute__((packed)) TRANSACT_IOCTL_REQ;
-
-typedef struct smb_com_transaction_ioctl_rsp {
- struct smb_hdr hdr; /* wct = 19 */
- __u8 Reserved[3];
- __le32 TotalParameterCount;
- __le32 TotalDataCount;
- __le32 ParameterCount;
- __le32 ParameterOffset;
- __le32 ParameterDisplacement;
- __le32 DataCount;
- __le32 DataOffset;
- __le32 DataDisplacement;
- __u8 SetupCount; /* 1 */
- __le16 ReturnedDataLen;
- __u16 ByteCount;
-} __attribute__((packed)) TRANSACT_IOCTL_RSP;
-
-#define CIFS_ACL_OWNER 1
-#define CIFS_ACL_GROUP 2
-#define CIFS_ACL_DACL 4
-#define CIFS_ACL_SACL 8
-
-typedef struct smb_com_transaction_qsec_req {
- struct smb_hdr hdr; /* wct = 19 */
- __u8 MaxSetupCount;
- __u16 Reserved;
- __le32 TotalParameterCount;
- __le32 TotalDataCount;
- __le32 MaxParameterCount;
- __le32 MaxDataCount;
- __le32 ParameterCount;
- __le32 ParameterOffset;
- __le32 DataCount;
- __le32 DataOffset;
- __u8 SetupCount; /* no setup words follow subcommand */
- /* SNIA spec incorrectly included spurious pad here */
- __le16 SubCommand; /* 6 = QUERY_SECURITY_DESC */
- __le16 ByteCount; /* bcc = 3 + 8 */
- __u8 Pad[3];
- __u16 Fid;
- __u16 Reserved2;
- __le32 AclFlags;
-} __attribute__((packed)) QUERY_SEC_DESC_REQ;
-
-
-typedef struct smb_com_transaction_ssec_req {
- struct smb_hdr hdr; /* wct = 19 */
- __u8 MaxSetupCount;
- __u16 Reserved;
- __le32 TotalParameterCount;
- __le32 TotalDataCount;
- __le32 MaxParameterCount;
- __le32 MaxDataCount;
- __le32 ParameterCount;
- __le32 ParameterOffset;
- __le32 DataCount;
- __le32 DataOffset;
- __u8 SetupCount; /* no setup words follow subcommand */
- /* SNIA spec incorrectly included spurious pad here */
- __le16 SubCommand; /* 3 = SET_SECURITY_DESC */
- __le16 ByteCount; /* bcc = 3 + 8 */
- __u8 Pad[3];
- __u16 Fid;
- __u16 Reserved2;
- __le32 AclFlags;
-} __attribute__((packed)) SET_SEC_DESC_REQ;
-
-typedef struct smb_com_transaction_change_notify_req {
- struct smb_hdr hdr; /* wct = 23 */
- __u8 MaxSetupCount;
- __u16 Reserved;
- __le32 TotalParameterCount;
- __le32 TotalDataCount;
- __le32 MaxParameterCount;
- __le32 MaxDataCount;
- __le32 ParameterCount;
- __le32 ParameterOffset;
- __le32 DataCount;
- __le32 DataOffset;
- __u8 SetupCount; /* four setup words follow subcommand */
- /* SNIA spec incorrectly included spurious pad here */
- __le16 SubCommand;/* 4 = Change Notify */
- __le32 CompletionFilter; /* operation to monitor */
- __u16 Fid;
- __u8 WatchTree; /* 1 = Monitor subdirectories */
- __u8 Reserved2;
- __le16 ByteCount;
-/* __u8 Pad[3];*/
-/* __u8 Data[1];*/
-} __attribute__((packed)) TRANSACT_CHANGE_NOTIFY_REQ;
-
-/* BB eventually change to use generic ntransact rsp struct
- and validation routine */
-typedef struct smb_com_transaction_change_notify_rsp {
- struct smb_hdr hdr; /* wct = 18 */
- __u8 Reserved[3];
- __le32 TotalParameterCount;
- __le32 TotalDataCount;
- __le32 ParameterCount;
- __le32 ParameterOffset;
- __le32 ParameterDisplacement;
- __le32 DataCount;
- __le32 DataOffset;
- __le32 DataDisplacement;
- __u8 SetupCount; /* 0 */
- __u16 ByteCount;
- /* __u8 Pad[3]; */
-} __attribute__((packed)) TRANSACT_CHANGE_NOTIFY_RSP;
-/* Completion Filter flags for Notify */
-#define FILE_NOTIFY_CHANGE_FILE_NAME 0x00000001
-#define FILE_NOTIFY_CHANGE_DIR_NAME 0x00000002
-#define FILE_NOTIFY_CHANGE_NAME 0x00000003
-#define FILE_NOTIFY_CHANGE_ATTRIBUTES 0x00000004
-#define FILE_NOTIFY_CHANGE_SIZE 0x00000008
-#define FILE_NOTIFY_CHANGE_LAST_WRITE 0x00000010
-#define FILE_NOTIFY_CHANGE_LAST_ACCESS 0x00000020
-#define FILE_NOTIFY_CHANGE_CREATION 0x00000040
-#define FILE_NOTIFY_CHANGE_EA 0x00000080
-#define FILE_NOTIFY_CHANGE_SECURITY 0x00000100
-#define FILE_NOTIFY_CHANGE_STREAM_NAME 0x00000200
-#define FILE_NOTIFY_CHANGE_STREAM_SIZE 0x00000400
-#define FILE_NOTIFY_CHANGE_STREAM_WRITE 0x00000800
-
-#define FILE_ACTION_ADDED 0x00000001
-#define FILE_ACTION_REMOVED 0x00000002
-#define FILE_ACTION_MODIFIED 0x00000003
-#define FILE_ACTION_RENAMED_OLD_NAME 0x00000004
-#define FILE_ACTION_RENAMED_NEW_NAME 0x00000005
-#define FILE_ACTION_ADDED_STREAM 0x00000006
-#define FILE_ACTION_REMOVED_STREAM 0x00000007
-#define FILE_ACTION_MODIFIED_STREAM 0x00000008
-
-/* response contains array of the following structures */
-struct file_notify_information {
- __le32 NextEntryOffset;
- __le32 Action;
- __le32 FileNameLength;
- __u8 FileName[0];
-} __attribute__((packed));
-
-struct reparse_data {
- __u32 ReparseTag;
- __u16 ReparseDataLength;
- __u16 Reserved;
- __u16 AltNameOffset;
- __u16 AltNameLen;
- __u16 TargetNameOffset;
- __u16 TargetNameLen;
- char LinkNamesBuf[1];
-} __attribute__((packed));
-
-struct cifs_quota_data {
- __u32 rsrvd1; /* 0 */
- __u32 sid_size;
- __u64 rsrvd2; /* 0 */
- __u64 space_used;
- __u64 soft_limit;
- __u64 hard_limit;
- char sid[1]; /* variable size? */
-} __attribute__((packed));
-
-/* quota sub commands */
-#define QUOTA_LIST_CONTINUE 0
-#define QUOTA_LIST_START 0x100
-#define QUOTA_FOR_SID 0x101
-
-struct trans2_req {
- /* struct smb_hdr hdr precedes. Set wct = 14+ */
- __le16 TotalParameterCount;
- __le16 TotalDataCount;
- __le16 MaxParameterCount;
- __le16 MaxDataCount;
- __u8 MaxSetupCount;
- __u8 Reserved;
- __le16 Flags;
- __le32 Timeout;
- __u16 Reserved2;
- __le16 ParameterCount;
- __le16 ParameterOffset;
- __le16 DataCount;
- __le16 DataOffset;
- __u8 SetupCount;
- __u8 Reserved3;
- __le16 SubCommand; /* 1st setup word - SetupCount words follow */
- __le16 ByteCount;
-} __attribute__((packed));
-
-struct smb_t2_req {
- struct smb_hdr hdr;
- struct trans2_req t2_req;
-} __attribute__((packed));
-
-struct trans2_resp {
- /* struct smb_hdr hdr precedes. Note wct = 10 + setup count */
- __le16 TotalParameterCount;
- __le16 TotalDataCount;
- __u16 Reserved;
- __le16 ParameterCount;
- __le16 ParameterOffset;
- __le16 ParameterDisplacement;
- __le16 DataCount;
- __le16 DataOffset;
- __le16 DataDisplacement;
- __u8 SetupCount;
- __u8 Reserved1;
- /* SetupWords[SetupCount];
- __u16 ByteCount;
- __u16 Reserved2;*/
- /* data area follows */
-} __attribute__((packed));
-
-struct smb_t2_rsp {
- struct smb_hdr hdr;
- struct trans2_resp t2_rsp;
-} __attribute__((packed));
-
-/* PathInfo/FileInfo infolevels */
-#define SMB_INFO_STANDARD 1
-#define SMB_SET_FILE_EA 2
-#define SMB_QUERY_FILE_EA_SIZE 2
-#define SMB_INFO_QUERY_EAS_FROM_LIST 3
-#define SMB_INFO_QUERY_ALL_EAS 4
-#define SMB_INFO_IS_NAME_VALID 6
-#define SMB_QUERY_FILE_BASIC_INFO 0x101
-#define SMB_QUERY_FILE_STANDARD_INFO 0x102
-#define SMB_QUERY_FILE_EA_INFO 0x103
-#define SMB_QUERY_FILE_NAME_INFO 0x104
-#define SMB_QUERY_FILE_ALLOCATION_INFO 0x105
-#define SMB_QUERY_FILE_END_OF_FILEINFO 0x106
-#define SMB_QUERY_FILE_ALL_INFO 0x107
-#define SMB_QUERY_ALT_NAME_INFO 0x108
-#define SMB_QUERY_FILE_STREAM_INFO 0x109
-#define SMB_QUERY_FILE_COMPRESSION_INFO 0x10B
-#define SMB_QUERY_FILE_UNIX_BASIC 0x200
-#define SMB_QUERY_FILE_UNIX_LINK 0x201
-#define SMB_QUERY_POSIX_ACL 0x204
-#define SMB_QUERY_XATTR 0x205 /* e.g. system EA name space */
-#define SMB_QUERY_ATTR_FLAGS 0x206 /* append,immutable etc. */
-#define SMB_QUERY_POSIX_PERMISSION 0x207
-#define SMB_QUERY_POSIX_LOCK 0x208
-/* #define SMB_POSIX_OPEN 0x209 */
-/* #define SMB_POSIX_UNLINK 0x20a */
-#define SMB_QUERY_FILE__UNIX_INFO2 0x20b
-#define SMB_QUERY_FILE_INTERNAL_INFO 0x3ee
-#define SMB_QUERY_FILE_ACCESS_INFO 0x3f0
-#define SMB_QUERY_FILE_NAME_INFO2 0x3f1 /* 0x30 bytes */
-#define SMB_QUERY_FILE_POSITION_INFO 0x3f6
-#define SMB_QUERY_FILE_MODE_INFO 0x3f8
-#define SMB_QUERY_FILE_ALGN_INFO 0x3f9
-
-
-#define SMB_SET_FILE_BASIC_INFO 0x101
-#define SMB_SET_FILE_DISPOSITION_INFO 0x102
-#define SMB_SET_FILE_ALLOCATION_INFO 0x103
-#define SMB_SET_FILE_END_OF_FILE_INFO 0x104
-#define SMB_SET_FILE_UNIX_BASIC 0x200
-#define SMB_SET_FILE_UNIX_LINK 0x201
-#define SMB_SET_FILE_UNIX_HLINK 0x203
-#define SMB_SET_POSIX_ACL 0x204
-#define SMB_SET_XATTR 0x205
-#define SMB_SET_ATTR_FLAGS 0x206 /* append, immutable etc. */
-#define SMB_SET_POSIX_LOCK 0x208
-#define SMB_POSIX_OPEN 0x209
-#define SMB_POSIX_UNLINK 0x20a
-#define SMB_SET_FILE_UNIX_INFO2 0x20b
-#define SMB_SET_FILE_BASIC_INFO2 0x3ec
-#define SMB_SET_FILE_RENAME_INFORMATION 0x3f2 /* BB check if qpathinfo too */
-#define SMB_FILE_ALL_INFO2 0x3fa
-#define SMB_SET_FILE_ALLOCATION_INFO2 0x3fb
-#define SMB_SET_FILE_END_OF_FILE_INFO2 0x3fc
-#define SMB_FILE_MOVE_CLUSTER_INFO 0x407
-#define SMB_FILE_QUOTA_INFO 0x408
-#define SMB_FILE_REPARSEPOINT_INFO 0x409
-#define SMB_FILE_MAXIMUM_INFO 0x40d
-
-/* Find File infolevels */
-#define SMB_FIND_FILE_INFO_STANDARD 0x001
-#define SMB_FIND_FILE_QUERY_EA_SIZE 0x002
-#define SMB_FIND_FILE_QUERY_EAS_FROM_LIST 0x003
-#define SMB_FIND_FILE_DIRECTORY_INFO 0x101
-#define SMB_FIND_FILE_FULL_DIRECTORY_INFO 0x102
-#define SMB_FIND_FILE_NAMES_INFO 0x103
-#define SMB_FIND_FILE_BOTH_DIRECTORY_INFO 0x104
-#define SMB_FIND_FILE_ID_FULL_DIR_INFO 0x105
-#define SMB_FIND_FILE_ID_BOTH_DIR_INFO 0x106
-#define SMB_FIND_FILE_UNIX 0x202
-
-typedef struct smb_com_transaction2_qpi_req {
- struct smb_hdr hdr; /* wct = 14+ */
- __le16 TotalParameterCount;
- __le16 TotalDataCount;
- __le16 MaxParameterCount;
- __le16 MaxDataCount;
- __u8 MaxSetupCount;
- __u8 Reserved;
- __le16 Flags;
- __le32 Timeout;
- __u16 Reserved2;
- __le16 ParameterCount;
- __le16 ParameterOffset;
- __le16 DataCount;
- __le16 DataOffset;
- __u8 SetupCount;
- __u8 Reserved3;
- __le16 SubCommand; /* one setup word */
- __le16 ByteCount;
- __u8 Pad;
- __le16 InformationLevel;
- __u32 Reserved4;
- char FileName[1];
-} __attribute__((packed)) TRANSACTION2_QPI_REQ;
-
-typedef struct smb_com_transaction2_qpi_rsp {
- struct smb_hdr hdr; /* wct = 10 + SetupCount */
- struct trans2_resp t2;
- __u16 ByteCount;
- __u16 Reserved2; /* parameter word is present for infolevels > 100 */
-} __attribute__((packed)) TRANSACTION2_QPI_RSP;
-
-typedef struct smb_com_transaction2_spi_req {
- struct smb_hdr hdr; /* wct = 15 */
- __le16 TotalParameterCount;
- __le16 TotalDataCount;
- __le16 MaxParameterCount;
- __le16 MaxDataCount;
- __u8 MaxSetupCount;
- __u8 Reserved;
- __le16 Flags;
- __le32 Timeout;
- __u16 Reserved2;
- __le16 ParameterCount;
- __le16 ParameterOffset;
- __le16 DataCount;
- __le16 DataOffset;
- __u8 SetupCount;
- __u8 Reserved3;
- __le16 SubCommand; /* one setup word */
- __le16 ByteCount;
- __u8 Pad;
- __u16 Pad1;
- __le16 InformationLevel;
- __u32 Reserved4;
- char FileName[1];
-} __attribute__((packed)) TRANSACTION2_SPI_REQ;
-
-typedef struct smb_com_transaction2_spi_rsp {
- struct smb_hdr hdr; /* wct = 10 + SetupCount */
- struct trans2_resp t2;
- __u16 ByteCount;
- __u16 Reserved2; /* parameter word is present for infolevels > 100 */
-} __attribute__((packed)) TRANSACTION2_SPI_RSP;
-
-struct set_file_rename {
- __le32 overwrite; /* 1 = overwrite dest */
- __u32 root_fid; /* zero */
- __le32 target_name_len;
- char target_name[0]; /* Must be unicode */
-} __attribute__((packed));
-
-struct smb_com_transaction2_sfi_req {
- struct smb_hdr hdr; /* wct = 15 */
- __le16 TotalParameterCount;
- __le16 TotalDataCount;
- __le16 MaxParameterCount;
- __le16 MaxDataCount;
- __u8 MaxSetupCount;
- __u8 Reserved;
- __le16 Flags;
- __le32 Timeout;
- __u16 Reserved2;
- __le16 ParameterCount;
- __le16 ParameterOffset;
- __le16 DataCount;
- __le16 DataOffset;
- __u8 SetupCount;
- __u8 Reserved3;
- __le16 SubCommand; /* one setup word */
- __le16 ByteCount;
- __u8 Pad;
- __u16 Pad1;
- __u16 Fid;
- __le16 InformationLevel;
- __u16 Reserved4;
-} __attribute__((packed));
-
-struct smb_com_transaction2_sfi_rsp {
- struct smb_hdr hdr; /* wct = 10 + SetupCount */
- struct trans2_resp t2;
- __u16 ByteCount;
- __u16 Reserved2; /* parameter word reserved -
- present for infolevels > 100 */
-} __attribute__((packed));
-
-struct smb_t2_qfi_req {
- struct smb_hdr hdr;
- struct trans2_req t2;
- __u8 Pad;
- __u16 Fid;
- __le16 InformationLevel;
-} __attribute__((packed));
-
-struct smb_t2_qfi_rsp {
- struct smb_hdr hdr; /* wct = 10 + SetupCount */
- struct trans2_resp t2;
- __u16 ByteCount;
- __u16 Reserved2; /* parameter word reserved -
- present for infolevels > 100 */
-} __attribute__((packed));
-
-/*
- * Flags on T2 FINDFIRST and FINDNEXT
- */
-#define CIFS_SEARCH_CLOSE_ALWAYS 0x0001
-#define CIFS_SEARCH_CLOSE_AT_END 0x0002
-#define CIFS_SEARCH_RETURN_RESUME 0x0004
-#define CIFS_SEARCH_CONTINUE_FROM_LAST 0x0008
-#define CIFS_SEARCH_BACKUP_SEARCH 0x0010
-
-/*
- * Size of the resume key on FINDFIRST and FINDNEXT calls
- */
-#define CIFS_SMB_RESUME_KEY_SIZE 4
-
-typedef struct smb_com_transaction2_ffirst_req {
- struct smb_hdr hdr; /* wct = 15 */
- __le16 TotalParameterCount;
- __le16 TotalDataCount;
- __le16 MaxParameterCount;
- __le16 MaxDataCount;
- __u8 MaxSetupCount;
- __u8 Reserved;
- __le16 Flags;
- __le32 Timeout;
- __u16 Reserved2;
- __le16 ParameterCount;
- __le16 ParameterOffset;
- __le16 DataCount;
- __le16 DataOffset;
- __u8 SetupCount; /* one */
- __u8 Reserved3;
- __le16 SubCommand; /* TRANS2_FIND_FIRST */
- __le16 ByteCount;
- __u8 Pad;
- __le16 SearchAttributes;
- __le16 SearchCount;
- __le16 SearchFlags;
- __le16 InformationLevel;
- __le32 SearchStorageType;
- char FileName[1];
-} __attribute__((packed)) TRANSACTION2_FFIRST_REQ;
-
-typedef struct smb_com_transaction2_ffirst_rsp {
- struct smb_hdr hdr; /* wct = 10 */
- struct trans2_resp t2;
- __u16 ByteCount;
-} __attribute__((packed)) TRANSACTION2_FFIRST_RSP;
-
-typedef struct smb_com_transaction2_ffirst_rsp_parms {
- __u16 SearchHandle;
- __le16 SearchCount;
- __le16 EndofSearch;
- __le16 EAErrorOffset;
- __le16 LastNameOffset;
-} __attribute__((packed)) T2_FFIRST_RSP_PARMS;
-
-typedef struct smb_com_transaction2_fnext_req {
- struct smb_hdr hdr; /* wct = 15 */
- __le16 TotalParameterCount;
- __le16 TotalDataCount;
- __le16 MaxParameterCount;
- __le16 MaxDataCount;
- __u8 MaxSetupCount;
- __u8 Reserved;
- __le16 Flags;
- __le32 Timeout;
- __u16 Reserved2;
- __le16 ParameterCount;
- __le16 ParameterOffset;
- __le16 DataCount;
- __le16 DataOffset;
- __u8 SetupCount; /* one */
- __u8 Reserved3;
- __le16 SubCommand; /* TRANS2_FIND_NEXT */
- __le16 ByteCount;
- __u8 Pad;
- __u16 SearchHandle;
- __le16 SearchCount;
- __le16 InformationLevel;
- __u32 ResumeKey;
- __le16 SearchFlags;
- char ResumeFileName[1];
-} __attribute__((packed)) TRANSACTION2_FNEXT_REQ;
-
-typedef struct smb_com_transaction2_fnext_rsp {
- struct smb_hdr hdr; /* wct = 10 */
- struct trans2_resp t2;
- __u16 ByteCount;
-} __attribute__((packed)) TRANSACTION2_FNEXT_RSP;
-
-typedef struct smb_com_transaction2_fnext_rsp_parms {
- __le16 SearchCount;
- __le16 EndofSearch;
- __le16 EAErrorOffset;
- __le16 LastNameOffset;
-} __attribute__((packed)) T2_FNEXT_RSP_PARMS;
-
-/* QFSInfo Levels */
-#define SMB_INFO_ALLOCATION 1
-#define SMB_INFO_VOLUME 2
-#define SMB_QUERY_FS_VOLUME_INFO 0x102
-#define SMB_QUERY_FS_SIZE_INFO 0x103
-#define SMB_QUERY_FS_DEVICE_INFO 0x104
-#define SMB_QUERY_FS_ATTRIBUTE_INFO 0x105
-#define SMB_QUERY_CIFS_UNIX_INFO 0x200
-#define SMB_QUERY_POSIX_FS_INFO 0x201
-#define SMB_QUERY_POSIX_WHO_AM_I 0x202
-#define SMB_REQUEST_TRANSPORT_ENCRYPTION 0x203
-#define SMB_QUERY_FS_PROXY 0x204 /* WAFS enabled. Returns structure
- FILE_SYSTEM__UNIX_INFO to tell
- whether new NTIOCTL available
- (0xACE) for WAN friendly SMB
- operations to be carried */
-#define SMB_QUERY_LABEL_INFO 0x3ea
-#define SMB_QUERY_FS_QUOTA_INFO 0x3ee
-#define SMB_QUERY_FS_FULL_SIZE_INFO 0x3ef
-#define SMB_QUERY_OBJECTID_INFO 0x3f0
-
-typedef struct smb_com_transaction2_qfsi_req {
- struct smb_hdr hdr; /* wct = 14+ */
- __le16 TotalParameterCount;
- __le16 TotalDataCount;
- __le16 MaxParameterCount;
- __le16 MaxDataCount;
- __u8 MaxSetupCount;
- __u8 Reserved;
- __le16 Flags;
- __le32 Timeout;
- __u16 Reserved2;
- __le16 ParameterCount;
- __le16 ParameterOffset;
- __le16 DataCount;
- __le16 DataOffset;
- __u8 SetupCount;
- __u8 Reserved3;
- __le16 SubCommand; /* one setup word */
- __le16 ByteCount;
- __u8 Pad;
- __le16 InformationLevel;
-} __attribute__((packed)) TRANSACTION2_QFSI_REQ;
-
-typedef struct smb_com_transaction_qfsi_rsp {
- struct smb_hdr hdr; /* wct = 10 + SetupCount */
- struct trans2_resp t2;
- __u16 ByteCount;
- __u8 Pad; /* may be three bytes? *//* followed by data area */
-} __attribute__((packed)) TRANSACTION2_QFSI_RSP;
-
-typedef struct whoami_rsp_data { /* Query level 0x202 */
- __u32 flags; /* 0 = Authenticated user 1 = GUEST */
- __u32 mask; /* which flags bits server understands ie 0x0001 */
- __u64 unix_user_id;
- __u64 unix_user_gid;
- __u32 number_of_supplementary_gids; /* may be zero */
- __u32 number_of_sids; /* may be zero */
- __u32 length_of_sid_array; /* in bytes - may be zero */
- __u32 pad; /* reserved - MBZ */
- /* __u64 gid_array[0]; */ /* may be empty */
- /* __u8 * psid_list */ /* may be empty */
-} __attribute__((packed)) WHOAMI_RSP_DATA;
-
-/* SETFSInfo Levels */
-#define SMB_SET_CIFS_UNIX_INFO 0x200
-/* level 0x203 is defined above in list of QFS info levels */
-/* #define SMB_REQUEST_TRANSPORT_ENCRYPTION 0x203 */
-
-/* Level 0x200 request structure follows */
-typedef struct smb_com_transaction2_setfsi_req {
- struct smb_hdr hdr; /* wct = 15 */
- __le16 TotalParameterCount;
- __le16 TotalDataCount;
- __le16 MaxParameterCount;
- __le16 MaxDataCount;
- __u8 MaxSetupCount;
- __u8 Reserved;
- __le16 Flags;
- __le32 Timeout;
- __u16 Reserved2;
- __le16 ParameterCount; /* 4 */
- __le16 ParameterOffset;
- __le16 DataCount; /* 12 */
- __le16 DataOffset;
- __u8 SetupCount; /* one */
- __u8 Reserved3;
- __le16 SubCommand; /* TRANS2_SET_FS_INFORMATION */
- __le16 ByteCount;
- __u8 Pad;
- __u16 FileNum; /* Parameters start. */
- __le16 InformationLevel;/* Parameters end. */
- __le16 ClientUnixMajor; /* Data start. */
- __le16 ClientUnixMinor;
- __le64 ClientUnixCap; /* Data end */
-} __attribute__((packed)) TRANSACTION2_SETFSI_REQ;
-
-/* level 0x203 request structure follows */
-typedef struct smb_com_transaction2_setfs_enc_req {
- struct smb_hdr hdr; /* wct = 15 */
- __le16 TotalParameterCount;
- __le16 TotalDataCount;
- __le16 MaxParameterCount;
- __le16 MaxDataCount;
- __u8 MaxSetupCount;
- __u8 Reserved;
- __le16 Flags;
- __le32 Timeout;
- __u16 Reserved2;
- __le16 ParameterCount; /* 4 */
- __le16 ParameterOffset;
- __le16 DataCount; /* 12 */
- __le16 DataOffset;
- __u8 SetupCount; /* one */
- __u8 Reserved3;
- __le16 SubCommand; /* TRANS2_SET_FS_INFORMATION */
- __le16 ByteCount;
- __u8 Pad;
- __u16 Reserved4; /* Parameters start. */
- __le16 InformationLevel;/* Parameters end. */
- /* NTLMSSP Blob, Data start. */
-} __attribute__((packed)) TRANSACTION2_SETFSI_ENC_REQ;
-
-/* response for setfsinfo levels 0x200 and 0x203 */
-typedef struct smb_com_transaction2_setfsi_rsp {
- struct smb_hdr hdr; /* wct = 10 */
- struct trans2_resp t2;
- __u16 ByteCount;
-} __attribute__((packed)) TRANSACTION2_SETFSI_RSP;
-
-typedef struct smb_com_transaction2_get_dfs_refer_req {
- struct smb_hdr hdr; /* wct = 15 */
- __le16 TotalParameterCount;
- __le16 TotalDataCount;
- __le16 MaxParameterCount;
- __le16 MaxDataCount;
- __u8 MaxSetupCount;
- __u8 Reserved;
- __le16 Flags;
- __le32 Timeout;
- __u16 Reserved2;
- __le16 ParameterCount;
- __le16 ParameterOffset;
- __le16 DataCount;
- __le16 DataOffset;
- __u8 SetupCount;
- __u8 Reserved3;
- __le16 SubCommand; /* one setup word */
- __le16 ByteCount;
- __u8 Pad[3]; /* Win2K has sent 0x0F01 (max response length
- perhaps?) followed by one byte pad - doesn't
- seem to matter though */
- __le16 MaxReferralLevel;
- char RequestFileName[1];
-} __attribute__((packed)) TRANSACTION2_GET_DFS_REFER_REQ;
-
-#define DFS_VERSION cpu_to_le16(0x0003)
-
-/* DFS server target type */
-#define DFS_TYPE_LINK 0x0000 /* also for sysvol targets */
-#define DFS_TYPE_ROOT 0x0001
-
-/* Referral Entry Flags */
-#define DFS_NAME_LIST_REF 0x0200 /* set for domain or DC referral responses */
-#define DFS_TARGET_SET_BOUNDARY 0x0400 /* only valid with version 4 dfs req */
-
-typedef struct dfs_referral_level_3 { /* version 4 is same, + one flag bit */
- __le16 VersionNumber; /* must be 3 or 4 */
- __le16 Size;
- __le16 ServerType; /* 0x0001 = root targets; 0x0000 = link targets */
- __le16 ReferralEntryFlags;
- __le32 TimeToLive;
- __le16 DfsPathOffset;
- __le16 DfsAlternatePathOffset;
- __le16 NetworkAddressOffset; /* offset of the link target */
- __u8 ServiceSiteGuid[16]; /* MBZ, ignored */
-} __attribute__((packed)) REFERRAL3;
-
-typedef struct smb_com_transaction_get_dfs_refer_rsp {
- struct smb_hdr hdr; /* wct = 10 */
- struct trans2_resp t2;
- __u16 ByteCount;
- __u8 Pad;
- __le16 PathConsumed;
- __le16 NumberOfReferrals;
- __le32 DFSFlags;
- REFERRAL3 referrals[1]; /* array of level 3 dfs_referral structures */
- /* followed by the strings pointed to by the referral structures */
-} __attribute__((packed)) TRANSACTION2_GET_DFS_REFER_RSP;
-
-/* DFS Flags */
-#define DFSREF_REFERRAL_SERVER 0x00000001 /* all targets are DFS roots */
-#define DFSREF_STORAGE_SERVER 0x00000002 /* no further ref requests needed */
-#define DFSREF_TARGET_FAILBACK 0x00000004 /* only for DFS referral version 4 */
-
-/*
- ************************************************************************
- * All structs for everything above the SMB PDUs themselves
- * (such as the T2 level specific data) go here
- ************************************************************************
- */
-
-/*
- * Information on a server
- */
-
-struct serverInfo {
- char name[16];
- unsigned char versionMajor;
- unsigned char versionMinor;
- unsigned long type;
- unsigned int commentOffset;
-} __attribute__((packed));
-
-/*
- * The following structure is the format of the data returned on a NetShareEnum
- * with level "90" (x5A)
- */
-
-struct shareInfo {
- char shareName[13];
- char pad;
- unsigned short type;
- unsigned int commentOffset;
-} __attribute__((packed));
-
-struct aliasInfo {
- char aliasName[9];
- char pad;
- unsigned int commentOffset;
- unsigned char type[2];
-} __attribute__((packed));
-
-struct aliasInfo92 {
- int aliasNameOffset;
- int serverNameOffset;
- int shareNameOffset;
-} __attribute__((packed));
-
-typedef struct {
- __le64 TotalAllocationUnits;
- __le64 FreeAllocationUnits;
- __le32 SectorsPerAllocationUnit;
- __le32 BytesPerSector;
-} __attribute__((packed)) FILE_SYSTEM_INFO; /* size info, level 0x103 */
-
-typedef struct {
- __le32 fsid;
- __le32 SectorsPerAllocationUnit;
- __le32 TotalAllocationUnits;
- __le32 FreeAllocationUnits;
- __le16 BytesPerSector;
-} __attribute__((packed)) FILE_SYSTEM_ALLOC_INFO;
-
-typedef struct {
- __le16 MajorVersionNumber;
- __le16 MinorVersionNumber;
- __le64 Capability;
-} __attribute__((packed)) FILE_SYSTEM_UNIX_INFO; /* Unix extension level 0x200*/
-
-/* Version numbers for CIFS UNIX major and minor. */
-#define CIFS_UNIX_MAJOR_VERSION 1
-#define CIFS_UNIX_MINOR_VERSION 0
-
-/* Linux/Unix extensions capability flags */
-#define CIFS_UNIX_FCNTL_CAP 0x00000001 /* support for fcntl locks */
-#define CIFS_UNIX_POSIX_ACL_CAP 0x00000002 /* support getfacl/setfacl */
-#define CIFS_UNIX_XATTR_CAP 0x00000004 /* support new namespace */
-#define CIFS_UNIX_EXTATTR_CAP 0x00000008 /* support chattr/chflag */
-#define CIFS_UNIX_POSIX_PATHNAMES_CAP 0x00000010 /* Allow POSIX path chars */
-#define CIFS_UNIX_POSIX_PATH_OPS_CAP 0x00000020 /* Allow new POSIX path based
- calls including posix open
- and posix unlink */
-#define CIFS_UNIX_LARGE_READ_CAP 0x00000040 /* support reads >128K (up
- to 0xFFFF00 */
-#define CIFS_UNIX_LARGE_WRITE_CAP 0x00000080
-#define CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP 0x00000100 /* can do SPNEGO crypt */
-#define CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP 0x00000200 /* must do */
-#define CIFS_UNIX_PROXY_CAP 0x00000400 /* Proxy cap: 0xACE ioctl and
- QFS PROXY call */
-#ifdef CONFIG_CIFS_POSIX
-/* presumably don't need the 0x20 POSIX_PATH_OPS_CAP since we never send
- LockingX instead of posix locking call on unix sess (and we do not expect
- LockingX to use different (ie Windows) semantics than posix locking on
- the same session (if WINE needs to do this later, we can add this cap
- back in later */
-/* #define CIFS_UNIX_CAP_MASK 0x000000fb */
-#define CIFS_UNIX_CAP_MASK 0x000003db
-#else
-#define CIFS_UNIX_CAP_MASK 0x00000013
-#endif /* CONFIG_CIFS_POSIX */
-
-
-#define CIFS_POSIX_EXTENSIONS 0x00000010 /* support for new QFSInfo */
-
-typedef struct {
- /* For undefined recommended transfer size return -1 in that field */
- __le32 OptimalTransferSize; /* bsize on some os, iosize on other os */
- __le32 BlockSize;
- /* The next three fields are in terms of the block size.
- (above). If block size is unknown, 4096 would be a
- reasonable block size for a server to report.
- Note that returning the blocks/blocksavail removes need
- to make a second call (to QFSInfo level 0x103 to get this info.
- UserBlockAvail is typically less than or equal to BlocksAvail,
- if no distinction is made return the same value in each */
- __le64 TotalBlocks;
- __le64 BlocksAvail; /* bfree */
- __le64 UserBlocksAvail; /* bavail */
- /* For undefined Node fields or FSID return -1 */
- __le64 TotalFileNodes;
- __le64 FreeFileNodes;
- __le64 FileSysIdentifier; /* fsid */
- /* NB Namelen comes from FILE_SYSTEM_ATTRIBUTE_INFO call */
- /* NB flags can come from FILE_SYSTEM_DEVICE_INFO call */
-} __attribute__((packed)) FILE_SYSTEM_POSIX_INFO;
-
-/* DeviceType Flags */
-#define FILE_DEVICE_CD_ROM 0x00000002
-#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003
-#define FILE_DEVICE_DFS 0x00000006
-#define FILE_DEVICE_DISK 0x00000007
-#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008
-#define FILE_DEVICE_FILE_SYSTEM 0x00000009
-#define FILE_DEVICE_NAMED_PIPE 0x00000011
-#define FILE_DEVICE_NETWORK 0x00000012
-#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014
-#define FILE_DEVICE_NULL 0x00000015
-#define FILE_DEVICE_PARALLEL_PORT 0x00000016
-#define FILE_DEVICE_PRINTER 0x00000018
-#define FILE_DEVICE_SERIAL_PORT 0x0000001b
-#define FILE_DEVICE_STREAMS 0x0000001e
-#define FILE_DEVICE_TAPE 0x0000001f
-#define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020
-#define FILE_DEVICE_VIRTUAL_DISK 0x00000024
-#define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028
-
-typedef struct {
- __le32 DeviceType;
- __le32 DeviceCharacteristics;
-} __attribute__((packed)) FILE_SYSTEM_DEVICE_INFO; /* device info level 0x104 */
-
-typedef struct {
- __le32 Attributes;
- __le32 MaxPathNameComponentLength;
- __le32 FileSystemNameLen;
- char FileSystemName[52]; /* do not have to save this - get subset? */
-} __attribute__((packed)) FILE_SYSTEM_ATTRIBUTE_INFO;
-
-/******************************************************************************/
-/* QueryFileInfo/QueryPathinfo (also for SetPath/SetFile) data buffer formats */
-/******************************************************************************/
-typedef struct { /* data block encoding of response to level 263 QPathInfo */
- __le64 CreationTime;
- __le64 LastAccessTime;
- __le64 LastWriteTime;
- __le64 ChangeTime;
- __le32 Attributes;
- __u32 Pad1;
- __le64 AllocationSize;
- __le64 EndOfFile; /* size ie offset to first free byte in file */
- __le32 NumberOfLinks; /* hard links */
- __u8 DeletePending;
- __u8 Directory;
- __u16 Pad2;
- __u64 IndexNumber;
- __le32 EASize;
- __le32 AccessFlags;
- __u64 IndexNumber1;
- __le64 CurrentByteOffset;
- __le32 Mode;
- __le32 AlignmentRequirement;
- __le32 FileNameLength;
- char FileName[1];
-} __attribute__((packed)) FILE_ALL_INFO; /* level 0x107 QPathInfo */
-
-/* defines for enumerating possible values of the Unix type field below */
-#define UNIX_FILE 0
-#define UNIX_DIR 1
-#define UNIX_SYMLINK 2
-#define UNIX_CHARDEV 3
-#define UNIX_BLOCKDEV 4
-#define UNIX_FIFO 5
-#define UNIX_SOCKET 6
-typedef struct {
- __le64 EndOfFile;
- __le64 NumOfBytes;
- __le64 LastStatusChange; /*SNIA specs DCE time for the 3 time fields */
- __le64 LastAccessTime;
- __le64 LastModificationTime;
- __le64 Uid;
- __le64 Gid;
- __le32 Type;
- __le64 DevMajor;
- __le64 DevMinor;
- __le64 UniqueId;
- __le64 Permissions;
- __le64 Nlinks;
-} __attribute__((packed)) FILE_UNIX_BASIC_INFO; /* level 0x200 QPathInfo */
-
-typedef struct {
- char LinkDest[1];
-} __attribute__((packed)) FILE_UNIX_LINK_INFO; /* level 0x201 QPathInfo */
-
-/* The following three structures are needed only for
- setting time to NT4 and some older servers via
- the primitive DOS time format */
-typedef struct {
- __u16 Day:5;
- __u16 Month:4;
- __u16 Year:7;
-} __attribute__((packed)) SMB_DATE;
-
-typedef struct {
- __u16 TwoSeconds:5;
- __u16 Minutes:6;
- __u16 Hours:5;
-} __attribute__((packed)) SMB_TIME;
-
-typedef struct {
- __le16 CreationDate; /* SMB Date see above */
- __le16 CreationTime; /* SMB Time */
- __le16 LastAccessDate;
- __le16 LastAccessTime;
- __le16 LastWriteDate;
- __le16 LastWriteTime;
- __le32 DataSize; /* File Size (EOF) */
- __le32 AllocationSize;
- __le16 Attributes; /* verify not u32 */
- __le32 EASize;
-} __attribute__((packed)) FILE_INFO_STANDARD; /* level 1 SetPath/FileInfo */
-
-typedef struct {
- __le64 CreationTime;
- __le64 LastAccessTime;
- __le64 LastWriteTime;
- __le64 ChangeTime;
- __le32 Attributes;
- __u32 Pad;
-} __attribute__((packed)) FILE_BASIC_INFO; /* size info, level 0x101 */
-
-struct file_allocation_info {
- __le64 AllocationSize; /* Note old Samba srvr rounds this up too much */
-} __attribute__((packed)); /* size used on disk, for level 0x103 for set,
- 0x105 for query */
-
-struct file_end_of_file_info {
- __le64 FileSize; /* offset to end of file */
-} __attribute__((packed)); /* size info, level 0x104 for set, 0x106 for query */
-
-struct file_alt_name_info {
- __u8 alt_name[1];
-} __attribute__((packed)); /* level 0x0108 */
-
-struct file_stream_info {
- __le32 number_of_streams; /* BB check sizes and verify location */
- /* followed by info on streams themselves
- u64 size;
- u64 allocation_size
- stream info */
-}; /* level 0x109 */
-
-struct file_compression_info {
- __le64 compressed_size;
- __le16 format;
- __u8 unit_shift;
- __u8 ch_shift;
- __u8 cl_shift;
- __u8 pad[3];
-} __attribute__((packed)); /* level 0x10b */
-
-/* POSIX ACL set/query path info structures */
-#define CIFS_ACL_VERSION 1
-struct cifs_posix_ace { /* access control entry (ACE) */
- __u8 cifs_e_tag;
- __u8 cifs_e_perm;
- __le64 cifs_uid; /* or gid */
-} __attribute__((packed));
-
-struct cifs_posix_acl { /* access conrol list (ACL) */
- __le16 version;
- __le16 access_entry_count; /* access ACL - count of entries */
- __le16 default_entry_count; /* default ACL - count of entries */
- struct cifs_posix_ace ace_array[0];
- /* followed by
- struct cifs_posix_ace default_ace_arraay[] */
-} __attribute__((packed)); /* level 0x204 */
-
-/* types of access control entries already defined in posix_acl.h */
-/* #define CIFS_POSIX_ACL_USER_OBJ 0x01
-#define CIFS_POSIX_ACL_USER 0x02
-#define CIFS_POSIX_ACL_GROUP_OBJ 0x04
-#define CIFS_POSIX_ACL_GROUP 0x08
-#define CIFS_POSIX_ACL_MASK 0x10
-#define CIFS_POSIX_ACL_OTHER 0x20 */
-
-/* types of perms */
-/* #define CIFS_POSIX_ACL_EXECUTE 0x01
-#define CIFS_POSIX_ACL_WRITE 0x02
-#define CIFS_POSIX_ACL_READ 0x04 */
-
-/* end of POSIX ACL definitions */
-
-/* POSIX Open Flags */
-#define SMB_O_RDONLY 0x1
-#define SMB_O_WRONLY 0x2
-#define SMB_O_RDWR 0x4
-#define SMB_O_CREAT 0x10
-#define SMB_O_EXCL 0x20
-#define SMB_O_TRUNC 0x40
-#define SMB_O_APPEND 0x80
-#define SMB_O_SYNC 0x100
-#define SMB_O_DIRECTORY 0x200
-#define SMB_O_NOFOLLOW 0x400
-#define SMB_O_DIRECT 0x800
-
-typedef struct {
- __le32 OpenFlags; /* same as NT CreateX */
- __le32 PosixOpenFlags;
- __le64 Permissions;
- __le16 Level; /* reply level requested (see QPathInfo levels) */
-} __attribute__((packed)) OPEN_PSX_REQ; /* level 0x209 SetPathInfo data */
-
-typedef struct {
- __le16 OplockFlags;
- __u16 Fid;
- __le32 CreateAction;
- __le16 ReturnedLevel;
- __le16 Pad;
- /* struct following varies based on requested level */
-} __attribute__((packed)) OPEN_PSX_RSP; /* level 0x209 SetPathInfo data */
-
-#define SMB_POSIX_UNLINK_FILE_TARGET 0
-#define SMB_POSIX_UNLINK_DIRECTORY_TARGET 1
-
-struct unlink_psx_rq { /* level 0x20a SetPathInfo */
- __le16 type;
-} __attribute__((packed));
-
-struct file_internal_info {
- __le64 UniqueId; /* inode number */
-} __attribute__((packed)); /* level 0x3ee */
-
-struct file_mode_info {
- __le32 Mode;
-} __attribute__((packed)); /* level 0x3f8 */
-
-struct file_attrib_tag {
- __le32 Attribute;
- __le32 ReparseTag;
-} __attribute__((packed)); /* level 0x40b */
-
-
-/********************************************************/
-/* FindFirst/FindNext transact2 data buffer formats */
-/********************************************************/
-
-typedef struct {
- __le32 NextEntryOffset;
- __u32 ResumeKey; /* as with FileIndex - no need to convert */
- FILE_UNIX_BASIC_INFO basic;
- char FileName[1];
-} __attribute__((packed)) FILE_UNIX_INFO; /* level 0x202 */
-
-typedef struct {
- __le32 NextEntryOffset;
- __u32 FileIndex;
- __le64 CreationTime;
- __le64 LastAccessTime;
- __le64 LastWriteTime;
- __le64 ChangeTime;
- __le64 EndOfFile;
- __le64 AllocationSize;
- __le32 ExtFileAttributes;
- __le32 FileNameLength;
- char FileName[1];
-} __attribute__((packed)) FILE_DIRECTORY_INFO; /* level 0x101 FF resp data */
-
-typedef struct {
- __le32 NextEntryOffset;
- __u32 FileIndex;
- __le64 CreationTime;
- __le64 LastAccessTime;
- __le64 LastWriteTime;
- __le64 ChangeTime;
- __le64 EndOfFile;
- __le64 AllocationSize;
- __le32 ExtFileAttributes;
- __le32 FileNameLength;
- __le32 EaSize; /* length of the xattrs */
- char FileName[1];
-} __attribute__((packed)) FILE_FULL_DIRECTORY_INFO; /* level 0x102 rsp data */
-
-typedef struct {
- __le32 NextEntryOffset;
- __u32 FileIndex;
- __le64 CreationTime;
- __le64 LastAccessTime;
- __le64 LastWriteTime;
- __le64 ChangeTime;
- __le64 EndOfFile;
- __le64 AllocationSize;
- __le32 ExtFileAttributes;
- __le32 FileNameLength;
- __le32 EaSize; /* EA size */
- __le32 Reserved;
- __le64 UniqueId; /* inode num - le since Samba puts ino in low 32 bit*/
- char FileName[1];
-} __attribute__((packed)) SEARCH_ID_FULL_DIR_INFO; /* level 0x105 FF rsp data */
-
-typedef struct {
- __le32 NextEntryOffset;
- __u32 FileIndex;
- __le64 CreationTime;
- __le64 LastAccessTime;
- __le64 LastWriteTime;
- __le64 ChangeTime;
- __le64 EndOfFile;
- __le64 AllocationSize;
- __le32 ExtFileAttributes;
- __le32 FileNameLength;
- __le32 EaSize; /* length of the xattrs */
- __u8 ShortNameLength;
- __u8 Reserved;
- __u8 ShortName[12];
- char FileName[1];
-} __attribute__((packed)) FILE_BOTH_DIRECTORY_INFO; /* level 0x104 FFrsp data */
-
-typedef struct {
- __u32 ResumeKey;
- __le16 CreationDate; /* SMB Date */
- __le16 CreationTime; /* SMB Time */
- __le16 LastAccessDate;
- __le16 LastAccessTime;
- __le16 LastWriteDate;
- __le16 LastWriteTime;
- __le32 DataSize; /* File Size (EOF) */
- __le32 AllocationSize;
- __le16 Attributes; /* verify not u32 */
- __u8 FileNameLength;
- char FileName[1];
-} __attribute__((packed)) FIND_FILE_STANDARD_INFO; /* level 0x1 FF resp data */
-
-
-struct win_dev {
- unsigned char type[8]; /* IntxCHR or IntxBLK */
- __le64 major;
- __le64 minor;
-} __attribute__((packed));
-
-struct gea {
- unsigned char name_len;
- char name[1];
-} __attribute__((packed));
-
-struct gealist {
- unsigned long list_len;
- struct gea list[1];
-} __attribute__((packed));
-
-struct fea {
- unsigned char EA_flags;
- __u8 name_len;
- __le16 value_len;
- char name[1];
- /* optionally followed by value */
-} __attribute__((packed));
-/* flags for _FEA.fEA */
-#define FEA_NEEDEA 0x80 /* need EA bit */
-
-struct fealist {
- __le32 list_len;
- struct fea list[1];
-} __attribute__((packed));
-
-/* used to hold an arbitrary blob of data */
-struct data_blob {
- __u8 *data;
- size_t length;
- void (*free) (struct data_blob *data_blob);
-} __attribute__((packed));
-
-
-#ifdef CONFIG_CIFS_POSIX
-/*
- For better POSIX semantics from Linux client, (even better
- than the existing CIFS Unix Extensions) we need updated PDUs for:
-
- 1) PosixCreateX - to set and return the mode, inode#, device info and
- perhaps add a CreateDevice - to create Pipes and other special .inodes
- Also note POSIX open flags
- 2) Close - to return the last write time to do cache across close
- more safely
- 3) FindFirst return unique inode number - what about resume key, two
- forms short (matches readdir) and full (enough info to cache inodes)
- 4) Mkdir - set mode
-
- And under consideration:
- 5) FindClose2 (return nanosecond timestamp ??)
- 6) Use nanosecond timestamps throughout all time fields if
- corresponding attribute flag is set
- 7) sendfile - handle based copy
-
- what about fixing 64 bit alignment
-
- There are also various legacy SMB/CIFS requests used as is
-
- From existing Lanman and NTLM dialects:
- --------------------------------------
- NEGOTIATE
- SESSION_SETUP_ANDX (BB which?)
- TREE_CONNECT_ANDX (BB which wct?)
- TREE_DISCONNECT (BB add volume timestamp on response)
- LOGOFF_ANDX
- DELETE (note delete open file behavior)
- DELETE_DIRECTORY
- READ_AND_X
- WRITE_AND_X
- LOCKING_AND_X (note posix lock semantics)
- RENAME (note rename across dirs and open file rename posix behaviors)
- NT_RENAME (for hardlinks) Is this good enough for all features?
- FIND_CLOSE2
- TRANSACTION2 (18 cases)
- SMB_SET_FILE_END_OF_FILE_INFO2 SMB_SET_PATH_END_OF_FILE_INFO2
- (BB verify that never need to set allocation size)
- SMB_SET_FILE_BASIC_INFO2 (setting times - BB can it be done via
- Unix ext?)
-
- COPY (note support for copy across directories) - FUTURE, OPTIONAL
- setting/getting OS/2 EAs - FUTURE (BB can this handle
- setting Linux xattrs perfectly) - OPTIONAL
- dnotify - FUTURE, OPTIONAL
- quota - FUTURE, OPTIONAL
-
- Note that various requests implemented for NT interop such as
- NT_TRANSACT (IOCTL) QueryReparseInfo
- are unneeded to servers compliant with the CIFS POSIX extensions
-
- From CIFS Unix Extensions:
- -------------------------
- T2 SET_PATH_INFO (SMB_SET_FILE_UNIX_LINK) for symlinks
- T2 SET_PATH_INFO (SMB_SET_FILE_BASIC_INFO2)
- T2 QUERY_PATH_INFO (SMB_QUERY_FILE_UNIX_LINK)
- T2 QUERY_PATH_INFO (SMB_QUERY_FILE_UNIX_BASIC) BB check for missing
- inode fields
- Actually a need QUERY_FILE_UNIX_INFO
- since has inode num
- BB what about a) blksize/blkbits/blocks
- b) i_version
- c) i_rdev
- d) notify mask?
- e) generation
- f) size_seqcount
- T2 FIND_FIRST/FIND_NEXT FIND_FILE_UNIX
- TRANS2_GET_DFS_REFERRAL - OPTIONAL but recommended
- T2_QFS_INFO QueryDevice/AttributeInfo - OPTIONAL
- */
-
-/* xsymlink is a symlink format (used by MacOS) that can be used
- to save symlink info in a regular file when
- mounted to operating systems that do not
- support the cifs Unix extensions or EAs (for xattr
- based symlinks). For such a file to be recognized
- as containing symlink data:
-
- 1) file size must be 1067,
- 2) signature must begin file data,
- 3) length field must be set to ASCII representation
- of a number which is less than or equal to 1024,
- 4) md5 must match that of the path data */
-
-struct xsymlink {
- /* 1067 bytes */
- char signature[4]; /* XSym */ /* not null terminated */
- char cr0; /* \n */
-/* ASCII representation of length (4 bytes decimal) terminated by \n not null */
- char length[4];
- char cr1; /* \n */
-/* md5 of valid subset of path ie path[0] through path[length-1] */
- __u8 md5[32];
- char cr2; /* \n */
-/* if room left, then end with \n then 0x20s by convention but not required */
- char path[1024];
-} __attribute__((packed));
-
-typedef struct file_xattr_info {
- /* BB do we need another field for flags? BB */
- __u32 xattr_name_len;
- __u32 xattr_value_len;
- char xattr_name[0];
- /* followed by xattr_value[xattr_value_len], no pad */
-} __attribute__((packed)) FILE_XATTR_INFO; /* extended attribute info
- level 0x205 */
-
-
-/* flags for chattr command */
-#define EXT_SECURE_DELETE 0x00000001 /* EXT3_SECRM_FL */
-#define EXT_ENABLE_UNDELETE 0x00000002 /* EXT3_UNRM_FL */
-/* Reserved for compress file 0x4 */
-#define EXT_SYNCHRONOUS 0x00000008 /* EXT3_SYNC_FL */
-#define EXT_IMMUTABLE_FL 0x00000010 /* EXT3_IMMUTABLE_FL */
-#define EXT_OPEN_APPEND_ONLY 0x00000020 /* EXT3_APPEND_FL */
-#define EXT_DO_NOT_BACKUP 0x00000040 /* EXT3_NODUMP_FL */
-#define EXT_NO_UPDATE_ATIME 0x00000080 /* EXT3_NOATIME_FL */
-/* 0x100 through 0x800 reserved for compression flags and are GET-ONLY */
-#define EXT_HASH_TREE_INDEXED_DIR 0x00001000 /* GET-ONLY EXT3_INDEX_FL */
-/* 0x2000 reserved for IMAGIC_FL */
-#define EXT_JOURNAL_THIS_FILE 0x00004000 /* GET-ONLY EXT3_JOURNAL_DATA_FL */
-/* 0x8000 reserved for EXT3_NOTAIL_FL */
-#define EXT_SYNCHRONOUS_DIR 0x00010000 /* EXT3_DIRSYNC_FL */
-#define EXT_TOPDIR 0x00020000 /* EXT3_TOPDIR_FL */
-
-#define EXT_SET_MASK 0x000300FF
-#define EXT_GET_MASK 0x0003DFFF
-
-typedef struct file_chattr_info {
- __le64 mask; /* list of all possible attribute bits */
- __le64 mode; /* list of actual attribute bits on this inode */
-} __attribute__((packed)) FILE_CHATTR_INFO; /* ext attributes
- (chattr, chflags) level 0x206 */
-#endif /* POSIX */
-#endif /* _CIFSPDU_H */
diff --git a/ANDROID_3.4.5/fs/cifs/cifsproto.h b/ANDROID_3.4.5/fs/cifs/cifsproto.h
deleted file mode 100644
index 97f5d037..00000000
--- a/ANDROID_3.4.5/fs/cifs/cifsproto.h
+++ /dev/null
@@ -1,509 +0,0 @@
-/*
- * fs/cifs/cifsproto.h
- *
- * Copyright (c) International Business Machines Corp., 2002,2008
- * Author(s): Steve French (sfrench@us.ibm.com)
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef _CIFSPROTO_H
-#define _CIFSPROTO_H
-#include <linux/nls.h>
-
-struct statfs;
-struct smb_vol;
-
-/*
- *****************************************************************
- * All Prototypes
- *****************************************************************
- */
-
-extern struct smb_hdr *cifs_buf_get(void);
-extern void cifs_buf_release(void *);
-extern struct smb_hdr *cifs_small_buf_get(void);
-extern void cifs_small_buf_release(void *);
-extern int smb_send(struct TCP_Server_Info *, struct smb_hdr *,
- unsigned int /* length */);
-extern unsigned int _GetXid(void);
-extern void _FreeXid(unsigned int);
-#define GetXid() \
-({ \
- int __xid = (int)_GetXid(); \
- cFYI(1, "CIFS VFS: in %s as Xid: %d with uid: %d", \
- __func__, __xid, current_fsuid()); \
- __xid; \
-})
-
-#define FreeXid(curr_xid) \
-do { \
- _FreeXid(curr_xid); \
- cFYI(1, "CIFS VFS: leaving %s (xid = %d) rc = %d", \
- __func__, curr_xid, (int)rc); \
-} while (0)
-extern int init_cifs_idmap(void);
-extern void exit_cifs_idmap(void);
-extern void cifs_destroy_idmaptrees(void);
-extern char *build_path_from_dentry(struct dentry *);
-extern char *cifs_build_path_to_root(struct smb_vol *vol,
- struct cifs_sb_info *cifs_sb,
- struct cifs_tcon *tcon);
-extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
-extern char *cifs_compose_mount_options(const char *sb_mountdata,
- const char *fullpath, const struct dfs_info3_param *ref,
- char **devname);
-/* extern void renew_parental_timestamps(struct dentry *direntry);*/
-extern struct mid_q_entry *AllocMidQEntry(const struct smb_hdr *smb_buffer,
- struct TCP_Server_Info *server);
-extern void DeleteMidQEntry(struct mid_q_entry *midEntry);
-extern int cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov,
- unsigned int nvec, mid_receive_t *receive,
- mid_callback_t *callback, void *cbdata,
- bool ignore_pend);
-extern int SendReceive(const unsigned int /* xid */ , struct cifs_ses *,
- struct smb_hdr * /* input */ ,
- struct smb_hdr * /* out */ ,
- int * /* bytes returned */ , const int long_op);
-extern int SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses,
- char *in_buf, int flags);
-extern int cifs_check_receive(struct mid_q_entry *mid,
- struct TCP_Server_Info *server, bool log_error);
-extern int SendReceive2(const unsigned int /* xid */ , struct cifs_ses *,
- struct kvec *, int /* nvec to send */,
- int * /* type of buf returned */ , const int flags);
-extern int SendReceiveBlockingLock(const unsigned int xid,
- struct cifs_tcon *ptcon,
- struct smb_hdr *in_buf ,
- struct smb_hdr *out_buf,
- int *bytes_returned);
-extern void cifs_add_credits(struct TCP_Server_Info *server,
- const unsigned int add);
-extern void cifs_set_credits(struct TCP_Server_Info *server, const int val);
-extern int checkSMB(char *buf, unsigned int length);
-extern bool is_valid_oplock_break(char *, struct TCP_Server_Info *);
-extern bool backup_cred(struct cifs_sb_info *);
-extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof);
-extern void cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
- unsigned int bytes_written);
-extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool);
-extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool);
-extern unsigned int smbCalcSize(struct smb_hdr *ptr);
-extern int decode_negTokenInit(unsigned char *security_blob, int length,
- struct TCP_Server_Info *server);
-extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len);
-extern int cifs_set_port(struct sockaddr *addr, const unsigned short int port);
-extern int cifs_fill_sockaddr(struct sockaddr *dst, const char *src, int len,
- const unsigned short int port);
-extern int map_smb_to_linux_error(char *buf, bool logErr);
-extern void header_assemble(struct smb_hdr *, char /* command */ ,
- const struct cifs_tcon *, int /* length of
- fixed section (word count) in two byte units */);
-extern int small_smb_init_no_tc(const int smb_cmd, const int wct,
- struct cifs_ses *ses,
- void **request_buf);
-extern int CIFS_SessSetup(unsigned int xid, struct cifs_ses *ses,
- const struct nls_table *nls_cp);
-extern __u64 GetNextMid(struct TCP_Server_Info *server);
-extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601);
-extern u64 cifs_UnixTimeToNT(struct timespec);
-extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time,
- int offset);
-extern void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock);
-
-extern struct cifsFileInfo *cifs_new_fileinfo(__u16 fileHandle,
- struct file *file, struct tcon_link *tlink,
- __u32 oplock);
-extern int cifs_posix_open(char *full_path, struct inode **pinode,
- struct super_block *sb,
- int mode, unsigned int f_flags,
- __u32 *poplock, __u16 *pnetfid, int xid);
-void cifs_fill_uniqueid(struct super_block *sb, struct cifs_fattr *fattr);
-extern void cifs_unix_basic_to_fattr(struct cifs_fattr *fattr,
- FILE_UNIX_BASIC_INFO *info,
- struct cifs_sb_info *cifs_sb);
-extern void cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr);
-extern struct inode *cifs_iget(struct super_block *sb,
- struct cifs_fattr *fattr);
-
-extern int cifs_get_file_info(struct file *filp);
-extern int cifs_get_inode_info(struct inode **pinode,
- const unsigned char *search_path,
- FILE_ALL_INFO *pfile_info,
- struct super_block *sb, int xid, const __u16 *pfid);
-extern int cifs_get_file_info_unix(struct file *filp);
-extern int cifs_get_inode_info_unix(struct inode **pinode,
- const unsigned char *search_path,
- struct super_block *sb, int xid);
-extern int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb,
- struct cifs_fattr *fattr, struct inode *inode,
- const char *path, const __u16 *pfid);
-extern int id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64,
- uid_t, gid_t);
-extern struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *, struct inode *,
- const char *, u32 *);
-extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *,
- const char *, int);
-
-extern void dequeue_mid(struct mid_q_entry *mid, bool malformed);
-extern int cifs_read_from_socket(struct TCP_Server_Info *server, char *buf,
- unsigned int to_read);
-extern int cifs_readv_from_socket(struct TCP_Server_Info *server,
- struct kvec *iov_orig, unsigned int nr_segs,
- unsigned int to_read);
-extern void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
- struct cifs_sb_info *cifs_sb);
-extern int cifs_match_super(struct super_block *, void *);
-extern void cifs_cleanup_volume_info(struct smb_vol *pvolume_info);
-extern struct smb_vol *cifs_get_volume_info(char *mount_data,
- const char *devname);
-extern int cifs_mount(struct cifs_sb_info *, struct smb_vol *);
-extern void cifs_umount(struct cifs_sb_info *);
-
-#if IS_ENABLED(CONFIG_CIFS_DFS_UPCALL)
-extern void cifs_dfs_release_automount_timer(void);
-#else /* ! IS_ENABLED(CONFIG_CIFS_DFS_UPCALL) */
-#define cifs_dfs_release_automount_timer() do { } while (0)
-#endif /* ! IS_ENABLED(CONFIG_CIFS_DFS_UPCALL) */
-
-void cifs_proc_init(void);
-void cifs_proc_clean(void);
-
-extern int cifs_negotiate_protocol(unsigned int xid,
- struct cifs_ses *ses);
-extern int cifs_setup_session(unsigned int xid, struct cifs_ses *ses,
- struct nls_table *nls_info);
-extern int CIFSSMBNegotiate(unsigned int xid, struct cifs_ses *ses);
-
-extern int CIFSTCon(unsigned int xid, struct cifs_ses *ses,
- const char *tree, struct cifs_tcon *tcon,
- const struct nls_table *);
-
-extern int CIFSFindFirst(const int xid, struct cifs_tcon *tcon,
- const char *searchName, const struct nls_table *nls_codepage,
- __u16 *searchHandle, __u16 search_flags,
- struct cifs_search_info *psrch_inf,
- int map, const char dirsep);
-
-extern int CIFSFindNext(const int xid, struct cifs_tcon *tcon,
- __u16 searchHandle, __u16 search_flags,
- struct cifs_search_info *psrch_inf);
-
-extern int CIFSFindClose(const int, struct cifs_tcon *tcon,
- const __u16 search_handle);
-
-extern int CIFSSMBQFileInfo(const int xid, struct cifs_tcon *tcon,
- u16 netfid, FILE_ALL_INFO *pFindData);
-extern int CIFSSMBQPathInfo(const int xid, struct cifs_tcon *tcon,
- const unsigned char *searchName,
- FILE_ALL_INFO *findData,
- int legacy /* whether to use old info level */,
- const struct nls_table *nls_codepage, int remap);
-extern int SMBQueryInformation(const int xid, struct cifs_tcon *tcon,
- const unsigned char *searchName,
- FILE_ALL_INFO *findData,
- const struct nls_table *nls_codepage, int remap);
-
-extern int CIFSSMBUnixQFileInfo(const int xid, struct cifs_tcon *tcon,
- u16 netfid, FILE_UNIX_BASIC_INFO *pFindData);
-extern int CIFSSMBUnixQPathInfo(const int xid,
- struct cifs_tcon *tcon,
- const unsigned char *searchName,
- FILE_UNIX_BASIC_INFO *pFindData,
- const struct nls_table *nls_codepage, int remap);
-
-extern int CIFSGetDFSRefer(const int xid, struct cifs_ses *ses,
- const unsigned char *searchName,
- struct dfs_info3_param **target_nodes,
- unsigned int *number_of_nodes_in_array,
- const struct nls_table *nls_codepage, int remap);
-
-extern int get_dfs_path(int xid, struct cifs_ses *pSesInfo,
- const char *old_path,
- const struct nls_table *nls_codepage,
- unsigned int *pnum_referrals,
- struct dfs_info3_param **preferrals,
- int remap);
-extern void reset_cifs_unix_caps(int xid, struct cifs_tcon *tcon,
- struct cifs_sb_info *cifs_sb,
- struct smb_vol *vol);
-extern int CIFSSMBQFSInfo(const int xid, struct cifs_tcon *tcon,
- struct kstatfs *FSData);
-extern int SMBOldQFSInfo(const int xid, struct cifs_tcon *tcon,
- struct kstatfs *FSData);
-extern int CIFSSMBSetFSUnixInfo(const int xid, struct cifs_tcon *tcon,
- __u64 cap);
-
-extern int CIFSSMBQFSAttributeInfo(const int xid,
- struct cifs_tcon *tcon);
-extern int CIFSSMBQFSDeviceInfo(const int xid, struct cifs_tcon *tcon);
-extern int CIFSSMBQFSUnixInfo(const int xid, struct cifs_tcon *tcon);
-extern int CIFSSMBQFSPosixInfo(const int xid, struct cifs_tcon *tcon,
- struct kstatfs *FSData);
-
-extern int CIFSSMBSetPathInfo(const int xid, struct cifs_tcon *tcon,
- const char *fileName, const FILE_BASIC_INFO *data,
- const struct nls_table *nls_codepage,
- int remap_special_chars);
-extern int CIFSSMBSetFileInfo(const int xid, struct cifs_tcon *tcon,
- const FILE_BASIC_INFO *data, __u16 fid,
- __u32 pid_of_opener);
-extern int CIFSSMBSetFileDisposition(const int xid, struct cifs_tcon *tcon,
- bool delete_file, __u16 fid, __u32 pid_of_opener);
-#if 0
-extern int CIFSSMBSetAttrLegacy(int xid, struct cifs_tcon *tcon,
- char *fileName, __u16 dos_attributes,
- const struct nls_table *nls_codepage);
-#endif /* possibly unneeded function */
-extern int CIFSSMBSetEOF(const int xid, struct cifs_tcon *tcon,
- const char *fileName, __u64 size,
- bool setAllocationSizeFlag,
- const struct nls_table *nls_codepage,
- int remap_special_chars);
-extern int CIFSSMBSetFileSize(const int xid, struct cifs_tcon *tcon,
- __u64 size, __u16 fileHandle, __u32 opener_pid,
- bool AllocSizeFlag);
-
-struct cifs_unix_set_info_args {
- __u64 ctime;
- __u64 atime;
- __u64 mtime;
- __u64 mode;
- __u64 uid;
- __u64 gid;
- dev_t device;
-};
-
-extern int CIFSSMBUnixSetFileInfo(const int xid, struct cifs_tcon *tcon,
- const struct cifs_unix_set_info_args *args,
- u16 fid, u32 pid_of_opener);
-
-extern int CIFSSMBUnixSetPathInfo(const int xid, struct cifs_tcon *pTcon,
- char *fileName,
- const struct cifs_unix_set_info_args *args,
- const struct nls_table *nls_codepage,
- int remap_special_chars);
-
-extern int CIFSSMBMkDir(const int xid, struct cifs_tcon *tcon,
- const char *newName,
- const struct nls_table *nls_codepage,
- int remap_special_chars);
-extern int CIFSSMBRmDir(const int xid, struct cifs_tcon *tcon,
- const char *name, const struct nls_table *nls_codepage,
- int remap_special_chars);
-extern int CIFSPOSIXDelFile(const int xid, struct cifs_tcon *tcon,
- const char *name, __u16 type,
- const struct nls_table *nls_codepage,
- int remap_special_chars);
-extern int CIFSSMBDelFile(const int xid, struct cifs_tcon *tcon,
- const char *name,
- const struct nls_table *nls_codepage,
- int remap_special_chars);
-extern int CIFSSMBRename(const int xid, struct cifs_tcon *tcon,
- const char *fromName, const char *toName,
- const struct nls_table *nls_codepage,
- int remap_special_chars);
-extern int CIFSSMBRenameOpenFile(const int xid, struct cifs_tcon *pTcon,
- int netfid, const char *target_name,
- const struct nls_table *nls_codepage,
- int remap_special_chars);
-extern int CIFSCreateHardLink(const int xid,
- struct cifs_tcon *tcon,
- const char *fromName, const char *toName,
- const struct nls_table *nls_codepage,
- int remap_special_chars);
-extern int CIFSUnixCreateHardLink(const int xid,
- struct cifs_tcon *tcon,
- const char *fromName, const char *toName,
- const struct nls_table *nls_codepage,
- int remap_special_chars);
-extern int CIFSUnixCreateSymLink(const int xid,
- struct cifs_tcon *tcon,
- const char *fromName, const char *toName,
- const struct nls_table *nls_codepage);
-extern int CIFSSMBUnixQuerySymLink(const int xid,
- struct cifs_tcon *tcon,
- const unsigned char *searchName, char **syminfo,
- const struct nls_table *nls_codepage);
-#ifdef CONFIG_CIFS_SYMLINK_EXPERIMENTAL
-extern int CIFSSMBQueryReparseLinkInfo(const int xid,
- struct cifs_tcon *tcon,
- const unsigned char *searchName,
- char *symlinkinfo, const int buflen, __u16 fid,
- const struct nls_table *nls_codepage);
-#endif /* temporarily unused until cifs_symlink fixed */
-extern int CIFSSMBOpen(const int xid, struct cifs_tcon *tcon,
- const char *fileName, const int disposition,
- const int access_flags, const int omode,
- __u16 *netfid, int *pOplock, FILE_ALL_INFO *,
- const struct nls_table *nls_codepage, int remap);
-extern int SMBLegacyOpen(const int xid, struct cifs_tcon *tcon,
- const char *fileName, const int disposition,
- const int access_flags, const int omode,
- __u16 *netfid, int *pOplock, FILE_ALL_INFO *,
- const struct nls_table *nls_codepage, int remap);
-extern int CIFSPOSIXCreate(const int xid, struct cifs_tcon *tcon,
- u32 posix_flags, __u64 mode, __u16 *netfid,
- FILE_UNIX_BASIC_INFO *pRetData,
- __u32 *pOplock, const char *name,
- const struct nls_table *nls_codepage, int remap);
-extern int CIFSSMBClose(const int xid, struct cifs_tcon *tcon,
- const int smb_file_id);
-
-extern int CIFSSMBFlush(const int xid, struct cifs_tcon *tcon,
- const int smb_file_id);
-
-extern int CIFSSMBRead(const int xid, struct cifs_io_parms *io_parms,
- unsigned int *nbytes, char **buf,
- int *return_buf_type);
-extern int CIFSSMBWrite(const int xid, struct cifs_io_parms *io_parms,
- unsigned int *nbytes, const char *buf,
- const char __user *ubuf, const int long_op);
-extern int CIFSSMBWrite2(const int xid, struct cifs_io_parms *io_parms,
- unsigned int *nbytes, struct kvec *iov, const int nvec,
- const int long_op);
-extern int CIFSGetSrvInodeNumber(const int xid, struct cifs_tcon *tcon,
- const unsigned char *searchName, __u64 *inode_number,
- const struct nls_table *nls_codepage,
- int remap_special_chars);
-
-extern int cifs_lockv(const int xid, struct cifs_tcon *tcon, const __u16 netfid,
- const __u8 lock_type, const __u32 num_unlock,
- const __u32 num_lock, LOCKING_ANDX_RANGE *buf);
-extern int CIFSSMBLock(const int xid, struct cifs_tcon *tcon,
- const __u16 netfid, const __u32 netpid, const __u64 len,
- const __u64 offset, const __u32 numUnlock,
- const __u32 numLock, const __u8 lockType,
- const bool waitFlag, const __u8 oplock_level);
-extern int CIFSSMBPosixLock(const int xid, struct cifs_tcon *tcon,
- const __u16 smb_file_id, const __u32 netpid,
- const int get_flag, const __u64 len, struct file_lock *,
- const __u16 lock_type, const bool waitFlag);
-extern int CIFSSMBTDis(const int xid, struct cifs_tcon *tcon);
-extern int CIFSSMBEcho(struct TCP_Server_Info *server);
-extern int CIFSSMBLogoff(const int xid, struct cifs_ses *ses);
-
-extern struct cifs_ses *sesInfoAlloc(void);
-extern void sesInfoFree(struct cifs_ses *);
-extern struct cifs_tcon *tconInfoAlloc(void);
-extern void tconInfoFree(struct cifs_tcon *);
-
-extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *, __u32 *);
-extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,
- __u32 *);
-extern int cifs_verify_signature(struct kvec *iov, unsigned int nr_iov,
- struct TCP_Server_Info *server,
- __u32 expected_sequence_number);
-extern int SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *,
- const struct nls_table *);
-extern int setup_ntlm_response(struct cifs_ses *, const struct nls_table *);
-extern int setup_ntlmv2_rsp(struct cifs_ses *, const struct nls_table *);
-extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *);
-extern void cifs_crypto_shash_release(struct TCP_Server_Info *);
-extern int calc_seckey(struct cifs_ses *);
-
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
-extern int calc_lanman_hash(const char *password, const char *cryptkey,
- bool encrypt, char *lnm_session_key);
-#endif /* CIFS_WEAK_PW_HASH */
-#ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* unused temporarily */
-extern int CIFSSMBNotify(const int xid, struct cifs_tcon *tcon,
- const int notify_subdirs, const __u16 netfid,
- __u32 filter, struct file *file, int multishot,
- const struct nls_table *nls_codepage);
-#endif /* was needed for dnotify, and will be needed for inotify when VFS fix */
-extern int CIFSSMBCopy(int xid,
- struct cifs_tcon *source_tcon,
- const char *fromName,
- const __u16 target_tid,
- const char *toName, const int flags,
- const struct nls_table *nls_codepage,
- int remap_special_chars);
-extern ssize_t CIFSSMBQAllEAs(const int xid, struct cifs_tcon *tcon,
- const unsigned char *searchName,
- const unsigned char *ea_name, char *EAData,
- size_t bufsize, const struct nls_table *nls_codepage,
- int remap_special_chars);
-extern int CIFSSMBSetEA(const int xid, struct cifs_tcon *tcon,
- const char *fileName, const char *ea_name,
- const void *ea_value, const __u16 ea_value_len,
- const struct nls_table *nls_codepage, int remap_special_chars);
-extern int CIFSSMBGetCIFSACL(const int xid, struct cifs_tcon *tcon,
- __u16 fid, struct cifs_ntsd **acl_inf, __u32 *buflen);
-extern int CIFSSMBSetCIFSACL(const int, struct cifs_tcon *, __u16,
- struct cifs_ntsd *, __u32, int);
-extern int CIFSSMBGetPosixACL(const int xid, struct cifs_tcon *tcon,
- const unsigned char *searchName,
- char *acl_inf, const int buflen, const int acl_type,
- const struct nls_table *nls_codepage, int remap_special_chars);
-extern int CIFSSMBSetPosixACL(const int xid, struct cifs_tcon *tcon,
- const unsigned char *fileName,
- const char *local_acl, const int buflen, const int acl_type,
- const struct nls_table *nls_codepage, int remap_special_chars);
-extern int CIFSGetExtAttr(const int xid, struct cifs_tcon *tcon,
- const int netfid, __u64 *pExtAttrBits, __u64 *pMask);
-extern void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb);
-extern bool CIFSCouldBeMFSymlink(const struct cifs_fattr *fattr);
-extern int CIFSCheckMFSymlink(struct cifs_fattr *fattr,
- const unsigned char *path,
- struct cifs_sb_info *cifs_sb, int xid);
-extern int mdfour(unsigned char *, unsigned char *, int);
-extern int E_md4hash(const unsigned char *passwd, unsigned char *p16,
- const struct nls_table *codepage);
-extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8,
- unsigned char *p24);
-
-/* asynchronous read support */
-struct cifs_readdata {
- struct cifsFileInfo *cfile;
- struct address_space *mapping;
- __u64 offset;
- unsigned int bytes;
- pid_t pid;
- int result;
- struct list_head pages;
- struct work_struct work;
- unsigned int nr_iov;
- struct kvec iov[1];
-};
-
-struct cifs_readdata *cifs_readdata_alloc(unsigned int nr_pages);
-void cifs_readdata_free(struct cifs_readdata *rdata);
-int cifs_async_readv(struct cifs_readdata *rdata);
-
-/* asynchronous write support */
-struct cifs_writedata {
- struct kref refcount;
- struct list_head list;
- struct completion done;
- enum writeback_sync_modes sync_mode;
- struct work_struct work;
- struct cifsFileInfo *cfile;
- __u64 offset;
- pid_t pid;
- unsigned int bytes;
- int result;
- void (*marshal_iov) (struct kvec *iov,
- struct cifs_writedata *wdata);
- unsigned int nr_pages;
- struct page *pages[1];
-};
-
-int cifs_async_writev(struct cifs_writedata *wdata);
-void cifs_writev_complete(struct work_struct *work);
-struct cifs_writedata *cifs_writedata_alloc(unsigned int nr_pages,
- work_func_t complete);
-void cifs_writedata_release(struct kref *refcount);
-
-#endif /* _CIFSPROTO_H */
diff --git a/ANDROID_3.4.5/fs/cifs/cifssmb.c b/ANDROID_3.4.5/fs/cifs/cifssmb.c
deleted file mode 100644
index 6b79efd7..00000000
--- a/ANDROID_3.4.5/fs/cifs/cifssmb.c
+++ /dev/null
@@ -1,6504 +0,0 @@
-/*
- * fs/cifs/cifssmb.c
- *
- * Copyright (C) International Business Machines Corp., 2002,2010
- * Author(s): Steve French (sfrench@us.ibm.com)
- *
- * Contains the routines for constructing the SMB PDUs themselves
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
- /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c */
- /* These are mostly routines that operate on a pathname, or on a tree id */
- /* (mounted volume), but there are eight handle based routines which must be */
- /* treated slightly differently for reconnection purposes since we never */
- /* want to reuse a stale file handle and only the caller knows the file info */
-
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/vfs.h>
-#include <linux/slab.h>
-#include <linux/posix_acl_xattr.h>
-#include <linux/pagemap.h>
-#include <linux/swap.h>
-#include <linux/task_io_accounting_ops.h>
-#include <asm/uaccess.h>
-#include "cifspdu.h"
-#include "cifsglob.h"
-#include "cifsacl.h"
-#include "cifsproto.h"
-#include "cifs_unicode.h"
-#include "cifs_debug.h"
-#include "fscache.h"
-
-#ifdef CONFIG_CIFS_POSIX
-static struct {
- int index;
- char *name;
-} protocols[] = {
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
- {LANMAN_PROT, "\2LM1.2X002"},
- {LANMAN2_PROT, "\2LANMAN2.1"},
-#endif /* weak password hashing for legacy clients */
- {CIFS_PROT, "\2NT LM 0.12"},
- {POSIX_PROT, "\2POSIX 2"},
- {BAD_PROT, "\2"}
-};
-#else
-static struct {
- int index;
- char *name;
-} protocols[] = {
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
- {LANMAN_PROT, "\2LM1.2X002"},
- {LANMAN2_PROT, "\2LANMAN2.1"},
-#endif /* weak password hashing for legacy clients */
- {CIFS_PROT, "\2NT LM 0.12"},
- {BAD_PROT, "\2"}
-};
-#endif
-
-/* define the number of elements in the cifs dialect array */
-#ifdef CONFIG_CIFS_POSIX
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
-#define CIFS_NUM_PROT 4
-#else
-#define CIFS_NUM_PROT 2
-#endif /* CIFS_WEAK_PW_HASH */
-#else /* not posix */
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
-#define CIFS_NUM_PROT 3
-#else
-#define CIFS_NUM_PROT 1
-#endif /* CONFIG_CIFS_WEAK_PW_HASH */
-#endif /* CIFS_POSIX */
-
-/* Forward declarations */
-static void cifs_readv_complete(struct work_struct *work);
-
-/* Mark as invalid, all open files on tree connections since they
- were closed when session to server was lost */
-static void mark_open_files_invalid(struct cifs_tcon *pTcon)
-{
- struct cifsFileInfo *open_file = NULL;
- struct list_head *tmp;
- struct list_head *tmp1;
-
-/* list all files open on tree connection and mark them invalid */
- spin_lock(&cifs_file_list_lock);
- list_for_each_safe(tmp, tmp1, &pTcon->openFileList) {
- open_file = list_entry(tmp, struct cifsFileInfo, tlist);
- open_file->invalidHandle = true;
- open_file->oplock_break_cancelled = true;
- }
- spin_unlock(&cifs_file_list_lock);
- /* BB Add call to invalidate_inodes(sb) for all superblocks mounted
- to this tcon */
-}
-
-/* reconnect the socket, tcon, and smb session if needed */
-static int
-cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
-{
- int rc;
- struct cifs_ses *ses;
- struct TCP_Server_Info *server;
- struct nls_table *nls_codepage;
-
- /*
- * SMBs NegProt, SessSetup, uLogoff do not have tcon yet so check for
- * tcp and smb session status done differently for those three - in the
- * calling routine
- */
- if (!tcon)
- return 0;
-
- ses = tcon->ses;
- server = ses->server;
-
- /*
- * only tree disconnect, open, and write, (and ulogoff which does not
- * have tcon) are allowed as we start force umount
- */
- if (tcon->tidStatus == CifsExiting) {
- if (smb_command != SMB_COM_WRITE_ANDX &&
- smb_command != SMB_COM_OPEN_ANDX &&
- smb_command != SMB_COM_TREE_DISCONNECT) {
- cFYI(1, "can not send cmd %d while umounting",
- smb_command);
- return -ENODEV;
- }
- }
-
- /*
- * Give demultiplex thread up to 10 seconds to reconnect, should be
- * greater than cifs socket timeout which is 7 seconds
- */
- while (server->tcpStatus == CifsNeedReconnect) {
- wait_event_interruptible_timeout(server->response_q,
- (server->tcpStatus != CifsNeedReconnect), 10 * HZ);
-
- /* are we still trying to reconnect? */
- if (server->tcpStatus != CifsNeedReconnect)
- break;
-
- /*
- * on "soft" mounts we wait once. Hard mounts keep
- * retrying until process is killed or server comes
- * back on-line
- */
- if (!tcon->retry) {
- cFYI(1, "gave up waiting on reconnect in smb_init");
- return -EHOSTDOWN;
- }
- }
-
- if (!ses->need_reconnect && !tcon->need_reconnect)
- return 0;
-
- nls_codepage = load_nls_default();
-
- /*
- * need to prevent multiple threads trying to simultaneously
- * reconnect the same SMB session
- */
- mutex_lock(&ses->session_mutex);
- rc = cifs_negotiate_protocol(0, ses);
- if (rc == 0 && ses->need_reconnect)
- rc = cifs_setup_session(0, ses, nls_codepage);
-
- /* do we need to reconnect tcon? */
- if (rc || !tcon->need_reconnect) {
- mutex_unlock(&ses->session_mutex);
- goto out;
- }
-
- mark_open_files_invalid(tcon);
- rc = CIFSTCon(0, ses, tcon->treeName, tcon, nls_codepage);
- mutex_unlock(&ses->session_mutex);
- cFYI(1, "reconnect tcon rc = %d", rc);
-
- if (rc)
- goto out;
-
- /*
- * FIXME: check if wsize needs updated due to negotiated smb buffer
- * size shrinking
- */
- atomic_inc(&tconInfoReconnectCount);
-
- /* tell server Unix caps we support */
- if (ses->capabilities & CAP_UNIX)
- reset_cifs_unix_caps(0, tcon, NULL, NULL);
-
- /*
- * Removed call to reopen open files here. It is safer (and faster) to
- * reopen files one at a time as needed in read and write.
- *
- * FIXME: what about file locks? don't we need to reclaim them ASAP?
- */
-
-out:
- /*
- * Check if handle based operation so we know whether we can continue
- * or not without returning to caller to reset file handle
- */
- switch (smb_command) {
- case SMB_COM_READ_ANDX:
- case SMB_COM_WRITE_ANDX:
- case SMB_COM_CLOSE:
- case SMB_COM_FIND_CLOSE2:
- case SMB_COM_LOCKING_ANDX:
- rc = -EAGAIN;
- }
-
- unload_nls(nls_codepage);
- return rc;
-}
-
-/* Allocate and return pointer to an SMB request buffer, and set basic
- SMB information in the SMB header. If the return code is zero, this
- function must have filled in request_buf pointer */
-static int
-small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
- void **request_buf)
-{
- int rc;
-
- rc = cifs_reconnect_tcon(tcon, smb_command);
- if (rc)
- return rc;
-
- *request_buf = cifs_small_buf_get();
- if (*request_buf == NULL) {
- /* BB should we add a retry in here if not a writepage? */
- return -ENOMEM;
- }
-
- header_assemble((struct smb_hdr *) *request_buf, smb_command,
- tcon, wct);
-
- if (tcon != NULL)
- cifs_stats_inc(&tcon->num_smbs_sent);
-
- return 0;
-}
-
-int
-small_smb_init_no_tc(const int smb_command, const int wct,
- struct cifs_ses *ses, void **request_buf)
-{
- int rc;
- struct smb_hdr *buffer;
-
- rc = small_smb_init(smb_command, wct, NULL, request_buf);
- if (rc)
- return rc;
-
- buffer = (struct smb_hdr *)*request_buf;
- buffer->Mid = GetNextMid(ses->server);
- if (ses->capabilities & CAP_UNICODE)
- buffer->Flags2 |= SMBFLG2_UNICODE;
- if (ses->capabilities & CAP_STATUS32)
- buffer->Flags2 |= SMBFLG2_ERR_STATUS;
-
- /* uid, tid can stay at zero as set in header assemble */
-
- /* BB add support for turning on the signing when
- this function is used after 1st of session setup requests */
-
- return rc;
-}
-
-/* If the return code is zero, this function must fill in request_buf pointer */
-static int
-__smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
- void **request_buf, void **response_buf)
-{
- *request_buf = cifs_buf_get();
- if (*request_buf == NULL) {
- /* BB should we add a retry in here if not a writepage? */
- return -ENOMEM;
- }
- /* Although the original thought was we needed the response buf for */
- /* potential retries of smb operations it turns out we can determine */
- /* from the mid flags when the request buffer can be resent without */
- /* having to use a second distinct buffer for the response */
- if (response_buf)
- *response_buf = *request_buf;
-
- header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
- wct);
-
- if (tcon != NULL)
- cifs_stats_inc(&tcon->num_smbs_sent);
-
- return 0;
-}
-
-/* If the return code is zero, this function must fill in request_buf pointer */
-static int
-smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
- void **request_buf, void **response_buf)
-{
- int rc;
-
- rc = cifs_reconnect_tcon(tcon, smb_command);
- if (rc)
- return rc;
-
- return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
-}
-
-static int
-smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
- void **request_buf, void **response_buf)
-{
- if (tcon->ses->need_reconnect || tcon->need_reconnect)
- return -EHOSTDOWN;
-
- return __smb_init(smb_command, wct, tcon, request_buf, response_buf);
-}
-
-static int validate_t2(struct smb_t2_rsp *pSMB)
-{
- unsigned int total_size;
-
- /* check for plausible wct */
- if (pSMB->hdr.WordCount < 10)
- goto vt2_err;
-
- /* check for parm and data offset going beyond end of smb */
- if (get_unaligned_le16(&pSMB->t2_rsp.ParameterOffset) > 1024 ||
- get_unaligned_le16(&pSMB->t2_rsp.DataOffset) > 1024)
- goto vt2_err;
-
- total_size = get_unaligned_le16(&pSMB->t2_rsp.ParameterCount);
- if (total_size >= 512)
- goto vt2_err;
-
- /* check that bcc is at least as big as parms + data, and that it is
- * less than negotiated smb buffer
- */
- total_size += get_unaligned_le16(&pSMB->t2_rsp.DataCount);
- if (total_size > get_bcc(&pSMB->hdr) ||
- total_size >= CIFSMaxBufSize + MAX_CIFS_HDR_SIZE)
- goto vt2_err;
-
- return 0;
-vt2_err:
- cifs_dump_mem("Invalid transact2 SMB: ", (char *)pSMB,
- sizeof(struct smb_t2_rsp) + 16);
- return -EINVAL;
-}
-
-static inline void inc_rfc1001_len(void *pSMB, int count)
-{
- struct smb_hdr *hdr = (struct smb_hdr *)pSMB;
-
- be32_add_cpu(&hdr->smb_buf_length, count);
-}
-
-int
-CIFSSMBNegotiate(unsigned int xid, struct cifs_ses *ses)
-{
- NEGOTIATE_REQ *pSMB;
- NEGOTIATE_RSP *pSMBr;
- int rc = 0;
- int bytes_returned;
- int i;
- struct TCP_Server_Info *server;
- u16 count;
- unsigned int secFlags;
-
- if (ses->server)
- server = ses->server;
- else {
- rc = -EIO;
- return rc;
- }
- rc = smb_init(SMB_COM_NEGOTIATE, 0, NULL /* no tcon yet */ ,
- (void **) &pSMB, (void **) &pSMBr);
- if (rc)
- return rc;
-
- /* if any of auth flags (ie not sign or seal) are overriden use them */
- if (ses->overrideSecFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL)))
- secFlags = ses->overrideSecFlg; /* BB FIXME fix sign flags? */
- else /* if override flags set only sign/seal OR them with global auth */
- secFlags = global_secflags | ses->overrideSecFlg;
-
- cFYI(1, "secFlags 0x%x", secFlags);
-
- pSMB->hdr.Mid = GetNextMid(server);
- pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS);
-
- if ((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5)
- pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
- else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_KRB5) {
- cFYI(1, "Kerberos only mechanism, enable extended security");
- pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
- } else if ((secFlags & CIFSSEC_MUST_NTLMSSP) == CIFSSEC_MUST_NTLMSSP)
- pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
- else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_NTLMSSP) {
- cFYI(1, "NTLMSSP only mechanism, enable extended security");
- pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
- }
-
- count = 0;
- for (i = 0; i < CIFS_NUM_PROT; i++) {
- strncpy(pSMB->DialectsArray+count, protocols[i].name, 16);
- count += strlen(protocols[i].name) + 1;
- /* null at end of source and target buffers anyway */
- }
- inc_rfc1001_len(pSMB, count);
- pSMB->ByteCount = cpu_to_le16(count);
-
- rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc != 0)
- goto neg_err_exit;
-
- server->dialect = le16_to_cpu(pSMBr->DialectIndex);
- cFYI(1, "Dialect: %d", server->dialect);
- /* Check wct = 1 error case */
- if ((pSMBr->hdr.WordCount < 13) || (server->dialect == BAD_PROT)) {
- /* core returns wct = 1, but we do not ask for core - otherwise
- small wct just comes when dialect index is -1 indicating we
- could not negotiate a common dialect */
- rc = -EOPNOTSUPP;
- goto neg_err_exit;
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
- } else if ((pSMBr->hdr.WordCount == 13)
- && ((server->dialect == LANMAN_PROT)
- || (server->dialect == LANMAN2_PROT))) {
- __s16 tmp;
- struct lanman_neg_rsp *rsp = (struct lanman_neg_rsp *)pSMBr;
-
- if ((secFlags & CIFSSEC_MAY_LANMAN) ||
- (secFlags & CIFSSEC_MAY_PLNTXT))
- server->secType = LANMAN;
- else {
- cERROR(1, "mount failed weak security disabled"
- " in /proc/fs/cifs/SecurityFlags");
- rc = -EOPNOTSUPP;
- goto neg_err_exit;
- }
- server->sec_mode = (__u8)le16_to_cpu(rsp->SecurityMode);
- server->maxReq = min_t(unsigned int,
- le16_to_cpu(rsp->MaxMpxCount),
- cifs_max_pending);
- cifs_set_credits(server, server->maxReq);
- server->maxBuf = le16_to_cpu(rsp->MaxBufSize);
- server->max_vcs = le16_to_cpu(rsp->MaxNumberVcs);
- /* even though we do not use raw we might as well set this
- accurately, in case we ever find a need for it */
- if ((le16_to_cpu(rsp->RawMode) & RAW_ENABLE) == RAW_ENABLE) {
- server->max_rw = 0xFF00;
- server->capabilities = CAP_MPX_MODE | CAP_RAW_MODE;
- } else {
- server->max_rw = 0;/* do not need to use raw anyway */
- server->capabilities = CAP_MPX_MODE;
- }
- tmp = (__s16)le16_to_cpu(rsp->ServerTimeZone);
- if (tmp == -1) {
- /* OS/2 often does not set timezone therefore
- * we must use server time to calc time zone.
- * Could deviate slightly from the right zone.
- * Smallest defined timezone difference is 15 minutes
- * (i.e. Nepal). Rounding up/down is done to match
- * this requirement.
- */
- int val, seconds, remain, result;
- struct timespec ts, utc;
- utc = CURRENT_TIME;
- ts = cnvrtDosUnixTm(rsp->SrvTime.Date,
- rsp->SrvTime.Time, 0);
- cFYI(1, "SrvTime %d sec since 1970 (utc: %d) diff: %d",
- (int)ts.tv_sec, (int)utc.tv_sec,
- (int)(utc.tv_sec - ts.tv_sec));
- val = (int)(utc.tv_sec - ts.tv_sec);
- seconds = abs(val);
- result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ;
- remain = seconds % MIN_TZ_ADJ;
- if (remain >= (MIN_TZ_ADJ / 2))
- result += MIN_TZ_ADJ;
- if (val < 0)
- result = -result;
- server->timeAdj = result;
- } else {
- server->timeAdj = (int)tmp;
- server->timeAdj *= 60; /* also in seconds */
- }
- cFYI(1, "server->timeAdj: %d seconds", server->timeAdj);
-
-
- /* BB get server time for time conversions and add
- code to use it and timezone since this is not UTC */
-
- if (rsp->EncryptionKeyLength ==
- cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
- memcpy(ses->server->cryptkey, rsp->EncryptionKey,
- CIFS_CRYPTO_KEY_SIZE);
- } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
- rc = -EIO; /* need cryptkey unless plain text */
- goto neg_err_exit;
- }
-
- cFYI(1, "LANMAN negotiated");
- /* we will not end up setting signing flags - as no signing
- was in LANMAN and server did not return the flags on */
- goto signing_check;
-#else /* weak security disabled */
- } else if (pSMBr->hdr.WordCount == 13) {
- cERROR(1, "mount failed, cifs module not built "
- "with CIFS_WEAK_PW_HASH support");
- rc = -EOPNOTSUPP;
-#endif /* WEAK_PW_HASH */
- goto neg_err_exit;
- } else if (pSMBr->hdr.WordCount != 17) {
- /* unknown wct */
- rc = -EOPNOTSUPP;
- goto neg_err_exit;
- }
- /* else wct == 17 NTLM */
- server->sec_mode = pSMBr->SecurityMode;
- if ((server->sec_mode & SECMODE_USER) == 0)
- cFYI(1, "share mode security");
-
- if ((server->sec_mode & SECMODE_PW_ENCRYPT) == 0)
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
- if ((secFlags & CIFSSEC_MAY_PLNTXT) == 0)
-#endif /* CIFS_WEAK_PW_HASH */
- cERROR(1, "Server requests plain text password"
- " but client support disabled");
-
- if ((secFlags & CIFSSEC_MUST_NTLMV2) == CIFSSEC_MUST_NTLMV2)
- server->secType = NTLMv2;
- else if (secFlags & CIFSSEC_MAY_NTLM)
- server->secType = NTLM;
- else if (secFlags & CIFSSEC_MAY_NTLMV2)
- server->secType = NTLMv2;
- else if (secFlags & CIFSSEC_MAY_KRB5)
- server->secType = Kerberos;
- else if (secFlags & CIFSSEC_MAY_NTLMSSP)
- server->secType = RawNTLMSSP;
- else if (secFlags & CIFSSEC_MAY_LANMAN)
- server->secType = LANMAN;
- else {
- rc = -EOPNOTSUPP;
- cERROR(1, "Invalid security type");
- goto neg_err_exit;
- }
- /* else ... any others ...? */
-
- /* one byte, so no need to convert this or EncryptionKeyLen from
- little endian */
- server->maxReq = min_t(unsigned int, le16_to_cpu(pSMBr->MaxMpxCount),
- cifs_max_pending);
- cifs_set_credits(server, server->maxReq);
- /* probably no need to store and check maxvcs */
- server->maxBuf = le32_to_cpu(pSMBr->MaxBufferSize);
- server->max_rw = le32_to_cpu(pSMBr->MaxRawSize);
- cFYI(DBG2, "Max buf = %d", ses->server->maxBuf);
- server->capabilities = le32_to_cpu(pSMBr->Capabilities);
- server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone);
- server->timeAdj *= 60;
- if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
- memcpy(ses->server->cryptkey, pSMBr->u.EncryptionKey,
- CIFS_CRYPTO_KEY_SIZE);
- } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC ||
- server->capabilities & CAP_EXTENDED_SECURITY) &&
- (pSMBr->EncryptionKeyLength == 0)) {
- /* decode security blob */
- count = get_bcc(&pSMBr->hdr);
- if (count < 16) {
- rc = -EIO;
- goto neg_err_exit;
- }
- spin_lock(&cifs_tcp_ses_lock);
- if (server->srv_count > 1) {
- spin_unlock(&cifs_tcp_ses_lock);
- if (memcmp(server->server_GUID,
- pSMBr->u.extended_response.
- GUID, 16) != 0) {
- cFYI(1, "server UID changed");
- memcpy(server->server_GUID,
- pSMBr->u.extended_response.GUID,
- 16);
- }
- } else {
- spin_unlock(&cifs_tcp_ses_lock);
- memcpy(server->server_GUID,
- pSMBr->u.extended_response.GUID, 16);
- }
-
- if (count == 16) {
- server->secType = RawNTLMSSP;
- } else {
- rc = decode_negTokenInit(pSMBr->u.extended_response.
- SecurityBlob, count - 16,
- server);
- if (rc == 1)
- rc = 0;
- else
- rc = -EINVAL;
- if (server->secType == Kerberos) {
- if (!server->sec_kerberos &&
- !server->sec_mskerberos)
- rc = -EOPNOTSUPP;
- } else if (server->secType == RawNTLMSSP) {
- if (!server->sec_ntlmssp)
- rc = -EOPNOTSUPP;
- } else
- rc = -EOPNOTSUPP;
- }
- } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
- rc = -EIO; /* no crypt key only if plain text pwd */
- goto neg_err_exit;
- } else
- server->capabilities &= ~CAP_EXTENDED_SECURITY;
-
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
-signing_check:
-#endif
- if ((secFlags & CIFSSEC_MAY_SIGN) == 0) {
- /* MUST_SIGN already includes the MAY_SIGN FLAG
- so if this is zero it means that signing is disabled */
- cFYI(1, "Signing disabled");
- if (server->sec_mode & SECMODE_SIGN_REQUIRED) {
- cERROR(1, "Server requires "
- "packet signing to be enabled in "
- "/proc/fs/cifs/SecurityFlags.");
- rc = -EOPNOTSUPP;
- }
- server->sec_mode &=
- ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
- } else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) {
- /* signing required */
- cFYI(1, "Must sign - secFlags 0x%x", secFlags);
- if ((server->sec_mode &
- (SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED)) == 0) {
- cERROR(1, "signing required but server lacks support");
- rc = -EOPNOTSUPP;
- } else
- server->sec_mode |= SECMODE_SIGN_REQUIRED;
- } else {
- /* signing optional ie CIFSSEC_MAY_SIGN */
- if ((server->sec_mode & SECMODE_SIGN_REQUIRED) == 0)
- server->sec_mode &=
- ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
- }
-
-neg_err_exit:
- cifs_buf_release(pSMB);
-
- cFYI(1, "negprot rc %d", rc);
- return rc;
-}
-
-int
-CIFSSMBTDis(const int xid, struct cifs_tcon *tcon)
-{
- struct smb_hdr *smb_buffer;
- int rc = 0;
-
- cFYI(1, "In tree disconnect");
-
- /* BB: do we need to check this? These should never be NULL. */
- if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
- return -EIO;
-
- /*
- * No need to return error on this operation if tid invalidated and
- * closed on server already e.g. due to tcp session crashing. Also,
- * the tcon is no longer on the list, so no need to take lock before
- * checking this.
- */
- if ((tcon->need_reconnect) || (tcon->ses->need_reconnect))
- return 0;
-
- rc = small_smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
- (void **)&smb_buffer);
- if (rc)
- return rc;
-
- rc = SendReceiveNoRsp(xid, tcon->ses, (char *)smb_buffer, 0);
- if (rc)
- cFYI(1, "Tree disconnect failed %d", rc);
-
- /* No need to return error on this operation if tid invalidated and
- closed on server already e.g. due to tcp session crashing */
- if (rc == -EAGAIN)
- rc = 0;
-
- return rc;
-}
-
-/*
- * This is a no-op for now. We're not really interested in the reply, but
- * rather in the fact that the server sent one and that server->lstrp
- * gets updated.
- *
- * FIXME: maybe we should consider checking that the reply matches request?
- */
-static void
-cifs_echo_callback(struct mid_q_entry *mid)
-{
- struct TCP_Server_Info *server = mid->callback_data;
-
- DeleteMidQEntry(mid);
- cifs_add_credits(server, 1);
-}
-
-int
-CIFSSMBEcho(struct TCP_Server_Info *server)
-{
- ECHO_REQ *smb;
- int rc = 0;
- struct kvec iov;
-
- cFYI(1, "In echo request");
-
- rc = small_smb_init(SMB_COM_ECHO, 0, NULL, (void **)&smb);
- if (rc)
- return rc;
-
- /* set up echo request */
- smb->hdr.Tid = 0xffff;
- smb->hdr.WordCount = 1;
- put_unaligned_le16(1, &smb->EchoCount);
- put_bcc(1, &smb->hdr);
- smb->Data[0] = 'a';
- inc_rfc1001_len(smb, 3);
- iov.iov_base = smb;
- iov.iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4;
-
- rc = cifs_call_async(server, &iov, 1, NULL, cifs_echo_callback,
- server, true);
- if (rc)
- cFYI(1, "Echo request failed: %d", rc);
-
- cifs_small_buf_release(smb);
-
- return rc;
-}
-
-int
-CIFSSMBLogoff(const int xid, struct cifs_ses *ses)
-{
- LOGOFF_ANDX_REQ *pSMB;
- int rc = 0;
-
- cFYI(1, "In SMBLogoff for session disconnect");
-
- /*
- * BB: do we need to check validity of ses and server? They should
- * always be valid since we have an active reference. If not, that
- * should probably be a BUG()
- */
- if (!ses || !ses->server)
- return -EIO;
-
- mutex_lock(&ses->session_mutex);
- if (ses->need_reconnect)
- goto session_already_dead; /* no need to send SMBlogoff if uid
- already closed due to reconnect */
- rc = small_smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL, (void **)&pSMB);
- if (rc) {
- mutex_unlock(&ses->session_mutex);
- return rc;
- }
-
- pSMB->hdr.Mid = GetNextMid(ses->server);
-
- if (ses->server->sec_mode &
- (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
- pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
-
- pSMB->hdr.Uid = ses->Suid;
-
- pSMB->AndXCommand = 0xFF;
- rc = SendReceiveNoRsp(xid, ses, (char *) pSMB, 0);
-session_already_dead:
- mutex_unlock(&ses->session_mutex);
-
- /* if session dead then we do not need to do ulogoff,
- since server closed smb session, no sense reporting
- error */
- if (rc == -EAGAIN)
- rc = 0;
- return rc;
-}
-
-int
-CIFSPOSIXDelFile(const int xid, struct cifs_tcon *tcon, const char *fileName,
- __u16 type, const struct nls_table *nls_codepage, int remap)
-{
- TRANSACTION2_SPI_REQ *pSMB = NULL;
- TRANSACTION2_SPI_RSP *pSMBr = NULL;
- struct unlink_psx_rq *pRqD;
- int name_len;
- int rc = 0;
- int bytes_returned = 0;
- __u16 params, param_offset, offset, byte_count;
-
- cFYI(1, "In POSIX delete");
-PsxDelete:
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len =
- cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
- PATH_MAX, nls_codepage, remap);
- name_len++; /* trailing null */
- name_len *= 2;
- } else { /* BB add path length overrun check */
- name_len = strnlen(fileName, PATH_MAX);
- name_len++; /* trailing null */
- strncpy(pSMB->FileName, fileName, name_len);
- }
-
- params = 6 + name_len;
- pSMB->MaxParameterCount = cpu_to_le16(2);
- pSMB->MaxDataCount = 0; /* BB double check this with jra */
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- param_offset = offsetof(struct smb_com_transaction2_spi_req,
- InformationLevel) - 4;
- offset = param_offset + params;
-
- /* Setup pointer to Request Data (inode type) */
- pRqD = (struct unlink_psx_rq *)(((char *)&pSMB->hdr.Protocol) + offset);
- pRqD->type = cpu_to_le16(type);
- pSMB->ParameterOffset = cpu_to_le16(param_offset);
- pSMB->DataOffset = cpu_to_le16(offset);
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
- byte_count = 3 /* pad */ + params + sizeof(struct unlink_psx_rq);
-
- pSMB->DataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
- pSMB->TotalDataCount = cpu_to_le16(sizeof(struct unlink_psx_rq));
- pSMB->ParameterCount = cpu_to_le16(params);
- pSMB->TotalParameterCount = pSMB->ParameterCount;
- pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_UNLINK);
- pSMB->Reserved4 = 0;
- inc_rfc1001_len(pSMB, byte_count);
- pSMB->ByteCount = cpu_to_le16(byte_count);
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc)
- cFYI(1, "Posix delete returned %d", rc);
- cifs_buf_release(pSMB);
-
- cifs_stats_inc(&tcon->num_deletes);
-
- if (rc == -EAGAIN)
- goto PsxDelete;
-
- return rc;
-}
-
-int
-CIFSSMBDelFile(const int xid, struct cifs_tcon *tcon, const char *fileName,
- const struct nls_table *nls_codepage, int remap)
-{
- DELETE_FILE_REQ *pSMB = NULL;
- DELETE_FILE_RSP *pSMBr = NULL;
- int rc = 0;
- int bytes_returned;
- int name_len;
-
-DelFileRetry:
- rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len =
- cifsConvertToUTF16((__le16 *) pSMB->fileName, fileName,
- PATH_MAX, nls_codepage, remap);
- name_len++; /* trailing null */
- name_len *= 2;
- } else { /* BB improve check for buffer overruns BB */
- name_len = strnlen(fileName, PATH_MAX);
- name_len++; /* trailing null */
- strncpy(pSMB->fileName, fileName, name_len);
- }
- pSMB->SearchAttributes =
- cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
- pSMB->BufferFormat = 0x04;
- inc_rfc1001_len(pSMB, name_len + 1);
- pSMB->ByteCount = cpu_to_le16(name_len + 1);
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- cifs_stats_inc(&tcon->num_deletes);
- if (rc)
- cFYI(1, "Error in RMFile = %d", rc);
-
- cifs_buf_release(pSMB);
- if (rc == -EAGAIN)
- goto DelFileRetry;
-
- return rc;
-}
-
-int
-CIFSSMBRmDir(const int xid, struct cifs_tcon *tcon, const char *dirName,
- const struct nls_table *nls_codepage, int remap)
-{
- DELETE_DIRECTORY_REQ *pSMB = NULL;
- DELETE_DIRECTORY_RSP *pSMBr = NULL;
- int rc = 0;
- int bytes_returned;
- int name_len;
-
- cFYI(1, "In CIFSSMBRmDir");
-RmDirRetry:
- rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, dirName,
- PATH_MAX, nls_codepage, remap);
- name_len++; /* trailing null */
- name_len *= 2;
- } else { /* BB improve check for buffer overruns BB */
- name_len = strnlen(dirName, PATH_MAX);
- name_len++; /* trailing null */
- strncpy(pSMB->DirName, dirName, name_len);
- }
-
- pSMB->BufferFormat = 0x04;
- inc_rfc1001_len(pSMB, name_len + 1);
- pSMB->ByteCount = cpu_to_le16(name_len + 1);
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- cifs_stats_inc(&tcon->num_rmdirs);
- if (rc)
- cFYI(1, "Error in RMDir = %d", rc);
-
- cifs_buf_release(pSMB);
- if (rc == -EAGAIN)
- goto RmDirRetry;
- return rc;
-}
-
-int
-CIFSSMBMkDir(const int xid, struct cifs_tcon *tcon,
- const char *name, const struct nls_table *nls_codepage, int remap)
-{
- int rc = 0;
- CREATE_DIRECTORY_REQ *pSMB = NULL;
- CREATE_DIRECTORY_RSP *pSMBr = NULL;
- int bytes_returned;
- int name_len;
-
- cFYI(1, "In CIFSSMBMkDir");
-MkDirRetry:
- rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name,
- PATH_MAX, nls_codepage, remap);
- name_len++; /* trailing null */
- name_len *= 2;
- } else { /* BB improve check for buffer overruns BB */
- name_len = strnlen(name, PATH_MAX);
- name_len++; /* trailing null */
- strncpy(pSMB->DirName, name, name_len);
- }
-
- pSMB->BufferFormat = 0x04;
- inc_rfc1001_len(pSMB, name_len + 1);
- pSMB->ByteCount = cpu_to_le16(name_len + 1);
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- cifs_stats_inc(&tcon->num_mkdirs);
- if (rc)
- cFYI(1, "Error in Mkdir = %d", rc);
-
- cifs_buf_release(pSMB);
- if (rc == -EAGAIN)
- goto MkDirRetry;
- return rc;
-}
-
-int
-CIFSPOSIXCreate(const int xid, struct cifs_tcon *tcon, __u32 posix_flags,
- __u64 mode, __u16 *netfid, FILE_UNIX_BASIC_INFO *pRetData,
- __u32 *pOplock, const char *name,
- const struct nls_table *nls_codepage, int remap)
-{
- TRANSACTION2_SPI_REQ *pSMB = NULL;
- TRANSACTION2_SPI_RSP *pSMBr = NULL;
- int name_len;
- int rc = 0;
- int bytes_returned = 0;
- __u16 params, param_offset, offset, byte_count, count;
- OPEN_PSX_REQ *pdata;
- OPEN_PSX_RSP *psx_rsp;
-
- cFYI(1, "In POSIX Create");
-PsxCreat:
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len =
- cifsConvertToUTF16((__le16 *) pSMB->FileName, name,
- PATH_MAX, nls_codepage, remap);
- name_len++; /* trailing null */
- name_len *= 2;
- } else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(name, PATH_MAX);
- name_len++; /* trailing null */
- strncpy(pSMB->FileName, name, name_len);
- }
-
- params = 6 + name_len;
- count = sizeof(OPEN_PSX_REQ);
- pSMB->MaxParameterCount = cpu_to_le16(2);
- pSMB->MaxDataCount = cpu_to_le16(1000); /* large enough */
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- param_offset = offsetof(struct smb_com_transaction2_spi_req,
- InformationLevel) - 4;
- offset = param_offset + params;
- pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset);
- pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
- pdata->Permissions = cpu_to_le64(mode);
- pdata->PosixOpenFlags = cpu_to_le32(posix_flags);
- pdata->OpenFlags = cpu_to_le32(*pOplock);
- pSMB->ParameterOffset = cpu_to_le16(param_offset);
- pSMB->DataOffset = cpu_to_le16(offset);
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
- byte_count = 3 /* pad */ + params + count;
-
- pSMB->DataCount = cpu_to_le16(count);
- pSMB->ParameterCount = cpu_to_le16(params);
- pSMB->TotalDataCount = pSMB->DataCount;
- pSMB->TotalParameterCount = pSMB->ParameterCount;
- pSMB->InformationLevel = cpu_to_le16(SMB_POSIX_OPEN);
- pSMB->Reserved4 = 0;
- inc_rfc1001_len(pSMB, byte_count);
- pSMB->ByteCount = cpu_to_le16(byte_count);
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc) {
- cFYI(1, "Posix create returned %d", rc);
- goto psx_create_err;
- }
-
- cFYI(1, "copying inode info");
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
-
- if (rc || get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)) {
- rc = -EIO; /* bad smb */
- goto psx_create_err;
- }
-
- /* copy return information to pRetData */
- psx_rsp = (OPEN_PSX_RSP *)((char *) &pSMBr->hdr.Protocol
- + le16_to_cpu(pSMBr->t2.DataOffset));
-
- *pOplock = le16_to_cpu(psx_rsp->OplockFlags);
- if (netfid)
- *netfid = psx_rsp->Fid; /* cifs fid stays in le */
- /* Let caller know file was created so we can set the mode. */
- /* Do we care about the CreateAction in any other cases? */
- if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction)
- *pOplock |= CIFS_CREATE_ACTION;
- /* check to make sure response data is there */
- if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) {
- pRetData->Type = cpu_to_le32(-1); /* unknown */
- cFYI(DBG2, "unknown type");
- } else {
- if (get_bcc(&pSMBr->hdr) < sizeof(OPEN_PSX_RSP)
- + sizeof(FILE_UNIX_BASIC_INFO)) {
- cERROR(1, "Open response data too small");
- pRetData->Type = cpu_to_le32(-1);
- goto psx_create_err;
- }
- memcpy((char *) pRetData,
- (char *)psx_rsp + sizeof(OPEN_PSX_RSP),
- sizeof(FILE_UNIX_BASIC_INFO));
- }
-
-psx_create_err:
- cifs_buf_release(pSMB);
-
- if (posix_flags & SMB_O_DIRECTORY)
- cifs_stats_inc(&tcon->num_posixmkdirs);
- else
- cifs_stats_inc(&tcon->num_posixopens);
-
- if (rc == -EAGAIN)
- goto PsxCreat;
-
- return rc;
-}
-
-static __u16 convert_disposition(int disposition)
-{
- __u16 ofun = 0;
-
- switch (disposition) {
- case FILE_SUPERSEDE:
- ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
- break;
- case FILE_OPEN:
- ofun = SMBOPEN_OAPPEND;
- break;
- case FILE_CREATE:
- ofun = SMBOPEN_OCREATE;
- break;
- case FILE_OPEN_IF:
- ofun = SMBOPEN_OCREATE | SMBOPEN_OAPPEND;
- break;
- case FILE_OVERWRITE:
- ofun = SMBOPEN_OTRUNC;
- break;
- case FILE_OVERWRITE_IF:
- ofun = SMBOPEN_OCREATE | SMBOPEN_OTRUNC;
- break;
- default:
- cFYI(1, "unknown disposition %d", disposition);
- ofun = SMBOPEN_OAPPEND; /* regular open */
- }
- return ofun;
-}
-
-static int
-access_flags_to_smbopen_mode(const int access_flags)
-{
- int masked_flags = access_flags & (GENERIC_READ | GENERIC_WRITE);
-
- if (masked_flags == GENERIC_READ)
- return SMBOPEN_READ;
- else if (masked_flags == GENERIC_WRITE)
- return SMBOPEN_WRITE;
-
- /* just go for read/write */
- return SMBOPEN_READWRITE;
-}
-
-int
-SMBLegacyOpen(const int xid, struct cifs_tcon *tcon,
- const char *fileName, const int openDisposition,
- const int access_flags, const int create_options, __u16 *netfid,
- int *pOplock, FILE_ALL_INFO *pfile_info,
- const struct nls_table *nls_codepage, int remap)
-{
- int rc = -EACCES;
- OPENX_REQ *pSMB = NULL;
- OPENX_RSP *pSMBr = NULL;
- int bytes_returned;
- int name_len;
- __u16 count;
-
-OldOpenRetry:
- rc = smb_init(SMB_COM_OPEN_ANDX, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- pSMB->AndXCommand = 0xFF; /* none */
-
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- count = 1; /* account for one byte pad to word boundary */
- name_len =
- cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
- fileName, PATH_MAX, nls_codepage, remap);
- name_len++; /* trailing null */
- name_len *= 2;
- } else { /* BB improve check for buffer overruns BB */
- count = 0; /* no pad */
- name_len = strnlen(fileName, PATH_MAX);
- name_len++; /* trailing null */
- strncpy(pSMB->fileName, fileName, name_len);
- }
- if (*pOplock & REQ_OPLOCK)
- pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK);
- else if (*pOplock & REQ_BATCHOPLOCK)
- pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK);
-
- pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO);
- pSMB->Mode = cpu_to_le16(access_flags_to_smbopen_mode(access_flags));
- pSMB->Mode |= cpu_to_le16(0x40); /* deny none */
- /* set file as system file if special file such
- as fifo and server expecting SFU style and
- no Unix extensions */
-
- if (create_options & CREATE_OPTION_SPECIAL)
- pSMB->FileAttributes = cpu_to_le16(ATTR_SYSTEM);
- else /* BB FIXME BB */
- pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/);
-
- if (create_options & CREATE_OPTION_READONLY)
- pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY);
-
- /* BB FIXME BB */
-/* pSMB->CreateOptions = cpu_to_le32(create_options &
- CREATE_OPTIONS_MASK); */
- /* BB FIXME END BB */
-
- pSMB->Sattr = cpu_to_le16(ATTR_HIDDEN | ATTR_SYSTEM | ATTR_DIRECTORY);
- pSMB->OpenFunction = cpu_to_le16(convert_disposition(openDisposition));
- count += name_len;
- inc_rfc1001_len(pSMB, count);
-
- pSMB->ByteCount = cpu_to_le16(count);
- /* long_op set to 1 to allow for oplock break timeouts */
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *)pSMBr, &bytes_returned, 0);
- cifs_stats_inc(&tcon->num_opens);
- if (rc) {
- cFYI(1, "Error in Open = %d", rc);
- } else {
- /* BB verify if wct == 15 */
-
-/* *pOplock = pSMBr->OplockLevel; */ /* BB take from action field*/
-
- *netfid = pSMBr->Fid; /* cifs fid stays in le */
- /* Let caller know file was created so we can set the mode. */
- /* Do we care about the CreateAction in any other cases? */
- /* BB FIXME BB */
-/* if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
- *pOplock |= CIFS_CREATE_ACTION; */
- /* BB FIXME END */
-
- if (pfile_info) {
- pfile_info->CreationTime = 0; /* BB convert CreateTime*/
- pfile_info->LastAccessTime = 0; /* BB fixme */
- pfile_info->LastWriteTime = 0; /* BB fixme */
- pfile_info->ChangeTime = 0; /* BB fixme */
- pfile_info->Attributes =
- cpu_to_le32(le16_to_cpu(pSMBr->FileAttributes));
- /* the file_info buf is endian converted by caller */
- pfile_info->AllocationSize =
- cpu_to_le64(le32_to_cpu(pSMBr->EndOfFile));
- pfile_info->EndOfFile = pfile_info->AllocationSize;
- pfile_info->NumberOfLinks = cpu_to_le32(1);
- pfile_info->DeletePending = 0;
- }
- }
-
- cifs_buf_release(pSMB);
- if (rc == -EAGAIN)
- goto OldOpenRetry;
- return rc;
-}
-
-int
-CIFSSMBOpen(const int xid, struct cifs_tcon *tcon,
- const char *fileName, const int openDisposition,
- const int access_flags, const int create_options, __u16 *netfid,
- int *pOplock, FILE_ALL_INFO *pfile_info,
- const struct nls_table *nls_codepage, int remap)
-{
- int rc = -EACCES;
- OPEN_REQ *pSMB = NULL;
- OPEN_RSP *pSMBr = NULL;
- int bytes_returned;
- int name_len;
- __u16 count;
-
-openRetry:
- rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- pSMB->AndXCommand = 0xFF; /* none */
-
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- count = 1; /* account for one byte pad to word boundary */
- name_len =
- cifsConvertToUTF16((__le16 *) (pSMB->fileName + 1),
- fileName, PATH_MAX, nls_codepage, remap);
- name_len++; /* trailing null */
- name_len *= 2;
- pSMB->NameLength = cpu_to_le16(name_len);
- } else { /* BB improve check for buffer overruns BB */
- count = 0; /* no pad */
- name_len = strnlen(fileName, PATH_MAX);
- name_len++; /* trailing null */
- pSMB->NameLength = cpu_to_le16(name_len);
- strncpy(pSMB->fileName, fileName, name_len);
- }
- if (*pOplock & REQ_OPLOCK)
- pSMB->OpenFlags = cpu_to_le32(REQ_OPLOCK);
- else if (*pOplock & REQ_BATCHOPLOCK)
- pSMB->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
- pSMB->DesiredAccess = cpu_to_le32(access_flags);
- pSMB->AllocationSize = 0;
- /* set file as system file if special file such
- as fifo and server expecting SFU style and
- no Unix extensions */
- if (create_options & CREATE_OPTION_SPECIAL)
- pSMB->FileAttributes = cpu_to_le32(ATTR_SYSTEM);
- else
- pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL);
-
- /* XP does not handle ATTR_POSIX_SEMANTICS */
- /* but it helps speed up case sensitive checks for other
- servers such as Samba */
- if (tcon->ses->capabilities & CAP_UNIX)
- pSMB->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS);
-
- if (create_options & CREATE_OPTION_READONLY)
- pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);
-
- pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
- pSMB->CreateDisposition = cpu_to_le32(openDisposition);
- pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK);
- /* BB Expirement with various impersonation levels and verify */
- pSMB->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION);
- pSMB->SecurityFlags =
- SECURITY_CONTEXT_TRACKING | SECURITY_EFFECTIVE_ONLY;
-
- count += name_len;
- inc_rfc1001_len(pSMB, count);
-
- pSMB->ByteCount = cpu_to_le16(count);
- /* long_op set to 1 to allow for oplock break timeouts */
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *)pSMBr, &bytes_returned, 0);
- cifs_stats_inc(&tcon->num_opens);
- if (rc) {
- cFYI(1, "Error in Open = %d", rc);
- } else {
- *pOplock = pSMBr->OplockLevel; /* 1 byte no need to le_to_cpu */
- *netfid = pSMBr->Fid; /* cifs fid stays in le */
- /* Let caller know file was created so we can set the mode. */
- /* Do we care about the CreateAction in any other cases? */
- if (cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
- *pOplock |= CIFS_CREATE_ACTION;
- if (pfile_info) {
- memcpy((char *)pfile_info, (char *)&pSMBr->CreationTime,
- 36 /* CreationTime to Attributes */);
- /* the file_info buf is endian converted by caller */
- pfile_info->AllocationSize = pSMBr->AllocationSize;
- pfile_info->EndOfFile = pSMBr->EndOfFile;
- pfile_info->NumberOfLinks = cpu_to_le32(1);
- pfile_info->DeletePending = 0;
- }
- }
-
- cifs_buf_release(pSMB);
- if (rc == -EAGAIN)
- goto openRetry;
- return rc;
-}
-
-struct cifs_readdata *
-cifs_readdata_alloc(unsigned int nr_pages)
-{
- struct cifs_readdata *rdata;
-
- /* readdata + 1 kvec for each page */
- rdata = kzalloc(sizeof(*rdata) +
- sizeof(struct kvec) * nr_pages, GFP_KERNEL);
- if (rdata != NULL) {
- INIT_WORK(&rdata->work, cifs_readv_complete);
- INIT_LIST_HEAD(&rdata->pages);
- }
- return rdata;
-}
-
-void
-cifs_readdata_free(struct cifs_readdata *rdata)
-{
- cifsFileInfo_put(rdata->cfile);
- kfree(rdata);
-}
-
-/*
- * Discard any remaining data in the current SMB. To do this, we borrow the
- * current bigbuf.
- */
-static int
-cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
-{
- unsigned int rfclen = get_rfc1002_length(server->smallbuf);
- int remaining = rfclen + 4 - server->total_read;
- struct cifs_readdata *rdata = mid->callback_data;
-
- while (remaining > 0) {
- int length;
-
- length = cifs_read_from_socket(server, server->bigbuf,
- min_t(unsigned int, remaining,
- CIFSMaxBufSize + max_header_size()));
- if (length < 0)
- return length;
- server->total_read += length;
- remaining -= length;
- }
-
- dequeue_mid(mid, rdata->result);
- return 0;
-}
-
-static inline size_t
-read_rsp_size(void)
-{
- return sizeof(READ_RSP);
-}
-
-static inline unsigned int
-read_data_offset(char *buf)
-{
- READ_RSP *rsp = (READ_RSP *)buf;
- return le16_to_cpu(rsp->DataOffset);
-}
-
-static inline unsigned int
-read_data_length(char *buf)
-{
- READ_RSP *rsp = (READ_RSP *)buf;
- return (le16_to_cpu(rsp->DataLengthHigh) << 16) +
- le16_to_cpu(rsp->DataLength);
-}
-
-static int
-cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
-{
- int length, len;
- unsigned int data_offset, remaining, data_len;
- struct cifs_readdata *rdata = mid->callback_data;
- char *buf = server->smallbuf;
- unsigned int buflen = get_rfc1002_length(buf) + 4;
- u64 eof;
- pgoff_t eof_index;
- struct page *page, *tpage;
-
- cFYI(1, "%s: mid=%llu offset=%llu bytes=%u", __func__,
- mid->mid, rdata->offset, rdata->bytes);
-
- /*
- * read the rest of READ_RSP header (sans Data array), or whatever we
- * can if there's not enough data. At this point, we've read down to
- * the Mid.
- */
- len = min_t(unsigned int, buflen, read_rsp_size()) - header_size() + 1;
-
- rdata->iov[0].iov_base = buf + header_size() - 1;
- rdata->iov[0].iov_len = len;
-
- length = cifs_readv_from_socket(server, rdata->iov, 1, len);
- if (length < 0)
- return length;
- server->total_read += length;
-
- /* Was the SMB read successful? */
- rdata->result = map_smb_to_linux_error(buf, false);
- if (rdata->result != 0) {
- cFYI(1, "%s: server returned error %d", __func__,
- rdata->result);
- return cifs_readv_discard(server, mid);
- }
-
- /* Is there enough to get to the rest of the READ_RSP header? */
- if (server->total_read < read_rsp_size()) {
- cFYI(1, "%s: server returned short header. got=%u expected=%zu",
- __func__, server->total_read, read_rsp_size());
- rdata->result = -EIO;
- return cifs_readv_discard(server, mid);
- }
-
- data_offset = read_data_offset(buf) + 4;
- if (data_offset < server->total_read) {
- /*
- * win2k8 sometimes sends an offset of 0 when the read
- * is beyond the EOF. Treat it as if the data starts just after
- * the header.
- */
- cFYI(1, "%s: data offset (%u) inside read response header",
- __func__, data_offset);
- data_offset = server->total_read;
- } else if (data_offset > MAX_CIFS_SMALL_BUFFER_SIZE) {
- /* data_offset is beyond the end of smallbuf */
- cFYI(1, "%s: data offset (%u) beyond end of smallbuf",
- __func__, data_offset);
- rdata->result = -EIO;
- return cifs_readv_discard(server, mid);
- }
-
- cFYI(1, "%s: total_read=%u data_offset=%u", __func__,
- server->total_read, data_offset);
-
- len = data_offset - server->total_read;
- if (len > 0) {
- /* read any junk before data into the rest of smallbuf */
- rdata->iov[0].iov_base = buf + server->total_read;
- rdata->iov[0].iov_len = len;
- length = cifs_readv_from_socket(server, rdata->iov, 1, len);
- if (length < 0)
- return length;
- server->total_read += length;
- }
-
- /* set up first iov for signature check */
- rdata->iov[0].iov_base = buf;
- rdata->iov[0].iov_len = server->total_read;
- cFYI(1, "0: iov_base=%p iov_len=%zu",
- rdata->iov[0].iov_base, rdata->iov[0].iov_len);
-
- /* how much data is in the response? */
- data_len = read_data_length(buf);
- if (data_offset + data_len > buflen) {
- /* data_len is corrupt -- discard frame */
- rdata->result = -EIO;
- return cifs_readv_discard(server, mid);
- }
-
- /* marshal up the page array */
- len = 0;
- remaining = data_len;
- rdata->nr_iov = 1;
-
- /* determine the eof that the server (probably) has */
- eof = CIFS_I(rdata->mapping->host)->server_eof;
- eof_index = eof ? (eof - 1) >> PAGE_CACHE_SHIFT : 0;
- cFYI(1, "eof=%llu eof_index=%lu", eof, eof_index);
-
- list_for_each_entry_safe(page, tpage, &rdata->pages, lru) {
- if (remaining >= PAGE_CACHE_SIZE) {
- /* enough data to fill the page */
- rdata->iov[rdata->nr_iov].iov_base = kmap(page);
- rdata->iov[rdata->nr_iov].iov_len = PAGE_CACHE_SIZE;
- cFYI(1, "%u: idx=%lu iov_base=%p iov_len=%zu",
- rdata->nr_iov, page->index,
- rdata->iov[rdata->nr_iov].iov_base,
- rdata->iov[rdata->nr_iov].iov_len);
- ++rdata->nr_iov;
- len += PAGE_CACHE_SIZE;
- remaining -= PAGE_CACHE_SIZE;
- } else if (remaining > 0) {
- /* enough for partial page, fill and zero the rest */
- rdata->iov[rdata->nr_iov].iov_base = kmap(page);
- rdata->iov[rdata->nr_iov].iov_len = remaining;
- cFYI(1, "%u: idx=%lu iov_base=%p iov_len=%zu",
- rdata->nr_iov, page->index,
- rdata->iov[rdata->nr_iov].iov_base,
- rdata->iov[rdata->nr_iov].iov_len);
- memset(rdata->iov[rdata->nr_iov].iov_base + remaining,
- '\0', PAGE_CACHE_SIZE - remaining);
- ++rdata->nr_iov;
- len += remaining;
- remaining = 0;
- } else if (page->index > eof_index) {
- /*
- * The VFS will not try to do readahead past the
- * i_size, but it's possible that we have outstanding
- * writes with gaps in the middle and the i_size hasn't
- * caught up yet. Populate those with zeroed out pages
- * to prevent the VFS from repeatedly attempting to
- * fill them until the writes are flushed.
- */
- zero_user(page, 0, PAGE_CACHE_SIZE);
- list_del(&page->lru);
- lru_cache_add_file(page);
- flush_dcache_page(page);
- SetPageUptodate(page);
- unlock_page(page);
- page_cache_release(page);
- } else {
- /* no need to hold page hostage */
- list_del(&page->lru);
- lru_cache_add_file(page);
- unlock_page(page);
- page_cache_release(page);
- }
- }
-
- /* issue the read if we have any iovecs left to fill */
- if (rdata->nr_iov > 1) {
- length = cifs_readv_from_socket(server, &rdata->iov[1],
- rdata->nr_iov - 1, len);
- if (length < 0)
- return length;
- server->total_read += length;
- } else {
- length = 0;
- }
-
- rdata->bytes = length;
-
- cFYI(1, "total_read=%u buflen=%u remaining=%u", server->total_read,
- buflen, remaining);
-
- /* discard anything left over */
- if (server->total_read < buflen)
- return cifs_readv_discard(server, mid);
-
- dequeue_mid(mid, false);
- return length;
-}
-
-static void
-cifs_readv_complete(struct work_struct *work)
-{
- struct cifs_readdata *rdata = container_of(work,
- struct cifs_readdata, work);
- struct page *page, *tpage;
-
- list_for_each_entry_safe(page, tpage, &rdata->pages, lru) {
- list_del(&page->lru);
- lru_cache_add_file(page);
-
- if (rdata->result == 0) {
- kunmap(page);
- flush_dcache_page(page);
- SetPageUptodate(page);
- }
-
- unlock_page(page);
-
- if (rdata->result == 0)
- cifs_readpage_to_fscache(rdata->mapping->host, page);
-
- page_cache_release(page);
- }
- cifs_readdata_free(rdata);
-}
-
-static void
-cifs_readv_callback(struct mid_q_entry *mid)
-{
- struct cifs_readdata *rdata = mid->callback_data;
- struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
- struct TCP_Server_Info *server = tcon->ses->server;
-
- cFYI(1, "%s: mid=%llu state=%d result=%d bytes=%u", __func__,
- mid->mid, mid->mid_state, rdata->result, rdata->bytes);
-
- switch (mid->mid_state) {
- case MID_RESPONSE_RECEIVED:
- /* result already set, check signature */
- if (server->sec_mode &
- (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
- if (cifs_verify_signature(rdata->iov, rdata->nr_iov,
- server, mid->sequence_number + 1))
- cERROR(1, "Unexpected SMB signature");
- }
- /* FIXME: should this be counted toward the initiating task? */
- task_io_account_read(rdata->bytes);
- cifs_stats_bytes_read(tcon, rdata->bytes);
- break;
- case MID_REQUEST_SUBMITTED:
- case MID_RETRY_NEEDED:
- rdata->result = -EAGAIN;
- break;
- default:
- rdata->result = -EIO;
- }
-
- queue_work(cifsiod_wq, &rdata->work);
- DeleteMidQEntry(mid);
- cifs_add_credits(server, 1);
-}
-
-/* cifs_async_readv - send an async write, and set up mid to handle result */
-int
-cifs_async_readv(struct cifs_readdata *rdata)
-{
- int rc;
- READ_REQ *smb = NULL;
- int wct;
- struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
-
- cFYI(1, "%s: offset=%llu bytes=%u", __func__,
- rdata->offset, rdata->bytes);
-
- if (tcon->ses->capabilities & CAP_LARGE_FILES)
- wct = 12;
- else {
- wct = 10; /* old style read */
- if ((rdata->offset >> 32) > 0) {
- /* can not handle this big offset for old */
- return -EIO;
- }
- }
-
- rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **)&smb);
- if (rc)
- return rc;
-
- smb->hdr.Pid = cpu_to_le16((__u16)rdata->pid);
- smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
-
- smb->AndXCommand = 0xFF; /* none */
- smb->Fid = rdata->cfile->netfid;
- smb->OffsetLow = cpu_to_le32(rdata->offset & 0xFFFFFFFF);
- if (wct == 12)
- smb->OffsetHigh = cpu_to_le32(rdata->offset >> 32);
- smb->Remaining = 0;
- smb->MaxCount = cpu_to_le16(rdata->bytes & 0xFFFF);
- smb->MaxCountHigh = cpu_to_le32(rdata->bytes >> 16);
- if (wct == 12)
- smb->ByteCount = 0;
- else {
- /* old style read */
- struct smb_com_readx_req *smbr =
- (struct smb_com_readx_req *)smb;
- smbr->ByteCount = 0;
- }
-
- /* 4 for RFC1001 length + 1 for BCC */
- rdata->iov[0].iov_base = smb;
- rdata->iov[0].iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4;
-
- rc = cifs_call_async(tcon->ses->server, rdata->iov, 1,
- cifs_readv_receive, cifs_readv_callback,
- rdata, false);
-
- if (rc == 0)
- cifs_stats_inc(&tcon->num_reads);
-
- cifs_small_buf_release(smb);
- return rc;
-}
-
-int
-CIFSSMBRead(const int xid, struct cifs_io_parms *io_parms, unsigned int *nbytes,
- char **buf, int *pbuf_type)
-{
- int rc = -EACCES;
- READ_REQ *pSMB = NULL;
- READ_RSP *pSMBr = NULL;
- char *pReadData = NULL;
- int wct;
- int resp_buf_type = 0;
- struct kvec iov[1];
- __u32 pid = io_parms->pid;
- __u16 netfid = io_parms->netfid;
- __u64 offset = io_parms->offset;
- struct cifs_tcon *tcon = io_parms->tcon;
- unsigned int count = io_parms->length;
-
- cFYI(1, "Reading %d bytes on fid %d", count, netfid);
- if (tcon->ses->capabilities & CAP_LARGE_FILES)
- wct = 12;
- else {
- wct = 10; /* old style read */
- if ((offset >> 32) > 0) {
- /* can not handle this big offset for old */
- return -EIO;
- }
- }
-
- *nbytes = 0;
- rc = small_smb_init(SMB_COM_READ_ANDX, wct, tcon, (void **) &pSMB);
- if (rc)
- return rc;
-
- pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
- pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
-
- /* tcon and ses pointer are checked in smb_init */
- if (tcon->ses->server == NULL)
- return -ECONNABORTED;
-
- pSMB->AndXCommand = 0xFF; /* none */
- pSMB->Fid = netfid;
- pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
- if (wct == 12)
- pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
-
- pSMB->Remaining = 0;
- pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
- pSMB->MaxCountHigh = cpu_to_le32(count >> 16);
- if (wct == 12)
- pSMB->ByteCount = 0; /* no need to do le conversion since 0 */
- else {
- /* old style read */
- struct smb_com_readx_req *pSMBW =
- (struct smb_com_readx_req *)pSMB;
- pSMBW->ByteCount = 0;
- }
-
- iov[0].iov_base = (char *)pSMB;
- iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
- rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
- &resp_buf_type, CIFS_LOG_ERROR);
- cifs_stats_inc(&tcon->num_reads);
- pSMBr = (READ_RSP *)iov[0].iov_base;
- if (rc) {
- cERROR(1, "Send error in read = %d", rc);
- } else {
- int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
- data_length = data_length << 16;
- data_length += le16_to_cpu(pSMBr->DataLength);
- *nbytes = data_length;
-
- /*check that DataLength would not go beyond end of SMB */
- if ((data_length > CIFSMaxBufSize)
- || (data_length > count)) {
- cFYI(1, "bad length %d for count %d",
- data_length, count);
- rc = -EIO;
- *nbytes = 0;
- } else {
- pReadData = (char *) (&pSMBr->hdr.Protocol) +
- le16_to_cpu(pSMBr->DataOffset);
-/* if (rc = copy_to_user(buf, pReadData, data_length)) {
- cERROR(1, "Faulting on read rc = %d",rc);
- rc = -EFAULT;
- }*/ /* can not use copy_to_user when using page cache*/
- if (*buf)
- memcpy(*buf, pReadData, data_length);
- }
- }
-
-/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
- if (*buf) {
- if (resp_buf_type == CIFS_SMALL_BUFFER)
- cifs_small_buf_release(iov[0].iov_base);
- else if (resp_buf_type == CIFS_LARGE_BUFFER)
- cifs_buf_release(iov[0].iov_base);
- } else if (resp_buf_type != CIFS_NO_BUFFER) {
- /* return buffer to caller to free */
- *buf = iov[0].iov_base;
- if (resp_buf_type == CIFS_SMALL_BUFFER)
- *pbuf_type = CIFS_SMALL_BUFFER;
- else if (resp_buf_type == CIFS_LARGE_BUFFER)
- *pbuf_type = CIFS_LARGE_BUFFER;
- } /* else no valid buffer on return - leave as null */
-
- /* Note: On -EAGAIN error only caller can retry on handle based calls
- since file handle passed in no longer valid */
- return rc;
-}
-
-
-int
-CIFSSMBWrite(const int xid, struct cifs_io_parms *io_parms,
- unsigned int *nbytes, const char *buf,
- const char __user *ubuf, const int long_op)
-{
- int rc = -EACCES;
- WRITE_REQ *pSMB = NULL;
- WRITE_RSP *pSMBr = NULL;
- int bytes_returned, wct;
- __u32 bytes_sent;
- __u16 byte_count;
- __u32 pid = io_parms->pid;
- __u16 netfid = io_parms->netfid;
- __u64 offset = io_parms->offset;
- struct cifs_tcon *tcon = io_parms->tcon;
- unsigned int count = io_parms->length;
-
- *nbytes = 0;
-
- /* cFYI(1, "write at %lld %d bytes", offset, count);*/
- if (tcon->ses == NULL)
- return -ECONNABORTED;
-
- if (tcon->ses->capabilities & CAP_LARGE_FILES)
- wct = 14;
- else {
- wct = 12;
- if ((offset >> 32) > 0) {
- /* can not handle big offset for old srv */
- return -EIO;
- }
- }
-
- rc = smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
- pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
-
- /* tcon and ses pointer are checked in smb_init */
- if (tcon->ses->server == NULL)
- return -ECONNABORTED;
-
- pSMB->AndXCommand = 0xFF; /* none */
- pSMB->Fid = netfid;
- pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
- if (wct == 14)
- pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
-
- pSMB->Reserved = 0xFFFFFFFF;
- pSMB->WriteMode = 0;
- pSMB->Remaining = 0;
-
- /* Can increase buffer size if buffer is big enough in some cases ie we
- can send more if LARGE_WRITE_X capability returned by the server and if
- our buffer is big enough or if we convert to iovecs on socket writes
- and eliminate the copy to the CIFS buffer */
- if (tcon->ses->capabilities & CAP_LARGE_WRITE_X) {
- bytes_sent = min_t(const unsigned int, CIFSMaxBufSize, count);
- } else {
- bytes_sent = (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE)
- & ~0xFF;
- }
-
- if (bytes_sent > count)
- bytes_sent = count;
- pSMB->DataOffset =
- cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
- if (buf)
- memcpy(pSMB->Data, buf, bytes_sent);
- else if (ubuf) {
- if (copy_from_user(pSMB->Data, ubuf, bytes_sent)) {
- cifs_buf_release(pSMB);
- return -EFAULT;
- }
- } else if (count != 0) {
- /* No buffer */
- cifs_buf_release(pSMB);
- return -EINVAL;
- } /* else setting file size with write of zero bytes */
- if (wct == 14)
- byte_count = bytes_sent + 1; /* pad */
- else /* wct == 12 */
- byte_count = bytes_sent + 5; /* bigger pad, smaller smb hdr */
-
- pSMB->DataLengthLow = cpu_to_le16(bytes_sent & 0xFFFF);
- pSMB->DataLengthHigh = cpu_to_le16(bytes_sent >> 16);
- inc_rfc1001_len(pSMB, byte_count);
-
- if (wct == 14)
- pSMB->ByteCount = cpu_to_le16(byte_count);
- else { /* old style write has byte count 4 bytes earlier
- so 4 bytes pad */
- struct smb_com_writex_req *pSMBW =
- (struct smb_com_writex_req *)pSMB;
- pSMBW->ByteCount = cpu_to_le16(byte_count);
- }
-
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, long_op);
- cifs_stats_inc(&tcon->num_writes);
- if (rc) {
- cFYI(1, "Send error in write = %d", rc);
- } else {
- *nbytes = le16_to_cpu(pSMBr->CountHigh);
- *nbytes = (*nbytes) << 16;
- *nbytes += le16_to_cpu(pSMBr->Count);
-
- /*
- * Mask off high 16 bits when bytes written as returned by the
- * server is greater than bytes requested by the client. Some
- * OS/2 servers are known to set incorrect CountHigh values.
- */
- if (*nbytes > count)
- *nbytes &= 0xFFFF;
- }
-
- cifs_buf_release(pSMB);
-
- /* Note: On -EAGAIN error only caller can retry on handle based calls
- since file handle passed in no longer valid */
-
- return rc;
-}
-
-void
-cifs_writedata_release(struct kref *refcount)
-{
- struct cifs_writedata *wdata = container_of(refcount,
- struct cifs_writedata, refcount);
-
- if (wdata->cfile)
- cifsFileInfo_put(wdata->cfile);
-
- kfree(wdata);
-}
-
-/*
- * Write failed with a retryable error. Resend the write request. It's also
- * possible that the page was redirtied so re-clean the page.
- */
-static void
-cifs_writev_requeue(struct cifs_writedata *wdata)
-{
- int i, rc;
- struct inode *inode = wdata->cfile->dentry->d_inode;
-
- for (i = 0; i < wdata->nr_pages; i++) {
- lock_page(wdata->pages[i]);
- clear_page_dirty_for_io(wdata->pages[i]);
- }
-
- do {
- rc = cifs_async_writev(wdata);
- } while (rc == -EAGAIN);
-
- for (i = 0; i < wdata->nr_pages; i++) {
- if (rc != 0)
- SetPageError(wdata->pages[i]);
- unlock_page(wdata->pages[i]);
- }
-
- mapping_set_error(inode->i_mapping, rc);
- kref_put(&wdata->refcount, cifs_writedata_release);
-}
-
-void
-cifs_writev_complete(struct work_struct *work)
-{
- struct cifs_writedata *wdata = container_of(work,
- struct cifs_writedata, work);
- struct inode *inode = wdata->cfile->dentry->d_inode;
- int i = 0;
-
- if (wdata->result == 0) {
- spin_lock(&inode->i_lock);
- cifs_update_eof(CIFS_I(inode), wdata->offset, wdata->bytes);
- spin_unlock(&inode->i_lock);
- cifs_stats_bytes_written(tlink_tcon(wdata->cfile->tlink),
- wdata->bytes);
- } else if (wdata->sync_mode == WB_SYNC_ALL && wdata->result == -EAGAIN)
- return cifs_writev_requeue(wdata);
-
- for (i = 0; i < wdata->nr_pages; i++) {
- struct page *page = wdata->pages[i];
- if (wdata->result == -EAGAIN)
- __set_page_dirty_nobuffers(page);
- else if (wdata->result < 0)
- SetPageError(page);
- end_page_writeback(page);
- page_cache_release(page);
- }
- if (wdata->result != -EAGAIN)
- mapping_set_error(inode->i_mapping, wdata->result);
- kref_put(&wdata->refcount, cifs_writedata_release);
-}
-
-struct cifs_writedata *
-cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete)
-{
- struct cifs_writedata *wdata;
-
- /* this would overflow */
- if (nr_pages == 0) {
- cERROR(1, "%s: called with nr_pages == 0!", __func__);
- return NULL;
- }
-
- /* writedata + number of page pointers */
- wdata = kzalloc(sizeof(*wdata) +
- sizeof(struct page *) * (nr_pages - 1), GFP_NOFS);
- if (wdata != NULL) {
- kref_init(&wdata->refcount);
- INIT_LIST_HEAD(&wdata->list);
- init_completion(&wdata->done);
- INIT_WORK(&wdata->work, complete);
- }
- return wdata;
-}
-
-/*
- * Check the mid_state and signature on received buffer (if any), and queue the
- * workqueue completion task.
- */
-static void
-cifs_writev_callback(struct mid_q_entry *mid)
-{
- struct cifs_writedata *wdata = mid->callback_data;
- struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
- unsigned int written;
- WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
-
- switch (mid->mid_state) {
- case MID_RESPONSE_RECEIVED:
- wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
- if (wdata->result != 0)
- break;
-
- written = le16_to_cpu(smb->CountHigh);
- written <<= 16;
- written += le16_to_cpu(smb->Count);
- /*
- * Mask off high 16 bits when bytes written as returned
- * by the server is greater than bytes requested by the
- * client. OS/2 servers are known to set incorrect
- * CountHigh values.
- */
- if (written > wdata->bytes)
- written &= 0xFFFF;
-
- if (written < wdata->bytes)
- wdata->result = -ENOSPC;
- else
- wdata->bytes = written;
- break;
- case MID_REQUEST_SUBMITTED:
- case MID_RETRY_NEEDED:
- wdata->result = -EAGAIN;
- break;
- default:
- wdata->result = -EIO;
- break;
- }
-
- queue_work(cifsiod_wq, &wdata->work);
- DeleteMidQEntry(mid);
- cifs_add_credits(tcon->ses->server, 1);
-}
-
-/* cifs_async_writev - send an async write, and set up mid to handle result */
-int
-cifs_async_writev(struct cifs_writedata *wdata)
-{
- int i, rc = -EACCES;
- WRITE_REQ *smb = NULL;
- int wct;
- struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
- struct kvec *iov = NULL;
-
- if (tcon->ses->capabilities & CAP_LARGE_FILES) {
- wct = 14;
- } else {
- wct = 12;
- if (wdata->offset >> 32 > 0) {
- /* can not handle big offset for old srv */
- return -EIO;
- }
- }
-
- rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **)&smb);
- if (rc)
- goto async_writev_out;
-
- /* 1 iov per page + 1 for header */
- iov = kzalloc((wdata->nr_pages + 1) * sizeof(*iov), GFP_NOFS);
- if (iov == NULL) {
- rc = -ENOMEM;
- goto async_writev_out;
- }
-
- smb->hdr.Pid = cpu_to_le16((__u16)wdata->pid);
- smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
-
- smb->AndXCommand = 0xFF; /* none */
- smb->Fid = wdata->cfile->netfid;
- smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
- if (wct == 14)
- smb->OffsetHigh = cpu_to_le32(wdata->offset >> 32);
- smb->Reserved = 0xFFFFFFFF;
- smb->WriteMode = 0;
- smb->Remaining = 0;
-
- smb->DataOffset =
- cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
-
- /* 4 for RFC1001 length + 1 for BCC */
- iov[0].iov_len = be32_to_cpu(smb->hdr.smb_buf_length) + 4 + 1;
- iov[0].iov_base = smb;
-
- /*
- * This function should marshal up the page array into the kvec
- * array, reserving [0] for the header. It should kmap the pages
- * and set the iov_len properly for each one. It may also set
- * wdata->bytes too.
- */
- wdata->marshal_iov(iov, wdata);
-
- cFYI(1, "async write at %llu %u bytes", wdata->offset, wdata->bytes);
-
- smb->DataLengthLow = cpu_to_le16(wdata->bytes & 0xFFFF);
- smb->DataLengthHigh = cpu_to_le16(wdata->bytes >> 16);
-
- if (wct == 14) {
- inc_rfc1001_len(&smb->hdr, wdata->bytes + 1);
- put_bcc(wdata->bytes + 1, &smb->hdr);
- } else {
- /* wct == 12 */
- struct smb_com_writex_req *smbw =
- (struct smb_com_writex_req *)smb;
- inc_rfc1001_len(&smbw->hdr, wdata->bytes + 5);
- put_bcc(wdata->bytes + 5, &smbw->hdr);
- iov[0].iov_len += 4; /* pad bigger by four bytes */
- }
-
- kref_get(&wdata->refcount);
- rc = cifs_call_async(tcon->ses->server, iov, wdata->nr_pages + 1,
- NULL, cifs_writev_callback, wdata, false);
-
- if (rc == 0)
- cifs_stats_inc(&tcon->num_writes);
- else
- kref_put(&wdata->refcount, cifs_writedata_release);
-
- /* send is done, unmap pages */
- for (i = 0; i < wdata->nr_pages; i++)
- kunmap(wdata->pages[i]);
-
-async_writev_out:
- cifs_small_buf_release(smb);
- kfree(iov);
- return rc;
-}
-
-int
-CIFSSMBWrite2(const int xid, struct cifs_io_parms *io_parms,
- unsigned int *nbytes, struct kvec *iov, int n_vec,
- const int long_op)
-{
- int rc = -EACCES;
- WRITE_REQ *pSMB = NULL;
- int wct;
- int smb_hdr_len;
- int resp_buf_type = 0;
- __u32 pid = io_parms->pid;
- __u16 netfid = io_parms->netfid;
- __u64 offset = io_parms->offset;
- struct cifs_tcon *tcon = io_parms->tcon;
- unsigned int count = io_parms->length;
-
- *nbytes = 0;
-
- cFYI(1, "write2 at %lld %d bytes", (long long)offset, count);
-
- if (tcon->ses->capabilities & CAP_LARGE_FILES) {
- wct = 14;
- } else {
- wct = 12;
- if ((offset >> 32) > 0) {
- /* can not handle big offset for old srv */
- return -EIO;
- }
- }
- rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
- if (rc)
- return rc;
-
- pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
- pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));
-
- /* tcon and ses pointer are checked in smb_init */
- if (tcon->ses->server == NULL)
- return -ECONNABORTED;
-
- pSMB->AndXCommand = 0xFF; /* none */
- pSMB->Fid = netfid;
- pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
- if (wct == 14)
- pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
- pSMB->Reserved = 0xFFFFFFFF;
- pSMB->WriteMode = 0;
- pSMB->Remaining = 0;
-
- pSMB->DataOffset =
- cpu_to_le16(offsetof(struct smb_com_write_req, Data) - 4);
-
- pSMB->DataLengthLow = cpu_to_le16(count & 0xFFFF);
- pSMB->DataLengthHigh = cpu_to_le16(count >> 16);
- /* header + 1 byte pad */
- smb_hdr_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 1;
- if (wct == 14)
- inc_rfc1001_len(pSMB, count + 1);
- else /* wct == 12 */
- inc_rfc1001_len(pSMB, count + 5); /* smb data starts later */
- if (wct == 14)
- pSMB->ByteCount = cpu_to_le16(count + 1);
- else /* wct == 12 */ /* bigger pad, smaller smb hdr, keep offset ok */ {
- struct smb_com_writex_req *pSMBW =
- (struct smb_com_writex_req *)pSMB;
- pSMBW->ByteCount = cpu_to_le16(count + 5);
- }
- iov[0].iov_base = pSMB;
- if (wct == 14)
- iov[0].iov_len = smb_hdr_len + 4;
- else /* wct == 12 pad bigger by four bytes */
- iov[0].iov_len = smb_hdr_len + 8;
-
-
- rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type,
- long_op);
- cifs_stats_inc(&tcon->num_writes);
- if (rc) {
- cFYI(1, "Send error Write2 = %d", rc);
- } else if (resp_buf_type == 0) {
- /* presumably this can not happen, but best to be safe */
- rc = -EIO;
- } else {
- WRITE_RSP *pSMBr = (WRITE_RSP *)iov[0].iov_base;
- *nbytes = le16_to_cpu(pSMBr->CountHigh);
- *nbytes = (*nbytes) << 16;
- *nbytes += le16_to_cpu(pSMBr->Count);
-
- /*
- * Mask off high 16 bits when bytes written as returned by the
- * server is greater than bytes requested by the client. OS/2
- * servers are known to set incorrect CountHigh values.
- */
- if (*nbytes > count)
- *nbytes &= 0xFFFF;
- }
-
-/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
- if (resp_buf_type == CIFS_SMALL_BUFFER)
- cifs_small_buf_release(iov[0].iov_base);
- else if (resp_buf_type == CIFS_LARGE_BUFFER)
- cifs_buf_release(iov[0].iov_base);
-
- /* Note: On -EAGAIN error only caller can retry on handle based calls
- since file handle passed in no longer valid */
-
- return rc;
-}
-
-int cifs_lockv(const int xid, struct cifs_tcon *tcon, const __u16 netfid,
- const __u8 lock_type, const __u32 num_unlock,
- const __u32 num_lock, LOCKING_ANDX_RANGE *buf)
-{
- int rc = 0;
- LOCK_REQ *pSMB = NULL;
- struct kvec iov[2];
- int resp_buf_type;
- __u16 count;
-
- cFYI(1, "cifs_lockv num lock %d num unlock %d", num_lock, num_unlock);
-
- rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
- if (rc)
- return rc;
-
- pSMB->Timeout = 0;
- pSMB->NumberOfLocks = cpu_to_le16(num_lock);
- pSMB->NumberOfUnlocks = cpu_to_le16(num_unlock);
- pSMB->LockType = lock_type;
- pSMB->AndXCommand = 0xFF; /* none */
- pSMB->Fid = netfid; /* netfid stays le */
-
- count = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
- inc_rfc1001_len(pSMB, count);
- pSMB->ByteCount = cpu_to_le16(count);
-
- iov[0].iov_base = (char *)pSMB;
- iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4 -
- (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
- iov[1].iov_base = (char *)buf;
- iov[1].iov_len = (num_unlock + num_lock) * sizeof(LOCKING_ANDX_RANGE);
-
- cifs_stats_inc(&tcon->num_locks);
- rc = SendReceive2(xid, tcon->ses, iov, 2, &resp_buf_type, CIFS_NO_RESP);
- if (rc)
- cFYI(1, "Send error in cifs_lockv = %d", rc);
-
- return rc;
-}
-
-int
-CIFSSMBLock(const int xid, struct cifs_tcon *tcon,
- const __u16 smb_file_id, const __u32 netpid, const __u64 len,
- const __u64 offset, const __u32 numUnlock,
- const __u32 numLock, const __u8 lockType,
- const bool waitFlag, const __u8 oplock_level)
-{
- int rc = 0;
- LOCK_REQ *pSMB = NULL;
-/* LOCK_RSP *pSMBr = NULL; */ /* No response data other than rc to parse */
- int bytes_returned;
- int timeout = 0;
- __u16 count;
-
- cFYI(1, "CIFSSMBLock timeout %d numLock %d", (int)waitFlag, numLock);
- rc = small_smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB);
-
- if (rc)
- return rc;
-
- if (lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
- timeout = CIFS_ASYNC_OP; /* no response expected */
- pSMB->Timeout = 0;
- } else if (waitFlag) {
- timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
- pSMB->Timeout = cpu_to_le32(-1);/* blocking - do not time out */
- } else {
- pSMB->Timeout = 0;
- }
-
- pSMB->NumberOfLocks = cpu_to_le16(numLock);
- pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
- pSMB->LockType = lockType;
- pSMB->OplockLevel = oplock_level;
- pSMB->AndXCommand = 0xFF; /* none */
- pSMB->Fid = smb_file_id; /* netfid stays le */
-
- if ((numLock != 0) || (numUnlock != 0)) {
- pSMB->Locks[0].Pid = cpu_to_le16(netpid);
- /* BB where to store pid high? */
- pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
- pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
- pSMB->Locks[0].OffsetLow = cpu_to_le32((u32)offset);
- pSMB->Locks[0].OffsetHigh = cpu_to_le32((u32)(offset>>32));
- count = sizeof(LOCKING_ANDX_RANGE);
- } else {
- /* oplock break */
- count = 0;
- }
- inc_rfc1001_len(pSMB, count);
- pSMB->ByteCount = cpu_to_le16(count);
-
- if (waitFlag) {
- rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMB, &bytes_returned);
- cifs_small_buf_release(pSMB);
- } else {
- rc = SendReceiveNoRsp(xid, tcon->ses, (char *)pSMB, timeout);
- /* SMB buffer freed by function above */
- }
- cifs_stats_inc(&tcon->num_locks);
- if (rc)
- cFYI(1, "Send error in Lock = %d", rc);
-
- /* Note: On -EAGAIN error only caller can retry on handle based calls
- since file handle passed in no longer valid */
- return rc;
-}
-
-int
-CIFSSMBPosixLock(const int xid, struct cifs_tcon *tcon,
- const __u16 smb_file_id, const __u32 netpid, const int get_flag,
- const __u64 len, struct file_lock *pLockData,
- const __u16 lock_type, const bool waitFlag)
-{
- struct smb_com_transaction2_sfi_req *pSMB = NULL;
- struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
- struct cifs_posix_lock *parm_data;
- int rc = 0;
- int timeout = 0;
- int bytes_returned = 0;
- int resp_buf_type = 0;
- __u16 params, param_offset, offset, byte_count, count;
- struct kvec iov[1];
-
- cFYI(1, "Posix Lock");
-
- if (pLockData == NULL)
- return -EINVAL;
-
- rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
-
- if (rc)
- return rc;
-
- pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
-
- params = 6;
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Reserved2 = 0;
- param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
- offset = param_offset + params;
-
- count = sizeof(struct cifs_posix_lock);
- pSMB->MaxParameterCount = cpu_to_le16(2);
- pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- if (get_flag)
- pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
- else
- pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
- byte_count = 3 /* pad */ + params + count;
- pSMB->DataCount = cpu_to_le16(count);
- pSMB->ParameterCount = cpu_to_le16(params);
- pSMB->TotalDataCount = pSMB->DataCount;
- pSMB->TotalParameterCount = pSMB->ParameterCount;
- pSMB->ParameterOffset = cpu_to_le16(param_offset);
- parm_data = (struct cifs_posix_lock *)
- (((char *) &pSMB->hdr.Protocol) + offset);
-
- parm_data->lock_type = cpu_to_le16(lock_type);
- if (waitFlag) {
- timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
- parm_data->lock_flags = cpu_to_le16(1);
- pSMB->Timeout = cpu_to_le32(-1);
- } else
- pSMB->Timeout = 0;
-
- parm_data->pid = cpu_to_le32(netpid);
- parm_data->start = cpu_to_le64(pLockData->fl_start);
- parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
-
- pSMB->DataOffset = cpu_to_le16(offset);
- pSMB->Fid = smb_file_id;
- pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
- pSMB->Reserved4 = 0;
- inc_rfc1001_len(pSMB, byte_count);
- pSMB->ByteCount = cpu_to_le16(byte_count);
- if (waitFlag) {
- rc = SendReceiveBlockingLock(xid, tcon, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned);
- } else {
- iov[0].iov_base = (char *)pSMB;
- iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
- rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
- &resp_buf_type, timeout);
- pSMB = NULL; /* request buf already freed by SendReceive2. Do
- not try to free it twice below on exit */
- pSMBr = (struct smb_com_transaction2_sfi_rsp *)iov[0].iov_base;
- }
-
- if (rc) {
- cFYI(1, "Send error in Posix Lock = %d", rc);
- } else if (get_flag) {
- /* lock structure can be returned on get */
- __u16 data_offset;
- __u16 data_count;
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
-
- if (rc || get_bcc(&pSMBr->hdr) < sizeof(*parm_data)) {
- rc = -EIO; /* bad smb */
- goto plk_err_exit;
- }
- data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
- data_count = le16_to_cpu(pSMBr->t2.DataCount);
- if (data_count < sizeof(struct cifs_posix_lock)) {
- rc = -EIO;
- goto plk_err_exit;
- }
- parm_data = (struct cifs_posix_lock *)
- ((char *)&pSMBr->hdr.Protocol + data_offset);
- if (parm_data->lock_type == __constant_cpu_to_le16(CIFS_UNLCK))
- pLockData->fl_type = F_UNLCK;
- else {
- if (parm_data->lock_type ==
- __constant_cpu_to_le16(CIFS_RDLCK))
- pLockData->fl_type = F_RDLCK;
- else if (parm_data->lock_type ==
- __constant_cpu_to_le16(CIFS_WRLCK))
- pLockData->fl_type = F_WRLCK;
-
- pLockData->fl_start = le64_to_cpu(parm_data->start);
- pLockData->fl_end = pLockData->fl_start +
- le64_to_cpu(parm_data->length) - 1;
- pLockData->fl_pid = le32_to_cpu(parm_data->pid);
- }
- }
-
-plk_err_exit:
- if (pSMB)
- cifs_small_buf_release(pSMB);
-
- if (resp_buf_type == CIFS_SMALL_BUFFER)
- cifs_small_buf_release(iov[0].iov_base);
- else if (resp_buf_type == CIFS_LARGE_BUFFER)
- cifs_buf_release(iov[0].iov_base);
-
- /* Note: On -EAGAIN error only caller can retry on handle based calls
- since file handle passed in no longer valid */
-
- return rc;
-}
-
-
-int
-CIFSSMBClose(const int xid, struct cifs_tcon *tcon, int smb_file_id)
-{
- int rc = 0;
- CLOSE_REQ *pSMB = NULL;
- cFYI(1, "In CIFSSMBClose");
-
-/* do not retry on dead session on close */
- rc = small_smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB);
- if (rc == -EAGAIN)
- return 0;
- if (rc)
- return rc;
-
- pSMB->FileID = (__u16) smb_file_id;
- pSMB->LastWriteTime = 0xFFFFFFFF;
- pSMB->ByteCount = 0;
- rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
- cifs_stats_inc(&tcon->num_closes);
- if (rc) {
- if (rc != -EINTR) {
- /* EINTR is expected when user ctl-c to kill app */
- cERROR(1, "Send error in Close = %d", rc);
- }
- }
-
- /* Since session is dead, file will be closed on server already */
- if (rc == -EAGAIN)
- rc = 0;
-
- return rc;
-}
-
-int
-CIFSSMBFlush(const int xid, struct cifs_tcon *tcon, int smb_file_id)
-{
- int rc = 0;
- FLUSH_REQ *pSMB = NULL;
- cFYI(1, "In CIFSSMBFlush");
-
- rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
- if (rc)
- return rc;
-
- pSMB->FileID = (__u16) smb_file_id;
- pSMB->ByteCount = 0;
- rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
- cifs_stats_inc(&tcon->num_flushes);
- if (rc)
- cERROR(1, "Send error in Flush = %d", rc);
-
- return rc;
-}
-
-int
-CIFSSMBRename(const int xid, struct cifs_tcon *tcon,
- const char *fromName, const char *toName,
- const struct nls_table *nls_codepage, int remap)
-{
- int rc = 0;
- RENAME_REQ *pSMB = NULL;
- RENAME_RSP *pSMBr = NULL;
- int bytes_returned;
- int name_len, name_len2;
- __u16 count;
-
- cFYI(1, "In CIFSSMBRename");
-renameRetry:
- rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- pSMB->BufferFormat = 0x04;
- pSMB->SearchAttributes =
- cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
- ATTR_DIRECTORY);
-
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len =
- cifsConvertToUTF16((__le16 *) pSMB->OldFileName, fromName,
- PATH_MAX, nls_codepage, remap);
- name_len++; /* trailing null */
- name_len *= 2;
- pSMB->OldFileName[name_len] = 0x04; /* pad */
- /* protocol requires ASCII signature byte on Unicode string */
- pSMB->OldFileName[name_len + 1] = 0x00;
- name_len2 =
- cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
- toName, PATH_MAX, nls_codepage, remap);
- name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
- name_len2 *= 2; /* convert to bytes */
- } else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(fromName, PATH_MAX);
- name_len++; /* trailing null */
- strncpy(pSMB->OldFileName, fromName, name_len);
- name_len2 = strnlen(toName, PATH_MAX);
- name_len2++; /* trailing null */
- pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
- strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
- name_len2++; /* trailing null */
- name_len2++; /* signature byte */
- }
-
- count = 1 /* 1st signature byte */ + name_len + name_len2;
- inc_rfc1001_len(pSMB, count);
- pSMB->ByteCount = cpu_to_le16(count);
-
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- cifs_stats_inc(&tcon->num_renames);
- if (rc)
- cFYI(1, "Send error in rename = %d", rc);
-
- cifs_buf_release(pSMB);
-
- if (rc == -EAGAIN)
- goto renameRetry;
-
- return rc;
-}
-
-int CIFSSMBRenameOpenFile(const int xid, struct cifs_tcon *pTcon,
- int netfid, const char *target_name,
- const struct nls_table *nls_codepage, int remap)
-{
- struct smb_com_transaction2_sfi_req *pSMB = NULL;
- struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
- struct set_file_rename *rename_info;
- char *data_offset;
- char dummy_string[30];
- int rc = 0;
- int bytes_returned = 0;
- int len_of_str;
- __u16 params, param_offset, offset, count, byte_count;
-
- cFYI(1, "Rename to File by handle");
- rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- params = 6;
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
- offset = param_offset + params;
-
- data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
- rename_info = (struct set_file_rename *) data_offset;
- pSMB->MaxParameterCount = cpu_to_le16(2);
- pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB from sess */
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
- byte_count = 3 /* pad */ + params;
- pSMB->ParameterCount = cpu_to_le16(params);
- pSMB->TotalParameterCount = pSMB->ParameterCount;
- pSMB->ParameterOffset = cpu_to_le16(param_offset);
- pSMB->DataOffset = cpu_to_le16(offset);
- /* construct random name ".cifs_tmp<inodenum><mid>" */
- rename_info->overwrite = cpu_to_le32(1);
- rename_info->root_fid = 0;
- /* unicode only call */
- if (target_name == NULL) {
- sprintf(dummy_string, "cifs%x", pSMB->hdr.Mid);
- len_of_str =
- cifsConvertToUTF16((__le16 *)rename_info->target_name,
- dummy_string, 24, nls_codepage, remap);
- } else {
- len_of_str =
- cifsConvertToUTF16((__le16 *)rename_info->target_name,
- target_name, PATH_MAX, nls_codepage,
- remap);
- }
- rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
- count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
- byte_count += count;
- pSMB->DataCount = cpu_to_le16(count);
- pSMB->TotalDataCount = pSMB->DataCount;
- pSMB->Fid = netfid;
- pSMB->InformationLevel =
- cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
- pSMB->Reserved4 = 0;
- inc_rfc1001_len(pSMB, byte_count);
- pSMB->ByteCount = cpu_to_le16(byte_count);
- rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- cifs_stats_inc(&pTcon->num_t2renames);
- if (rc)
- cFYI(1, "Send error in Rename (by file handle) = %d", rc);
-
- cifs_buf_release(pSMB);
-
- /* Note: On -EAGAIN error only caller can retry on handle based calls
- since file handle passed in no longer valid */
-
- return rc;
-}
-
-int
-CIFSSMBCopy(const int xid, struct cifs_tcon *tcon, const char *fromName,
- const __u16 target_tid, const char *toName, const int flags,
- const struct nls_table *nls_codepage, int remap)
-{
- int rc = 0;
- COPY_REQ *pSMB = NULL;
- COPY_RSP *pSMBr = NULL;
- int bytes_returned;
- int name_len, name_len2;
- __u16 count;
-
- cFYI(1, "In CIFSSMBCopy");
-copyRetry:
- rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- pSMB->BufferFormat = 0x04;
- pSMB->Tid2 = target_tid;
-
- pSMB->Flags = cpu_to_le16(flags & COPY_TREE);
-
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len = cifsConvertToUTF16((__le16 *) pSMB->OldFileName,
- fromName, PATH_MAX, nls_codepage,
- remap);
- name_len++; /* trailing null */
- name_len *= 2;
- pSMB->OldFileName[name_len] = 0x04; /* pad */
- /* protocol requires ASCII signature byte on Unicode string */
- pSMB->OldFileName[name_len + 1] = 0x00;
- name_len2 =
- cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
- toName, PATH_MAX, nls_codepage, remap);
- name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
- name_len2 *= 2; /* convert to bytes */
- } else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(fromName, PATH_MAX);
- name_len++; /* trailing null */
- strncpy(pSMB->OldFileName, fromName, name_len);
- name_len2 = strnlen(toName, PATH_MAX);
- name_len2++; /* trailing null */
- pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
- strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
- name_len2++; /* trailing null */
- name_len2++; /* signature byte */
- }
-
- count = 1 /* 1st signature byte */ + name_len + name_len2;
- inc_rfc1001_len(pSMB, count);
- pSMB->ByteCount = cpu_to_le16(count);
-
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc) {
- cFYI(1, "Send error in copy = %d with %d files copied",
- rc, le16_to_cpu(pSMBr->CopyCount));
- }
- cifs_buf_release(pSMB);
-
- if (rc == -EAGAIN)
- goto copyRetry;
-
- return rc;
-}
-
-int
-CIFSUnixCreateSymLink(const int xid, struct cifs_tcon *tcon,
- const char *fromName, const char *toName,
- const struct nls_table *nls_codepage)
-{
- TRANSACTION2_SPI_REQ *pSMB = NULL;
- TRANSACTION2_SPI_RSP *pSMBr = NULL;
- char *data_offset;
- int name_len;
- int name_len_target;
- int rc = 0;
- int bytes_returned = 0;
- __u16 params, param_offset, offset, byte_count;
-
- cFYI(1, "In Symlink Unix style");
-createSymLinkRetry:
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len =
- cifs_strtoUTF16((__le16 *) pSMB->FileName, fromName,
- /* find define for this maxpathcomponent */
- PATH_MAX, nls_codepage);
- name_len++; /* trailing null */
- name_len *= 2;
-
- } else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(fromName, PATH_MAX);
- name_len++; /* trailing null */
- strncpy(pSMB->FileName, fromName, name_len);
- }
- params = 6 + name_len;
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- param_offset = offsetof(struct smb_com_transaction2_spi_req,
- InformationLevel) - 4;
- offset = param_offset + params;
-
- data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len_target =
- cifs_strtoUTF16((__le16 *) data_offset, toName, PATH_MAX
- /* find define for this maxpathcomponent */
- , nls_codepage);
- name_len_target++; /* trailing null */
- name_len_target *= 2;
- } else { /* BB improve the check for buffer overruns BB */
- name_len_target = strnlen(toName, PATH_MAX);
- name_len_target++; /* trailing null */
- strncpy(data_offset, toName, name_len_target);
- }
-
- pSMB->MaxParameterCount = cpu_to_le16(2);
- /* BB find exact max on data count below from sess */
- pSMB->MaxDataCount = cpu_to_le16(1000);
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
- byte_count = 3 /* pad */ + params + name_len_target;
- pSMB->DataCount = cpu_to_le16(name_len_target);
- pSMB->ParameterCount = cpu_to_le16(params);
- pSMB->TotalDataCount = pSMB->DataCount;
- pSMB->TotalParameterCount = pSMB->ParameterCount;
- pSMB->ParameterOffset = cpu_to_le16(param_offset);
- pSMB->DataOffset = cpu_to_le16(offset);
- pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
- pSMB->Reserved4 = 0;
- inc_rfc1001_len(pSMB, byte_count);
- pSMB->ByteCount = cpu_to_le16(byte_count);
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- cifs_stats_inc(&tcon->num_symlinks);
- if (rc)
- cFYI(1, "Send error in SetPathInfo create symlink = %d", rc);
-
- cifs_buf_release(pSMB);
-
- if (rc == -EAGAIN)
- goto createSymLinkRetry;
-
- return rc;
-}
-
-int
-CIFSUnixCreateHardLink(const int xid, struct cifs_tcon *tcon,
- const char *fromName, const char *toName,
- const struct nls_table *nls_codepage, int remap)
-{
- TRANSACTION2_SPI_REQ *pSMB = NULL;
- TRANSACTION2_SPI_RSP *pSMBr = NULL;
- char *data_offset;
- int name_len;
- int name_len_target;
- int rc = 0;
- int bytes_returned = 0;
- __u16 params, param_offset, offset, byte_count;
-
- cFYI(1, "In Create Hard link Unix style");
-createHardLinkRetry:
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len = cifsConvertToUTF16((__le16 *) pSMB->FileName, toName,
- PATH_MAX, nls_codepage, remap);
- name_len++; /* trailing null */
- name_len *= 2;
-
- } else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(toName, PATH_MAX);
- name_len++; /* trailing null */
- strncpy(pSMB->FileName, toName, name_len);
- }
- params = 6 + name_len;
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- param_offset = offsetof(struct smb_com_transaction2_spi_req,
- InformationLevel) - 4;
- offset = param_offset + params;
-
- data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len_target =
- cifsConvertToUTF16((__le16 *) data_offset, fromName,
- PATH_MAX, nls_codepage, remap);
- name_len_target++; /* trailing null */
- name_len_target *= 2;
- } else { /* BB improve the check for buffer overruns BB */
- name_len_target = strnlen(fromName, PATH_MAX);
- name_len_target++; /* trailing null */
- strncpy(data_offset, fromName, name_len_target);
- }
-
- pSMB->MaxParameterCount = cpu_to_le16(2);
- /* BB find exact max on data count below from sess*/
- pSMB->MaxDataCount = cpu_to_le16(1000);
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
- byte_count = 3 /* pad */ + params + name_len_target;
- pSMB->ParameterCount = cpu_to_le16(params);
- pSMB->TotalParameterCount = pSMB->ParameterCount;
- pSMB->DataCount = cpu_to_le16(name_len_target);
- pSMB->TotalDataCount = pSMB->DataCount;
- pSMB->ParameterOffset = cpu_to_le16(param_offset);
- pSMB->DataOffset = cpu_to_le16(offset);
- pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
- pSMB->Reserved4 = 0;
- inc_rfc1001_len(pSMB, byte_count);
- pSMB->ByteCount = cpu_to_le16(byte_count);
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- cifs_stats_inc(&tcon->num_hardlinks);
- if (rc)
- cFYI(1, "Send error in SetPathInfo (hard link) = %d", rc);
-
- cifs_buf_release(pSMB);
- if (rc == -EAGAIN)
- goto createHardLinkRetry;
-
- return rc;
-}
-
-int
-CIFSCreateHardLink(const int xid, struct cifs_tcon *tcon,
- const char *fromName, const char *toName,
- const struct nls_table *nls_codepage, int remap)
-{
- int rc = 0;
- NT_RENAME_REQ *pSMB = NULL;
- RENAME_RSP *pSMBr = NULL;
- int bytes_returned;
- int name_len, name_len2;
- __u16 count;
-
- cFYI(1, "In CIFSCreateHardLink");
-winCreateHardLinkRetry:
-
- rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- pSMB->SearchAttributes =
- cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
- ATTR_DIRECTORY);
- pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
- pSMB->ClusterCount = 0;
-
- pSMB->BufferFormat = 0x04;
-
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len =
- cifsConvertToUTF16((__le16 *) pSMB->OldFileName, fromName,
- PATH_MAX, nls_codepage, remap);
- name_len++; /* trailing null */
- name_len *= 2;
-
- /* protocol specifies ASCII buffer format (0x04) for unicode */
- pSMB->OldFileName[name_len] = 0x04;
- pSMB->OldFileName[name_len + 1] = 0x00; /* pad */
- name_len2 =
- cifsConvertToUTF16((__le16 *)&pSMB->OldFileName[name_len+2],
- toName, PATH_MAX, nls_codepage, remap);
- name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
- name_len2 *= 2; /* convert to bytes */
- } else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(fromName, PATH_MAX);
- name_len++; /* trailing null */
- strncpy(pSMB->OldFileName, fromName, name_len);
- name_len2 = strnlen(toName, PATH_MAX);
- name_len2++; /* trailing null */
- pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
- strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
- name_len2++; /* trailing null */
- name_len2++; /* signature byte */
- }
-
- count = 1 /* string type byte */ + name_len + name_len2;
- inc_rfc1001_len(pSMB, count);
- pSMB->ByteCount = cpu_to_le16(count);
-
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- cifs_stats_inc(&tcon->num_hardlinks);
- if (rc)
- cFYI(1, "Send error in hard link (NT rename) = %d", rc);
-
- cifs_buf_release(pSMB);
- if (rc == -EAGAIN)
- goto winCreateHardLinkRetry;
-
- return rc;
-}
-
-int
-CIFSSMBUnixQuerySymLink(const int xid, struct cifs_tcon *tcon,
- const unsigned char *searchName, char **symlinkinfo,
- const struct nls_table *nls_codepage)
-{
-/* SMB_QUERY_FILE_UNIX_LINK */
- TRANSACTION2_QPI_REQ *pSMB = NULL;
- TRANSACTION2_QPI_RSP *pSMBr = NULL;
- int rc = 0;
- int bytes_returned;
- int name_len;
- __u16 params, byte_count;
- char *data_start;
-
- cFYI(1, "In QPathSymLinkInfo (Unix) for path %s", searchName);
-
-querySymLinkRetry:
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len =
- cifs_strtoUTF16((__le16 *) pSMB->FileName, searchName,
- PATH_MAX, nls_codepage);
- name_len++; /* trailing null */
- name_len *= 2;
- } else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(searchName, PATH_MAX);
- name_len++; /* trailing null */
- strncpy(pSMB->FileName, searchName, name_len);
- }
-
- params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
- pSMB->TotalDataCount = 0;
- pSMB->MaxParameterCount = cpu_to_le16(2);
- pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- pSMB->ParameterOffset = cpu_to_le16(offsetof(
- struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
- pSMB->DataCount = 0;
- pSMB->DataOffset = 0;
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
- byte_count = params + 1 /* pad */ ;
- pSMB->TotalParameterCount = cpu_to_le16(params);
- pSMB->ParameterCount = pSMB->TotalParameterCount;
- pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
- pSMB->Reserved4 = 0;
- inc_rfc1001_len(pSMB, byte_count);
- pSMB->ByteCount = cpu_to_le16(byte_count);
-
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc) {
- cFYI(1, "Send error in QuerySymLinkInfo = %d", rc);
- } else {
- /* decode response */
-
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
- /* BB also check enough total bytes returned */
- if (rc || get_bcc(&pSMBr->hdr) < 2)
- rc = -EIO;
- else {
- bool is_unicode;
- u16 count = le16_to_cpu(pSMBr->t2.DataCount);
-
- data_start = ((char *) &pSMBr->hdr.Protocol) +
- le16_to_cpu(pSMBr->t2.DataOffset);
-
- if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
- is_unicode = true;
- else
- is_unicode = false;
-
- /* BB FIXME investigate remapping reserved chars here */
- *symlinkinfo = cifs_strndup_from_utf16(data_start,
- count, is_unicode, nls_codepage);
- if (!*symlinkinfo)
- rc = -ENOMEM;
- }
- }
- cifs_buf_release(pSMB);
- if (rc == -EAGAIN)
- goto querySymLinkRetry;
- return rc;
-}
-
-#ifdef CONFIG_CIFS_SYMLINK_EXPERIMENTAL
-/*
- * Recent Windows versions now create symlinks more frequently
- * and they use the "reparse point" mechanism below. We can of course
- * do symlinks nicely to Samba and other servers which support the
- * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
- * "MF" symlinks optionally, but for recent Windows we really need to
- * reenable the code below and fix the cifs_symlink callers to handle this.
- * In the interim this code has been moved to its own config option so
- * it is not compiled in by default until callers fixed up and more tested.
- */
-int
-CIFSSMBQueryReparseLinkInfo(const int xid, struct cifs_tcon *tcon,
- const unsigned char *searchName,
- char *symlinkinfo, const int buflen, __u16 fid,
- const struct nls_table *nls_codepage)
-{
- int rc = 0;
- int bytes_returned;
- struct smb_com_transaction_ioctl_req *pSMB;
- struct smb_com_transaction_ioctl_rsp *pSMBr;
-
- cFYI(1, "In Windows reparse style QueryLink for path %s", searchName);
- rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- pSMB->TotalParameterCount = 0 ;
- pSMB->TotalDataCount = 0;
- pSMB->MaxParameterCount = cpu_to_le32(2);
- /* BB find exact data count max from sess structure BB */
- pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
- pSMB->MaxSetupCount = 4;
- pSMB->Reserved = 0;
- pSMB->ParameterOffset = 0;
- pSMB->DataCount = 0;
- pSMB->DataOffset = 0;
- pSMB->SetupCount = 4;
- pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
- pSMB->ParameterCount = pSMB->TotalParameterCount;
- pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
- pSMB->IsFsctl = 1; /* FSCTL */
- pSMB->IsRootFlag = 0;
- pSMB->Fid = fid; /* file handle always le */
- pSMB->ByteCount = 0;
-
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc) {
- cFYI(1, "Send error in QueryReparseLinkInfo = %d", rc);
- } else { /* decode response */
- __u32 data_offset = le32_to_cpu(pSMBr->DataOffset);
- __u32 data_count = le32_to_cpu(pSMBr->DataCount);
- if (get_bcc(&pSMBr->hdr) < 2 || data_offset > 512) {
- /* BB also check enough total bytes returned */
- rc = -EIO; /* bad smb */
- goto qreparse_out;
- }
- if (data_count && (data_count < 2048)) {
- char *end_of_smb = 2 /* sizeof byte count */ +
- get_bcc(&pSMBr->hdr) + (char *)&pSMBr->ByteCount;
-
- struct reparse_data *reparse_buf =
- (struct reparse_data *)
- ((char *)&pSMBr->hdr.Protocol
- + data_offset);
- if ((char *)reparse_buf >= end_of_smb) {
- rc = -EIO;
- goto qreparse_out;
- }
- if ((reparse_buf->LinkNamesBuf +
- reparse_buf->TargetNameOffset +
- reparse_buf->TargetNameLen) > end_of_smb) {
- cFYI(1, "reparse buf beyond SMB");
- rc = -EIO;
- goto qreparse_out;
- }
-
- if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
- cifs_from_ucs2(symlinkinfo, (__le16 *)
- (reparse_buf->LinkNamesBuf +
- reparse_buf->TargetNameOffset),
- buflen,
- reparse_buf->TargetNameLen,
- nls_codepage, 0);
- } else { /* ASCII names */
- strncpy(symlinkinfo,
- reparse_buf->LinkNamesBuf +
- reparse_buf->TargetNameOffset,
- min_t(const int, buflen,
- reparse_buf->TargetNameLen));
- }
- } else {
- rc = -EIO;
- cFYI(1, "Invalid return data count on "
- "get reparse info ioctl");
- }
- symlinkinfo[buflen] = 0; /* just in case so the caller
- does not go off the end of the buffer */
- cFYI(1, "readlink result - %s", symlinkinfo);
- }
-
-qreparse_out:
- cifs_buf_release(pSMB);
-
- /* Note: On -EAGAIN error only caller can retry on handle based calls
- since file handle passed in no longer valid */
-
- return rc;
-}
-#endif /* CIFS_SYMLINK_EXPERIMENTAL */ /* BB temporarily unused */
-
-#ifdef CONFIG_CIFS_POSIX
-
-/*Convert an Access Control Entry from wire format to local POSIX xattr format*/
-static void cifs_convert_ace(posix_acl_xattr_entry *ace,
- struct cifs_posix_ace *cifs_ace)
-{
- /* u8 cifs fields do not need le conversion */
- ace->e_perm = cpu_to_le16(cifs_ace->cifs_e_perm);
- ace->e_tag = cpu_to_le16(cifs_ace->cifs_e_tag);
- ace->e_id = cpu_to_le32(le64_to_cpu(cifs_ace->cifs_uid));
- /* cFYI(1, "perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id); */
-
- return;
-}
-
-/* Convert ACL from CIFS POSIX wire format to local Linux POSIX ACL xattr */
-static int cifs_copy_posix_acl(char *trgt, char *src, const int buflen,
- const int acl_type, const int size_of_data_area)
-{
- int size = 0;
- int i;
- __u16 count;
- struct cifs_posix_ace *pACE;
- struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)src;
- posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)trgt;
-
- if (le16_to_cpu(cifs_acl->version) != CIFS_ACL_VERSION)
- return -EOPNOTSUPP;
-
- if (acl_type & ACL_TYPE_ACCESS) {
- count = le16_to_cpu(cifs_acl->access_entry_count);
- pACE = &cifs_acl->ace_array[0];
- size = sizeof(struct cifs_posix_acl);
- size += sizeof(struct cifs_posix_ace) * count;
- /* check if we would go beyond end of SMB */
- if (size_of_data_area < size) {
- cFYI(1, "bad CIFS POSIX ACL size %d vs. %d",
- size_of_data_area, size);
- return -EINVAL;
- }
- } else if (acl_type & ACL_TYPE_DEFAULT) {
- count = le16_to_cpu(cifs_acl->access_entry_count);
- size = sizeof(struct cifs_posix_acl);
- size += sizeof(struct cifs_posix_ace) * count;
-/* skip past access ACEs to get to default ACEs */
- pACE = &cifs_acl->ace_array[count];
- count = le16_to_cpu(cifs_acl->default_entry_count);
- size += sizeof(struct cifs_posix_ace) * count;
- /* check if we would go beyond end of SMB */
- if (size_of_data_area < size)
- return -EINVAL;
- } else {
- /* illegal type */
- return -EINVAL;
- }
-
- size = posix_acl_xattr_size(count);
- if ((buflen == 0) || (local_acl == NULL)) {
- /* used to query ACL EA size */
- } else if (size > buflen) {
- return -ERANGE;
- } else /* buffer big enough */ {
- local_acl->a_version = cpu_to_le32(POSIX_ACL_XATTR_VERSION);
- for (i = 0; i < count ; i++) {
- cifs_convert_ace(&local_acl->a_entries[i], pACE);
- pACE++;
- }
- }
- return size;
-}
-
-static __u16 convert_ace_to_cifs_ace(struct cifs_posix_ace *cifs_ace,
- const posix_acl_xattr_entry *local_ace)
-{
- __u16 rc = 0; /* 0 = ACL converted ok */
-
- cifs_ace->cifs_e_perm = le16_to_cpu(local_ace->e_perm);
- cifs_ace->cifs_e_tag = le16_to_cpu(local_ace->e_tag);
- /* BB is there a better way to handle the large uid? */
- if (local_ace->e_id == cpu_to_le32(-1)) {
- /* Probably no need to le convert -1 on any arch but can not hurt */
- cifs_ace->cifs_uid = cpu_to_le64(-1);
- } else
- cifs_ace->cifs_uid = cpu_to_le64(le32_to_cpu(local_ace->e_id));
- /*cFYI(1, "perm %d tag %d id %d",ace->e_perm,ace->e_tag,ace->e_id);*/
- return rc;
-}
-
-/* Convert ACL from local Linux POSIX xattr to CIFS POSIX ACL wire format */
-static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
- const int buflen, const int acl_type)
-{
- __u16 rc = 0;
- struct cifs_posix_acl *cifs_acl = (struct cifs_posix_acl *)parm_data;
- posix_acl_xattr_header *local_acl = (posix_acl_xattr_header *)pACL;
- int count;
- int i;
-
- if ((buflen == 0) || (pACL == NULL) || (cifs_acl == NULL))
- return 0;
-
- count = posix_acl_xattr_count((size_t)buflen);
- cFYI(1, "setting acl with %d entries from buf of length %d and "
- "version of %d",
- count, buflen, le32_to_cpu(local_acl->a_version));
- if (le32_to_cpu(local_acl->a_version) != 2) {
- cFYI(1, "unknown POSIX ACL version %d",
- le32_to_cpu(local_acl->a_version));
- return 0;
- }
- cifs_acl->version = cpu_to_le16(1);
- if (acl_type == ACL_TYPE_ACCESS)
- cifs_acl->access_entry_count = cpu_to_le16(count);
- else if (acl_type == ACL_TYPE_DEFAULT)
- cifs_acl->default_entry_count = cpu_to_le16(count);
- else {
- cFYI(1, "unknown ACL type %d", acl_type);
- return 0;
- }
- for (i = 0; i < count; i++) {
- rc = convert_ace_to_cifs_ace(&cifs_acl->ace_array[i],
- &local_acl->a_entries[i]);
- if (rc != 0) {
- /* ACE not converted */
- break;
- }
- }
- if (rc == 0) {
- rc = (__u16)(count * sizeof(struct cifs_posix_ace));
- rc += sizeof(struct cifs_posix_acl);
- /* BB add check to make sure ACL does not overflow SMB */
- }
- return rc;
-}
-
-int
-CIFSSMBGetPosixACL(const int xid, struct cifs_tcon *tcon,
- const unsigned char *searchName,
- char *acl_inf, const int buflen, const int acl_type,
- const struct nls_table *nls_codepage, int remap)
-{
-/* SMB_QUERY_POSIX_ACL */
- TRANSACTION2_QPI_REQ *pSMB = NULL;
- TRANSACTION2_QPI_RSP *pSMBr = NULL;
- int rc = 0;
- int bytes_returned;
- int name_len;
- __u16 params, byte_count;
-
- cFYI(1, "In GetPosixACL (Unix) for path %s", searchName);
-
-queryAclRetry:
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len =
- cifsConvertToUTF16((__le16 *) pSMB->FileName,
- searchName, PATH_MAX, nls_codepage,
- remap);
- name_len++; /* trailing null */
- name_len *= 2;
- pSMB->FileName[name_len] = 0;
- pSMB->FileName[name_len+1] = 0;
- } else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(searchName, PATH_MAX);
- name_len++; /* trailing null */
- strncpy(pSMB->FileName, searchName, name_len);
- }
-
- params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
- pSMB->TotalDataCount = 0;
- pSMB->MaxParameterCount = cpu_to_le16(2);
- /* BB find exact max data count below from sess structure BB */
- pSMB->MaxDataCount = cpu_to_le16(4000);
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- pSMB->ParameterOffset = cpu_to_le16(
- offsetof(struct smb_com_transaction2_qpi_req,
- InformationLevel) - 4);
- pSMB->DataCount = 0;
- pSMB->DataOffset = 0;
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
- byte_count = params + 1 /* pad */ ;
- pSMB->TotalParameterCount = cpu_to_le16(params);
- pSMB->ParameterCount = pSMB->TotalParameterCount;
- pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_ACL);
- pSMB->Reserved4 = 0;
- inc_rfc1001_len(pSMB, byte_count);
- pSMB->ByteCount = cpu_to_le16(byte_count);
-
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- cifs_stats_inc(&tcon->num_acl_get);
- if (rc) {
- cFYI(1, "Send error in Query POSIX ACL = %d", rc);
- } else {
- /* decode response */
-
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
- /* BB also check enough total bytes returned */
- if (rc || get_bcc(&pSMBr->hdr) < 2)
- rc = -EIO; /* bad smb */
- else {
- __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
- __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
- rc = cifs_copy_posix_acl(acl_inf,
- (char *)&pSMBr->hdr.Protocol+data_offset,
- buflen, acl_type, count);
- }
- }
- cifs_buf_release(pSMB);
- if (rc == -EAGAIN)
- goto queryAclRetry;
- return rc;
-}
-
-int
-CIFSSMBSetPosixACL(const int xid, struct cifs_tcon *tcon,
- const unsigned char *fileName,
- const char *local_acl, const int buflen,
- const int acl_type,
- const struct nls_table *nls_codepage, int remap)
-{
- struct smb_com_transaction2_spi_req *pSMB = NULL;
- struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
- char *parm_data;
- int name_len;
- int rc = 0;
- int bytes_returned = 0;
- __u16 params, byte_count, data_count, param_offset, offset;
-
- cFYI(1, "In SetPosixACL (Unix) for path %s", fileName);
-setAclRetry:
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len =
- cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
- PATH_MAX, nls_codepage, remap);
- name_len++; /* trailing null */
- name_len *= 2;
- } else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(fileName, PATH_MAX);
- name_len++; /* trailing null */
- strncpy(pSMB->FileName, fileName, name_len);
- }
- params = 6 + name_len;
- pSMB->MaxParameterCount = cpu_to_le16(2);
- /* BB find max SMB size from sess */
- pSMB->MaxDataCount = cpu_to_le16(1000);
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- param_offset = offsetof(struct smb_com_transaction2_spi_req,
- InformationLevel) - 4;
- offset = param_offset + params;
- parm_data = ((char *) &pSMB->hdr.Protocol) + offset;
- pSMB->ParameterOffset = cpu_to_le16(param_offset);
-
- /* convert to on the wire format for POSIX ACL */
- data_count = ACL_to_cifs_posix(parm_data, local_acl, buflen, acl_type);
-
- if (data_count == 0) {
- rc = -EOPNOTSUPP;
- goto setACLerrorExit;
- }
- pSMB->DataOffset = cpu_to_le16(offset);
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
- pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_ACL);
- byte_count = 3 /* pad */ + params + data_count;
- pSMB->DataCount = cpu_to_le16(data_count);
- pSMB->TotalDataCount = pSMB->DataCount;
- pSMB->ParameterCount = cpu_to_le16(params);
- pSMB->TotalParameterCount = pSMB->ParameterCount;
- pSMB->Reserved4 = 0;
- inc_rfc1001_len(pSMB, byte_count);
- pSMB->ByteCount = cpu_to_le16(byte_count);
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc)
- cFYI(1, "Set POSIX ACL returned %d", rc);
-
-setACLerrorExit:
- cifs_buf_release(pSMB);
- if (rc == -EAGAIN)
- goto setAclRetry;
- return rc;
-}
-
-/* BB fix tabs in this function FIXME BB */
-int
-CIFSGetExtAttr(const int xid, struct cifs_tcon *tcon,
- const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
-{
- int rc = 0;
- struct smb_t2_qfi_req *pSMB = NULL;
- struct smb_t2_qfi_rsp *pSMBr = NULL;
- int bytes_returned;
- __u16 params, byte_count;
-
- cFYI(1, "In GetExtAttr");
- if (tcon == NULL)
- return -ENODEV;
-
-GetExtAttrRetry:
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- params = 2 /* level */ + 2 /* fid */;
- pSMB->t2.TotalDataCount = 0;
- pSMB->t2.MaxParameterCount = cpu_to_le16(4);
- /* BB find exact max data count below from sess structure BB */
- pSMB->t2.MaxDataCount = cpu_to_le16(4000);
- pSMB->t2.MaxSetupCount = 0;
- pSMB->t2.Reserved = 0;
- pSMB->t2.Flags = 0;
- pSMB->t2.Timeout = 0;
- pSMB->t2.Reserved2 = 0;
- pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
- Fid) - 4);
- pSMB->t2.DataCount = 0;
- pSMB->t2.DataOffset = 0;
- pSMB->t2.SetupCount = 1;
- pSMB->t2.Reserved3 = 0;
- pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
- byte_count = params + 1 /* pad */ ;
- pSMB->t2.TotalParameterCount = cpu_to_le16(params);
- pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
- pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_ATTR_FLAGS);
- pSMB->Pad = 0;
- pSMB->Fid = netfid;
- inc_rfc1001_len(pSMB, byte_count);
- pSMB->t2.ByteCount = cpu_to_le16(byte_count);
-
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc) {
- cFYI(1, "error %d in GetExtAttr", rc);
- } else {
- /* decode response */
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
- /* BB also check enough total bytes returned */
- if (rc || get_bcc(&pSMBr->hdr) < 2)
- /* If rc should we check for EOPNOSUPP and
- disable the srvino flag? or in caller? */
- rc = -EIO; /* bad smb */
- else {
- __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
- __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
- struct file_chattr_info *pfinfo;
- /* BB Do we need a cast or hash here ? */
- if (count != 16) {
- cFYI(1, "Illegal size ret in GetExtAttr");
- rc = -EIO;
- goto GetExtAttrOut;
- }
- pfinfo = (struct file_chattr_info *)
- (data_offset + (char *) &pSMBr->hdr.Protocol);
- *pExtAttrBits = le64_to_cpu(pfinfo->mode);
- *pMask = le64_to_cpu(pfinfo->mask);
- }
- }
-GetExtAttrOut:
- cifs_buf_release(pSMB);
- if (rc == -EAGAIN)
- goto GetExtAttrRetry;
- return rc;
-}
-
-#endif /* CONFIG_POSIX */
-
-#ifdef CONFIG_CIFS_ACL
-/*
- * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that
- * all NT TRANSACTS that we init here have total parm and data under about 400
- * bytes (to fit in small cifs buffer size), which is the case so far, it
- * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of
- * returned setup area) and MaxParameterCount (returned parms size) must be set
- * by caller
- */
-static int
-smb_init_nttransact(const __u16 sub_command, const int setup_count,
- const int parm_len, struct cifs_tcon *tcon,
- void **ret_buf)
-{
- int rc;
- __u32 temp_offset;
- struct smb_com_ntransact_req *pSMB;
-
- rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon,
- (void **)&pSMB);
- if (rc)
- return rc;
- *ret_buf = (void *)pSMB;
- pSMB->Reserved = 0;
- pSMB->TotalParameterCount = cpu_to_le32(parm_len);
- pSMB->TotalDataCount = 0;
- pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
- pSMB->ParameterCount = pSMB->TotalParameterCount;
- pSMB->DataCount = pSMB->TotalDataCount;
- temp_offset = offsetof(struct smb_com_ntransact_req, Parms) +
- (setup_count * 2) - 4 /* for rfc1001 length itself */;
- pSMB->ParameterOffset = cpu_to_le32(temp_offset);
- pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len);
- pSMB->SetupCount = setup_count; /* no need to le convert byte fields */
- pSMB->SubCommand = cpu_to_le16(sub_command);
- return 0;
-}
-
-static int
-validate_ntransact(char *buf, char **ppparm, char **ppdata,
- __u32 *pparmlen, __u32 *pdatalen)
-{
- char *end_of_smb;
- __u32 data_count, data_offset, parm_count, parm_offset;
- struct smb_com_ntransact_rsp *pSMBr;
- u16 bcc;
-
- *pdatalen = 0;
- *pparmlen = 0;
-
- if (buf == NULL)
- return -EINVAL;
-
- pSMBr = (struct smb_com_ntransact_rsp *)buf;
-
- bcc = get_bcc(&pSMBr->hdr);
- end_of_smb = 2 /* sizeof byte count */ + bcc +
- (char *)&pSMBr->ByteCount;
-
- data_offset = le32_to_cpu(pSMBr->DataOffset);
- data_count = le32_to_cpu(pSMBr->DataCount);
- parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
- parm_count = le32_to_cpu(pSMBr->ParameterCount);
-
- *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
- *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
-
- /* should we also check that parm and data areas do not overlap? */
- if (*ppparm > end_of_smb) {
- cFYI(1, "parms start after end of smb");
- return -EINVAL;
- } else if (parm_count + *ppparm > end_of_smb) {
- cFYI(1, "parm end after end of smb");
- return -EINVAL;
- } else if (*ppdata > end_of_smb) {
- cFYI(1, "data starts after end of smb");
- return -EINVAL;
- } else if (data_count + *ppdata > end_of_smb) {
- cFYI(1, "data %p + count %d (%p) past smb end %p start %p",
- *ppdata, data_count, (data_count + *ppdata),
- end_of_smb, pSMBr);
- return -EINVAL;
- } else if (parm_count + data_count > bcc) {
- cFYI(1, "parm count and data count larger than SMB");
- return -EINVAL;
- }
- *pdatalen = data_count;
- *pparmlen = parm_count;
- return 0;
-}
-
-/* Get Security Descriptor (by handle) from remote server for a file or dir */
-int
-CIFSSMBGetCIFSACL(const int xid, struct cifs_tcon *tcon, __u16 fid,
- struct cifs_ntsd **acl_inf, __u32 *pbuflen)
-{
- int rc = 0;
- int buf_type = 0;
- QUERY_SEC_DESC_REQ *pSMB;
- struct kvec iov[1];
-
- cFYI(1, "GetCifsACL");
-
- *pbuflen = 0;
- *acl_inf = NULL;
-
- rc = smb_init_nttransact(NT_TRANSACT_QUERY_SECURITY_DESC, 0,
- 8 /* parm len */, tcon, (void **) &pSMB);
- if (rc)
- return rc;
-
- pSMB->MaxParameterCount = cpu_to_le32(4);
- /* BB TEST with big acls that might need to be e.g. larger than 16K */
- pSMB->MaxSetupCount = 0;
- pSMB->Fid = fid; /* file handle always le */
- pSMB->AclFlags = cpu_to_le32(CIFS_ACL_OWNER | CIFS_ACL_GROUP |
- CIFS_ACL_DACL);
- pSMB->ByteCount = cpu_to_le16(11); /* 3 bytes pad + 8 bytes parm */
- inc_rfc1001_len(pSMB, 11);
- iov[0].iov_base = (char *)pSMB;
- iov[0].iov_len = be32_to_cpu(pSMB->hdr.smb_buf_length) + 4;
-
- rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
- 0);
- cifs_stats_inc(&tcon->num_acl_get);
- if (rc) {
- cFYI(1, "Send error in QuerySecDesc = %d", rc);
- } else { /* decode response */
- __le32 *parm;
- __u32 parm_len;
- __u32 acl_len;
- struct smb_com_ntransact_rsp *pSMBr;
- char *pdata;
-
-/* validate_nttransact */
- rc = validate_ntransact(iov[0].iov_base, (char **)&parm,
- &pdata, &parm_len, pbuflen);
- if (rc)
- goto qsec_out;
- pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base;
-
- cFYI(1, "smb %p parm %p data %p", pSMBr, parm, *acl_inf);
-
- if (le32_to_cpu(pSMBr->ParameterCount) != 4) {
- rc = -EIO; /* bad smb */
- *pbuflen = 0;
- goto qsec_out;
- }
-
-/* BB check that data area is minimum length and as big as acl_len */
-
- acl_len = le32_to_cpu(*parm);
- if (acl_len != *pbuflen) {
- cERROR(1, "acl length %d does not match %d",
- acl_len, *pbuflen);
- if (*pbuflen > acl_len)
- *pbuflen = acl_len;
- }
-
- /* check if buffer is big enough for the acl
- header followed by the smallest SID */
- if ((*pbuflen < sizeof(struct cifs_ntsd) + 8) ||
- (*pbuflen >= 64 * 1024)) {
- cERROR(1, "bad acl length %d", *pbuflen);
- rc = -EINVAL;
- *pbuflen = 0;
- } else {
- *acl_inf = kmalloc(*pbuflen, GFP_KERNEL);
- if (*acl_inf == NULL) {
- *pbuflen = 0;
- rc = -ENOMEM;
- }
- memcpy(*acl_inf, pdata, *pbuflen);
- }
- }
-qsec_out:
- if (buf_type == CIFS_SMALL_BUFFER)
- cifs_small_buf_release(iov[0].iov_base);
- else if (buf_type == CIFS_LARGE_BUFFER)
- cifs_buf_release(iov[0].iov_base);
-/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
- return rc;
-}
-
-int
-CIFSSMBSetCIFSACL(const int xid, struct cifs_tcon *tcon, __u16 fid,
- struct cifs_ntsd *pntsd, __u32 acllen, int aclflag)
-{
- __u16 byte_count, param_count, data_count, param_offset, data_offset;
- int rc = 0;
- int bytes_returned = 0;
- SET_SEC_DESC_REQ *pSMB = NULL;
- void *pSMBr;
-
-setCifsAclRetry:
- rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB, &pSMBr);
- if (rc)
- return rc;
-
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
-
- param_count = 8;
- param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
- data_count = acllen;
- data_offset = param_offset + param_count;
- byte_count = 3 /* pad */ + param_count;
-
- pSMB->DataCount = cpu_to_le32(data_count);
- pSMB->TotalDataCount = pSMB->DataCount;
- pSMB->MaxParameterCount = cpu_to_le32(4);
- pSMB->MaxDataCount = cpu_to_le32(16384);
- pSMB->ParameterCount = cpu_to_le32(param_count);
- pSMB->ParameterOffset = cpu_to_le32(param_offset);
- pSMB->TotalParameterCount = pSMB->ParameterCount;
- pSMB->DataOffset = cpu_to_le32(data_offset);
- pSMB->SetupCount = 0;
- pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
- pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
-
- pSMB->Fid = fid; /* file handle always le */
- pSMB->Reserved2 = 0;
- pSMB->AclFlags = cpu_to_le32(aclflag);
-
- if (pntsd && acllen) {
- memcpy((char *)pSMBr + offsetof(struct smb_hdr, Protocol) +
- data_offset, pntsd, acllen);
- inc_rfc1001_len(pSMB, byte_count + data_count);
- } else
- inc_rfc1001_len(pSMB, byte_count);
-
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
-
- cFYI(1, "SetCIFSACL bytes_returned: %d, rc: %d", bytes_returned, rc);
- if (rc)
- cFYI(1, "Set CIFS ACL returned %d", rc);
- cifs_buf_release(pSMB);
-
- if (rc == -EAGAIN)
- goto setCifsAclRetry;
-
- return (rc);
-}
-
-#endif /* CONFIG_CIFS_ACL */
-
-/* Legacy Query Path Information call for lookup to old servers such
- as Win9x/WinME */
-int SMBQueryInformation(const int xid, struct cifs_tcon *tcon,
- const unsigned char *searchName,
- FILE_ALL_INFO *pFinfo,
- const struct nls_table *nls_codepage, int remap)
-{
- QUERY_INFORMATION_REQ *pSMB;
- QUERY_INFORMATION_RSP *pSMBr;
- int rc = 0;
- int bytes_returned;
- int name_len;
-
- cFYI(1, "In SMBQPath path %s", searchName);
-QInfRetry:
- rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len =
- cifsConvertToUTF16((__le16 *) pSMB->FileName,
- searchName, PATH_MAX, nls_codepage,
- remap);
- name_len++; /* trailing null */
- name_len *= 2;
- } else {
- name_len = strnlen(searchName, PATH_MAX);
- name_len++; /* trailing null */
- strncpy(pSMB->FileName, searchName, name_len);
- }
- pSMB->BufferFormat = 0x04;
- name_len++; /* account for buffer type byte */
- inc_rfc1001_len(pSMB, (__u16)name_len);
- pSMB->ByteCount = cpu_to_le16(name_len);
-
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc) {
- cFYI(1, "Send error in QueryInfo = %d", rc);
- } else if (pFinfo) {
- struct timespec ts;
- __u32 time = le32_to_cpu(pSMBr->last_write_time);
-
- /* decode response */
- /* BB FIXME - add time zone adjustment BB */
- memset(pFinfo, 0, sizeof(FILE_ALL_INFO));
- ts.tv_nsec = 0;
- ts.tv_sec = time;
- /* decode time fields */
- pFinfo->ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(ts));
- pFinfo->LastWriteTime = pFinfo->ChangeTime;
- pFinfo->LastAccessTime = 0;
- pFinfo->AllocationSize =
- cpu_to_le64(le32_to_cpu(pSMBr->size));
- pFinfo->EndOfFile = pFinfo->AllocationSize;
- pFinfo->Attributes =
- cpu_to_le32(le16_to_cpu(pSMBr->attr));
- } else
- rc = -EIO; /* bad buffer passed in */
-
- cifs_buf_release(pSMB);
-
- if (rc == -EAGAIN)
- goto QInfRetry;
-
- return rc;
-}
-
-int
-CIFSSMBQFileInfo(const int xid, struct cifs_tcon *tcon,
- u16 netfid, FILE_ALL_INFO *pFindData)
-{
- struct smb_t2_qfi_req *pSMB = NULL;
- struct smb_t2_qfi_rsp *pSMBr = NULL;
- int rc = 0;
- int bytes_returned;
- __u16 params, byte_count;
-
-QFileInfoRetry:
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- params = 2 /* level */ + 2 /* fid */;
- pSMB->t2.TotalDataCount = 0;
- pSMB->t2.MaxParameterCount = cpu_to_le16(4);
- /* BB find exact max data count below from sess structure BB */
- pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
- pSMB->t2.MaxSetupCount = 0;
- pSMB->t2.Reserved = 0;
- pSMB->t2.Flags = 0;
- pSMB->t2.Timeout = 0;
- pSMB->t2.Reserved2 = 0;
- pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
- Fid) - 4);
- pSMB->t2.DataCount = 0;
- pSMB->t2.DataOffset = 0;
- pSMB->t2.SetupCount = 1;
- pSMB->t2.Reserved3 = 0;
- pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
- byte_count = params + 1 /* pad */ ;
- pSMB->t2.TotalParameterCount = cpu_to_le16(params);
- pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
- pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
- pSMB->Pad = 0;
- pSMB->Fid = netfid;
- inc_rfc1001_len(pSMB, byte_count);
-
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc) {
- cFYI(1, "Send error in QPathInfo = %d", rc);
- } else { /* decode response */
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
-
- if (rc) /* BB add auto retry on EOPNOTSUPP? */
- rc = -EIO;
- else if (get_bcc(&pSMBr->hdr) < 40)
- rc = -EIO; /* bad smb */
- else if (pFindData) {
- __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
- memcpy((char *) pFindData,
- (char *) &pSMBr->hdr.Protocol +
- data_offset, sizeof(FILE_ALL_INFO));
- } else
- rc = -ENOMEM;
- }
- cifs_buf_release(pSMB);
- if (rc == -EAGAIN)
- goto QFileInfoRetry;
-
- return rc;
-}
-
-int
-CIFSSMBQPathInfo(const int xid, struct cifs_tcon *tcon,
- const unsigned char *searchName,
- FILE_ALL_INFO *pFindData,
- int legacy /* old style infolevel */,
- const struct nls_table *nls_codepage, int remap)
-{
-/* level 263 SMB_QUERY_FILE_ALL_INFO */
- TRANSACTION2_QPI_REQ *pSMB = NULL;
- TRANSACTION2_QPI_RSP *pSMBr = NULL;
- int rc = 0;
- int bytes_returned;
- int name_len;
- __u16 params, byte_count;
-
-/* cFYI(1, "In QPathInfo path %s", searchName); */
-QPathInfoRetry:
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len =
- cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
- PATH_MAX, nls_codepage, remap);
- name_len++; /* trailing null */
- name_len *= 2;
- } else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(searchName, PATH_MAX);
- name_len++; /* trailing null */
- strncpy(pSMB->FileName, searchName, name_len);
- }
-
- params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
- pSMB->TotalDataCount = 0;
- pSMB->MaxParameterCount = cpu_to_le16(2);
- /* BB find exact max SMB PDU from sess structure BB */
- pSMB->MaxDataCount = cpu_to_le16(4000);
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- pSMB->ParameterOffset = cpu_to_le16(offsetof(
- struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
- pSMB->DataCount = 0;
- pSMB->DataOffset = 0;
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
- byte_count = params + 1 /* pad */ ;
- pSMB->TotalParameterCount = cpu_to_le16(params);
- pSMB->ParameterCount = pSMB->TotalParameterCount;
- if (legacy)
- pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
- else
- pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
- pSMB->Reserved4 = 0;
- inc_rfc1001_len(pSMB, byte_count);
- pSMB->ByteCount = cpu_to_le16(byte_count);
-
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc) {
- cFYI(1, "Send error in QPathInfo = %d", rc);
- } else { /* decode response */
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
-
- if (rc) /* BB add auto retry on EOPNOTSUPP? */
- rc = -EIO;
- else if (!legacy && get_bcc(&pSMBr->hdr) < 40)
- rc = -EIO; /* bad smb */
- else if (legacy && get_bcc(&pSMBr->hdr) < 24)
- rc = -EIO; /* 24 or 26 expected but we do not read
- last field */
- else if (pFindData) {
- int size;
- __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
-
- /* On legacy responses we do not read the last field,
- EAsize, fortunately since it varies by subdialect and
- also note it differs on Set vs. Get, ie two bytes or 4
- bytes depending but we don't care here */
- if (legacy)
- size = sizeof(FILE_INFO_STANDARD);
- else
- size = sizeof(FILE_ALL_INFO);
- memcpy((char *) pFindData,
- (char *) &pSMBr->hdr.Protocol +
- data_offset, size);
- } else
- rc = -ENOMEM;
- }
- cifs_buf_release(pSMB);
- if (rc == -EAGAIN)
- goto QPathInfoRetry;
-
- return rc;
-}
-
-int
-CIFSSMBUnixQFileInfo(const int xid, struct cifs_tcon *tcon,
- u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
-{
- struct smb_t2_qfi_req *pSMB = NULL;
- struct smb_t2_qfi_rsp *pSMBr = NULL;
- int rc = 0;
- int bytes_returned;
- __u16 params, byte_count;
-
-UnixQFileInfoRetry:
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- params = 2 /* level */ + 2 /* fid */;
- pSMB->t2.TotalDataCount = 0;
- pSMB->t2.MaxParameterCount = cpu_to_le16(4);
- /* BB find exact max data count below from sess structure BB */
- pSMB->t2.MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
- pSMB->t2.MaxSetupCount = 0;
- pSMB->t2.Reserved = 0;
- pSMB->t2.Flags = 0;
- pSMB->t2.Timeout = 0;
- pSMB->t2.Reserved2 = 0;
- pSMB->t2.ParameterOffset = cpu_to_le16(offsetof(struct smb_t2_qfi_req,
- Fid) - 4);
- pSMB->t2.DataCount = 0;
- pSMB->t2.DataOffset = 0;
- pSMB->t2.SetupCount = 1;
- pSMB->t2.Reserved3 = 0;
- pSMB->t2.SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
- byte_count = params + 1 /* pad */ ;
- pSMB->t2.TotalParameterCount = cpu_to_le16(params);
- pSMB->t2.ParameterCount = pSMB->t2.TotalParameterCount;
- pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
- pSMB->Pad = 0;
- pSMB->Fid = netfid;
- inc_rfc1001_len(pSMB, byte_count);
-
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc) {
- cFYI(1, "Send error in QPathInfo = %d", rc);
- } else { /* decode response */
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
-
- if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
- cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response.\n"
- "Unix Extensions can be disabled on mount "
- "by specifying the nosfu mount option.");
- rc = -EIO; /* bad smb */
- } else {
- __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
- memcpy((char *) pFindData,
- (char *) &pSMBr->hdr.Protocol +
- data_offset,
- sizeof(FILE_UNIX_BASIC_INFO));
- }
- }
-
- cifs_buf_release(pSMB);
- if (rc == -EAGAIN)
- goto UnixQFileInfoRetry;
-
- return rc;
-}
-
-int
-CIFSSMBUnixQPathInfo(const int xid, struct cifs_tcon *tcon,
- const unsigned char *searchName,
- FILE_UNIX_BASIC_INFO *pFindData,
- const struct nls_table *nls_codepage, int remap)
-{
-/* SMB_QUERY_FILE_UNIX_BASIC */
- TRANSACTION2_QPI_REQ *pSMB = NULL;
- TRANSACTION2_QPI_RSP *pSMBr = NULL;
- int rc = 0;
- int bytes_returned = 0;
- int name_len;
- __u16 params, byte_count;
-
- cFYI(1, "In QPathInfo (Unix) the path %s", searchName);
-UnixQPathInfoRetry:
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len =
- cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
- PATH_MAX, nls_codepage, remap);
- name_len++; /* trailing null */
- name_len *= 2;
- } else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(searchName, PATH_MAX);
- name_len++; /* trailing null */
- strncpy(pSMB->FileName, searchName, name_len);
- }
-
- params = 2 /* level */ + 4 /* reserved */ + name_len /* includes NUL */;
- pSMB->TotalDataCount = 0;
- pSMB->MaxParameterCount = cpu_to_le16(2);
- /* BB find exact max SMB PDU from sess structure BB */
- pSMB->MaxDataCount = cpu_to_le16(4000);
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- pSMB->ParameterOffset = cpu_to_le16(offsetof(
- struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
- pSMB->DataCount = 0;
- pSMB->DataOffset = 0;
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
- byte_count = params + 1 /* pad */ ;
- pSMB->TotalParameterCount = cpu_to_le16(params);
- pSMB->ParameterCount = pSMB->TotalParameterCount;
- pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
- pSMB->Reserved4 = 0;
- inc_rfc1001_len(pSMB, byte_count);
- pSMB->ByteCount = cpu_to_le16(byte_count);
-
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc) {
- cFYI(1, "Send error in QPathInfo = %d", rc);
- } else { /* decode response */
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
-
- if (rc || get_bcc(&pSMBr->hdr) < sizeof(FILE_UNIX_BASIC_INFO)) {
- cERROR(1, "Malformed FILE_UNIX_BASIC_INFO response.\n"
- "Unix Extensions can be disabled on mount "
- "by specifying the nosfu mount option.");
- rc = -EIO; /* bad smb */
- } else {
- __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
- memcpy((char *) pFindData,
- (char *) &pSMBr->hdr.Protocol +
- data_offset,
- sizeof(FILE_UNIX_BASIC_INFO));
- }
- }
- cifs_buf_release(pSMB);
- if (rc == -EAGAIN)
- goto UnixQPathInfoRetry;
-
- return rc;
-}
-
-/* xid, tcon, searchName and codepage are input parms, rest are returned */
-int
-CIFSFindFirst(const int xid, struct cifs_tcon *tcon,
- const char *searchName,
- const struct nls_table *nls_codepage,
- __u16 *pnetfid, __u16 search_flags,
- struct cifs_search_info *psrch_inf, int remap, const char dirsep)
-{
-/* level 257 SMB_ */
- TRANSACTION2_FFIRST_REQ *pSMB = NULL;
- TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
- T2_FFIRST_RSP_PARMS *parms;
- int rc = 0;
- int bytes_returned = 0;
- int name_len;
- __u16 params, byte_count;
-
- cFYI(1, "In FindFirst for %s", searchName);
-
-findFirstRetry:
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len =
- cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
- PATH_MAX, nls_codepage, remap);
- /* We can not add the asterik earlier in case
- it got remapped to 0xF03A as if it were part of the
- directory name instead of a wildcard */
- name_len *= 2;
- pSMB->FileName[name_len] = dirsep;
- pSMB->FileName[name_len+1] = 0;
- pSMB->FileName[name_len+2] = '*';
- pSMB->FileName[name_len+3] = 0;
- name_len += 4; /* now the trailing null */
- pSMB->FileName[name_len] = 0; /* null terminate just in case */
- pSMB->FileName[name_len+1] = 0;
- name_len += 2;
- } else { /* BB add check for overrun of SMB buf BB */
- name_len = strnlen(searchName, PATH_MAX);
-/* BB fix here and in unicode clause above ie
- if (name_len > buffersize-header)
- free buffer exit; BB */
- strncpy(pSMB->FileName, searchName, name_len);
- pSMB->FileName[name_len] = dirsep;
- pSMB->FileName[name_len+1] = '*';
- pSMB->FileName[name_len+2] = 0;
- name_len += 3;
- }
-
- params = 12 + name_len /* includes null */ ;
- pSMB->TotalDataCount = 0; /* no EAs */
- pSMB->MaxParameterCount = cpu_to_le16(10);
- pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- byte_count = params + 1 /* pad */ ;
- pSMB->TotalParameterCount = cpu_to_le16(params);
- pSMB->ParameterCount = pSMB->TotalParameterCount;
- pSMB->ParameterOffset = cpu_to_le16(
- offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
- - 4);
- pSMB->DataCount = 0;
- pSMB->DataOffset = 0;
- pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
- pSMB->SearchAttributes =
- cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
- ATTR_DIRECTORY);
- pSMB->SearchCount = cpu_to_le16(CIFSMaxBufSize/sizeof(FILE_UNIX_INFO));
- pSMB->SearchFlags = cpu_to_le16(search_flags);
- pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
-
- /* BB what should we set StorageType to? Does it matter? BB */
- pSMB->SearchStorageType = 0;
- inc_rfc1001_len(pSMB, byte_count);
- pSMB->ByteCount = cpu_to_le16(byte_count);
-
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- cifs_stats_inc(&tcon->num_ffirst);
-
- if (rc) {/* BB add logic to retry regular search if Unix search
- rejected unexpectedly by server */
- /* BB Add code to handle unsupported level rc */
- cFYI(1, "Error in FindFirst = %d", rc);
-
- cifs_buf_release(pSMB);
-
- /* BB eventually could optimize out free and realloc of buf */
- /* for this case */
- if (rc == -EAGAIN)
- goto findFirstRetry;
- } else { /* decode response */
- /* BB remember to free buffer if error BB */
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
- if (rc == 0) {
- unsigned int lnoff;
-
- if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
- psrch_inf->unicode = true;
- else
- psrch_inf->unicode = false;
-
- psrch_inf->ntwrk_buf_start = (char *)pSMBr;
- psrch_inf->smallBuf = 0;
- psrch_inf->srch_entries_start =
- (char *) &pSMBr->hdr.Protocol +
- le16_to_cpu(pSMBr->t2.DataOffset);
- parms = (T2_FFIRST_RSP_PARMS *)((char *) &pSMBr->hdr.Protocol +
- le16_to_cpu(pSMBr->t2.ParameterOffset));
-
- if (parms->EndofSearch)
- psrch_inf->endOfSearch = true;
- else
- psrch_inf->endOfSearch = false;
-
- psrch_inf->entries_in_buffer =
- le16_to_cpu(parms->SearchCount);
- psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
- psrch_inf->entries_in_buffer;
- lnoff = le16_to_cpu(parms->LastNameOffset);
- if (CIFSMaxBufSize < lnoff) {
- cERROR(1, "ignoring corrupt resume name");
- psrch_inf->last_entry = NULL;
- return rc;
- }
-
- psrch_inf->last_entry = psrch_inf->srch_entries_start +
- lnoff;
-
- *pnetfid = parms->SearchHandle;
- } else {
- cifs_buf_release(pSMB);
- }
- }
-
- return rc;
-}
-
-int CIFSFindNext(const int xid, struct cifs_tcon *tcon, __u16 searchHandle,
- __u16 search_flags, struct cifs_search_info *psrch_inf)
-{
- TRANSACTION2_FNEXT_REQ *pSMB = NULL;
- TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
- T2_FNEXT_RSP_PARMS *parms;
- char *response_data;
- int rc = 0;
- int bytes_returned;
- unsigned int name_len;
- __u16 params, byte_count;
-
- cFYI(1, "In FindNext");
-
- if (psrch_inf->endOfSearch)
- return -ENOENT;
-
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- params = 14; /* includes 2 bytes of null string, converted to LE below*/
- byte_count = 0;
- pSMB->TotalDataCount = 0; /* no EAs */
- pSMB->MaxParameterCount = cpu_to_le16(8);
- pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize & 0xFFFFFF00);
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- pSMB->ParameterOffset = cpu_to_le16(
- offsetof(struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
- pSMB->DataCount = 0;
- pSMB->DataOffset = 0;
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
- pSMB->SearchHandle = searchHandle; /* always kept as le */
- pSMB->SearchCount =
- cpu_to_le16(CIFSMaxBufSize / sizeof(FILE_UNIX_INFO));
- pSMB->InformationLevel = cpu_to_le16(psrch_inf->info_level);
- pSMB->ResumeKey = psrch_inf->resume_key;
- pSMB->SearchFlags = cpu_to_le16(search_flags);
-
- name_len = psrch_inf->resume_name_len;
- params += name_len;
- if (name_len < PATH_MAX) {
- memcpy(pSMB->ResumeFileName, psrch_inf->presume_name, name_len);
- byte_count += name_len;
- /* 14 byte parm len above enough for 2 byte null terminator */
- pSMB->ResumeFileName[name_len] = 0;
- pSMB->ResumeFileName[name_len+1] = 0;
- } else {
- rc = -EINVAL;
- goto FNext2_err_exit;
- }
- byte_count = params + 1 /* pad */ ;
- pSMB->TotalParameterCount = cpu_to_le16(params);
- pSMB->ParameterCount = pSMB->TotalParameterCount;
- inc_rfc1001_len(pSMB, byte_count);
- pSMB->ByteCount = cpu_to_le16(byte_count);
-
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- cifs_stats_inc(&tcon->num_fnext);
- if (rc) {
- if (rc == -EBADF) {
- psrch_inf->endOfSearch = true;
- cifs_buf_release(pSMB);
- rc = 0; /* search probably was closed at end of search*/
- } else
- cFYI(1, "FindNext returned = %d", rc);
- } else { /* decode response */
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
-
- if (rc == 0) {
- unsigned int lnoff;
-
- /* BB fixme add lock for file (srch_info) struct here */
- if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
- psrch_inf->unicode = true;
- else
- psrch_inf->unicode = false;
- response_data = (char *) &pSMBr->hdr.Protocol +
- le16_to_cpu(pSMBr->t2.ParameterOffset);
- parms = (T2_FNEXT_RSP_PARMS *)response_data;
- response_data = (char *)&pSMBr->hdr.Protocol +
- le16_to_cpu(pSMBr->t2.DataOffset);
- if (psrch_inf->smallBuf)
- cifs_small_buf_release(
- psrch_inf->ntwrk_buf_start);
- else
- cifs_buf_release(psrch_inf->ntwrk_buf_start);
- psrch_inf->srch_entries_start = response_data;
- psrch_inf->ntwrk_buf_start = (char *)pSMB;
- psrch_inf->smallBuf = 0;
- if (parms->EndofSearch)
- psrch_inf->endOfSearch = true;
- else
- psrch_inf->endOfSearch = false;
- psrch_inf->entries_in_buffer =
- le16_to_cpu(parms->SearchCount);
- psrch_inf->index_of_last_entry +=
- psrch_inf->entries_in_buffer;
- lnoff = le16_to_cpu(parms->LastNameOffset);
- if (CIFSMaxBufSize < lnoff) {
- cERROR(1, "ignoring corrupt resume name");
- psrch_inf->last_entry = NULL;
- return rc;
- } else
- psrch_inf->last_entry =
- psrch_inf->srch_entries_start + lnoff;
-
-/* cFYI(1, "fnxt2 entries in buf %d index_of_last %d",
- psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry); */
-
- /* BB fixme add unlock here */
- }
-
- }
-
- /* BB On error, should we leave previous search buf (and count and
- last entry fields) intact or free the previous one? */
-
- /* Note: On -EAGAIN error only caller can retry on handle based calls
- since file handle passed in no longer valid */
-FNext2_err_exit:
- if (rc != 0)
- cifs_buf_release(pSMB);
- return rc;
-}
-
-int
-CIFSFindClose(const int xid, struct cifs_tcon *tcon,
- const __u16 searchHandle)
-{
- int rc = 0;
- FINDCLOSE_REQ *pSMB = NULL;
-
- cFYI(1, "In CIFSSMBFindClose");
- rc = small_smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **)&pSMB);
-
- /* no sense returning error if session restarted
- as file handle has been closed */
- if (rc == -EAGAIN)
- return 0;
- if (rc)
- return rc;
-
- pSMB->FileID = searchHandle;
- pSMB->ByteCount = 0;
- rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
- if (rc)
- cERROR(1, "Send error in FindClose = %d", rc);
-
- cifs_stats_inc(&tcon->num_fclose);
-
- /* Since session is dead, search handle closed on server already */
- if (rc == -EAGAIN)
- rc = 0;
-
- return rc;
-}
-
-int
-CIFSGetSrvInodeNumber(const int xid, struct cifs_tcon *tcon,
- const unsigned char *searchName,
- __u64 *inode_number,
- const struct nls_table *nls_codepage, int remap)
-{
- int rc = 0;
- TRANSACTION2_QPI_REQ *pSMB = NULL;
- TRANSACTION2_QPI_RSP *pSMBr = NULL;
- int name_len, bytes_returned;
- __u16 params, byte_count;
-
- cFYI(1, "In GetSrvInodeNum for %s", searchName);
- if (tcon == NULL)
- return -ENODEV;
-
-GetInodeNumberRetry:
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len =
- cifsConvertToUTF16((__le16 *) pSMB->FileName,
- searchName, PATH_MAX, nls_codepage,
- remap);
- name_len++; /* trailing null */
- name_len *= 2;
- } else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(searchName, PATH_MAX);
- name_len++; /* trailing null */
- strncpy(pSMB->FileName, searchName, name_len);
- }
-
- params = 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
- pSMB->TotalDataCount = 0;
- pSMB->MaxParameterCount = cpu_to_le16(2);
- /* BB find exact max data count below from sess structure BB */
- pSMB->MaxDataCount = cpu_to_le16(4000);
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- pSMB->ParameterOffset = cpu_to_le16(offsetof(
- struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
- pSMB->DataCount = 0;
- pSMB->DataOffset = 0;
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
- byte_count = params + 1 /* pad */ ;
- pSMB->TotalParameterCount = cpu_to_le16(params);
- pSMB->ParameterCount = pSMB->TotalParameterCount;
- pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_INTERNAL_INFO);
- pSMB->Reserved4 = 0;
- inc_rfc1001_len(pSMB, byte_count);
- pSMB->ByteCount = cpu_to_le16(byte_count);
-
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc) {
- cFYI(1, "error %d in QueryInternalInfo", rc);
- } else {
- /* decode response */
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
- /* BB also check enough total bytes returned */
- if (rc || get_bcc(&pSMBr->hdr) < 2)
- /* If rc should we check for EOPNOSUPP and
- disable the srvino flag? or in caller? */
- rc = -EIO; /* bad smb */
- else {
- __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
- __u16 count = le16_to_cpu(pSMBr->t2.DataCount);
- struct file_internal_info *pfinfo;
- /* BB Do we need a cast or hash here ? */
- if (count < 8) {
- cFYI(1, "Illegal size ret in QryIntrnlInf");
- rc = -EIO;
- goto GetInodeNumOut;
- }
- pfinfo = (struct file_internal_info *)
- (data_offset + (char *) &pSMBr->hdr.Protocol);
- *inode_number = le64_to_cpu(pfinfo->UniqueId);
- }
- }
-GetInodeNumOut:
- cifs_buf_release(pSMB);
- if (rc == -EAGAIN)
- goto GetInodeNumberRetry;
- return rc;
-}
-
-/* parses DFS refferal V3 structure
- * caller is responsible for freeing target_nodes
- * returns:
- * on success - 0
- * on failure - errno
- */
-static int
-parse_DFS_referrals(TRANSACTION2_GET_DFS_REFER_RSP *pSMBr,
- unsigned int *num_of_nodes,
- struct dfs_info3_param **target_nodes,
- const struct nls_table *nls_codepage, int remap,
- const char *searchName)
-{
- int i, rc = 0;
- char *data_end;
- bool is_unicode;
- struct dfs_referral_level_3 *ref;
-
- if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
- is_unicode = true;
- else
- is_unicode = false;
- *num_of_nodes = le16_to_cpu(pSMBr->NumberOfReferrals);
-
- if (*num_of_nodes < 1) {
- cERROR(1, "num_referrals: must be at least > 0,"
- "but we get num_referrals = %d\n", *num_of_nodes);
- rc = -EINVAL;
- goto parse_DFS_referrals_exit;
- }
-
- ref = (struct dfs_referral_level_3 *) &(pSMBr->referrals);
- if (ref->VersionNumber != cpu_to_le16(3)) {
- cERROR(1, "Referrals of V%d version are not supported,"
- "should be V3", le16_to_cpu(ref->VersionNumber));
- rc = -EINVAL;
- goto parse_DFS_referrals_exit;
- }
-
- /* get the upper boundary of the resp buffer */
- data_end = (char *)(&(pSMBr->PathConsumed)) +
- le16_to_cpu(pSMBr->t2.DataCount);
-
- cFYI(1, "num_referrals: %d dfs flags: 0x%x ...\n",
- *num_of_nodes,
- le32_to_cpu(pSMBr->DFSFlags));
-
- *target_nodes = kzalloc(sizeof(struct dfs_info3_param) *
- *num_of_nodes, GFP_KERNEL);
- if (*target_nodes == NULL) {
- cERROR(1, "Failed to allocate buffer for target_nodes\n");
- rc = -ENOMEM;
- goto parse_DFS_referrals_exit;
- }
-
- /* collect necessary data from referrals */
- for (i = 0; i < *num_of_nodes; i++) {
- char *temp;
- int max_len;
- struct dfs_info3_param *node = (*target_nodes)+i;
-
- node->flags = le32_to_cpu(pSMBr->DFSFlags);
- if (is_unicode) {
- __le16 *tmp = kmalloc(strlen(searchName)*2 + 2,
- GFP_KERNEL);
- if (tmp == NULL) {
- rc = -ENOMEM;
- goto parse_DFS_referrals_exit;
- }
- cifsConvertToUTF16((__le16 *) tmp, searchName,
- PATH_MAX, nls_codepage, remap);
- node->path_consumed = cifs_utf16_bytes(tmp,
- le16_to_cpu(pSMBr->PathConsumed),
- nls_codepage);
- kfree(tmp);
- } else
- node->path_consumed = le16_to_cpu(pSMBr->PathConsumed);
-
- node->server_type = le16_to_cpu(ref->ServerType);
- node->ref_flag = le16_to_cpu(ref->ReferralEntryFlags);
-
- /* copy DfsPath */
- temp = (char *)ref + le16_to_cpu(ref->DfsPathOffset);
- max_len = data_end - temp;
- node->path_name = cifs_strndup_from_utf16(temp, max_len,
- is_unicode, nls_codepage);
- if (!node->path_name) {
- rc = -ENOMEM;
- goto parse_DFS_referrals_exit;
- }
-
- /* copy link target UNC */
- temp = (char *)ref + le16_to_cpu(ref->NetworkAddressOffset);
- max_len = data_end - temp;
- node->node_name = cifs_strndup_from_utf16(temp, max_len,
- is_unicode, nls_codepage);
- if (!node->node_name) {
- rc = -ENOMEM;
- goto parse_DFS_referrals_exit;
- }
-
- ref++;
- }
-
-parse_DFS_referrals_exit:
- if (rc) {
- free_dfs_info_array(*target_nodes, *num_of_nodes);
- *target_nodes = NULL;
- *num_of_nodes = 0;
- }
- return rc;
-}
-
-int
-CIFSGetDFSRefer(const int xid, struct cifs_ses *ses,
- const unsigned char *searchName,
- struct dfs_info3_param **target_nodes,
- unsigned int *num_of_nodes,
- const struct nls_table *nls_codepage, int remap)
-{
-/* TRANS2_GET_DFS_REFERRAL */
- TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
- TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
- int rc = 0;
- int bytes_returned;
- int name_len;
- __u16 params, byte_count;
- *num_of_nodes = 0;
- *target_nodes = NULL;
-
- cFYI(1, "In GetDFSRefer the path %s", searchName);
- if (ses == NULL)
- return -ENODEV;
-getDFSRetry:
- rc = smb_init(SMB_COM_TRANSACTION2, 15, NULL, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- /* server pointer checked in called function,
- but should never be null here anyway */
- pSMB->hdr.Mid = GetNextMid(ses->server);
- pSMB->hdr.Tid = ses->ipc_tid;
- pSMB->hdr.Uid = ses->Suid;
- if (ses->capabilities & CAP_STATUS32)
- pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
- if (ses->capabilities & CAP_DFS)
- pSMB->hdr.Flags2 |= SMBFLG2_DFS;
-
- if (ses->capabilities & CAP_UNICODE) {
- pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
- name_len =
- cifsConvertToUTF16((__le16 *) pSMB->RequestFileName,
- searchName, PATH_MAX, nls_codepage,
- remap);
- name_len++; /* trailing null */
- name_len *= 2;
- } else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(searchName, PATH_MAX);
- name_len++; /* trailing null */
- strncpy(pSMB->RequestFileName, searchName, name_len);
- }
-
- if (ses->server) {
- if (ses->server->sec_mode &
- (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
- pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
- }
-
- pSMB->hdr.Uid = ses->Suid;
-
- params = 2 /* level */ + name_len /*includes null */ ;
- pSMB->TotalDataCount = 0;
- pSMB->DataCount = 0;
- pSMB->DataOffset = 0;
- pSMB->MaxParameterCount = 0;
- /* BB find exact max SMB PDU from sess structure BB */
- pSMB->MaxDataCount = cpu_to_le16(4000);
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- pSMB->ParameterOffset = cpu_to_le16(offsetof(
- struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
- byte_count = params + 3 /* pad */ ;
- pSMB->ParameterCount = cpu_to_le16(params);
- pSMB->TotalParameterCount = pSMB->ParameterCount;
- pSMB->MaxReferralLevel = cpu_to_le16(3);
- inc_rfc1001_len(pSMB, byte_count);
- pSMB->ByteCount = cpu_to_le16(byte_count);
-
- rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc) {
- cFYI(1, "Send error in GetDFSRefer = %d", rc);
- goto GetDFSRefExit;
- }
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
-
- /* BB Also check if enough total bytes returned? */
- if (rc || get_bcc(&pSMBr->hdr) < 17) {
- rc = -EIO; /* bad smb */
- goto GetDFSRefExit;
- }
-
- cFYI(1, "Decoding GetDFSRefer response BCC: %d Offset %d",
- get_bcc(&pSMBr->hdr),
- le16_to_cpu(pSMBr->t2.DataOffset));
-
- /* parse returned result into more usable form */
- rc = parse_DFS_referrals(pSMBr, num_of_nodes,
- target_nodes, nls_codepage, remap,
- searchName);
-
-GetDFSRefExit:
- cifs_buf_release(pSMB);
-
- if (rc == -EAGAIN)
- goto getDFSRetry;
-
- return rc;
-}
-
-/* Query File System Info such as free space to old servers such as Win 9x */
-int
-SMBOldQFSInfo(const int xid, struct cifs_tcon *tcon, struct kstatfs *FSData)
-{
-/* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
- TRANSACTION2_QFSI_REQ *pSMB = NULL;
- TRANSACTION2_QFSI_RSP *pSMBr = NULL;
- FILE_SYSTEM_ALLOC_INFO *response_data;
- int rc = 0;
- int bytes_returned = 0;
- __u16 params, byte_count;
-
- cFYI(1, "OldQFSInfo");
-oldQFSInfoRetry:
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- params = 2; /* level */
- pSMB->TotalDataCount = 0;
- pSMB->MaxParameterCount = cpu_to_le16(2);
- pSMB->MaxDataCount = cpu_to_le16(1000);
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- byte_count = params + 1 /* pad */ ;
- pSMB->TotalParameterCount = cpu_to_le16(params);
- pSMB->ParameterCount = pSMB->TotalParameterCount;
- pSMB->ParameterOffset = cpu_to_le16(offsetof(
- struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
- pSMB->DataCount = 0;
- pSMB->DataOffset = 0;
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
- pSMB->InformationLevel = cpu_to_le16(SMB_INFO_ALLOCATION);
- inc_rfc1001_len(pSMB, byte_count);
- pSMB->ByteCount = cpu_to_le16(byte_count);
-
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc) {
- cFYI(1, "Send error in QFSInfo = %d", rc);
- } else { /* decode response */
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
-
- if (rc || get_bcc(&pSMBr->hdr) < 18)
- rc = -EIO; /* bad smb */
- else {
- __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
- cFYI(1, "qfsinf resp BCC: %d Offset %d",
- get_bcc(&pSMBr->hdr), data_offset);
-
- response_data = (FILE_SYSTEM_ALLOC_INFO *)
- (((char *) &pSMBr->hdr.Protocol) + data_offset);
- FSData->f_bsize =
- le16_to_cpu(response_data->BytesPerSector) *
- le32_to_cpu(response_data->
- SectorsPerAllocationUnit);
- FSData->f_blocks =
- le32_to_cpu(response_data->TotalAllocationUnits);
- FSData->f_bfree = FSData->f_bavail =
- le32_to_cpu(response_data->FreeAllocationUnits);
- cFYI(1, "Blocks: %lld Free: %lld Block size %ld",
- (unsigned long long)FSData->f_blocks,
- (unsigned long long)FSData->f_bfree,
- FSData->f_bsize);
- }
- }
- cifs_buf_release(pSMB);
-
- if (rc == -EAGAIN)
- goto oldQFSInfoRetry;
-
- return rc;
-}
-
-int
-CIFSSMBQFSInfo(const int xid, struct cifs_tcon *tcon, struct kstatfs *FSData)
-{
-/* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
- TRANSACTION2_QFSI_REQ *pSMB = NULL;
- TRANSACTION2_QFSI_RSP *pSMBr = NULL;
- FILE_SYSTEM_INFO *response_data;
- int rc = 0;
- int bytes_returned = 0;
- __u16 params, byte_count;
-
- cFYI(1, "In QFSInfo");
-QFSInfoRetry:
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- params = 2; /* level */
- pSMB->TotalDataCount = 0;
- pSMB->MaxParameterCount = cpu_to_le16(2);
- pSMB->MaxDataCount = cpu_to_le16(1000);
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- byte_count = params + 1 /* pad */ ;
- pSMB->TotalParameterCount = cpu_to_le16(params);
- pSMB->ParameterCount = pSMB->TotalParameterCount;
- pSMB->ParameterOffset = cpu_to_le16(offsetof(
- struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
- pSMB->DataCount = 0;
- pSMB->DataOffset = 0;
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
- pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
- inc_rfc1001_len(pSMB, byte_count);
- pSMB->ByteCount = cpu_to_le16(byte_count);
-
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc) {
- cFYI(1, "Send error in QFSInfo = %d", rc);
- } else { /* decode response */
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
-
- if (rc || get_bcc(&pSMBr->hdr) < 24)
- rc = -EIO; /* bad smb */
- else {
- __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
-
- response_data =
- (FILE_SYSTEM_INFO
- *) (((char *) &pSMBr->hdr.Protocol) +
- data_offset);
- FSData->f_bsize =
- le32_to_cpu(response_data->BytesPerSector) *
- le32_to_cpu(response_data->
- SectorsPerAllocationUnit);
- FSData->f_blocks =
- le64_to_cpu(response_data->TotalAllocationUnits);
- FSData->f_bfree = FSData->f_bavail =
- le64_to_cpu(response_data->FreeAllocationUnits);
- cFYI(1, "Blocks: %lld Free: %lld Block size %ld",
- (unsigned long long)FSData->f_blocks,
- (unsigned long long)FSData->f_bfree,
- FSData->f_bsize);
- }
- }
- cifs_buf_release(pSMB);
-
- if (rc == -EAGAIN)
- goto QFSInfoRetry;
-
- return rc;
-}
-
-int
-CIFSSMBQFSAttributeInfo(const int xid, struct cifs_tcon *tcon)
-{
-/* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
- TRANSACTION2_QFSI_REQ *pSMB = NULL;
- TRANSACTION2_QFSI_RSP *pSMBr = NULL;
- FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
- int rc = 0;
- int bytes_returned = 0;
- __u16 params, byte_count;
-
- cFYI(1, "In QFSAttributeInfo");
-QFSAttributeRetry:
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- params = 2; /* level */
- pSMB->TotalDataCount = 0;
- pSMB->MaxParameterCount = cpu_to_le16(2);
- /* BB find exact max SMB PDU from sess structure BB */
- pSMB->MaxDataCount = cpu_to_le16(1000);
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- byte_count = params + 1 /* pad */ ;
- pSMB->TotalParameterCount = cpu_to_le16(params);
- pSMB->ParameterCount = pSMB->TotalParameterCount;
- pSMB->ParameterOffset = cpu_to_le16(offsetof(
- struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
- pSMB->DataCount = 0;
- pSMB->DataOffset = 0;
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
- pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
- inc_rfc1001_len(pSMB, byte_count);
- pSMB->ByteCount = cpu_to_le16(byte_count);
-
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc) {
- cERROR(1, "Send error in QFSAttributeInfo = %d", rc);
- } else { /* decode response */
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
-
- if (rc || get_bcc(&pSMBr->hdr) < 13) {
- /* BB also check if enough bytes returned */
- rc = -EIO; /* bad smb */
- } else {
- __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
- response_data =
- (FILE_SYSTEM_ATTRIBUTE_INFO
- *) (((char *) &pSMBr->hdr.Protocol) +
- data_offset);
- memcpy(&tcon->fsAttrInfo, response_data,
- sizeof(FILE_SYSTEM_ATTRIBUTE_INFO));
- }
- }
- cifs_buf_release(pSMB);
-
- if (rc == -EAGAIN)
- goto QFSAttributeRetry;
-
- return rc;
-}
-
-int
-CIFSSMBQFSDeviceInfo(const int xid, struct cifs_tcon *tcon)
-{
-/* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
- TRANSACTION2_QFSI_REQ *pSMB = NULL;
- TRANSACTION2_QFSI_RSP *pSMBr = NULL;
- FILE_SYSTEM_DEVICE_INFO *response_data;
- int rc = 0;
- int bytes_returned = 0;
- __u16 params, byte_count;
-
- cFYI(1, "In QFSDeviceInfo");
-QFSDeviceRetry:
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- params = 2; /* level */
- pSMB->TotalDataCount = 0;
- pSMB->MaxParameterCount = cpu_to_le16(2);
- /* BB find exact max SMB PDU from sess structure BB */
- pSMB->MaxDataCount = cpu_to_le16(1000);
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- byte_count = params + 1 /* pad */ ;
- pSMB->TotalParameterCount = cpu_to_le16(params);
- pSMB->ParameterCount = pSMB->TotalParameterCount;
- pSMB->ParameterOffset = cpu_to_le16(offsetof(
- struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
-
- pSMB->DataCount = 0;
- pSMB->DataOffset = 0;
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
- pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
- inc_rfc1001_len(pSMB, byte_count);
- pSMB->ByteCount = cpu_to_le16(byte_count);
-
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc) {
- cFYI(1, "Send error in QFSDeviceInfo = %d", rc);
- } else { /* decode response */
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
-
- if (rc || get_bcc(&pSMBr->hdr) <
- sizeof(FILE_SYSTEM_DEVICE_INFO))
- rc = -EIO; /* bad smb */
- else {
- __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
- response_data =
- (FILE_SYSTEM_DEVICE_INFO *)
- (((char *) &pSMBr->hdr.Protocol) +
- data_offset);
- memcpy(&tcon->fsDevInfo, response_data,
- sizeof(FILE_SYSTEM_DEVICE_INFO));
- }
- }
- cifs_buf_release(pSMB);
-
- if (rc == -EAGAIN)
- goto QFSDeviceRetry;
-
- return rc;
-}
-
-int
-CIFSSMBQFSUnixInfo(const int xid, struct cifs_tcon *tcon)
-{
-/* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
- TRANSACTION2_QFSI_REQ *pSMB = NULL;
- TRANSACTION2_QFSI_RSP *pSMBr = NULL;
- FILE_SYSTEM_UNIX_INFO *response_data;
- int rc = 0;
- int bytes_returned = 0;
- __u16 params, byte_count;
-
- cFYI(1, "In QFSUnixInfo");
-QFSUnixRetry:
- rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
- (void **) &pSMB, (void **) &pSMBr);
- if (rc)
- return rc;
-
- params = 2; /* level */
- pSMB->TotalDataCount = 0;
- pSMB->DataCount = 0;
- pSMB->DataOffset = 0;
- pSMB->MaxParameterCount = cpu_to_le16(2);
- /* BB find exact max SMB PDU from sess structure BB */
- pSMB->MaxDataCount = cpu_to_le16(100);
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- byte_count = params + 1 /* pad */ ;
- pSMB->ParameterCount = cpu_to_le16(params);
- pSMB->TotalParameterCount = pSMB->ParameterCount;
- pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
- smb_com_transaction2_qfsi_req, InformationLevel) - 4);
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
- pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
- inc_rfc1001_len(pSMB, byte_count);
- pSMB->ByteCount = cpu_to_le16(byte_count);
-
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc) {
- cERROR(1, "Send error in QFSUnixInfo = %d", rc);
- } else { /* decode response */
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
-
- if (rc || get_bcc(&pSMBr->hdr) < 13) {
- rc = -EIO; /* bad smb */
- } else {
- __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
- response_data =
- (FILE_SYSTEM_UNIX_INFO
- *) (((char *) &pSMBr->hdr.Protocol) +
- data_offset);
- memcpy(&tcon->fsUnixInfo, response_data,
- sizeof(FILE_SYSTEM_UNIX_INFO));
- }
- }
- cifs_buf_release(pSMB);
-
- if (rc == -EAGAIN)
- goto QFSUnixRetry;
-
-
- return rc;
-}
-
-int
-CIFSSMBSetFSUnixInfo(const int xid, struct cifs_tcon *tcon, __u64 cap)
-{
-/* level 0x200 SMB_SET_CIFS_UNIX_INFO */
- TRANSACTION2_SETFSI_REQ *pSMB = NULL;
- TRANSACTION2_SETFSI_RSP *pSMBr = NULL;
- int rc = 0;
- int bytes_returned = 0;
- __u16 params, param_offset, offset, byte_count;
-
- cFYI(1, "In SETFSUnixInfo");
-SETFSUnixRetry:
- /* BB switch to small buf init to save memory */
- rc = smb_init_no_reconnect(SMB_COM_TRANSACTION2, 15, tcon,
- (void **) &pSMB, (void **) &pSMBr);
- if (rc)
- return rc;
-
- params = 4; /* 2 bytes zero followed by info level. */
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- param_offset = offsetof(struct smb_com_transaction2_setfsi_req, FileNum)
- - 4;
- offset = param_offset + params;
-
- pSMB->MaxParameterCount = cpu_to_le16(4);
- /* BB find exact max SMB PDU from sess structure BB */
- pSMB->MaxDataCount = cpu_to_le16(100);
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FS_INFORMATION);
- byte_count = 1 /* pad */ + params + 12;
-
- pSMB->DataCount = cpu_to_le16(12);
- pSMB->ParameterCount = cpu_to_le16(params);
- pSMB->TotalDataCount = pSMB->DataCount;
- pSMB->TotalParameterCount = pSMB->ParameterCount;
- pSMB->ParameterOffset = cpu_to_le16(param_offset);
- pSMB->DataOffset = cpu_to_le16(offset);
-
- /* Params. */
- pSMB->FileNum = 0;
- pSMB->InformationLevel = cpu_to_le16(SMB_SET_CIFS_UNIX_INFO);
-
- /* Data. */
- pSMB->ClientUnixMajor = cpu_to_le16(CIFS_UNIX_MAJOR_VERSION);
- pSMB->ClientUnixMinor = cpu_to_le16(CIFS_UNIX_MINOR_VERSION);
- pSMB->ClientUnixCap = cpu_to_le64(cap);
-
- inc_rfc1001_len(pSMB, byte_count);
- pSMB->ByteCount = cpu_to_le16(byte_count);
-
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc) {
- cERROR(1, "Send error in SETFSUnixInfo = %d", rc);
- } else { /* decode response */
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
- if (rc)
- rc = -EIO; /* bad smb */
- }
- cifs_buf_release(pSMB);
-
- if (rc == -EAGAIN)
- goto SETFSUnixRetry;
-
- return rc;
-}
-
-
-
-int
-CIFSSMBQFSPosixInfo(const int xid, struct cifs_tcon *tcon,
- struct kstatfs *FSData)
-{
-/* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
- TRANSACTION2_QFSI_REQ *pSMB = NULL;
- TRANSACTION2_QFSI_RSP *pSMBr = NULL;
- FILE_SYSTEM_POSIX_INFO *response_data;
- int rc = 0;
- int bytes_returned = 0;
- __u16 params, byte_count;
-
- cFYI(1, "In QFSPosixInfo");
-QFSPosixRetry:
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- params = 2; /* level */
- pSMB->TotalDataCount = 0;
- pSMB->DataCount = 0;
- pSMB->DataOffset = 0;
- pSMB->MaxParameterCount = cpu_to_le16(2);
- /* BB find exact max SMB PDU from sess structure BB */
- pSMB->MaxDataCount = cpu_to_le16(100);
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- byte_count = params + 1 /* pad */ ;
- pSMB->ParameterCount = cpu_to_le16(params);
- pSMB->TotalParameterCount = pSMB->ParameterCount;
- pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
- smb_com_transaction2_qfsi_req, InformationLevel) - 4);
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
- pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_POSIX_FS_INFO);
- inc_rfc1001_len(pSMB, byte_count);
- pSMB->ByteCount = cpu_to_le16(byte_count);
-
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc) {
- cFYI(1, "Send error in QFSUnixInfo = %d", rc);
- } else { /* decode response */
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
-
- if (rc || get_bcc(&pSMBr->hdr) < 13) {
- rc = -EIO; /* bad smb */
- } else {
- __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
- response_data =
- (FILE_SYSTEM_POSIX_INFO
- *) (((char *) &pSMBr->hdr.Protocol) +
- data_offset);
- FSData->f_bsize =
- le32_to_cpu(response_data->BlockSize);
- FSData->f_blocks =
- le64_to_cpu(response_data->TotalBlocks);
- FSData->f_bfree =
- le64_to_cpu(response_data->BlocksAvail);
- if (response_data->UserBlocksAvail == cpu_to_le64(-1)) {
- FSData->f_bavail = FSData->f_bfree;
- } else {
- FSData->f_bavail =
- le64_to_cpu(response_data->UserBlocksAvail);
- }
- if (response_data->TotalFileNodes != cpu_to_le64(-1))
- FSData->f_files =
- le64_to_cpu(response_data->TotalFileNodes);
- if (response_data->FreeFileNodes != cpu_to_le64(-1))
- FSData->f_ffree =
- le64_to_cpu(response_data->FreeFileNodes);
- }
- }
- cifs_buf_release(pSMB);
-
- if (rc == -EAGAIN)
- goto QFSPosixRetry;
-
- return rc;
-}
-
-
-/* We can not use write of zero bytes trick to
- set file size due to need for large file support. Also note that
- this SetPathInfo is preferred to SetFileInfo based method in next
- routine which is only needed to work around a sharing violation bug
- in Samba which this routine can run into */
-
-int
-CIFSSMBSetEOF(const int xid, struct cifs_tcon *tcon, const char *fileName,
- __u64 size, bool SetAllocation,
- const struct nls_table *nls_codepage, int remap)
-{
- struct smb_com_transaction2_spi_req *pSMB = NULL;
- struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
- struct file_end_of_file_info *parm_data;
- int name_len;
- int rc = 0;
- int bytes_returned = 0;
- __u16 params, byte_count, data_count, param_offset, offset;
-
- cFYI(1, "In SetEOF");
-SetEOFRetry:
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len =
- cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
- PATH_MAX, nls_codepage, remap);
- name_len++; /* trailing null */
- name_len *= 2;
- } else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(fileName, PATH_MAX);
- name_len++; /* trailing null */
- strncpy(pSMB->FileName, fileName, name_len);
- }
- params = 6 + name_len;
- data_count = sizeof(struct file_end_of_file_info);
- pSMB->MaxParameterCount = cpu_to_le16(2);
- pSMB->MaxDataCount = cpu_to_le16(4100);
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- param_offset = offsetof(struct smb_com_transaction2_spi_req,
- InformationLevel) - 4;
- offset = param_offset + params;
- if (SetAllocation) {
- if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
- pSMB->InformationLevel =
- cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
- else
- pSMB->InformationLevel =
- cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
- } else /* Set File Size */ {
- if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
- pSMB->InformationLevel =
- cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
- else
- pSMB->InformationLevel =
- cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
- }
-
- parm_data =
- (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
- offset);
- pSMB->ParameterOffset = cpu_to_le16(param_offset);
- pSMB->DataOffset = cpu_to_le16(offset);
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
- byte_count = 3 /* pad */ + params + data_count;
- pSMB->DataCount = cpu_to_le16(data_count);
- pSMB->TotalDataCount = pSMB->DataCount;
- pSMB->ParameterCount = cpu_to_le16(params);
- pSMB->TotalParameterCount = pSMB->ParameterCount;
- pSMB->Reserved4 = 0;
- inc_rfc1001_len(pSMB, byte_count);
- parm_data->FileSize = cpu_to_le64(size);
- pSMB->ByteCount = cpu_to_le16(byte_count);
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc)
- cFYI(1, "SetPathInfo (file size) returned %d", rc);
-
- cifs_buf_release(pSMB);
-
- if (rc == -EAGAIN)
- goto SetEOFRetry;
-
- return rc;
-}
-
-int
-CIFSSMBSetFileSize(const int xid, struct cifs_tcon *tcon, __u64 size,
- __u16 fid, __u32 pid_of_opener, bool SetAllocation)
-{
- struct smb_com_transaction2_sfi_req *pSMB = NULL;
- struct file_end_of_file_info *parm_data;
- int rc = 0;
- __u16 params, param_offset, offset, byte_count, count;
-
- cFYI(1, "SetFileSize (via SetFileInfo) %lld",
- (long long)size);
- rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
-
- if (rc)
- return rc;
-
- pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
- pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
-
- params = 6;
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
- offset = param_offset + params;
-
- count = sizeof(struct file_end_of_file_info);
- pSMB->MaxParameterCount = cpu_to_le16(2);
- /* BB find exact max SMB PDU from sess structure BB */
- pSMB->MaxDataCount = cpu_to_le16(1000);
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
- byte_count = 3 /* pad */ + params + count;
- pSMB->DataCount = cpu_to_le16(count);
- pSMB->ParameterCount = cpu_to_le16(params);
- pSMB->TotalDataCount = pSMB->DataCount;
- pSMB->TotalParameterCount = pSMB->ParameterCount;
- pSMB->ParameterOffset = cpu_to_le16(param_offset);
- parm_data =
- (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol)
- + offset);
- pSMB->DataOffset = cpu_to_le16(offset);
- parm_data->FileSize = cpu_to_le64(size);
- pSMB->Fid = fid;
- if (SetAllocation) {
- if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
- pSMB->InformationLevel =
- cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
- else
- pSMB->InformationLevel =
- cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
- } else /* Set File Size */ {
- if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
- pSMB->InformationLevel =
- cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
- else
- pSMB->InformationLevel =
- cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
- }
- pSMB->Reserved4 = 0;
- inc_rfc1001_len(pSMB, byte_count);
- pSMB->ByteCount = cpu_to_le16(byte_count);
- rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
- if (rc) {
- cFYI(1, "Send error in SetFileInfo (SetFileSize) = %d", rc);
- }
-
- /* Note: On -EAGAIN error only caller can retry on handle based calls
- since file handle passed in no longer valid */
-
- return rc;
-}
-
-/* Some legacy servers such as NT4 require that the file times be set on
- an open handle, rather than by pathname - this is awkward due to
- potential access conflicts on the open, but it is unavoidable for these
- old servers since the only other choice is to go from 100 nanosecond DCE
- time and resort to the original setpathinfo level which takes the ancient
- DOS time format with 2 second granularity */
-int
-CIFSSMBSetFileInfo(const int xid, struct cifs_tcon *tcon,
- const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
-{
- struct smb_com_transaction2_sfi_req *pSMB = NULL;
- char *data_offset;
- int rc = 0;
- __u16 params, param_offset, offset, byte_count, count;
-
- cFYI(1, "Set Times (via SetFileInfo)");
- rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
-
- if (rc)
- return rc;
-
- pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
- pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
-
- params = 6;
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
- offset = param_offset + params;
-
- data_offset = (char *)pSMB +
- offsetof(struct smb_hdr, Protocol) + offset;
-
- count = sizeof(FILE_BASIC_INFO);
- pSMB->MaxParameterCount = cpu_to_le16(2);
- /* BB find max SMB PDU from sess */
- pSMB->MaxDataCount = cpu_to_le16(1000);
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
- byte_count = 3 /* pad */ + params + count;
- pSMB->DataCount = cpu_to_le16(count);
- pSMB->ParameterCount = cpu_to_le16(params);
- pSMB->TotalDataCount = pSMB->DataCount;
- pSMB->TotalParameterCount = pSMB->ParameterCount;
- pSMB->ParameterOffset = cpu_to_le16(param_offset);
- pSMB->DataOffset = cpu_to_le16(offset);
- pSMB->Fid = fid;
- if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
- pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
- else
- pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
- pSMB->Reserved4 = 0;
- inc_rfc1001_len(pSMB, byte_count);
- pSMB->ByteCount = cpu_to_le16(byte_count);
- memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
- rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
- if (rc)
- cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc);
-
- /* Note: On -EAGAIN error only caller can retry on handle based calls
- since file handle passed in no longer valid */
-
- return rc;
-}
-
-int
-CIFSSMBSetFileDisposition(const int xid, struct cifs_tcon *tcon,
- bool delete_file, __u16 fid, __u32 pid_of_opener)
-{
- struct smb_com_transaction2_sfi_req *pSMB = NULL;
- char *data_offset;
- int rc = 0;
- __u16 params, param_offset, offset, byte_count, count;
-
- cFYI(1, "Set File Disposition (via SetFileInfo)");
- rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
-
- if (rc)
- return rc;
-
- pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
- pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
-
- params = 6;
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
- offset = param_offset + params;
-
- data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
-
- count = 1;
- pSMB->MaxParameterCount = cpu_to_le16(2);
- /* BB find max SMB PDU from sess */
- pSMB->MaxDataCount = cpu_to_le16(1000);
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
- byte_count = 3 /* pad */ + params + count;
- pSMB->DataCount = cpu_to_le16(count);
- pSMB->ParameterCount = cpu_to_le16(params);
- pSMB->TotalDataCount = pSMB->DataCount;
- pSMB->TotalParameterCount = pSMB->ParameterCount;
- pSMB->ParameterOffset = cpu_to_le16(param_offset);
- pSMB->DataOffset = cpu_to_le16(offset);
- pSMB->Fid = fid;
- pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
- pSMB->Reserved4 = 0;
- inc_rfc1001_len(pSMB, byte_count);
- pSMB->ByteCount = cpu_to_le16(byte_count);
- *data_offset = delete_file ? 1 : 0;
- rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
- if (rc)
- cFYI(1, "Send error in SetFileDisposition = %d", rc);
-
- return rc;
-}
-
-int
-CIFSSMBSetPathInfo(const int xid, struct cifs_tcon *tcon,
- const char *fileName, const FILE_BASIC_INFO *data,
- const struct nls_table *nls_codepage, int remap)
-{
- TRANSACTION2_SPI_REQ *pSMB = NULL;
- TRANSACTION2_SPI_RSP *pSMBr = NULL;
- int name_len;
- int rc = 0;
- int bytes_returned = 0;
- char *data_offset;
- __u16 params, param_offset, offset, byte_count, count;
-
- cFYI(1, "In SetTimes");
-
-SetTimesRetry:
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len =
- cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
- PATH_MAX, nls_codepage, remap);
- name_len++; /* trailing null */
- name_len *= 2;
- } else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(fileName, PATH_MAX);
- name_len++; /* trailing null */
- strncpy(pSMB->FileName, fileName, name_len);
- }
-
- params = 6 + name_len;
- count = sizeof(FILE_BASIC_INFO);
- pSMB->MaxParameterCount = cpu_to_le16(2);
- /* BB find max SMB PDU from sess structure BB */
- pSMB->MaxDataCount = cpu_to_le16(1000);
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- param_offset = offsetof(struct smb_com_transaction2_spi_req,
- InformationLevel) - 4;
- offset = param_offset + params;
- data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
- pSMB->ParameterOffset = cpu_to_le16(param_offset);
- pSMB->DataOffset = cpu_to_le16(offset);
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
- byte_count = 3 /* pad */ + params + count;
-
- pSMB->DataCount = cpu_to_le16(count);
- pSMB->ParameterCount = cpu_to_le16(params);
- pSMB->TotalDataCount = pSMB->DataCount;
- pSMB->TotalParameterCount = pSMB->ParameterCount;
- if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
- pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
- else
- pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
- pSMB->Reserved4 = 0;
- inc_rfc1001_len(pSMB, byte_count);
- memcpy(data_offset, data, sizeof(FILE_BASIC_INFO));
- pSMB->ByteCount = cpu_to_le16(byte_count);
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc)
- cFYI(1, "SetPathInfo (times) returned %d", rc);
-
- cifs_buf_release(pSMB);
-
- if (rc == -EAGAIN)
- goto SetTimesRetry;
-
- return rc;
-}
-
-/* Can not be used to set time stamps yet (due to old DOS time format) */
-/* Can be used to set attributes */
-#if 0 /* Possibly not needed - since it turns out that strangely NT4 has a bug
- handling it anyway and NT4 was what we thought it would be needed for
- Do not delete it until we prove whether needed for Win9x though */
-int
-CIFSSMBSetAttrLegacy(int xid, struct cifs_tcon *tcon, char *fileName,
- __u16 dos_attrs, const struct nls_table *nls_codepage)
-{
- SETATTR_REQ *pSMB = NULL;
- SETATTR_RSP *pSMBr = NULL;
- int rc = 0;
- int bytes_returned;
- int name_len;
-
- cFYI(1, "In SetAttrLegacy");
-
-SetAttrLgcyRetry:
- rc = smb_init(SMB_COM_SETATTR, 8, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len =
- ConvertToUTF16((__le16 *) pSMB->fileName, fileName,
- PATH_MAX, nls_codepage);
- name_len++; /* trailing null */
- name_len *= 2;
- } else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(fileName, PATH_MAX);
- name_len++; /* trailing null */
- strncpy(pSMB->fileName, fileName, name_len);
- }
- pSMB->attr = cpu_to_le16(dos_attrs);
- pSMB->BufferFormat = 0x04;
- inc_rfc1001_len(pSMB, name_len + 1);
- pSMB->ByteCount = cpu_to_le16(name_len + 1);
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc)
- cFYI(1, "Error in LegacySetAttr = %d", rc);
-
- cifs_buf_release(pSMB);
-
- if (rc == -EAGAIN)
- goto SetAttrLgcyRetry;
-
- return rc;
-}
-#endif /* temporarily unneeded SetAttr legacy function */
-
-static void
-cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
- const struct cifs_unix_set_info_args *args)
-{
- u64 mode = args->mode;
-
- /*
- * Samba server ignores set of file size to zero due to bugs in some
- * older clients, but we should be precise - we use SetFileSize to
- * set file size and do not want to truncate file size to zero
- * accidentally as happened on one Samba server beta by putting
- * zero instead of -1 here
- */
- data_offset->EndOfFile = cpu_to_le64(NO_CHANGE_64);
- data_offset->NumOfBytes = cpu_to_le64(NO_CHANGE_64);
- data_offset->LastStatusChange = cpu_to_le64(args->ctime);
- data_offset->LastAccessTime = cpu_to_le64(args->atime);
- data_offset->LastModificationTime = cpu_to_le64(args->mtime);
- data_offset->Uid = cpu_to_le64(args->uid);
- data_offset->Gid = cpu_to_le64(args->gid);
- /* better to leave device as zero when it is */
- data_offset->DevMajor = cpu_to_le64(MAJOR(args->device));
- data_offset->DevMinor = cpu_to_le64(MINOR(args->device));
- data_offset->Permissions = cpu_to_le64(mode);
-
- if (S_ISREG(mode))
- data_offset->Type = cpu_to_le32(UNIX_FILE);
- else if (S_ISDIR(mode))
- data_offset->Type = cpu_to_le32(UNIX_DIR);
- else if (S_ISLNK(mode))
- data_offset->Type = cpu_to_le32(UNIX_SYMLINK);
- else if (S_ISCHR(mode))
- data_offset->Type = cpu_to_le32(UNIX_CHARDEV);
- else if (S_ISBLK(mode))
- data_offset->Type = cpu_to_le32(UNIX_BLOCKDEV);
- else if (S_ISFIFO(mode))
- data_offset->Type = cpu_to_le32(UNIX_FIFO);
- else if (S_ISSOCK(mode))
- data_offset->Type = cpu_to_le32(UNIX_SOCKET);
-}
-
-int
-CIFSSMBUnixSetFileInfo(const int xid, struct cifs_tcon *tcon,
- const struct cifs_unix_set_info_args *args,
- u16 fid, u32 pid_of_opener)
-{
- struct smb_com_transaction2_sfi_req *pSMB = NULL;
- char *data_offset;
- int rc = 0;
- u16 params, param_offset, offset, byte_count, count;
-
- cFYI(1, "Set Unix Info (via SetFileInfo)");
- rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
-
- if (rc)
- return rc;
-
- pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
- pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));
-
- params = 6;
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
- offset = param_offset + params;
-
- data_offset = (char *)pSMB +
- offsetof(struct smb_hdr, Protocol) + offset;
-
- count = sizeof(FILE_UNIX_BASIC_INFO);
-
- pSMB->MaxParameterCount = cpu_to_le16(2);
- /* BB find max SMB PDU from sess */
- pSMB->MaxDataCount = cpu_to_le16(1000);
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
- byte_count = 3 /* pad */ + params + count;
- pSMB->DataCount = cpu_to_le16(count);
- pSMB->ParameterCount = cpu_to_le16(params);
- pSMB->TotalDataCount = pSMB->DataCount;
- pSMB->TotalParameterCount = pSMB->ParameterCount;
- pSMB->ParameterOffset = cpu_to_le16(param_offset);
- pSMB->DataOffset = cpu_to_le16(offset);
- pSMB->Fid = fid;
- pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
- pSMB->Reserved4 = 0;
- inc_rfc1001_len(pSMB, byte_count);
- pSMB->ByteCount = cpu_to_le16(byte_count);
-
- cifs_fill_unix_set_info((FILE_UNIX_BASIC_INFO *)data_offset, args);
-
- rc = SendReceiveNoRsp(xid, tcon->ses, (char *) pSMB, 0);
- if (rc)
- cFYI(1, "Send error in Set Time (SetFileInfo) = %d", rc);
-
- /* Note: On -EAGAIN error only caller can retry on handle based calls
- since file handle passed in no longer valid */
-
- return rc;
-}
-
-int
-CIFSSMBUnixSetPathInfo(const int xid, struct cifs_tcon *tcon, char *fileName,
- const struct cifs_unix_set_info_args *args,
- const struct nls_table *nls_codepage, int remap)
-{
- TRANSACTION2_SPI_REQ *pSMB = NULL;
- TRANSACTION2_SPI_RSP *pSMBr = NULL;
- int name_len;
- int rc = 0;
- int bytes_returned = 0;
- FILE_UNIX_BASIC_INFO *data_offset;
- __u16 params, param_offset, offset, count, byte_count;
-
- cFYI(1, "In SetUID/GID/Mode");
-setPermsRetry:
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len =
- cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
- PATH_MAX, nls_codepage, remap);
- name_len++; /* trailing null */
- name_len *= 2;
- } else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(fileName, PATH_MAX);
- name_len++; /* trailing null */
- strncpy(pSMB->FileName, fileName, name_len);
- }
-
- params = 6 + name_len;
- count = sizeof(FILE_UNIX_BASIC_INFO);
- pSMB->MaxParameterCount = cpu_to_le16(2);
- /* BB find max SMB PDU from sess structure BB */
- pSMB->MaxDataCount = cpu_to_le16(1000);
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- param_offset = offsetof(struct smb_com_transaction2_spi_req,
- InformationLevel) - 4;
- offset = param_offset + params;
- data_offset =
- (FILE_UNIX_BASIC_INFO *) ((char *) &pSMB->hdr.Protocol +
- offset);
- memset(data_offset, 0, count);
- pSMB->DataOffset = cpu_to_le16(offset);
- pSMB->ParameterOffset = cpu_to_le16(param_offset);
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
- byte_count = 3 /* pad */ + params + count;
- pSMB->ParameterCount = cpu_to_le16(params);
- pSMB->DataCount = cpu_to_le16(count);
- pSMB->TotalParameterCount = pSMB->ParameterCount;
- pSMB->TotalDataCount = pSMB->DataCount;
- pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
- pSMB->Reserved4 = 0;
- inc_rfc1001_len(pSMB, byte_count);
-
- cifs_fill_unix_set_info(data_offset, args);
-
- pSMB->ByteCount = cpu_to_le16(byte_count);
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc)
- cFYI(1, "SetPathInfo (perms) returned %d", rc);
-
- cifs_buf_release(pSMB);
- if (rc == -EAGAIN)
- goto setPermsRetry;
- return rc;
-}
-
-#ifdef CONFIG_CIFS_XATTR
-/*
- * Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
- * function used by listxattr and getxattr type calls. When ea_name is set,
- * it looks for that attribute name and stuffs that value into the EAData
- * buffer. When ea_name is NULL, it stuffs a list of attribute names into the
- * buffer. In both cases, the return value is either the length of the
- * resulting data or a negative error code. If EAData is a NULL pointer then
- * the data isn't copied to it, but the length is returned.
- */
-ssize_t
-CIFSSMBQAllEAs(const int xid, struct cifs_tcon *tcon,
- const unsigned char *searchName, const unsigned char *ea_name,
- char *EAData, size_t buf_size,
- const struct nls_table *nls_codepage, int remap)
-{
- /* BB assumes one setup word */
- TRANSACTION2_QPI_REQ *pSMB = NULL;
- TRANSACTION2_QPI_RSP *pSMBr = NULL;
- int rc = 0;
- int bytes_returned;
- int list_len;
- struct fealist *ea_response_data;
- struct fea *temp_fea;
- char *temp_ptr;
- char *end_of_smb;
- __u16 params, byte_count, data_offset;
- unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
-
- cFYI(1, "In Query All EAs path %s", searchName);
-QAllEAsRetry:
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- list_len =
- cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
- PATH_MAX, nls_codepage, remap);
- list_len++; /* trailing null */
- list_len *= 2;
- } else { /* BB improve the check for buffer overruns BB */
- list_len = strnlen(searchName, PATH_MAX);
- list_len++; /* trailing null */
- strncpy(pSMB->FileName, searchName, list_len);
- }
-
- params = 2 /* level */ + 4 /* reserved */ + list_len /* includes NUL */;
- pSMB->TotalDataCount = 0;
- pSMB->MaxParameterCount = cpu_to_le16(2);
- /* BB find exact max SMB PDU from sess structure BB */
- pSMB->MaxDataCount = cpu_to_le16(CIFSMaxBufSize);
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- pSMB->ParameterOffset = cpu_to_le16(offsetof(
- struct smb_com_transaction2_qpi_req, InformationLevel) - 4);
- pSMB->DataCount = 0;
- pSMB->DataOffset = 0;
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
- byte_count = params + 1 /* pad */ ;
- pSMB->TotalParameterCount = cpu_to_le16(params);
- pSMB->ParameterCount = pSMB->TotalParameterCount;
- pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
- pSMB->Reserved4 = 0;
- inc_rfc1001_len(pSMB, byte_count);
- pSMB->ByteCount = cpu_to_le16(byte_count);
-
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc) {
- cFYI(1, "Send error in QueryAllEAs = %d", rc);
- goto QAllEAsOut;
- }
-
-
- /* BB also check enough total bytes returned */
- /* BB we need to improve the validity checking
- of these trans2 responses */
-
- rc = validate_t2((struct smb_t2_rsp *)pSMBr);
- if (rc || get_bcc(&pSMBr->hdr) < 4) {
- rc = -EIO; /* bad smb */
- goto QAllEAsOut;
- }
-
- /* check that length of list is not more than bcc */
- /* check that each entry does not go beyond length
- of list */
- /* check that each element of each entry does not
- go beyond end of list */
- /* validate_trans2_offsets() */
- /* BB check if start of smb + data_offset > &bcc+ bcc */
-
- data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
- ea_response_data = (struct fealist *)
- (((char *) &pSMBr->hdr.Protocol) + data_offset);
-
- list_len = le32_to_cpu(ea_response_data->list_len);
- cFYI(1, "ea length %d", list_len);
- if (list_len <= 8) {
- cFYI(1, "empty EA list returned from server");
- goto QAllEAsOut;
- }
-
- /* make sure list_len doesn't go past end of SMB */
- end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
- if ((char *)ea_response_data + list_len > end_of_smb) {
- cFYI(1, "EA list appears to go beyond SMB");
- rc = -EIO;
- goto QAllEAsOut;
- }
-
- /* account for ea list len */
- list_len -= 4;
- temp_fea = ea_response_data->list;
- temp_ptr = (char *)temp_fea;
- while (list_len > 0) {
- unsigned int name_len;
- __u16 value_len;
-
- list_len -= 4;
- temp_ptr += 4;
- /* make sure we can read name_len and value_len */
- if (list_len < 0) {
- cFYI(1, "EA entry goes beyond length of list");
- rc = -EIO;
- goto QAllEAsOut;
- }
-
- name_len = temp_fea->name_len;
- value_len = le16_to_cpu(temp_fea->value_len);
- list_len -= name_len + 1 + value_len;
- if (list_len < 0) {
- cFYI(1, "EA entry goes beyond length of list");
- rc = -EIO;
- goto QAllEAsOut;
- }
-
- if (ea_name) {
- if (ea_name_len == name_len &&
- memcmp(ea_name, temp_ptr, name_len) == 0) {
- temp_ptr += name_len + 1;
- rc = value_len;
- if (buf_size == 0)
- goto QAllEAsOut;
- if ((size_t)value_len > buf_size) {
- rc = -ERANGE;
- goto QAllEAsOut;
- }
- memcpy(EAData, temp_ptr, value_len);
- goto QAllEAsOut;
- }
- } else {
- /* account for prefix user. and trailing null */
- rc += (5 + 1 + name_len);
- if (rc < (int) buf_size) {
- memcpy(EAData, "user.", 5);
- EAData += 5;
- memcpy(EAData, temp_ptr, name_len);
- EAData += name_len;
- /* null terminate name */
- *EAData = 0;
- ++EAData;
- } else if (buf_size == 0) {
- /* skip copy - calc size only */
- } else {
- /* stop before overrun buffer */
- rc = -ERANGE;
- break;
- }
- }
- temp_ptr += name_len + 1 + value_len;
- temp_fea = (struct fea *)temp_ptr;
- }
-
- /* didn't find the named attribute */
- if (ea_name)
- rc = -ENODATA;
-
-QAllEAsOut:
- cifs_buf_release(pSMB);
- if (rc == -EAGAIN)
- goto QAllEAsRetry;
-
- return (ssize_t)rc;
-}
-
-int
-CIFSSMBSetEA(const int xid, struct cifs_tcon *tcon, const char *fileName,
- const char *ea_name, const void *ea_value,
- const __u16 ea_value_len, const struct nls_table *nls_codepage,
- int remap)
-{
- struct smb_com_transaction2_spi_req *pSMB = NULL;
- struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
- struct fealist *parm_data;
- int name_len;
- int rc = 0;
- int bytes_returned = 0;
- __u16 params, param_offset, byte_count, offset, count;
-
- cFYI(1, "In SetEA");
-SetEARetry:
- rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
- name_len =
- cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName,
- PATH_MAX, nls_codepage, remap);
- name_len++; /* trailing null */
- name_len *= 2;
- } else { /* BB improve the check for buffer overruns BB */
- name_len = strnlen(fileName, PATH_MAX);
- name_len++; /* trailing null */
- strncpy(pSMB->FileName, fileName, name_len);
- }
-
- params = 6 + name_len;
-
- /* done calculating parms using name_len of file name,
- now use name_len to calculate length of ea name
- we are going to create in the inode xattrs */
- if (ea_name == NULL)
- name_len = 0;
- else
- name_len = strnlen(ea_name, 255);
-
- count = sizeof(*parm_data) + ea_value_len + name_len;
- pSMB->MaxParameterCount = cpu_to_le16(2);
- /* BB find max SMB PDU from sess */
- pSMB->MaxDataCount = cpu_to_le16(1000);
- pSMB->MaxSetupCount = 0;
- pSMB->Reserved = 0;
- pSMB->Flags = 0;
- pSMB->Timeout = 0;
- pSMB->Reserved2 = 0;
- param_offset = offsetof(struct smb_com_transaction2_spi_req,
- InformationLevel) - 4;
- offset = param_offset + params;
- pSMB->InformationLevel =
- cpu_to_le16(SMB_SET_FILE_EA);
-
- parm_data =
- (struct fealist *) (((char *) &pSMB->hdr.Protocol) +
- offset);
- pSMB->ParameterOffset = cpu_to_le16(param_offset);
- pSMB->DataOffset = cpu_to_le16(offset);
- pSMB->SetupCount = 1;
- pSMB->Reserved3 = 0;
- pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
- byte_count = 3 /* pad */ + params + count;
- pSMB->DataCount = cpu_to_le16(count);
- parm_data->list_len = cpu_to_le32(count);
- parm_data->list[0].EA_flags = 0;
- /* we checked above that name len is less than 255 */
- parm_data->list[0].name_len = (__u8)name_len;
- /* EA names are always ASCII */
- if (ea_name)
- strncpy(parm_data->list[0].name, ea_name, name_len);
- parm_data->list[0].name[name_len] = 0;
- parm_data->list[0].value_len = cpu_to_le16(ea_value_len);
- /* caller ensures that ea_value_len is less than 64K but
- we need to ensure that it fits within the smb */
-
- /*BB add length check to see if it would fit in
- negotiated SMB buffer size BB */
- /* if (ea_value_len > buffer_size - 512 (enough for header)) */
- if (ea_value_len)
- memcpy(parm_data->list[0].name+name_len+1,
- ea_value, ea_value_len);
-
- pSMB->TotalDataCount = pSMB->DataCount;
- pSMB->ParameterCount = cpu_to_le16(params);
- pSMB->TotalParameterCount = pSMB->ParameterCount;
- pSMB->Reserved4 = 0;
- inc_rfc1001_len(pSMB, byte_count);
- pSMB->ByteCount = cpu_to_le16(byte_count);
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *) pSMBr, &bytes_returned, 0);
- if (rc)
- cFYI(1, "SetPathInfo (EA) returned %d", rc);
-
- cifs_buf_release(pSMB);
-
- if (rc == -EAGAIN)
- goto SetEARetry;
-
- return rc;
-}
-#endif
-
-#ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
-/*
- * Years ago the kernel added a "dnotify" function for Samba server,
- * to allow network clients (such as Windows) to display updated
- * lists of files in directory listings automatically when
- * files are added by one user when another user has the
- * same directory open on their desktop. The Linux cifs kernel
- * client hooked into the kernel side of this interface for
- * the same reason, but ironically when the VFS moved from
- * "dnotify" to "inotify" it became harder to plug in Linux
- * network file system clients (the most obvious use case
- * for notify interfaces is when multiple users can update
- * the contents of the same directory - exactly what network
- * file systems can do) although the server (Samba) could
- * still use it. For the short term we leave the worker
- * function ifdeffed out (below) until inotify is fixed
- * in the VFS to make it easier to plug in network file
- * system clients. If inotify turns out to be permanently
- * incompatible for network fs clients, we could instead simply
- * expose this config flag by adding a future cifs (and smb2) notify ioctl.
- */
-int CIFSSMBNotify(const int xid, struct cifs_tcon *tcon,
- const int notify_subdirs, const __u16 netfid,
- __u32 filter, struct file *pfile, int multishot,
- const struct nls_table *nls_codepage)
-{
- int rc = 0;
- struct smb_com_transaction_change_notify_req *pSMB = NULL;
- struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
- struct dir_notify_req *dnotify_req;
- int bytes_returned;
-
- cFYI(1, "In CIFSSMBNotify for file handle %d", (int)netfid);
- rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- pSMB->TotalParameterCount = 0 ;
- pSMB->TotalDataCount = 0;
- pSMB->MaxParameterCount = cpu_to_le32(2);
- pSMB->MaxDataCount = cpu_to_le32(CIFSMaxBufSize & 0xFFFFFF00);
- pSMB->MaxSetupCount = 4;
- pSMB->Reserved = 0;
- pSMB->ParameterOffset = 0;
- pSMB->DataCount = 0;
- pSMB->DataOffset = 0;
- pSMB->SetupCount = 4; /* single byte does not need le conversion */
- pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
- pSMB->ParameterCount = pSMB->TotalParameterCount;
- if (notify_subdirs)
- pSMB->WatchTree = 1; /* one byte - no le conversion needed */
- pSMB->Reserved2 = 0;
- pSMB->CompletionFilter = cpu_to_le32(filter);
- pSMB->Fid = netfid; /* file handle always le */
- pSMB->ByteCount = 0;
-
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *)pSMBr, &bytes_returned,
- CIFS_ASYNC_OP);
- if (rc) {
- cFYI(1, "Error in Notify = %d", rc);
- } else {
- /* Add file to outstanding requests */
- /* BB change to kmem cache alloc */
- dnotify_req = kmalloc(
- sizeof(struct dir_notify_req),
- GFP_KERNEL);
- if (dnotify_req) {
- dnotify_req->Pid = pSMB->hdr.Pid;
- dnotify_req->PidHigh = pSMB->hdr.PidHigh;
- dnotify_req->Mid = pSMB->hdr.Mid;
- dnotify_req->Tid = pSMB->hdr.Tid;
- dnotify_req->Uid = pSMB->hdr.Uid;
- dnotify_req->netfid = netfid;
- dnotify_req->pfile = pfile;
- dnotify_req->filter = filter;
- dnotify_req->multishot = multishot;
- spin_lock(&GlobalMid_Lock);
- list_add_tail(&dnotify_req->lhead,
- &GlobalDnotifyReqList);
- spin_unlock(&GlobalMid_Lock);
- } else
- rc = -ENOMEM;
- }
- cifs_buf_release(pSMB);
- return rc;
-}
-#endif /* was needed for dnotify, and will be needed for inotify when VFS fix */
diff --git a/ANDROID_3.4.5/fs/cifs/connect.c b/ANDROID_3.4.5/fs/cifs/connect.c
deleted file mode 100644
index 402fa0f9..00000000
--- a/ANDROID_3.4.5/fs/cifs/connect.c
+++ /dev/null
@@ -1,4348 +0,0 @@
-/*
- * fs/cifs/connect.c
- *
- * Copyright (C) International Business Machines Corp., 2002,2009
- * Author(s): Steve French (sfrench@us.ibm.com)
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <linux/fs.h>
-#include <linux/net.h>
-#include <linux/string.h>
-#include <linux/list.h>
-#include <linux/wait.h>
-#include <linux/slab.h>
-#include <linux/pagemap.h>
-#include <linux/ctype.h>
-#include <linux/utsname.h>
-#include <linux/mempool.h>
-#include <linux/delay.h>
-#include <linux/completion.h>
-#include <linux/kthread.h>
-#include <linux/pagevec.h>
-#include <linux/freezer.h>
-#include <linux/namei.h>
-#include <asm/uaccess.h>
-#include <asm/processor.h>
-#include <linux/inet.h>
-#include <linux/module.h>
-#include <keys/user-type.h>
-#include <net/ipv6.h>
-#include <linux/parser.h>
-
-#include "cifspdu.h"
-#include "cifsglob.h"
-#include "cifsproto.h"
-#include "cifs_unicode.h"
-#include "cifs_debug.h"
-#include "cifs_fs_sb.h"
-#include "ntlmssp.h"
-#include "nterr.h"
-#include "rfc1002pdu.h"
-#include "fscache.h"
-
-#define CIFS_PORT 445
-#define RFC1001_PORT 139
-
-/* SMB echo "timeout" -- FIXME: tunable? */
-#define SMB_ECHO_INTERVAL (60 * HZ)
-
-extern mempool_t *cifs_req_poolp;
-
-/* FIXME: should these be tunable? */
-#define TLINK_ERROR_EXPIRE (1 * HZ)
-#define TLINK_IDLE_EXPIRE (600 * HZ)
-
-enum {
-
- /* Mount options that take no arguments */
- Opt_user_xattr, Opt_nouser_xattr,
- Opt_forceuid, Opt_noforceuid,
- Opt_noblocksend, Opt_noautotune,
- Opt_hard, Opt_soft, Opt_perm, Opt_noperm,
- Opt_mapchars, Opt_nomapchars, Opt_sfu,
- Opt_nosfu, Opt_nodfs, Opt_posixpaths,
- Opt_noposixpaths, Opt_nounix,
- Opt_nocase,
- Opt_brl, Opt_nobrl,
- Opt_forcemandatorylock, Opt_setuids,
- Opt_nosetuids, Opt_dynperm, Opt_nodynperm,
- Opt_nohard, Opt_nosoft,
- Opt_nointr, Opt_intr,
- Opt_nostrictsync, Opt_strictsync,
- Opt_serverino, Opt_noserverino,
- Opt_rwpidforward, Opt_cifsacl, Opt_nocifsacl,
- Opt_acl, Opt_noacl, Opt_locallease,
- Opt_sign, Opt_seal, Opt_direct,
- Opt_strictcache, Opt_noac,
- Opt_fsc, Opt_mfsymlinks,
- Opt_multiuser, Opt_sloppy,
-
- /* Mount options which take numeric value */
- Opt_backupuid, Opt_backupgid, Opt_uid,
- Opt_cruid, Opt_gid, Opt_file_mode,
- Opt_dirmode, Opt_port,
- Opt_rsize, Opt_wsize, Opt_actimeo,
-
- /* Mount options which take string value */
- Opt_user, Opt_pass, Opt_ip,
- Opt_unc, Opt_domain,
- Opt_srcaddr, Opt_prefixpath,
- Opt_iocharset, Opt_sockopt,
- Opt_netbiosname, Opt_servern,
- Opt_ver, Opt_sec,
-
- /* Mount options to be ignored */
- Opt_ignore,
-
- /* Options which could be blank */
- Opt_blank_pass,
- Opt_blank_user,
- Opt_blank_ip,
-
- Opt_err
-};
-
-static const match_table_t cifs_mount_option_tokens = {
-
- { Opt_user_xattr, "user_xattr" },
- { Opt_nouser_xattr, "nouser_xattr" },
- { Opt_forceuid, "forceuid" },
- { Opt_noforceuid, "noforceuid" },
- { Opt_noblocksend, "noblocksend" },
- { Opt_noautotune, "noautotune" },
- { Opt_hard, "hard" },
- { Opt_soft, "soft" },
- { Opt_perm, "perm" },
- { Opt_noperm, "noperm" },
- { Opt_mapchars, "mapchars" },
- { Opt_nomapchars, "nomapchars" },
- { Opt_sfu, "sfu" },
- { Opt_nosfu, "nosfu" },
- { Opt_nodfs, "nodfs" },
- { Opt_posixpaths, "posixpaths" },
- { Opt_noposixpaths, "noposixpaths" },
- { Opt_nounix, "nounix" },
- { Opt_nounix, "nolinux" },
- { Opt_nocase, "nocase" },
- { Opt_nocase, "ignorecase" },
- { Opt_brl, "brl" },
- { Opt_nobrl, "nobrl" },
- { Opt_nobrl, "nolock" },
- { Opt_forcemandatorylock, "forcemandatorylock" },
- { Opt_forcemandatorylock, "forcemand" },
- { Opt_setuids, "setuids" },
- { Opt_nosetuids, "nosetuids" },
- { Opt_dynperm, "dynperm" },
- { Opt_nodynperm, "nodynperm" },
- { Opt_nohard, "nohard" },
- { Opt_nosoft, "nosoft" },
- { Opt_nointr, "nointr" },
- { Opt_intr, "intr" },
- { Opt_nostrictsync, "nostrictsync" },
- { Opt_strictsync, "strictsync" },
- { Opt_serverino, "serverino" },
- { Opt_noserverino, "noserverino" },
- { Opt_rwpidforward, "rwpidforward" },
- { Opt_cifsacl, "cifsacl" },
- { Opt_nocifsacl, "nocifsacl" },
- { Opt_acl, "acl" },
- { Opt_noacl, "noacl" },
- { Opt_locallease, "locallease" },
- { Opt_sign, "sign" },
- { Opt_seal, "seal" },
- { Opt_direct, "direct" },
- { Opt_direct, "directio" },
- { Opt_direct, "forcedirectio" },
- { Opt_strictcache, "strictcache" },
- { Opt_noac, "noac" },
- { Opt_fsc, "fsc" },
- { Opt_mfsymlinks, "mfsymlinks" },
- { Opt_multiuser, "multiuser" },
- { Opt_sloppy, "sloppy" },
-
- { Opt_backupuid, "backupuid=%s" },
- { Opt_backupgid, "backupgid=%s" },
- { Opt_uid, "uid=%s" },
- { Opt_cruid, "cruid=%s" },
- { Opt_gid, "gid=%s" },
- { Opt_file_mode, "file_mode=%s" },
- { Opt_dirmode, "dirmode=%s" },
- { Opt_dirmode, "dir_mode=%s" },
- { Opt_port, "port=%s" },
- { Opt_rsize, "rsize=%s" },
- { Opt_wsize, "wsize=%s" },
- { Opt_actimeo, "actimeo=%s" },
-
- { Opt_blank_user, "user=" },
- { Opt_blank_user, "username=" },
- { Opt_user, "user=%s" },
- { Opt_user, "username=%s" },
- { Opt_blank_pass, "pass=" },
- { Opt_pass, "pass=%s" },
- { Opt_pass, "password=%s" },
- { Opt_blank_ip, "ip=" },
- { Opt_blank_ip, "addr=" },
- { Opt_ip, "ip=%s" },
- { Opt_ip, "addr=%s" },
- { Opt_unc, "unc=%s" },
- { Opt_unc, "target=%s" },
- { Opt_unc, "path=%s" },
- { Opt_domain, "dom=%s" },
- { Opt_domain, "domain=%s" },
- { Opt_domain, "workgroup=%s" },
- { Opt_srcaddr, "srcaddr=%s" },
- { Opt_prefixpath, "prefixpath=%s" },
- { Opt_iocharset, "iocharset=%s" },
- { Opt_sockopt, "sockopt=%s" },
- { Opt_netbiosname, "netbiosname=%s" },
- { Opt_servern, "servern=%s" },
- { Opt_ver, "ver=%s" },
- { Opt_ver, "vers=%s" },
- { Opt_ver, "version=%s" },
- { Opt_sec, "sec=%s" },
-
- { Opt_ignore, "cred" },
- { Opt_ignore, "credentials" },
- { Opt_ignore, "cred=%s" },
- { Opt_ignore, "credentials=%s" },
- { Opt_ignore, "guest" },
- { Opt_ignore, "rw" },
- { Opt_ignore, "ro" },
- { Opt_ignore, "suid" },
- { Opt_ignore, "nosuid" },
- { Opt_ignore, "exec" },
- { Opt_ignore, "noexec" },
- { Opt_ignore, "nodev" },
- { Opt_ignore, "noauto" },
- { Opt_ignore, "dev" },
- { Opt_ignore, "mand" },
- { Opt_ignore, "nomand" },
- { Opt_ignore, "_netdev" },
-
- { Opt_err, NULL }
-};
-
-enum {
- Opt_sec_krb5, Opt_sec_krb5i, Opt_sec_krb5p,
- Opt_sec_ntlmsspi, Opt_sec_ntlmssp,
- Opt_ntlm, Opt_sec_ntlmi, Opt_sec_ntlmv2i,
- Opt_sec_nontlm, Opt_sec_lanman,
- Opt_sec_none,
-
- Opt_sec_err
-};
-
-static const match_table_t cifs_secflavor_tokens = {
- { Opt_sec_krb5, "krb5" },
- { Opt_sec_krb5i, "krb5i" },
- { Opt_sec_krb5p, "krb5p" },
- { Opt_sec_ntlmsspi, "ntlmsspi" },
- { Opt_sec_ntlmssp, "ntlmssp" },
- { Opt_ntlm, "ntlm" },
- { Opt_sec_ntlmi, "ntlmi" },
- { Opt_sec_ntlmv2i, "ntlmv2i" },
- { Opt_sec_nontlm, "nontlm" },
- { Opt_sec_lanman, "lanman" },
- { Opt_sec_none, "none" },
-
- { Opt_sec_err, NULL }
-};
-
-static int ip_connect(struct TCP_Server_Info *server);
-static int generic_ip_connect(struct TCP_Server_Info *server);
-static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink);
-static void cifs_prune_tlinks(struct work_struct *work);
-static int cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data,
- const char *devname);
-
-/*
- * cifs tcp session reconnection
- *
- * mark tcp session as reconnecting so temporarily locked
- * mark all smb sessions as reconnecting for tcp session
- * reconnect tcp session
- * wake up waiters on reconnection? - (not needed currently)
- */
-static int
-cifs_reconnect(struct TCP_Server_Info *server)
-{
- int rc = 0;
- struct list_head *tmp, *tmp2;
- struct cifs_ses *ses;
- struct cifs_tcon *tcon;
- struct mid_q_entry *mid_entry;
- struct list_head retry_list;
-
- spin_lock(&GlobalMid_Lock);
- if (server->tcpStatus == CifsExiting) {
- /* the demux thread will exit normally
- next time through the loop */
- spin_unlock(&GlobalMid_Lock);
- return rc;
- } else
- server->tcpStatus = CifsNeedReconnect;
- spin_unlock(&GlobalMid_Lock);
- server->maxBuf = 0;
-
- cFYI(1, "Reconnecting tcp session");
-
- /* before reconnecting the tcp session, mark the smb session (uid)
- and the tid bad so they are not used until reconnected */
- cFYI(1, "%s: marking sessions and tcons for reconnect", __func__);
- spin_lock(&cifs_tcp_ses_lock);
- list_for_each(tmp, &server->smb_ses_list) {
- ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
- ses->need_reconnect = true;
- ses->ipc_tid = 0;
- list_for_each(tmp2, &ses->tcon_list) {
- tcon = list_entry(tmp2, struct cifs_tcon, tcon_list);
- tcon->need_reconnect = true;
- }
- }
- spin_unlock(&cifs_tcp_ses_lock);
-
- /* do not want to be sending data on a socket we are freeing */
- cFYI(1, "%s: tearing down socket", __func__);
- mutex_lock(&server->srv_mutex);
- if (server->ssocket) {
- cFYI(1, "State: 0x%x Flags: 0x%lx", server->ssocket->state,
- server->ssocket->flags);
- kernel_sock_shutdown(server->ssocket, SHUT_WR);
- cFYI(1, "Post shutdown state: 0x%x Flags: 0x%lx",
- server->ssocket->state,
- server->ssocket->flags);
- sock_release(server->ssocket);
- server->ssocket = NULL;
- }
- server->sequence_number = 0;
- server->session_estab = false;
- kfree(server->session_key.response);
- server->session_key.response = NULL;
- server->session_key.len = 0;
- server->lstrp = jiffies;
- mutex_unlock(&server->srv_mutex);
-
- /* mark submitted MIDs for retry and issue callback */
- INIT_LIST_HEAD(&retry_list);
- cFYI(1, "%s: moving mids to private list", __func__);
- spin_lock(&GlobalMid_Lock);
- list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {
- mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
- if (mid_entry->mid_state == MID_REQUEST_SUBMITTED)
- mid_entry->mid_state = MID_RETRY_NEEDED;
- list_move(&mid_entry->qhead, &retry_list);
- }
- spin_unlock(&GlobalMid_Lock);
-
- cFYI(1, "%s: issuing mid callbacks", __func__);
- list_for_each_safe(tmp, tmp2, &retry_list) {
- mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
- list_del_init(&mid_entry->qhead);
- mid_entry->callback(mid_entry);
- }
-
- do {
- try_to_freeze();
-
- /* we should try only the port we connected to before */
- rc = generic_ip_connect(server);
- if (rc) {
- cFYI(1, "reconnect error %d", rc);
- msleep(3000);
- } else {
- atomic_inc(&tcpSesReconnectCount);
- spin_lock(&GlobalMid_Lock);
- if (server->tcpStatus != CifsExiting)
- server->tcpStatus = CifsNeedNegotiate;
- spin_unlock(&GlobalMid_Lock);
- }
- } while (server->tcpStatus == CifsNeedReconnect);
-
- return rc;
-}
-
-/*
- return codes:
- 0 not a transact2, or all data present
- >0 transact2 with that much data missing
- -EINVAL = invalid transact2
-
- */
-static int check2ndT2(char *buf)
-{
- struct smb_hdr *pSMB = (struct smb_hdr *)buf;
- struct smb_t2_rsp *pSMBt;
- int remaining;
- __u16 total_data_size, data_in_this_rsp;
-
- if (pSMB->Command != SMB_COM_TRANSACTION2)
- return 0;
-
- /* check for plausible wct, bcc and t2 data and parm sizes */
- /* check for parm and data offset going beyond end of smb */
- if (pSMB->WordCount != 10) { /* coalesce_t2 depends on this */
- cFYI(1, "invalid transact2 word count");
- return -EINVAL;
- }
-
- pSMBt = (struct smb_t2_rsp *)pSMB;
-
- total_data_size = get_unaligned_le16(&pSMBt->t2_rsp.TotalDataCount);
- data_in_this_rsp = get_unaligned_le16(&pSMBt->t2_rsp.DataCount);
-
- if (total_data_size == data_in_this_rsp)
- return 0;
- else if (total_data_size < data_in_this_rsp) {
- cFYI(1, "total data %d smaller than data in frame %d",
- total_data_size, data_in_this_rsp);
- return -EINVAL;
- }
-
- remaining = total_data_size - data_in_this_rsp;
-
- cFYI(1, "missing %d bytes from transact2, check next response",
- remaining);
- if (total_data_size > CIFSMaxBufSize) {
- cERROR(1, "TotalDataSize %d is over maximum buffer %d",
- total_data_size, CIFSMaxBufSize);
- return -EINVAL;
- }
- return remaining;
-}
-
-static int coalesce_t2(char *second_buf, struct smb_hdr *target_hdr)
-{
- struct smb_t2_rsp *pSMBs = (struct smb_t2_rsp *)second_buf;
- struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)target_hdr;
- char *data_area_of_tgt;
- char *data_area_of_src;
- int remaining;
- unsigned int byte_count, total_in_tgt;
- __u16 tgt_total_cnt, src_total_cnt, total_in_src;
-
- src_total_cnt = get_unaligned_le16(&pSMBs->t2_rsp.TotalDataCount);
- tgt_total_cnt = get_unaligned_le16(&pSMBt->t2_rsp.TotalDataCount);
-
- if (tgt_total_cnt != src_total_cnt)
- cFYI(1, "total data count of primary and secondary t2 differ "
- "source=%hu target=%hu", src_total_cnt, tgt_total_cnt);
-
- total_in_tgt = get_unaligned_le16(&pSMBt->t2_rsp.DataCount);
-
- remaining = tgt_total_cnt - total_in_tgt;
-
- if (remaining < 0) {
- cFYI(1, "Server sent too much data. tgt_total_cnt=%hu "
- "total_in_tgt=%hu", tgt_total_cnt, total_in_tgt);
- return -EPROTO;
- }
-
- if (remaining == 0) {
- /* nothing to do, ignore */
- cFYI(1, "no more data remains");
- return 0;
- }
-
- total_in_src = get_unaligned_le16(&pSMBs->t2_rsp.DataCount);
- if (remaining < total_in_src)
- cFYI(1, "transact2 2nd response contains too much data");
-
- /* find end of first SMB data area */
- data_area_of_tgt = (char *)&pSMBt->hdr.Protocol +
- get_unaligned_le16(&pSMBt->t2_rsp.DataOffset);
-
- /* validate target area */
- data_area_of_src = (char *)&pSMBs->hdr.Protocol +
- get_unaligned_le16(&pSMBs->t2_rsp.DataOffset);
-
- data_area_of_tgt += total_in_tgt;
-
- total_in_tgt += total_in_src;
- /* is the result too big for the field? */
- if (total_in_tgt > USHRT_MAX) {
- cFYI(1, "coalesced DataCount too large (%u)", total_in_tgt);
- return -EPROTO;
- }
- put_unaligned_le16(total_in_tgt, &pSMBt->t2_rsp.DataCount);
-
- /* fix up the BCC */
- byte_count = get_bcc(target_hdr);
- byte_count += total_in_src;
- /* is the result too big for the field? */
- if (byte_count > USHRT_MAX) {
- cFYI(1, "coalesced BCC too large (%u)", byte_count);
- return -EPROTO;
- }
- put_bcc(byte_count, target_hdr);
-
- byte_count = be32_to_cpu(target_hdr->smb_buf_length);
- byte_count += total_in_src;
- /* don't allow buffer to overflow */
- if (byte_count > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
- cFYI(1, "coalesced BCC exceeds buffer size (%u)", byte_count);
- return -ENOBUFS;
- }
- target_hdr->smb_buf_length = cpu_to_be32(byte_count);
-
- /* copy second buffer into end of first buffer */
- memcpy(data_area_of_tgt, data_area_of_src, total_in_src);
-
- if (remaining != total_in_src) {
- /* more responses to go */
- cFYI(1, "waiting for more secondary responses");
- return 1;
- }
-
- /* we are done */
- cFYI(1, "found the last secondary response");
- return 0;
-}
-
-static void
-cifs_echo_request(struct work_struct *work)
-{
- int rc;
- struct TCP_Server_Info *server = container_of(work,
- struct TCP_Server_Info, echo.work);
-
- /*
- * We cannot send an echo until the NEGOTIATE_PROTOCOL request is
- * done, which is indicated by maxBuf != 0. Also, no need to ping if
- * we got a response recently
- */
- if (server->maxBuf == 0 ||
- time_before(jiffies, server->lstrp + SMB_ECHO_INTERVAL - HZ))
- goto requeue_echo;
-
- rc = CIFSSMBEcho(server);
- if (rc)
- cFYI(1, "Unable to send echo request to server: %s",
- server->hostname);
-
-requeue_echo:
- queue_delayed_work(cifsiod_wq, &server->echo, SMB_ECHO_INTERVAL);
-}
-
-static bool
-allocate_buffers(struct TCP_Server_Info *server)
-{
- if (!server->bigbuf) {
- server->bigbuf = (char *)cifs_buf_get();
- if (!server->bigbuf) {
- cERROR(1, "No memory for large SMB response");
- msleep(3000);
- /* retry will check if exiting */
- return false;
- }
- } else if (server->large_buf) {
- /* we are reusing a dirty large buf, clear its start */
- memset(server->bigbuf, 0, header_size());
- }
-
- if (!server->smallbuf) {
- server->smallbuf = (char *)cifs_small_buf_get();
- if (!server->smallbuf) {
- cERROR(1, "No memory for SMB response");
- msleep(1000);
- /* retry will check if exiting */
- return false;
- }
- /* beginning of smb buffer is cleared in our buf_get */
- } else {
- /* if existing small buf clear beginning */
- memset(server->smallbuf, 0, header_size());
- }
-
- return true;
-}
-
-static bool
-server_unresponsive(struct TCP_Server_Info *server)
-{
- /*
- * We need to wait 2 echo intervals to make sure we handle such
- * situations right:
- * 1s client sends a normal SMB request
- * 2s client gets a response
- * 30s echo workqueue job pops, and decides we got a response recently
- * and don't need to send another
- * ...
- * 65s kernel_recvmsg times out, and we see that we haven't gotten
- * a response in >60s.
- */
- if (server->tcpStatus == CifsGood &&
- time_after(jiffies, server->lstrp + 2 * SMB_ECHO_INTERVAL)) {
- cERROR(1, "Server %s has not responded in %d seconds. "
- "Reconnecting...", server->hostname,
- (2 * SMB_ECHO_INTERVAL) / HZ);
- cifs_reconnect(server);
- wake_up(&server->response_q);
- return true;
- }
-
- return false;
-}
-
-/*
- * kvec_array_init - clone a kvec array, and advance into it
- * @new: pointer to memory for cloned array
- * @iov: pointer to original array
- * @nr_segs: number of members in original array
- * @bytes: number of bytes to advance into the cloned array
- *
- * This function will copy the array provided in iov to a section of memory
- * and advance the specified number of bytes into the new array. It returns
- * the number of segments in the new array. "new" must be at least as big as
- * the original iov array.
- */
-static unsigned int
-kvec_array_init(struct kvec *new, struct kvec *iov, unsigned int nr_segs,
- size_t bytes)
-{
- size_t base = 0;
-
- while (bytes || !iov->iov_len) {
- int copy = min(bytes, iov->iov_len);
-
- bytes -= copy;
- base += copy;
- if (iov->iov_len == base) {
- iov++;
- nr_segs--;
- base = 0;
- }
- }
- memcpy(new, iov, sizeof(*iov) * nr_segs);
- new->iov_base += base;
- new->iov_len -= base;
- return nr_segs;
-}
-
-static struct kvec *
-get_server_iovec(struct TCP_Server_Info *server, unsigned int nr_segs)
-{
- struct kvec *new_iov;
-
- if (server->iov && nr_segs <= server->nr_iov)
- return server->iov;
-
- /* not big enough -- allocate a new one and release the old */
- new_iov = kmalloc(sizeof(*new_iov) * nr_segs, GFP_NOFS);
- if (new_iov) {
- kfree(server->iov);
- server->iov = new_iov;
- server->nr_iov = nr_segs;
- }
- return new_iov;
-}
-
-int
-cifs_readv_from_socket(struct TCP_Server_Info *server, struct kvec *iov_orig,
- unsigned int nr_segs, unsigned int to_read)
-{
- int length = 0;
- int total_read;
- unsigned int segs;
- struct msghdr smb_msg;
- struct kvec *iov;
-
- iov = get_server_iovec(server, nr_segs);
- if (!iov)
- return -ENOMEM;
-
- smb_msg.msg_control = NULL;
- smb_msg.msg_controllen = 0;
-
- for (total_read = 0; to_read; total_read += length, to_read -= length) {
- try_to_freeze();
-
- if (server_unresponsive(server)) {
- total_read = -EAGAIN;
- break;
- }
-
- segs = kvec_array_init(iov, iov_orig, nr_segs, total_read);
-
- length = kernel_recvmsg(server->ssocket, &smb_msg,
- iov, segs, to_read, 0);
-
- if (server->tcpStatus == CifsExiting) {
- total_read = -ESHUTDOWN;
- break;
- } else if (server->tcpStatus == CifsNeedReconnect) {
- cifs_reconnect(server);
- total_read = -EAGAIN;
- break;
- } else if (length == -ERESTARTSYS ||
- length == -EAGAIN ||
- length == -EINTR) {
- /*
- * Minimum sleep to prevent looping, allowing socket
- * to clear and app threads to set tcpStatus
- * CifsNeedReconnect if server hung.
- */
- usleep_range(1000, 2000);
- length = 0;
- continue;
- } else if (length <= 0) {
- cFYI(1, "Received no data or error: expecting %d "
- "got %d", to_read, length);
- cifs_reconnect(server);
- total_read = -EAGAIN;
- break;
- }
- }
- return total_read;
-}
-
-int
-cifs_read_from_socket(struct TCP_Server_Info *server, char *buf,
- unsigned int to_read)
-{
- struct kvec iov;
-
- iov.iov_base = buf;
- iov.iov_len = to_read;
-
- return cifs_readv_from_socket(server, &iov, 1, to_read);
-}
-
-static bool
-is_smb_response(struct TCP_Server_Info *server, unsigned char type)
-{
- /*
- * The first byte big endian of the length field,
- * is actually not part of the length but the type
- * with the most common, zero, as regular data.
- */
- switch (type) {
- case RFC1002_SESSION_MESSAGE:
- /* Regular SMB response */
- return true;
- case RFC1002_SESSION_KEEP_ALIVE:
- cFYI(1, "RFC 1002 session keep alive");
- break;
- case RFC1002_POSITIVE_SESSION_RESPONSE:
- cFYI(1, "RFC 1002 positive session response");
- break;
- case RFC1002_NEGATIVE_SESSION_RESPONSE:
- /*
- * We get this from Windows 98 instead of an error on
- * SMB negprot response.
- */
- cFYI(1, "RFC 1002 negative session response");
- /* give server a second to clean up */
- msleep(1000);
- /*
- * Always try 445 first on reconnect since we get NACK
- * on some if we ever connected to port 139 (the NACK
- * is since we do not begin with RFC1001 session
- * initialize frame).
- */
- cifs_set_port((struct sockaddr *)&server->dstaddr, CIFS_PORT);
- cifs_reconnect(server);
- wake_up(&server->response_q);
- break;
- default:
- cERROR(1, "RFC 1002 unknown response type 0x%x", type);
- cifs_reconnect(server);
- }
-
- return false;
-}
-
-static struct mid_q_entry *
-find_mid(struct TCP_Server_Info *server, char *buffer)
-{
- struct smb_hdr *buf = (struct smb_hdr *)buffer;
- struct mid_q_entry *mid;
-
- spin_lock(&GlobalMid_Lock);
- list_for_each_entry(mid, &server->pending_mid_q, qhead) {
- if (mid->mid == buf->Mid &&
- mid->mid_state == MID_REQUEST_SUBMITTED &&
- le16_to_cpu(mid->command) == buf->Command) {
- spin_unlock(&GlobalMid_Lock);
- return mid;
- }
- }
- spin_unlock(&GlobalMid_Lock);
- return NULL;
-}
-
-void
-dequeue_mid(struct mid_q_entry *mid, bool malformed)
-{
-#ifdef CONFIG_CIFS_STATS2
- mid->when_received = jiffies;
-#endif
- spin_lock(&GlobalMid_Lock);
- if (!malformed)
- mid->mid_state = MID_RESPONSE_RECEIVED;
- else
- mid->mid_state = MID_RESPONSE_MALFORMED;
- list_del_init(&mid->qhead);
- spin_unlock(&GlobalMid_Lock);
-}
-
-static void
-handle_mid(struct mid_q_entry *mid, struct TCP_Server_Info *server,
- char *buf, int malformed)
-{
- if (malformed == 0 && check2ndT2(buf) > 0) {
- mid->multiRsp = true;
- if (mid->resp_buf) {
- /* merge response - fix up 1st*/
- malformed = coalesce_t2(buf, mid->resp_buf);
- if (malformed > 0)
- return;
-
- /* All parts received or packet is malformed. */
- mid->multiEnd = true;
- return dequeue_mid(mid, malformed);
- }
- if (!server->large_buf) {
- /*FIXME: switch to already allocated largebuf?*/
- cERROR(1, "1st trans2 resp needs bigbuf");
- } else {
- /* Have first buffer */
- mid->resp_buf = buf;
- mid->large_buf = true;
- server->bigbuf = NULL;
- }
- return;
- }
- mid->resp_buf = buf;
- mid->large_buf = server->large_buf;
- /* Was previous buf put in mpx struct for multi-rsp? */
- if (!mid->multiRsp) {
- /* smb buffer will be freed by user thread */
- if (server->large_buf)
- server->bigbuf = NULL;
- else
- server->smallbuf = NULL;
- }
- dequeue_mid(mid, malformed);
-}
-
-static void clean_demultiplex_info(struct TCP_Server_Info *server)
-{
- int length;
-
- /* take it off the list, if it's not already */
- spin_lock(&cifs_tcp_ses_lock);
- list_del_init(&server->tcp_ses_list);
- spin_unlock(&cifs_tcp_ses_lock);
-
- spin_lock(&GlobalMid_Lock);
- server->tcpStatus = CifsExiting;
- spin_unlock(&GlobalMid_Lock);
- wake_up_all(&server->response_q);
-
- /* check if we have blocked requests that need to free */
- spin_lock(&server->req_lock);
- if (server->credits <= 0)
- server->credits = 1;
- spin_unlock(&server->req_lock);
- /*
- * Although there should not be any requests blocked on this queue it
- * can not hurt to be paranoid and try to wake up requests that may
- * haven been blocked when more than 50 at time were on the wire to the
- * same server - they now will see the session is in exit state and get
- * out of SendReceive.
- */
- wake_up_all(&server->request_q);
- /* give those requests time to exit */
- msleep(125);
-
- if (server->ssocket) {
- sock_release(server->ssocket);
- server->ssocket = NULL;
- }
-
- if (!list_empty(&server->pending_mid_q)) {
- struct list_head dispose_list;
- struct mid_q_entry *mid_entry;
- struct list_head *tmp, *tmp2;
-
- INIT_LIST_HEAD(&dispose_list);
- spin_lock(&GlobalMid_Lock);
- list_for_each_safe(tmp, tmp2, &server->pending_mid_q) {
- mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
- cFYI(1, "Clearing mid 0x%llx", mid_entry->mid);
- mid_entry->mid_state = MID_SHUTDOWN;
- list_move(&mid_entry->qhead, &dispose_list);
- }
- spin_unlock(&GlobalMid_Lock);
-
- /* now walk dispose list and issue callbacks */
- list_for_each_safe(tmp, tmp2, &dispose_list) {
- mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
- cFYI(1, "Callback mid 0x%llx", mid_entry->mid);
- list_del_init(&mid_entry->qhead);
- mid_entry->callback(mid_entry);
- }
- /* 1/8th of sec is more than enough time for them to exit */
- msleep(125);
- }
-
- if (!list_empty(&server->pending_mid_q)) {
- /*
- * mpx threads have not exited yet give them at least the smb
- * send timeout time for long ops.
- *
- * Due to delays on oplock break requests, we need to wait at
- * least 45 seconds before giving up on a request getting a
- * response and going ahead and killing cifsd.
- */
- cFYI(1, "Wait for exit from demultiplex thread");
- msleep(46000);
- /*
- * If threads still have not exited they are probably never
- * coming home not much else we can do but free the memory.
- */
- }
-
- kfree(server->hostname);
- kfree(server->iov);
- kfree(server);
-
- length = atomic_dec_return(&tcpSesAllocCount);
- if (length > 0)
- mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
- GFP_KERNEL);
-}
-
-static int
-standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid)
-{
- int length;
- char *buf = server->smallbuf;
- unsigned int pdu_length = get_rfc1002_length(buf);
-
- /* make sure this will fit in a large buffer */
- if (pdu_length > CIFSMaxBufSize + max_header_size() - 4) {
- cERROR(1, "SMB response too long (%u bytes)",
- pdu_length);
- cifs_reconnect(server);
- wake_up(&server->response_q);
- return -EAGAIN;
- }
-
- /* switch to large buffer if too big for a small one */
- if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
- server->large_buf = true;
- memcpy(server->bigbuf, buf, server->total_read);
- buf = server->bigbuf;
- }
-
- /* now read the rest */
- length = cifs_read_from_socket(server, buf + header_size() - 1,
- pdu_length - header_size() + 1 + 4);
- if (length < 0)
- return length;
- server->total_read += length;
-
- dump_smb(buf, server->total_read);
-
- /*
- * We know that we received enough to get to the MID as we
- * checked the pdu_length earlier. Now check to see
- * if the rest of the header is OK. We borrow the length
- * var for the rest of the loop to avoid a new stack var.
- *
- * 48 bytes is enough to display the header and a little bit
- * into the payload for debugging purposes.
- */
- length = checkSMB(buf, server->total_read);
- if (length != 0)
- cifs_dump_mem("Bad SMB: ", buf,
- min_t(unsigned int, server->total_read, 48));
-
- if (!mid)
- return length;
-
- handle_mid(mid, server, buf, length);
- return 0;
-}
-
-static int
-cifs_demultiplex_thread(void *p)
-{
- int length;
- struct TCP_Server_Info *server = p;
- unsigned int pdu_length;
- char *buf = NULL;
- struct task_struct *task_to_wake = NULL;
- struct mid_q_entry *mid_entry;
-
- current->flags |= PF_MEMALLOC;
- cFYI(1, "Demultiplex PID: %d", task_pid_nr(current));
-
- length = atomic_inc_return(&tcpSesAllocCount);
- if (length > 1)
- mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
- GFP_KERNEL);
-
- set_freezable();
- while (server->tcpStatus != CifsExiting) {
- if (try_to_freeze())
- continue;
-
- if (!allocate_buffers(server))
- continue;
-
- server->large_buf = false;
- buf = server->smallbuf;
- pdu_length = 4; /* enough to get RFC1001 header */
-
- length = cifs_read_from_socket(server, buf, pdu_length);
- if (length < 0)
- continue;
- server->total_read = length;
-
- /*
- * The right amount was read from socket - 4 bytes,
- * so we can now interpret the length field.
- */
- pdu_length = get_rfc1002_length(buf);
-
- cFYI(1, "RFC1002 header 0x%x", pdu_length);
- if (!is_smb_response(server, buf[0]))
- continue;
-
- /* make sure we have enough to get to the MID */
- if (pdu_length < header_size() - 1 - 4) {
- cERROR(1, "SMB response too short (%u bytes)",
- pdu_length);
- cifs_reconnect(server);
- wake_up(&server->response_q);
- continue;
- }
-
- /* read down to the MID */
- length = cifs_read_from_socket(server, buf + 4,
- header_size() - 1 - 4);
- if (length < 0)
- continue;
- server->total_read += length;
-
- mid_entry = find_mid(server, buf);
-
- if (!mid_entry || !mid_entry->receive)
- length = standard_receive3(server, mid_entry);
- else
- length = mid_entry->receive(server, mid_entry);
-
- if (length < 0)
- continue;
-
- if (server->large_buf)
- buf = server->bigbuf;
-
- server->lstrp = jiffies;
- if (mid_entry != NULL) {
- if (!mid_entry->multiRsp || mid_entry->multiEnd)
- mid_entry->callback(mid_entry);
- } else if (!is_valid_oplock_break(buf, server)) {
- cERROR(1, "No task to wake, unknown frame received! "
- "NumMids %d", atomic_read(&midCount));
- cifs_dump_mem("Received Data is: ", buf, header_size());
-#ifdef CONFIG_CIFS_DEBUG2
- cifs_dump_detail(buf);
- cifs_dump_mids(server);
-#endif /* CIFS_DEBUG2 */
-
- }
- } /* end while !EXITING */
-
- /* buffer usually freed in free_mid - need to free it here on exit */
- cifs_buf_release(server->bigbuf);
- if (server->smallbuf) /* no sense logging a debug message if NULL */
- cifs_small_buf_release(server->smallbuf);
-
- task_to_wake = xchg(&server->tsk, NULL);
- clean_demultiplex_info(server);
-
- /* if server->tsk was NULL then wait for a signal before exiting */
- if (!task_to_wake) {
- set_current_state(TASK_INTERRUPTIBLE);
- while (!signal_pending(current)) {
- schedule();
- set_current_state(TASK_INTERRUPTIBLE);
- }
- set_current_state(TASK_RUNNING);
- }
-
- module_put_and_exit(0);
-}
-
-/* extract the host portion of the UNC string */
-static char *
-extract_hostname(const char *unc)
-{
- const char *src;
- char *dst, *delim;
- unsigned int len;
-
- /* skip double chars at beginning of string */
- /* BB: check validity of these bytes? */
- src = unc + 2;
-
- /* delimiter between hostname and sharename is always '\\' now */
- delim = strchr(src, '\\');
- if (!delim)
- return ERR_PTR(-EINVAL);
-
- len = delim - src;
- dst = kmalloc((len + 1), GFP_KERNEL);
- if (dst == NULL)
- return ERR_PTR(-ENOMEM);
-
- memcpy(dst, src, len);
- dst[len] = '\0';
-
- return dst;
-}
-
-static int get_option_ul(substring_t args[], unsigned long *option)
-{
- int rc;
- char *string;
-
- string = match_strdup(args);
- if (string == NULL)
- return -ENOMEM;
- rc = kstrtoul(string, 0, option);
- kfree(string);
-
- return rc;
-}
-
-
-static int cifs_parse_security_flavors(char *value,
- struct smb_vol *vol)
-{
-
- substring_t args[MAX_OPT_ARGS];
-
- switch (match_token(value, cifs_secflavor_tokens, args)) {
- case Opt_sec_krb5:
- vol->secFlg |= CIFSSEC_MAY_KRB5;
- break;
- case Opt_sec_krb5i:
- vol->secFlg |= CIFSSEC_MAY_KRB5 | CIFSSEC_MUST_SIGN;
- break;
- case Opt_sec_krb5p:
- /* vol->secFlg |= CIFSSEC_MUST_SEAL | CIFSSEC_MAY_KRB5; */
- cERROR(1, "Krb5 cifs privacy not supported");
- break;
- case Opt_sec_ntlmssp:
- vol->secFlg |= CIFSSEC_MAY_NTLMSSP;
- break;
- case Opt_sec_ntlmsspi:
- vol->secFlg |= CIFSSEC_MAY_NTLMSSP | CIFSSEC_MUST_SIGN;
- break;
- case Opt_ntlm:
- /* ntlm is default so can be turned off too */
- vol->secFlg |= CIFSSEC_MAY_NTLM;
- break;
- case Opt_sec_ntlmi:
- vol->secFlg |= CIFSSEC_MAY_NTLM | CIFSSEC_MUST_SIGN;
- break;
- case Opt_sec_nontlm:
- vol->secFlg |= CIFSSEC_MAY_NTLMV2;
- break;
- case Opt_sec_ntlmv2i:
- vol->secFlg |= CIFSSEC_MAY_NTLMV2 | CIFSSEC_MUST_SIGN;
- break;
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
- case Opt_sec_lanman:
- vol->secFlg |= CIFSSEC_MAY_LANMAN;
- break;
-#endif
- case Opt_sec_none:
- vol->nullauth = 1;
- break;
- default:
- cERROR(1, "bad security option: %s", value);
- return 1;
- }
-
- return 0;
-}
-
-static int
-cifs_parse_mount_options(const char *mountdata, const char *devname,
- struct smb_vol *vol)
-{
- char *data, *end;
- char *mountdata_copy = NULL, *options;
- unsigned int temp_len, i, j;
- char separator[2];
- short int override_uid = -1;
- short int override_gid = -1;
- bool uid_specified = false;
- bool gid_specified = false;
- bool sloppy = false;
- char *invalid = NULL;
- char *nodename = utsname()->nodename;
- char *string = NULL;
- char *tmp_end, *value;
- char delim;
-
- separator[0] = ',';
- separator[1] = 0;
- delim = separator[0];
-
- /*
- * does not have to be perfect mapping since field is
- * informational, only used for servers that do not support
- * port 445 and it can be overridden at mount time
- */
- memset(vol->source_rfc1001_name, 0x20, RFC1001_NAME_LEN);
- for (i = 0; i < strnlen(nodename, RFC1001_NAME_LEN); i++)
- vol->source_rfc1001_name[i] = toupper(nodename[i]);
-
- vol->source_rfc1001_name[RFC1001_NAME_LEN] = 0;
- /* null target name indicates to use *SMBSERVR default called name
- if we end up sending RFC1001 session initialize */
- vol->target_rfc1001_name[0] = 0;
- vol->cred_uid = current_uid();
- vol->linux_uid = current_uid();
- vol->linux_gid = current_gid();
-
- /* default to only allowing write access to owner of the mount */
- vol->dir_mode = vol->file_mode = S_IRUGO | S_IXUGO | S_IWUSR;
-
- /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
- /* default is always to request posix paths. */
- vol->posix_paths = 1;
- /* default to using server inode numbers where available */
- vol->server_ino = 1;
-
- vol->actimeo = CIFS_DEF_ACTIMEO;
-
- if (!mountdata)
- goto cifs_parse_mount_err;
-
- mountdata_copy = kstrndup(mountdata, PAGE_SIZE, GFP_KERNEL);
- if (!mountdata_copy)
- goto cifs_parse_mount_err;
-
- options = mountdata_copy;
- end = options + strlen(options);
-
- if (strncmp(options, "sep=", 4) == 0) {
- if (options[4] != 0) {
- separator[0] = options[4];
- options += 5;
- } else {
- cFYI(1, "Null separator not allowed");
- }
- }
- vol->backupuid_specified = false; /* no backup intent for a user */
- vol->backupgid_specified = false; /* no backup intent for a group */
-
- while ((data = strsep(&options, separator)) != NULL) {
- substring_t args[MAX_OPT_ARGS];
- unsigned long option;
- int token;
-
- if (!*data)
- continue;
-
- token = match_token(data, cifs_mount_option_tokens, args);
-
- switch (token) {
-
- /* Ingnore the following */
- case Opt_ignore:
- break;
-
- /* Boolean values */
- case Opt_user_xattr:
- vol->no_xattr = 0;
- break;
- case Opt_nouser_xattr:
- vol->no_xattr = 1;
- break;
- case Opt_forceuid:
- override_uid = 1;
- break;
- case Opt_noforceuid:
- override_uid = 0;
- break;
- case Opt_noblocksend:
- vol->noblocksnd = 1;
- break;
- case Opt_noautotune:
- vol->noautotune = 1;
- break;
- case Opt_hard:
- vol->retry = 1;
- break;
- case Opt_soft:
- vol->retry = 0;
- break;
- case Opt_perm:
- vol->noperm = 0;
- break;
- case Opt_noperm:
- vol->noperm = 1;
- break;
- case Opt_mapchars:
- vol->remap = 1;
- break;
- case Opt_nomapchars:
- vol->remap = 0;
- break;
- case Opt_sfu:
- vol->sfu_emul = 1;
- break;
- case Opt_nosfu:
- vol->sfu_emul = 0;
- break;
- case Opt_nodfs:
- vol->nodfs = 1;
- break;
- case Opt_posixpaths:
- vol->posix_paths = 1;
- break;
- case Opt_noposixpaths:
- vol->posix_paths = 0;
- break;
- case Opt_nounix:
- vol->no_linux_ext = 1;
- break;
- case Opt_nocase:
- vol->nocase = 1;
- break;
- case Opt_brl:
- vol->nobrl = 0;
- break;
- case Opt_nobrl:
- vol->nobrl = 1;
- /*
- * turn off mandatory locking in mode
- * if remote locking is turned off since the
- * local vfs will do advisory
- */
- if (vol->file_mode ==
- (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
- vol->file_mode = S_IALLUGO;
- break;
- case Opt_forcemandatorylock:
- vol->mand_lock = 1;
- break;
- case Opt_setuids:
- vol->setuids = 1;
- break;
- case Opt_nosetuids:
- vol->setuids = 0;
- break;
- case Opt_dynperm:
- vol->dynperm = true;
- break;
- case Opt_nodynperm:
- vol->dynperm = false;
- break;
- case Opt_nohard:
- vol->retry = 0;
- break;
- case Opt_nosoft:
- vol->retry = 1;
- break;
- case Opt_nointr:
- vol->intr = 0;
- break;
- case Opt_intr:
- vol->intr = 1;
- break;
- case Opt_nostrictsync:
- vol->nostrictsync = 1;
- break;
- case Opt_strictsync:
- vol->nostrictsync = 0;
- break;
- case Opt_serverino:
- vol->server_ino = 1;
- break;
- case Opt_noserverino:
- vol->server_ino = 0;
- break;
- case Opt_rwpidforward:
- vol->rwpidforward = 1;
- break;
- case Opt_cifsacl:
- vol->cifs_acl = 1;
- break;
- case Opt_nocifsacl:
- vol->cifs_acl = 0;
- break;
- case Opt_acl:
- vol->no_psx_acl = 0;
- break;
- case Opt_noacl:
- vol->no_psx_acl = 1;
- break;
- case Opt_locallease:
- vol->local_lease = 1;
- break;
- case Opt_sign:
- vol->secFlg |= CIFSSEC_MUST_SIGN;
- break;
- case Opt_seal:
- /* we do not do the following in secFlags because seal
- * is a per tree connection (mount) not a per socket
- * or per-smb connection option in the protocol
- * vol->secFlg |= CIFSSEC_MUST_SEAL;
- */
- vol->seal = 1;
- break;
- case Opt_direct:
- vol->direct_io = 1;
- break;
- case Opt_strictcache:
- vol->strict_io = 1;
- break;
- case Opt_noac:
- printk(KERN_WARNING "CIFS: Mount option noac not "
- "supported. Instead set "
- "/proc/fs/cifs/LookupCacheEnabled to 0\n");
- break;
- case Opt_fsc:
-#ifndef CONFIG_CIFS_FSCACHE
- cERROR(1, "FS-Cache support needs CONFIG_CIFS_FSCACHE "
- "kernel config option set");
- goto cifs_parse_mount_err;
-#endif
- vol->fsc = true;
- break;
- case Opt_mfsymlinks:
- vol->mfsymlinks = true;
- break;
- case Opt_multiuser:
- vol->multiuser = true;
- break;
- case Opt_sloppy:
- sloppy = true;
- break;
-
- /* Numeric Values */
- case Opt_backupuid:
- if (get_option_ul(args, &option)) {
- cERROR(1, "%s: Invalid backupuid value",
- __func__);
- goto cifs_parse_mount_err;
- }
- vol->backupuid = option;
- vol->backupuid_specified = true;
- break;
- case Opt_backupgid:
- if (get_option_ul(args, &option)) {
- cERROR(1, "%s: Invalid backupgid value",
- __func__);
- goto cifs_parse_mount_err;
- }
- vol->backupgid = option;
- vol->backupgid_specified = true;
- break;
- case Opt_uid:
- if (get_option_ul(args, &option)) {
- cERROR(1, "%s: Invalid uid value",
- __func__);
- goto cifs_parse_mount_err;
- }
- vol->linux_uid = option;
- uid_specified = true;
- break;
- case Opt_cruid:
- if (get_option_ul(args, &option)) {
- cERROR(1, "%s: Invalid cruid value",
- __func__);
- goto cifs_parse_mount_err;
- }
- vol->cred_uid = option;
- break;
- case Opt_gid:
- if (get_option_ul(args, &option)) {
- cERROR(1, "%s: Invalid gid value",
- __func__);
- goto cifs_parse_mount_err;
- }
- vol->linux_gid = option;
- gid_specified = true;
- break;
- case Opt_file_mode:
- if (get_option_ul(args, &option)) {
- cERROR(1, "%s: Invalid file_mode value",
- __func__);
- goto cifs_parse_mount_err;
- }
- vol->file_mode = option;
- break;
- case Opt_dirmode:
- if (get_option_ul(args, &option)) {
- cERROR(1, "%s: Invalid dir_mode value",
- __func__);
- goto cifs_parse_mount_err;
- }
- vol->dir_mode = option;
- break;
- case Opt_port:
- if (get_option_ul(args, &option)) {
- cERROR(1, "%s: Invalid port value",
- __func__);
- goto cifs_parse_mount_err;
- }
- vol->port = option;
- break;
- case Opt_rsize:
- if (get_option_ul(args, &option)) {
- cERROR(1, "%s: Invalid rsize value",
- __func__);
- goto cifs_parse_mount_err;
- }
- vol->rsize = option;
- break;
- case Opt_wsize:
- if (get_option_ul(args, &option)) {
- cERROR(1, "%s: Invalid wsize value",
- __func__);
- goto cifs_parse_mount_err;
- }
- vol->wsize = option;
- break;
- case Opt_actimeo:
- if (get_option_ul(args, &option)) {
- cERROR(1, "%s: Invalid actimeo value",
- __func__);
- goto cifs_parse_mount_err;
- }
- vol->actimeo = HZ * option;
- if (vol->actimeo > CIFS_MAX_ACTIMEO) {
- cERROR(1, "CIFS: attribute cache"
- "timeout too large");
- goto cifs_parse_mount_err;
- }
- break;
-
- /* String Arguments */
-
- case Opt_blank_user:
- /* null user, ie. anonymous authentication */
- vol->nullauth = 1;
- vol->username = NULL;
- break;
- case Opt_user:
- string = match_strdup(args);
- if (string == NULL)
- goto out_nomem;
-
- if (strnlen(string, MAX_USERNAME_SIZE) >
- MAX_USERNAME_SIZE) {
- printk(KERN_WARNING "CIFS: username too long\n");
- goto cifs_parse_mount_err;
- }
- vol->username = kstrdup(string, GFP_KERNEL);
- if (!vol->username) {
- printk(KERN_WARNING "CIFS: no memory "
- "for username\n");
- goto cifs_parse_mount_err;
- }
- break;
- case Opt_blank_pass:
- vol->password = NULL;
- break;
- case Opt_pass:
- /* passwords have to be handled differently
- * to allow the character used for deliminator
- * to be passed within them
- */
-
- /* Obtain the value string */
- value = strchr(data, '=');
- value++;
-
- /* Set tmp_end to end of the string */
- tmp_end = (char *) value + strlen(value);
-
- /* Check if following character is the deliminator
- * If yes, we have encountered a double deliminator
- * reset the NULL character to the deliminator
- */
- if (tmp_end < end && tmp_end[1] == delim) {
- tmp_end[0] = delim;
-
- /* Keep iterating until we get to a single
- * deliminator OR the end
- */
- while ((tmp_end = strchr(tmp_end, delim))
- != NULL && (tmp_end[1] == delim)) {
- tmp_end = (char *) &tmp_end[2];
- }
-
- /* Reset var options to point to next element */
- if (tmp_end) {
- tmp_end[0] = '\0';
- options = (char *) &tmp_end[1];
- } else
- /* Reached the end of the mount option
- * string */
- options = end;
- }
-
- /* Now build new password string */
- temp_len = strlen(value);
- vol->password = kzalloc(temp_len+1, GFP_KERNEL);
- if (vol->password == NULL) {
- printk(KERN_WARNING "CIFS: no memory "
- "for password\n");
- goto cifs_parse_mount_err;
- }
-
- for (i = 0, j = 0; i < temp_len; i++, j++) {
- vol->password[j] = value[i];
- if ((value[i] == delim) &&
- value[i+1] == delim)
- /* skip the second deliminator */
- i++;
- }
- vol->password[j] = '\0';
- break;
- case Opt_blank_ip:
- vol->UNCip = NULL;
- break;
- case Opt_ip:
- string = match_strdup(args);
- if (string == NULL)
- goto out_nomem;
-
- if (strnlen(string, INET6_ADDRSTRLEN) >
- INET6_ADDRSTRLEN) {
- printk(KERN_WARNING "CIFS: ip address "
- "too long\n");
- goto cifs_parse_mount_err;
- }
- vol->UNCip = kstrdup(string, GFP_KERNEL);
- if (!vol->UNCip) {
- printk(KERN_WARNING "CIFS: no memory "
- "for UNC IP\n");
- goto cifs_parse_mount_err;
- }
- break;
- case Opt_unc:
- string = match_strdup(args);
- if (string == NULL)
- goto out_nomem;
-
- temp_len = strnlen(string, 300);
- if (temp_len == 300) {
- printk(KERN_WARNING "CIFS: UNC name too long\n");
- goto cifs_parse_mount_err;
- }
-
- vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
- if (vol->UNC == NULL) {
- printk(KERN_WARNING "CIFS: no memory for UNC\n");
- goto cifs_parse_mount_err;
- }
- strcpy(vol->UNC, string);
-
- if (strncmp(string, "//", 2) == 0) {
- vol->UNC[0] = '\\';
- vol->UNC[1] = '\\';
- } else if (strncmp(string, "\\\\", 2) != 0) {
- printk(KERN_WARNING "CIFS: UNC Path does not "
- "begin with // or \\\\\n");
- goto cifs_parse_mount_err;
- }
-
- break;
- case Opt_domain:
- string = match_strdup(args);
- if (string == NULL)
- goto out_nomem;
-
- if (strnlen(string, 256) == 256) {
- printk(KERN_WARNING "CIFS: domain name too"
- " long\n");
- goto cifs_parse_mount_err;
- }
-
- vol->domainname = kstrdup(string, GFP_KERNEL);
- if (!vol->domainname) {
- printk(KERN_WARNING "CIFS: no memory "
- "for domainname\n");
- goto cifs_parse_mount_err;
- }
- cFYI(1, "Domain name set");
- break;
- case Opt_srcaddr:
- string = match_strdup(args);
- if (string == NULL)
- goto out_nomem;
-
- if (!cifs_convert_address(
- (struct sockaddr *)&vol->srcaddr,
- string, strlen(string))) {
- printk(KERN_WARNING "CIFS: Could not parse"
- " srcaddr: %s\n", string);
- goto cifs_parse_mount_err;
- }
- break;
- case Opt_prefixpath:
- string = match_strdup(args);
- if (string == NULL)
- goto out_nomem;
-
- temp_len = strnlen(string, 1024);
- if (string[0] != '/')
- temp_len++; /* missing leading slash */
- if (temp_len > 1024) {
- printk(KERN_WARNING "CIFS: prefix too long\n");
- goto cifs_parse_mount_err;
- }
-
- vol->prepath = kmalloc(temp_len+1, GFP_KERNEL);
- if (vol->prepath == NULL) {
- printk(KERN_WARNING "CIFS: no memory "
- "for path prefix\n");
- goto cifs_parse_mount_err;
- }
-
- if (string[0] != '/') {
- vol->prepath[0] = '/';
- strcpy(vol->prepath+1, string);
- } else
- strcpy(vol->prepath, string);
-
- break;
- case Opt_iocharset:
- string = match_strdup(args);
- if (string == NULL)
- goto out_nomem;
-
- if (strnlen(string, 1024) >= 65) {
- printk(KERN_WARNING "CIFS: iocharset name "
- "too long.\n");
- goto cifs_parse_mount_err;
- }
-
- if (strnicmp(string, "default", 7) != 0) {
- vol->iocharset = kstrdup(string,
- GFP_KERNEL);
- if (!vol->iocharset) {
- printk(KERN_WARNING "CIFS: no memory"
- "for charset\n");
- goto cifs_parse_mount_err;
- }
- }
- /* if iocharset not set then load_nls_default
- * is used by caller
- */
- cFYI(1, "iocharset set to %s", string);
- break;
- case Opt_sockopt:
- string = match_strdup(args);
- if (string == NULL)
- goto out_nomem;
-
- if (strnicmp(string, "TCP_NODELAY", 11) == 0)
- vol->sockopt_tcp_nodelay = 1;
- break;
- case Opt_netbiosname:
- string = match_strdup(args);
- if (string == NULL)
- goto out_nomem;
-
- memset(vol->source_rfc1001_name, 0x20,
- RFC1001_NAME_LEN);
- /*
- * FIXME: are there cases in which a comma can
- * be valid in workstation netbios name (and
- * need special handling)?
- */
- for (i = 0; i < RFC1001_NAME_LEN; i++) {
- /* don't ucase netbiosname for user */
- if (string[i] == 0)
- break;
- vol->source_rfc1001_name[i] = string[i];
- }
- /* The string has 16th byte zero still from
- * set at top of the function
- */
- if (i == RFC1001_NAME_LEN && string[i] != 0)
- printk(KERN_WARNING "CIFS: netbiosname"
- " longer than 15 truncated.\n");
-
- break;
- case Opt_servern:
- /* servernetbiosname specified override *SMBSERVER */
- string = match_strdup(args);
- if (string == NULL)
- goto out_nomem;
-
- /* last byte, type, is 0x20 for servr type */
- memset(vol->target_rfc1001_name, 0x20,
- RFC1001_NAME_LEN_WITH_NULL);
-
- /* BB are there cases in which a comma can be
- valid in this workstation netbios name
- (and need special handling)? */
-
- /* user or mount helper must uppercase the
- netbios name */
- for (i = 0; i < 15; i++) {
- if (string[i] == 0)
- break;
- vol->target_rfc1001_name[i] = string[i];
- }
- /* The string has 16th byte zero still from
- set at top of the function */
- if (i == RFC1001_NAME_LEN && string[i] != 0)
- printk(KERN_WARNING "CIFS: server net"
- "biosname longer than 15 truncated.\n");
- break;
- case Opt_ver:
- string = match_strdup(args);
- if (string == NULL)
- goto out_nomem;
-
- if (strnicmp(string, "cifs", 4) == 0 ||
- strnicmp(string, "1", 1) == 0) {
- /* This is the default */
- break;
- }
- /* For all other value, error */
- printk(KERN_WARNING "CIFS: Invalid version"
- " specified\n");
- goto cifs_parse_mount_err;
- case Opt_sec:
- string = match_strdup(args);
- if (string == NULL)
- goto out_nomem;
-
- if (cifs_parse_security_flavors(string, vol) != 0)
- goto cifs_parse_mount_err;
- break;
- default:
- /*
- * An option we don't recognize. Save it off for later
- * if we haven't already found one
- */
- if (!invalid)
- invalid = data;
- break;
- }
- /* Free up any allocated string */
- kfree(string);
- string = NULL;
- }
-
- if (!sloppy && invalid) {
- printk(KERN_ERR "CIFS: Unknown mount option \"%s\"\n", invalid);
- goto cifs_parse_mount_err;
- }
-
-#ifndef CONFIG_KEYS
- /* Muliuser mounts require CONFIG_KEYS support */
- if (vol->multiuser) {
- cERROR(1, "Multiuser mounts require kernels with "
- "CONFIG_KEYS enabled.");
- goto cifs_parse_mount_err;
- }
-#endif
-
- if (vol->UNCip == NULL)
- vol->UNCip = &vol->UNC[2];
-
- if (uid_specified)
- vol->override_uid = override_uid;
- else if (override_uid == 1)
- printk(KERN_NOTICE "CIFS: ignoring forceuid mount option "
- "specified with no uid= option.\n");
-
- if (gid_specified)
- vol->override_gid = override_gid;
- else if (override_gid == 1)
- printk(KERN_NOTICE "CIFS: ignoring forcegid mount option "
- "specified with no gid= option.\n");
-
- kfree(mountdata_copy);
- return 0;
-
-out_nomem:
- printk(KERN_WARNING "Could not allocate temporary buffer\n");
-cifs_parse_mount_err:
- kfree(string);
- kfree(mountdata_copy);
- return 1;
-}
-
-/** Returns true if srcaddr isn't specified and rhs isn't
- * specified, or if srcaddr is specified and
- * matches the IP address of the rhs argument.
- */
-static bool
-srcip_matches(struct sockaddr *srcaddr, struct sockaddr *rhs)
-{
- switch (srcaddr->sa_family) {
- case AF_UNSPEC:
- return (rhs->sa_family == AF_UNSPEC);
- case AF_INET: {
- struct sockaddr_in *saddr4 = (struct sockaddr_in *)srcaddr;
- struct sockaddr_in *vaddr4 = (struct sockaddr_in *)rhs;
- return (saddr4->sin_addr.s_addr == vaddr4->sin_addr.s_addr);
- }
- case AF_INET6: {
- struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)srcaddr;
- struct sockaddr_in6 *vaddr6 = (struct sockaddr_in6 *)&rhs;
- return ipv6_addr_equal(&saddr6->sin6_addr, &vaddr6->sin6_addr);
- }
- default:
- WARN_ON(1);
- return false; /* don't expect to be here */
- }
-}
-
-/*
- * If no port is specified in addr structure, we try to match with 445 port
- * and if it fails - with 139 ports. It should be called only if address
- * families of server and addr are equal.
- */
-static bool
-match_port(struct TCP_Server_Info *server, struct sockaddr *addr)
-{
- __be16 port, *sport;
-
- switch (addr->sa_family) {
- case AF_INET:
- sport = &((struct sockaddr_in *) &server->dstaddr)->sin_port;
- port = ((struct sockaddr_in *) addr)->sin_port;
- break;
- case AF_INET6:
- sport = &((struct sockaddr_in6 *) &server->dstaddr)->sin6_port;
- port = ((struct sockaddr_in6 *) addr)->sin6_port;
- break;
- default:
- WARN_ON(1);
- return false;
- }
-
- if (!port) {
- port = htons(CIFS_PORT);
- if (port == *sport)
- return true;
-
- port = htons(RFC1001_PORT);
- }
-
- return port == *sport;
-}
-
-static bool
-match_address(struct TCP_Server_Info *server, struct sockaddr *addr,
- struct sockaddr *srcaddr)
-{
- switch (addr->sa_family) {
- case AF_INET: {
- struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
- struct sockaddr_in *srv_addr4 =
- (struct sockaddr_in *)&server->dstaddr;
-
- if (addr4->sin_addr.s_addr != srv_addr4->sin_addr.s_addr)
- return false;
- break;
- }
- case AF_INET6: {
- struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
- struct sockaddr_in6 *srv_addr6 =
- (struct sockaddr_in6 *)&server->dstaddr;
-
- if (!ipv6_addr_equal(&addr6->sin6_addr,
- &srv_addr6->sin6_addr))
- return false;
- if (addr6->sin6_scope_id != srv_addr6->sin6_scope_id)
- return false;
- break;
- }
- default:
- WARN_ON(1);
- return false; /* don't expect to be here */
- }
-
- if (!srcip_matches(srcaddr, (struct sockaddr *)&server->srcaddr))
- return false;
-
- return true;
-}
-
-static bool
-match_security(struct TCP_Server_Info *server, struct smb_vol *vol)
-{
- unsigned int secFlags;
-
- if (vol->secFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL)))
- secFlags = vol->secFlg;
- else
- secFlags = global_secflags | vol->secFlg;
-
- switch (server->secType) {
- case LANMAN:
- if (!(secFlags & (CIFSSEC_MAY_LANMAN|CIFSSEC_MAY_PLNTXT)))
- return false;
- break;
- case NTLMv2:
- if (!(secFlags & CIFSSEC_MAY_NTLMV2))
- return false;
- break;
- case NTLM:
- if (!(secFlags & CIFSSEC_MAY_NTLM))
- return false;
- break;
- case Kerberos:
- if (!(secFlags & CIFSSEC_MAY_KRB5))
- return false;
- break;
- case RawNTLMSSP:
- if (!(secFlags & CIFSSEC_MAY_NTLMSSP))
- return false;
- break;
- default:
- /* shouldn't happen */
- return false;
- }
-
- /* now check if signing mode is acceptable */
- if ((secFlags & CIFSSEC_MAY_SIGN) == 0 &&
- (server->sec_mode & SECMODE_SIGN_REQUIRED))
- return false;
- else if (((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) &&
- (server->sec_mode &
- (SECMODE_SIGN_ENABLED|SECMODE_SIGN_REQUIRED)) == 0)
- return false;
-
- return true;
-}
-
-static int match_server(struct TCP_Server_Info *server, struct sockaddr *addr,
- struct smb_vol *vol)
-{
- if (!net_eq(cifs_net_ns(server), current->nsproxy->net_ns))
- return 0;
-
- if (!match_address(server, addr,
- (struct sockaddr *)&vol->srcaddr))
- return 0;
-
- if (!match_port(server, addr))
- return 0;
-
- if (!match_security(server, vol))
- return 0;
-
- return 1;
-}
-
-static struct TCP_Server_Info *
-cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol)
-{
- struct TCP_Server_Info *server;
-
- spin_lock(&cifs_tcp_ses_lock);
- list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
- if (!match_server(server, addr, vol))
- continue;
-
- ++server->srv_count;
- spin_unlock(&cifs_tcp_ses_lock);
- cFYI(1, "Existing tcp session with server found");
- return server;
- }
- spin_unlock(&cifs_tcp_ses_lock);
- return NULL;
-}
-
-static void
-cifs_put_tcp_session(struct TCP_Server_Info *server)
-{
- struct task_struct *task;
-
- spin_lock(&cifs_tcp_ses_lock);
- if (--server->srv_count > 0) {
- spin_unlock(&cifs_tcp_ses_lock);
- return;
- }
-
- put_net(cifs_net_ns(server));
-
- list_del_init(&server->tcp_ses_list);
- spin_unlock(&cifs_tcp_ses_lock);
-
- cancel_delayed_work_sync(&server->echo);
-
- spin_lock(&GlobalMid_Lock);
- server->tcpStatus = CifsExiting;
- spin_unlock(&GlobalMid_Lock);
-
- cifs_crypto_shash_release(server);
- cifs_fscache_release_client_cookie(server);
-
- kfree(server->session_key.response);
- server->session_key.response = NULL;
- server->session_key.len = 0;
-
- task = xchg(&server->tsk, NULL);
- if (task)
- force_sig(SIGKILL, task);
-}
-
-static struct TCP_Server_Info *
-cifs_get_tcp_session(struct smb_vol *volume_info)
-{
- struct TCP_Server_Info *tcp_ses = NULL;
- struct sockaddr_storage addr;
- struct sockaddr_in *sin_server = (struct sockaddr_in *) &addr;
- struct sockaddr_in6 *sin_server6 = (struct sockaddr_in6 *) &addr;
- int rc;
-
- memset(&addr, 0, sizeof(struct sockaddr_storage));
-
- cFYI(1, "UNC: %s ip: %s", volume_info->UNC, volume_info->UNCip);
-
- if (volume_info->UNCip && volume_info->UNC) {
- rc = cifs_fill_sockaddr((struct sockaddr *)&addr,
- volume_info->UNCip,
- strlen(volume_info->UNCip),
- volume_info->port);
- if (!rc) {
- /* we failed translating address */
- rc = -EINVAL;
- goto out_err;
- }
- } else if (volume_info->UNCip) {
- /* BB using ip addr as tcp_ses name to connect to the
- DFS root below */
- cERROR(1, "Connecting to DFS root not implemented yet");
- rc = -EINVAL;
- goto out_err;
- } else /* which tcp_sess DFS root would we conect to */ {
- cERROR(1, "CIFS mount error: No UNC path (e.g. -o "
- "unc=//192.168.1.100/public) specified");
- rc = -EINVAL;
- goto out_err;
- }
-
- /* see if we already have a matching tcp_ses */
- tcp_ses = cifs_find_tcp_session((struct sockaddr *)&addr, volume_info);
- if (tcp_ses)
- return tcp_ses;
-
- tcp_ses = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL);
- if (!tcp_ses) {
- rc = -ENOMEM;
- goto out_err;
- }
-
- rc = cifs_crypto_shash_allocate(tcp_ses);
- if (rc) {
- cERROR(1, "could not setup hash structures rc %d", rc);
- goto out_err;
- }
-
- cifs_set_net_ns(tcp_ses, get_net(current->nsproxy->net_ns));
- tcp_ses->hostname = extract_hostname(volume_info->UNC);
- if (IS_ERR(tcp_ses->hostname)) {
- rc = PTR_ERR(tcp_ses->hostname);
- goto out_err_crypto_release;
- }
-
- tcp_ses->noblocksnd = volume_info->noblocksnd;
- tcp_ses->noautotune = volume_info->noautotune;
- tcp_ses->tcp_nodelay = volume_info->sockopt_tcp_nodelay;
- tcp_ses->in_flight = 0;
- tcp_ses->credits = 1;
- init_waitqueue_head(&tcp_ses->response_q);
- init_waitqueue_head(&tcp_ses->request_q);
- INIT_LIST_HEAD(&tcp_ses->pending_mid_q);
- mutex_init(&tcp_ses->srv_mutex);
- memcpy(tcp_ses->workstation_RFC1001_name,
- volume_info->source_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
- memcpy(tcp_ses->server_RFC1001_name,
- volume_info->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
- tcp_ses->session_estab = false;
- tcp_ses->sequence_number = 0;
- tcp_ses->lstrp = jiffies;
- spin_lock_init(&tcp_ses->req_lock);
- INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
- INIT_LIST_HEAD(&tcp_ses->smb_ses_list);
- INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request);
-
- /*
- * at this point we are the only ones with the pointer
- * to the struct since the kernel thread not created yet
- * no need to spinlock this init of tcpStatus or srv_count
- */
- tcp_ses->tcpStatus = CifsNew;
- memcpy(&tcp_ses->srcaddr, &volume_info->srcaddr,
- sizeof(tcp_ses->srcaddr));
- ++tcp_ses->srv_count;
-
- if (addr.ss_family == AF_INET6) {
- cFYI(1, "attempting ipv6 connect");
- /* BB should we allow ipv6 on port 139? */
- /* other OS never observed in Wild doing 139 with v6 */
- memcpy(&tcp_ses->dstaddr, sin_server6,
- sizeof(struct sockaddr_in6));
- } else
- memcpy(&tcp_ses->dstaddr, sin_server,
- sizeof(struct sockaddr_in));
-
- rc = ip_connect(tcp_ses);
- if (rc < 0) {
- cERROR(1, "Error connecting to socket. Aborting operation");
- goto out_err_crypto_release;
- }
-
- /*
- * since we're in a cifs function already, we know that
- * this will succeed. No need for try_module_get().
- */
- __module_get(THIS_MODULE);
- tcp_ses->tsk = kthread_run(cifs_demultiplex_thread,
- tcp_ses, "cifsd");
- if (IS_ERR(tcp_ses->tsk)) {
- rc = PTR_ERR(tcp_ses->tsk);
- cERROR(1, "error %d create cifsd thread", rc);
- module_put(THIS_MODULE);
- goto out_err_crypto_release;
- }
- tcp_ses->tcpStatus = CifsNeedNegotiate;
-
- /* thread spawned, put it on the list */
- spin_lock(&cifs_tcp_ses_lock);
- list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list);
- spin_unlock(&cifs_tcp_ses_lock);
-
- cifs_fscache_get_client_cookie(tcp_ses);
-
- /* queue echo request delayed work */
- queue_delayed_work(cifsiod_wq, &tcp_ses->echo, SMB_ECHO_INTERVAL);
-
- return tcp_ses;
-
-out_err_crypto_release:
- cifs_crypto_shash_release(tcp_ses);
-
- put_net(cifs_net_ns(tcp_ses));
-
-out_err:
- if (tcp_ses) {
- if (!IS_ERR(tcp_ses->hostname))
- kfree(tcp_ses->hostname);
- if (tcp_ses->ssocket)
- sock_release(tcp_ses->ssocket);
- kfree(tcp_ses);
- }
- return ERR_PTR(rc);
-}
-
-static int match_session(struct cifs_ses *ses, struct smb_vol *vol)
-{
- switch (ses->server->secType) {
- case Kerberos:
- if (vol->cred_uid != ses->cred_uid)
- return 0;
- break;
- default:
- /* NULL username means anonymous session */
- if (ses->user_name == NULL) {
- if (!vol->nullauth)
- return 0;
- break;
- }
-
- /* anything else takes username/password */
- if (strncmp(ses->user_name,
- vol->username ? vol->username : "",
- MAX_USERNAME_SIZE))
- return 0;
- if (strlen(vol->username) != 0 &&
- ses->password != NULL &&
- strncmp(ses->password,
- vol->password ? vol->password : "",
- MAX_PASSWORD_SIZE))
- return 0;
- }
- return 1;
-}
-
-static struct cifs_ses *
-cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol)
-{
- struct cifs_ses *ses;
-
- spin_lock(&cifs_tcp_ses_lock);
- list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
- if (!match_session(ses, vol))
- continue;
- ++ses->ses_count;
- spin_unlock(&cifs_tcp_ses_lock);
- return ses;
- }
- spin_unlock(&cifs_tcp_ses_lock);
- return NULL;
-}
-
-static void
-cifs_put_smb_ses(struct cifs_ses *ses)
-{
- int xid;
- struct TCP_Server_Info *server = ses->server;
-
- cFYI(1, "%s: ses_count=%d\n", __func__, ses->ses_count);
- spin_lock(&cifs_tcp_ses_lock);
- if (--ses->ses_count > 0) {
- spin_unlock(&cifs_tcp_ses_lock);
- return;
- }
-
- list_del_init(&ses->smb_ses_list);
- spin_unlock(&cifs_tcp_ses_lock);
-
- if (ses->status == CifsGood) {
- xid = GetXid();
- CIFSSMBLogoff(xid, ses);
- _FreeXid(xid);
- }
- sesInfoFree(ses);
- cifs_put_tcp_session(server);
-}
-
-#ifdef CONFIG_KEYS
-
-/* strlen("cifs:a:") + INET6_ADDRSTRLEN + 1 */
-#define CIFSCREDS_DESC_SIZE (7 + INET6_ADDRSTRLEN + 1)
-
-/* Populate username and pw fields from keyring if possible */
-static int
-cifs_set_cifscreds(struct smb_vol *vol, struct cifs_ses *ses)
-{
- int rc = 0;
- char *desc, *delim, *payload;
- ssize_t len;
- struct key *key;
- struct TCP_Server_Info *server = ses->server;
- struct sockaddr_in *sa;
- struct sockaddr_in6 *sa6;
- struct user_key_payload *upayload;
-
- desc = kmalloc(CIFSCREDS_DESC_SIZE, GFP_KERNEL);
- if (!desc)
- return -ENOMEM;
-
- /* try to find an address key first */
- switch (server->dstaddr.ss_family) {
- case AF_INET:
- sa = (struct sockaddr_in *)&server->dstaddr;
- sprintf(desc, "cifs:a:%pI4", &sa->sin_addr.s_addr);
- break;
- case AF_INET6:
- sa6 = (struct sockaddr_in6 *)&server->dstaddr;
- sprintf(desc, "cifs:a:%pI6c", &sa6->sin6_addr.s6_addr);
- break;
- default:
- cFYI(1, "Bad ss_family (%hu)", server->dstaddr.ss_family);
- rc = -EINVAL;
- goto out_err;
- }
-
- cFYI(1, "%s: desc=%s", __func__, desc);
- key = request_key(&key_type_logon, desc, "");
- if (IS_ERR(key)) {
- if (!ses->domainName) {
- cFYI(1, "domainName is NULL");
- rc = PTR_ERR(key);
- goto out_err;
- }
-
- /* didn't work, try to find a domain key */
- sprintf(desc, "cifs:d:%s", ses->domainName);
- cFYI(1, "%s: desc=%s", __func__, desc);
- key = request_key(&key_type_logon, desc, "");
- if (IS_ERR(key)) {
- rc = PTR_ERR(key);
- goto out_err;
- }
- }
-
- down_read(&key->sem);
- upayload = key->payload.data;
- if (IS_ERR_OR_NULL(upayload)) {
- rc = upayload ? PTR_ERR(upayload) : -EINVAL;
- goto out_key_put;
- }
-
- /* find first : in payload */
- payload = (char *)upayload->data;
- delim = strnchr(payload, upayload->datalen, ':');
- cFYI(1, "payload=%s", payload);
- if (!delim) {
- cFYI(1, "Unable to find ':' in payload (datalen=%d)",
- upayload->datalen);
- rc = -EINVAL;
- goto out_key_put;
- }
-
- len = delim - payload;
- if (len > MAX_USERNAME_SIZE || len <= 0) {
- cFYI(1, "Bad value from username search (len=%zd)", len);
- rc = -EINVAL;
- goto out_key_put;
- }
-
- vol->username = kstrndup(payload, len, GFP_KERNEL);
- if (!vol->username) {
- cFYI(1, "Unable to allocate %zd bytes for username", len);
- rc = -ENOMEM;
- goto out_key_put;
- }
- cFYI(1, "%s: username=%s", __func__, vol->username);
-
- len = key->datalen - (len + 1);
- if (len > MAX_PASSWORD_SIZE || len <= 0) {
- cFYI(1, "Bad len for password search (len=%zd)", len);
- rc = -EINVAL;
- kfree(vol->username);
- vol->username = NULL;
- goto out_key_put;
- }
-
- ++delim;
- vol->password = kstrndup(delim, len, GFP_KERNEL);
- if (!vol->password) {
- cFYI(1, "Unable to allocate %zd bytes for password", len);
- rc = -ENOMEM;
- kfree(vol->username);
- vol->username = NULL;
- goto out_key_put;
- }
-
-out_key_put:
- up_read(&key->sem);
- key_put(key);
-out_err:
- kfree(desc);
- cFYI(1, "%s: returning %d", __func__, rc);
- return rc;
-}
-#else /* ! CONFIG_KEYS */
-static inline int
-cifs_set_cifscreds(struct smb_vol *vol __attribute__((unused)),
- struct cifs_ses *ses __attribute__((unused)))
-{
- return -ENOSYS;
-}
-#endif /* CONFIG_KEYS */
-
-static bool warned_on_ntlm; /* globals init to false automatically */
-
-static struct cifs_ses *
-cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
-{
- int rc = -ENOMEM, xid;
- struct cifs_ses *ses;
- struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
- struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr;
-
- xid = GetXid();
-
- ses = cifs_find_smb_ses(server, volume_info);
- if (ses) {
- cFYI(1, "Existing smb sess found (status=%d)", ses->status);
-
- mutex_lock(&ses->session_mutex);
- rc = cifs_negotiate_protocol(xid, ses);
- if (rc) {
- mutex_unlock(&ses->session_mutex);
- /* problem -- put our ses reference */
- cifs_put_smb_ses(ses);
- FreeXid(xid);
- return ERR_PTR(rc);
- }
- if (ses->need_reconnect) {
- cFYI(1, "Session needs reconnect");
- rc = cifs_setup_session(xid, ses,
- volume_info->local_nls);
- if (rc) {
- mutex_unlock(&ses->session_mutex);
- /* problem -- put our reference */
- cifs_put_smb_ses(ses);
- FreeXid(xid);
- return ERR_PTR(rc);
- }
- }
- mutex_unlock(&ses->session_mutex);
-
- /* existing SMB ses has a server reference already */
- cifs_put_tcp_session(server);
- FreeXid(xid);
- return ses;
- }
-
- cFYI(1, "Existing smb sess not found");
- ses = sesInfoAlloc();
- if (ses == NULL)
- goto get_ses_fail;
-
- /* new SMB session uses our server ref */
- ses->server = server;
- if (server->dstaddr.ss_family == AF_INET6)
- sprintf(ses->serverName, "%pI6", &addr6->sin6_addr);
- else
- sprintf(ses->serverName, "%pI4", &addr->sin_addr);
-
- if (volume_info->username) {
- ses->user_name = kstrdup(volume_info->username, GFP_KERNEL);
- if (!ses->user_name)
- goto get_ses_fail;
- }
-
- /* volume_info->password freed at unmount */
- if (volume_info->password) {
- ses->password = kstrdup(volume_info->password, GFP_KERNEL);
- if (!ses->password)
- goto get_ses_fail;
- }
- if (volume_info->domainname) {
- ses->domainName = kstrdup(volume_info->domainname, GFP_KERNEL);
- if (!ses->domainName)
- goto get_ses_fail;
- }
- ses->cred_uid = volume_info->cred_uid;
- ses->linux_uid = volume_info->linux_uid;
-
- /* ntlmv2 is much stronger than ntlm security, and has been broadly
- supported for many years, time to update default security mechanism */
- if ((volume_info->secFlg == 0) && warned_on_ntlm == false) {
- warned_on_ntlm = true;
- cERROR(1, "default security mechanism requested. The default "
- "security mechanism will be upgraded from ntlm to "
- "ntlmv2 in kernel release 3.3");
- }
- ses->overrideSecFlg = volume_info->secFlg;
-
- mutex_lock(&ses->session_mutex);
- rc = cifs_negotiate_protocol(xid, ses);
- if (!rc)
- rc = cifs_setup_session(xid, ses, volume_info->local_nls);
- mutex_unlock(&ses->session_mutex);
- if (rc)
- goto get_ses_fail;
-
- /* success, put it on the list */
- spin_lock(&cifs_tcp_ses_lock);
- list_add(&ses->smb_ses_list, &server->smb_ses_list);
- spin_unlock(&cifs_tcp_ses_lock);
-
- FreeXid(xid);
- return ses;
-
-get_ses_fail:
- sesInfoFree(ses);
- FreeXid(xid);
- return ERR_PTR(rc);
-}
-
-static int match_tcon(struct cifs_tcon *tcon, const char *unc)
-{
- if (tcon->tidStatus == CifsExiting)
- return 0;
- if (strncmp(tcon->treeName, unc, MAX_TREE_SIZE))
- return 0;
- return 1;
-}
-
-static struct cifs_tcon *
-cifs_find_tcon(struct cifs_ses *ses, const char *unc)
-{
- struct list_head *tmp;
- struct cifs_tcon *tcon;
-
- spin_lock(&cifs_tcp_ses_lock);
- list_for_each(tmp, &ses->tcon_list) {
- tcon = list_entry(tmp, struct cifs_tcon, tcon_list);
- if (!match_tcon(tcon, unc))
- continue;
- ++tcon->tc_count;
- spin_unlock(&cifs_tcp_ses_lock);
- return tcon;
- }
- spin_unlock(&cifs_tcp_ses_lock);
- return NULL;
-}
-
-static void
-cifs_put_tcon(struct cifs_tcon *tcon)
-{
- int xid;
- struct cifs_ses *ses = tcon->ses;
-
- cFYI(1, "%s: tc_count=%d\n", __func__, tcon->tc_count);
- spin_lock(&cifs_tcp_ses_lock);
- if (--tcon->tc_count > 0) {
- spin_unlock(&cifs_tcp_ses_lock);
- return;
- }
-
- list_del_init(&tcon->tcon_list);
- spin_unlock(&cifs_tcp_ses_lock);
-
- xid = GetXid();
- CIFSSMBTDis(xid, tcon);
- _FreeXid(xid);
-
- cifs_fscache_release_super_cookie(tcon);
- tconInfoFree(tcon);
- cifs_put_smb_ses(ses);
-}
-
-static struct cifs_tcon *
-cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
-{
- int rc, xid;
- struct cifs_tcon *tcon;
-
- tcon = cifs_find_tcon(ses, volume_info->UNC);
- if (tcon) {
- cFYI(1, "Found match on UNC path");
- /* existing tcon already has a reference */
- cifs_put_smb_ses(ses);
- if (tcon->seal != volume_info->seal)
- cERROR(1, "transport encryption setting "
- "conflicts with existing tid");
- return tcon;
- }
-
- tcon = tconInfoAlloc();
- if (tcon == NULL) {
- rc = -ENOMEM;
- goto out_fail;
- }
-
- tcon->ses = ses;
- if (volume_info->password) {
- tcon->password = kstrdup(volume_info->password, GFP_KERNEL);
- if (!tcon->password) {
- rc = -ENOMEM;
- goto out_fail;
- }
- }
-
- if (strchr(volume_info->UNC + 3, '\\') == NULL
- && strchr(volume_info->UNC + 3, '/') == NULL) {
- cERROR(1, "Missing share name");
- rc = -ENODEV;
- goto out_fail;
- }
-
- /* BB Do we need to wrap session_mutex around
- * this TCon call and Unix SetFS as
- * we do on SessSetup and reconnect? */
- xid = GetXid();
- rc = CIFSTCon(xid, ses, volume_info->UNC, tcon, volume_info->local_nls);
- FreeXid(xid);
- cFYI(1, "CIFS Tcon rc = %d", rc);
- if (rc)
- goto out_fail;
-
- if (volume_info->nodfs) {
- tcon->Flags &= ~SMB_SHARE_IS_IN_DFS;
- cFYI(1, "DFS disabled (%d)", tcon->Flags);
- }
- tcon->seal = volume_info->seal;
- /* we can have only one retry value for a connection
- to a share so for resources mounted more than once
- to the same server share the last value passed in
- for the retry flag is used */
- tcon->retry = volume_info->retry;
- tcon->nocase = volume_info->nocase;
- tcon->local_lease = volume_info->local_lease;
-
- spin_lock(&cifs_tcp_ses_lock);
- list_add(&tcon->tcon_list, &ses->tcon_list);
- spin_unlock(&cifs_tcp_ses_lock);
-
- cifs_fscache_get_super_cookie(tcon);
-
- return tcon;
-
-out_fail:
- tconInfoFree(tcon);
- return ERR_PTR(rc);
-}
-
-void
-cifs_put_tlink(struct tcon_link *tlink)
-{
- if (!tlink || IS_ERR(tlink))
- return;
-
- if (!atomic_dec_and_test(&tlink->tl_count) ||
- test_bit(TCON_LINK_IN_TREE, &tlink->tl_flags)) {
- tlink->tl_time = jiffies;
- return;
- }
-
- if (!IS_ERR(tlink_tcon(tlink)))
- cifs_put_tcon(tlink_tcon(tlink));
- kfree(tlink);
- return;
-}
-
-static inline struct tcon_link *
-cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb)
-{
- return cifs_sb->master_tlink;
-}
-
-static int
-compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data)
-{
- struct cifs_sb_info *old = CIFS_SB(sb);
- struct cifs_sb_info *new = mnt_data->cifs_sb;
-
- if ((sb->s_flags & CIFS_MS_MASK) != (mnt_data->flags & CIFS_MS_MASK))
- return 0;
-
- if ((old->mnt_cifs_flags & CIFS_MOUNT_MASK) !=
- (new->mnt_cifs_flags & CIFS_MOUNT_MASK))
- return 0;
-
- /*
- * We want to share sb only if we don't specify an r/wsize or
- * specified r/wsize is greater than or equal to existing one.
- */
- if (new->wsize && new->wsize < old->wsize)
- return 0;
-
- if (new->rsize && new->rsize < old->rsize)
- return 0;
-
- if (old->mnt_uid != new->mnt_uid || old->mnt_gid != new->mnt_gid)
- return 0;
-
- if (old->mnt_file_mode != new->mnt_file_mode ||
- old->mnt_dir_mode != new->mnt_dir_mode)
- return 0;
-
- if (strcmp(old->local_nls->charset, new->local_nls->charset))
- return 0;
-
- if (old->actimeo != new->actimeo)
- return 0;
-
- return 1;
-}
-
-int
-cifs_match_super(struct super_block *sb, void *data)
-{
- struct cifs_mnt_data *mnt_data = (struct cifs_mnt_data *)data;
- struct smb_vol *volume_info;
- struct cifs_sb_info *cifs_sb;
- struct TCP_Server_Info *tcp_srv;
- struct cifs_ses *ses;
- struct cifs_tcon *tcon;
- struct tcon_link *tlink;
- struct sockaddr_storage addr;
- int rc = 0;
-
- memset(&addr, 0, sizeof(struct sockaddr_storage));
-
- spin_lock(&cifs_tcp_ses_lock);
- cifs_sb = CIFS_SB(sb);
- tlink = cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));
- if (IS_ERR(tlink)) {
- spin_unlock(&cifs_tcp_ses_lock);
- return rc;
- }
- tcon = tlink_tcon(tlink);
- ses = tcon->ses;
- tcp_srv = ses->server;
-
- volume_info = mnt_data->vol;
-
- if (!volume_info->UNCip || !volume_info->UNC)
- goto out;
-
- rc = cifs_fill_sockaddr((struct sockaddr *)&addr,
- volume_info->UNCip,
- strlen(volume_info->UNCip),
- volume_info->port);
- if (!rc)
- goto out;
-
- if (!match_server(tcp_srv, (struct sockaddr *)&addr, volume_info) ||
- !match_session(ses, volume_info) ||
- !match_tcon(tcon, volume_info->UNC)) {
- rc = 0;
- goto out;
- }
-
- rc = compare_mount_options(sb, mnt_data);
-out:
- spin_unlock(&cifs_tcp_ses_lock);
- cifs_put_tlink(tlink);
- return rc;
-}
-
-int
-get_dfs_path(int xid, struct cifs_ses *pSesInfo, const char *old_path,
- const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
- struct dfs_info3_param **preferrals, int remap)
-{
- char *temp_unc;
- int rc = 0;
-
- *pnum_referrals = 0;
- *preferrals = NULL;
-
- if (pSesInfo->ipc_tid == 0) {
- temp_unc = kmalloc(2 /* for slashes */ +
- strnlen(pSesInfo->serverName,
- SERVER_NAME_LEN_WITH_NULL * 2)
- + 1 + 4 /* slash IPC$ */ + 2,
- GFP_KERNEL);
- if (temp_unc == NULL)
- return -ENOMEM;
- temp_unc[0] = '\\';
- temp_unc[1] = '\\';
- strcpy(temp_unc + 2, pSesInfo->serverName);
- strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$");
- rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);
- cFYI(1, "CIFS Tcon rc = %d ipc_tid = %d", rc, pSesInfo->ipc_tid);
- kfree(temp_unc);
- }
- if (rc == 0)
- rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,
- pnum_referrals, nls_codepage, remap);
- /* BB map targetUNCs to dfs_info3 structures, here or
- in CIFSGetDFSRefer BB */
-
- return rc;
-}
-
-#ifdef CONFIG_DEBUG_LOCK_ALLOC
-static struct lock_class_key cifs_key[2];
-static struct lock_class_key cifs_slock_key[2];
-
-static inline void
-cifs_reclassify_socket4(struct socket *sock)
-{
- struct sock *sk = sock->sk;
- BUG_ON(sock_owned_by_user(sk));
- sock_lock_init_class_and_name(sk, "slock-AF_INET-CIFS",
- &cifs_slock_key[0], "sk_lock-AF_INET-CIFS", &cifs_key[0]);
-}
-
-static inline void
-cifs_reclassify_socket6(struct socket *sock)
-{
- struct sock *sk = sock->sk;
- BUG_ON(sock_owned_by_user(sk));
- sock_lock_init_class_and_name(sk, "slock-AF_INET6-CIFS",
- &cifs_slock_key[1], "sk_lock-AF_INET6-CIFS", &cifs_key[1]);
-}
-#else
-static inline void
-cifs_reclassify_socket4(struct socket *sock)
-{
-}
-
-static inline void
-cifs_reclassify_socket6(struct socket *sock)
-{
-}
-#endif
-
-/* See RFC1001 section 14 on representation of Netbios names */
-static void rfc1002mangle(char *target, char *source, unsigned int length)
-{
- unsigned int i, j;
-
- for (i = 0, j = 0; i < (length); i++) {
- /* mask a nibble at a time and encode */
- target[j] = 'A' + (0x0F & (source[i] >> 4));
- target[j+1] = 'A' + (0x0F & source[i]);
- j += 2;
- }
-
-}
-
-static int
-bind_socket(struct TCP_Server_Info *server)
-{
- int rc = 0;
- if (server->srcaddr.ss_family != AF_UNSPEC) {
- /* Bind to the specified local IP address */
- struct socket *socket = server->ssocket;
- rc = socket->ops->bind(socket,
- (struct sockaddr *) &server->srcaddr,
- sizeof(server->srcaddr));
- if (rc < 0) {
- struct sockaddr_in *saddr4;
- struct sockaddr_in6 *saddr6;
- saddr4 = (struct sockaddr_in *)&server->srcaddr;
- saddr6 = (struct sockaddr_in6 *)&server->srcaddr;
- if (saddr6->sin6_family == AF_INET6)
- cERROR(1, "cifs: "
- "Failed to bind to: %pI6c, error: %d\n",
- &saddr6->sin6_addr, rc);
- else
- cERROR(1, "cifs: "
- "Failed to bind to: %pI4, error: %d\n",
- &saddr4->sin_addr.s_addr, rc);
- }
- }
- return rc;
-}
-
-static int
-ip_rfc1001_connect(struct TCP_Server_Info *server)
-{
- int rc = 0;
- /*
- * some servers require RFC1001 sessinit before sending
- * negprot - BB check reconnection in case where second
- * sessinit is sent but no second negprot
- */
- struct rfc1002_session_packet *ses_init_buf;
- struct smb_hdr *smb_buf;
- ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
- GFP_KERNEL);
- if (ses_init_buf) {
- ses_init_buf->trailer.session_req.called_len = 32;
-
- if (server->server_RFC1001_name &&
- server->server_RFC1001_name[0] != 0)
- rfc1002mangle(ses_init_buf->trailer.
- session_req.called_name,
- server->server_RFC1001_name,
- RFC1001_NAME_LEN_WITH_NULL);
- else
- rfc1002mangle(ses_init_buf->trailer.
- session_req.called_name,
- DEFAULT_CIFS_CALLED_NAME,
- RFC1001_NAME_LEN_WITH_NULL);
-
- ses_init_buf->trailer.session_req.calling_len = 32;
-
- /*
- * calling name ends in null (byte 16) from old smb
- * convention.
- */
- if (server->workstation_RFC1001_name &&
- server->workstation_RFC1001_name[0] != 0)
- rfc1002mangle(ses_init_buf->trailer.
- session_req.calling_name,
- server->workstation_RFC1001_name,
- RFC1001_NAME_LEN_WITH_NULL);
- else
- rfc1002mangle(ses_init_buf->trailer.
- session_req.calling_name,
- "LINUX_CIFS_CLNT",
- RFC1001_NAME_LEN_WITH_NULL);
-
- ses_init_buf->trailer.session_req.scope1 = 0;
- ses_init_buf->trailer.session_req.scope2 = 0;
- smb_buf = (struct smb_hdr *)ses_init_buf;
-
- /* sizeof RFC1002_SESSION_REQUEST with no scope */
- smb_buf->smb_buf_length = cpu_to_be32(0x81000044);
- rc = smb_send(server, smb_buf, 0x44);
- kfree(ses_init_buf);
- /*
- * RFC1001 layer in at least one server
- * requires very short break before negprot
- * presumably because not expecting negprot
- * to follow so fast. This is a simple
- * solution that works without
- * complicating the code and causes no
- * significant slowing down on mount
- * for everyone else
- */
- usleep_range(1000, 2000);
- }
- /*
- * else the negprot may still work without this
- * even though malloc failed
- */
-
- return rc;
-}
-
-static int
-generic_ip_connect(struct TCP_Server_Info *server)
-{
- int rc = 0;
- __be16 sport;
- int slen, sfamily;
- struct socket *socket = server->ssocket;
- struct sockaddr *saddr;
-
- saddr = (struct sockaddr *) &server->dstaddr;
-
- if (server->dstaddr.ss_family == AF_INET6) {
- sport = ((struct sockaddr_in6 *) saddr)->sin6_port;
- slen = sizeof(struct sockaddr_in6);
- sfamily = AF_INET6;
- } else {
- sport = ((struct sockaddr_in *) saddr)->sin_port;
- slen = sizeof(struct sockaddr_in);
- sfamily = AF_INET;
- }
-
- if (socket == NULL) {
- rc = __sock_create(cifs_net_ns(server), sfamily, SOCK_STREAM,
- IPPROTO_TCP, &socket, 1);
- if (rc < 0) {
- cERROR(1, "Error %d creating socket", rc);
- server->ssocket = NULL;
- return rc;
- }
-
- /* BB other socket options to set KEEPALIVE, NODELAY? */
- cFYI(1, "Socket created");
- server->ssocket = socket;
- socket->sk->sk_allocation = GFP_NOFS;
- if (sfamily == AF_INET6)
- cifs_reclassify_socket6(socket);
- else
- cifs_reclassify_socket4(socket);
- }
-
- rc = bind_socket(server);
- if (rc < 0)
- return rc;
-
- /*
- * Eventually check for other socket options to change from
- * the default. sock_setsockopt not used because it expects
- * user space buffer
- */
- socket->sk->sk_rcvtimeo = 7 * HZ;
- socket->sk->sk_sndtimeo = 5 * HZ;
-
- /* make the bufsizes depend on wsize/rsize and max requests */
- if (server->noautotune) {
- if (socket->sk->sk_sndbuf < (200 * 1024))
- socket->sk->sk_sndbuf = 200 * 1024;
- if (socket->sk->sk_rcvbuf < (140 * 1024))
- socket->sk->sk_rcvbuf = 140 * 1024;
- }
-
- if (server->tcp_nodelay) {
- int val = 1;
- rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
- (char *)&val, sizeof(val));
- if (rc)
- cFYI(1, "set TCP_NODELAY socket option error %d", rc);
- }
-
- cFYI(1, "sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
- socket->sk->sk_sndbuf,
- socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo);
-
- rc = socket->ops->connect(socket, saddr, slen, 0);
- if (rc < 0) {
- cFYI(1, "Error %d connecting to server", rc);
- sock_release(socket);
- server->ssocket = NULL;
- return rc;
- }
-
- if (sport == htons(RFC1001_PORT))
- rc = ip_rfc1001_connect(server);
-
- return rc;
-}
-
-static int
-ip_connect(struct TCP_Server_Info *server)
-{
- __be16 *sport;
- struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr;
- struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
-
- if (server->dstaddr.ss_family == AF_INET6)
- sport = &addr6->sin6_port;
- else
- sport = &addr->sin_port;
-
- if (*sport == 0) {
- int rc;
-
- /* try with 445 port at first */
- *sport = htons(CIFS_PORT);
-
- rc = generic_ip_connect(server);
- if (rc >= 0)
- return rc;
-
- /* if it failed, try with 139 port */
- *sport = htons(RFC1001_PORT);
- }
-
- return generic_ip_connect(server);
-}
-
-void reset_cifs_unix_caps(int xid, struct cifs_tcon *tcon,
- struct cifs_sb_info *cifs_sb, struct smb_vol *vol_info)
-{
- /* if we are reconnecting then should we check to see if
- * any requested capabilities changed locally e.g. via
- * remount but we can not do much about it here
- * if they have (even if we could detect it by the following)
- * Perhaps we could add a backpointer to array of sb from tcon
- * or if we change to make all sb to same share the same
- * sb as NFS - then we only have one backpointer to sb.
- * What if we wanted to mount the server share twice once with
- * and once without posixacls or posix paths? */
- __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
-
- if (vol_info && vol_info->no_linux_ext) {
- tcon->fsUnixInfo.Capability = 0;
- tcon->unix_ext = 0; /* Unix Extensions disabled */
- cFYI(1, "Linux protocol extensions disabled");
- return;
- } else if (vol_info)
- tcon->unix_ext = 1; /* Unix Extensions supported */
-
- if (tcon->unix_ext == 0) {
- cFYI(1, "Unix extensions disabled so not set on reconnect");
- return;
- }
-
- if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
- __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
- cFYI(1, "unix caps which server supports %lld", cap);
- /* check for reconnect case in which we do not
- want to change the mount behavior if we can avoid it */
- if (vol_info == NULL) {
- /* turn off POSIX ACL and PATHNAMES if not set
- originally at mount time */
- if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
- cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
- if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
- if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
- cERROR(1, "POSIXPATH support change");
- cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
- } else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
- cERROR(1, "possible reconnect error");
- cERROR(1, "server disabled POSIX path support");
- }
- }
-
- if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)
- cERROR(1, "per-share encryption not supported yet");
-
- cap &= CIFS_UNIX_CAP_MASK;
- if (vol_info && vol_info->no_psx_acl)
- cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
- else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
- cFYI(1, "negotiated posix acl support");
- if (cifs_sb)
- cifs_sb->mnt_cifs_flags |=
- CIFS_MOUNT_POSIXACL;
- }
-
- if (vol_info && vol_info->posix_paths == 0)
- cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
- else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
- cFYI(1, "negotiate posix pathnames");
- if (cifs_sb)
- cifs_sb->mnt_cifs_flags |=
- CIFS_MOUNT_POSIX_PATHS;
- }
-
- cFYI(1, "Negotiate caps 0x%x", (int)cap);
-#ifdef CONFIG_CIFS_DEBUG2
- if (cap & CIFS_UNIX_FCNTL_CAP)
- cFYI(1, "FCNTL cap");
- if (cap & CIFS_UNIX_EXTATTR_CAP)
- cFYI(1, "EXTATTR cap");
- if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
- cFYI(1, "POSIX path cap");
- if (cap & CIFS_UNIX_XATTR_CAP)
- cFYI(1, "XATTR cap");
- if (cap & CIFS_UNIX_POSIX_ACL_CAP)
- cFYI(1, "POSIX ACL cap");
- if (cap & CIFS_UNIX_LARGE_READ_CAP)
- cFYI(1, "very large read cap");
- if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
- cFYI(1, "very large write cap");
- if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)
- cFYI(1, "transport encryption cap");
- if (cap & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)
- cFYI(1, "mandatory transport encryption cap");
-#endif /* CIFS_DEBUG2 */
- if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
- if (vol_info == NULL) {
- cFYI(1, "resetting capabilities failed");
- } else
- cERROR(1, "Negotiating Unix capabilities "
- "with the server failed. Consider "
- "mounting with the Unix Extensions\n"
- "disabled, if problems are found, "
- "by specifying the nounix mount "
- "option.");
-
- }
- }
-}
-
-void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
- struct cifs_sb_info *cifs_sb)
-{
- INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks);
-
- spin_lock_init(&cifs_sb->tlink_tree_lock);
- cifs_sb->tlink_tree = RB_ROOT;
-
- /*
- * Temporarily set r/wsize for matching superblock. If we end up using
- * new sb then client will later negotiate it downward if needed.
- */
- cifs_sb->rsize = pvolume_info->rsize;
- cifs_sb->wsize = pvolume_info->wsize;
-
- cifs_sb->mnt_uid = pvolume_info->linux_uid;
- cifs_sb->mnt_gid = pvolume_info->linux_gid;
- cifs_sb->mnt_file_mode = pvolume_info->file_mode;
- cifs_sb->mnt_dir_mode = pvolume_info->dir_mode;
- cFYI(1, "file mode: 0x%hx dir mode: 0x%hx",
- cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode);
-
- cifs_sb->actimeo = pvolume_info->actimeo;
- cifs_sb->local_nls = pvolume_info->local_nls;
-
- if (pvolume_info->noperm)
- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
- if (pvolume_info->setuids)
- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
- if (pvolume_info->server_ino)
- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
- if (pvolume_info->remap)
- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
- if (pvolume_info->no_xattr)
- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
- if (pvolume_info->sfu_emul)
- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
- if (pvolume_info->nobrl)
- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
- if (pvolume_info->nostrictsync)
- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOSSYNC;
- if (pvolume_info->mand_lock)
- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL;
- if (pvolume_info->rwpidforward)
- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RWPIDFORWARD;
- if (pvolume_info->cifs_acl)
- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
- if (pvolume_info->backupuid_specified) {
- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPUID;
- cifs_sb->mnt_backupuid = pvolume_info->backupuid;
- }
- if (pvolume_info->backupgid_specified) {
- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPGID;
- cifs_sb->mnt_backupgid = pvolume_info->backupgid;
- }
- if (pvolume_info->override_uid)
- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
- if (pvolume_info->override_gid)
- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
- if (pvolume_info->dynperm)
- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
- if (pvolume_info->fsc)
- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE;
- if (pvolume_info->multiuser)
- cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_MULTIUSER |
- CIFS_MOUNT_NO_PERM);
- if (pvolume_info->strict_io)
- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_STRICT_IO;
- if (pvolume_info->direct_io) {
- cFYI(1, "mounting share using direct i/o");
- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
- }
- if (pvolume_info->mfsymlinks) {
- if (pvolume_info->sfu_emul) {
- cERROR(1, "mount option mfsymlinks ignored if sfu "
- "mount option is used");
- } else {
- cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MF_SYMLINKS;
- }
- }
-
- if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm))
- cERROR(1, "mount option dynperm ignored if cifsacl "
- "mount option supported");
-}
-
-/*
- * When the server supports very large reads and writes via POSIX extensions,
- * we can allow up to 2^24-1, minus the size of a READ/WRITE_AND_X header, not
- * including the RFC1001 length.
- *
- * Note that this might make for "interesting" allocation problems during
- * writeback however as we have to allocate an array of pointers for the
- * pages. A 16M write means ~32kb page array with PAGE_CACHE_SIZE == 4096.
- *
- * For reads, there is a similar problem as we need to allocate an array
- * of kvecs to handle the receive, though that should only need to be done
- * once.
- */
-#define CIFS_MAX_WSIZE ((1<<24) - 1 - sizeof(WRITE_REQ) + 4)
-#define CIFS_MAX_RSIZE ((1<<24) - sizeof(READ_RSP) + 4)
-
-/*
- * When the server doesn't allow large posix writes, only allow a rsize/wsize
- * of 2^17-1 minus the size of the call header. That allows for a read or
- * write up to the maximum size described by RFC1002.
- */
-#define CIFS_MAX_RFC1002_WSIZE ((1<<17) - 1 - sizeof(WRITE_REQ) + 4)
-#define CIFS_MAX_RFC1002_RSIZE ((1<<17) - 1 - sizeof(READ_RSP) + 4)
-
-/*
- * The default wsize is 1M. find_get_pages seems to return a maximum of 256
- * pages in a single call. With PAGE_CACHE_SIZE == 4k, this means we can fill
- * a single wsize request with a single call.
- */
-#define CIFS_DEFAULT_IOSIZE (1024 * 1024)
-
-/*
- * Windows only supports a max of 60kb reads and 65535 byte writes. Default to
- * those values when posix extensions aren't in force. In actuality here, we
- * use 65536 to allow for a write that is a multiple of 4k. Most servers seem
- * to be ok with the extra byte even though Windows doesn't send writes that
- * are that large.
- *
- * Citation:
- *
- * http://blogs.msdn.com/b/openspecification/archive/2009/04/10/smb-maximum-transmit-buffer-size-and-performance-tuning.aspx
- */
-#define CIFS_DEFAULT_NON_POSIX_RSIZE (60 * 1024)
-#define CIFS_DEFAULT_NON_POSIX_WSIZE (65536)
-
-static unsigned int
-cifs_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info)
-{
- __u64 unix_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
- struct TCP_Server_Info *server = tcon->ses->server;
- unsigned int wsize;
-
- /* start with specified wsize, or default */
- if (pvolume_info->wsize)
- wsize = pvolume_info->wsize;
- else if (tcon->unix_ext && (unix_cap & CIFS_UNIX_LARGE_WRITE_CAP))
- wsize = CIFS_DEFAULT_IOSIZE;
- else
- wsize = CIFS_DEFAULT_NON_POSIX_WSIZE;
-
- /* can server support 24-bit write sizes? (via UNIX extensions) */
- if (!tcon->unix_ext || !(unix_cap & CIFS_UNIX_LARGE_WRITE_CAP))
- wsize = min_t(unsigned int, wsize, CIFS_MAX_RFC1002_WSIZE);
-
- /*
- * no CAP_LARGE_WRITE_X or is signing enabled without CAP_UNIX set?
- * Limit it to max buffer offered by the server, minus the size of the
- * WRITEX header, not including the 4 byte RFC1001 length.
- */
- if (!(server->capabilities & CAP_LARGE_WRITE_X) ||
- (!(server->capabilities & CAP_UNIX) &&
- (server->sec_mode & (SECMODE_SIGN_ENABLED|SECMODE_SIGN_REQUIRED))))
- wsize = min_t(unsigned int, wsize,
- server->maxBuf - sizeof(WRITE_REQ) + 4);
-
- /* hard limit of CIFS_MAX_WSIZE */
- wsize = min_t(unsigned int, wsize, CIFS_MAX_WSIZE);
-
- return wsize;
-}
-
-static unsigned int
-cifs_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *pvolume_info)
-{
- __u64 unix_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
- struct TCP_Server_Info *server = tcon->ses->server;
- unsigned int rsize, defsize;
-
- /*
- * Set default value...
- *
- * HACK alert! Ancient servers have very small buffers. Even though
- * MS-CIFS indicates that servers are only limited by the client's
- * bufsize for reads, testing against win98se shows that it throws
- * INVALID_PARAMETER errors if you try to request too large a read.
- * OS/2 just sends back short reads.
- *
- * If the server doesn't advertise CAP_LARGE_READ_X, then assume that
- * it can't handle a read request larger than its MaxBufferSize either.
- */
- if (tcon->unix_ext && (unix_cap & CIFS_UNIX_LARGE_READ_CAP))
- defsize = CIFS_DEFAULT_IOSIZE;
- else if (server->capabilities & CAP_LARGE_READ_X)
- defsize = CIFS_DEFAULT_NON_POSIX_RSIZE;
- else
- defsize = server->maxBuf - sizeof(READ_RSP);
-
- rsize = pvolume_info->rsize ? pvolume_info->rsize : defsize;
-
- /*
- * no CAP_LARGE_READ_X? Then MS-CIFS states that we must limit this to
- * the client's MaxBufferSize.
- */
- if (!(server->capabilities & CAP_LARGE_READ_X))
- rsize = min_t(unsigned int, CIFSMaxBufSize, rsize);
-
- /* hard limit of CIFS_MAX_RSIZE */
- rsize = min_t(unsigned int, rsize, CIFS_MAX_RSIZE);
-
- return rsize;
-}
-
-static int
-is_path_accessible(int xid, struct cifs_tcon *tcon,
- struct cifs_sb_info *cifs_sb, const char *full_path)
-{
- int rc;
- FILE_ALL_INFO *pfile_info;
-
- pfile_info = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
- if (pfile_info == NULL)
- return -ENOMEM;
-
- rc = CIFSSMBQPathInfo(xid, tcon, full_path, pfile_info,
- 0 /* not legacy */, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
-
- if (rc == -EOPNOTSUPP || rc == -EINVAL)
- rc = SMBQueryInformation(xid, tcon, full_path, pfile_info,
- cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- kfree(pfile_info);
- return rc;
-}
-
-static void
-cleanup_volume_info_contents(struct smb_vol *volume_info)
-{
- kfree(volume_info->username);
- kzfree(volume_info->password);
- if (volume_info->UNCip != volume_info->UNC + 2)
- kfree(volume_info->UNCip);
- kfree(volume_info->UNC);
- kfree(volume_info->domainname);
- kfree(volume_info->iocharset);
- kfree(volume_info->prepath);
-}
-
-void
-cifs_cleanup_volume_info(struct smb_vol *volume_info)
-{
- if (!volume_info)
- return;
- cleanup_volume_info_contents(volume_info);
- kfree(volume_info);
-}
-
-
-#ifdef CONFIG_CIFS_DFS_UPCALL
-/* build_path_to_root returns full path to root when
- * we do not have an exiting connection (tcon) */
-static char *
-build_unc_path_to_root(const struct smb_vol *vol,
- const struct cifs_sb_info *cifs_sb)
-{
- char *full_path, *pos;
- unsigned int pplen = vol->prepath ? strlen(vol->prepath) : 0;
- unsigned int unc_len = strnlen(vol->UNC, MAX_TREE_SIZE + 1);
-
- full_path = kmalloc(unc_len + pplen + 1, GFP_KERNEL);
- if (full_path == NULL)
- return ERR_PTR(-ENOMEM);
-
- strncpy(full_path, vol->UNC, unc_len);
- pos = full_path + unc_len;
-
- if (pplen) {
- strncpy(pos, vol->prepath, pplen);
- pos += pplen;
- }
-
- *pos = '\0'; /* add trailing null */
- convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb));
- cFYI(1, "%s: full_path=%s", __func__, full_path);
- return full_path;
-}
-
-/*
- * Perform a dfs referral query for a share and (optionally) prefix
- *
- * If a referral is found, cifs_sb->mountdata will be (re-)allocated
- * to a string containing updated options for the submount. Otherwise it
- * will be left untouched.
- *
- * Returns the rc from get_dfs_path to the caller, which can be used to
- * determine whether there were referrals.
- */
-static int
-expand_dfs_referral(int xid, struct cifs_ses *pSesInfo,
- struct smb_vol *volume_info, struct cifs_sb_info *cifs_sb,
- int check_prefix)
-{
- int rc;
- unsigned int num_referrals = 0;
- struct dfs_info3_param *referrals = NULL;
- char *full_path = NULL, *ref_path = NULL, *mdata = NULL;
-
- full_path = build_unc_path_to_root(volume_info, cifs_sb);
- if (IS_ERR(full_path))
- return PTR_ERR(full_path);
-
- /* For DFS paths, skip the first '\' of the UNC */
- ref_path = check_prefix ? full_path + 1 : volume_info->UNC + 1;
-
- rc = get_dfs_path(xid, pSesInfo , ref_path, cifs_sb->local_nls,
- &num_referrals, &referrals,
- cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
-
- if (!rc && num_referrals > 0) {
- char *fake_devname = NULL;
-
- mdata = cifs_compose_mount_options(cifs_sb->mountdata,
- full_path + 1, referrals,
- &fake_devname);
-
- free_dfs_info_array(referrals, num_referrals);
-
- if (IS_ERR(mdata)) {
- rc = PTR_ERR(mdata);
- mdata = NULL;
- } else {
- cleanup_volume_info_contents(volume_info);
- memset(volume_info, '\0', sizeof(*volume_info));
- rc = cifs_setup_volume_info(volume_info, mdata,
- fake_devname);
- }
- kfree(fake_devname);
- kfree(cifs_sb->mountdata);
- cifs_sb->mountdata = mdata;
- }
- kfree(full_path);
- return rc;
-}
-#endif
-
-static int
-cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data,
- const char *devname)
-{
- int rc = 0;
-
- if (cifs_parse_mount_options(mount_data, devname, volume_info))
- return -EINVAL;
-
- if (volume_info->nullauth) {
- cFYI(1, "Anonymous login");
- kfree(volume_info->username);
- volume_info->username = NULL;
- } else if (volume_info->username) {
- /* BB fixme parse for domain name here */
- cFYI(1, "Username: %s", volume_info->username);
- } else {
- cifserror("No username specified");
- /* In userspace mount helper we can get user name from alternate
- locations such as env variables and files on disk */
- return -EINVAL;
- }
-
- /* this is needed for ASCII cp to Unicode converts */
- if (volume_info->iocharset == NULL) {
- /* load_nls_default cannot return null */
- volume_info->local_nls = load_nls_default();
- } else {
- volume_info->local_nls = load_nls(volume_info->iocharset);
- if (volume_info->local_nls == NULL) {
- cERROR(1, "CIFS mount error: iocharset %s not found",
- volume_info->iocharset);
- return -ELIBACC;
- }
- }
-
- return rc;
-}
-
-struct smb_vol *
-cifs_get_volume_info(char *mount_data, const char *devname)
-{
- int rc;
- struct smb_vol *volume_info;
-
- volume_info = kzalloc(sizeof(struct smb_vol), GFP_KERNEL);
- if (!volume_info)
- return ERR_PTR(-ENOMEM);
-
- rc = cifs_setup_volume_info(volume_info, mount_data, devname);
- if (rc) {
- cifs_cleanup_volume_info(volume_info);
- volume_info = ERR_PTR(rc);
- }
-
- return volume_info;
-}
-
-int
-cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info)
-{
- int rc;
- int xid;
- struct cifs_ses *pSesInfo;
- struct cifs_tcon *tcon;
- struct TCP_Server_Info *srvTcp;
- char *full_path;
- struct tcon_link *tlink;
-#ifdef CONFIG_CIFS_DFS_UPCALL
- int referral_walks_count = 0;
-#endif
-
- rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY);
- if (rc)
- return rc;
-
-#ifdef CONFIG_CIFS_DFS_UPCALL
-try_mount_again:
- /* cleanup activities if we're chasing a referral */
- if (referral_walks_count) {
- if (tcon)
- cifs_put_tcon(tcon);
- else if (pSesInfo)
- cifs_put_smb_ses(pSesInfo);
-
- FreeXid(xid);
- }
-#endif
- rc = 0;
- tcon = NULL;
- pSesInfo = NULL;
- srvTcp = NULL;
- full_path = NULL;
- tlink = NULL;
-
- xid = GetXid();
-
- /* get a reference to a tcp session */
- srvTcp = cifs_get_tcp_session(volume_info);
- if (IS_ERR(srvTcp)) {
- rc = PTR_ERR(srvTcp);
- bdi_destroy(&cifs_sb->bdi);
- goto out;
- }
-
- /* get a reference to a SMB session */
- pSesInfo = cifs_get_smb_ses(srvTcp, volume_info);
- if (IS_ERR(pSesInfo)) {
- rc = PTR_ERR(pSesInfo);
- pSesInfo = NULL;
- goto mount_fail_check;
- }
-
- /* search for existing tcon to this server share */
- tcon = cifs_get_tcon(pSesInfo, volume_info);
- if (IS_ERR(tcon)) {
- rc = PTR_ERR(tcon);
- tcon = NULL;
- goto remote_path_check;
- }
-
- /* tell server which Unix caps we support */
- if (tcon->ses->capabilities & CAP_UNIX) {
- /* reset of caps checks mount to see if unix extensions
- disabled for just this mount */
- reset_cifs_unix_caps(xid, tcon, cifs_sb, volume_info);
- if ((tcon->ses->server->tcpStatus == CifsNeedReconnect) &&
- (le64_to_cpu(tcon->fsUnixInfo.Capability) &
- CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP)) {
- rc = -EACCES;
- goto mount_fail_check;
- }
- } else
- tcon->unix_ext = 0; /* server does not support them */
-
- /* do not care if following two calls succeed - informational */
- if (!tcon->ipc) {
- CIFSSMBQFSDeviceInfo(xid, tcon);
- CIFSSMBQFSAttributeInfo(xid, tcon);
- }
-
- cifs_sb->wsize = cifs_negotiate_wsize(tcon, volume_info);
- cifs_sb->rsize = cifs_negotiate_rsize(tcon, volume_info);
-
- /* tune readahead according to rsize */
- cifs_sb->bdi.ra_pages = cifs_sb->rsize / PAGE_CACHE_SIZE;
-
-remote_path_check:
-#ifdef CONFIG_CIFS_DFS_UPCALL
- /*
- * Perform an unconditional check for whether there are DFS
- * referrals for this path without prefix, to provide support
- * for DFS referrals from w2k8 servers which don't seem to respond
- * with PATH_NOT_COVERED to requests that include the prefix.
- * Chase the referral if found, otherwise continue normally.
- */
- if (referral_walks_count == 0) {
- int refrc = expand_dfs_referral(xid, pSesInfo, volume_info,
- cifs_sb, false);
- if (!refrc) {
- referral_walks_count++;
- goto try_mount_again;
- }
- }
-#endif
-
- /* check if a whole path is not remote */
- if (!rc && tcon) {
- /* build_path_to_root works only when we have a valid tcon */
- full_path = cifs_build_path_to_root(volume_info, cifs_sb, tcon);
- if (full_path == NULL) {
- rc = -ENOMEM;
- goto mount_fail_check;
- }
- rc = is_path_accessible(xid, tcon, cifs_sb, full_path);
- if (rc != 0 && rc != -EREMOTE) {
- kfree(full_path);
- goto mount_fail_check;
- }
- kfree(full_path);
- }
-
- /* get referral if needed */
- if (rc == -EREMOTE) {
-#ifdef CONFIG_CIFS_DFS_UPCALL
- if (referral_walks_count > MAX_NESTED_LINKS) {
- /*
- * BB: when we implement proper loop detection,
- * we will remove this check. But now we need it
- * to prevent an indefinite loop if 'DFS tree' is
- * misconfigured (i.e. has loops).
- */
- rc = -ELOOP;
- goto mount_fail_check;
- }
-
- rc = expand_dfs_referral(xid, pSesInfo, volume_info, cifs_sb,
- true);
-
- if (!rc) {
- referral_walks_count++;
- goto try_mount_again;
- }
- goto mount_fail_check;
-#else /* No DFS support, return error on mount */
- rc = -EOPNOTSUPP;
-#endif
- }
-
- if (rc)
- goto mount_fail_check;
-
- /* now, hang the tcon off of the superblock */
- tlink = kzalloc(sizeof *tlink, GFP_KERNEL);
- if (tlink == NULL) {
- rc = -ENOMEM;
- goto mount_fail_check;
- }
-
- tlink->tl_uid = pSesInfo->linux_uid;
- tlink->tl_tcon = tcon;
- tlink->tl_time = jiffies;
- set_bit(TCON_LINK_MASTER, &tlink->tl_flags);
- set_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
-
- cifs_sb->master_tlink = tlink;
- spin_lock(&cifs_sb->tlink_tree_lock);
- tlink_rb_insert(&cifs_sb->tlink_tree, tlink);
- spin_unlock(&cifs_sb->tlink_tree_lock);
-
- queue_delayed_work(cifsiod_wq, &cifs_sb->prune_tlinks,
- TLINK_IDLE_EXPIRE);
-
-mount_fail_check:
- /* on error free sesinfo and tcon struct if needed */
- if (rc) {
- /* If find_unc succeeded then rc == 0 so we can not end */
- /* up accidentally freeing someone elses tcon struct */
- if (tcon)
- cifs_put_tcon(tcon);
- else if (pSesInfo)
- cifs_put_smb_ses(pSesInfo);
- else
- cifs_put_tcp_session(srvTcp);
- bdi_destroy(&cifs_sb->bdi);
- }
-
-out:
- FreeXid(xid);
- return rc;
-}
-
-/*
- * Issue a TREE_CONNECT request. Note that for IPC$ shares, that the tcon
- * pointer may be NULL.
- */
-int
-CIFSTCon(unsigned int xid, struct cifs_ses *ses,
- const char *tree, struct cifs_tcon *tcon,
- const struct nls_table *nls_codepage)
-{
- struct smb_hdr *smb_buffer;
- struct smb_hdr *smb_buffer_response;
- TCONX_REQ *pSMB;
- TCONX_RSP *pSMBr;
- unsigned char *bcc_ptr;
- int rc = 0;
- int length;
- __u16 bytes_left, count;
-
- if (ses == NULL)
- return -EIO;
-
- smb_buffer = cifs_buf_get();
- if (smb_buffer == NULL)
- return -ENOMEM;
-
- smb_buffer_response = smb_buffer;
-
- header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
- NULL /*no tid */ , 4 /*wct */ );
-
- smb_buffer->Mid = GetNextMid(ses->server);
- smb_buffer->Uid = ses->Suid;
- pSMB = (TCONX_REQ *) smb_buffer;
- pSMBr = (TCONX_RSP *) smb_buffer_response;
-
- pSMB->AndXCommand = 0xFF;
- pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
- bcc_ptr = &pSMB->Password[0];
- if (!tcon || (ses->server->sec_mode & SECMODE_USER)) {
- pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
- *bcc_ptr = 0; /* password is null byte */
- bcc_ptr++; /* skip password */
- /* already aligned so no need to do it below */
- } else {
- pSMB->PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE);
- /* BB FIXME add code to fail this if NTLMv2 or Kerberos
- specified as required (when that support is added to
- the vfs in the future) as only NTLM or the much
- weaker LANMAN (which we do not send by default) is accepted
- by Samba (not sure whether other servers allow
- NTLMv2 password here) */
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
- if ((global_secflags & CIFSSEC_MAY_LANMAN) &&
- (ses->server->secType == LANMAN))
- calc_lanman_hash(tcon->password, ses->server->cryptkey,
- ses->server->sec_mode &
- SECMODE_PW_ENCRYPT ? true : false,
- bcc_ptr);
- else
-#endif /* CIFS_WEAK_PW_HASH */
- rc = SMBNTencrypt(tcon->password, ses->server->cryptkey,
- bcc_ptr, nls_codepage);
-
- bcc_ptr += CIFS_AUTH_RESP_SIZE;
- if (ses->capabilities & CAP_UNICODE) {
- /* must align unicode strings */
- *bcc_ptr = 0; /* null byte password */
- bcc_ptr++;
- }
- }
-
- if (ses->server->sec_mode &
- (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
- smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
-
- if (ses->capabilities & CAP_STATUS32) {
- smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
- }
- if (ses->capabilities & CAP_DFS) {
- smb_buffer->Flags2 |= SMBFLG2_DFS;
- }
- if (ses->capabilities & CAP_UNICODE) {
- smb_buffer->Flags2 |= SMBFLG2_UNICODE;
- length =
- cifs_strtoUTF16((__le16 *) bcc_ptr, tree,
- 6 /* max utf8 char length in bytes */ *
- (/* server len*/ + 256 /* share len */), nls_codepage);
- bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */
- bcc_ptr += 2; /* skip trailing null */
- } else { /* ASCII */
- strcpy(bcc_ptr, tree);
- bcc_ptr += strlen(tree) + 1;
- }
- strcpy(bcc_ptr, "?????");
- bcc_ptr += strlen("?????");
- bcc_ptr += 1;
- count = bcc_ptr - &pSMB->Password[0];
- pSMB->hdr.smb_buf_length = cpu_to_be32(be32_to_cpu(
- pSMB->hdr.smb_buf_length) + count);
- pSMB->ByteCount = cpu_to_le16(count);
-
- rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
- 0);
-
- /* above now done in SendReceive */
- if ((rc == 0) && (tcon != NULL)) {
- bool is_unicode;
-
- tcon->tidStatus = CifsGood;
- tcon->need_reconnect = false;
- tcon->tid = smb_buffer_response->Tid;
- bcc_ptr = pByteArea(smb_buffer_response);
- bytes_left = get_bcc(smb_buffer_response);
- length = strnlen(bcc_ptr, bytes_left - 2);
- if (smb_buffer->Flags2 & SMBFLG2_UNICODE)
- is_unicode = true;
- else
- is_unicode = false;
-
-
- /* skip service field (NB: this field is always ASCII) */
- if (length == 3) {
- if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
- (bcc_ptr[2] == 'C')) {
- cFYI(1, "IPC connection");
- tcon->ipc = 1;
- }
- } else if (length == 2) {
- if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
- /* the most common case */
- cFYI(1, "disk share connection");
- }
- }
- bcc_ptr += length + 1;
- bytes_left -= (length + 1);
- strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
-
- /* mostly informational -- no need to fail on error here */
- kfree(tcon->nativeFileSystem);
- tcon->nativeFileSystem = cifs_strndup_from_utf16(bcc_ptr,
- bytes_left, is_unicode,
- nls_codepage);
-
- cFYI(1, "nativeFileSystem=%s", tcon->nativeFileSystem);
-
- if ((smb_buffer_response->WordCount == 3) ||
- (smb_buffer_response->WordCount == 7))
- /* field is in same location */
- tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
- else
- tcon->Flags = 0;
- cFYI(1, "Tcon flags: 0x%x ", tcon->Flags);
- } else if ((rc == 0) && tcon == NULL) {
- /* all we need to save for IPC$ connection */
- ses->ipc_tid = smb_buffer_response->Tid;
- }
-
- cifs_buf_release(smb_buffer);
- return rc;
-}
-
-void
-cifs_umount(struct cifs_sb_info *cifs_sb)
-{
- struct rb_root *root = &cifs_sb->tlink_tree;
- struct rb_node *node;
- struct tcon_link *tlink;
-
- cancel_delayed_work_sync(&cifs_sb->prune_tlinks);
-
- spin_lock(&cifs_sb->tlink_tree_lock);
- while ((node = rb_first(root))) {
- tlink = rb_entry(node, struct tcon_link, tl_rbnode);
- cifs_get_tlink(tlink);
- clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
- rb_erase(node, root);
-
- spin_unlock(&cifs_sb->tlink_tree_lock);
- cifs_put_tlink(tlink);
- spin_lock(&cifs_sb->tlink_tree_lock);
- }
- spin_unlock(&cifs_sb->tlink_tree_lock);
-
- bdi_destroy(&cifs_sb->bdi);
- kfree(cifs_sb->mountdata);
- unload_nls(cifs_sb->local_nls);
- kfree(cifs_sb);
-}
-
-int cifs_negotiate_protocol(unsigned int xid, struct cifs_ses *ses)
-{
- int rc = 0;
- struct TCP_Server_Info *server = ses->server;
-
- /* only send once per connect */
- if (server->maxBuf != 0)
- return 0;
-
- cifs_set_credits(server, 1);
- rc = CIFSSMBNegotiate(xid, ses);
- if (rc == -EAGAIN) {
- /* retry only once on 1st time connection */
- cifs_set_credits(server, 1);
- rc = CIFSSMBNegotiate(xid, ses);
- if (rc == -EAGAIN)
- rc = -EHOSTDOWN;
- }
- if (rc == 0) {
- spin_lock(&GlobalMid_Lock);
- if (server->tcpStatus == CifsNeedNegotiate)
- server->tcpStatus = CifsGood;
- else
- rc = -EHOSTDOWN;
- spin_unlock(&GlobalMid_Lock);
-
- }
-
- return rc;
-}
-
-
-int cifs_setup_session(unsigned int xid, struct cifs_ses *ses,
- struct nls_table *nls_info)
-{
- int rc = 0;
- struct TCP_Server_Info *server = ses->server;
-
- ses->flags = 0;
- ses->capabilities = server->capabilities;
- if (linuxExtEnabled == 0)
- ses->capabilities &= (~CAP_UNIX);
-
- cFYI(1, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
- server->sec_mode, server->capabilities, server->timeAdj);
-
- rc = CIFS_SessSetup(xid, ses, nls_info);
- if (rc) {
- cERROR(1, "Send error in SessSetup = %d", rc);
- } else {
- mutex_lock(&ses->server->srv_mutex);
- if (!server->session_estab) {
- server->session_key.response = ses->auth_key.response;
- server->session_key.len = ses->auth_key.len;
- server->sequence_number = 0x2;
- server->session_estab = true;
- ses->auth_key.response = NULL;
- }
- mutex_unlock(&server->srv_mutex);
-
- cFYI(1, "CIFS Session Established successfully");
- spin_lock(&GlobalMid_Lock);
- ses->status = CifsGood;
- ses->need_reconnect = false;
- spin_unlock(&GlobalMid_Lock);
- }
-
- kfree(ses->auth_key.response);
- ses->auth_key.response = NULL;
- ses->auth_key.len = 0;
- kfree(ses->ntlmssp);
- ses->ntlmssp = NULL;
-
- return rc;
-}
-
-static int
-cifs_set_vol_auth(struct smb_vol *vol, struct cifs_ses *ses)
-{
- switch (ses->server->secType) {
- case Kerberos:
- vol->secFlg = CIFSSEC_MUST_KRB5;
- return 0;
- case NTLMv2:
- vol->secFlg = CIFSSEC_MUST_NTLMV2;
- break;
- case NTLM:
- vol->secFlg = CIFSSEC_MUST_NTLM;
- break;
- case RawNTLMSSP:
- vol->secFlg = CIFSSEC_MUST_NTLMSSP;
- break;
- case LANMAN:
- vol->secFlg = CIFSSEC_MUST_LANMAN;
- break;
- }
-
- return cifs_set_cifscreds(vol, ses);
-}
-
-static struct cifs_tcon *
-cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid)
-{
- int rc;
- struct cifs_tcon *master_tcon = cifs_sb_master_tcon(cifs_sb);
- struct cifs_ses *ses;
- struct cifs_tcon *tcon = NULL;
- struct smb_vol *vol_info;
-
- vol_info = kzalloc(sizeof(*vol_info), GFP_KERNEL);
- if (vol_info == NULL)
- return ERR_PTR(-ENOMEM);
-
- vol_info->local_nls = cifs_sb->local_nls;
- vol_info->linux_uid = fsuid;
- vol_info->cred_uid = fsuid;
- vol_info->UNC = master_tcon->treeName;
- vol_info->retry = master_tcon->retry;
- vol_info->nocase = master_tcon->nocase;
- vol_info->local_lease = master_tcon->local_lease;
- vol_info->no_linux_ext = !master_tcon->unix_ext;
-
- rc = cifs_set_vol_auth(vol_info, master_tcon->ses);
- if (rc) {
- tcon = ERR_PTR(rc);
- goto out;
- }
-
- /* get a reference for the same TCP session */
- spin_lock(&cifs_tcp_ses_lock);
- ++master_tcon->ses->server->srv_count;
- spin_unlock(&cifs_tcp_ses_lock);
-
- ses = cifs_get_smb_ses(master_tcon->ses->server, vol_info);
- if (IS_ERR(ses)) {
- tcon = (struct cifs_tcon *)ses;
- cifs_put_tcp_session(master_tcon->ses->server);
- goto out;
- }
-
- tcon = cifs_get_tcon(ses, vol_info);
- if (IS_ERR(tcon)) {
- cifs_put_smb_ses(ses);
- goto out;
- }
-
- if (ses->capabilities & CAP_UNIX)
- reset_cifs_unix_caps(0, tcon, NULL, vol_info);
-out:
- kfree(vol_info->username);
- kfree(vol_info->password);
- kfree(vol_info);
-
- return tcon;
-}
-
-struct cifs_tcon *
-cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb)
-{
- return tlink_tcon(cifs_sb_master_tlink(cifs_sb));
-}
-
-static int
-cifs_sb_tcon_pending_wait(void *unused)
-{
- schedule();
- return signal_pending(current) ? -ERESTARTSYS : 0;
-}
-
-/* find and return a tlink with given uid */
-static struct tcon_link *
-tlink_rb_search(struct rb_root *root, uid_t uid)
-{
- struct rb_node *node = root->rb_node;
- struct tcon_link *tlink;
-
- while (node) {
- tlink = rb_entry(node, struct tcon_link, tl_rbnode);
-
- if (tlink->tl_uid > uid)
- node = node->rb_left;
- else if (tlink->tl_uid < uid)
- node = node->rb_right;
- else
- return tlink;
- }
- return NULL;
-}
-
-/* insert a tcon_link into the tree */
-static void
-tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink)
-{
- struct rb_node **new = &(root->rb_node), *parent = NULL;
- struct tcon_link *tlink;
-
- while (*new) {
- tlink = rb_entry(*new, struct tcon_link, tl_rbnode);
- parent = *new;
-
- if (tlink->tl_uid > new_tlink->tl_uid)
- new = &((*new)->rb_left);
- else
- new = &((*new)->rb_right);
- }
-
- rb_link_node(&new_tlink->tl_rbnode, parent, new);
- rb_insert_color(&new_tlink->tl_rbnode, root);
-}
-
-/*
- * Find or construct an appropriate tcon given a cifs_sb and the fsuid of the
- * current task.
- *
- * If the superblock doesn't refer to a multiuser mount, then just return
- * the master tcon for the mount.
- *
- * First, search the rbtree for an existing tcon for this fsuid. If one
- * exists, then check to see if it's pending construction. If it is then wait
- * for construction to complete. Once it's no longer pending, check to see if
- * it failed and either return an error or retry construction, depending on
- * the timeout.
- *
- * If one doesn't exist then insert a new tcon_link struct into the tree and
- * try to construct a new one.
- */
-struct tcon_link *
-cifs_sb_tlink(struct cifs_sb_info *cifs_sb)
-{
- int ret;
- uid_t fsuid = current_fsuid();
- struct tcon_link *tlink, *newtlink;
-
- if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
- return cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));
-
- spin_lock(&cifs_sb->tlink_tree_lock);
- tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid);
- if (tlink)
- cifs_get_tlink(tlink);
- spin_unlock(&cifs_sb->tlink_tree_lock);
-
- if (tlink == NULL) {
- newtlink = kzalloc(sizeof(*tlink), GFP_KERNEL);
- if (newtlink == NULL)
- return ERR_PTR(-ENOMEM);
- newtlink->tl_uid = fsuid;
- newtlink->tl_tcon = ERR_PTR(-EACCES);
- set_bit(TCON_LINK_PENDING, &newtlink->tl_flags);
- set_bit(TCON_LINK_IN_TREE, &newtlink->tl_flags);
- cifs_get_tlink(newtlink);
-
- spin_lock(&cifs_sb->tlink_tree_lock);
- /* was one inserted after previous search? */
- tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid);
- if (tlink) {
- cifs_get_tlink(tlink);
- spin_unlock(&cifs_sb->tlink_tree_lock);
- kfree(newtlink);
- goto wait_for_construction;
- }
- tlink = newtlink;
- tlink_rb_insert(&cifs_sb->tlink_tree, tlink);
- spin_unlock(&cifs_sb->tlink_tree_lock);
- } else {
-wait_for_construction:
- ret = wait_on_bit(&tlink->tl_flags, TCON_LINK_PENDING,
- cifs_sb_tcon_pending_wait,
- TASK_INTERRUPTIBLE);
- if (ret) {
- cifs_put_tlink(tlink);
- return ERR_PTR(ret);
- }
-
- /* if it's good, return it */
- if (!IS_ERR(tlink->tl_tcon))
- return tlink;
-
- /* return error if we tried this already recently */
- if (time_before(jiffies, tlink->tl_time + TLINK_ERROR_EXPIRE)) {
- cifs_put_tlink(tlink);
- return ERR_PTR(-EACCES);
- }
-
- if (test_and_set_bit(TCON_LINK_PENDING, &tlink->tl_flags))
- goto wait_for_construction;
- }
-
- tlink->tl_tcon = cifs_construct_tcon(cifs_sb, fsuid);
- clear_bit(TCON_LINK_PENDING, &tlink->tl_flags);
- wake_up_bit(&tlink->tl_flags, TCON_LINK_PENDING);
-
- if (IS_ERR(tlink->tl_tcon)) {
- cifs_put_tlink(tlink);
- return ERR_PTR(-EACCES);
- }
-
- return tlink;
-}
-
-/*
- * periodic workqueue job that scans tcon_tree for a superblock and closes
- * out tcons.
- */
-static void
-cifs_prune_tlinks(struct work_struct *work)
-{
- struct cifs_sb_info *cifs_sb = container_of(work, struct cifs_sb_info,
- prune_tlinks.work);
- struct rb_root *root = &cifs_sb->tlink_tree;
- struct rb_node *node = rb_first(root);
- struct rb_node *tmp;
- struct tcon_link *tlink;
-
- /*
- * Because we drop the spinlock in the loop in order to put the tlink
- * it's not guarded against removal of links from the tree. The only
- * places that remove entries from the tree are this function and
- * umounts. Because this function is non-reentrant and is canceled
- * before umount can proceed, this is safe.
- */
- spin_lock(&cifs_sb->tlink_tree_lock);
- node = rb_first(root);
- while (node != NULL) {
- tmp = node;
- node = rb_next(tmp);
- tlink = rb_entry(tmp, struct tcon_link, tl_rbnode);
-
- if (test_bit(TCON_LINK_MASTER, &tlink->tl_flags) ||
- atomic_read(&tlink->tl_count) != 0 ||
- time_after(tlink->tl_time + TLINK_IDLE_EXPIRE, jiffies))
- continue;
-
- cifs_get_tlink(tlink);
- clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
- rb_erase(tmp, root);
-
- spin_unlock(&cifs_sb->tlink_tree_lock);
- cifs_put_tlink(tlink);
- spin_lock(&cifs_sb->tlink_tree_lock);
- }
- spin_unlock(&cifs_sb->tlink_tree_lock);
-
- queue_delayed_work(cifsiod_wq, &cifs_sb->prune_tlinks,
- TLINK_IDLE_EXPIRE);
-}
diff --git a/ANDROID_3.4.5/fs/cifs/dir.c b/ANDROID_3.4.5/fs/cifs/dir.c
deleted file mode 100644
index ec4e9a2a..00000000
--- a/ANDROID_3.4.5/fs/cifs/dir.c
+++ /dev/null
@@ -1,758 +0,0 @@
-/*
- * fs/cifs/dir.c
- *
- * vfs operations that deal with dentries
- *
- * Copyright (C) International Business Machines Corp., 2002,2009
- * Author(s): Steve French (sfrench@us.ibm.com)
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <linux/fs.h>
-#include <linux/stat.h>
-#include <linux/slab.h>
-#include <linux/namei.h>
-#include <linux/mount.h>
-#include <linux/file.h>
-#include "cifsfs.h"
-#include "cifspdu.h"
-#include "cifsglob.h"
-#include "cifsproto.h"
-#include "cifs_debug.h"
-#include "cifs_fs_sb.h"
-
-static void
-renew_parental_timestamps(struct dentry *direntry)
-{
- /* BB check if there is a way to get the kernel to do this or if we
- really need this */
- do {
- direntry->d_time = jiffies;
- direntry = direntry->d_parent;
- } while (!IS_ROOT(direntry));
-}
-
-/* Note: caller must free return buffer */
-char *
-build_path_from_dentry(struct dentry *direntry)
-{
- struct dentry *temp;
- int namelen;
- int dfsplen;
- char *full_path;
- char dirsep;
- struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
- struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
- unsigned seq;
-
- dirsep = CIFS_DIR_SEP(cifs_sb);
- if (tcon->Flags & SMB_SHARE_IS_IN_DFS)
- dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
- else
- dfsplen = 0;
-cifs_bp_rename_retry:
- namelen = dfsplen;
- seq = read_seqbegin(&rename_lock);
- rcu_read_lock();
- for (temp = direntry; !IS_ROOT(temp);) {
- namelen += (1 + temp->d_name.len);
- temp = temp->d_parent;
- if (temp == NULL) {
- cERROR(1, "corrupt dentry");
- rcu_read_unlock();
- return NULL;
- }
- }
- rcu_read_unlock();
-
- full_path = kmalloc(namelen+1, GFP_KERNEL);
- if (full_path == NULL)
- return full_path;
- full_path[namelen] = 0; /* trailing null */
- rcu_read_lock();
- for (temp = direntry; !IS_ROOT(temp);) {
- spin_lock(&temp->d_lock);
- namelen -= 1 + temp->d_name.len;
- if (namelen < 0) {
- spin_unlock(&temp->d_lock);
- break;
- } else {
- full_path[namelen] = dirsep;
- strncpy(full_path + namelen + 1, temp->d_name.name,
- temp->d_name.len);
- cFYI(0, "name: %s", full_path + namelen);
- }
- spin_unlock(&temp->d_lock);
- temp = temp->d_parent;
- if (temp == NULL) {
- cERROR(1, "corrupt dentry");
- rcu_read_unlock();
- kfree(full_path);
- return NULL;
- }
- }
- rcu_read_unlock();
- if (namelen != dfsplen || read_seqretry(&rename_lock, seq)) {
- cFYI(1, "did not end path lookup where expected. namelen=%d "
- "dfsplen=%d", namelen, dfsplen);
- /* presumably this is only possible if racing with a rename
- of one of the parent directories (we can not lock the dentries
- above us to prevent this, but retrying should be harmless) */
- kfree(full_path);
- goto cifs_bp_rename_retry;
- }
- /* DIR_SEP already set for byte 0 / vs \ but not for
- subsequent slashes in prepath which currently must
- be entered the right way - not sure if there is an alternative
- since the '\' is a valid posix character so we can not switch
- those safely to '/' if any are found in the middle of the prepath */
- /* BB test paths to Windows with '/' in the midst of prepath */
-
- if (dfsplen) {
- strncpy(full_path, tcon->treeName, dfsplen);
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
- int i;
- for (i = 0; i < dfsplen; i++) {
- if (full_path[i] == '\\')
- full_path[i] = '/';
- }
- }
- }
- return full_path;
-}
-
-/* Inode operations in similar order to how they appear in Linux file fs.h */
-
-int
-cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode,
- struct nameidata *nd)
-{
- int rc = -ENOENT;
- int xid;
- int create_options = CREATE_NOT_DIR;
- __u32 oplock = 0;
- int oflags;
- /*
- * BB below access is probably too much for mknod to request
- * but we have to do query and setpathinfo so requesting
- * less could fail (unless we want to request getatr and setatr
- * permissions (only). At least for POSIX we do not have to
- * request so much.
- */
- int desiredAccess = GENERIC_READ | GENERIC_WRITE;
- __u16 fileHandle;
- struct cifs_sb_info *cifs_sb;
- struct tcon_link *tlink;
- struct cifs_tcon *tcon;
- char *full_path = NULL;
- FILE_ALL_INFO *buf = NULL;
- struct inode *newinode = NULL;
- int disposition = FILE_OVERWRITE_IF;
-
- xid = GetXid();
-
- cifs_sb = CIFS_SB(inode->i_sb);
- tlink = cifs_sb_tlink(cifs_sb);
- if (IS_ERR(tlink)) {
- FreeXid(xid);
- return PTR_ERR(tlink);
- }
- tcon = tlink_tcon(tlink);
-
- if (tcon->ses->server->oplocks)
- oplock = REQ_OPLOCK;
-
- if (nd)
- oflags = nd->intent.open.file->f_flags;
- else
- oflags = O_RDONLY | O_CREAT;
-
- full_path = build_path_from_dentry(direntry);
- if (full_path == NULL) {
- rc = -ENOMEM;
- goto cifs_create_out;
- }
-
- if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) &&
- (CIFS_UNIX_POSIX_PATH_OPS_CAP &
- le64_to_cpu(tcon->fsUnixInfo.Capability))) {
- rc = cifs_posix_open(full_path, &newinode,
- inode->i_sb, mode, oflags, &oplock, &fileHandle, xid);
- /* EIO could indicate that (posix open) operation is not
- supported, despite what server claimed in capability
- negotiation. EREMOTE indicates DFS junction, which is not
- handled in posix open */
-
- if (rc == 0) {
- if (newinode == NULL) /* query inode info */
- goto cifs_create_get_file_info;
- else /* success, no need to query */
- goto cifs_create_set_dentry;
- } else if ((rc != -EIO) && (rc != -EREMOTE) &&
- (rc != -EOPNOTSUPP) && (rc != -EINVAL))
- goto cifs_create_out;
- /* else fallthrough to retry, using older open call, this is
- case where server does not support this SMB level, and
- falsely claims capability (also get here for DFS case
- which should be rare for path not covered on files) */
- }
-
- if (nd) {
- /* if the file is going to stay open, then we
- need to set the desired access properly */
- desiredAccess = 0;
- if (OPEN_FMODE(oflags) & FMODE_READ)
- desiredAccess |= GENERIC_READ; /* is this too little? */
- if (OPEN_FMODE(oflags) & FMODE_WRITE)
- desiredAccess |= GENERIC_WRITE;
-
- if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
- disposition = FILE_CREATE;
- else if ((oflags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
- disposition = FILE_OVERWRITE_IF;
- else if ((oflags & O_CREAT) == O_CREAT)
- disposition = FILE_OPEN_IF;
- else
- cFYI(1, "Create flag not set in create function");
- }
-
- /* BB add processing to set equivalent of mode - e.g. via CreateX with
- ACLs */
-
- buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
- if (buf == NULL) {
- rc = -ENOMEM;
- goto cifs_create_out;
- }
-
- /*
- * if we're not using unix extensions, see if we need to set
- * ATTR_READONLY on the create call
- */
- if (!tcon->unix_ext && (mode & S_IWUGO) == 0)
- create_options |= CREATE_OPTION_READONLY;
-
- if (backup_cred(cifs_sb))
- create_options |= CREATE_OPEN_BACKUP_INTENT;
-
- if (tcon->ses->capabilities & CAP_NT_SMBS)
- rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
- desiredAccess, create_options,
- &fileHandle, &oplock, buf, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
- else
- rc = -EIO; /* no NT SMB support fall into legacy open below */
-
- if (rc == -EIO) {
- /* old server, retry the open legacy style */
- rc = SMBLegacyOpen(xid, tcon, full_path, disposition,
- desiredAccess, create_options,
- &fileHandle, &oplock, buf, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
- }
- if (rc) {
- cFYI(1, "cifs_create returned 0x%x", rc);
- goto cifs_create_out;
- }
-
- /* If Open reported that we actually created a file
- then we now have to set the mode if possible */
- if ((tcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) {
- struct cifs_unix_set_info_args args = {
- .mode = mode,
- .ctime = NO_CHANGE_64,
- .atime = NO_CHANGE_64,
- .mtime = NO_CHANGE_64,
- .device = 0,
- };
-
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
- args.uid = (__u64) current_fsuid();
- if (inode->i_mode & S_ISGID)
- args.gid = (__u64) inode->i_gid;
- else
- args.gid = (__u64) current_fsgid();
- } else {
- args.uid = NO_CHANGE_64;
- args.gid = NO_CHANGE_64;
- }
- CIFSSMBUnixSetFileInfo(xid, tcon, &args, fileHandle,
- current->tgid);
- } else {
- /* BB implement mode setting via Windows security
- descriptors e.g. */
- /* CIFSSMBWinSetPerms(xid,tcon,path,mode,-1,-1,nls);*/
-
- /* Could set r/o dos attribute if mode & 0222 == 0 */
- }
-
-cifs_create_get_file_info:
- /* server might mask mode so we have to query for it */
- if (tcon->unix_ext)
- rc = cifs_get_inode_info_unix(&newinode, full_path,
- inode->i_sb, xid);
- else {
- rc = cifs_get_inode_info(&newinode, full_path, buf,
- inode->i_sb, xid, &fileHandle);
- if (newinode) {
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
- newinode->i_mode = mode;
- if ((oplock & CIFS_CREATE_ACTION) &&
- (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) {
- newinode->i_uid = current_fsuid();
- if (inode->i_mode & S_ISGID)
- newinode->i_gid = inode->i_gid;
- else
- newinode->i_gid = current_fsgid();
- }
- }
- }
-
-cifs_create_set_dentry:
- if (rc == 0)
- d_instantiate(direntry, newinode);
- else
- cFYI(1, "Create worked, get_inode_info failed rc = %d", rc);
-
- if (newinode && nd) {
- struct cifsFileInfo *pfile_info;
- struct file *filp;
-
- filp = lookup_instantiate_filp(nd, direntry, generic_file_open);
- if (IS_ERR(filp)) {
- rc = PTR_ERR(filp);
- CIFSSMBClose(xid, tcon, fileHandle);
- goto cifs_create_out;
- }
-
- pfile_info = cifs_new_fileinfo(fileHandle, filp, tlink, oplock);
- if (pfile_info == NULL) {
- fput(filp);
- CIFSSMBClose(xid, tcon, fileHandle);
- rc = -ENOMEM;
- }
- } else {
- CIFSSMBClose(xid, tcon, fileHandle);
- }
-
-cifs_create_out:
- kfree(buf);
- kfree(full_path);
- cifs_put_tlink(tlink);
- FreeXid(xid);
- return rc;
-}
-
-int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode,
- dev_t device_number)
-{
- int rc = -EPERM;
- int xid;
- int create_options = CREATE_NOT_DIR | CREATE_OPTION_SPECIAL;
- struct cifs_sb_info *cifs_sb;
- struct tcon_link *tlink;
- struct cifs_tcon *pTcon;
- struct cifs_io_parms io_parms;
- char *full_path = NULL;
- struct inode *newinode = NULL;
- int oplock = 0;
- u16 fileHandle;
- FILE_ALL_INFO *buf = NULL;
- unsigned int bytes_written;
- struct win_dev *pdev;
-
- if (!old_valid_dev(device_number))
- return -EINVAL;
-
- cifs_sb = CIFS_SB(inode->i_sb);
- tlink = cifs_sb_tlink(cifs_sb);
- if (IS_ERR(tlink))
- return PTR_ERR(tlink);
-
- pTcon = tlink_tcon(tlink);
-
- xid = GetXid();
-
- full_path = build_path_from_dentry(direntry);
- if (full_path == NULL) {
- rc = -ENOMEM;
- goto mknod_out;
- }
-
- if (pTcon->unix_ext) {
- struct cifs_unix_set_info_args args = {
- .mode = mode & ~current_umask(),
- .ctime = NO_CHANGE_64,
- .atime = NO_CHANGE_64,
- .mtime = NO_CHANGE_64,
- .device = device_number,
- };
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
- args.uid = (__u64) current_fsuid();
- args.gid = (__u64) current_fsgid();
- } else {
- args.uid = NO_CHANGE_64;
- args.gid = NO_CHANGE_64;
- }
- rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, &args,
- cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- if (rc)
- goto mknod_out;
-
- rc = cifs_get_inode_info_unix(&newinode, full_path,
- inode->i_sb, xid);
-
- if (rc == 0)
- d_instantiate(direntry, newinode);
- goto mknod_out;
- }
-
- if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL))
- goto mknod_out;
-
-
- cFYI(1, "sfu compat create special file");
-
- buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
- if (buf == NULL) {
- kfree(full_path);
- rc = -ENOMEM;
- FreeXid(xid);
- return rc;
- }
-
- if (backup_cred(cifs_sb))
- create_options |= CREATE_OPEN_BACKUP_INTENT;
-
- rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_CREATE,
- GENERIC_WRITE, create_options,
- &fileHandle, &oplock, buf, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
- if (rc)
- goto mknod_out;
-
- /* BB Do not bother to decode buf since no local inode yet to put
- * timestamps in, but we can reuse it safely */
-
- pdev = (struct win_dev *)buf;
- io_parms.netfid = fileHandle;
- io_parms.pid = current->tgid;
- io_parms.tcon = pTcon;
- io_parms.offset = 0;
- io_parms.length = sizeof(struct win_dev);
- if (S_ISCHR(mode)) {
- memcpy(pdev->type, "IntxCHR", 8);
- pdev->major =
- cpu_to_le64(MAJOR(device_number));
- pdev->minor =
- cpu_to_le64(MINOR(device_number));
- rc = CIFSSMBWrite(xid, &io_parms,
- &bytes_written, (char *)pdev,
- NULL, 0);
- } else if (S_ISBLK(mode)) {
- memcpy(pdev->type, "IntxBLK", 8);
- pdev->major =
- cpu_to_le64(MAJOR(device_number));
- pdev->minor =
- cpu_to_le64(MINOR(device_number));
- rc = CIFSSMBWrite(xid, &io_parms,
- &bytes_written, (char *)pdev,
- NULL, 0);
- } /* else if (S_ISFIFO) */
- CIFSSMBClose(xid, pTcon, fileHandle);
- d_drop(direntry);
-
- /* FIXME: add code here to set EAs */
-
-mknod_out:
- kfree(full_path);
- kfree(buf);
- FreeXid(xid);
- cifs_put_tlink(tlink);
- return rc;
-}
-
-struct dentry *
-cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
- struct nameidata *nd)
-{
- int xid;
- int rc = 0; /* to get around spurious gcc warning, set to zero here */
- __u32 oplock;
- __u16 fileHandle = 0;
- bool posix_open = false;
- struct cifs_sb_info *cifs_sb;
- struct tcon_link *tlink;
- struct cifs_tcon *pTcon;
- struct cifsFileInfo *cfile;
- struct inode *newInode = NULL;
- char *full_path = NULL;
- struct file *filp;
-
- xid = GetXid();
-
- cFYI(1, "parent inode = 0x%p name is: %s and dentry = 0x%p",
- parent_dir_inode, direntry->d_name.name, direntry);
-
- /* check whether path exists */
-
- cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
- tlink = cifs_sb_tlink(cifs_sb);
- if (IS_ERR(tlink)) {
- FreeXid(xid);
- return (struct dentry *)tlink;
- }
- pTcon = tlink_tcon(tlink);
-
- oplock = pTcon->ses->server->oplocks ? REQ_OPLOCK : 0;
-
- /*
- * Don't allow the separator character in a path component.
- * The VFS will not allow "/", but "\" is allowed by posix.
- */
- if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) {
- int i;
- for (i = 0; i < direntry->d_name.len; i++)
- if (direntry->d_name.name[i] == '\\') {
- cFYI(1, "Invalid file name");
- rc = -EINVAL;
- goto lookup_out;
- }
- }
-
- /*
- * O_EXCL: optimize away the lookup, but don't hash the dentry. Let
- * the VFS handle the create.
- */
- if (nd && (nd->flags & LOOKUP_EXCL)) {
- d_instantiate(direntry, NULL);
- rc = 0;
- goto lookup_out;
- }
-
- /* can not grab the rename sem here since it would
- deadlock in the cases (beginning of sys_rename itself)
- in which we already have the sb rename sem */
- full_path = build_path_from_dentry(direntry);
- if (full_path == NULL) {
- rc = -ENOMEM;
- goto lookup_out;
- }
-
- if (direntry->d_inode != NULL) {
- cFYI(1, "non-NULL inode in lookup");
- } else {
- cFYI(1, "NULL inode in lookup");
- }
- cFYI(1, "Full path: %s inode = 0x%p", full_path, direntry->d_inode);
-
- /* Posix open is only called (at lookup time) for file create now.
- * For opens (rather than creates), because we do not know if it
- * is a file or directory yet, and current Samba no longer allows
- * us to do posix open on dirs, we could end up wasting an open call
- * on what turns out to be a dir. For file opens, we wait to call posix
- * open till cifs_open. It could be added here (lookup) in the future
- * but the performance tradeoff of the extra network request when EISDIR
- * or EACCES is returned would have to be weighed against the 50%
- * reduction in network traffic in the other paths.
- */
- if (pTcon->unix_ext) {
- if (nd && !(nd->flags & LOOKUP_DIRECTORY) &&
- (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open &&
- (nd->intent.open.file->f_flags & O_CREAT)) {
- rc = cifs_posix_open(full_path, &newInode,
- parent_dir_inode->i_sb,
- nd->intent.open.create_mode,
- nd->intent.open.file->f_flags, &oplock,
- &fileHandle, xid);
- /*
- * The check below works around a bug in POSIX
- * open in samba versions 3.3.1 and earlier where
- * open could incorrectly fail with invalid parameter.
- * If either that or op not supported returned, follow
- * the normal lookup.
- */
- switch (rc) {
- case 0:
- /*
- * The server may allow us to open things like
- * FIFOs, but the client isn't set up to deal
- * with that. If it's not a regular file, just
- * close it and proceed as if it were a normal
- * lookup.
- */
- if (newInode && !S_ISREG(newInode->i_mode)) {
- CIFSSMBClose(xid, pTcon, fileHandle);
- break;
- }
- case -ENOENT:
- posix_open = true;
- case -EOPNOTSUPP:
- break;
- default:
- pTcon->broken_posix_open = true;
- }
- }
- if (!posix_open)
- rc = cifs_get_inode_info_unix(&newInode, full_path,
- parent_dir_inode->i_sb, xid);
- } else
- rc = cifs_get_inode_info(&newInode, full_path, NULL,
- parent_dir_inode->i_sb, xid, NULL);
-
- if ((rc == 0) && (newInode != NULL)) {
- d_add(direntry, newInode);
- if (posix_open) {
- filp = lookup_instantiate_filp(nd, direntry,
- generic_file_open);
- if (IS_ERR(filp)) {
- rc = PTR_ERR(filp);
- CIFSSMBClose(xid, pTcon, fileHandle);
- goto lookup_out;
- }
-
- cfile = cifs_new_fileinfo(fileHandle, filp, tlink,
- oplock);
- if (cfile == NULL) {
- fput(filp);
- CIFSSMBClose(xid, pTcon, fileHandle);
- rc = -ENOMEM;
- goto lookup_out;
- }
- }
- /* since paths are not looked up by component - the parent
- directories are presumed to be good here */
- renew_parental_timestamps(direntry);
-
- } else if (rc == -ENOENT) {
- rc = 0;
- direntry->d_time = jiffies;
- d_add(direntry, NULL);
- /* if it was once a directory (but how can we tell?) we could do
- shrink_dcache_parent(direntry); */
- } else if (rc != -EACCES) {
- cERROR(1, "Unexpected lookup error %d", rc);
- /* We special case check for Access Denied - since that
- is a common return code */
- }
-
-lookup_out:
- kfree(full_path);
- cifs_put_tlink(tlink);
- FreeXid(xid);
- return ERR_PTR(rc);
-}
-
-static int
-cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
-{
- if (nd && (nd->flags & LOOKUP_RCU))
- return -ECHILD;
-
- if (direntry->d_inode) {
- if (cifs_revalidate_dentry(direntry))
- return 0;
- else {
- /*
- * If the inode wasn't known to be a dfs entry when
- * the dentry was instantiated, such as when created
- * via ->readdir(), it needs to be set now since the
- * attributes will have been updated by
- * cifs_revalidate_dentry().
- */
- if (IS_AUTOMOUNT(direntry->d_inode) &&
- !(direntry->d_flags & DCACHE_NEED_AUTOMOUNT)) {
- spin_lock(&direntry->d_lock);
- direntry->d_flags |= DCACHE_NEED_AUTOMOUNT;
- spin_unlock(&direntry->d_lock);
- }
-
- return 1;
- }
- }
-
- /*
- * This may be nfsd (or something), anyway, we can't see the
- * intent of this. So, since this can be for creation, drop it.
- */
- if (!nd)
- return 0;
-
- /*
- * Drop the negative dentry, in order to make sure to use the
- * case sensitive name which is specified by user if this is
- * for creation.
- */
- if (nd->flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET))
- return 0;
-
- if (time_after(jiffies, direntry->d_time + HZ) || !lookupCacheEnabled)
- return 0;
-
- return 1;
-}
-
-/* static int cifs_d_delete(struct dentry *direntry)
-{
- int rc = 0;
-
- cFYI(1, "In cifs d_delete, name = %s", direntry->d_name.name);
-
- return rc;
-} */
-
-const struct dentry_operations cifs_dentry_ops = {
- .d_revalidate = cifs_d_revalidate,
- .d_automount = cifs_dfs_d_automount,
-/* d_delete: cifs_d_delete, */ /* not needed except for debugging */
-};
-
-static int cifs_ci_hash(const struct dentry *dentry, const struct inode *inode,
- struct qstr *q)
-{
- struct nls_table *codepage = CIFS_SB(dentry->d_sb)->local_nls;
- unsigned long hash;
- int i;
-
- hash = init_name_hash();
- for (i = 0; i < q->len; i++)
- hash = partial_name_hash(nls_tolower(codepage, q->name[i]),
- hash);
- q->hash = end_name_hash(hash);
-
- return 0;
-}
-
-static int cifs_ci_compare(const struct dentry *parent,
- const struct inode *pinode,
- const struct dentry *dentry, const struct inode *inode,
- unsigned int len, const char *str, const struct qstr *name)
-{
- struct nls_table *codepage = CIFS_SB(pinode->i_sb)->local_nls;
-
- if ((name->len == len) &&
- (nls_strnicmp(codepage, name->name, str, len) == 0))
- return 0;
- return 1;
-}
-
-const struct dentry_operations cifs_ci_dentry_ops = {
- .d_revalidate = cifs_d_revalidate,
- .d_hash = cifs_ci_hash,
- .d_compare = cifs_ci_compare,
- .d_automount = cifs_dfs_d_automount,
-};
diff --git a/ANDROID_3.4.5/fs/cifs/dns_resolve.c b/ANDROID_3.4.5/fs/cifs/dns_resolve.c
deleted file mode 100644
index 1d2d91d9..00000000
--- a/ANDROID_3.4.5/fs/cifs/dns_resolve.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * fs/cifs/dns_resolve.c
- *
- * Copyright (c) 2007 Igor Mammedov
- * Author(s): Igor Mammedov (niallain@gmail.com)
- * Steve French (sfrench@us.ibm.com)
- * Wang Lei (wang840925@gmail.com)
- * David Howells (dhowells@redhat.com)
- *
- * Contains the CIFS DFS upcall routines used for hostname to
- * IP address translation.
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/slab.h>
-#include <linux/dns_resolver.h>
-#include "dns_resolve.h"
-#include "cifsglob.h"
-#include "cifsproto.h"
-#include "cifs_debug.h"
-
-/**
- * dns_resolve_server_name_to_ip - Resolve UNC server name to ip address.
- * @unc: UNC path specifying the server
- * @ip_addr: Where to return the IP address.
- *
- * The IP address will be returned in string form, and the caller is
- * responsible for freeing it.
- *
- * Returns length of result on success, -ve on error.
- */
-int
-dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
-{
- struct sockaddr_storage ss;
- const char *hostname, *sep;
- char *name;
- int len, rc;
-
- if (!ip_addr || !unc)
- return -EINVAL;
-
- len = strlen(unc);
- if (len < 3) {
- cFYI(1, "%s: unc is too short: %s", __func__, unc);
- return -EINVAL;
- }
-
- /* Discount leading slashes for cifs */
- len -= 2;
- hostname = unc + 2;
-
- /* Search for server name delimiter */
- sep = memchr(hostname, '\\', len);
- if (sep)
- len = sep - hostname;
- else
- cFYI(1, "%s: probably server name is whole unc: %s",
- __func__, unc);
-
- /* Try to interpret hostname as an IPv4 or IPv6 address */
- rc = cifs_convert_address((struct sockaddr *)&ss, hostname, len);
- if (rc > 0)
- goto name_is_IP_address;
-
- /* Perform the upcall */
- rc = dns_query(NULL, hostname, len, NULL, ip_addr, NULL);
- if (rc < 0)
- cFYI(1, "%s: unable to resolve: %*.*s",
- __func__, len, len, hostname);
- else
- cFYI(1, "%s: resolved: %*.*s to %s",
- __func__, len, len, hostname, *ip_addr);
- return rc;
-
-name_is_IP_address:
- name = kmalloc(len + 1, GFP_KERNEL);
- if (!name)
- return -ENOMEM;
- memcpy(name, hostname, len);
- name[len] = 0;
- cFYI(1, "%s: unc is IP, skipping dns upcall: %s", __func__, name);
- *ip_addr = name;
- return 0;
-}
diff --git a/ANDROID_3.4.5/fs/cifs/dns_resolve.h b/ANDROID_3.4.5/fs/cifs/dns_resolve.h
deleted file mode 100644
index d3f5d27f..00000000
--- a/ANDROID_3.4.5/fs/cifs/dns_resolve.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * fs/cifs/dns_resolve.h -- DNS Resolver upcall management for CIFS DFS
- * Handles host name to IP address resolution
- *
- * Copyright (c) International Business Machines Corp., 2008
- * Author(s): Steve French (sfrench@us.ibm.com)
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef _DNS_RESOLVE_H
-#define _DNS_RESOLVE_H
-
-#ifdef __KERNEL__
-extern int dns_resolve_server_name_to_ip(const char *unc, char **ip_addr);
-#endif /* KERNEL */
-
-#endif /* _DNS_RESOLVE_H */
diff --git a/ANDROID_3.4.5/fs/cifs/export.c b/ANDROID_3.4.5/fs/cifs/export.c
deleted file mode 100644
index 9c7ecdcc..00000000
--- a/ANDROID_3.4.5/fs/cifs/export.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * fs/cifs/export.c
- *
- * Copyright (C) International Business Machines Corp., 2007
- * Author(s): Steve French (sfrench@us.ibm.com)
- *
- * Common Internet FileSystem (CIFS) client
- *
- * Operations related to support for exporting files via NFSD
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
- /*
- * See Documentation/filesystems/nfs/Exporting
- * and examples in fs/exportfs
- *
- * Since cifs is a network file system, an "fsid" must be included for
- * any nfs exports file entries which refer to cifs paths. In addition
- * the cifs mount must be mounted with the "serverino" option (ie use stable
- * server inode numbers instead of locally generated temporary ones).
- * Although cifs inodes do not use generation numbers (have generation number
- * of zero) - the inode number alone should be good enough for simple cases
- * in which users want to export cifs shares with NFS. The decode and encode
- * could be improved by using a new routine which expects 64 bit inode numbers
- * instead of the default 32 bit routines in fs/exportfs
- *
- */
-
-#include <linux/fs.h>
-#include <linux/exportfs.h>
-#include "cifsglob.h"
-#include "cifs_debug.h"
-#include "cifsfs.h"
-
-#ifdef CONFIG_CIFS_NFSD_EXPORT
-static struct dentry *cifs_get_parent(struct dentry *dentry)
-{
- /* BB need to add code here eventually to enable export via NFSD */
- cFYI(1, "get parent for %p", dentry);
- return ERR_PTR(-EACCES);
-}
-
-const struct export_operations cifs_export_ops = {
- .get_parent = cifs_get_parent,
-/* Following five export operations are unneeded so far and can default:
- .get_dentry =
- .get_name =
- .find_exported_dentry =
- .decode_fh =
- .encode_fs = */
-};
-
-#endif /* CONFIG_CIFS_NFSD_EXPORT */
-
diff --git a/ANDROID_3.4.5/fs/cifs/file.c b/ANDROID_3.4.5/fs/cifs/file.c
deleted file mode 100644
index e7ebb5a2..00000000
--- a/ANDROID_3.4.5/fs/cifs/file.c
+++ /dev/null
@@ -1,3060 +0,0 @@
-/*
- * fs/cifs/file.c
- *
- * vfs operations that deal with files
- *
- * Copyright (C) International Business Machines Corp., 2002,2010
- * Author(s): Steve French (sfrench@us.ibm.com)
- * Jeremy Allison (jra@samba.org)
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <linux/fs.h>
-#include <linux/backing-dev.h>
-#include <linux/stat.h>
-#include <linux/fcntl.h>
-#include <linux/pagemap.h>
-#include <linux/pagevec.h>
-#include <linux/writeback.h>
-#include <linux/task_io_accounting_ops.h>
-#include <linux/delay.h>
-#include <linux/mount.h>
-#include <linux/slab.h>
-#include <linux/swap.h>
-#include <asm/div64.h>
-#include "cifsfs.h"
-#include "cifspdu.h"
-#include "cifsglob.h"
-#include "cifsproto.h"
-#include "cifs_unicode.h"
-#include "cifs_debug.h"
-#include "cifs_fs_sb.h"
-#include "fscache.h"
-
-static inline int cifs_convert_flags(unsigned int flags)
-{
- if ((flags & O_ACCMODE) == O_RDONLY)
- return GENERIC_READ;
- else if ((flags & O_ACCMODE) == O_WRONLY)
- return GENERIC_WRITE;
- else if ((flags & O_ACCMODE) == O_RDWR) {
- /* GENERIC_ALL is too much permission to request
- can cause unnecessary access denied on create */
- /* return GENERIC_ALL; */
- return (GENERIC_READ | GENERIC_WRITE);
- }
-
- return (READ_CONTROL | FILE_WRITE_ATTRIBUTES | FILE_READ_ATTRIBUTES |
- FILE_WRITE_EA | FILE_APPEND_DATA | FILE_WRITE_DATA |
- FILE_READ_DATA);
-}
-
-static u32 cifs_posix_convert_flags(unsigned int flags)
-{
- u32 posix_flags = 0;
-
- if ((flags & O_ACCMODE) == O_RDONLY)
- posix_flags = SMB_O_RDONLY;
- else if ((flags & O_ACCMODE) == O_WRONLY)
- posix_flags = SMB_O_WRONLY;
- else if ((flags & O_ACCMODE) == O_RDWR)
- posix_flags = SMB_O_RDWR;
-
- if (flags & O_CREAT)
- posix_flags |= SMB_O_CREAT;
- if (flags & O_EXCL)
- posix_flags |= SMB_O_EXCL;
- if (flags & O_TRUNC)
- posix_flags |= SMB_O_TRUNC;
- /* be safe and imply O_SYNC for O_DSYNC */
- if (flags & O_DSYNC)
- posix_flags |= SMB_O_SYNC;
- if (flags & O_DIRECTORY)
- posix_flags |= SMB_O_DIRECTORY;
- if (flags & O_NOFOLLOW)
- posix_flags |= SMB_O_NOFOLLOW;
- if (flags & O_DIRECT)
- posix_flags |= SMB_O_DIRECT;
-
- return posix_flags;
-}
-
-static inline int cifs_get_disposition(unsigned int flags)
-{
- if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
- return FILE_CREATE;
- else if ((flags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
- return FILE_OVERWRITE_IF;
- else if ((flags & O_CREAT) == O_CREAT)
- return FILE_OPEN_IF;
- else if ((flags & O_TRUNC) == O_TRUNC)
- return FILE_OVERWRITE;
- else
- return FILE_OPEN;
-}
-
-int cifs_posix_open(char *full_path, struct inode **pinode,
- struct super_block *sb, int mode, unsigned int f_flags,
- __u32 *poplock, __u16 *pnetfid, int xid)
-{
- int rc;
- FILE_UNIX_BASIC_INFO *presp_data;
- __u32 posix_flags = 0;
- struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
- struct cifs_fattr fattr;
- struct tcon_link *tlink;
- struct cifs_tcon *tcon;
-
- cFYI(1, "posix open %s", full_path);
-
- presp_data = kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
- if (presp_data == NULL)
- return -ENOMEM;
-
- tlink = cifs_sb_tlink(cifs_sb);
- if (IS_ERR(tlink)) {
- rc = PTR_ERR(tlink);
- goto posix_open_ret;
- }
-
- tcon = tlink_tcon(tlink);
- mode &= ~current_umask();
-
- posix_flags = cifs_posix_convert_flags(f_flags);
- rc = CIFSPOSIXCreate(xid, tcon, posix_flags, mode, pnetfid, presp_data,
- poplock, full_path, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- cifs_put_tlink(tlink);
-
- if (rc)
- goto posix_open_ret;
-
- if (presp_data->Type == cpu_to_le32(-1))
- goto posix_open_ret; /* open ok, caller does qpathinfo */
-
- if (!pinode)
- goto posix_open_ret; /* caller does not need info */
-
- cifs_unix_basic_to_fattr(&fattr, presp_data, cifs_sb);
-
- /* get new inode and set it up */
- if (*pinode == NULL) {
- cifs_fill_uniqueid(sb, &fattr);
- *pinode = cifs_iget(sb, &fattr);
- if (!*pinode) {
- rc = -ENOMEM;
- goto posix_open_ret;
- }
- } else {
- cifs_fattr_to_inode(*pinode, &fattr);
- }
-
-posix_open_ret:
- kfree(presp_data);
- return rc;
-}
-
-static int
-cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
- struct cifs_tcon *tcon, unsigned int f_flags, __u32 *poplock,
- __u16 *pnetfid, int xid)
-{
- int rc;
- int desiredAccess;
- int disposition;
- int create_options = CREATE_NOT_DIR;
- FILE_ALL_INFO *buf;
-
- desiredAccess = cifs_convert_flags(f_flags);
-
-/*********************************************************************
- * open flag mapping table:
- *
- * POSIX Flag CIFS Disposition
- * ---------- ----------------
- * O_CREAT FILE_OPEN_IF
- * O_CREAT | O_EXCL FILE_CREATE
- * O_CREAT | O_TRUNC FILE_OVERWRITE_IF
- * O_TRUNC FILE_OVERWRITE
- * none of the above FILE_OPEN
- *
- * Note that there is not a direct match between disposition
- * FILE_SUPERSEDE (ie create whether or not file exists although
- * O_CREAT | O_TRUNC is similar but truncates the existing
- * file rather than creating a new file as FILE_SUPERSEDE does
- * (which uses the attributes / metadata passed in on open call)
- *?
- *? O_SYNC is a reasonable match to CIFS writethrough flag
- *? and the read write flags match reasonably. O_LARGEFILE
- *? is irrelevant because largefile support is always used
- *? by this client. Flags O_APPEND, O_DIRECT, O_DIRECTORY,
- * O_FASYNC, O_NOFOLLOW, O_NONBLOCK need further investigation
- *********************************************************************/
-
- disposition = cifs_get_disposition(f_flags);
-
- /* BB pass O_SYNC flag through on file attributes .. BB */
-
- buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- if (backup_cred(cifs_sb))
- create_options |= CREATE_OPEN_BACKUP_INTENT;
-
- if (tcon->ses->capabilities & CAP_NT_SMBS)
- rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
- desiredAccess, create_options, pnetfid, poplock, buf,
- cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
- & CIFS_MOUNT_MAP_SPECIAL_CHR);
- else
- rc = SMBLegacyOpen(xid, tcon, full_path, disposition,
- desiredAccess, CREATE_NOT_DIR, pnetfid, poplock, buf,
- cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
- & CIFS_MOUNT_MAP_SPECIAL_CHR);
-
- if (rc)
- goto out;
-
- if (tcon->unix_ext)
- rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb,
- xid);
- else
- rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb,
- xid, pnetfid);
-
-out:
- kfree(buf);
- return rc;
-}
-
-struct cifsFileInfo *
-cifs_new_fileinfo(__u16 fileHandle, struct file *file,
- struct tcon_link *tlink, __u32 oplock)
-{
- struct dentry *dentry = file->f_path.dentry;
- struct inode *inode = dentry->d_inode;
- struct cifsInodeInfo *pCifsInode = CIFS_I(inode);
- struct cifsFileInfo *pCifsFile;
-
- pCifsFile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
- if (pCifsFile == NULL)
- return pCifsFile;
-
- pCifsFile->count = 1;
- pCifsFile->netfid = fileHandle;
- pCifsFile->pid = current->tgid;
- pCifsFile->uid = current_fsuid();
- pCifsFile->dentry = dget(dentry);
- pCifsFile->f_flags = file->f_flags;
- pCifsFile->invalidHandle = false;
- pCifsFile->tlink = cifs_get_tlink(tlink);
- mutex_init(&pCifsFile->fh_mutex);
- INIT_WORK(&pCifsFile->oplock_break, cifs_oplock_break);
-
- spin_lock(&cifs_file_list_lock);
- list_add(&pCifsFile->tlist, &(tlink_tcon(tlink)->openFileList));
- /* if readable file instance put first in list*/
- if (file->f_mode & FMODE_READ)
- list_add(&pCifsFile->flist, &pCifsInode->openFileList);
- else
- list_add_tail(&pCifsFile->flist, &pCifsInode->openFileList);
- spin_unlock(&cifs_file_list_lock);
-
- cifs_set_oplock_level(pCifsInode, oplock);
- pCifsInode->can_cache_brlcks = pCifsInode->clientCanCacheAll;
-
- file->private_data = pCifsFile;
- return pCifsFile;
-}
-
-static void cifs_del_lock_waiters(struct cifsLockInfo *lock);
-
-/*
- * Release a reference on the file private data. This may involve closing
- * the filehandle out on the server. Must be called without holding
- * cifs_file_list_lock.
- */
-void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
-{
- struct inode *inode = cifs_file->dentry->d_inode;
- struct cifs_tcon *tcon = tlink_tcon(cifs_file->tlink);
- struct cifsInodeInfo *cifsi = CIFS_I(inode);
- struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
- struct cifsLockInfo *li, *tmp;
-
- spin_lock(&cifs_file_list_lock);
- if (--cifs_file->count > 0) {
- spin_unlock(&cifs_file_list_lock);
- return;
- }
-
- /* remove it from the lists */
- list_del(&cifs_file->flist);
- list_del(&cifs_file->tlist);
-
- if (list_empty(&cifsi->openFileList)) {
- cFYI(1, "closing last open instance for inode %p",
- cifs_file->dentry->d_inode);
-
- /* in strict cache mode we need invalidate mapping on the last
- close because it may cause a error when we open this file
- again and get at least level II oplock */
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO)
- CIFS_I(inode)->invalid_mapping = true;
-
- cifs_set_oplock_level(cifsi, 0);
- }
- spin_unlock(&cifs_file_list_lock);
-
- cancel_work_sync(&cifs_file->oplock_break);
-
- if (!tcon->need_reconnect && !cifs_file->invalidHandle) {
- int xid, rc;
-
- xid = GetXid();
- rc = CIFSSMBClose(xid, tcon, cifs_file->netfid);
- FreeXid(xid);
- }
-
- /* Delete any outstanding lock records. We'll lose them when the file
- * is closed anyway.
- */
- mutex_lock(&cifsi->lock_mutex);
- list_for_each_entry_safe(li, tmp, &cifsi->llist, llist) {
- if (li->netfid != cifs_file->netfid)
- continue;
- list_del(&li->llist);
- cifs_del_lock_waiters(li);
- kfree(li);
- }
- mutex_unlock(&cifsi->lock_mutex);
-
- cifs_put_tlink(cifs_file->tlink);
- dput(cifs_file->dentry);
- kfree(cifs_file);
-}
-
-int cifs_open(struct inode *inode, struct file *file)
-{
- int rc = -EACCES;
- int xid;
- __u32 oplock;
- struct cifs_sb_info *cifs_sb;
- struct cifs_tcon *tcon;
- struct tcon_link *tlink;
- struct cifsFileInfo *pCifsFile = NULL;
- char *full_path = NULL;
- bool posix_open_ok = false;
- __u16 netfid;
-
- xid = GetXid();
-
- cifs_sb = CIFS_SB(inode->i_sb);
- tlink = cifs_sb_tlink(cifs_sb);
- if (IS_ERR(tlink)) {
- FreeXid(xid);
- return PTR_ERR(tlink);
- }
- tcon = tlink_tcon(tlink);
-
- full_path = build_path_from_dentry(file->f_path.dentry);
- if (full_path == NULL) {
- rc = -ENOMEM;
- goto out;
- }
-
- cFYI(1, "inode = 0x%p file flags are 0x%x for %s",
- inode, file->f_flags, full_path);
-
- if (tcon->ses->server->oplocks)
- oplock = REQ_OPLOCK;
- else
- oplock = 0;
-
- if (!tcon->broken_posix_open && tcon->unix_ext &&
- (tcon->ses->capabilities & CAP_UNIX) &&
- (CIFS_UNIX_POSIX_PATH_OPS_CAP &
- le64_to_cpu(tcon->fsUnixInfo.Capability))) {
- /* can not refresh inode info since size could be stale */
- rc = cifs_posix_open(full_path, &inode, inode->i_sb,
- cifs_sb->mnt_file_mode /* ignored */,
- file->f_flags, &oplock, &netfid, xid);
- if (rc == 0) {
- cFYI(1, "posix open succeeded");
- posix_open_ok = true;
- } else if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
- if (tcon->ses->serverNOS)
- cERROR(1, "server %s of type %s returned"
- " unexpected error on SMB posix open"
- ", disabling posix open support."
- " Check if server update available.",
- tcon->ses->serverName,
- tcon->ses->serverNOS);
- tcon->broken_posix_open = true;
- } else if ((rc != -EIO) && (rc != -EREMOTE) &&
- (rc != -EOPNOTSUPP)) /* path not found or net err */
- goto out;
- /* else fallthrough to retry open the old way on network i/o
- or DFS errors */
- }
-
- if (!posix_open_ok) {
- rc = cifs_nt_open(full_path, inode, cifs_sb, tcon,
- file->f_flags, &oplock, &netfid, xid);
- if (rc)
- goto out;
- }
-
- pCifsFile = cifs_new_fileinfo(netfid, file, tlink, oplock);
- if (pCifsFile == NULL) {
- CIFSSMBClose(xid, tcon, netfid);
- rc = -ENOMEM;
- goto out;
- }
-
- cifs_fscache_set_inode_cookie(inode, file);
-
- if ((oplock & CIFS_CREATE_ACTION) && !posix_open_ok && tcon->unix_ext) {
- /* time to set mode which we can not set earlier due to
- problems creating new read-only files */
- struct cifs_unix_set_info_args args = {
- .mode = inode->i_mode,
- .uid = NO_CHANGE_64,
- .gid = NO_CHANGE_64,
- .ctime = NO_CHANGE_64,
- .atime = NO_CHANGE_64,
- .mtime = NO_CHANGE_64,
- .device = 0,
- };
- CIFSSMBUnixSetFileInfo(xid, tcon, &args, netfid,
- pCifsFile->pid);
- }
-
-out:
- kfree(full_path);
- FreeXid(xid);
- cifs_put_tlink(tlink);
- return rc;
-}
-
-/* Try to reacquire byte range locks that were released when session */
-/* to server was lost */
-static int cifs_relock_file(struct cifsFileInfo *cifsFile)
-{
- int rc = 0;
-
-/* BB list all locks open on this file and relock */
-
- return rc;
-}
-
-static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush)
-{
- int rc = -EACCES;
- int xid;
- __u32 oplock;
- struct cifs_sb_info *cifs_sb;
- struct cifs_tcon *tcon;
- struct cifsInodeInfo *pCifsInode;
- struct inode *inode;
- char *full_path = NULL;
- int desiredAccess;
- int disposition = FILE_OPEN;
- int create_options = CREATE_NOT_DIR;
- __u16 netfid;
-
- xid = GetXid();
- mutex_lock(&pCifsFile->fh_mutex);
- if (!pCifsFile->invalidHandle) {
- mutex_unlock(&pCifsFile->fh_mutex);
- rc = 0;
- FreeXid(xid);
- return rc;
- }
-
- inode = pCifsFile->dentry->d_inode;
- cifs_sb = CIFS_SB(inode->i_sb);
- tcon = tlink_tcon(pCifsFile->tlink);
-
-/* can not grab rename sem here because various ops, including
- those that already have the rename sem can end up causing writepage
- to get called and if the server was down that means we end up here,
- and we can never tell if the caller already has the rename_sem */
- full_path = build_path_from_dentry(pCifsFile->dentry);
- if (full_path == NULL) {
- rc = -ENOMEM;
- mutex_unlock(&pCifsFile->fh_mutex);
- FreeXid(xid);
- return rc;
- }
-
- cFYI(1, "inode = 0x%p file flags 0x%x for %s",
- inode, pCifsFile->f_flags, full_path);
-
- if (tcon->ses->server->oplocks)
- oplock = REQ_OPLOCK;
- else
- oplock = 0;
-
- if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) &&
- (CIFS_UNIX_POSIX_PATH_OPS_CAP &
- le64_to_cpu(tcon->fsUnixInfo.Capability))) {
-
- /*
- * O_CREAT, O_EXCL and O_TRUNC already had their effect on the
- * original open. Must mask them off for a reopen.
- */
- unsigned int oflags = pCifsFile->f_flags &
- ~(O_CREAT | O_EXCL | O_TRUNC);
-
- rc = cifs_posix_open(full_path, NULL, inode->i_sb,
- cifs_sb->mnt_file_mode /* ignored */,
- oflags, &oplock, &netfid, xid);
- if (rc == 0) {
- cFYI(1, "posix reopen succeeded");
- goto reopen_success;
- }
- /* fallthrough to retry open the old way on errors, especially
- in the reconnect path it is important to retry hard */
- }
-
- desiredAccess = cifs_convert_flags(pCifsFile->f_flags);
-
- if (backup_cred(cifs_sb))
- create_options |= CREATE_OPEN_BACKUP_INTENT;
-
- /* Can not refresh inode by passing in file_info buf to be returned
- by SMBOpen and then calling get_inode_info with returned buf
- since file might have write behind data that needs to be flushed
- and server version of file size can be stale. If we knew for sure
- that inode was not dirty locally we could do this */
-
- rc = CIFSSMBOpen(xid, tcon, full_path, disposition, desiredAccess,
- create_options, &netfid, &oplock, NULL,
- cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- if (rc) {
- mutex_unlock(&pCifsFile->fh_mutex);
- cFYI(1, "cifs_open returned 0x%x", rc);
- cFYI(1, "oplock: %d", oplock);
- goto reopen_error_exit;
- }
-
-reopen_success:
- pCifsFile->netfid = netfid;
- pCifsFile->invalidHandle = false;
- mutex_unlock(&pCifsFile->fh_mutex);
- pCifsInode = CIFS_I(inode);
-
- if (can_flush) {
- rc = filemap_write_and_wait(inode->i_mapping);
- mapping_set_error(inode->i_mapping, rc);
-
- if (tcon->unix_ext)
- rc = cifs_get_inode_info_unix(&inode,
- full_path, inode->i_sb, xid);
- else
- rc = cifs_get_inode_info(&inode,
- full_path, NULL, inode->i_sb,
- xid, NULL);
- } /* else we are writing out data to server already
- and could deadlock if we tried to flush data, and
- since we do not know if we have data that would
- invalidate the current end of file on the server
- we can not go to the server to get the new inod
- info */
-
- cifs_set_oplock_level(pCifsInode, oplock);
-
- cifs_relock_file(pCifsFile);
-
-reopen_error_exit:
- kfree(full_path);
- FreeXid(xid);
- return rc;
-}
-
-int cifs_close(struct inode *inode, struct file *file)
-{
- if (file->private_data != NULL) {
- cifsFileInfo_put(file->private_data);
- file->private_data = NULL;
- }
-
- /* return code from the ->release op is always ignored */
- return 0;
-}
-
-int cifs_closedir(struct inode *inode, struct file *file)
-{
- int rc = 0;
- int xid;
- struct cifsFileInfo *pCFileStruct = file->private_data;
- char *ptmp;
-
- cFYI(1, "Closedir inode = 0x%p", inode);
-
- xid = GetXid();
-
- if (pCFileStruct) {
- struct cifs_tcon *pTcon = tlink_tcon(pCFileStruct->tlink);
-
- cFYI(1, "Freeing private data in close dir");
- spin_lock(&cifs_file_list_lock);
- if (!pCFileStruct->srch_inf.endOfSearch &&
- !pCFileStruct->invalidHandle) {
- pCFileStruct->invalidHandle = true;
- spin_unlock(&cifs_file_list_lock);
- rc = CIFSFindClose(xid, pTcon, pCFileStruct->netfid);
- cFYI(1, "Closing uncompleted readdir with rc %d",
- rc);
- /* not much we can do if it fails anyway, ignore rc */
- rc = 0;
- } else
- spin_unlock(&cifs_file_list_lock);
- ptmp = pCFileStruct->srch_inf.ntwrk_buf_start;
- if (ptmp) {
- cFYI(1, "closedir free smb buf in srch struct");
- pCFileStruct->srch_inf.ntwrk_buf_start = NULL;
- if (pCFileStruct->srch_inf.smallBuf)
- cifs_small_buf_release(ptmp);
- else
- cifs_buf_release(ptmp);
- }
- cifs_put_tlink(pCFileStruct->tlink);
- kfree(file->private_data);
- file->private_data = NULL;
- }
- /* BB can we lock the filestruct while this is going on? */
- FreeXid(xid);
- return rc;
-}
-
-static struct cifsLockInfo *
-cifs_lock_init(__u64 offset, __u64 length, __u8 type, __u16 netfid)
-{
- struct cifsLockInfo *lock =
- kmalloc(sizeof(struct cifsLockInfo), GFP_KERNEL);
- if (!lock)
- return lock;
- lock->offset = offset;
- lock->length = length;
- lock->type = type;
- lock->netfid = netfid;
- lock->pid = current->tgid;
- INIT_LIST_HEAD(&lock->blist);
- init_waitqueue_head(&lock->block_q);
- return lock;
-}
-
-static void
-cifs_del_lock_waiters(struct cifsLockInfo *lock)
-{
- struct cifsLockInfo *li, *tmp;
- list_for_each_entry_safe(li, tmp, &lock->blist, blist) {
- list_del_init(&li->blist);
- wake_up(&li->block_q);
- }
-}
-
-static bool
-__cifs_find_lock_conflict(struct cifsInodeInfo *cinode, __u64 offset,
- __u64 length, __u8 type, __u16 netfid,
- struct cifsLockInfo **conf_lock)
-{
- struct cifsLockInfo *li, *tmp;
-
- list_for_each_entry_safe(li, tmp, &cinode->llist, llist) {
- if (offset + length <= li->offset ||
- offset >= li->offset + li->length)
- continue;
- else if ((type & LOCKING_ANDX_SHARED_LOCK) &&
- ((netfid == li->netfid && current->tgid == li->pid) ||
- type == li->type))
- continue;
- else {
- *conf_lock = li;
- return true;
- }
- }
- return false;
-}
-
-static bool
-cifs_find_lock_conflict(struct cifsInodeInfo *cinode, struct cifsLockInfo *lock,
- struct cifsLockInfo **conf_lock)
-{
- return __cifs_find_lock_conflict(cinode, lock->offset, lock->length,
- lock->type, lock->netfid, conf_lock);
-}
-
-/*
- * Check if there is another lock that prevents us to set the lock (mandatory
- * style). If such a lock exists, update the flock structure with its
- * properties. Otherwise, set the flock type to F_UNLCK if we can cache brlocks
- * or leave it the same if we can't. Returns 0 if we don't need to request to
- * the server or 1 otherwise.
- */
-static int
-cifs_lock_test(struct cifsInodeInfo *cinode, __u64 offset, __u64 length,
- __u8 type, __u16 netfid, struct file_lock *flock)
-{
- int rc = 0;
- struct cifsLockInfo *conf_lock;
- bool exist;
-
- mutex_lock(&cinode->lock_mutex);
-
- exist = __cifs_find_lock_conflict(cinode, offset, length, type, netfid,
- &conf_lock);
- if (exist) {
- flock->fl_start = conf_lock->offset;
- flock->fl_end = conf_lock->offset + conf_lock->length - 1;
- flock->fl_pid = conf_lock->pid;
- if (conf_lock->type & LOCKING_ANDX_SHARED_LOCK)
- flock->fl_type = F_RDLCK;
- else
- flock->fl_type = F_WRLCK;
- } else if (!cinode->can_cache_brlcks)
- rc = 1;
- else
- flock->fl_type = F_UNLCK;
-
- mutex_unlock(&cinode->lock_mutex);
- return rc;
-}
-
-static void
-cifs_lock_add(struct cifsInodeInfo *cinode, struct cifsLockInfo *lock)
-{
- mutex_lock(&cinode->lock_mutex);
- list_add_tail(&lock->llist, &cinode->llist);
- mutex_unlock(&cinode->lock_mutex);
-}
-
-/*
- * Set the byte-range lock (mandatory style). Returns:
- * 1) 0, if we set the lock and don't need to request to the server;
- * 2) 1, if no locks prevent us but we need to request to the server;
- * 3) -EACCESS, if there is a lock that prevents us and wait is false.
- */
-static int
-cifs_lock_add_if(struct cifsInodeInfo *cinode, struct cifsLockInfo *lock,
- bool wait)
-{
- struct cifsLockInfo *conf_lock;
- bool exist;
- int rc = 0;
-
-try_again:
- exist = false;
- mutex_lock(&cinode->lock_mutex);
-
- exist = cifs_find_lock_conflict(cinode, lock, &conf_lock);
- if (!exist && cinode->can_cache_brlcks) {
- list_add_tail(&lock->llist, &cinode->llist);
- mutex_unlock(&cinode->lock_mutex);
- return rc;
- }
-
- if (!exist)
- rc = 1;
- else if (!wait)
- rc = -EACCES;
- else {
- list_add_tail(&lock->blist, &conf_lock->blist);
- mutex_unlock(&cinode->lock_mutex);
- rc = wait_event_interruptible(lock->block_q,
- (lock->blist.prev == &lock->blist) &&
- (lock->blist.next == &lock->blist));
- if (!rc)
- goto try_again;
- mutex_lock(&cinode->lock_mutex);
- list_del_init(&lock->blist);
- }
-
- mutex_unlock(&cinode->lock_mutex);
- return rc;
-}
-
-/*
- * Check if there is another lock that prevents us to set the lock (posix
- * style). If such a lock exists, update the flock structure with its
- * properties. Otherwise, set the flock type to F_UNLCK if we can cache brlocks
- * or leave it the same if we can't. Returns 0 if we don't need to request to
- * the server or 1 otherwise.
- */
-static int
-cifs_posix_lock_test(struct file *file, struct file_lock *flock)
-{
- int rc = 0;
- struct cifsInodeInfo *cinode = CIFS_I(file->f_path.dentry->d_inode);
- unsigned char saved_type = flock->fl_type;
-
- if ((flock->fl_flags & FL_POSIX) == 0)
- return 1;
-
- mutex_lock(&cinode->lock_mutex);
- posix_test_lock(file, flock);
-
- if (flock->fl_type == F_UNLCK && !cinode->can_cache_brlcks) {
- flock->fl_type = saved_type;
- rc = 1;
- }
-
- mutex_unlock(&cinode->lock_mutex);
- return rc;
-}
-
-/*
- * Set the byte-range lock (posix style). Returns:
- * 1) 0, if we set the lock and don't need to request to the server;
- * 2) 1, if we need to request to the server;
- * 3) <0, if the error occurs while setting the lock.
- */
-static int
-cifs_posix_lock_set(struct file *file, struct file_lock *flock)
-{
- struct cifsInodeInfo *cinode = CIFS_I(file->f_path.dentry->d_inode);
- int rc = 1;
-
- if ((flock->fl_flags & FL_POSIX) == 0)
- return rc;
-
-try_again:
- mutex_lock(&cinode->lock_mutex);
- if (!cinode->can_cache_brlcks) {
- mutex_unlock(&cinode->lock_mutex);
- return rc;
- }
-
- rc = posix_lock_file(file, flock, NULL);
- mutex_unlock(&cinode->lock_mutex);
- if (rc == FILE_LOCK_DEFERRED) {
- rc = wait_event_interruptible(flock->fl_wait, !flock->fl_next);
- if (!rc)
- goto try_again;
- locks_delete_block(flock);
- }
- return rc;
-}
-
-static int
-cifs_push_mandatory_locks(struct cifsFileInfo *cfile)
-{
- int xid, rc = 0, stored_rc;
- struct cifsLockInfo *li, *tmp;
- struct cifs_tcon *tcon;
- struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
- unsigned int num, max_num;
- LOCKING_ANDX_RANGE *buf, *cur;
- int types[] = {LOCKING_ANDX_LARGE_FILES,
- LOCKING_ANDX_SHARED_LOCK | LOCKING_ANDX_LARGE_FILES};
- int i;
-
- xid = GetXid();
- tcon = tlink_tcon(cfile->tlink);
-
- mutex_lock(&cinode->lock_mutex);
- if (!cinode->can_cache_brlcks) {
- mutex_unlock(&cinode->lock_mutex);
- FreeXid(xid);
- return rc;
- }
-
- max_num = (tcon->ses->server->maxBuf - sizeof(struct smb_hdr)) /
- sizeof(LOCKING_ANDX_RANGE);
- buf = kzalloc(max_num * sizeof(LOCKING_ANDX_RANGE), GFP_KERNEL);
- if (!buf) {
- mutex_unlock(&cinode->lock_mutex);
- FreeXid(xid);
- return rc;
- }
-
- for (i = 0; i < 2; i++) {
- cur = buf;
- num = 0;
- list_for_each_entry_safe(li, tmp, &cinode->llist, llist) {
- if (li->type != types[i])
- continue;
- cur->Pid = cpu_to_le16(li->pid);
- cur->LengthLow = cpu_to_le32((u32)li->length);
- cur->LengthHigh = cpu_to_le32((u32)(li->length>>32));
- cur->OffsetLow = cpu_to_le32((u32)li->offset);
- cur->OffsetHigh = cpu_to_le32((u32)(li->offset>>32));
- if (++num == max_num) {
- stored_rc = cifs_lockv(xid, tcon, cfile->netfid,
- li->type, 0, num, buf);
- if (stored_rc)
- rc = stored_rc;
- cur = buf;
- num = 0;
- } else
- cur++;
- }
-
- if (num) {
- stored_rc = cifs_lockv(xid, tcon, cfile->netfid,
- types[i], 0, num, buf);
- if (stored_rc)
- rc = stored_rc;
- }
- }
-
- cinode->can_cache_brlcks = false;
- mutex_unlock(&cinode->lock_mutex);
-
- kfree(buf);
- FreeXid(xid);
- return rc;
-}
-
-/* copied from fs/locks.c with a name change */
-#define cifs_for_each_lock(inode, lockp) \
- for (lockp = &inode->i_flock; *lockp != NULL; \
- lockp = &(*lockp)->fl_next)
-
-struct lock_to_push {
- struct list_head llist;
- __u64 offset;
- __u64 length;
- __u32 pid;
- __u16 netfid;
- __u8 type;
-};
-
-static int
-cifs_push_posix_locks(struct cifsFileInfo *cfile)
-{
- struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
- struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
- struct file_lock *flock, **before;
- unsigned int count = 0, i = 0;
- int rc = 0, xid, type;
- struct list_head locks_to_send, *el;
- struct lock_to_push *lck, *tmp;
- __u64 length;
-
- xid = GetXid();
-
- mutex_lock(&cinode->lock_mutex);
- if (!cinode->can_cache_brlcks) {
- mutex_unlock(&cinode->lock_mutex);
- FreeXid(xid);
- return rc;
- }
-
- lock_flocks();
- cifs_for_each_lock(cfile->dentry->d_inode, before) {
- if ((*before)->fl_flags & FL_POSIX)
- count++;
- }
- unlock_flocks();
-
- INIT_LIST_HEAD(&locks_to_send);
-
- /*
- * Allocating count locks is enough because no FL_POSIX locks can be
- * added to the list while we are holding cinode->lock_mutex that
- * protects locking operations of this inode.
- */
- for (; i < count; i++) {
- lck = kmalloc(sizeof(struct lock_to_push), GFP_KERNEL);
- if (!lck) {
- rc = -ENOMEM;
- goto err_out;
- }
- list_add_tail(&lck->llist, &locks_to_send);
- }
-
- el = locks_to_send.next;
- lock_flocks();
- cifs_for_each_lock(cfile->dentry->d_inode, before) {
- flock = *before;
- if ((flock->fl_flags & FL_POSIX) == 0)
- continue;
- if (el == &locks_to_send) {
- /*
- * The list ended. We don't have enough allocated
- * structures - something is really wrong.
- */
- cERROR(1, "Can't push all brlocks!");
- break;
- }
- length = 1 + flock->fl_end - flock->fl_start;
- if (flock->fl_type == F_RDLCK || flock->fl_type == F_SHLCK)
- type = CIFS_RDLCK;
- else
- type = CIFS_WRLCK;
- lck = list_entry(el, struct lock_to_push, llist);
- lck->pid = flock->fl_pid;
- lck->netfid = cfile->netfid;
- lck->length = length;
- lck->type = type;
- lck->offset = flock->fl_start;
- el = el->next;
- }
- unlock_flocks();
-
- list_for_each_entry_safe(lck, tmp, &locks_to_send, llist) {
- struct file_lock tmp_lock;
- int stored_rc;
-
- tmp_lock.fl_start = lck->offset;
- stored_rc = CIFSSMBPosixLock(xid, tcon, lck->netfid, lck->pid,
- 0, lck->length, &tmp_lock,
- lck->type, 0);
- if (stored_rc)
- rc = stored_rc;
- list_del(&lck->llist);
- kfree(lck);
- }
-
-out:
- cinode->can_cache_brlcks = false;
- mutex_unlock(&cinode->lock_mutex);
-
- FreeXid(xid);
- return rc;
-err_out:
- list_for_each_entry_safe(lck, tmp, &locks_to_send, llist) {
- list_del(&lck->llist);
- kfree(lck);
- }
- goto out;
-}
-
-static int
-cifs_push_locks(struct cifsFileInfo *cfile)
-{
- struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb);
- struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
-
- if ((tcon->ses->capabilities & CAP_UNIX) &&
- (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
- ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
- return cifs_push_posix_locks(cfile);
-
- return cifs_push_mandatory_locks(cfile);
-}
-
-static void
-cifs_read_flock(struct file_lock *flock, __u8 *type, int *lock, int *unlock,
- bool *wait_flag)
-{
- if (flock->fl_flags & FL_POSIX)
- cFYI(1, "Posix");
- if (flock->fl_flags & FL_FLOCK)
- cFYI(1, "Flock");
- if (flock->fl_flags & FL_SLEEP) {
- cFYI(1, "Blocking lock");
- *wait_flag = true;
- }
- if (flock->fl_flags & FL_ACCESS)
- cFYI(1, "Process suspended by mandatory locking - "
- "not implemented yet");
- if (flock->fl_flags & FL_LEASE)
- cFYI(1, "Lease on file - not implemented yet");
- if (flock->fl_flags &
- (~(FL_POSIX | FL_FLOCK | FL_SLEEP | FL_ACCESS | FL_LEASE)))
- cFYI(1, "Unknown lock flags 0x%x", flock->fl_flags);
-
- *type = LOCKING_ANDX_LARGE_FILES;
- if (flock->fl_type == F_WRLCK) {
- cFYI(1, "F_WRLCK ");
- *lock = 1;
- } else if (flock->fl_type == F_UNLCK) {
- cFYI(1, "F_UNLCK");
- *unlock = 1;
- /* Check if unlock includes more than one lock range */
- } else if (flock->fl_type == F_RDLCK) {
- cFYI(1, "F_RDLCK");
- *type |= LOCKING_ANDX_SHARED_LOCK;
- *lock = 1;
- } else if (flock->fl_type == F_EXLCK) {
- cFYI(1, "F_EXLCK");
- *lock = 1;
- } else if (flock->fl_type == F_SHLCK) {
- cFYI(1, "F_SHLCK");
- *type |= LOCKING_ANDX_SHARED_LOCK;
- *lock = 1;
- } else
- cFYI(1, "Unknown type of lock");
-}
-
-static int
-cifs_getlk(struct file *file, struct file_lock *flock, __u8 type,
- bool wait_flag, bool posix_lck, int xid)
-{
- int rc = 0;
- __u64 length = 1 + flock->fl_end - flock->fl_start;
- struct cifsFileInfo *cfile = (struct cifsFileInfo *)file->private_data;
- struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
- struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
- __u16 netfid = cfile->netfid;
-
- if (posix_lck) {
- int posix_lock_type;
-
- rc = cifs_posix_lock_test(file, flock);
- if (!rc)
- return rc;
-
- if (type & LOCKING_ANDX_SHARED_LOCK)
- posix_lock_type = CIFS_RDLCK;
- else
- posix_lock_type = CIFS_WRLCK;
- rc = CIFSSMBPosixLock(xid, tcon, netfid, current->tgid,
- 1 /* get */, length, flock,
- posix_lock_type, wait_flag);
- return rc;
- }
-
- rc = cifs_lock_test(cinode, flock->fl_start, length, type, netfid,
- flock);
- if (!rc)
- return rc;
-
- /* BB we could chain these into one lock request BB */
- rc = CIFSSMBLock(xid, tcon, netfid, current->tgid, length,
- flock->fl_start, 0, 1, type, 0, 0);
- if (rc == 0) {
- rc = CIFSSMBLock(xid, tcon, netfid, current->tgid,
- length, flock->fl_start, 1, 0,
- type, 0, 0);
- flock->fl_type = F_UNLCK;
- if (rc != 0)
- cERROR(1, "Error unlocking previously locked "
- "range %d during test of lock", rc);
- return 0;
- }
-
- if (type & LOCKING_ANDX_SHARED_LOCK) {
- flock->fl_type = F_WRLCK;
- return 0;
- }
-
- rc = CIFSSMBLock(xid, tcon, netfid, current->tgid, length,
- flock->fl_start, 0, 1,
- type | LOCKING_ANDX_SHARED_LOCK, 0, 0);
- if (rc == 0) {
- rc = CIFSSMBLock(xid, tcon, netfid, current->tgid,
- length, flock->fl_start, 1, 0,
- type | LOCKING_ANDX_SHARED_LOCK,
- 0, 0);
- flock->fl_type = F_RDLCK;
- if (rc != 0)
- cERROR(1, "Error unlocking previously locked "
- "range %d during test of lock", rc);
- } else
- flock->fl_type = F_WRLCK;
-
- return 0;
-}
-
-static void
-cifs_move_llist(struct list_head *source, struct list_head *dest)
-{
- struct list_head *li, *tmp;
- list_for_each_safe(li, tmp, source)
- list_move(li, dest);
-}
-
-static void
-cifs_free_llist(struct list_head *llist)
-{
- struct cifsLockInfo *li, *tmp;
- list_for_each_entry_safe(li, tmp, llist, llist) {
- cifs_del_lock_waiters(li);
- list_del(&li->llist);
- kfree(li);
- }
-}
-
-static int
-cifs_unlock_range(struct cifsFileInfo *cfile, struct file_lock *flock, int xid)
-{
- int rc = 0, stored_rc;
- int types[] = {LOCKING_ANDX_LARGE_FILES,
- LOCKING_ANDX_SHARED_LOCK | LOCKING_ANDX_LARGE_FILES};
- unsigned int i;
- unsigned int max_num, num;
- LOCKING_ANDX_RANGE *buf, *cur;
- struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
- struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
- struct cifsLockInfo *li, *tmp;
- __u64 length = 1 + flock->fl_end - flock->fl_start;
- struct list_head tmp_llist;
-
- INIT_LIST_HEAD(&tmp_llist);
-
- max_num = (tcon->ses->server->maxBuf - sizeof(struct smb_hdr)) /
- sizeof(LOCKING_ANDX_RANGE);
- buf = kzalloc(max_num * sizeof(LOCKING_ANDX_RANGE), GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- mutex_lock(&cinode->lock_mutex);
- for (i = 0; i < 2; i++) {
- cur = buf;
- num = 0;
- list_for_each_entry_safe(li, tmp, &cinode->llist, llist) {
- if (flock->fl_start > li->offset ||
- (flock->fl_start + length) <
- (li->offset + li->length))
- continue;
- if (current->tgid != li->pid)
- continue;
- if (cfile->netfid != li->netfid)
- continue;
- if (types[i] != li->type)
- continue;
- if (!cinode->can_cache_brlcks) {
- cur->Pid = cpu_to_le16(li->pid);
- cur->LengthLow = cpu_to_le32((u32)li->length);
- cur->LengthHigh =
- cpu_to_le32((u32)(li->length>>32));
- cur->OffsetLow = cpu_to_le32((u32)li->offset);
- cur->OffsetHigh =
- cpu_to_le32((u32)(li->offset>>32));
- /*
- * We need to save a lock here to let us add
- * it again to the inode list if the unlock
- * range request fails on the server.
- */
- list_move(&li->llist, &tmp_llist);
- if (++num == max_num) {
- stored_rc = cifs_lockv(xid, tcon,
- cfile->netfid,
- li->type, num,
- 0, buf);
- if (stored_rc) {
- /*
- * We failed on the unlock range
- * request - add all locks from
- * the tmp list to the head of
- * the inode list.
- */
- cifs_move_llist(&tmp_llist,
- &cinode->llist);
- rc = stored_rc;
- } else
- /*
- * The unlock range request
- * succeed - free the tmp list.
- */
- cifs_free_llist(&tmp_llist);
- cur = buf;
- num = 0;
- } else
- cur++;
- } else {
- /*
- * We can cache brlock requests - simply remove
- * a lock from the inode list.
- */
- list_del(&li->llist);
- cifs_del_lock_waiters(li);
- kfree(li);
- }
- }
- if (num) {
- stored_rc = cifs_lockv(xid, tcon, cfile->netfid,
- types[i], num, 0, buf);
- if (stored_rc) {
- cifs_move_llist(&tmp_llist, &cinode->llist);
- rc = stored_rc;
- } else
- cifs_free_llist(&tmp_llist);
- }
- }
-
- mutex_unlock(&cinode->lock_mutex);
- kfree(buf);
- return rc;
-}
-
-static int
-cifs_setlk(struct file *file, struct file_lock *flock, __u8 type,
- bool wait_flag, bool posix_lck, int lock, int unlock, int xid)
-{
- int rc = 0;
- __u64 length = 1 + flock->fl_end - flock->fl_start;
- struct cifsFileInfo *cfile = (struct cifsFileInfo *)file->private_data;
- struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
- struct cifsInodeInfo *cinode = CIFS_I(file->f_path.dentry->d_inode);
- __u16 netfid = cfile->netfid;
-
- if (posix_lck) {
- int posix_lock_type;
-
- rc = cifs_posix_lock_set(file, flock);
- if (!rc || rc < 0)
- return rc;
-
- if (type & LOCKING_ANDX_SHARED_LOCK)
- posix_lock_type = CIFS_RDLCK;
- else
- posix_lock_type = CIFS_WRLCK;
-
- if (unlock == 1)
- posix_lock_type = CIFS_UNLCK;
-
- rc = CIFSSMBPosixLock(xid, tcon, netfid, current->tgid,
- 0 /* set */, length, flock,
- posix_lock_type, wait_flag);
- goto out;
- }
-
- if (lock) {
- struct cifsLockInfo *lock;
-
- lock = cifs_lock_init(flock->fl_start, length, type, netfid);
- if (!lock)
- return -ENOMEM;
-
- rc = cifs_lock_add_if(cinode, lock, wait_flag);
- if (rc < 0)
- kfree(lock);
- if (rc <= 0)
- goto out;
-
- rc = CIFSSMBLock(xid, tcon, netfid, current->tgid, length,
- flock->fl_start, 0, 1, type, wait_flag, 0);
- if (rc) {
- kfree(lock);
- goto out;
- }
-
- cifs_lock_add(cinode, lock);
- } else if (unlock)
- rc = cifs_unlock_range(cfile, flock, xid);
-
-out:
- if (flock->fl_flags & FL_POSIX)
- posix_lock_file_wait(file, flock);
- return rc;
-}
-
-int cifs_lock(struct file *file, int cmd, struct file_lock *flock)
-{
- int rc, xid;
- int lock = 0, unlock = 0;
- bool wait_flag = false;
- bool posix_lck = false;
- struct cifs_sb_info *cifs_sb;
- struct cifs_tcon *tcon;
- struct cifsInodeInfo *cinode;
- struct cifsFileInfo *cfile;
- __u16 netfid;
- __u8 type;
-
- rc = -EACCES;
- xid = GetXid();
-
- cFYI(1, "Lock parm: 0x%x flockflags: 0x%x flocktype: 0x%x start: %lld "
- "end: %lld", cmd, flock->fl_flags, flock->fl_type,
- flock->fl_start, flock->fl_end);
-
- cifs_read_flock(flock, &type, &lock, &unlock, &wait_flag);
-
- cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
- cfile = (struct cifsFileInfo *)file->private_data;
- tcon = tlink_tcon(cfile->tlink);
- netfid = cfile->netfid;
- cinode = CIFS_I(file->f_path.dentry->d_inode);
-
- if ((tcon->ses->capabilities & CAP_UNIX) &&
- (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
- ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
- posix_lck = true;
- /*
- * BB add code here to normalize offset and length to account for
- * negative length which we can not accept over the wire.
- */
- if (IS_GETLK(cmd)) {
- rc = cifs_getlk(file, flock, type, wait_flag, posix_lck, xid);
- FreeXid(xid);
- return rc;
- }
-
- if (!lock && !unlock) {
- /*
- * if no lock or unlock then nothing to do since we do not
- * know what it is
- */
- FreeXid(xid);
- return -EOPNOTSUPP;
- }
-
- rc = cifs_setlk(file, flock, type, wait_flag, posix_lck, lock, unlock,
- xid);
- FreeXid(xid);
- return rc;
-}
-
-/*
- * update the file size (if needed) after a write. Should be called with
- * the inode->i_lock held
- */
-void
-cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
- unsigned int bytes_written)
-{
- loff_t end_of_write = offset + bytes_written;
-
- if (end_of_write > cifsi->server_eof)
- cifsi->server_eof = end_of_write;
-}
-
-static ssize_t cifs_write(struct cifsFileInfo *open_file, __u32 pid,
- const char *write_data, size_t write_size,
- loff_t *poffset)
-{
- int rc = 0;
- unsigned int bytes_written = 0;
- unsigned int total_written;
- struct cifs_sb_info *cifs_sb;
- struct cifs_tcon *pTcon;
- int xid;
- struct dentry *dentry = open_file->dentry;
- struct cifsInodeInfo *cifsi = CIFS_I(dentry->d_inode);
- struct cifs_io_parms io_parms;
-
- cifs_sb = CIFS_SB(dentry->d_sb);
-
- cFYI(1, "write %zd bytes to offset %lld of %s", write_size,
- *poffset, dentry->d_name.name);
-
- pTcon = tlink_tcon(open_file->tlink);
-
- xid = GetXid();
-
- for (total_written = 0; write_size > total_written;
- total_written += bytes_written) {
- rc = -EAGAIN;
- while (rc == -EAGAIN) {
- struct kvec iov[2];
- unsigned int len;
-
- if (open_file->invalidHandle) {
- /* we could deadlock if we called
- filemap_fdatawait from here so tell
- reopen_file not to flush data to
- server now */
- rc = cifs_reopen_file(open_file, false);
- if (rc != 0)
- break;
- }
-
- len = min((size_t)cifs_sb->wsize,
- write_size - total_written);
- /* iov[0] is reserved for smb header */
- iov[1].iov_base = (char *)write_data + total_written;
- iov[1].iov_len = len;
- io_parms.netfid = open_file->netfid;
- io_parms.pid = pid;
- io_parms.tcon = pTcon;
- io_parms.offset = *poffset;
- io_parms.length = len;
- rc = CIFSSMBWrite2(xid, &io_parms, &bytes_written, iov,
- 1, 0);
- }
- if (rc || (bytes_written == 0)) {
- if (total_written)
- break;
- else {
- FreeXid(xid);
- return rc;
- }
- } else {
- spin_lock(&dentry->d_inode->i_lock);
- cifs_update_eof(cifsi, *poffset, bytes_written);
- spin_unlock(&dentry->d_inode->i_lock);
- *poffset += bytes_written;
- }
- }
-
- cifs_stats_bytes_written(pTcon, total_written);
-
- if (total_written > 0) {
- spin_lock(&dentry->d_inode->i_lock);
- if (*poffset > dentry->d_inode->i_size)
- i_size_write(dentry->d_inode, *poffset);
- spin_unlock(&dentry->d_inode->i_lock);
- }
- mark_inode_dirty_sync(dentry->d_inode);
- FreeXid(xid);
- return total_written;
-}
-
-struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
- bool fsuid_only)
-{
- struct cifsFileInfo *open_file = NULL;
- struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb);
-
- /* only filter by fsuid on multiuser mounts */
- if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
- fsuid_only = false;
-
- spin_lock(&cifs_file_list_lock);
- /* we could simply get the first_list_entry since write-only entries
- are always at the end of the list but since the first entry might
- have a close pending, we go through the whole list */
- list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
- if (fsuid_only && open_file->uid != current_fsuid())
- continue;
- if (OPEN_FMODE(open_file->f_flags) & FMODE_READ) {
- if (!open_file->invalidHandle) {
- /* found a good file */
- /* lock it so it will not be closed on us */
- cifsFileInfo_get(open_file);
- spin_unlock(&cifs_file_list_lock);
- return open_file;
- } /* else might as well continue, and look for
- another, or simply have the caller reopen it
- again rather than trying to fix this handle */
- } else /* write only file */
- break; /* write only files are last so must be done */
- }
- spin_unlock(&cifs_file_list_lock);
- return NULL;
-}
-
-struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode,
- bool fsuid_only)
-{
- struct cifsFileInfo *open_file, *inv_file = NULL;
- struct cifs_sb_info *cifs_sb;
- bool any_available = false;
- int rc;
- unsigned int refind = 0;
-
- /* Having a null inode here (because mapping->host was set to zero by
- the VFS or MM) should not happen but we had reports of on oops (due to
- it being zero) during stress testcases so we need to check for it */
-
- if (cifs_inode == NULL) {
- cERROR(1, "Null inode passed to cifs_writeable_file");
- dump_stack();
- return NULL;
- }
-
- cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb);
-
- /* only filter by fsuid on multiuser mounts */
- if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
- fsuid_only = false;
-
- spin_lock(&cifs_file_list_lock);
-refind_writable:
- if (refind > MAX_REOPEN_ATT) {
- spin_unlock(&cifs_file_list_lock);
- return NULL;
- }
- list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
- if (!any_available && open_file->pid != current->tgid)
- continue;
- if (fsuid_only && open_file->uid != current_fsuid())
- continue;
- if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) {
- if (!open_file->invalidHandle) {
- /* found a good writable file */
- cifsFileInfo_get(open_file);
- spin_unlock(&cifs_file_list_lock);
- return open_file;
- } else {
- if (!inv_file)
- inv_file = open_file;
- }
- }
- }
- /* couldn't find useable FH with same pid, try any available */
- if (!any_available) {
- any_available = true;
- goto refind_writable;
- }
-
- if (inv_file) {
- any_available = false;
- cifsFileInfo_get(inv_file);
- }
-
- spin_unlock(&cifs_file_list_lock);
-
- if (inv_file) {
- rc = cifs_reopen_file(inv_file, false);
- if (!rc)
- return inv_file;
- else {
- spin_lock(&cifs_file_list_lock);
- list_move_tail(&inv_file->flist,
- &cifs_inode->openFileList);
- spin_unlock(&cifs_file_list_lock);
- cifsFileInfo_put(inv_file);
- spin_lock(&cifs_file_list_lock);
- ++refind;
- goto refind_writable;
- }
- }
-
- return NULL;
-}
-
-static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
-{
- struct address_space *mapping = page->mapping;
- loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
- char *write_data;
- int rc = -EFAULT;
- int bytes_written = 0;
- struct inode *inode;
- struct cifsFileInfo *open_file;
-
- if (!mapping || !mapping->host)
- return -EFAULT;
-
- inode = page->mapping->host;
-
- offset += (loff_t)from;
- write_data = kmap(page);
- write_data += from;
-
- if ((to > PAGE_CACHE_SIZE) || (from > to)) {
- kunmap(page);
- return -EIO;
- }
-
- /* racing with truncate? */
- if (offset > mapping->host->i_size) {
- kunmap(page);
- return 0; /* don't care */
- }
-
- /* check to make sure that we are not extending the file */
- if (mapping->host->i_size - offset < (loff_t)to)
- to = (unsigned)(mapping->host->i_size - offset);
-
- open_file = find_writable_file(CIFS_I(mapping->host), false);
- if (open_file) {
- bytes_written = cifs_write(open_file, open_file->pid,
- write_data, to - from, &offset);
- cifsFileInfo_put(open_file);
- /* Does mm or vfs already set times? */
- inode->i_atime = inode->i_mtime = current_fs_time(inode->i_sb);
- if ((bytes_written > 0) && (offset))
- rc = 0;
- else if (bytes_written < 0)
- rc = bytes_written;
- } else {
- cFYI(1, "No writeable filehandles for inode");
- rc = -EIO;
- }
-
- kunmap(page);
- return rc;
-}
-
-/*
- * Marshal up the iov array, reserving the first one for the header. Also,
- * set wdata->bytes.
- */
-static void
-cifs_writepages_marshal_iov(struct kvec *iov, struct cifs_writedata *wdata)
-{
- int i;
- struct inode *inode = wdata->cfile->dentry->d_inode;
- loff_t size = i_size_read(inode);
-
- /* marshal up the pages into iov array */
- wdata->bytes = 0;
- for (i = 0; i < wdata->nr_pages; i++) {
- iov[i + 1].iov_len = min(size - page_offset(wdata->pages[i]),
- (loff_t)PAGE_CACHE_SIZE);
- iov[i + 1].iov_base = kmap(wdata->pages[i]);
- wdata->bytes += iov[i + 1].iov_len;
- }
-}
-
-static int cifs_writepages(struct address_space *mapping,
- struct writeback_control *wbc)
-{
- struct cifs_sb_info *cifs_sb = CIFS_SB(mapping->host->i_sb);
- bool done = false, scanned = false, range_whole = false;
- pgoff_t end, index;
- struct cifs_writedata *wdata;
- struct page *page;
- int rc = 0;
-
- /*
- * If wsize is smaller than the page cache size, default to writing
- * one page at a time via cifs_writepage
- */
- if (cifs_sb->wsize < PAGE_CACHE_SIZE)
- return generic_writepages(mapping, wbc);
-
- if (wbc->range_cyclic) {
- index = mapping->writeback_index; /* Start from prev offset */
- end = -1;
- } else {
- index = wbc->range_start >> PAGE_CACHE_SHIFT;
- end = wbc->range_end >> PAGE_CACHE_SHIFT;
- if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
- range_whole = true;
- scanned = true;
- }
-retry:
- while (!done && index <= end) {
- unsigned int i, nr_pages, found_pages;
- pgoff_t next = 0, tofind;
- struct page **pages;
-
- tofind = min((cifs_sb->wsize / PAGE_CACHE_SIZE) - 1,
- end - index) + 1;
-
- wdata = cifs_writedata_alloc((unsigned int)tofind,
- cifs_writev_complete);
- if (!wdata) {
- rc = -ENOMEM;
- break;
- }
-
- /*
- * find_get_pages_tag seems to return a max of 256 on each
- * iteration, so we must call it several times in order to
- * fill the array or the wsize is effectively limited to
- * 256 * PAGE_CACHE_SIZE.
- */
- found_pages = 0;
- pages = wdata->pages;
- do {
- nr_pages = find_get_pages_tag(mapping, &index,
- PAGECACHE_TAG_DIRTY,
- tofind, pages);
- found_pages += nr_pages;
- tofind -= nr_pages;
- pages += nr_pages;
- } while (nr_pages && tofind && index <= end);
-
- if (found_pages == 0) {
- kref_put(&wdata->refcount, cifs_writedata_release);
- break;
- }
-
- nr_pages = 0;
- for (i = 0; i < found_pages; i++) {
- page = wdata->pages[i];
- /*
- * At this point we hold neither mapping->tree_lock nor
- * lock on the page itself: the page may be truncated or
- * invalidated (changing page->mapping to NULL), or even
- * swizzled back from swapper_space to tmpfs file
- * mapping
- */
-
- if (nr_pages == 0)
- lock_page(page);
- else if (!trylock_page(page))
- break;
-
- if (unlikely(page->mapping != mapping)) {
- unlock_page(page);
- break;
- }
-
- if (!wbc->range_cyclic && page->index > end) {
- done = true;
- unlock_page(page);
- break;
- }
-
- if (next && (page->index != next)) {
- /* Not next consecutive page */
- unlock_page(page);
- break;
- }
-
- if (wbc->sync_mode != WB_SYNC_NONE)
- wait_on_page_writeback(page);
-
- if (PageWriteback(page) ||
- !clear_page_dirty_for_io(page)) {
- unlock_page(page);
- break;
- }
-
- /*
- * This actually clears the dirty bit in the radix tree.
- * See cifs_writepage() for more commentary.
- */
- set_page_writeback(page);
-
- if (page_offset(page) >= mapping->host->i_size) {
- done = true;
- unlock_page(page);
- end_page_writeback(page);
- break;
- }
-
- wdata->pages[i] = page;
- next = page->index + 1;
- ++nr_pages;
- }
-
- /* reset index to refind any pages skipped */
- if (nr_pages == 0)
- index = wdata->pages[0]->index + 1;
-
- /* put any pages we aren't going to use */
- for (i = nr_pages; i < found_pages; i++) {
- page_cache_release(wdata->pages[i]);
- wdata->pages[i] = NULL;
- }
-
- /* nothing to write? */
- if (nr_pages == 0) {
- kref_put(&wdata->refcount, cifs_writedata_release);
- continue;
- }
-
- wdata->sync_mode = wbc->sync_mode;
- wdata->nr_pages = nr_pages;
- wdata->offset = page_offset(wdata->pages[0]);
- wdata->marshal_iov = cifs_writepages_marshal_iov;
-
- do {
- if (wdata->cfile != NULL)
- cifsFileInfo_put(wdata->cfile);
- wdata->cfile = find_writable_file(CIFS_I(mapping->host),
- false);
- if (!wdata->cfile) {
- cERROR(1, "No writable handles for inode");
- rc = -EBADF;
- break;
- }
- wdata->pid = wdata->cfile->pid;
- rc = cifs_async_writev(wdata);
- } while (wbc->sync_mode == WB_SYNC_ALL && rc == -EAGAIN);
-
- for (i = 0; i < nr_pages; ++i)
- unlock_page(wdata->pages[i]);
-
- /* send failure -- clean up the mess */
- if (rc != 0) {
- for (i = 0; i < nr_pages; ++i) {
- if (rc == -EAGAIN)
- redirty_page_for_writepage(wbc,
- wdata->pages[i]);
- else
- SetPageError(wdata->pages[i]);
- end_page_writeback(wdata->pages[i]);
- page_cache_release(wdata->pages[i]);
- }
- if (rc != -EAGAIN)
- mapping_set_error(mapping, rc);
- }
- kref_put(&wdata->refcount, cifs_writedata_release);
-
- wbc->nr_to_write -= nr_pages;
- if (wbc->nr_to_write <= 0)
- done = true;
-
- index = next;
- }
-
- if (!scanned && !done) {
- /*
- * We hit the last page and there is more work to be done: wrap
- * back to the start of the file
- */
- scanned = true;
- index = 0;
- goto retry;
- }
-
- if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
- mapping->writeback_index = index;
-
- return rc;
-}
-
-static int
-cifs_writepage_locked(struct page *page, struct writeback_control *wbc)
-{
- int rc;
- int xid;
-
- xid = GetXid();
-/* BB add check for wbc flags */
- page_cache_get(page);
- if (!PageUptodate(page))
- cFYI(1, "ppw - page not up to date");
-
- /*
- * Set the "writeback" flag, and clear "dirty" in the radix tree.
- *
- * A writepage() implementation always needs to do either this,
- * or re-dirty the page with "redirty_page_for_writepage()" in
- * the case of a failure.
- *
- * Just unlocking the page will cause the radix tree tag-bits
- * to fail to update with the state of the page correctly.
- */
- set_page_writeback(page);
-retry_write:
- rc = cifs_partialpagewrite(page, 0, PAGE_CACHE_SIZE);
- if (rc == -EAGAIN && wbc->sync_mode == WB_SYNC_ALL)
- goto retry_write;
- else if (rc == -EAGAIN)
- redirty_page_for_writepage(wbc, page);
- else if (rc != 0)
- SetPageError(page);
- else
- SetPageUptodate(page);
- end_page_writeback(page);
- page_cache_release(page);
- FreeXid(xid);
- return rc;
-}
-
-static int cifs_writepage(struct page *page, struct writeback_control *wbc)
-{
- int rc = cifs_writepage_locked(page, wbc);
- unlock_page(page);
- return rc;
-}
-
-static int cifs_write_end(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned copied,
- struct page *page, void *fsdata)
-{
- int rc;
- struct inode *inode = mapping->host;
- struct cifsFileInfo *cfile = file->private_data;
- struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb);
- __u32 pid;
-
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
- pid = cfile->pid;
- else
- pid = current->tgid;
-
- cFYI(1, "write_end for page %p from pos %lld with %d bytes",
- page, pos, copied);
-
- if (PageChecked(page)) {
- if (copied == len)
- SetPageUptodate(page);
- ClearPageChecked(page);
- } else if (!PageUptodate(page) && copied == PAGE_CACHE_SIZE)
- SetPageUptodate(page);
-
- if (!PageUptodate(page)) {
- char *page_data;
- unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
- int xid;
-
- xid = GetXid();
- /* this is probably better than directly calling
- partialpage_write since in this function the file handle is
- known which we might as well leverage */
- /* BB check if anything else missing out of ppw
- such as updating last write time */
- page_data = kmap(page);
- rc = cifs_write(cfile, pid, page_data + offset, copied, &pos);
- /* if (rc < 0) should we set writebehind rc? */
- kunmap(page);
-
- FreeXid(xid);
- } else {
- rc = copied;
- pos += copied;
- set_page_dirty(page);
- }
-
- if (rc > 0) {
- spin_lock(&inode->i_lock);
- if (pos > inode->i_size)
- i_size_write(inode, pos);
- spin_unlock(&inode->i_lock);
- }
-
- unlock_page(page);
- page_cache_release(page);
-
- return rc;
-}
-
-int cifs_strict_fsync(struct file *file, loff_t start, loff_t end,
- int datasync)
-{
- int xid;
- int rc = 0;
- struct cifs_tcon *tcon;
- struct cifsFileInfo *smbfile = file->private_data;
- struct inode *inode = file->f_path.dentry->d_inode;
- struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
-
- rc = filemap_write_and_wait_range(inode->i_mapping, start, end);
- if (rc)
- return rc;
- mutex_lock(&inode->i_mutex);
-
- xid = GetXid();
-
- cFYI(1, "Sync file - name: %s datasync: 0x%x",
- file->f_path.dentry->d_name.name, datasync);
-
- if (!CIFS_I(inode)->clientCanCacheRead) {
- rc = cifs_invalidate_mapping(inode);
- if (rc) {
- cFYI(1, "rc: %d during invalidate phase", rc);
- rc = 0; /* don't care about it in fsync */
- }
- }
-
- tcon = tlink_tcon(smbfile->tlink);
- if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC))
- rc = CIFSSMBFlush(xid, tcon, smbfile->netfid);
-
- FreeXid(xid);
- mutex_unlock(&inode->i_mutex);
- return rc;
-}
-
-int cifs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
-{
- int xid;
- int rc = 0;
- struct cifs_tcon *tcon;
- struct cifsFileInfo *smbfile = file->private_data;
- struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
- struct inode *inode = file->f_mapping->host;
-
- rc = filemap_write_and_wait_range(inode->i_mapping, start, end);
- if (rc)
- return rc;
- mutex_lock(&inode->i_mutex);
-
- xid = GetXid();
-
- cFYI(1, "Sync file - name: %s datasync: 0x%x",
- file->f_path.dentry->d_name.name, datasync);
-
- tcon = tlink_tcon(smbfile->tlink);
- if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOSSYNC))
- rc = CIFSSMBFlush(xid, tcon, smbfile->netfid);
-
- FreeXid(xid);
- mutex_unlock(&inode->i_mutex);
- return rc;
-}
-
-/*
- * As file closes, flush all cached write data for this inode checking
- * for write behind errors.
- */
-int cifs_flush(struct file *file, fl_owner_t id)
-{
- struct inode *inode = file->f_path.dentry->d_inode;
- int rc = 0;
-
- if (file->f_mode & FMODE_WRITE)
- rc = filemap_write_and_wait(inode->i_mapping);
-
- cFYI(1, "Flush inode %p file %p rc %d", inode, file, rc);
-
- return rc;
-}
-
-static int
-cifs_write_allocate_pages(struct page **pages, unsigned long num_pages)
-{
- int rc = 0;
- unsigned long i;
-
- for (i = 0; i < num_pages; i++) {
- pages[i] = alloc_page(GFP_KERNEL|__GFP_HIGHMEM);
- if (!pages[i]) {
- /*
- * save number of pages we have already allocated and
- * return with ENOMEM error
- */
- num_pages = i;
- rc = -ENOMEM;
- break;
- }
- }
-
- if (rc) {
- for (i = 0; i < num_pages; i++)
- put_page(pages[i]);
- }
- return rc;
-}
-
-static inline
-size_t get_numpages(const size_t wsize, const size_t len, size_t *cur_len)
-{
- size_t num_pages;
- size_t clen;
-
- clen = min_t(const size_t, len, wsize);
- num_pages = DIV_ROUND_UP(clen, PAGE_SIZE);
-
- if (cur_len)
- *cur_len = clen;
-
- return num_pages;
-}
-
-static void
-cifs_uncached_marshal_iov(struct kvec *iov, struct cifs_writedata *wdata)
-{
- int i;
- size_t bytes = wdata->bytes;
-
- /* marshal up the pages into iov array */
- for (i = 0; i < wdata->nr_pages; i++) {
- iov[i + 1].iov_len = min_t(size_t, bytes, PAGE_SIZE);
- iov[i + 1].iov_base = kmap(wdata->pages[i]);
- bytes -= iov[i + 1].iov_len;
- }
-}
-
-static void
-cifs_uncached_writev_complete(struct work_struct *work)
-{
- int i;
- struct cifs_writedata *wdata = container_of(work,
- struct cifs_writedata, work);
- struct inode *inode = wdata->cfile->dentry->d_inode;
- struct cifsInodeInfo *cifsi = CIFS_I(inode);
-
- spin_lock(&inode->i_lock);
- cifs_update_eof(cifsi, wdata->offset, wdata->bytes);
- if (cifsi->server_eof > inode->i_size)
- i_size_write(inode, cifsi->server_eof);
- spin_unlock(&inode->i_lock);
-
- complete(&wdata->done);
-
- if (wdata->result != -EAGAIN) {
- for (i = 0; i < wdata->nr_pages; i++)
- put_page(wdata->pages[i]);
- }
-
- kref_put(&wdata->refcount, cifs_writedata_release);
-}
-
-/* attempt to send write to server, retry on any -EAGAIN errors */
-static int
-cifs_uncached_retry_writev(struct cifs_writedata *wdata)
-{
- int rc;
-
- do {
- if (wdata->cfile->invalidHandle) {
- rc = cifs_reopen_file(wdata->cfile, false);
- if (rc != 0)
- continue;
- }
- rc = cifs_async_writev(wdata);
- } while (rc == -EAGAIN);
-
- return rc;
-}
-
-static ssize_t
-cifs_iovec_write(struct file *file, const struct iovec *iov,
- unsigned long nr_segs, loff_t *poffset)
-{
- unsigned long nr_pages, i;
- size_t copied, len, cur_len;
- ssize_t total_written = 0;
- loff_t offset;
- struct iov_iter it;
- struct cifsFileInfo *open_file;
- struct cifs_tcon *tcon;
- struct cifs_sb_info *cifs_sb;
- struct cifs_writedata *wdata, *tmp;
- struct list_head wdata_list;
- int rc;
- pid_t pid;
-
- len = iov_length(iov, nr_segs);
- if (!len)
- return 0;
-
- rc = generic_write_checks(file, poffset, &len, 0);
- if (rc)
- return rc;
-
- INIT_LIST_HEAD(&wdata_list);
- cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
- open_file = file->private_data;
- tcon = tlink_tcon(open_file->tlink);
- offset = *poffset;
-
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
- pid = open_file->pid;
- else
- pid = current->tgid;
-
- iov_iter_init(&it, iov, nr_segs, len, 0);
- do {
- size_t save_len;
-
- nr_pages = get_numpages(cifs_sb->wsize, len, &cur_len);
- wdata = cifs_writedata_alloc(nr_pages,
- cifs_uncached_writev_complete);
- if (!wdata) {
- rc = -ENOMEM;
- break;
- }
-
- rc = cifs_write_allocate_pages(wdata->pages, nr_pages);
- if (rc) {
- kfree(wdata);
- break;
- }
-
- save_len = cur_len;
- for (i = 0; i < nr_pages; i++) {
- copied = min_t(const size_t, cur_len, PAGE_SIZE);
- copied = iov_iter_copy_from_user(wdata->pages[i], &it,
- 0, copied);
- cur_len -= copied;
- iov_iter_advance(&it, copied);
- }
- cur_len = save_len - cur_len;
-
- wdata->sync_mode = WB_SYNC_ALL;
- wdata->nr_pages = nr_pages;
- wdata->offset = (__u64)offset;
- wdata->cfile = cifsFileInfo_get(open_file);
- wdata->pid = pid;
- wdata->bytes = cur_len;
- wdata->marshal_iov = cifs_uncached_marshal_iov;
- rc = cifs_uncached_retry_writev(wdata);
- if (rc) {
- kref_put(&wdata->refcount, cifs_writedata_release);
- break;
- }
-
- list_add_tail(&wdata->list, &wdata_list);
- offset += cur_len;
- len -= cur_len;
- } while (len > 0);
-
- /*
- * If at least one write was successfully sent, then discard any rc
- * value from the later writes. If the other write succeeds, then
- * we'll end up returning whatever was written. If it fails, then
- * we'll get a new rc value from that.
- */
- if (!list_empty(&wdata_list))
- rc = 0;
-
- /*
- * Wait for and collect replies for any successful sends in order of
- * increasing offset. Once an error is hit or we get a fatal signal
- * while waiting, then return without waiting for any more replies.
- */
-restart_loop:
- list_for_each_entry_safe(wdata, tmp, &wdata_list, list) {
- if (!rc) {
- /* FIXME: freezable too? */
- rc = wait_for_completion_killable(&wdata->done);
- if (rc)
- rc = -EINTR;
- else if (wdata->result)
- rc = wdata->result;
- else
- total_written += wdata->bytes;
-
- /* resend call if it's a retryable error */
- if (rc == -EAGAIN) {
- rc = cifs_uncached_retry_writev(wdata);
- goto restart_loop;
- }
- }
- list_del_init(&wdata->list);
- kref_put(&wdata->refcount, cifs_writedata_release);
- }
-
- if (total_written > 0)
- *poffset += total_written;
-
- cifs_stats_bytes_written(tcon, total_written);
- return total_written ? total_written : (ssize_t)rc;
-}
-
-ssize_t cifs_user_writev(struct kiocb *iocb, const struct iovec *iov,
- unsigned long nr_segs, loff_t pos)
-{
- ssize_t written;
- struct inode *inode;
-
- inode = iocb->ki_filp->f_path.dentry->d_inode;
-
- /*
- * BB - optimize the way when signing is disabled. We can drop this
- * extra memory-to-memory copying and use iovec buffers for constructing
- * write request.
- */
-
- written = cifs_iovec_write(iocb->ki_filp, iov, nr_segs, &pos);
- if (written > 0) {
- CIFS_I(inode)->invalid_mapping = true;
- iocb->ki_pos = pos;
- }
-
- return written;
-}
-
-ssize_t cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov,
- unsigned long nr_segs, loff_t pos)
-{
- struct inode *inode;
-
- inode = iocb->ki_filp->f_path.dentry->d_inode;
-
- if (CIFS_I(inode)->clientCanCacheAll)
- return generic_file_aio_write(iocb, iov, nr_segs, pos);
-
- /*
- * In strict cache mode we need to write the data to the server exactly
- * from the pos to pos+len-1 rather than flush all affected pages
- * because it may cause a error with mandatory locks on these pages but
- * not on the region from pos to ppos+len-1.
- */
-
- return cifs_user_writev(iocb, iov, nr_segs, pos);
-}
-
-static ssize_t
-cifs_iovec_read(struct file *file, const struct iovec *iov,
- unsigned long nr_segs, loff_t *poffset)
-{
- int rc;
- int xid;
- ssize_t total_read;
- unsigned int bytes_read = 0;
- size_t len, cur_len;
- int iov_offset = 0;
- struct cifs_sb_info *cifs_sb;
- struct cifs_tcon *pTcon;
- struct cifsFileInfo *open_file;
- struct smb_com_read_rsp *pSMBr;
- struct cifs_io_parms io_parms;
- char *read_data;
- unsigned int rsize;
- __u32 pid;
-
- if (!nr_segs)
- return 0;
-
- len = iov_length(iov, nr_segs);
- if (!len)
- return 0;
-
- xid = GetXid();
- cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
-
- /* FIXME: set up handlers for larger reads and/or convert to async */
- rsize = min_t(unsigned int, cifs_sb->rsize, CIFSMaxBufSize);
-
- open_file = file->private_data;
- pTcon = tlink_tcon(open_file->tlink);
-
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
- pid = open_file->pid;
- else
- pid = current->tgid;
-
- if ((file->f_flags & O_ACCMODE) == O_WRONLY)
- cFYI(1, "attempting read on write only file instance");
-
- for (total_read = 0; total_read < len; total_read += bytes_read) {
- cur_len = min_t(const size_t, len - total_read, rsize);
- rc = -EAGAIN;
- read_data = NULL;
-
- while (rc == -EAGAIN) {
- int buf_type = CIFS_NO_BUFFER;
- if (open_file->invalidHandle) {
- rc = cifs_reopen_file(open_file, true);
- if (rc != 0)
- break;
- }
- io_parms.netfid = open_file->netfid;
- io_parms.pid = pid;
- io_parms.tcon = pTcon;
- io_parms.offset = *poffset;
- io_parms.length = cur_len;
- rc = CIFSSMBRead(xid, &io_parms, &bytes_read,
- &read_data, &buf_type);
- pSMBr = (struct smb_com_read_rsp *)read_data;
- if (read_data) {
- char *data_offset = read_data + 4 +
- le16_to_cpu(pSMBr->DataOffset);
- if (memcpy_toiovecend(iov, data_offset,
- iov_offset, bytes_read))
- rc = -EFAULT;
- if (buf_type == CIFS_SMALL_BUFFER)
- cifs_small_buf_release(read_data);
- else if (buf_type == CIFS_LARGE_BUFFER)
- cifs_buf_release(read_data);
- read_data = NULL;
- iov_offset += bytes_read;
- }
- }
-
- if (rc || (bytes_read == 0)) {
- if (total_read) {
- break;
- } else {
- FreeXid(xid);
- return rc;
- }
- } else {
- cifs_stats_bytes_read(pTcon, bytes_read);
- *poffset += bytes_read;
- }
- }
-
- FreeXid(xid);
- return total_read;
-}
-
-ssize_t cifs_user_readv(struct kiocb *iocb, const struct iovec *iov,
- unsigned long nr_segs, loff_t pos)
-{
- ssize_t read;
-
- read = cifs_iovec_read(iocb->ki_filp, iov, nr_segs, &pos);
- if (read > 0)
- iocb->ki_pos = pos;
-
- return read;
-}
-
-ssize_t cifs_strict_readv(struct kiocb *iocb, const struct iovec *iov,
- unsigned long nr_segs, loff_t pos)
-{
- struct inode *inode;
-
- inode = iocb->ki_filp->f_path.dentry->d_inode;
-
- if (CIFS_I(inode)->clientCanCacheRead)
- return generic_file_aio_read(iocb, iov, nr_segs, pos);
-
- /*
- * In strict cache mode we need to read from the server all the time
- * if we don't have level II oplock because the server can delay mtime
- * change - so we can't make a decision about inode invalidating.
- * And we can also fail with pagereading if there are mandatory locks
- * on pages affected by this read but not on the region from pos to
- * pos+len-1.
- */
-
- return cifs_user_readv(iocb, iov, nr_segs, pos);
-}
-
-static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
- loff_t *poffset)
-{
- int rc = -EACCES;
- unsigned int bytes_read = 0;
- unsigned int total_read;
- unsigned int current_read_size;
- unsigned int rsize;
- struct cifs_sb_info *cifs_sb;
- struct cifs_tcon *pTcon;
- int xid;
- char *current_offset;
- struct cifsFileInfo *open_file;
- struct cifs_io_parms io_parms;
- int buf_type = CIFS_NO_BUFFER;
- __u32 pid;
-
- xid = GetXid();
- cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
-
- /* FIXME: set up handlers for larger reads and/or convert to async */
- rsize = min_t(unsigned int, cifs_sb->rsize, CIFSMaxBufSize);
-
- if (file->private_data == NULL) {
- rc = -EBADF;
- FreeXid(xid);
- return rc;
- }
- open_file = file->private_data;
- pTcon = tlink_tcon(open_file->tlink);
-
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
- pid = open_file->pid;
- else
- pid = current->tgid;
-
- if ((file->f_flags & O_ACCMODE) == O_WRONLY)
- cFYI(1, "attempting read on write only file instance");
-
- for (total_read = 0, current_offset = read_data;
- read_size > total_read;
- total_read += bytes_read, current_offset += bytes_read) {
- current_read_size = min_t(uint, read_size - total_read, rsize);
-
- /* For windows me and 9x we do not want to request more
- than it negotiated since it will refuse the read then */
- if ((pTcon->ses) &&
- !(pTcon->ses->capabilities & CAP_LARGE_FILES)) {
- current_read_size = min_t(uint, current_read_size,
- CIFSMaxBufSize);
- }
- rc = -EAGAIN;
- while (rc == -EAGAIN) {
- if (open_file->invalidHandle) {
- rc = cifs_reopen_file(open_file, true);
- if (rc != 0)
- break;
- }
- io_parms.netfid = open_file->netfid;
- io_parms.pid = pid;
- io_parms.tcon = pTcon;
- io_parms.offset = *poffset;
- io_parms.length = current_read_size;
- rc = CIFSSMBRead(xid, &io_parms, &bytes_read,
- &current_offset, &buf_type);
- }
- if (rc || (bytes_read == 0)) {
- if (total_read) {
- break;
- } else {
- FreeXid(xid);
- return rc;
- }
- } else {
- cifs_stats_bytes_read(pTcon, total_read);
- *poffset += bytes_read;
- }
- }
- FreeXid(xid);
- return total_read;
-}
-
-/*
- * If the page is mmap'ed into a process' page tables, then we need to make
- * sure that it doesn't change while being written back.
- */
-static int
-cifs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
-{
- struct page *page = vmf->page;
-
- lock_page(page);
- return VM_FAULT_LOCKED;
-}
-
-static struct vm_operations_struct cifs_file_vm_ops = {
- .fault = filemap_fault,
- .page_mkwrite = cifs_page_mkwrite,
-};
-
-int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma)
-{
- int rc, xid;
- struct inode *inode = file->f_path.dentry->d_inode;
-
- xid = GetXid();
-
- if (!CIFS_I(inode)->clientCanCacheRead) {
- rc = cifs_invalidate_mapping(inode);
- if (rc)
- return rc;
- }
-
- rc = generic_file_mmap(file, vma);
- if (rc == 0)
- vma->vm_ops = &cifs_file_vm_ops;
- FreeXid(xid);
- return rc;
-}
-
-int cifs_file_mmap(struct file *file, struct vm_area_struct *vma)
-{
- int rc, xid;
-
- xid = GetXid();
- rc = cifs_revalidate_file(file);
- if (rc) {
- cFYI(1, "Validation prior to mmap failed, error=%d", rc);
- FreeXid(xid);
- return rc;
- }
- rc = generic_file_mmap(file, vma);
- if (rc == 0)
- vma->vm_ops = &cifs_file_vm_ops;
- FreeXid(xid);
- return rc;
-}
-
-static int cifs_readpages(struct file *file, struct address_space *mapping,
- struct list_head *page_list, unsigned num_pages)
-{
- int rc;
- struct list_head tmplist;
- struct cifsFileInfo *open_file = file->private_data;
- struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
- unsigned int rsize = cifs_sb->rsize;
- pid_t pid;
-
- /*
- * Give up immediately if rsize is too small to read an entire page.
- * The VFS will fall back to readpage. We should never reach this
- * point however since we set ra_pages to 0 when the rsize is smaller
- * than a cache page.
- */
- if (unlikely(rsize < PAGE_CACHE_SIZE))
- return 0;
-
- /*
- * Reads as many pages as possible from fscache. Returns -ENOBUFS
- * immediately if the cookie is negative
- */
- rc = cifs_readpages_from_fscache(mapping->host, mapping, page_list,
- &num_pages);
- if (rc == 0)
- return rc;
-
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
- pid = open_file->pid;
- else
- pid = current->tgid;
-
- rc = 0;
- INIT_LIST_HEAD(&tmplist);
-
- cFYI(1, "%s: file=%p mapping=%p num_pages=%u", __func__, file,
- mapping, num_pages);
-
- /*
- * Start with the page at end of list and move it to private
- * list. Do the same with any following pages until we hit
- * the rsize limit, hit an index discontinuity, or run out of
- * pages. Issue the async read and then start the loop again
- * until the list is empty.
- *
- * Note that list order is important. The page_list is in
- * the order of declining indexes. When we put the pages in
- * the rdata->pages, then we want them in increasing order.
- */
- while (!list_empty(page_list)) {
- unsigned int bytes = PAGE_CACHE_SIZE;
- unsigned int expected_index;
- unsigned int nr_pages = 1;
- loff_t offset;
- struct page *page, *tpage;
- struct cifs_readdata *rdata;
-
- page = list_entry(page_list->prev, struct page, lru);
-
- /*
- * Lock the page and put it in the cache. Since no one else
- * should have access to this page, we're safe to simply set
- * PG_locked without checking it first.
- */
- __set_page_locked(page);
- rc = add_to_page_cache_locked(page, mapping,
- page->index, GFP_KERNEL);
-
- /* give up if we can't stick it in the cache */
- if (rc) {
- __clear_page_locked(page);
- break;
- }
-
- /* move first page to the tmplist */
- offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
- list_move_tail(&page->lru, &tmplist);
-
- /* now try and add more pages onto the request */
- expected_index = page->index + 1;
- list_for_each_entry_safe_reverse(page, tpage, page_list, lru) {
- /* discontinuity ? */
- if (page->index != expected_index)
- break;
-
- /* would this page push the read over the rsize? */
- if (bytes + PAGE_CACHE_SIZE > rsize)
- break;
-
- __set_page_locked(page);
- if (add_to_page_cache_locked(page, mapping,
- page->index, GFP_KERNEL)) {
- __clear_page_locked(page);
- break;
- }
- list_move_tail(&page->lru, &tmplist);
- bytes += PAGE_CACHE_SIZE;
- expected_index++;
- nr_pages++;
- }
-
- rdata = cifs_readdata_alloc(nr_pages);
- if (!rdata) {
- /* best to give up if we're out of mem */
- list_for_each_entry_safe(page, tpage, &tmplist, lru) {
- list_del(&page->lru);
- lru_cache_add_file(page);
- unlock_page(page);
- page_cache_release(page);
- }
- rc = -ENOMEM;
- break;
- }
-
- spin_lock(&cifs_file_list_lock);
- cifsFileInfo_get(open_file);
- spin_unlock(&cifs_file_list_lock);
- rdata->cfile = open_file;
- rdata->mapping = mapping;
- rdata->offset = offset;
- rdata->bytes = bytes;
- rdata->pid = pid;
- list_splice_init(&tmplist, &rdata->pages);
-
- do {
- if (open_file->invalidHandle) {
- rc = cifs_reopen_file(open_file, true);
- if (rc != 0)
- continue;
- }
- rc = cifs_async_readv(rdata);
- } while (rc == -EAGAIN);
-
- if (rc != 0) {
- list_for_each_entry_safe(page, tpage, &rdata->pages,
- lru) {
- list_del(&page->lru);
- lru_cache_add_file(page);
- unlock_page(page);
- page_cache_release(page);
- }
- cifs_readdata_free(rdata);
- break;
- }
- }
-
- return rc;
-}
-
-static int cifs_readpage_worker(struct file *file, struct page *page,
- loff_t *poffset)
-{
- char *read_data;
- int rc;
-
- /* Is the page cached? */
- rc = cifs_readpage_from_fscache(file->f_path.dentry->d_inode, page);
- if (rc == 0)
- goto read_complete;
-
- page_cache_get(page);
- read_data = kmap(page);
- /* for reads over a certain size could initiate async read ahead */
-
- rc = cifs_read(file, read_data, PAGE_CACHE_SIZE, poffset);
-
- if (rc < 0)
- goto io_error;
- else
- cFYI(1, "Bytes read %d", rc);
-
- file->f_path.dentry->d_inode->i_atime =
- current_fs_time(file->f_path.dentry->d_inode->i_sb);
-
- if (PAGE_CACHE_SIZE > rc)
- memset(read_data + rc, 0, PAGE_CACHE_SIZE - rc);
-
- flush_dcache_page(page);
- SetPageUptodate(page);
-
- /* send this page to the cache */
- cifs_readpage_to_fscache(file->f_path.dentry->d_inode, page);
-
- rc = 0;
-
-io_error:
- kunmap(page);
- page_cache_release(page);
-
-read_complete:
- return rc;
-}
-
-static int cifs_readpage(struct file *file, struct page *page)
-{
- loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
- int rc = -EACCES;
- int xid;
-
- xid = GetXid();
-
- if (file->private_data == NULL) {
- rc = -EBADF;
- FreeXid(xid);
- return rc;
- }
-
- cFYI(1, "readpage %p at offset %d 0x%x\n",
- page, (int)offset, (int)offset);
-
- rc = cifs_readpage_worker(file, page, &offset);
-
- unlock_page(page);
-
- FreeXid(xid);
- return rc;
-}
-
-static int is_inode_writable(struct cifsInodeInfo *cifs_inode)
-{
- struct cifsFileInfo *open_file;
-
- spin_lock(&cifs_file_list_lock);
- list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
- if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) {
- spin_unlock(&cifs_file_list_lock);
- return 1;
- }
- }
- spin_unlock(&cifs_file_list_lock);
- return 0;
-}
-
-/* We do not want to update the file size from server for inodes
- open for write - to avoid races with writepage extending
- the file - in the future we could consider allowing
- refreshing the inode only on increases in the file size
- but this is tricky to do without racing with writebehind
- page caching in the current Linux kernel design */
-bool is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file)
-{
- if (!cifsInode)
- return true;
-
- if (is_inode_writable(cifsInode)) {
- /* This inode is open for write at least once */
- struct cifs_sb_info *cifs_sb;
-
- cifs_sb = CIFS_SB(cifsInode->vfs_inode.i_sb);
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
- /* since no page cache to corrupt on directio
- we can change size safely */
- return true;
- }
-
- if (i_size_read(&cifsInode->vfs_inode) < end_of_file)
- return true;
-
- return false;
- } else
- return true;
-}
-
-static int cifs_write_begin(struct file *file, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned flags,
- struct page **pagep, void **fsdata)
-{
- pgoff_t index = pos >> PAGE_CACHE_SHIFT;
- loff_t offset = pos & (PAGE_CACHE_SIZE - 1);
- loff_t page_start = pos & PAGE_MASK;
- loff_t i_size;
- struct page *page;
- int rc = 0;
-
- cFYI(1, "write_begin from %lld len %d", (long long)pos, len);
-
- page = grab_cache_page_write_begin(mapping, index, flags);
- if (!page) {
- rc = -ENOMEM;
- goto out;
- }
-
- if (PageUptodate(page))
- goto out;
-
- /*
- * If we write a full page it will be up to date, no need to read from
- * the server. If the write is short, we'll end up doing a sync write
- * instead.
- */
- if (len == PAGE_CACHE_SIZE)
- goto out;
-
- /*
- * optimize away the read when we have an oplock, and we're not
- * expecting to use any of the data we'd be reading in. That
- * is, when the page lies beyond the EOF, or straddles the EOF
- * and the write will cover all of the existing data.
- */
- if (CIFS_I(mapping->host)->clientCanCacheRead) {
- i_size = i_size_read(mapping->host);
- if (page_start >= i_size ||
- (offset == 0 && (pos + len) >= i_size)) {
- zero_user_segments(page, 0, offset,
- offset + len,
- PAGE_CACHE_SIZE);
- /*
- * PageChecked means that the parts of the page
- * to which we're not writing are considered up
- * to date. Once the data is copied to the
- * page, it can be set uptodate.
- */
- SetPageChecked(page);
- goto out;
- }
- }
-
- if ((file->f_flags & O_ACCMODE) != O_WRONLY) {
- /*
- * might as well read a page, it is fast enough. If we get
- * an error, we don't need to return it. cifs_write_end will
- * do a sync write instead since PG_uptodate isn't set.
- */
- cifs_readpage_worker(file, page, &page_start);
- } else {
- /* we could try using another file handle if there is one -
- but how would we lock it to prevent close of that handle
- racing with this read? In any case
- this will be written out by write_end so is fine */
- }
-out:
- *pagep = page;
- return rc;
-}
-
-static int cifs_release_page(struct page *page, gfp_t gfp)
-{
- if (PagePrivate(page))
- return 0;
-
- return cifs_fscache_release_page(page, gfp);
-}
-
-static void cifs_invalidate_page(struct page *page, unsigned long offset)
-{
- struct cifsInodeInfo *cifsi = CIFS_I(page->mapping->host);
-
- if (offset == 0)
- cifs_fscache_invalidate_page(page, &cifsi->vfs_inode);
-}
-
-static int cifs_launder_page(struct page *page)
-{
- int rc = 0;
- loff_t range_start = page_offset(page);
- loff_t range_end = range_start + (loff_t)(PAGE_CACHE_SIZE - 1);
- struct writeback_control wbc = {
- .sync_mode = WB_SYNC_ALL,
- .nr_to_write = 0,
- .range_start = range_start,
- .range_end = range_end,
- };
-
- cFYI(1, "Launder page: %p", page);
-
- if (clear_page_dirty_for_io(page))
- rc = cifs_writepage_locked(page, &wbc);
-
- cifs_fscache_invalidate_page(page, page->mapping->host);
- return rc;
-}
-
-void cifs_oplock_break(struct work_struct *work)
-{
- struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo,
- oplock_break);
- struct inode *inode = cfile->dentry->d_inode;
- struct cifsInodeInfo *cinode = CIFS_I(inode);
- int rc = 0;
-
- if (inode && S_ISREG(inode->i_mode)) {
- if (cinode->clientCanCacheRead)
- break_lease(inode, O_RDONLY);
- else
- break_lease(inode, O_WRONLY);
- rc = filemap_fdatawrite(inode->i_mapping);
- if (cinode->clientCanCacheRead == 0) {
- rc = filemap_fdatawait(inode->i_mapping);
- mapping_set_error(inode->i_mapping, rc);
- invalidate_remote_inode(inode);
- }
- cFYI(1, "Oplock flush inode %p rc %d", inode, rc);
- }
-
- rc = cifs_push_locks(cfile);
- if (rc)
- cERROR(1, "Push locks rc = %d", rc);
-
- /*
- * releasing stale oplock after recent reconnect of smb session using
- * a now incorrect file handle is not a data integrity issue but do
- * not bother sending an oplock release if session to server still is
- * disconnected since oplock already released by the server
- */
- if (!cfile->oplock_break_cancelled) {
- rc = CIFSSMBLock(0, tlink_tcon(cfile->tlink), cfile->netfid,
- current->tgid, 0, 0, 0, 0,
- LOCKING_ANDX_OPLOCK_RELEASE, false,
- cinode->clientCanCacheRead ? 1 : 0);
- cFYI(1, "Oplock release rc = %d", rc);
- }
-}
-
-const struct address_space_operations cifs_addr_ops = {
- .readpage = cifs_readpage,
- .readpages = cifs_readpages,
- .writepage = cifs_writepage,
- .writepages = cifs_writepages,
- .write_begin = cifs_write_begin,
- .write_end = cifs_write_end,
- .set_page_dirty = __set_page_dirty_nobuffers,
- .releasepage = cifs_release_page,
- .invalidatepage = cifs_invalidate_page,
- .launder_page = cifs_launder_page,
-};
-
-/*
- * cifs_readpages requires the server to support a buffer large enough to
- * contain the header plus one complete page of data. Otherwise, we need
- * to leave cifs_readpages out of the address space operations.
- */
-const struct address_space_operations cifs_addr_ops_smallbuf = {
- .readpage = cifs_readpage,
- .writepage = cifs_writepage,
- .writepages = cifs_writepages,
- .write_begin = cifs_write_begin,
- .write_end = cifs_write_end,
- .set_page_dirty = __set_page_dirty_nobuffers,
- .releasepage = cifs_release_page,
- .invalidatepage = cifs_invalidate_page,
- .launder_page = cifs_launder_page,
-};
diff --git a/ANDROID_3.4.5/fs/cifs/fscache.c b/ANDROID_3.4.5/fs/cifs/fscache.c
deleted file mode 100644
index 42e5363b..00000000
--- a/ANDROID_3.4.5/fs/cifs/fscache.c
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * fs/cifs/fscache.c - CIFS filesystem cache interface
- *
- * Copyright (c) 2010 Novell, Inc.
- * Author(s): Suresh Jayaraman <sjayaraman@suse.de>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include "fscache.h"
-#include "cifsglob.h"
-#include "cifs_debug.h"
-#include "cifs_fs_sb.h"
-
-void cifs_fscache_get_client_cookie(struct TCP_Server_Info *server)
-{
- server->fscache =
- fscache_acquire_cookie(cifs_fscache_netfs.primary_index,
- &cifs_fscache_server_index_def, server);
- cFYI(1, "%s: (0x%p/0x%p)", __func__, server,
- server->fscache);
-}
-
-void cifs_fscache_release_client_cookie(struct TCP_Server_Info *server)
-{
- cFYI(1, "%s: (0x%p/0x%p)", __func__, server,
- server->fscache);
- fscache_relinquish_cookie(server->fscache, 0);
- server->fscache = NULL;
-}
-
-void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon)
-{
- struct TCP_Server_Info *server = tcon->ses->server;
-
- tcon->fscache =
- fscache_acquire_cookie(server->fscache,
- &cifs_fscache_super_index_def, tcon);
- cFYI(1, "%s: (0x%p/0x%p)", __func__, server->fscache,
- tcon->fscache);
-}
-
-void cifs_fscache_release_super_cookie(struct cifs_tcon *tcon)
-{
- cFYI(1, "%s: (0x%p)", __func__, tcon->fscache);
- fscache_relinquish_cookie(tcon->fscache, 0);
- tcon->fscache = NULL;
-}
-
-static void cifs_fscache_enable_inode_cookie(struct inode *inode)
-{
- struct cifsInodeInfo *cifsi = CIFS_I(inode);
- struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
- struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
-
- if (cifsi->fscache)
- return;
-
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_FSCACHE) {
- cifsi->fscache = fscache_acquire_cookie(tcon->fscache,
- &cifs_fscache_inode_object_def, cifsi);
- cFYI(1, "%s: got FH cookie (0x%p/0x%p)", __func__,
- tcon->fscache, cifsi->fscache);
- }
-}
-
-void cifs_fscache_release_inode_cookie(struct inode *inode)
-{
- struct cifsInodeInfo *cifsi = CIFS_I(inode);
-
- if (cifsi->fscache) {
- cFYI(1, "%s: (0x%p)", __func__, cifsi->fscache);
- fscache_relinquish_cookie(cifsi->fscache, 0);
- cifsi->fscache = NULL;
- }
-}
-
-static void cifs_fscache_disable_inode_cookie(struct inode *inode)
-{
- struct cifsInodeInfo *cifsi = CIFS_I(inode);
-
- if (cifsi->fscache) {
- cFYI(1, "%s: (0x%p)", __func__, cifsi->fscache);
- fscache_uncache_all_inode_pages(cifsi->fscache, inode);
- fscache_relinquish_cookie(cifsi->fscache, 1);
- cifsi->fscache = NULL;
- }
-}
-
-void cifs_fscache_set_inode_cookie(struct inode *inode, struct file *filp)
-{
- if ((filp->f_flags & O_ACCMODE) != O_RDONLY)
- cifs_fscache_disable_inode_cookie(inode);
- else
- cifs_fscache_enable_inode_cookie(inode);
-}
-
-void cifs_fscache_reset_inode_cookie(struct inode *inode)
-{
- struct cifsInodeInfo *cifsi = CIFS_I(inode);
- struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
- struct fscache_cookie *old = cifsi->fscache;
-
- if (cifsi->fscache) {
- /* retire the current fscache cache and get a new one */
- fscache_relinquish_cookie(cifsi->fscache, 1);
-
- cifsi->fscache = fscache_acquire_cookie(
- cifs_sb_master_tcon(cifs_sb)->fscache,
- &cifs_fscache_inode_object_def,
- cifsi);
- cFYI(1, "%s: new cookie 0x%p oldcookie 0x%p",
- __func__, cifsi->fscache, old);
- }
-}
-
-int cifs_fscache_release_page(struct page *page, gfp_t gfp)
-{
- if (PageFsCache(page)) {
- struct inode *inode = page->mapping->host;
- struct cifsInodeInfo *cifsi = CIFS_I(inode);
-
- cFYI(1, "%s: (0x%p/0x%p)", __func__, page,
- cifsi->fscache);
- if (!fscache_maybe_release_page(cifsi->fscache, page, gfp))
- return 0;
- }
-
- return 1;
-}
-
-static void cifs_readpage_from_fscache_complete(struct page *page, void *ctx,
- int error)
-{
- cFYI(1, "%s: (0x%p/%d)", __func__, page, error);
- if (!error)
- SetPageUptodate(page);
- unlock_page(page);
-}
-
-/*
- * Retrieve a page from FS-Cache
- */
-int __cifs_readpage_from_fscache(struct inode *inode, struct page *page)
-{
- int ret;
-
- cFYI(1, "%s: (fsc:%p, p:%p, i:0x%p", __func__,
- CIFS_I(inode)->fscache, page, inode);
- ret = fscache_read_or_alloc_page(CIFS_I(inode)->fscache, page,
- cifs_readpage_from_fscache_complete,
- NULL,
- GFP_KERNEL);
- switch (ret) {
-
- case 0: /* page found in fscache, read submitted */
- cFYI(1, "%s: submitted", __func__);
- return ret;
- case -ENOBUFS: /* page won't be cached */
- case -ENODATA: /* page not in cache */
- cFYI(1, "%s: %d", __func__, ret);
- return 1;
-
- default:
- cERROR(1, "unknown error ret = %d", ret);
- }
- return ret;
-}
-
-/*
- * Retrieve a set of pages from FS-Cache
- */
-int __cifs_readpages_from_fscache(struct inode *inode,
- struct address_space *mapping,
- struct list_head *pages,
- unsigned *nr_pages)
-{
- int ret;
-
- cFYI(1, "%s: (0x%p/%u/0x%p)", __func__,
- CIFS_I(inode)->fscache, *nr_pages, inode);
- ret = fscache_read_or_alloc_pages(CIFS_I(inode)->fscache, mapping,
- pages, nr_pages,
- cifs_readpage_from_fscache_complete,
- NULL,
- mapping_gfp_mask(mapping));
- switch (ret) {
- case 0: /* read submitted to the cache for all pages */
- cFYI(1, "%s: submitted", __func__);
- return ret;
-
- case -ENOBUFS: /* some pages are not cached and can't be */
- case -ENODATA: /* some pages are not cached */
- cFYI(1, "%s: no page", __func__);
- return 1;
-
- default:
- cFYI(1, "unknown error ret = %d", ret);
- }
-
- return ret;
-}
-
-void __cifs_readpage_to_fscache(struct inode *inode, struct page *page)
-{
- int ret;
-
- cFYI(1, "%s: (fsc: %p, p: %p, i: %p)", __func__,
- CIFS_I(inode)->fscache, page, inode);
- ret = fscache_write_page(CIFS_I(inode)->fscache, page, GFP_KERNEL);
- if (ret != 0)
- fscache_uncache_page(CIFS_I(inode)->fscache, page);
-}
-
-void __cifs_fscache_invalidate_page(struct page *page, struct inode *inode)
-{
- struct cifsInodeInfo *cifsi = CIFS_I(inode);
- struct fscache_cookie *cookie = cifsi->fscache;
-
- cFYI(1, "%s: (0x%p/0x%p)", __func__, page, cookie);
- fscache_wait_on_page_write(cookie, page);
- fscache_uncache_page(cookie, page);
-}
-
diff --git a/ANDROID_3.4.5/fs/cifs/fscache.h b/ANDROID_3.4.5/fs/cifs/fscache.h
deleted file mode 100644
index 63539323..00000000
--- a/ANDROID_3.4.5/fs/cifs/fscache.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * fs/cifs/fscache.h - CIFS filesystem cache interface definitions
- *
- * Copyright (c) 2010 Novell, Inc.
- * Authors(s): Suresh Jayaraman (sjayaraman@suse.de>
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef _CIFS_FSCACHE_H
-#define _CIFS_FSCACHE_H
-
-#include <linux/fscache.h>
-
-#include "cifsglob.h"
-
-#ifdef CONFIG_CIFS_FSCACHE
-
-extern struct fscache_netfs cifs_fscache_netfs;
-extern const struct fscache_cookie_def cifs_fscache_server_index_def;
-extern const struct fscache_cookie_def cifs_fscache_super_index_def;
-extern const struct fscache_cookie_def cifs_fscache_inode_object_def;
-
-extern int cifs_fscache_register(void);
-extern void cifs_fscache_unregister(void);
-
-/*
- * fscache.c
- */
-extern void cifs_fscache_get_client_cookie(struct TCP_Server_Info *);
-extern void cifs_fscache_release_client_cookie(struct TCP_Server_Info *);
-extern void cifs_fscache_get_super_cookie(struct cifs_tcon *);
-extern void cifs_fscache_release_super_cookie(struct cifs_tcon *);
-
-extern void cifs_fscache_release_inode_cookie(struct inode *);
-extern void cifs_fscache_set_inode_cookie(struct inode *, struct file *);
-extern void cifs_fscache_reset_inode_cookie(struct inode *);
-
-extern void __cifs_fscache_invalidate_page(struct page *, struct inode *);
-extern int cifs_fscache_release_page(struct page *page, gfp_t gfp);
-extern int __cifs_readpage_from_fscache(struct inode *, struct page *);
-extern int __cifs_readpages_from_fscache(struct inode *,
- struct address_space *,
- struct list_head *,
- unsigned *);
-
-extern void __cifs_readpage_to_fscache(struct inode *, struct page *);
-
-static inline void cifs_fscache_invalidate_page(struct page *page,
- struct inode *inode)
-{
- if (PageFsCache(page))
- __cifs_fscache_invalidate_page(page, inode);
-}
-
-static inline int cifs_readpage_from_fscache(struct inode *inode,
- struct page *page)
-{
- if (CIFS_I(inode)->fscache)
- return __cifs_readpage_from_fscache(inode, page);
-
- return -ENOBUFS;
-}
-
-static inline int cifs_readpages_from_fscache(struct inode *inode,
- struct address_space *mapping,
- struct list_head *pages,
- unsigned *nr_pages)
-{
- if (CIFS_I(inode)->fscache)
- return __cifs_readpages_from_fscache(inode, mapping, pages,
- nr_pages);
- return -ENOBUFS;
-}
-
-static inline void cifs_readpage_to_fscache(struct inode *inode,
- struct page *page)
-{
- if (PageFsCache(page))
- __cifs_readpage_to_fscache(inode, page);
-}
-
-#else /* CONFIG_CIFS_FSCACHE */
-static inline int cifs_fscache_register(void) { return 0; }
-static inline void cifs_fscache_unregister(void) {}
-
-static inline void
-cifs_fscache_get_client_cookie(struct TCP_Server_Info *server) {}
-static inline void
-cifs_fscache_release_client_cookie(struct TCP_Server_Info *server) {}
-static inline void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon) {}
-static inline void
-cifs_fscache_release_super_cookie(struct cifs_tcon *tcon) {}
-
-static inline void cifs_fscache_release_inode_cookie(struct inode *inode) {}
-static inline void cifs_fscache_set_inode_cookie(struct inode *inode,
- struct file *filp) {}
-static inline void cifs_fscache_reset_inode_cookie(struct inode *inode) {}
-static inline int cifs_fscache_release_page(struct page *page, gfp_t gfp)
-{
- return 1; /* May release page */
-}
-
-static inline void cifs_fscache_invalidate_page(struct page *page,
- struct inode *inode) {}
-static inline int
-cifs_readpage_from_fscache(struct inode *inode, struct page *page)
-{
- return -ENOBUFS;
-}
-
-static inline int cifs_readpages_from_fscache(struct inode *inode,
- struct address_space *mapping,
- struct list_head *pages,
- unsigned *nr_pages)
-{
- return -ENOBUFS;
-}
-
-static inline void cifs_readpage_to_fscache(struct inode *inode,
- struct page *page) {}
-
-#endif /* CONFIG_CIFS_FSCACHE */
-
-#endif /* _CIFS_FSCACHE_H */
diff --git a/ANDROID_3.4.5/fs/cifs/inode.c b/ANDROID_3.4.5/fs/cifs/inode.c
deleted file mode 100644
index 745da3d0..00000000
--- a/ANDROID_3.4.5/fs/cifs/inode.c
+++ /dev/null
@@ -1,2293 +0,0 @@
-/*
- * fs/cifs/inode.c
- *
- * Copyright (C) International Business Machines Corp., 2002,2010
- * Author(s): Steve French (sfrench@us.ibm.com)
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <linux/fs.h>
-#include <linux/stat.h>
-#include <linux/slab.h>
-#include <linux/pagemap.h>
-#include <asm/div64.h>
-#include "cifsfs.h"
-#include "cifspdu.h"
-#include "cifsglob.h"
-#include "cifsproto.h"
-#include "cifs_debug.h"
-#include "cifs_fs_sb.h"
-#include "fscache.h"
-
-
-static void cifs_set_ops(struct inode *inode)
-{
- struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
-
- switch (inode->i_mode & S_IFMT) {
- case S_IFREG:
- inode->i_op = &cifs_file_inode_ops;
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
- inode->i_fop = &cifs_file_direct_nobrl_ops;
- else
- inode->i_fop = &cifs_file_direct_ops;
- } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO) {
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
- inode->i_fop = &cifs_file_strict_nobrl_ops;
- else
- inode->i_fop = &cifs_file_strict_ops;
- } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
- inode->i_fop = &cifs_file_nobrl_ops;
- else { /* not direct, send byte range locks */
- inode->i_fop = &cifs_file_ops;
- }
-
- /* check if server can support readpages */
- if (cifs_sb_master_tcon(cifs_sb)->ses->server->maxBuf <
- PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)
- inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
- else
- inode->i_data.a_ops = &cifs_addr_ops;
- break;
- case S_IFDIR:
-#ifdef CONFIG_CIFS_DFS_UPCALL
- if (IS_AUTOMOUNT(inode)) {
- inode->i_op = &cifs_dfs_referral_inode_operations;
- } else {
-#else /* NO DFS support, treat as a directory */
- {
-#endif
- inode->i_op = &cifs_dir_inode_ops;
- inode->i_fop = &cifs_dir_ops;
- }
- break;
- case S_IFLNK:
- inode->i_op = &cifs_symlink_inode_ops;
- break;
- default:
- init_special_inode(inode, inode->i_mode, inode->i_rdev);
- break;
- }
-}
-
-/* check inode attributes against fattr. If they don't match, tag the
- * inode for cache invalidation
- */
-static void
-cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr)
-{
- struct cifsInodeInfo *cifs_i = CIFS_I(inode);
-
- cFYI(1, "%s: revalidating inode %llu", __func__, cifs_i->uniqueid);
-
- if (inode->i_state & I_NEW) {
- cFYI(1, "%s: inode %llu is new", __func__, cifs_i->uniqueid);
- return;
- }
-
- /* don't bother with revalidation if we have an oplock */
- if (cifs_i->clientCanCacheRead) {
- cFYI(1, "%s: inode %llu is oplocked", __func__,
- cifs_i->uniqueid);
- return;
- }
-
- /* revalidate if mtime or size have changed */
- if (timespec_equal(&inode->i_mtime, &fattr->cf_mtime) &&
- cifs_i->server_eof == fattr->cf_eof) {
- cFYI(1, "%s: inode %llu is unchanged", __func__,
- cifs_i->uniqueid);
- return;
- }
-
- cFYI(1, "%s: invalidating inode %llu mapping", __func__,
- cifs_i->uniqueid);
- cifs_i->invalid_mapping = true;
-}
-
-/* populate an inode with info from a cifs_fattr struct */
-void
-cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
-{
- struct cifsInodeInfo *cifs_i = CIFS_I(inode);
- struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
- unsigned long oldtime = cifs_i->time;
-
- cifs_revalidate_cache(inode, fattr);
-
- inode->i_atime = fattr->cf_atime;
- inode->i_mtime = fattr->cf_mtime;
- inode->i_ctime = fattr->cf_ctime;
- inode->i_rdev = fattr->cf_rdev;
- set_nlink(inode, fattr->cf_nlink);
- inode->i_uid = fattr->cf_uid;
- inode->i_gid = fattr->cf_gid;
-
- /* if dynperm is set, don't clobber existing mode */
- if (inode->i_state & I_NEW ||
- !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM))
- inode->i_mode = fattr->cf_mode;
-
- cifs_i->cifsAttrs = fattr->cf_cifsattrs;
-
- if (fattr->cf_flags & CIFS_FATTR_NEED_REVAL)
- cifs_i->time = 0;
- else
- cifs_i->time = jiffies;
-
- cFYI(1, "inode 0x%p old_time=%ld new_time=%ld", inode,
- oldtime, cifs_i->time);
-
- cifs_i->delete_pending = fattr->cf_flags & CIFS_FATTR_DELETE_PENDING;
-
- cifs_i->server_eof = fattr->cf_eof;
- /*
- * Can't safely change the file size here if the client is writing to
- * it due to potential races.
- */
- spin_lock(&inode->i_lock);
- if (is_size_safe_to_change(cifs_i, fattr->cf_eof)) {
- i_size_write(inode, fattr->cf_eof);
-
- /*
- * i_blocks is not related to (i_size / i_blksize),
- * but instead 512 byte (2**9) size is required for
- * calculating num blocks.
- */
- inode->i_blocks = (512 - 1 + fattr->cf_bytes) >> 9;
- }
- spin_unlock(&inode->i_lock);
-
- if (fattr->cf_flags & CIFS_FATTR_DFS_REFERRAL)
- inode->i_flags |= S_AUTOMOUNT;
- cifs_set_ops(inode);
-}
-
-void
-cifs_fill_uniqueid(struct super_block *sb, struct cifs_fattr *fattr)
-{
- struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
-
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
- return;
-
- fattr->cf_uniqueid = iunique(sb, ROOT_I);
-}
-
-/* Fill a cifs_fattr struct with info from FILE_UNIX_BASIC_INFO. */
-void
-cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info,
- struct cifs_sb_info *cifs_sb)
-{
- memset(fattr, 0, sizeof(*fattr));
- fattr->cf_uniqueid = le64_to_cpu(info->UniqueId);
- fattr->cf_bytes = le64_to_cpu(info->NumOfBytes);
- fattr->cf_eof = le64_to_cpu(info->EndOfFile);
-
- fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);
- fattr->cf_mtime = cifs_NTtimeToUnix(info->LastModificationTime);
- fattr->cf_ctime = cifs_NTtimeToUnix(info->LastStatusChange);
- fattr->cf_mode = le64_to_cpu(info->Permissions);
-
- /*
- * Since we set the inode type below we need to mask off
- * to avoid strange results if bits set above.
- */
- fattr->cf_mode &= ~S_IFMT;
- switch (le32_to_cpu(info->Type)) {
- case UNIX_FILE:
- fattr->cf_mode |= S_IFREG;
- fattr->cf_dtype = DT_REG;
- break;
- case UNIX_SYMLINK:
- fattr->cf_mode |= S_IFLNK;
- fattr->cf_dtype = DT_LNK;
- break;
- case UNIX_DIR:
- fattr->cf_mode |= S_IFDIR;
- fattr->cf_dtype = DT_DIR;
- break;
- case UNIX_CHARDEV:
- fattr->cf_mode |= S_IFCHR;
- fattr->cf_dtype = DT_CHR;
- fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor),
- le64_to_cpu(info->DevMinor) & MINORMASK);
- break;
- case UNIX_BLOCKDEV:
- fattr->cf_mode |= S_IFBLK;
- fattr->cf_dtype = DT_BLK;
- fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor),
- le64_to_cpu(info->DevMinor) & MINORMASK);
- break;
- case UNIX_FIFO:
- fattr->cf_mode |= S_IFIFO;
- fattr->cf_dtype = DT_FIFO;
- break;
- case UNIX_SOCKET:
- fattr->cf_mode |= S_IFSOCK;
- fattr->cf_dtype = DT_SOCK;
- break;
- default:
- /* safest to call it a file if we do not know */
- fattr->cf_mode |= S_IFREG;
- fattr->cf_dtype = DT_REG;
- cFYI(1, "unknown type %d", le32_to_cpu(info->Type));
- break;
- }
-
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
- fattr->cf_uid = cifs_sb->mnt_uid;
- else
- fattr->cf_uid = le64_to_cpu(info->Uid);
-
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
- fattr->cf_gid = cifs_sb->mnt_gid;
- else
- fattr->cf_gid = le64_to_cpu(info->Gid);
-
- fattr->cf_nlink = le64_to_cpu(info->Nlinks);
-}
-
-/*
- * Fill a cifs_fattr struct with fake inode info.
- *
- * Needed to setup cifs_fattr data for the directory which is the
- * junction to the new submount (ie to setup the fake directory
- * which represents a DFS referral).
- */
-static void
-cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb)
-{
- struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
-
- cFYI(1, "creating fake fattr for DFS referral");
-
- memset(fattr, 0, sizeof(*fattr));
- fattr->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU;
- fattr->cf_uid = cifs_sb->mnt_uid;
- fattr->cf_gid = cifs_sb->mnt_gid;
- fattr->cf_atime = CURRENT_TIME;
- fattr->cf_ctime = CURRENT_TIME;
- fattr->cf_mtime = CURRENT_TIME;
- fattr->cf_nlink = 2;
- fattr->cf_flags |= CIFS_FATTR_DFS_REFERRAL;
-}
-
-int cifs_get_file_info_unix(struct file *filp)
-{
- int rc;
- int xid;
- FILE_UNIX_BASIC_INFO find_data;
- struct cifs_fattr fattr;
- struct inode *inode = filp->f_path.dentry->d_inode;
- struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
- struct cifsFileInfo *cfile = filp->private_data;
- struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
-
- xid = GetXid();
- rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->netfid, &find_data);
- if (!rc) {
- cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb);
- } else if (rc == -EREMOTE) {
- cifs_create_dfs_fattr(&fattr, inode->i_sb);
- rc = 0;
- }
-
- cifs_fattr_to_inode(inode, &fattr);
- FreeXid(xid);
- return rc;
-}
-
-int cifs_get_inode_info_unix(struct inode **pinode,
- const unsigned char *full_path,
- struct super_block *sb, int xid)
-{
- int rc;
- FILE_UNIX_BASIC_INFO find_data;
- struct cifs_fattr fattr;
- struct cifs_tcon *tcon;
- struct tcon_link *tlink;
- struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
-
- cFYI(1, "Getting info on %s", full_path);
-
- tlink = cifs_sb_tlink(cifs_sb);
- if (IS_ERR(tlink))
- return PTR_ERR(tlink);
- tcon = tlink_tcon(tlink);
-
- /* could have done a find first instead but this returns more info */
- rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data,
- cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- cifs_put_tlink(tlink);
-
- if (!rc) {
- cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb);
- } else if (rc == -EREMOTE) {
- cifs_create_dfs_fattr(&fattr, sb);
- rc = 0;
- } else {
- return rc;
- }
-
- /* check for Minshall+French symlinks */
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {
- int tmprc = CIFSCheckMFSymlink(&fattr, full_path, cifs_sb, xid);
- if (tmprc)
- cFYI(1, "CIFSCheckMFSymlink: %d", tmprc);
- }
-
- if (*pinode == NULL) {
- /* get new inode */
- cifs_fill_uniqueid(sb, &fattr);
- *pinode = cifs_iget(sb, &fattr);
- if (!*pinode)
- rc = -ENOMEM;
- } else {
- /* we already have inode, update it */
- cifs_fattr_to_inode(*pinode, &fattr);
- }
-
- return rc;
-}
-
-static int
-cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
- struct cifs_sb_info *cifs_sb, int xid)
-{
- int rc;
- int oplock = 0;
- __u16 netfid;
- struct tcon_link *tlink;
- struct cifs_tcon *tcon;
- struct cifs_io_parms io_parms;
- char buf[24];
- unsigned int bytes_read;
- char *pbuf;
-
- pbuf = buf;
-
- fattr->cf_mode &= ~S_IFMT;
-
- if (fattr->cf_eof == 0) {
- fattr->cf_mode |= S_IFIFO;
- fattr->cf_dtype = DT_FIFO;
- return 0;
- } else if (fattr->cf_eof < 8) {
- fattr->cf_mode |= S_IFREG;
- fattr->cf_dtype = DT_REG;
- return -EINVAL; /* EOPNOTSUPP? */
- }
-
- tlink = cifs_sb_tlink(cifs_sb);
- if (IS_ERR(tlink))
- return PTR_ERR(tlink);
- tcon = tlink_tcon(tlink);
-
- rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, GENERIC_READ,
- CREATE_NOT_DIR, &netfid, &oplock, NULL,
- cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- if (rc == 0) {
- int buf_type = CIFS_NO_BUFFER;
- /* Read header */
- io_parms.netfid = netfid;
- io_parms.pid = current->tgid;
- io_parms.tcon = tcon;
- io_parms.offset = 0;
- io_parms.length = 24;
- rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf,
- &buf_type);
- if ((rc == 0) && (bytes_read >= 8)) {
- if (memcmp("IntxBLK", pbuf, 8) == 0) {
- cFYI(1, "Block device");
- fattr->cf_mode |= S_IFBLK;
- fattr->cf_dtype = DT_BLK;
- if (bytes_read == 24) {
- /* we have enough to decode dev num */
- __u64 mjr; /* major */
- __u64 mnr; /* minor */
- mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
- mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
- fattr->cf_rdev = MKDEV(mjr, mnr);
- }
- } else if (memcmp("IntxCHR", pbuf, 8) == 0) {
- cFYI(1, "Char device");
- fattr->cf_mode |= S_IFCHR;
- fattr->cf_dtype = DT_CHR;
- if (bytes_read == 24) {
- /* we have enough to decode dev num */
- __u64 mjr; /* major */
- __u64 mnr; /* minor */
- mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
- mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
- fattr->cf_rdev = MKDEV(mjr, mnr);
- }
- } else if (memcmp("IntxLNK", pbuf, 7) == 0) {
- cFYI(1, "Symlink");
- fattr->cf_mode |= S_IFLNK;
- fattr->cf_dtype = DT_LNK;
- } else {
- fattr->cf_mode |= S_IFREG; /* file? */
- fattr->cf_dtype = DT_REG;
- rc = -EOPNOTSUPP;
- }
- } else {
- fattr->cf_mode |= S_IFREG; /* then it is a file */
- fattr->cf_dtype = DT_REG;
- rc = -EOPNOTSUPP; /* or some unknown SFU type */
- }
- CIFSSMBClose(xid, tcon, netfid);
- }
- cifs_put_tlink(tlink);
- return rc;
-}
-
-#define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID) /* SETFILEBITS valid bits */
-
-/*
- * Fetch mode bits as provided by SFU.
- *
- * FIXME: Doesn't this clobber the type bit we got from cifs_sfu_type ?
- */
-static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,
- struct cifs_sb_info *cifs_sb, int xid)
-{
-#ifdef CONFIG_CIFS_XATTR
- ssize_t rc;
- char ea_value[4];
- __u32 mode;
- struct tcon_link *tlink;
- struct cifs_tcon *tcon;
-
- tlink = cifs_sb_tlink(cifs_sb);
- if (IS_ERR(tlink))
- return PTR_ERR(tlink);
- tcon = tlink_tcon(tlink);
-
- rc = CIFSSMBQAllEAs(xid, tcon, path, "SETFILEBITS",
- ea_value, 4 /* size of buf */, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- cifs_put_tlink(tlink);
- if (rc < 0)
- return (int)rc;
- else if (rc > 3) {
- mode = le32_to_cpu(*((__le32 *)ea_value));
- fattr->cf_mode &= ~SFBITS_MASK;
- cFYI(1, "special bits 0%o org mode 0%o", mode,
- fattr->cf_mode);
- fattr->cf_mode = (mode & SFBITS_MASK) | fattr->cf_mode;
- cFYI(1, "special mode bits 0%o", mode);
- }
-
- return 0;
-#else
- return -EOPNOTSUPP;
-#endif
-}
-
-/* Fill a cifs_fattr struct with info from FILE_ALL_INFO */
-static void
-cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
- struct cifs_sb_info *cifs_sb, bool adjust_tz)
-{
- struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
-
- memset(fattr, 0, sizeof(*fattr));
- fattr->cf_cifsattrs = le32_to_cpu(info->Attributes);
- if (info->DeletePending)
- fattr->cf_flags |= CIFS_FATTR_DELETE_PENDING;
-
- if (info->LastAccessTime)
- fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);
- else
- fattr->cf_atime = CURRENT_TIME;
-
- fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime);
- fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime);
-
- if (adjust_tz) {
- fattr->cf_ctime.tv_sec += tcon->ses->server->timeAdj;
- fattr->cf_mtime.tv_sec += tcon->ses->server->timeAdj;
- }
-
- fattr->cf_eof = le64_to_cpu(info->EndOfFile);
- fattr->cf_bytes = le64_to_cpu(info->AllocationSize);
- fattr->cf_createtime = le64_to_cpu(info->CreationTime);
-
- if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
- fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode;
- fattr->cf_dtype = DT_DIR;
- /*
- * Server can return wrong NumberOfLinks value for directories
- * when Unix extensions are disabled - fake it.
- */
- fattr->cf_nlink = 2;
- } else {
- fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode;
- fattr->cf_dtype = DT_REG;
-
- /* clear write bits if ATTR_READONLY is set */
- if (fattr->cf_cifsattrs & ATTR_READONLY)
- fattr->cf_mode &= ~(S_IWUGO);
-
- fattr->cf_nlink = le32_to_cpu(info->NumberOfLinks);
- }
-
- fattr->cf_uid = cifs_sb->mnt_uid;
- fattr->cf_gid = cifs_sb->mnt_gid;
-}
-
-int cifs_get_file_info(struct file *filp)
-{
- int rc;
- int xid;
- FILE_ALL_INFO find_data;
- struct cifs_fattr fattr;
- struct inode *inode = filp->f_path.dentry->d_inode;
- struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
- struct cifsFileInfo *cfile = filp->private_data;
- struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
-
- xid = GetXid();
- rc = CIFSSMBQFileInfo(xid, tcon, cfile->netfid, &find_data);
- switch (rc) {
- case 0:
- cifs_all_info_to_fattr(&fattr, &find_data, cifs_sb, false);
- break;
- case -EREMOTE:
- cifs_create_dfs_fattr(&fattr, inode->i_sb);
- rc = 0;
- break;
- case -EOPNOTSUPP:
- case -EINVAL:
- /*
- * FIXME: legacy server -- fall back to path-based call?
- * for now, just skip revalidating and mark inode for
- * immediate reval.
- */
- rc = 0;
- CIFS_I(inode)->time = 0;
- default:
- goto cgfi_exit;
- }
-
- /*
- * don't bother with SFU junk here -- just mark inode as needing
- * revalidation.
- */
- fattr.cf_uniqueid = CIFS_I(inode)->uniqueid;
- fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
- cifs_fattr_to_inode(inode, &fattr);
-cgfi_exit:
- FreeXid(xid);
- return rc;
-}
-
-int cifs_get_inode_info(struct inode **pinode,
- const unsigned char *full_path, FILE_ALL_INFO *pfindData,
- struct super_block *sb, int xid, const __u16 *pfid)
-{
- int rc = 0, tmprc;
- struct cifs_tcon *pTcon;
- struct tcon_link *tlink;
- struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
- char *buf = NULL;
- bool adjustTZ = false;
- struct cifs_fattr fattr;
-
- tlink = cifs_sb_tlink(cifs_sb);
- if (IS_ERR(tlink))
- return PTR_ERR(tlink);
- pTcon = tlink_tcon(tlink);
-
- cFYI(1, "Getting info on %s", full_path);
-
- if ((pfindData == NULL) && (*pinode != NULL)) {
- if (CIFS_I(*pinode)->clientCanCacheRead) {
- cFYI(1, "No need to revalidate cached inode sizes");
- goto cgii_exit;
- }
- }
-
- /* if file info not passed in then get it from server */
- if (pfindData == NULL) {
- buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
- if (buf == NULL) {
- rc = -ENOMEM;
- goto cgii_exit;
- }
- pfindData = (FILE_ALL_INFO *)buf;
-
- /* could do find first instead but this returns more info */
- rc = CIFSSMBQPathInfo(xid, pTcon, full_path, pfindData,
- 0 /* not legacy */,
- cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- /* BB optimize code so we do not make the above call
- when server claims no NT SMB support and the above call
- failed at least once - set flag in tcon or mount */
- if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) {
- rc = SMBQueryInformation(xid, pTcon, full_path,
- pfindData, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- adjustTZ = true;
- }
- }
-
- if (!rc) {
- cifs_all_info_to_fattr(&fattr, (FILE_ALL_INFO *) pfindData,
- cifs_sb, adjustTZ);
- } else if (rc == -EREMOTE) {
- cifs_create_dfs_fattr(&fattr, sb);
- rc = 0;
- } else {
- goto cgii_exit;
- }
-
- /*
- * If an inode wasn't passed in, then get the inode number
- *
- * Is an i_ino of zero legal? Can we use that to check if the server
- * supports returning inode numbers? Are there other sanity checks we
- * can use to ensure that the server is really filling in that field?
- *
- * We can not use the IndexNumber field by default from Windows or
- * Samba (in ALL_INFO buf) but we can request it explicitly. The SNIA
- * CIFS spec claims that this value is unique within the scope of a
- * share, and the windows docs hint that it's actually unique
- * per-machine.
- *
- * There may be higher info levels that work but are there Windows
- * server or network appliances for which IndexNumber field is not
- * guaranteed unique?
- */
- if (*pinode == NULL) {
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
- int rc1 = 0;
-
- rc1 = CIFSGetSrvInodeNumber(xid, pTcon,
- full_path, &fattr.cf_uniqueid,
- cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- if (rc1 || !fattr.cf_uniqueid) {
- cFYI(1, "GetSrvInodeNum rc %d", rc1);
- fattr.cf_uniqueid = iunique(sb, ROOT_I);
- cifs_autodisable_serverino(cifs_sb);
- }
- } else {
- fattr.cf_uniqueid = iunique(sb, ROOT_I);
- }
- } else {
- fattr.cf_uniqueid = CIFS_I(*pinode)->uniqueid;
- }
-
- /* query for SFU type info if supported and needed */
- if (fattr.cf_cifsattrs & ATTR_SYSTEM &&
- cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
- tmprc = cifs_sfu_type(&fattr, full_path, cifs_sb, xid);
- if (tmprc)
- cFYI(1, "cifs_sfu_type failed: %d", tmprc);
- }
-
-#ifdef CONFIG_CIFS_ACL
- /* fill in 0777 bits from ACL */
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
- rc = cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path,
- pfid);
- if (rc) {
- cFYI(1, "%s: Getting ACL failed with error: %d",
- __func__, rc);
- goto cgii_exit;
- }
- }
-#endif /* CONFIG_CIFS_ACL */
-
- /* fill in remaining high mode bits e.g. SUID, VTX */
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
- cifs_sfu_mode(&fattr, full_path, cifs_sb, xid);
-
- /* check for Minshall+French symlinks */
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {
- tmprc = CIFSCheckMFSymlink(&fattr, full_path, cifs_sb, xid);
- if (tmprc)
- cFYI(1, "CIFSCheckMFSymlink: %d", tmprc);
- }
-
- if (!*pinode) {
- *pinode = cifs_iget(sb, &fattr);
- if (!*pinode)
- rc = -ENOMEM;
- } else {
- cifs_fattr_to_inode(*pinode, &fattr);
- }
-
-cgii_exit:
- kfree(buf);
- cifs_put_tlink(tlink);
- return rc;
-}
-
-static const struct inode_operations cifs_ipc_inode_ops = {
- .lookup = cifs_lookup,
-};
-
-char *cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
- struct cifs_tcon *tcon)
-{
- int pplen = vol->prepath ? strlen(vol->prepath) : 0;
- int dfsplen;
- char *full_path = NULL;
-
- /* if no prefix path, simply set path to the root of share to "" */
- if (pplen == 0) {
- full_path = kmalloc(1, GFP_KERNEL);
- if (full_path)
- full_path[0] = 0;
- return full_path;
- }
-
- if (tcon->Flags & SMB_SHARE_IS_IN_DFS)
- dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
- else
- dfsplen = 0;
-
- full_path = kmalloc(dfsplen + pplen + 1, GFP_KERNEL);
- if (full_path == NULL)
- return full_path;
-
- if (dfsplen)
- strncpy(full_path, tcon->treeName, dfsplen);
- strncpy(full_path + dfsplen, vol->prepath, pplen);
- convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb));
- full_path[dfsplen + pplen] = 0; /* add trailing null */
- return full_path;
-}
-
-static int
-cifs_find_inode(struct inode *inode, void *opaque)
-{
- struct cifs_fattr *fattr = (struct cifs_fattr *) opaque;
-
- /* don't match inode with different uniqueid */
- if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid)
- return 0;
-
- /* use createtime like an i_generation field */
- if (CIFS_I(inode)->createtime != fattr->cf_createtime)
- return 0;
-
- /* don't match inode of different type */
- if ((inode->i_mode & S_IFMT) != (fattr->cf_mode & S_IFMT))
- return 0;
-
- /* if it's not a directory or has no dentries, then flag it */
- if (S_ISDIR(inode->i_mode) && !list_empty(&inode->i_dentry))
- fattr->cf_flags |= CIFS_FATTR_INO_COLLISION;
-
- return 1;
-}
-
-static int
-cifs_init_inode(struct inode *inode, void *opaque)
-{
- struct cifs_fattr *fattr = (struct cifs_fattr *) opaque;
-
- CIFS_I(inode)->uniqueid = fattr->cf_uniqueid;
- CIFS_I(inode)->createtime = fattr->cf_createtime;
- return 0;
-}
-
-/*
- * walk dentry list for an inode and report whether it has aliases that
- * are hashed. We use this to determine if a directory inode can actually
- * be used.
- */
-static bool
-inode_has_hashed_dentries(struct inode *inode)
-{
- struct dentry *dentry;
-
- spin_lock(&inode->i_lock);
- list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
- if (!d_unhashed(dentry) || IS_ROOT(dentry)) {
- spin_unlock(&inode->i_lock);
- return true;
- }
- }
- spin_unlock(&inode->i_lock);
- return false;
-}
-
-/* Given fattrs, get a corresponding inode */
-struct inode *
-cifs_iget(struct super_block *sb, struct cifs_fattr *fattr)
-{
- unsigned long hash;
- struct inode *inode;
-
-retry_iget5_locked:
- cFYI(1, "looking for uniqueid=%llu", fattr->cf_uniqueid);
-
- /* hash down to 32-bits on 32-bit arch */
- hash = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid);
-
- inode = iget5_locked(sb, hash, cifs_find_inode, cifs_init_inode, fattr);
- if (inode) {
- /* was there a potentially problematic inode collision? */
- if (fattr->cf_flags & CIFS_FATTR_INO_COLLISION) {
- fattr->cf_flags &= ~CIFS_FATTR_INO_COLLISION;
-
- if (inode_has_hashed_dentries(inode)) {
- cifs_autodisable_serverino(CIFS_SB(sb));
- iput(inode);
- fattr->cf_uniqueid = iunique(sb, ROOT_I);
- goto retry_iget5_locked;
- }
- }
-
- cifs_fattr_to_inode(inode, fattr);
- if (sb->s_flags & MS_NOATIME)
- inode->i_flags |= S_NOATIME | S_NOCMTIME;
- if (inode->i_state & I_NEW) {
- inode->i_ino = hash;
- if (S_ISREG(inode->i_mode))
- inode->i_data.backing_dev_info = sb->s_bdi;
-#ifdef CONFIG_CIFS_FSCACHE
- /* initialize per-inode cache cookie pointer */
- CIFS_I(inode)->fscache = NULL;
-#endif
- unlock_new_inode(inode);
- }
- }
-
- return inode;
-}
-
-/* gets root inode */
-struct inode *cifs_root_iget(struct super_block *sb)
-{
- int xid;
- struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
- struct inode *inode = NULL;
- long rc;
- struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
-
- xid = GetXid();
- if (tcon->unix_ext)
- rc = cifs_get_inode_info_unix(&inode, "", sb, xid);
- else
- rc = cifs_get_inode_info(&inode, "", NULL, sb, xid, NULL);
-
- if (!inode) {
- inode = ERR_PTR(rc);
- goto out;
- }
-
-#ifdef CONFIG_CIFS_FSCACHE
- /* populate tcon->resource_id */
- tcon->resource_id = CIFS_I(inode)->uniqueid;
-#endif
-
- if (rc && tcon->ipc) {
- cFYI(1, "ipc connection - fake read inode");
- inode->i_mode |= S_IFDIR;
- set_nlink(inode, 2);
- inode->i_op = &cifs_ipc_inode_ops;
- inode->i_fop = &simple_dir_operations;
- inode->i_uid = cifs_sb->mnt_uid;
- inode->i_gid = cifs_sb->mnt_gid;
- } else if (rc) {
- iget_failed(inode);
- inode = ERR_PTR(rc);
- }
-
-out:
- /* can not call macro FreeXid here since in a void func
- * TODO: This is no longer true
- */
- _FreeXid(xid);
- return inode;
-}
-
-static int
-cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid,
- char *full_path, __u32 dosattr)
-{
- int rc;
- int oplock = 0;
- __u16 netfid;
- __u32 netpid;
- bool set_time = false;
- struct cifsFileInfo *open_file;
- struct cifsInodeInfo *cifsInode = CIFS_I(inode);
- struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
- struct tcon_link *tlink = NULL;
- struct cifs_tcon *pTcon;
- FILE_BASIC_INFO info_buf;
-
- if (attrs == NULL)
- return -EINVAL;
-
- if (attrs->ia_valid & ATTR_ATIME) {
- set_time = true;
- info_buf.LastAccessTime =
- cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_atime));
- } else
- info_buf.LastAccessTime = 0;
-
- if (attrs->ia_valid & ATTR_MTIME) {
- set_time = true;
- info_buf.LastWriteTime =
- cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime));
- } else
- info_buf.LastWriteTime = 0;
-
- /*
- * Samba throws this field away, but windows may actually use it.
- * Do not set ctime unless other time stamps are changed explicitly
- * (i.e. by utimes()) since we would then have a mix of client and
- * server times.
- */
- if (set_time && (attrs->ia_valid & ATTR_CTIME)) {
- cFYI(1, "CIFS - CTIME changed");
- info_buf.ChangeTime =
- cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime));
- } else
- info_buf.ChangeTime = 0;
-
- info_buf.CreationTime = 0; /* don't change */
- info_buf.Attributes = cpu_to_le32(dosattr);
-
- /*
- * If the file is already open for write, just use that fileid
- */
- open_file = find_writable_file(cifsInode, true);
- if (open_file) {
- netfid = open_file->netfid;
- netpid = open_file->pid;
- pTcon = tlink_tcon(open_file->tlink);
- goto set_via_filehandle;
- }
-
- tlink = cifs_sb_tlink(cifs_sb);
- if (IS_ERR(tlink)) {
- rc = PTR_ERR(tlink);
- tlink = NULL;
- goto out;
- }
- pTcon = tlink_tcon(tlink);
-
- /*
- * NT4 apparently returns success on this call, but it doesn't
- * really work.
- */
- if (!(pTcon->ses->flags & CIFS_SES_NT4)) {
- rc = CIFSSMBSetPathInfo(xid, pTcon, full_path,
- &info_buf, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- if (rc == 0) {
- cifsInode->cifsAttrs = dosattr;
- goto out;
- } else if (rc != -EOPNOTSUPP && rc != -EINVAL)
- goto out;
- }
-
- cFYI(1, "calling SetFileInfo since SetPathInfo for "
- "times not supported by this server");
- rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN,
- SYNCHRONIZE | FILE_WRITE_ATTRIBUTES,
- CREATE_NOT_DIR, &netfid, &oplock,
- NULL, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
-
- if (rc != 0) {
- if (rc == -EIO)
- rc = -EINVAL;
- goto out;
- }
-
- netpid = current->tgid;
-
-set_via_filehandle:
- rc = CIFSSMBSetFileInfo(xid, pTcon, &info_buf, netfid, netpid);
- if (!rc)
- cifsInode->cifsAttrs = dosattr;
-
- if (open_file == NULL)
- CIFSSMBClose(xid, pTcon, netfid);
- else
- cifsFileInfo_put(open_file);
-out:
- if (tlink != NULL)
- cifs_put_tlink(tlink);
- return rc;
-}
-
-/*
- * open the given file (if it isn't already), set the DELETE_ON_CLOSE bit
- * and rename it to a random name that hopefully won't conflict with
- * anything else.
- */
-static int
-cifs_rename_pending_delete(char *full_path, struct dentry *dentry, int xid)
-{
- int oplock = 0;
- int rc;
- __u16 netfid;
- struct inode *inode = dentry->d_inode;
- struct cifsInodeInfo *cifsInode = CIFS_I(inode);
- struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
- struct tcon_link *tlink;
- struct cifs_tcon *tcon;
- __u32 dosattr, origattr;
- FILE_BASIC_INFO *info_buf = NULL;
-
- tlink = cifs_sb_tlink(cifs_sb);
- if (IS_ERR(tlink))
- return PTR_ERR(tlink);
- tcon = tlink_tcon(tlink);
-
- rc = CIFSSMBOpen(xid, tcon, full_path, FILE_OPEN,
- DELETE|FILE_WRITE_ATTRIBUTES, CREATE_NOT_DIR,
- &netfid, &oplock, NULL, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
- if (rc != 0)
- goto out;
-
- origattr = cifsInode->cifsAttrs;
- if (origattr == 0)
- origattr |= ATTR_NORMAL;
-
- dosattr = origattr & ~ATTR_READONLY;
- if (dosattr == 0)
- dosattr |= ATTR_NORMAL;
- dosattr |= ATTR_HIDDEN;
-
- /* set ATTR_HIDDEN and clear ATTR_READONLY, but only if needed */
- if (dosattr != origattr) {
- info_buf = kzalloc(sizeof(*info_buf), GFP_KERNEL);
- if (info_buf == NULL) {
- rc = -ENOMEM;
- goto out_close;
- }
- info_buf->Attributes = cpu_to_le32(dosattr);
- rc = CIFSSMBSetFileInfo(xid, tcon, info_buf, netfid,
- current->tgid);
- /* although we would like to mark the file hidden
- if that fails we will still try to rename it */
- if (rc != 0)
- cifsInode->cifsAttrs = dosattr;
- else
- dosattr = origattr; /* since not able to change them */
- }
-
- /* rename the file */
- rc = CIFSSMBRenameOpenFile(xid, tcon, netfid, NULL, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- if (rc != 0) {
- rc = -ETXTBSY;
- goto undo_setattr;
- }
-
- /* try to set DELETE_ON_CLOSE */
- if (!cifsInode->delete_pending) {
- rc = CIFSSMBSetFileDisposition(xid, tcon, true, netfid,
- current->tgid);
- /*
- * some samba versions return -ENOENT when we try to set the
- * file disposition here. Likely a samba bug, but work around
- * it for now. This means that some cifsXXX files may hang
- * around after they shouldn't.
- *
- * BB: remove this hack after more servers have the fix
- */
- if (rc == -ENOENT)
- rc = 0;
- else if (rc != 0) {
- rc = -ETXTBSY;
- goto undo_rename;
- }
- cifsInode->delete_pending = true;
- }
-
-out_close:
- CIFSSMBClose(xid, tcon, netfid);
-out:
- kfree(info_buf);
- cifs_put_tlink(tlink);
- return rc;
-
- /*
- * reset everything back to the original state. Don't bother
- * dealing with errors here since we can't do anything about
- * them anyway.
- */
-undo_rename:
- CIFSSMBRenameOpenFile(xid, tcon, netfid, dentry->d_name.name,
- cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
-undo_setattr:
- if (dosattr != origattr) {
- info_buf->Attributes = cpu_to_le32(origattr);
- if (!CIFSSMBSetFileInfo(xid, tcon, info_buf, netfid,
- current->tgid))
- cifsInode->cifsAttrs = origattr;
- }
-
- goto out_close;
-}
-
-
-/*
- * If dentry->d_inode is null (usually meaning the cached dentry
- * is a negative dentry) then we would attempt a standard SMB delete, but
- * if that fails we can not attempt the fall back mechanisms on EACCESS
- * but will return the EACCESS to the caller. Note that the VFS does not call
- * unlink on negative dentries currently.
- */
-int cifs_unlink(struct inode *dir, struct dentry *dentry)
-{
- int rc = 0;
- int xid;
- char *full_path = NULL;
- struct inode *inode = dentry->d_inode;
- struct cifsInodeInfo *cifs_inode;
- struct super_block *sb = dir->i_sb;
- struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
- struct tcon_link *tlink;
- struct cifs_tcon *tcon;
- struct iattr *attrs = NULL;
- __u32 dosattr = 0, origattr = 0;
-
- cFYI(1, "cifs_unlink, dir=0x%p, dentry=0x%p", dir, dentry);
-
- tlink = cifs_sb_tlink(cifs_sb);
- if (IS_ERR(tlink))
- return PTR_ERR(tlink);
- tcon = tlink_tcon(tlink);
-
- xid = GetXid();
-
- /* Unlink can be called from rename so we can not take the
- * sb->s_vfs_rename_mutex here */
- full_path = build_path_from_dentry(dentry);
- if (full_path == NULL) {
- rc = -ENOMEM;
- goto unlink_out;
- }
-
- if ((tcon->ses->capabilities & CAP_UNIX) &&
- (CIFS_UNIX_POSIX_PATH_OPS_CAP &
- le64_to_cpu(tcon->fsUnixInfo.Capability))) {
- rc = CIFSPOSIXDelFile(xid, tcon, full_path,
- SMB_POSIX_UNLINK_FILE_TARGET, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
- cFYI(1, "posix del rc %d", rc);
- if ((rc == 0) || (rc == -ENOENT))
- goto psx_del_no_retry;
- }
-
-retry_std_delete:
- rc = CIFSSMBDelFile(xid, tcon, full_path, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
-
-psx_del_no_retry:
- if (!rc) {
- if (inode)
- drop_nlink(inode);
- } else if (rc == -ENOENT) {
- d_drop(dentry);
- } else if (rc == -ETXTBSY) {
- rc = cifs_rename_pending_delete(full_path, dentry, xid);
- if (rc == 0)
- drop_nlink(inode);
- } else if ((rc == -EACCES) && (dosattr == 0) && inode) {
- attrs = kzalloc(sizeof(*attrs), GFP_KERNEL);
- if (attrs == NULL) {
- rc = -ENOMEM;
- goto out_reval;
- }
-
- /* try to reset dos attributes */
- cifs_inode = CIFS_I(inode);
- origattr = cifs_inode->cifsAttrs;
- if (origattr == 0)
- origattr |= ATTR_NORMAL;
- dosattr = origattr & ~ATTR_READONLY;
- if (dosattr == 0)
- dosattr |= ATTR_NORMAL;
- dosattr |= ATTR_HIDDEN;
-
- rc = cifs_set_file_info(inode, attrs, xid, full_path, dosattr);
- if (rc != 0)
- goto out_reval;
-
- goto retry_std_delete;
- }
-
- /* undo the setattr if we errored out and it's needed */
- if (rc != 0 && dosattr != 0)
- cifs_set_file_info(inode, attrs, xid, full_path, origattr);
-
-out_reval:
- if (inode) {
- cifs_inode = CIFS_I(inode);
- cifs_inode->time = 0; /* will force revalidate to get info
- when needed */
- inode->i_ctime = current_fs_time(sb);
- }
- dir->i_ctime = dir->i_mtime = current_fs_time(sb);
- cifs_inode = CIFS_I(dir);
- CIFS_I(dir)->time = 0; /* force revalidate of dir as well */
-unlink_out:
- kfree(full_path);
- kfree(attrs);
- FreeXid(xid);
- cifs_put_tlink(tlink);
- return rc;
-}
-
-int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode)
-{
- int rc = 0, tmprc;
- int xid;
- struct cifs_sb_info *cifs_sb;
- struct tcon_link *tlink;
- struct cifs_tcon *pTcon;
- char *full_path = NULL;
- struct inode *newinode = NULL;
- struct cifs_fattr fattr;
-
- cFYI(1, "In cifs_mkdir, mode = 0x%hx inode = 0x%p", mode, inode);
-
- cifs_sb = CIFS_SB(inode->i_sb);
- tlink = cifs_sb_tlink(cifs_sb);
- if (IS_ERR(tlink))
- return PTR_ERR(tlink);
- pTcon = tlink_tcon(tlink);
-
- xid = GetXid();
-
- full_path = build_path_from_dentry(direntry);
- if (full_path == NULL) {
- rc = -ENOMEM;
- goto mkdir_out;
- }
-
- if ((pTcon->ses->capabilities & CAP_UNIX) &&
- (CIFS_UNIX_POSIX_PATH_OPS_CAP &
- le64_to_cpu(pTcon->fsUnixInfo.Capability))) {
- u32 oplock = 0;
- FILE_UNIX_BASIC_INFO *pInfo =
- kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
- if (pInfo == NULL) {
- rc = -ENOMEM;
- goto mkdir_out;
- }
-
- mode &= ~current_umask();
- rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT,
- mode, NULL /* netfid */, pInfo, &oplock,
- full_path, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- if (rc == -EOPNOTSUPP) {
- kfree(pInfo);
- goto mkdir_retry_old;
- } else if (rc) {
- cFYI(1, "posix mkdir returned 0x%x", rc);
- d_drop(direntry);
- } else {
- if (pInfo->Type == cpu_to_le32(-1)) {
- /* no return info, go query for it */
- kfree(pInfo);
- goto mkdir_get_info;
- }
-/*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need
- to set uid/gid */
-
- cifs_unix_basic_to_fattr(&fattr, pInfo, cifs_sb);
- cifs_fill_uniqueid(inode->i_sb, &fattr);
- newinode = cifs_iget(inode->i_sb, &fattr);
- if (!newinode) {
- kfree(pInfo);
- goto mkdir_get_info;
- }
-
- d_instantiate(direntry, newinode);
-
-#ifdef CONFIG_CIFS_DEBUG2
- cFYI(1, "instantiated dentry %p %s to inode %p",
- direntry, direntry->d_name.name, newinode);
-
- if (newinode->i_nlink != 2)
- cFYI(1, "unexpected number of links %d",
- newinode->i_nlink);
-#endif
- }
- kfree(pInfo);
- goto mkdir_out;
- }
-mkdir_retry_old:
- /* BB add setting the equivalent of mode via CreateX w/ACLs */
- rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
- if (rc) {
- cFYI(1, "cifs_mkdir returned 0x%x", rc);
- d_drop(direntry);
- } else {
-mkdir_get_info:
- if (pTcon->unix_ext)
- rc = cifs_get_inode_info_unix(&newinode, full_path,
- inode->i_sb, xid);
- else
- rc = cifs_get_inode_info(&newinode, full_path, NULL,
- inode->i_sb, xid, NULL);
-
- d_instantiate(direntry, newinode);
- /* setting nlink not necessary except in cases where we
- * failed to get it from the server or was set bogus */
- if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2))
- set_nlink(direntry->d_inode, 2);
-
- mode &= ~current_umask();
- /* must turn on setgid bit if parent dir has it */
- if (inode->i_mode & S_ISGID)
- mode |= S_ISGID;
-
- if (pTcon->unix_ext) {
- struct cifs_unix_set_info_args args = {
- .mode = mode,
- .ctime = NO_CHANGE_64,
- .atime = NO_CHANGE_64,
- .mtime = NO_CHANGE_64,
- .device = 0,
- };
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
- args.uid = (__u64)current_fsuid();
- if (inode->i_mode & S_ISGID)
- args.gid = (__u64)inode->i_gid;
- else
- args.gid = (__u64)current_fsgid();
- } else {
- args.uid = NO_CHANGE_64;
- args.gid = NO_CHANGE_64;
- }
- CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, &args,
- cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- } else {
- if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) &&
- (mode & S_IWUGO) == 0) {
- FILE_BASIC_INFO pInfo;
- struct cifsInodeInfo *cifsInode;
- u32 dosattrs;
-
- memset(&pInfo, 0, sizeof(pInfo));
- cifsInode = CIFS_I(newinode);
- dosattrs = cifsInode->cifsAttrs|ATTR_READONLY;
- pInfo.Attributes = cpu_to_le32(dosattrs);
- tmprc = CIFSSMBSetPathInfo(xid, pTcon,
- full_path, &pInfo,
- cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- if (tmprc == 0)
- cifsInode->cifsAttrs = dosattrs;
- }
- if (direntry->d_inode) {
- if (cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_DYNPERM)
- direntry->d_inode->i_mode =
- (mode | S_IFDIR);
-
- if (cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_SET_UID) {
- direntry->d_inode->i_uid =
- current_fsuid();
- if (inode->i_mode & S_ISGID)
- direntry->d_inode->i_gid =
- inode->i_gid;
- else
- direntry->d_inode->i_gid =
- current_fsgid();
- }
- }
- }
- }
-mkdir_out:
- /*
- * Force revalidate to get parent dir info when needed since cached
- * attributes are invalid now.
- */
- CIFS_I(inode)->time = 0;
- kfree(full_path);
- FreeXid(xid);
- cifs_put_tlink(tlink);
- return rc;
-}
-
-int cifs_rmdir(struct inode *inode, struct dentry *direntry)
-{
- int rc = 0;
- int xid;
- struct cifs_sb_info *cifs_sb;
- struct tcon_link *tlink;
- struct cifs_tcon *pTcon;
- char *full_path = NULL;
- struct cifsInodeInfo *cifsInode;
-
- cFYI(1, "cifs_rmdir, inode = 0x%p", inode);
-
- xid = GetXid();
-
- full_path = build_path_from_dentry(direntry);
- if (full_path == NULL) {
- rc = -ENOMEM;
- goto rmdir_exit;
- }
-
- cifs_sb = CIFS_SB(inode->i_sb);
- tlink = cifs_sb_tlink(cifs_sb);
- if (IS_ERR(tlink)) {
- rc = PTR_ERR(tlink);
- goto rmdir_exit;
- }
- pTcon = tlink_tcon(tlink);
-
- rc = CIFSSMBRmDir(xid, pTcon, full_path, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
- cifs_put_tlink(tlink);
-
- if (!rc) {
- spin_lock(&direntry->d_inode->i_lock);
- i_size_write(direntry->d_inode, 0);
- clear_nlink(direntry->d_inode);
- spin_unlock(&direntry->d_inode->i_lock);
- }
-
- cifsInode = CIFS_I(direntry->d_inode);
- /* force revalidate to go get info when needed */
- cifsInode->time = 0;
-
- cifsInode = CIFS_I(inode);
- /*
- * Force revalidate to get parent dir info when needed since cached
- * attributes are invalid now.
- */
- cifsInode->time = 0;
-
- direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime =
- current_fs_time(inode->i_sb);
-
-rmdir_exit:
- kfree(full_path);
- FreeXid(xid);
- return rc;
-}
-
-static int
-cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath,
- struct dentry *to_dentry, const char *toPath)
-{
- struct cifs_sb_info *cifs_sb = CIFS_SB(from_dentry->d_sb);
- struct tcon_link *tlink;
- struct cifs_tcon *pTcon;
- __u16 srcfid;
- int oplock, rc;
-
- tlink = cifs_sb_tlink(cifs_sb);
- if (IS_ERR(tlink))
- return PTR_ERR(tlink);
- pTcon = tlink_tcon(tlink);
-
- /* try path-based rename first */
- rc = CIFSSMBRename(xid, pTcon, fromPath, toPath, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
-
- /*
- * don't bother with rename by filehandle unless file is busy and
- * source Note that cross directory moves do not work with
- * rename by filehandle to various Windows servers.
- */
- if (rc == 0 || rc != -ETXTBSY)
- goto do_rename_exit;
-
- /* open-file renames don't work across directories */
- if (to_dentry->d_parent != from_dentry->d_parent)
- goto do_rename_exit;
-
- /* open the file to be renamed -- we need DELETE perms */
- rc = CIFSSMBOpen(xid, pTcon, fromPath, FILE_OPEN, DELETE,
- CREATE_NOT_DIR, &srcfid, &oplock, NULL,
- cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
-
- if (rc == 0) {
- rc = CIFSSMBRenameOpenFile(xid, pTcon, srcfid,
- (const char *) to_dentry->d_name.name,
- cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
-
- CIFSSMBClose(xid, pTcon, srcfid);
- }
-do_rename_exit:
- cifs_put_tlink(tlink);
- return rc;
-}
-
-int cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
- struct inode *target_dir, struct dentry *target_dentry)
-{
- char *fromName = NULL;
- char *toName = NULL;
- struct cifs_sb_info *cifs_sb;
- struct tcon_link *tlink;
- struct cifs_tcon *tcon;
- FILE_UNIX_BASIC_INFO *info_buf_source = NULL;
- FILE_UNIX_BASIC_INFO *info_buf_target;
- int xid, rc, tmprc;
-
- cifs_sb = CIFS_SB(source_dir->i_sb);
- tlink = cifs_sb_tlink(cifs_sb);
- if (IS_ERR(tlink))
- return PTR_ERR(tlink);
- tcon = tlink_tcon(tlink);
-
- xid = GetXid();
-
- /*
- * we already have the rename sem so we do not need to
- * grab it again here to protect the path integrity
- */
- fromName = build_path_from_dentry(source_dentry);
- if (fromName == NULL) {
- rc = -ENOMEM;
- goto cifs_rename_exit;
- }
-
- toName = build_path_from_dentry(target_dentry);
- if (toName == NULL) {
- rc = -ENOMEM;
- goto cifs_rename_exit;
- }
-
- rc = cifs_do_rename(xid, source_dentry, fromName,
- target_dentry, toName);
-
- if (rc == -EEXIST && tcon->unix_ext) {
- /*
- * Are src and dst hardlinks of same inode? We can
- * only tell with unix extensions enabled
- */
- info_buf_source =
- kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO),
- GFP_KERNEL);
- if (info_buf_source == NULL) {
- rc = -ENOMEM;
- goto cifs_rename_exit;
- }
-
- info_buf_target = info_buf_source + 1;
- tmprc = CIFSSMBUnixQPathInfo(xid, tcon, fromName,
- info_buf_source,
- cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- if (tmprc != 0)
- goto unlink_target;
-
- tmprc = CIFSSMBUnixQPathInfo(xid, tcon, toName,
- info_buf_target,
- cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
-
- if (tmprc == 0 && (info_buf_source->UniqueId ==
- info_buf_target->UniqueId)) {
- /* same file, POSIX says that this is a noop */
- rc = 0;
- goto cifs_rename_exit;
- }
- } /* else ... BB we could add the same check for Windows by
- checking the UniqueId via FILE_INTERNAL_INFO */
-
-unlink_target:
- /* Try unlinking the target dentry if it's not negative */
- if (target_dentry->d_inode && (rc == -EACCES || rc == -EEXIST)) {
- tmprc = cifs_unlink(target_dir, target_dentry);
- if (tmprc)
- goto cifs_rename_exit;
-
- rc = cifs_do_rename(xid, source_dentry, fromName,
- target_dentry, toName);
- }
-
-cifs_rename_exit:
- kfree(info_buf_source);
- kfree(fromName);
- kfree(toName);
- FreeXid(xid);
- cifs_put_tlink(tlink);
- return rc;
-}
-
-static bool
-cifs_inode_needs_reval(struct inode *inode)
-{
- struct cifsInodeInfo *cifs_i = CIFS_I(inode);
- struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
-
- if (cifs_i->clientCanCacheRead)
- return false;
-
- if (!lookupCacheEnabled)
- return true;
-
- if (cifs_i->time == 0)
- return true;
-
- if (!time_in_range(jiffies, cifs_i->time,
- cifs_i->time + cifs_sb->actimeo))
- return true;
-
- /* hardlinked files w/ noserverino get "special" treatment */
- if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) &&
- S_ISREG(inode->i_mode) && inode->i_nlink != 1)
- return true;
-
- return false;
-}
-
-/*
- * Zap the cache. Called when invalid_mapping flag is set.
- */
-int
-cifs_invalidate_mapping(struct inode *inode)
-{
- int rc = 0;
- struct cifsInodeInfo *cifs_i = CIFS_I(inode);
-
- cifs_i->invalid_mapping = false;
-
- if (inode->i_mapping && inode->i_mapping->nrpages != 0) {
- rc = invalidate_inode_pages2(inode->i_mapping);
- if (rc) {
- cERROR(1, "%s: could not invalidate inode %p", __func__,
- inode);
- cifs_i->invalid_mapping = true;
- }
- }
-
- cifs_fscache_reset_inode_cookie(inode);
- return rc;
-}
-
-int cifs_revalidate_file_attr(struct file *filp)
-{
- int rc = 0;
- struct inode *inode = filp->f_path.dentry->d_inode;
- struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data;
-
- if (!cifs_inode_needs_reval(inode))
- return rc;
-
- if (tlink_tcon(cfile->tlink)->unix_ext)
- rc = cifs_get_file_info_unix(filp);
- else
- rc = cifs_get_file_info(filp);
-
- return rc;
-}
-
-int cifs_revalidate_dentry_attr(struct dentry *dentry)
-{
- int xid;
- int rc = 0;
- struct inode *inode = dentry->d_inode;
- struct super_block *sb = dentry->d_sb;
- char *full_path = NULL;
-
- if (inode == NULL)
- return -ENOENT;
-
- if (!cifs_inode_needs_reval(inode))
- return rc;
-
- xid = GetXid();
-
- /* can not safely grab the rename sem here if rename calls revalidate
- since that would deadlock */
- full_path = build_path_from_dentry(dentry);
- if (full_path == NULL) {
- rc = -ENOMEM;
- goto out;
- }
-
- cFYI(1, "Update attributes: %s inode 0x%p count %d dentry: 0x%p d_time "
- "%ld jiffies %ld", full_path, inode, inode->i_count.counter,
- dentry, dentry->d_time, jiffies);
-
- if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext)
- rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
- else
- rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
- xid, NULL);
-
-out:
- kfree(full_path);
- FreeXid(xid);
- return rc;
-}
-
-int cifs_revalidate_file(struct file *filp)
-{
- int rc;
- struct inode *inode = filp->f_path.dentry->d_inode;
-
- rc = cifs_revalidate_file_attr(filp);
- if (rc)
- return rc;
-
- if (CIFS_I(inode)->invalid_mapping)
- rc = cifs_invalidate_mapping(inode);
- return rc;
-}
-
-/* revalidate a dentry's inode attributes */
-int cifs_revalidate_dentry(struct dentry *dentry)
-{
- int rc;
- struct inode *inode = dentry->d_inode;
-
- rc = cifs_revalidate_dentry_attr(dentry);
- if (rc)
- return rc;
-
- if (CIFS_I(inode)->invalid_mapping)
- rc = cifs_invalidate_mapping(inode);
- return rc;
-}
-
-int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
- struct kstat *stat)
-{
- struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb);
- struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
- struct inode *inode = dentry->d_inode;
- int rc;
-
- /*
- * We need to be sure that all dirty pages are written and the server
- * has actual ctime, mtime and file length.
- */
- if (!CIFS_I(inode)->clientCanCacheRead && inode->i_mapping &&
- inode->i_mapping->nrpages != 0) {
- rc = filemap_fdatawait(inode->i_mapping);
- if (rc) {
- mapping_set_error(inode->i_mapping, rc);
- return rc;
- }
- }
-
- rc = cifs_revalidate_dentry_attr(dentry);
- if (rc)
- return rc;
-
- generic_fillattr(inode, stat);
- stat->blksize = CIFS_MAX_MSGSIZE;
- stat->ino = CIFS_I(inode)->uniqueid;
-
- /*
- * If on a multiuser mount without unix extensions, and the admin hasn't
- * overridden them, set the ownership to the fsuid/fsgid of the current
- * process.
- */
- if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) &&
- !tcon->unix_ext) {
- if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID))
- stat->uid = current_fsuid();
- if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID))
- stat->gid = current_fsgid();
- }
- return rc;
-}
-
-static int cifs_truncate_page(struct address_space *mapping, loff_t from)
-{
- pgoff_t index = from >> PAGE_CACHE_SHIFT;
- unsigned offset = from & (PAGE_CACHE_SIZE - 1);
- struct page *page;
- int rc = 0;
-
- page = grab_cache_page(mapping, index);
- if (!page)
- return -ENOMEM;
-
- zero_user_segment(page, offset, PAGE_CACHE_SIZE);
- unlock_page(page);
- page_cache_release(page);
- return rc;
-}
-
-static void cifs_setsize(struct inode *inode, loff_t offset)
-{
- loff_t oldsize;
-
- spin_lock(&inode->i_lock);
- oldsize = inode->i_size;
- i_size_write(inode, offset);
- spin_unlock(&inode->i_lock);
-
- truncate_pagecache(inode, oldsize, offset);
-}
-
-static int
-cifs_set_file_size(struct inode *inode, struct iattr *attrs,
- int xid, char *full_path)
-{
- int rc;
- struct cifsFileInfo *open_file;
- struct cifsInodeInfo *cifsInode = CIFS_I(inode);
- struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
- struct tcon_link *tlink = NULL;
- struct cifs_tcon *pTcon = NULL;
- struct cifs_io_parms io_parms;
-
- /*
- * To avoid spurious oplock breaks from server, in the case of
- * inodes that we already have open, avoid doing path based
- * setting of file size if we can do it by handle.
- * This keeps our caching token (oplock) and avoids timeouts
- * when the local oplock break takes longer to flush
- * writebehind data than the SMB timeout for the SetPathInfo
- * request would allow
- */
- open_file = find_writable_file(cifsInode, true);
- if (open_file) {
- __u16 nfid = open_file->netfid;
- __u32 npid = open_file->pid;
- pTcon = tlink_tcon(open_file->tlink);
- rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid,
- npid, false);
- cifsFileInfo_put(open_file);
- cFYI(1, "SetFSize for attrs rc = %d", rc);
- if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
- unsigned int bytes_written;
-
- io_parms.netfid = nfid;
- io_parms.pid = npid;
- io_parms.tcon = pTcon;
- io_parms.offset = 0;
- io_parms.length = attrs->ia_size;
- rc = CIFSSMBWrite(xid, &io_parms, &bytes_written,
- NULL, NULL, 1);
- cFYI(1, "Wrt seteof rc %d", rc);
- }
- } else
- rc = -EINVAL;
-
- if (rc != 0) {
- if (pTcon == NULL) {
- tlink = cifs_sb_tlink(cifs_sb);
- if (IS_ERR(tlink))
- return PTR_ERR(tlink);
- pTcon = tlink_tcon(tlink);
- }
-
- /* Set file size by pathname rather than by handle
- either because no valid, writeable file handle for
- it was found or because there was an error setting
- it by handle */
- rc = CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size,
- false, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- cFYI(1, "SetEOF by path (setattrs) rc = %d", rc);
- if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
- __u16 netfid;
- int oplock = 0;
-
- rc = SMBLegacyOpen(xid, pTcon, full_path,
- FILE_OPEN, GENERIC_WRITE,
- CREATE_NOT_DIR, &netfid, &oplock, NULL,
- cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- if (rc == 0) {
- unsigned int bytes_written;
-
- io_parms.netfid = netfid;
- io_parms.pid = current->tgid;
- io_parms.tcon = pTcon;
- io_parms.offset = 0;
- io_parms.length = attrs->ia_size;
- rc = CIFSSMBWrite(xid, &io_parms,
- &bytes_written,
- NULL, NULL, 1);
- cFYI(1, "wrt seteof rc %d", rc);
- CIFSSMBClose(xid, pTcon, netfid);
- }
- }
- if (tlink)
- cifs_put_tlink(tlink);
- }
-
- if (rc == 0) {
- cifsInode->server_eof = attrs->ia_size;
- cifs_setsize(inode, attrs->ia_size);
- cifs_truncate_page(inode->i_mapping, inode->i_size);
- }
-
- return rc;
-}
-
-static int
-cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
-{
- int rc;
- int xid;
- char *full_path = NULL;
- struct inode *inode = direntry->d_inode;
- struct cifsInodeInfo *cifsInode = CIFS_I(inode);
- struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
- struct tcon_link *tlink;
- struct cifs_tcon *pTcon;
- struct cifs_unix_set_info_args *args = NULL;
- struct cifsFileInfo *open_file;
-
- cFYI(1, "setattr_unix on file %s attrs->ia_valid=0x%x",
- direntry->d_name.name, attrs->ia_valid);
-
- xid = GetXid();
-
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
- attrs->ia_valid |= ATTR_FORCE;
-
- rc = inode_change_ok(inode, attrs);
- if (rc < 0)
- goto out;
-
- full_path = build_path_from_dentry(direntry);
- if (full_path == NULL) {
- rc = -ENOMEM;
- goto out;
- }
-
- /*
- * Attempt to flush data before changing attributes. We need to do
- * this for ATTR_SIZE and ATTR_MTIME for sure, and if we change the
- * ownership or mode then we may also need to do this. Here, we take
- * the safe way out and just do the flush on all setattr requests. If
- * the flush returns error, store it to report later and continue.
- *
- * BB: This should be smarter. Why bother flushing pages that
- * will be truncated anyway? Also, should we error out here if
- * the flush returns error?
- */
- rc = filemap_write_and_wait(inode->i_mapping);
- mapping_set_error(inode->i_mapping, rc);
- rc = 0;
-
- if (attrs->ia_valid & ATTR_SIZE) {
- rc = cifs_set_file_size(inode, attrs, xid, full_path);
- if (rc != 0)
- goto out;
- }
-
- /* skip mode change if it's just for clearing setuid/setgid */
- if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
- attrs->ia_valid &= ~ATTR_MODE;
-
- args = kmalloc(sizeof(*args), GFP_KERNEL);
- if (args == NULL) {
- rc = -ENOMEM;
- goto out;
- }
-
- /* set up the struct */
- if (attrs->ia_valid & ATTR_MODE)
- args->mode = attrs->ia_mode;
- else
- args->mode = NO_CHANGE_64;
-
- if (attrs->ia_valid & ATTR_UID)
- args->uid = attrs->ia_uid;
- else
- args->uid = NO_CHANGE_64;
-
- if (attrs->ia_valid & ATTR_GID)
- args->gid = attrs->ia_gid;
- else
- args->gid = NO_CHANGE_64;
-
- if (attrs->ia_valid & ATTR_ATIME)
- args->atime = cifs_UnixTimeToNT(attrs->ia_atime);
- else
- args->atime = NO_CHANGE_64;
-
- if (attrs->ia_valid & ATTR_MTIME)
- args->mtime = cifs_UnixTimeToNT(attrs->ia_mtime);
- else
- args->mtime = NO_CHANGE_64;
-
- if (attrs->ia_valid & ATTR_CTIME)
- args->ctime = cifs_UnixTimeToNT(attrs->ia_ctime);
- else
- args->ctime = NO_CHANGE_64;
-
- args->device = 0;
- open_file = find_writable_file(cifsInode, true);
- if (open_file) {
- u16 nfid = open_file->netfid;
- u32 npid = open_file->pid;
- pTcon = tlink_tcon(open_file->tlink);
- rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid);
- cifsFileInfo_put(open_file);
- } else {
- tlink = cifs_sb_tlink(cifs_sb);
- if (IS_ERR(tlink)) {
- rc = PTR_ERR(tlink);
- goto out;
- }
- pTcon = tlink_tcon(tlink);
- rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args,
- cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- cifs_put_tlink(tlink);
- }
-
- if (rc)
- goto out;
-
- if ((attrs->ia_valid & ATTR_SIZE) &&
- attrs->ia_size != i_size_read(inode))
- truncate_setsize(inode, attrs->ia_size);
-
- setattr_copy(inode, attrs);
- mark_inode_dirty(inode);
-
- /* force revalidate when any of these times are set since some
- of the fs types (eg ext3, fat) do not have fine enough
- time granularity to match protocol, and we do not have a
- a way (yet) to query the server fs's time granularity (and
- whether it rounds times down).
- */
- if (attrs->ia_valid & (ATTR_MTIME | ATTR_CTIME))
- cifsInode->time = 0;
-out:
- kfree(args);
- kfree(full_path);
- FreeXid(xid);
- return rc;
-}
-
-static int
-cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
-{
- int xid;
- uid_t uid = NO_CHANGE_32;
- gid_t gid = NO_CHANGE_32;
- struct inode *inode = direntry->d_inode;
- struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
- struct cifsInodeInfo *cifsInode = CIFS_I(inode);
- char *full_path = NULL;
- int rc = -EACCES;
- __u32 dosattr = 0;
- __u64 mode = NO_CHANGE_64;
-
- xid = GetXid();
-
- cFYI(1, "setattr on file %s attrs->iavalid 0x%x",
- direntry->d_name.name, attrs->ia_valid);
-
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
- attrs->ia_valid |= ATTR_FORCE;
-
- rc = inode_change_ok(inode, attrs);
- if (rc < 0) {
- FreeXid(xid);
- return rc;
- }
-
- full_path = build_path_from_dentry(direntry);
- if (full_path == NULL) {
- rc = -ENOMEM;
- FreeXid(xid);
- return rc;
- }
-
- /*
- * Attempt to flush data before changing attributes. We need to do
- * this for ATTR_SIZE and ATTR_MTIME for sure, and if we change the
- * ownership or mode then we may also need to do this. Here, we take
- * the safe way out and just do the flush on all setattr requests. If
- * the flush returns error, store it to report later and continue.
- *
- * BB: This should be smarter. Why bother flushing pages that
- * will be truncated anyway? Also, should we error out here if
- * the flush returns error?
- */
- rc = filemap_write_and_wait(inode->i_mapping);
- mapping_set_error(inode->i_mapping, rc);
- rc = 0;
-
- if (attrs->ia_valid & ATTR_SIZE) {
- rc = cifs_set_file_size(inode, attrs, xid, full_path);
- if (rc != 0)
- goto cifs_setattr_exit;
- }
-
- if (attrs->ia_valid & ATTR_UID)
- uid = attrs->ia_uid;
-
- if (attrs->ia_valid & ATTR_GID)
- gid = attrs->ia_gid;
-
-#ifdef CONFIG_CIFS_ACL
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
- if (uid != NO_CHANGE_32 || gid != NO_CHANGE_32) {
- rc = id_mode_to_cifs_acl(inode, full_path, NO_CHANGE_64,
- uid, gid);
- if (rc) {
- cFYI(1, "%s: Setting id failed with error: %d",
- __func__, rc);
- goto cifs_setattr_exit;
- }
- }
- } else
-#endif /* CONFIG_CIFS_ACL */
- if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID))
- attrs->ia_valid &= ~(ATTR_UID | ATTR_GID);
-
- /* skip mode change if it's just for clearing setuid/setgid */
- if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
- attrs->ia_valid &= ~ATTR_MODE;
-
- if (attrs->ia_valid & ATTR_MODE) {
- mode = attrs->ia_mode;
- rc = 0;
-#ifdef CONFIG_CIFS_ACL
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
- rc = id_mode_to_cifs_acl(inode, full_path, mode,
- NO_CHANGE_32, NO_CHANGE_32);
- if (rc) {
- cFYI(1, "%s: Setting ACL failed with error: %d",
- __func__, rc);
- goto cifs_setattr_exit;
- }
- } else
-#endif /* CONFIG_CIFS_ACL */
- if (((mode & S_IWUGO) == 0) &&
- (cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
-
- dosattr = cifsInode->cifsAttrs | ATTR_READONLY;
-
- /* fix up mode if we're not using dynperm */
- if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0)
- attrs->ia_mode = inode->i_mode & ~S_IWUGO;
- } else if ((mode & S_IWUGO) &&
- (cifsInode->cifsAttrs & ATTR_READONLY)) {
-
- dosattr = cifsInode->cifsAttrs & ~ATTR_READONLY;
- /* Attributes of 0 are ignored */
- if (dosattr == 0)
- dosattr |= ATTR_NORMAL;
-
- /* reset local inode permissions to normal */
- if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
- attrs->ia_mode &= ~(S_IALLUGO);
- if (S_ISDIR(inode->i_mode))
- attrs->ia_mode |=
- cifs_sb->mnt_dir_mode;
- else
- attrs->ia_mode |=
- cifs_sb->mnt_file_mode;
- }
- } else if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
- /* ignore mode change - ATTR_READONLY hasn't changed */
- attrs->ia_valid &= ~ATTR_MODE;
- }
- }
-
- if (attrs->ia_valid & (ATTR_MTIME|ATTR_ATIME|ATTR_CTIME) ||
- ((attrs->ia_valid & ATTR_MODE) && dosattr)) {
- rc = cifs_set_file_info(inode, attrs, xid, full_path, dosattr);
- /* BB: check for rc = -EOPNOTSUPP and switch to legacy mode */
-
- /* Even if error on time set, no sense failing the call if
- the server would set the time to a reasonable value anyway,
- and this check ensures that we are not being called from
- sys_utimes in which case we ought to fail the call back to
- the user when the server rejects the call */
- if ((rc) && (attrs->ia_valid &
- (ATTR_MODE | ATTR_GID | ATTR_UID | ATTR_SIZE)))
- rc = 0;
- }
-
- /* do not need local check to inode_check_ok since the server does
- that */
- if (rc)
- goto cifs_setattr_exit;
-
- if ((attrs->ia_valid & ATTR_SIZE) &&
- attrs->ia_size != i_size_read(inode))
- truncate_setsize(inode, attrs->ia_size);
-
- setattr_copy(inode, attrs);
- mark_inode_dirty(inode);
-
-cifs_setattr_exit:
- kfree(full_path);
- FreeXid(xid);
- return rc;
-}
-
-int
-cifs_setattr(struct dentry *direntry, struct iattr *attrs)
-{
- struct inode *inode = direntry->d_inode;
- struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
- struct cifs_tcon *pTcon = cifs_sb_master_tcon(cifs_sb);
-
- if (pTcon->unix_ext)
- return cifs_setattr_unix(direntry, attrs);
-
- return cifs_setattr_nounix(direntry, attrs);
-
- /* BB: add cifs_setattr_legacy for really old servers */
-}
-
-#if 0
-void cifs_delete_inode(struct inode *inode)
-{
- cFYI(1, "In cifs_delete_inode, inode = 0x%p", inode);
- /* may have to add back in if and when safe distributed caching of
- directories added e.g. via FindNotify */
-}
-#endif
diff --git a/ANDROID_3.4.5/fs/cifs/ioctl.c b/ANDROID_3.4.5/fs/cifs/ioctl.c
deleted file mode 100644
index 4221b5e4..00000000
--- a/ANDROID_3.4.5/fs/cifs/ioctl.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * fs/cifs/ioctl.c
- *
- * vfs operations that deal with io control
- *
- * Copyright (C) International Business Machines Corp., 2005,2007
- * Author(s): Steve French (sfrench@us.ibm.com)
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/fs.h>
-#include "cifspdu.h"
-#include "cifsglob.h"
-#include "cifsproto.h"
-#include "cifs_debug.h"
-#include "cifsfs.h"
-
-#define CIFS_IOC_CHECKUMOUNT _IO(0xCF, 2)
-
-long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
-{
- struct inode *inode = filep->f_dentry->d_inode;
- int rc = -ENOTTY; /* strange error - but the precedent */
- int xid;
- struct cifs_sb_info *cifs_sb;
-#ifdef CONFIG_CIFS_POSIX
- struct cifsFileInfo *pSMBFile = filep->private_data;
- struct cifs_tcon *tcon;
- __u64 ExtAttrBits = 0;
- __u64 ExtAttrMask = 0;
- __u64 caps;
-#endif /* CONFIG_CIFS_POSIX */
-
- xid = GetXid();
-
- cFYI(1, "ioctl file %p cmd %u arg %lu", filep, command, arg);
-
- cifs_sb = CIFS_SB(inode->i_sb);
-
- switch (command) {
- case CIFS_IOC_CHECKUMOUNT:
- cFYI(1, "User unmount attempted");
- if (cifs_sb->mnt_uid == current_uid())
- rc = 0;
- else {
- rc = -EACCES;
- cFYI(1, "uids do not match");
- }
- break;
-#ifdef CONFIG_CIFS_POSIX
- case FS_IOC_GETFLAGS:
- if (pSMBFile == NULL)
- break;
- tcon = tlink_tcon(pSMBFile->tlink);
- caps = le64_to_cpu(tcon->fsUnixInfo.Capability);
- if (CIFS_UNIX_EXTATTR_CAP & caps) {
- rc = CIFSGetExtAttr(xid, tcon, pSMBFile->netfid,
- &ExtAttrBits, &ExtAttrMask);
- if (rc == 0)
- rc = put_user(ExtAttrBits &
- FS_FL_USER_VISIBLE,
- (int __user *)arg);
- }
- break;
-
- case FS_IOC_SETFLAGS:
- if (pSMBFile == NULL)
- break;
- tcon = tlink_tcon(pSMBFile->tlink);
- caps = le64_to_cpu(tcon->fsUnixInfo.Capability);
- if (CIFS_UNIX_EXTATTR_CAP & caps) {
- if (get_user(ExtAttrBits, (int __user *)arg)) {
- rc = -EFAULT;
- break;
- }
- /* rc= CIFSGetExtAttr(xid,tcon,pSMBFile->netfid,
- extAttrBits, &ExtAttrMask);*/
- }
- cFYI(1, "set flags not implemented yet");
- break;
-#endif /* CONFIG_CIFS_POSIX */
- default:
- cFYI(1, "unsupported ioctl");
- break;
- }
-
- FreeXid(xid);
- return rc;
-}
diff --git a/ANDROID_3.4.5/fs/cifs/link.c b/ANDROID_3.4.5/fs/cifs/link.c
deleted file mode 100644
index 6b0e0643..00000000
--- a/ANDROID_3.4.5/fs/cifs/link.c
+++ /dev/null
@@ -1,606 +0,0 @@
-/*
- * fs/cifs/link.c
- *
- * Copyright (C) International Business Machines Corp., 2002,2008
- * Author(s): Steve French (sfrench@us.ibm.com)
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <linux/fs.h>
-#include <linux/stat.h>
-#include <linux/slab.h>
-#include <linux/namei.h>
-#include "cifsfs.h"
-#include "cifspdu.h"
-#include "cifsglob.h"
-#include "cifsproto.h"
-#include "cifs_debug.h"
-#include "cifs_fs_sb.h"
-
-#define CIFS_MF_SYMLINK_LEN_OFFSET (4+1)
-#define CIFS_MF_SYMLINK_MD5_OFFSET (CIFS_MF_SYMLINK_LEN_OFFSET+(4+1))
-#define CIFS_MF_SYMLINK_LINK_OFFSET (CIFS_MF_SYMLINK_MD5_OFFSET+(32+1))
-#define CIFS_MF_SYMLINK_LINK_MAXLEN (1024)
-#define CIFS_MF_SYMLINK_FILE_SIZE \
- (CIFS_MF_SYMLINK_LINK_OFFSET + CIFS_MF_SYMLINK_LINK_MAXLEN)
-
-#define CIFS_MF_SYMLINK_LEN_FORMAT "XSym\n%04u\n"
-#define CIFS_MF_SYMLINK_MD5_FORMAT \
- "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n"
-#define CIFS_MF_SYMLINK_MD5_ARGS(md5_hash) \
- md5_hash[0], md5_hash[1], md5_hash[2], md5_hash[3], \
- md5_hash[4], md5_hash[5], md5_hash[6], md5_hash[7], \
- md5_hash[8], md5_hash[9], md5_hash[10], md5_hash[11],\
- md5_hash[12], md5_hash[13], md5_hash[14], md5_hash[15]
-
-static int
-symlink_hash(unsigned int link_len, const char *link_str, u8 *md5_hash)
-{
- int rc;
- unsigned int size;
- struct crypto_shash *md5;
- struct sdesc *sdescmd5;
-
- md5 = crypto_alloc_shash("md5", 0, 0);
- if (IS_ERR(md5)) {
- rc = PTR_ERR(md5);
- cERROR(1, "%s: Crypto md5 allocation error %d\n", __func__, rc);
- return rc;
- }
- size = sizeof(struct shash_desc) + crypto_shash_descsize(md5);
- sdescmd5 = kmalloc(size, GFP_KERNEL);
- if (!sdescmd5) {
- rc = -ENOMEM;
- cERROR(1, "%s: Memory allocation failure\n", __func__);
- goto symlink_hash_err;
- }
- sdescmd5->shash.tfm = md5;
- sdescmd5->shash.flags = 0x0;
-
- rc = crypto_shash_init(&sdescmd5->shash);
- if (rc) {
- cERROR(1, "%s: Could not init md5 shash\n", __func__);
- goto symlink_hash_err;
- }
- rc = crypto_shash_update(&sdescmd5->shash, link_str, link_len);
- if (rc) {
- cERROR(1, "%s: Could not update iwth link_str\n", __func__);
- goto symlink_hash_err;
- }
- rc = crypto_shash_final(&sdescmd5->shash, md5_hash);
- if (rc)
- cERROR(1, "%s: Could not generate md5 hash\n", __func__);
-
-symlink_hash_err:
- crypto_free_shash(md5);
- kfree(sdescmd5);
-
- return rc;
-}
-
-static int
-CIFSParseMFSymlink(const u8 *buf,
- unsigned int buf_len,
- unsigned int *_link_len,
- char **_link_str)
-{
- int rc;
- unsigned int link_len;
- const char *md5_str1;
- const char *link_str;
- u8 md5_hash[16];
- char md5_str2[34];
-
- if (buf_len != CIFS_MF_SYMLINK_FILE_SIZE)
- return -EINVAL;
-
- md5_str1 = (const char *)&buf[CIFS_MF_SYMLINK_MD5_OFFSET];
- link_str = (const char *)&buf[CIFS_MF_SYMLINK_LINK_OFFSET];
-
- rc = sscanf(buf, CIFS_MF_SYMLINK_LEN_FORMAT, &link_len);
- if (rc != 1)
- return -EINVAL;
-
- rc = symlink_hash(link_len, link_str, md5_hash);
- if (rc) {
- cFYI(1, "%s: MD5 hash failure: %d\n", __func__, rc);
- return rc;
- }
-
- snprintf(md5_str2, sizeof(md5_str2),
- CIFS_MF_SYMLINK_MD5_FORMAT,
- CIFS_MF_SYMLINK_MD5_ARGS(md5_hash));
-
- if (strncmp(md5_str1, md5_str2, 17) != 0)
- return -EINVAL;
-
- if (_link_str) {
- *_link_str = kstrndup(link_str, link_len, GFP_KERNEL);
- if (!*_link_str)
- return -ENOMEM;
- }
-
- *_link_len = link_len;
- return 0;
-}
-
-static int
-CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str)
-{
- int rc;
- unsigned int link_len;
- unsigned int ofs;
- u8 md5_hash[16];
-
- if (buf_len != CIFS_MF_SYMLINK_FILE_SIZE)
- return -EINVAL;
-
- link_len = strlen(link_str);
-
- if (link_len > CIFS_MF_SYMLINK_LINK_MAXLEN)
- return -ENAMETOOLONG;
-
- rc = symlink_hash(link_len, link_str, md5_hash);
- if (rc) {
- cFYI(1, "%s: MD5 hash failure: %d\n", __func__, rc);
- return rc;
- }
-
- snprintf(buf, buf_len,
- CIFS_MF_SYMLINK_LEN_FORMAT CIFS_MF_SYMLINK_MD5_FORMAT,
- link_len,
- CIFS_MF_SYMLINK_MD5_ARGS(md5_hash));
-
- ofs = CIFS_MF_SYMLINK_LINK_OFFSET;
- memcpy(buf + ofs, link_str, link_len);
-
- ofs += link_len;
- if (ofs < CIFS_MF_SYMLINK_FILE_SIZE) {
- buf[ofs] = '\n';
- ofs++;
- }
-
- while (ofs < CIFS_MF_SYMLINK_FILE_SIZE) {
- buf[ofs] = ' ';
- ofs++;
- }
-
- return 0;
-}
-
-static int
-CIFSCreateMFSymLink(const int xid, struct cifs_tcon *tcon,
- const char *fromName, const char *toName,
- struct cifs_sb_info *cifs_sb)
-{
- int rc;
- int oplock = 0;
- int remap;
- int create_options = CREATE_NOT_DIR;
- __u16 netfid = 0;
- u8 *buf;
- unsigned int bytes_written = 0;
- struct cifs_io_parms io_parms;
- struct nls_table *nls_codepage;
-
- nls_codepage = cifs_sb->local_nls;
- remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
-
- buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
-
- rc = CIFSFormatMFSymlink(buf, CIFS_MF_SYMLINK_FILE_SIZE, toName);
- if (rc != 0) {
- kfree(buf);
- return rc;
- }
-
- if (backup_cred(cifs_sb))
- create_options |= CREATE_OPEN_BACKUP_INTENT;
-
- rc = CIFSSMBOpen(xid, tcon, fromName, FILE_CREATE, GENERIC_WRITE,
- create_options, &netfid, &oplock, NULL,
- nls_codepage, remap);
- if (rc != 0) {
- kfree(buf);
- return rc;
- }
-
- io_parms.netfid = netfid;
- io_parms.pid = current->tgid;
- io_parms.tcon = tcon;
- io_parms.offset = 0;
- io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
-
- rc = CIFSSMBWrite(xid, &io_parms, &bytes_written, buf, NULL, 0);
- CIFSSMBClose(xid, tcon, netfid);
- kfree(buf);
- if (rc != 0)
- return rc;
-
- if (bytes_written != CIFS_MF_SYMLINK_FILE_SIZE)
- return -EIO;
-
- return 0;
-}
-
-static int
-CIFSQueryMFSymLink(const int xid, struct cifs_tcon *tcon,
- const unsigned char *searchName, char **symlinkinfo,
- const struct nls_table *nls_codepage, int remap)
-{
- int rc;
- int oplock = 0;
- __u16 netfid = 0;
- u8 *buf;
- char *pbuf;
- unsigned int bytes_read = 0;
- int buf_type = CIFS_NO_BUFFER;
- unsigned int link_len = 0;
- struct cifs_io_parms io_parms;
- FILE_ALL_INFO file_info;
-
- rc = CIFSSMBOpen(xid, tcon, searchName, FILE_OPEN, GENERIC_READ,
- CREATE_NOT_DIR, &netfid, &oplock, &file_info,
- nls_codepage, remap);
- if (rc != 0)
- return rc;
-
- if (file_info.EndOfFile != cpu_to_le64(CIFS_MF_SYMLINK_FILE_SIZE)) {
- CIFSSMBClose(xid, tcon, netfid);
- /* it's not a symlink */
- return -EINVAL;
- }
-
- buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
- if (!buf)
- return -ENOMEM;
- pbuf = buf;
- io_parms.netfid = netfid;
- io_parms.pid = current->tgid;
- io_parms.tcon = tcon;
- io_parms.offset = 0;
- io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
-
- rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf, &buf_type);
- CIFSSMBClose(xid, tcon, netfid);
- if (rc != 0) {
- kfree(buf);
- return rc;
- }
-
- rc = CIFSParseMFSymlink(buf, bytes_read, &link_len, symlinkinfo);
- kfree(buf);
- if (rc != 0)
- return rc;
-
- return 0;
-}
-
-bool
-CIFSCouldBeMFSymlink(const struct cifs_fattr *fattr)
-{
- if (!(fattr->cf_mode & S_IFREG))
- /* it's not a symlink */
- return false;
-
- if (fattr->cf_eof != CIFS_MF_SYMLINK_FILE_SIZE)
- /* it's not a symlink */
- return false;
-
- return true;
-}
-
-int
-CIFSCheckMFSymlink(struct cifs_fattr *fattr,
- const unsigned char *path,
- struct cifs_sb_info *cifs_sb, int xid)
-{
- int rc;
- int oplock = 0;
- __u16 netfid = 0;
- struct tcon_link *tlink;
- struct cifs_tcon *pTcon;
- struct cifs_io_parms io_parms;
- u8 *buf;
- char *pbuf;
- unsigned int bytes_read = 0;
- int buf_type = CIFS_NO_BUFFER;
- unsigned int link_len = 0;
- FILE_ALL_INFO file_info;
-
- if (!CIFSCouldBeMFSymlink(fattr))
- /* it's not a symlink */
- return 0;
-
- tlink = cifs_sb_tlink(cifs_sb);
- if (IS_ERR(tlink))
- return PTR_ERR(tlink);
- pTcon = tlink_tcon(tlink);
-
- rc = CIFSSMBOpen(xid, pTcon, path, FILE_OPEN, GENERIC_READ,
- CREATE_NOT_DIR, &netfid, &oplock, &file_info,
- cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- if (rc != 0)
- goto out;
-
- if (file_info.EndOfFile != cpu_to_le64(CIFS_MF_SYMLINK_FILE_SIZE)) {
- CIFSSMBClose(xid, pTcon, netfid);
- /* it's not a symlink */
- goto out;
- }
-
- buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
- if (!buf) {
- rc = -ENOMEM;
- goto out;
- }
- pbuf = buf;
- io_parms.netfid = netfid;
- io_parms.pid = current->tgid;
- io_parms.tcon = pTcon;
- io_parms.offset = 0;
- io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
-
- rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf, &buf_type);
- CIFSSMBClose(xid, pTcon, netfid);
- if (rc != 0) {
- kfree(buf);
- goto out;
- }
-
- rc = CIFSParseMFSymlink(buf, bytes_read, &link_len, NULL);
- kfree(buf);
- if (rc == -EINVAL) {
- /* it's not a symlink */
- rc = 0;
- goto out;
- }
-
- if (rc != 0)
- goto out;
-
- /* it is a symlink */
- fattr->cf_eof = link_len;
- fattr->cf_mode &= ~S_IFMT;
- fattr->cf_mode |= S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO;
- fattr->cf_dtype = DT_LNK;
-out:
- cifs_put_tlink(tlink);
- return rc;
-}
-
-int
-cifs_hardlink(struct dentry *old_file, struct inode *inode,
- struct dentry *direntry)
-{
- int rc = -EACCES;
- int xid;
- char *fromName = NULL;
- char *toName = NULL;
- struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
- struct tcon_link *tlink;
- struct cifs_tcon *pTcon;
- struct cifsInodeInfo *cifsInode;
-
- tlink = cifs_sb_tlink(cifs_sb);
- if (IS_ERR(tlink))
- return PTR_ERR(tlink);
- pTcon = tlink_tcon(tlink);
-
- xid = GetXid();
-
- fromName = build_path_from_dentry(old_file);
- toName = build_path_from_dentry(direntry);
- if ((fromName == NULL) || (toName == NULL)) {
- rc = -ENOMEM;
- goto cifs_hl_exit;
- }
-
- if (pTcon->unix_ext)
- rc = CIFSUnixCreateHardLink(xid, pTcon, fromName, toName,
- cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- else {
- rc = CIFSCreateHardLink(xid, pTcon, fromName, toName,
- cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- if ((rc == -EIO) || (rc == -EINVAL))
- rc = -EOPNOTSUPP;
- }
-
- d_drop(direntry); /* force new lookup from server of target */
-
- /* if source file is cached (oplocked) revalidate will not go to server
- until the file is closed or oplock broken so update nlinks locally */
- if (old_file->d_inode) {
- cifsInode = CIFS_I(old_file->d_inode);
- if (rc == 0) {
- inc_nlink(old_file->d_inode);
-/* BB should we make this contingent on superblock flag NOATIME? */
-/* old_file->d_inode->i_ctime = CURRENT_TIME;*/
- /* parent dir timestamps will update from srv
- within a second, would it really be worth it
- to set the parent dir cifs inode time to zero
- to force revalidate (faster) for it too? */
- }
- /* if not oplocked will force revalidate to get info
- on source file from srv */
- cifsInode->time = 0;
-
- /* Will update parent dir timestamps from srv within a second.
- Would it really be worth it to set the parent dir (cifs
- inode) time field to zero to force revalidate on parent
- directory faster ie
- CIFS_I(inode)->time = 0; */
- }
-
-cifs_hl_exit:
- kfree(fromName);
- kfree(toName);
- FreeXid(xid);
- cifs_put_tlink(tlink);
- return rc;
-}
-
-void *
-cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
-{
- struct inode *inode = direntry->d_inode;
- int rc = -ENOMEM;
- int xid;
- char *full_path = NULL;
- char *target_path = NULL;
- struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
- struct tcon_link *tlink = NULL;
- struct cifs_tcon *tcon;
-
- xid = GetXid();
-
- tlink = cifs_sb_tlink(cifs_sb);
- if (IS_ERR(tlink)) {
- rc = PTR_ERR(tlink);
- tlink = NULL;
- goto out;
- }
- tcon = tlink_tcon(tlink);
-
- /*
- * For now, we just handle symlinks with unix extensions enabled.
- * Eventually we should handle NTFS reparse points, and MacOS
- * symlink support. For instance...
- *
- * rc = CIFSSMBQueryReparseLinkInfo(...)
- *
- * For now, just return -EACCES when the server doesn't support posix
- * extensions. Note that we still allow querying symlinks when posix
- * extensions are manually disabled. We could disable these as well
- * but there doesn't seem to be any harm in allowing the client to
- * read them.
- */
- if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
- && !(tcon->ses->capabilities & CAP_UNIX)) {
- rc = -EACCES;
- goto out;
- }
-
- full_path = build_path_from_dentry(direntry);
- if (!full_path)
- goto out;
-
- cFYI(1, "Full path: %s inode = 0x%p", full_path, inode);
-
- rc = -EACCES;
- /*
- * First try Minshall+French Symlinks, if configured
- * and fallback to UNIX Extensions Symlinks.
- */
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
- rc = CIFSQueryMFSymLink(xid, tcon, full_path, &target_path,
- cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
-
- if ((rc != 0) && (tcon->ses->capabilities & CAP_UNIX))
- rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &target_path,
- cifs_sb->local_nls);
-
- kfree(full_path);
-out:
- if (rc != 0) {
- kfree(target_path);
- target_path = ERR_PTR(rc);
- }
-
- FreeXid(xid);
- if (tlink)
- cifs_put_tlink(tlink);
- nd_set_link(nd, target_path);
- return NULL;
-}
-
-int
-cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
-{
- int rc = -EOPNOTSUPP;
- int xid;
- struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
- struct tcon_link *tlink;
- struct cifs_tcon *pTcon;
- char *full_path = NULL;
- struct inode *newinode = NULL;
-
- xid = GetXid();
-
- tlink = cifs_sb_tlink(cifs_sb);
- if (IS_ERR(tlink)) {
- rc = PTR_ERR(tlink);
- goto symlink_exit;
- }
- pTcon = tlink_tcon(tlink);
-
- full_path = build_path_from_dentry(direntry);
- if (full_path == NULL) {
- rc = -ENOMEM;
- goto symlink_exit;
- }
-
- cFYI(1, "Full path: %s", full_path);
- cFYI(1, "symname is %s", symname);
-
- /* BB what if DFS and this volume is on different share? BB */
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
- rc = CIFSCreateMFSymLink(xid, pTcon, full_path, symname,
- cifs_sb);
- else if (pTcon->unix_ext)
- rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname,
- cifs_sb->local_nls);
- /* else
- rc = CIFSCreateReparseSymLink(xid, pTcon, fromName, toName,
- cifs_sb_target->local_nls); */
-
- if (rc == 0) {
- if (pTcon->unix_ext)
- rc = cifs_get_inode_info_unix(&newinode, full_path,
- inode->i_sb, xid);
- else
- rc = cifs_get_inode_info(&newinode, full_path, NULL,
- inode->i_sb, xid, NULL);
-
- if (rc != 0) {
- cFYI(1, "Create symlink ok, getinodeinfo fail rc = %d",
- rc);
- } else {
- d_instantiate(direntry, newinode);
- }
- }
-symlink_exit:
- kfree(full_path);
- cifs_put_tlink(tlink);
- FreeXid(xid);
- return rc;
-}
-
-void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie)
-{
- char *p = nd_get_link(nd);
- if (!IS_ERR(p))
- kfree(p);
-}
diff --git a/ANDROID_3.4.5/fs/cifs/misc.c b/ANDROID_3.4.5/fs/cifs/misc.c
deleted file mode 100644
index c29d1aa2..00000000
--- a/ANDROID_3.4.5/fs/cifs/misc.c
+++ /dev/null
@@ -1,721 +0,0 @@
-/*
- * fs/cifs/misc.c
- *
- * Copyright (C) International Business Machines Corp., 2002,2008
- * Author(s): Steve French (sfrench@us.ibm.com)
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/slab.h>
-#include <linux/ctype.h>
-#include <linux/mempool.h>
-#include "cifspdu.h"
-#include "cifsglob.h"
-#include "cifsproto.h"
-#include "cifs_debug.h"
-#include "smberr.h"
-#include "nterr.h"
-#include "cifs_unicode.h"
-
-extern mempool_t *cifs_sm_req_poolp;
-extern mempool_t *cifs_req_poolp;
-
-/* The xid serves as a useful identifier for each incoming vfs request,
- in a similar way to the mid which is useful to track each sent smb,
- and CurrentXid can also provide a running counter (although it
- will eventually wrap past zero) of the total vfs operations handled
- since the cifs fs was mounted */
-
-unsigned int
-_GetXid(void)
-{
- unsigned int xid;
-
- spin_lock(&GlobalMid_Lock);
- GlobalTotalActiveXid++;
-
- /* keep high water mark for number of simultaneous ops in filesystem */
- if (GlobalTotalActiveXid > GlobalMaxActiveXid)
- GlobalMaxActiveXid = GlobalTotalActiveXid;
- if (GlobalTotalActiveXid > 65000)
- cFYI(1, "warning: more than 65000 requests active");
- xid = GlobalCurrentXid++;
- spin_unlock(&GlobalMid_Lock);
- return xid;
-}
-
-void
-_FreeXid(unsigned int xid)
-{
- spin_lock(&GlobalMid_Lock);
- /* if (GlobalTotalActiveXid == 0)
- BUG(); */
- GlobalTotalActiveXid--;
- spin_unlock(&GlobalMid_Lock);
-}
-
-struct cifs_ses *
-sesInfoAlloc(void)
-{
- struct cifs_ses *ret_buf;
-
- ret_buf = kzalloc(sizeof(struct cifs_ses), GFP_KERNEL);
- if (ret_buf) {
- atomic_inc(&sesInfoAllocCount);
- ret_buf->status = CifsNew;
- ++ret_buf->ses_count;
- INIT_LIST_HEAD(&ret_buf->smb_ses_list);
- INIT_LIST_HEAD(&ret_buf->tcon_list);
- mutex_init(&ret_buf->session_mutex);
- }
- return ret_buf;
-}
-
-void
-sesInfoFree(struct cifs_ses *buf_to_free)
-{
- if (buf_to_free == NULL) {
- cFYI(1, "Null buffer passed to sesInfoFree");
- return;
- }
-
- atomic_dec(&sesInfoAllocCount);
- kfree(buf_to_free->serverOS);
- kfree(buf_to_free->serverDomain);
- kfree(buf_to_free->serverNOS);
- if (buf_to_free->password) {
- memset(buf_to_free->password, 0, strlen(buf_to_free->password));
- kfree(buf_to_free->password);
- }
- kfree(buf_to_free->user_name);
- kfree(buf_to_free->domainName);
- kfree(buf_to_free);
-}
-
-struct cifs_tcon *
-tconInfoAlloc(void)
-{
- struct cifs_tcon *ret_buf;
- ret_buf = kzalloc(sizeof(struct cifs_tcon), GFP_KERNEL);
- if (ret_buf) {
- atomic_inc(&tconInfoAllocCount);
- ret_buf->tidStatus = CifsNew;
- ++ret_buf->tc_count;
- INIT_LIST_HEAD(&ret_buf->openFileList);
- INIT_LIST_HEAD(&ret_buf->tcon_list);
-#ifdef CONFIG_CIFS_STATS
- spin_lock_init(&ret_buf->stat_lock);
-#endif
- }
- return ret_buf;
-}
-
-void
-tconInfoFree(struct cifs_tcon *buf_to_free)
-{
- if (buf_to_free == NULL) {
- cFYI(1, "Null buffer passed to tconInfoFree");
- return;
- }
- atomic_dec(&tconInfoAllocCount);
- kfree(buf_to_free->nativeFileSystem);
- if (buf_to_free->password) {
- memset(buf_to_free->password, 0, strlen(buf_to_free->password));
- kfree(buf_to_free->password);
- }
- kfree(buf_to_free);
-}
-
-struct smb_hdr *
-cifs_buf_get(void)
-{
- struct smb_hdr *ret_buf = NULL;
-
-/* We could use negotiated size instead of max_msgsize -
- but it may be more efficient to always alloc same size
- albeit slightly larger than necessary and maxbuffersize
- defaults to this and can not be bigger */
- ret_buf = mempool_alloc(cifs_req_poolp, GFP_NOFS);
-
- /* clear the first few header bytes */
- /* for most paths, more is cleared in header_assemble */
- if (ret_buf) {
- memset(ret_buf, 0, sizeof(struct smb_hdr) + 3);
- atomic_inc(&bufAllocCount);
-#ifdef CONFIG_CIFS_STATS2
- atomic_inc(&totBufAllocCount);
-#endif /* CONFIG_CIFS_STATS2 */
- }
-
- return ret_buf;
-}
-
-void
-cifs_buf_release(void *buf_to_free)
-{
- if (buf_to_free == NULL) {
- /* cFYI(1, "Null buffer passed to cifs_buf_release");*/
- return;
- }
- mempool_free(buf_to_free, cifs_req_poolp);
-
- atomic_dec(&bufAllocCount);
- return;
-}
-
-struct smb_hdr *
-cifs_small_buf_get(void)
-{
- struct smb_hdr *ret_buf = NULL;
-
-/* We could use negotiated size instead of max_msgsize -
- but it may be more efficient to always alloc same size
- albeit slightly larger than necessary and maxbuffersize
- defaults to this and can not be bigger */
- ret_buf = mempool_alloc(cifs_sm_req_poolp, GFP_NOFS);
- if (ret_buf) {
- /* No need to clear memory here, cleared in header assemble */
- /* memset(ret_buf, 0, sizeof(struct smb_hdr) + 27);*/
- atomic_inc(&smBufAllocCount);
-#ifdef CONFIG_CIFS_STATS2
- atomic_inc(&totSmBufAllocCount);
-#endif /* CONFIG_CIFS_STATS2 */
-
- }
- return ret_buf;
-}
-
-void
-cifs_small_buf_release(void *buf_to_free)
-{
-
- if (buf_to_free == NULL) {
- cFYI(1, "Null buffer passed to cifs_small_buf_release");
- return;
- }
- mempool_free(buf_to_free, cifs_sm_req_poolp);
-
- atomic_dec(&smBufAllocCount);
- return;
-}
-
-/*
- * Find a free multiplex id (SMB mid). Otherwise there could be
- * mid collisions which might cause problems, demultiplexing the
- * wrong response to this request. Multiplex ids could collide if
- * one of a series requests takes much longer than the others, or
- * if a very large number of long lived requests (byte range
- * locks or FindNotify requests) are pending. No more than
- * 64K-1 requests can be outstanding at one time. If no
- * mids are available, return zero. A future optimization
- * could make the combination of mids and uid the key we use
- * to demultiplex on (rather than mid alone).
- * In addition to the above check, the cifs demultiplex
- * code already used the command code as a secondary
- * check of the frame and if signing is negotiated the
- * response would be discarded if the mid were the same
- * but the signature was wrong. Since the mid is not put in the
- * pending queue until later (when it is about to be dispatched)
- * we do have to limit the number of outstanding requests
- * to somewhat less than 64K-1 although it is hard to imagine
- * so many threads being in the vfs at one time.
- */
-__u64 GetNextMid(struct TCP_Server_Info *server)
-{
- __u64 mid = 0;
- __u16 last_mid, cur_mid;
- bool collision;
-
- spin_lock(&GlobalMid_Lock);
-
- /* mid is 16 bit only for CIFS/SMB */
- cur_mid = (__u16)((server->CurrentMid) & 0xffff);
- /* we do not want to loop forever */
- last_mid = cur_mid;
- cur_mid++;
-
- /*
- * This nested loop looks more expensive than it is.
- * In practice the list of pending requests is short,
- * fewer than 50, and the mids are likely to be unique
- * on the first pass through the loop unless some request
- * takes longer than the 64 thousand requests before it
- * (and it would also have to have been a request that
- * did not time out).
- */
- while (cur_mid != last_mid) {
- struct mid_q_entry *mid_entry;
- unsigned int num_mids;
-
- collision = false;
- if (cur_mid == 0)
- cur_mid++;
-
- num_mids = 0;
- list_for_each_entry(mid_entry, &server->pending_mid_q, qhead) {
- ++num_mids;
- if (mid_entry->mid == cur_mid &&
- mid_entry->mid_state == MID_REQUEST_SUBMITTED) {
- /* This mid is in use, try a different one */
- collision = true;
- break;
- }
- }
-
- /*
- * if we have more than 32k mids in the list, then something
- * is very wrong. Possibly a local user is trying to DoS the
- * box by issuing long-running calls and SIGKILL'ing them. If
- * we get to 2^16 mids then we're in big trouble as this
- * function could loop forever.
- *
- * Go ahead and assign out the mid in this situation, but force
- * an eventual reconnect to clean out the pending_mid_q.
- */
- if (num_mids > 32768)
- server->tcpStatus = CifsNeedReconnect;
-
- if (!collision) {
- mid = (__u64)cur_mid;
- server->CurrentMid = mid;
- break;
- }
- cur_mid++;
- }
- spin_unlock(&GlobalMid_Lock);
- return mid;
-}
-
-/* NB: MID can not be set if treeCon not passed in, in that
- case it is responsbility of caller to set the mid */
-void
-header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
- const struct cifs_tcon *treeCon, int word_count
- /* length of fixed section (word count) in two byte units */)
-{
- struct list_head *temp_item;
- struct cifs_ses *ses;
- char *temp = (char *) buffer;
-
- memset(temp, 0, 256); /* bigger than MAX_CIFS_HDR_SIZE */
-
- buffer->smb_buf_length = cpu_to_be32(
- (2 * word_count) + sizeof(struct smb_hdr) -
- 4 /* RFC 1001 length field does not count */ +
- 2 /* for bcc field itself */) ;
-
- buffer->Protocol[0] = 0xFF;
- buffer->Protocol[1] = 'S';
- buffer->Protocol[2] = 'M';
- buffer->Protocol[3] = 'B';
- buffer->Command = smb_command;
- buffer->Flags = 0x00; /* case sensitive */
- buffer->Flags2 = SMBFLG2_KNOWS_LONG_NAMES;
- buffer->Pid = cpu_to_le16((__u16)current->tgid);
- buffer->PidHigh = cpu_to_le16((__u16)(current->tgid >> 16));
- if (treeCon) {
- buffer->Tid = treeCon->tid;
- if (treeCon->ses) {
- if (treeCon->ses->capabilities & CAP_UNICODE)
- buffer->Flags2 |= SMBFLG2_UNICODE;
- if (treeCon->ses->capabilities & CAP_STATUS32)
- buffer->Flags2 |= SMBFLG2_ERR_STATUS;
-
- /* Uid is not converted */
- buffer->Uid = treeCon->ses->Suid;
- buffer->Mid = GetNextMid(treeCon->ses->server);
- if (multiuser_mount != 0) {
- /* For the multiuser case, there are few obvious technically */
- /* possible mechanisms to match the local linux user (uid) */
- /* to a valid remote smb user (smb_uid): */
- /* 1) Query Winbind (or other local pam/nss daemon */
- /* for userid/password/logon_domain or credential */
- /* 2) Query Winbind for uid to sid to username mapping */
- /* and see if we have a matching password for existing*/
- /* session for that user perhas getting password by */
- /* adding a new pam_cifs module that stores passwords */
- /* so that the cifs vfs can get at that for all logged*/
- /* on users */
- /* 3) (Which is the mechanism we have chosen) */
- /* Search through sessions to the same server for a */
- /* a match on the uid that was passed in on mount */
- /* with the current processes uid (or euid?) and use */
- /* that smb uid. If no existing smb session for */
- /* that uid found, use the default smb session ie */
- /* the smb session for the volume mounted which is */
- /* the same as would be used if the multiuser mount */
- /* flag were disabled. */
-
- /* BB Add support for establishing new tCon and SMB Session */
- /* with userid/password pairs found on the smb session */
- /* for other target tcp/ip addresses BB */
- if (current_fsuid() != treeCon->ses->linux_uid) {
- cFYI(1, "Multiuser mode and UID "
- "did not match tcon uid");
- spin_lock(&cifs_tcp_ses_lock);
- list_for_each(temp_item, &treeCon->ses->server->smb_ses_list) {
- ses = list_entry(temp_item, struct cifs_ses, smb_ses_list);
- if (ses->linux_uid == current_fsuid()) {
- if (ses->server == treeCon->ses->server) {
- cFYI(1, "found matching uid substitute right smb_uid");
- buffer->Uid = ses->Suid;
- break;
- } else {
- /* BB eventually call cifs_setup_session here */
- cFYI(1, "local UID found but no smb sess with this server exists");
- }
- }
- }
- spin_unlock(&cifs_tcp_ses_lock);
- }
- }
- }
- if (treeCon->Flags & SMB_SHARE_IS_IN_DFS)
- buffer->Flags2 |= SMBFLG2_DFS;
- if (treeCon->nocase)
- buffer->Flags |= SMBFLG_CASELESS;
- if ((treeCon->ses) && (treeCon->ses->server))
- if (treeCon->ses->server->sec_mode &
- (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
- buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
- }
-
-/* endian conversion of flags is now done just before sending */
- buffer->WordCount = (char) word_count;
- return;
-}
-
-static int
-check_smb_hdr(struct smb_hdr *smb, __u16 mid)
-{
- /* does it have the right SMB "signature" ? */
- if (*(__le32 *) smb->Protocol != cpu_to_le32(0x424d53ff)) {
- cERROR(1, "Bad protocol string signature header 0x%x",
- *(unsigned int *)smb->Protocol);
- return 1;
- }
-
- /* Make sure that message ids match */
- if (mid != smb->Mid) {
- cERROR(1, "Mids do not match. received=%u expected=%u",
- smb->Mid, mid);
- return 1;
- }
-
- /* if it's a response then accept */
- if (smb->Flags & SMBFLG_RESPONSE)
- return 0;
-
- /* only one valid case where server sends us request */
- if (smb->Command == SMB_COM_LOCKING_ANDX)
- return 0;
-
- cERROR(1, "Server sent request, not response. mid=%u", smb->Mid);
- return 1;
-}
-
-int
-checkSMB(char *buf, unsigned int total_read)
-{
- struct smb_hdr *smb = (struct smb_hdr *)buf;
- __u16 mid = smb->Mid;
- __u32 rfclen = be32_to_cpu(smb->smb_buf_length);
- __u32 clc_len; /* calculated length */
- cFYI(0, "checkSMB Length: 0x%x, smb_buf_length: 0x%x",
- total_read, rfclen);
-
- /* is this frame too small to even get to a BCC? */
- if (total_read < 2 + sizeof(struct smb_hdr)) {
- if ((total_read >= sizeof(struct smb_hdr) - 1)
- && (smb->Status.CifsError != 0)) {
- /* it's an error return */
- smb->WordCount = 0;
- /* some error cases do not return wct and bcc */
- return 0;
- } else if ((total_read == sizeof(struct smb_hdr) + 1) &&
- (smb->WordCount == 0)) {
- char *tmp = (char *)smb;
- /* Need to work around a bug in two servers here */
- /* First, check if the part of bcc they sent was zero */
- if (tmp[sizeof(struct smb_hdr)] == 0) {
- /* some servers return only half of bcc
- * on simple responses (wct, bcc both zero)
- * in particular have seen this on
- * ulogoffX and FindClose. This leaves
- * one byte of bcc potentially unitialized
- */
- /* zero rest of bcc */
- tmp[sizeof(struct smb_hdr)+1] = 0;
- return 0;
- }
- cERROR(1, "rcvd invalid byte count (bcc)");
- } else {
- cERROR(1, "Length less than smb header size");
- }
- return -EIO;
- }
-
- /* otherwise, there is enough to get to the BCC */
- if (check_smb_hdr(smb, mid))
- return -EIO;
- clc_len = smbCalcSize(smb);
-
- if (4 + rfclen != total_read) {
- cERROR(1, "Length read does not match RFC1001 length %d",
- rfclen);
- return -EIO;
- }
-
- if (4 + rfclen != clc_len) {
- /* check if bcc wrapped around for large read responses */
- if ((rfclen > 64 * 1024) && (rfclen > clc_len)) {
- /* check if lengths match mod 64K */
- if (((4 + rfclen) & 0xFFFF) == (clc_len & 0xFFFF))
- return 0; /* bcc wrapped */
- }
- cFYI(1, "Calculated size %u vs length %u mismatch for mid=%u",
- clc_len, 4 + rfclen, smb->Mid);
-
- if (4 + rfclen < clc_len) {
- cERROR(1, "RFC1001 size %u smaller than SMB for mid=%u",
- rfclen, smb->Mid);
- return -EIO;
- } else if (rfclen > clc_len + 512) {
- /*
- * Some servers (Windows XP in particular) send more
- * data than the lengths in the SMB packet would
- * indicate on certain calls (byte range locks and
- * trans2 find first calls in particular). While the
- * client can handle such a frame by ignoring the
- * trailing data, we choose limit the amount of extra
- * data to 512 bytes.
- */
- cERROR(1, "RFC1001 size %u more than 512 bytes larger "
- "than SMB for mid=%u", rfclen, smb->Mid);
- return -EIO;
- }
- }
- return 0;
-}
-
-bool
-is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv)
-{
- struct smb_hdr *buf = (struct smb_hdr *)buffer;
- struct smb_com_lock_req *pSMB = (struct smb_com_lock_req *)buf;
- struct list_head *tmp, *tmp1, *tmp2;
- struct cifs_ses *ses;
- struct cifs_tcon *tcon;
- struct cifsInodeInfo *pCifsInode;
- struct cifsFileInfo *netfile;
-
- cFYI(1, "Checking for oplock break or dnotify response");
- if ((pSMB->hdr.Command == SMB_COM_NT_TRANSACT) &&
- (pSMB->hdr.Flags & SMBFLG_RESPONSE)) {
- struct smb_com_transaction_change_notify_rsp *pSMBr =
- (struct smb_com_transaction_change_notify_rsp *)buf;
- struct file_notify_information *pnotify;
- __u32 data_offset = 0;
- if (get_bcc(buf) > sizeof(struct file_notify_information)) {
- data_offset = le32_to_cpu(pSMBr->DataOffset);
-
- pnotify = (struct file_notify_information *)
- ((char *)&pSMBr->hdr.Protocol + data_offset);
- cFYI(1, "dnotify on %s Action: 0x%x",
- pnotify->FileName, pnotify->Action);
- /* cifs_dump_mem("Rcvd notify Data: ",buf,
- sizeof(struct smb_hdr)+60); */
- return true;
- }
- if (pSMBr->hdr.Status.CifsError) {
- cFYI(1, "notify err 0x%d",
- pSMBr->hdr.Status.CifsError);
- return true;
- }
- return false;
- }
- if (pSMB->hdr.Command != SMB_COM_LOCKING_ANDX)
- return false;
- if (pSMB->hdr.Flags & SMBFLG_RESPONSE) {
- /* no sense logging error on invalid handle on oplock
- break - harmless race between close request and oplock
- break response is expected from time to time writing out
- large dirty files cached on the client */
- if ((NT_STATUS_INVALID_HANDLE) ==
- le32_to_cpu(pSMB->hdr.Status.CifsError)) {
- cFYI(1, "invalid handle on oplock break");
- return true;
- } else if (ERRbadfid ==
- le16_to_cpu(pSMB->hdr.Status.DosError.Error)) {
- return true;
- } else {
- return false; /* on valid oplock brk we get "request" */
- }
- }
- if (pSMB->hdr.WordCount != 8)
- return false;
-
- cFYI(1, "oplock type 0x%d level 0x%d",
- pSMB->LockType, pSMB->OplockLevel);
- if (!(pSMB->LockType & LOCKING_ANDX_OPLOCK_RELEASE))
- return false;
-
- /* look up tcon based on tid & uid */
- spin_lock(&cifs_tcp_ses_lock);
- list_for_each(tmp, &srv->smb_ses_list) {
- ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
- list_for_each(tmp1, &ses->tcon_list) {
- tcon = list_entry(tmp1, struct cifs_tcon, tcon_list);
- if (tcon->tid != buf->Tid)
- continue;
-
- cifs_stats_inc(&tcon->num_oplock_brks);
- spin_lock(&cifs_file_list_lock);
- list_for_each(tmp2, &tcon->openFileList) {
- netfile = list_entry(tmp2, struct cifsFileInfo,
- tlist);
- if (pSMB->Fid != netfile->netfid)
- continue;
-
- cFYI(1, "file id match, oplock break");
- pCifsInode = CIFS_I(netfile->dentry->d_inode);
-
- cifs_set_oplock_level(pCifsInode,
- pSMB->OplockLevel ? OPLOCK_READ : 0);
- queue_work(cifsiod_wq,
- &netfile->oplock_break);
- netfile->oplock_break_cancelled = false;
-
- spin_unlock(&cifs_file_list_lock);
- spin_unlock(&cifs_tcp_ses_lock);
- return true;
- }
- spin_unlock(&cifs_file_list_lock);
- spin_unlock(&cifs_tcp_ses_lock);
- cFYI(1, "No matching file for oplock break");
- return true;
- }
- }
- spin_unlock(&cifs_tcp_ses_lock);
- cFYI(1, "Can not process oplock break for non-existent connection");
- return true;
-}
-
-void
-dump_smb(void *buf, int smb_buf_length)
-{
- int i, j;
- char debug_line[17];
- unsigned char *buffer = buf;
-
- if (traceSMB == 0)
- return;
-
- for (i = 0, j = 0; i < smb_buf_length; i++, j++) {
- if (i % 8 == 0) {
- /* have reached the beginning of line */
- printk(KERN_DEBUG "| ");
- j = 0;
- }
- printk("%0#4x ", buffer[i]);
- debug_line[2 * j] = ' ';
- if (isprint(buffer[i]))
- debug_line[1 + (2 * j)] = buffer[i];
- else
- debug_line[1 + (2 * j)] = '_';
-
- if (i % 8 == 7) {
- /* reached end of line, time to print ascii */
- debug_line[16] = 0;
- printk(" | %s\n", debug_line);
- }
- }
- for (; j < 8; j++) {
- printk(" ");
- debug_line[2 * j] = ' ';
- debug_line[1 + (2 * j)] = ' ';
- }
- printk(" | %s\n", debug_line);
- return;
-}
-
-void
-cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb)
-{
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
- cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM;
- cERROR(1, "Autodisabling the use of server inode numbers on "
- "%s. This server doesn't seem to support them "
- "properly. Hardlinks will not be recognized on this "
- "mount. Consider mounting with the \"noserverino\" "
- "option to silence this message.",
- cifs_sb_master_tcon(cifs_sb)->treeName);
- }
-}
-
-void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock)
-{
- oplock &= 0xF;
-
- if (oplock == OPLOCK_EXCLUSIVE) {
- cinode->clientCanCacheAll = true;
- cinode->clientCanCacheRead = true;
- cFYI(1, "Exclusive Oplock granted on inode %p",
- &cinode->vfs_inode);
- } else if (oplock == OPLOCK_READ) {
- cinode->clientCanCacheAll = false;
- cinode->clientCanCacheRead = true;
- cFYI(1, "Level II Oplock granted on inode %p",
- &cinode->vfs_inode);
- } else {
- cinode->clientCanCacheAll = false;
- cinode->clientCanCacheRead = false;
- }
-}
-
-bool
-backup_cred(struct cifs_sb_info *cifs_sb)
-{
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPUID) {
- if (cifs_sb->mnt_backupuid == current_fsuid())
- return true;
- }
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPGID) {
- if (in_group_p(cifs_sb->mnt_backupgid))
- return true;
- }
-
- return false;
-}
-
-void
-cifs_add_credits(struct TCP_Server_Info *server, const unsigned int add)
-{
- spin_lock(&server->req_lock);
- server->credits += add;
- server->in_flight--;
- spin_unlock(&server->req_lock);
- wake_up(&server->request_q);
-}
-
-void
-cifs_set_credits(struct TCP_Server_Info *server, const int val)
-{
- spin_lock(&server->req_lock);
- server->credits = val;
- server->oplocks = val > 1 ? enable_oplocks : false;
- spin_unlock(&server->req_lock);
-}
diff --git a/ANDROID_3.4.5/fs/cifs/netmisc.c b/ANDROID_3.4.5/fs/cifs/netmisc.c
deleted file mode 100644
index 581c225f..00000000
--- a/ANDROID_3.4.5/fs/cifs/netmisc.c
+++ /dev/null
@@ -1,1008 +0,0 @@
-/*
- * fs/cifs/netmisc.c
- *
- * Copyright (c) International Business Machines Corp., 2002,2008
- * Author(s): Steve French (sfrench@us.ibm.com)
- *
- * Error mapping routines from Samba libsmb/errormap.c
- * Copyright (C) Andrew Tridgell 2001
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/net.h>
-#include <linux/string.h>
-#include <linux/in.h>
-#include <linux/ctype.h>
-#include <linux/fs.h>
-#include <asm/div64.h>
-#include <asm/byteorder.h>
-#include <linux/inet.h>
-#include "cifsfs.h"
-#include "cifspdu.h"
-#include "cifsglob.h"
-#include "cifsproto.h"
-#include "smberr.h"
-#include "cifs_debug.h"
-#include "nterr.h"
-
-struct smb_to_posix_error {
- __u16 smb_err;
- int posix_code;
-};
-
-static const struct smb_to_posix_error mapping_table_ERRDOS[] = {
- {ERRbadfunc, -EINVAL},
- {ERRbadfile, -ENOENT},
- {ERRbadpath, -ENOTDIR},
- {ERRnofids, -EMFILE},
- {ERRnoaccess, -EACCES},
- {ERRbadfid, -EBADF},
- {ERRbadmcb, -EIO},
- {ERRnomem, -ENOMEM},
- {ERRbadmem, -EFAULT},
- {ERRbadenv, -EFAULT},
- {ERRbadformat, -EINVAL},
- {ERRbadaccess, -EACCES},
- {ERRbaddata, -EIO},
- {ERRbaddrive, -ENXIO},
- {ERRremcd, -EACCES},
- {ERRdiffdevice, -EXDEV},
- {ERRnofiles, -ENOENT},
- {ERRwriteprot, -EROFS},
- {ERRbadshare, -ETXTBSY},
- {ERRlock, -EACCES},
- {ERRunsup, -EINVAL},
- {ERRnosuchshare, -ENXIO},
- {ERRfilexists, -EEXIST},
- {ERRinvparm, -EINVAL},
- {ERRdiskfull, -ENOSPC},
- {ERRinvname, -ENOENT},
- {ERRinvlevel, -EOPNOTSUPP},
- {ERRdirnotempty, -ENOTEMPTY},
- {ERRnotlocked, -ENOLCK},
- {ERRcancelviolation, -ENOLCK},
- {ERRalreadyexists, -EEXIST},
- {ERRmoredata, -EOVERFLOW},
- {ERReasnotsupported, -EOPNOTSUPP},
- {ErrQuota, -EDQUOT},
- {ErrNotALink, -ENOLINK},
- {ERRnetlogonNotStarted, -ENOPROTOOPT},
- {ERRsymlink, -EOPNOTSUPP},
- {ErrTooManyLinks, -EMLINK},
- {0, 0}
-};
-
-static const struct smb_to_posix_error mapping_table_ERRSRV[] = {
- {ERRerror, -EIO},
- {ERRbadpw, -EACCES}, /* was EPERM */
- {ERRbadtype, -EREMOTE},
- {ERRaccess, -EACCES},
- {ERRinvtid, -ENXIO},
- {ERRinvnetname, -ENXIO},
- {ERRinvdevice, -ENXIO},
- {ERRqfull, -ENOSPC},
- {ERRqtoobig, -ENOSPC},
- {ERRqeof, -EIO},
- {ERRinvpfid, -EBADF},
- {ERRsmbcmd, -EBADRQC},
- {ERRsrverror, -EIO},
- {ERRbadBID, -EIO},
- {ERRfilespecs, -EINVAL},
- {ERRbadLink, -EIO},
- {ERRbadpermits, -EINVAL},
- {ERRbadPID, -ESRCH},
- {ERRsetattrmode, -EINVAL},
- {ERRpaused, -EHOSTDOWN},
- {ERRmsgoff, -EHOSTDOWN},
- {ERRnoroom, -ENOSPC},
- {ERRrmuns, -EUSERS},
- {ERRtimeout, -ETIME},
- {ERRnoresource, -ENOBUFS},
- {ERRtoomanyuids, -EUSERS},
- {ERRbaduid, -EACCES},
- {ERRusempx, -EIO},
- {ERRusestd, -EIO},
- {ERR_NOTIFY_ENUM_DIR, -ENOBUFS},
- {ERRnoSuchUser, -EACCES},
-/* {ERRaccountexpired, -EACCES},
- {ERRbadclient, -EACCES},
- {ERRbadLogonTime, -EACCES},
- {ERRpasswordExpired, -EACCES},*/
- {ERRaccountexpired, -EKEYEXPIRED},
- {ERRbadclient, -EACCES},
- {ERRbadLogonTime, -EACCES},
- {ERRpasswordExpired, -EKEYEXPIRED},
-
- {ERRnosupport, -EINVAL},
- {0, 0}
-};
-
-static const struct smb_to_posix_error mapping_table_ERRHRD[] = {
- {0, 0}
-};
-
-/*
- * Convert a string containing text IPv4 or IPv6 address to binary form.
- *
- * Returns 0 on failure.
- */
-static int
-cifs_inet_pton(const int address_family, const char *cp, int len, void *dst)
-{
- int ret = 0;
-
- /* calculate length by finding first slash or NULL */
- if (address_family == AF_INET)
- ret = in4_pton(cp, len, dst, '\\', NULL);
- else if (address_family == AF_INET6)
- ret = in6_pton(cp, len, dst , '\\', NULL);
-
- cFYI(DBG2, "address conversion returned %d for %*.*s",
- ret, len, len, cp);
- if (ret > 0)
- ret = 1;
- return ret;
-}
-
-/*
- * Try to convert a string to an IPv4 address and then attempt to convert
- * it to an IPv6 address if that fails. Set the family field if either
- * succeeds. If it's an IPv6 address and it has a '%' sign in it, try to
- * treat the part following it as a numeric sin6_scope_id.
- *
- * Returns 0 on failure.
- */
-int
-cifs_convert_address(struct sockaddr *dst, const char *src, int len)
-{
- int rc, alen, slen;
- const char *pct;
- char scope_id[13];
- struct sockaddr_in *s4 = (struct sockaddr_in *) dst;
- struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) dst;
-
- /* IPv4 address */
- if (cifs_inet_pton(AF_INET, src, len, &s4->sin_addr.s_addr)) {
- s4->sin_family = AF_INET;
- return 1;
- }
-
- /* attempt to exclude the scope ID from the address part */
- pct = memchr(src, '%', len);
- alen = pct ? pct - src : len;
-
- rc = cifs_inet_pton(AF_INET6, src, alen, &s6->sin6_addr.s6_addr);
- if (!rc)
- return rc;
-
- s6->sin6_family = AF_INET6;
- if (pct) {
- /* grab the scope ID */
- slen = len - (alen + 1);
- if (slen <= 0 || slen > 12)
- return 0;
- memcpy(scope_id, pct + 1, slen);
- scope_id[slen] = '\0';
-
- rc = kstrtouint(scope_id, 0, &s6->sin6_scope_id);
- rc = (rc == 0) ? 1 : 0;
- }
-
- return rc;
-}
-
-int
-cifs_set_port(struct sockaddr *addr, const unsigned short int port)
-{
- switch (addr->sa_family) {
- case AF_INET:
- ((struct sockaddr_in *)addr)->sin_port = htons(port);
- break;
- case AF_INET6:
- ((struct sockaddr_in6 *)addr)->sin6_port = htons(port);
- break;
- default:
- return 0;
- }
- return 1;
-}
-
-int
-cifs_fill_sockaddr(struct sockaddr *dst, const char *src, int len,
- const unsigned short int port)
-{
- if (!cifs_convert_address(dst, src, len))
- return 0;
- return cifs_set_port(dst, port);
-}
-
-/*****************************************************************************
-convert a NT status code to a dos class/code
- *****************************************************************************/
-/* NT status -> dos error map */
-static const struct {
- __u8 dos_class;
- __u16 dos_code;
- __u32 ntstatus;
-} ntstatus_to_dos_map[] = {
- {
- ERRDOS, ERRgeneral, NT_STATUS_UNSUCCESSFUL}, {
- ERRDOS, ERRbadfunc, NT_STATUS_NOT_IMPLEMENTED}, {
- ERRDOS, ERRinvlevel, NT_STATUS_INVALID_INFO_CLASS}, {
- ERRDOS, 24, NT_STATUS_INFO_LENGTH_MISMATCH}, {
- ERRHRD, ERRgeneral, NT_STATUS_ACCESS_VIOLATION}, {
- ERRHRD, ERRgeneral, NT_STATUS_IN_PAGE_ERROR}, {
- ERRHRD, ERRgeneral, NT_STATUS_PAGEFILE_QUOTA}, {
- ERRDOS, ERRbadfid, NT_STATUS_INVALID_HANDLE}, {
- ERRHRD, ERRgeneral, NT_STATUS_BAD_INITIAL_STACK}, {
- ERRDOS, 193, NT_STATUS_BAD_INITIAL_PC}, {
- ERRDOS, 87, NT_STATUS_INVALID_CID}, {
- ERRHRD, ERRgeneral, NT_STATUS_TIMER_NOT_CANCELED}, {
- ERRDOS, 87, NT_STATUS_INVALID_PARAMETER}, {
- ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_DEVICE}, {
- ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_FILE}, {
- ERRDOS, ERRbadfunc, NT_STATUS_INVALID_DEVICE_REQUEST}, {
- ERRDOS, 38, NT_STATUS_END_OF_FILE}, {
- ERRDOS, 34, NT_STATUS_WRONG_VOLUME}, {
- ERRDOS, 21, NT_STATUS_NO_MEDIA_IN_DEVICE}, {
- ERRHRD, ERRgeneral, NT_STATUS_UNRECOGNIZED_MEDIA}, {
- ERRDOS, 27, NT_STATUS_NONEXISTENT_SECTOR},
-/* { This NT error code was 'sqashed'
- from NT_STATUS_MORE_PROCESSING_REQUIRED to NT_STATUS_OK
- during the session setup } */
- {
- ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY}, {
- ERRDOS, 487, NT_STATUS_CONFLICTING_ADDRESSES}, {
- ERRDOS, 487, NT_STATUS_NOT_MAPPED_VIEW}, {
- ERRDOS, 87, NT_STATUS_UNABLE_TO_FREE_VM}, {
- ERRDOS, 87, NT_STATUS_UNABLE_TO_DELETE_SECTION}, {
- ERRDOS, 2142, NT_STATUS_INVALID_SYSTEM_SERVICE}, {
- ERRHRD, ERRgeneral, NT_STATUS_ILLEGAL_INSTRUCTION}, {
- ERRDOS, ERRnoaccess, NT_STATUS_INVALID_LOCK_SEQUENCE}, {
- ERRDOS, ERRnoaccess, NT_STATUS_INVALID_VIEW_SIZE}, {
- ERRDOS, 193, NT_STATUS_INVALID_FILE_FOR_SECTION}, {
- ERRDOS, ERRnoaccess, NT_STATUS_ALREADY_COMMITTED},
-/* { This NT error code was 'sqashed'
- from NT_STATUS_ACCESS_DENIED to NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE
- during the session setup } */
- {
- ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED}, {
- ERRDOS, 111, NT_STATUS_BUFFER_TOO_SMALL}, {
- ERRDOS, ERRbadfid, NT_STATUS_OBJECT_TYPE_MISMATCH}, {
- ERRHRD, ERRgeneral, NT_STATUS_NONCONTINUABLE_EXCEPTION}, {
- ERRHRD, ERRgeneral, NT_STATUS_INVALID_DISPOSITION}, {
- ERRHRD, ERRgeneral, NT_STATUS_UNWIND}, {
- ERRHRD, ERRgeneral, NT_STATUS_BAD_STACK}, {
- ERRHRD, ERRgeneral, NT_STATUS_INVALID_UNWIND_TARGET}, {
- ERRDOS, 158, NT_STATUS_NOT_LOCKED}, {
- ERRHRD, ERRgeneral, NT_STATUS_PARITY_ERROR}, {
- ERRDOS, 487, NT_STATUS_UNABLE_TO_DECOMMIT_VM}, {
- ERRDOS, 487, NT_STATUS_NOT_COMMITTED}, {
- ERRHRD, ERRgeneral, NT_STATUS_INVALID_PORT_ATTRIBUTES}, {
- ERRHRD, ERRgeneral, NT_STATUS_PORT_MESSAGE_TOO_LONG}, {
- ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_MIX}, {
- ERRHRD, ERRgeneral, NT_STATUS_INVALID_QUOTA_LOWER}, {
- ERRHRD, ERRgeneral, NT_STATUS_DISK_CORRUPT_ERROR}, {
- /* mapping changed since shell does lookup on * expects FileNotFound */
- ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_INVALID}, {
- ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_NOT_FOUND}, {
- ERRDOS, ERRalreadyexists, NT_STATUS_OBJECT_NAME_COLLISION}, {
- ERRHRD, ERRgeneral, NT_STATUS_HANDLE_NOT_WAITABLE}, {
- ERRDOS, ERRbadfid, NT_STATUS_PORT_DISCONNECTED}, {
- ERRHRD, ERRgeneral, NT_STATUS_DEVICE_ALREADY_ATTACHED}, {
- ERRDOS, 161, NT_STATUS_OBJECT_PATH_INVALID}, {
- ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND}, {
- ERRDOS, 161, NT_STATUS_OBJECT_PATH_SYNTAX_BAD}, {
- ERRHRD, ERRgeneral, NT_STATUS_DATA_OVERRUN}, {
- ERRHRD, ERRgeneral, NT_STATUS_DATA_LATE_ERROR}, {
- ERRDOS, 23, NT_STATUS_DATA_ERROR}, {
- ERRDOS, 23, NT_STATUS_CRC_ERROR}, {
- ERRDOS, ERRnomem, NT_STATUS_SECTION_TOO_BIG}, {
- ERRDOS, ERRnoaccess, NT_STATUS_PORT_CONNECTION_REFUSED}, {
- ERRDOS, ERRbadfid, NT_STATUS_INVALID_PORT_HANDLE}, {
- ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION}, {
- ERRHRD, ERRgeneral, NT_STATUS_QUOTA_EXCEEDED}, {
- ERRDOS, 87, NT_STATUS_INVALID_PAGE_PROTECTION}, {
- ERRDOS, 288, NT_STATUS_MUTANT_NOT_OWNED}, {
- ERRDOS, 298, NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED}, {
- ERRDOS, 87, NT_STATUS_PORT_ALREADY_SET}, {
- ERRDOS, 87, NT_STATUS_SECTION_NOT_IMAGE}, {
- ERRDOS, 156, NT_STATUS_SUSPEND_COUNT_EXCEEDED}, {
- ERRDOS, ERRnoaccess, NT_STATUS_THREAD_IS_TERMINATING}, {
- ERRDOS, 87, NT_STATUS_BAD_WORKING_SET_LIMIT}, {
- ERRDOS, 87, NT_STATUS_INCOMPATIBLE_FILE_MAP}, {
- ERRDOS, 87, NT_STATUS_SECTION_PROTECTION}, {
- ERRDOS, ERReasnotsupported, NT_STATUS_EAS_NOT_SUPPORTED}, {
- ERRDOS, 255, NT_STATUS_EA_TOO_LARGE}, {
- ERRHRD, ERRgeneral, NT_STATUS_NONEXISTENT_EA_ENTRY}, {
- ERRHRD, ERRgeneral, NT_STATUS_NO_EAS_ON_FILE}, {
- ERRHRD, ERRgeneral, NT_STATUS_EA_CORRUPT_ERROR}, {
- ERRDOS, ERRlock, NT_STATUS_FILE_LOCK_CONFLICT}, {
- ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED}, {
- ERRDOS, ERRbadfile, NT_STATUS_DELETE_PENDING}, {
- ERRDOS, ERRunsup, NT_STATUS_CTL_FILE_NOT_SUPPORTED}, {
- ERRHRD, ERRgeneral, NT_STATUS_UNKNOWN_REVISION}, {
- ERRHRD, ERRgeneral, NT_STATUS_REVISION_MISMATCH}, {
- ERRHRD, ERRgeneral, NT_STATUS_INVALID_OWNER}, {
- ERRHRD, ERRgeneral, NT_STATUS_INVALID_PRIMARY_GROUP}, {
- ERRHRD, ERRgeneral, NT_STATUS_NO_IMPERSONATION_TOKEN}, {
- ERRHRD, ERRgeneral, NT_STATUS_CANT_DISABLE_MANDATORY}, {
- ERRDOS, 2215, NT_STATUS_NO_LOGON_SERVERS}, {
- ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_LOGON_SESSION}, {
- ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_PRIVILEGE}, {
- ERRDOS, ERRnoaccess, NT_STATUS_PRIVILEGE_NOT_HELD}, {
- ERRHRD, ERRgeneral, NT_STATUS_INVALID_ACCOUNT_NAME}, {
- ERRHRD, ERRgeneral, NT_STATUS_USER_EXISTS},
-/* { This NT error code was 'sqashed'
- from NT_STATUS_NO_SUCH_USER to NT_STATUS_LOGON_FAILURE
- during the session setup } */
- {
- ERRDOS, ERRnoaccess, NT_STATUS_NO_SUCH_USER}, { /* could map to 2238 */
- ERRHRD, ERRgeneral, NT_STATUS_GROUP_EXISTS}, {
- ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_GROUP}, {
- ERRHRD, ERRgeneral, NT_STATUS_MEMBER_IN_GROUP}, {
- ERRHRD, ERRgeneral, NT_STATUS_MEMBER_NOT_IN_GROUP}, {
- ERRHRD, ERRgeneral, NT_STATUS_LAST_ADMIN},
-/* { This NT error code was 'sqashed'
- from NT_STATUS_WRONG_PASSWORD to NT_STATUS_LOGON_FAILURE
- during the session setup } */
- {
- ERRSRV, ERRbadpw, NT_STATUS_WRONG_PASSWORD}, {
- ERRHRD, ERRgeneral, NT_STATUS_ILL_FORMED_PASSWORD}, {
- ERRHRD, ERRgeneral, NT_STATUS_PASSWORD_RESTRICTION}, {
- ERRDOS, ERRnoaccess, NT_STATUS_LOGON_FAILURE}, {
- ERRHRD, ERRgeneral, NT_STATUS_ACCOUNT_RESTRICTION}, {
- ERRSRV, ERRbadLogonTime, NT_STATUS_INVALID_LOGON_HOURS}, {
- ERRSRV, ERRbadclient, NT_STATUS_INVALID_WORKSTATION}, {
- ERRSRV, ERRpasswordExpired, NT_STATUS_PASSWORD_EXPIRED}, {
- ERRSRV, ERRaccountexpired, NT_STATUS_ACCOUNT_DISABLED}, {
- ERRHRD, ERRgeneral, NT_STATUS_NONE_MAPPED}, {
- ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_LUIDS_REQUESTED}, {
- ERRHRD, ERRgeneral, NT_STATUS_LUIDS_EXHAUSTED}, {
- ERRHRD, ERRgeneral, NT_STATUS_INVALID_SUB_AUTHORITY}, {
- ERRHRD, ERRgeneral, NT_STATUS_INVALID_ACL}, {
- ERRHRD, ERRgeneral, NT_STATUS_INVALID_SID}, {
- ERRHRD, ERRgeneral, NT_STATUS_INVALID_SECURITY_DESCR}, {
- ERRDOS, 127, NT_STATUS_PROCEDURE_NOT_FOUND}, {
- ERRDOS, 193, NT_STATUS_INVALID_IMAGE_FORMAT}, {
- ERRHRD, ERRgeneral, NT_STATUS_NO_TOKEN}, {
- ERRHRD, ERRgeneral, NT_STATUS_BAD_INHERITANCE_ACL}, {
- ERRDOS, 158, NT_STATUS_RANGE_NOT_LOCKED}, {
- ERRDOS, 112, NT_STATUS_DISK_FULL}, {
- ERRHRD, ERRgeneral, NT_STATUS_SERVER_DISABLED}, {
- ERRHRD, ERRgeneral, NT_STATUS_SERVER_NOT_DISABLED}, {
- ERRDOS, 68, NT_STATUS_TOO_MANY_GUIDS_REQUESTED}, {
- ERRDOS, 259, NT_STATUS_GUIDS_EXHAUSTED}, {
- ERRHRD, ERRgeneral, NT_STATUS_INVALID_ID_AUTHORITY}, {
- ERRDOS, 259, NT_STATUS_AGENTS_EXHAUSTED}, {
- ERRDOS, 154, NT_STATUS_INVALID_VOLUME_LABEL}, {
- ERRDOS, 14, NT_STATUS_SECTION_NOT_EXTENDED}, {
- ERRDOS, 487, NT_STATUS_NOT_MAPPED_DATA}, {
- ERRHRD, ERRgeneral, NT_STATUS_RESOURCE_DATA_NOT_FOUND}, {
- ERRHRD, ERRgeneral, NT_STATUS_RESOURCE_TYPE_NOT_FOUND}, {
- ERRHRD, ERRgeneral, NT_STATUS_RESOURCE_NAME_NOT_FOUND}, {
- ERRHRD, ERRgeneral, NT_STATUS_ARRAY_BOUNDS_EXCEEDED}, {
- ERRHRD, ERRgeneral, NT_STATUS_FLOAT_DENORMAL_OPERAND}, {
- ERRHRD, ERRgeneral, NT_STATUS_FLOAT_DIVIDE_BY_ZERO}, {
- ERRHRD, ERRgeneral, NT_STATUS_FLOAT_INEXACT_RESULT}, {
- ERRHRD, ERRgeneral, NT_STATUS_FLOAT_INVALID_OPERATION}, {
- ERRHRD, ERRgeneral, NT_STATUS_FLOAT_OVERFLOW}, {
- ERRHRD, ERRgeneral, NT_STATUS_FLOAT_STACK_CHECK}, {
- ERRHRD, ERRgeneral, NT_STATUS_FLOAT_UNDERFLOW}, {
- ERRHRD, ERRgeneral, NT_STATUS_INTEGER_DIVIDE_BY_ZERO}, {
- ERRDOS, 534, NT_STATUS_INTEGER_OVERFLOW}, {
- ERRHRD, ERRgeneral, NT_STATUS_PRIVILEGED_INSTRUCTION}, {
- ERRDOS, ERRnomem, NT_STATUS_TOO_MANY_PAGING_FILES}, {
- ERRHRD, ERRgeneral, NT_STATUS_FILE_INVALID}, {
- ERRHRD, ERRgeneral, NT_STATUS_ALLOTTED_SPACE_EXCEEDED},
-/* { This NT error code was 'sqashed'
- from NT_STATUS_INSUFFICIENT_RESOURCES to
- NT_STATUS_INSUFF_SERVER_RESOURCES during the session setup } */
- {
- ERRDOS, ERRnomem, NT_STATUS_INSUFFICIENT_RESOURCES}, {
- ERRDOS, ERRbadpath, NT_STATUS_DFS_EXIT_PATH_FOUND}, {
- ERRDOS, 23, NT_STATUS_DEVICE_DATA_ERROR}, {
- ERRHRD, ERRgeneral, NT_STATUS_DEVICE_NOT_CONNECTED}, {
- ERRDOS, 21, NT_STATUS_DEVICE_POWER_FAILURE}, {
- ERRDOS, 487, NT_STATUS_FREE_VM_NOT_AT_BASE}, {
- ERRDOS, 487, NT_STATUS_MEMORY_NOT_ALLOCATED}, {
- ERRHRD, ERRgeneral, NT_STATUS_WORKING_SET_QUOTA}, {
- ERRDOS, 19, NT_STATUS_MEDIA_WRITE_PROTECTED}, {
- ERRDOS, 21, NT_STATUS_DEVICE_NOT_READY}, {
- ERRHRD, ERRgeneral, NT_STATUS_INVALID_GROUP_ATTRIBUTES}, {
- ERRHRD, ERRgeneral, NT_STATUS_BAD_IMPERSONATION_LEVEL}, {
- ERRHRD, ERRgeneral, NT_STATUS_CANT_OPEN_ANONYMOUS}, {
- ERRHRD, ERRgeneral, NT_STATUS_BAD_VALIDATION_CLASS}, {
- ERRHRD, ERRgeneral, NT_STATUS_BAD_TOKEN_TYPE}, {
- ERRDOS, 87, NT_STATUS_BAD_MASTER_BOOT_RECORD}, {
- ERRHRD, ERRgeneral, NT_STATUS_INSTRUCTION_MISALIGNMENT}, {
- ERRDOS, ERRpipebusy, NT_STATUS_INSTANCE_NOT_AVAILABLE}, {
- ERRDOS, ERRpipebusy, NT_STATUS_PIPE_NOT_AVAILABLE}, {
- ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PIPE_STATE}, {
- ERRDOS, ERRpipebusy, NT_STATUS_PIPE_BUSY}, {
- ERRDOS, ERRbadfunc, NT_STATUS_ILLEGAL_FUNCTION}, {
- ERRDOS, ERRnotconnected, NT_STATUS_PIPE_DISCONNECTED}, {
- ERRDOS, ERRpipeclosing, NT_STATUS_PIPE_CLOSING}, {
- ERRHRD, ERRgeneral, NT_STATUS_PIPE_CONNECTED}, {
- ERRHRD, ERRgeneral, NT_STATUS_PIPE_LISTENING}, {
- ERRDOS, ERRbadpipe, NT_STATUS_INVALID_READ_MODE}, {
- ERRDOS, 121, NT_STATUS_IO_TIMEOUT}, {
- ERRDOS, 38, NT_STATUS_FILE_FORCED_CLOSED}, {
- ERRHRD, ERRgeneral, NT_STATUS_PROFILING_NOT_STARTED}, {
- ERRHRD, ERRgeneral, NT_STATUS_PROFILING_NOT_STOPPED}, {
- ERRHRD, ERRgeneral, NT_STATUS_COULD_NOT_INTERPRET}, {
- ERRDOS, ERRnoaccess, NT_STATUS_FILE_IS_A_DIRECTORY}, {
- ERRDOS, ERRunsup, NT_STATUS_NOT_SUPPORTED}, {
- ERRDOS, 51, NT_STATUS_REMOTE_NOT_LISTENING}, {
- ERRDOS, 52, NT_STATUS_DUPLICATE_NAME}, {
- ERRDOS, 53, NT_STATUS_BAD_NETWORK_PATH}, {
- ERRDOS, 54, NT_STATUS_NETWORK_BUSY}, {
- ERRDOS, 55, NT_STATUS_DEVICE_DOES_NOT_EXIST}, {
- ERRDOS, 56, NT_STATUS_TOO_MANY_COMMANDS}, {
- ERRDOS, 57, NT_STATUS_ADAPTER_HARDWARE_ERROR}, {
- ERRDOS, 58, NT_STATUS_INVALID_NETWORK_RESPONSE}, {
- ERRDOS, 59, NT_STATUS_UNEXPECTED_NETWORK_ERROR}, {
- ERRDOS, 60, NT_STATUS_BAD_REMOTE_ADAPTER}, {
- ERRDOS, 61, NT_STATUS_PRINT_QUEUE_FULL}, {
- ERRDOS, 62, NT_STATUS_NO_SPOOL_SPACE}, {
- ERRDOS, 63, NT_STATUS_PRINT_CANCELLED}, {
- ERRDOS, 64, NT_STATUS_NETWORK_NAME_DELETED}, {
- ERRDOS, 65, NT_STATUS_NETWORK_ACCESS_DENIED}, {
- ERRDOS, 66, NT_STATUS_BAD_DEVICE_TYPE}, {
- ERRDOS, ERRnosuchshare, NT_STATUS_BAD_NETWORK_NAME}, {
- ERRDOS, 68, NT_STATUS_TOO_MANY_NAMES}, {
- ERRDOS, 69, NT_STATUS_TOO_MANY_SESSIONS}, {
- ERRDOS, 70, NT_STATUS_SHARING_PAUSED}, {
- ERRDOS, 71, NT_STATUS_REQUEST_NOT_ACCEPTED}, {
- ERRDOS, 72, NT_STATUS_REDIRECTOR_PAUSED}, {
- ERRDOS, 88, NT_STATUS_NET_WRITE_FAULT}, {
- ERRHRD, ERRgeneral, NT_STATUS_PROFILING_AT_LIMIT}, {
- ERRDOS, ERRdiffdevice, NT_STATUS_NOT_SAME_DEVICE}, {
- ERRDOS, ERRnoaccess, NT_STATUS_FILE_RENAMED}, {
- ERRDOS, 240, NT_STATUS_VIRTUAL_CIRCUIT_CLOSED}, {
- ERRHRD, ERRgeneral, NT_STATUS_NO_SECURITY_ON_OBJECT}, {
- ERRHRD, ERRgeneral, NT_STATUS_CANT_WAIT}, {
- ERRDOS, ERRpipeclosing, NT_STATUS_PIPE_EMPTY}, {
- ERRHRD, ERRgeneral, NT_STATUS_CANT_ACCESS_DOMAIN_INFO}, {
- ERRHRD, ERRgeneral, NT_STATUS_CANT_TERMINATE_SELF}, {
- ERRHRD, ERRgeneral, NT_STATUS_INVALID_SERVER_STATE}, {
- ERRHRD, ERRgeneral, NT_STATUS_INVALID_DOMAIN_STATE}, {
- ERRHRD, ERRgeneral, NT_STATUS_INVALID_DOMAIN_ROLE}, {
- ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_DOMAIN}, {
- ERRHRD, ERRgeneral, NT_STATUS_DOMAIN_EXISTS}, {
- ERRHRD, ERRgeneral, NT_STATUS_DOMAIN_LIMIT_EXCEEDED}, {
- ERRDOS, 300, NT_STATUS_OPLOCK_NOT_GRANTED}, {
- ERRDOS, 301, NT_STATUS_INVALID_OPLOCK_PROTOCOL}, {
- ERRHRD, ERRgeneral, NT_STATUS_INTERNAL_DB_CORRUPTION}, {
- ERRHRD, ERRgeneral, NT_STATUS_INTERNAL_ERROR}, {
- ERRHRD, ERRgeneral, NT_STATUS_GENERIC_NOT_MAPPED}, {
- ERRHRD, ERRgeneral, NT_STATUS_BAD_DESCRIPTOR_FORMAT}, {
- ERRHRD, ERRgeneral, NT_STATUS_INVALID_USER_BUFFER}, {
- ERRHRD, ERRgeneral, NT_STATUS_UNEXPECTED_IO_ERROR}, {
- ERRHRD, ERRgeneral, NT_STATUS_UNEXPECTED_MM_CREATE_ERR}, {
- ERRHRD, ERRgeneral, NT_STATUS_UNEXPECTED_MM_MAP_ERROR}, {
- ERRHRD, ERRgeneral, NT_STATUS_UNEXPECTED_MM_EXTEND_ERR}, {
- ERRHRD, ERRgeneral, NT_STATUS_NOT_LOGON_PROCESS}, {
- ERRHRD, ERRgeneral, NT_STATUS_LOGON_SESSION_EXISTS}, {
- ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_1}, {
- ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_2}, {
- ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_3}, {
- ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_4}, {
- ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_5}, {
- ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_6}, {
- ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_7}, {
- ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_8}, {
- ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_9}, {
- ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_10}, {
- ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_11}, {
- ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_12}, {
- ERRDOS, ERRbadpath, NT_STATUS_REDIRECTOR_NOT_STARTED}, {
- ERRHRD, ERRgeneral, NT_STATUS_REDIRECTOR_STARTED}, {
- ERRHRD, ERRgeneral, NT_STATUS_STACK_OVERFLOW}, {
- ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_PACKAGE}, {
- ERRHRD, ERRgeneral, NT_STATUS_BAD_FUNCTION_TABLE}, {
- ERRDOS, 203, 0xc0000100}, {
- ERRDOS, 145, NT_STATUS_DIRECTORY_NOT_EMPTY}, {
- ERRHRD, ERRgeneral, NT_STATUS_FILE_CORRUPT_ERROR}, {
- ERRDOS, 267, NT_STATUS_NOT_A_DIRECTORY}, {
- ERRHRD, ERRgeneral, NT_STATUS_BAD_LOGON_SESSION_STATE}, {
- ERRHRD, ERRgeneral, NT_STATUS_LOGON_SESSION_COLLISION}, {
- ERRDOS, 206, NT_STATUS_NAME_TOO_LONG}, {
- ERRDOS, 2401, NT_STATUS_FILES_OPEN}, {
- ERRDOS, 2404, NT_STATUS_CONNECTION_IN_USE}, {
- ERRHRD, ERRgeneral, NT_STATUS_MESSAGE_NOT_FOUND}, {
- ERRDOS, ERRnoaccess, NT_STATUS_PROCESS_IS_TERMINATING}, {
- ERRHRD, ERRgeneral, NT_STATUS_INVALID_LOGON_TYPE}, {
- ERRHRD, ERRgeneral, NT_STATUS_NO_GUID_TRANSLATION}, {
- ERRHRD, ERRgeneral, NT_STATUS_CANNOT_IMPERSONATE}, {
- ERRHRD, ERRgeneral, NT_STATUS_IMAGE_ALREADY_LOADED}, {
- ERRHRD, ERRgeneral, NT_STATUS_ABIOS_NOT_PRESENT}, {
- ERRHRD, ERRgeneral, NT_STATUS_ABIOS_LID_NOT_EXIST}, {
- ERRHRD, ERRgeneral, NT_STATUS_ABIOS_LID_ALREADY_OWNED}, {
- ERRHRD, ERRgeneral, NT_STATUS_ABIOS_NOT_LID_OWNER}, {
- ERRHRD, ERRgeneral, NT_STATUS_ABIOS_INVALID_COMMAND}, {
- ERRHRD, ERRgeneral, NT_STATUS_ABIOS_INVALID_LID}, {
- ERRHRD, ERRgeneral, NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE}, {
- ERRHRD, ERRgeneral, NT_STATUS_ABIOS_INVALID_SELECTOR}, {
- ERRHRD, ERRgeneral, NT_STATUS_NO_LDT}, {
- ERRHRD, ERRgeneral, NT_STATUS_INVALID_LDT_SIZE}, {
- ERRHRD, ERRgeneral, NT_STATUS_INVALID_LDT_OFFSET}, {
- ERRHRD, ERRgeneral, NT_STATUS_INVALID_LDT_DESCRIPTOR}, {
- ERRDOS, 193, NT_STATUS_INVALID_IMAGE_NE_FORMAT}, {
- ERRHRD, ERRgeneral, NT_STATUS_RXACT_INVALID_STATE}, {
- ERRHRD, ERRgeneral, NT_STATUS_RXACT_COMMIT_FAILURE}, {
- ERRHRD, ERRgeneral, NT_STATUS_MAPPED_FILE_SIZE_ZERO}, {
- ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES}, {
- ERRHRD, ERRgeneral, NT_STATUS_CANCELLED}, {
- ERRDOS, ERRnoaccess, NT_STATUS_CANNOT_DELETE}, {
- ERRHRD, ERRgeneral, NT_STATUS_INVALID_COMPUTER_NAME}, {
- ERRDOS, ERRnoaccess, NT_STATUS_FILE_DELETED}, {
- ERRHRD, ERRgeneral, NT_STATUS_SPECIAL_ACCOUNT}, {
- ERRHRD, ERRgeneral, NT_STATUS_SPECIAL_GROUP}, {
- ERRHRD, ERRgeneral, NT_STATUS_SPECIAL_USER}, {
- ERRHRD, ERRgeneral, NT_STATUS_MEMBERS_PRIMARY_GROUP}, {
- ERRDOS, ERRbadfid, NT_STATUS_FILE_CLOSED}, {
- ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_THREADS}, {
- ERRHRD, ERRgeneral, NT_STATUS_THREAD_NOT_IN_PROCESS}, {
- ERRHRD, ERRgeneral, NT_STATUS_TOKEN_ALREADY_IN_USE}, {
- ERRHRD, ERRgeneral, NT_STATUS_PAGEFILE_QUOTA_EXCEEDED}, {
- ERRHRD, ERRgeneral, NT_STATUS_COMMITMENT_LIMIT}, {
- ERRDOS, 193, NT_STATUS_INVALID_IMAGE_LE_FORMAT}, {
- ERRDOS, 193, NT_STATUS_INVALID_IMAGE_NOT_MZ}, {
- ERRDOS, 193, NT_STATUS_INVALID_IMAGE_PROTECT}, {
- ERRDOS, 193, NT_STATUS_INVALID_IMAGE_WIN_16}, {
- ERRHRD, ERRgeneral, NT_STATUS_LOGON_SERVER_CONFLICT}, {
- ERRHRD, ERRgeneral, NT_STATUS_TIME_DIFFERENCE_AT_DC}, {
- ERRHRD, ERRgeneral, NT_STATUS_SYNCHRONIZATION_REQUIRED}, {
- ERRDOS, 126, NT_STATUS_DLL_NOT_FOUND}, {
- ERRHRD, ERRgeneral, NT_STATUS_OPEN_FAILED}, {
- ERRHRD, ERRgeneral, NT_STATUS_IO_PRIVILEGE_FAILED}, {
- ERRDOS, 182, NT_STATUS_ORDINAL_NOT_FOUND}, {
- ERRDOS, 127, NT_STATUS_ENTRYPOINT_NOT_FOUND}, {
- ERRHRD, ERRgeneral, NT_STATUS_CONTROL_C_EXIT}, {
- ERRDOS, 64, NT_STATUS_LOCAL_DISCONNECT}, {
- ERRDOS, 64, NT_STATUS_REMOTE_DISCONNECT}, {
- ERRDOS, 51, NT_STATUS_REMOTE_RESOURCES}, {
- ERRDOS, 59, NT_STATUS_LINK_FAILED}, {
- ERRDOS, 59, NT_STATUS_LINK_TIMEOUT}, {
- ERRDOS, 59, NT_STATUS_INVALID_CONNECTION}, {
- ERRDOS, 59, NT_STATUS_INVALID_ADDRESS}, {
- ERRHRD, ERRgeneral, NT_STATUS_DLL_INIT_FAILED}, {
- ERRHRD, ERRgeneral, NT_STATUS_MISSING_SYSTEMFILE}, {
- ERRHRD, ERRgeneral, NT_STATUS_UNHANDLED_EXCEPTION}, {
- ERRHRD, ERRgeneral, NT_STATUS_APP_INIT_FAILURE}, {
- ERRHRD, ERRgeneral, NT_STATUS_PAGEFILE_CREATE_FAILED}, {
- ERRHRD, ERRgeneral, NT_STATUS_NO_PAGEFILE}, {
- ERRDOS, 124, NT_STATUS_INVALID_LEVEL}, {
- ERRDOS, 86, NT_STATUS_WRONG_PASSWORD_CORE}, {
- ERRHRD, ERRgeneral, NT_STATUS_ILLEGAL_FLOAT_CONTEXT}, {
- ERRDOS, 109, NT_STATUS_PIPE_BROKEN}, {
- ERRHRD, ERRgeneral, NT_STATUS_REGISTRY_CORRUPT}, {
- ERRHRD, ERRgeneral, NT_STATUS_REGISTRY_IO_FAILED}, {
- ERRHRD, ERRgeneral, NT_STATUS_NO_EVENT_PAIR}, {
- ERRHRD, ERRgeneral, NT_STATUS_UNRECOGNIZED_VOLUME}, {
- ERRHRD, ERRgeneral, NT_STATUS_SERIAL_NO_DEVICE_INITED}, {
- ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_ALIAS}, {
- ERRHRD, ERRgeneral, NT_STATUS_MEMBER_NOT_IN_ALIAS}, {
- ERRHRD, ERRgeneral, NT_STATUS_MEMBER_IN_ALIAS}, {
- ERRHRD, ERRgeneral, NT_STATUS_ALIAS_EXISTS}, {
- ERRHRD, ERRgeneral, NT_STATUS_LOGON_NOT_GRANTED}, {
- ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_SECRETS}, {
- ERRHRD, ERRgeneral, NT_STATUS_SECRET_TOO_LONG}, {
- ERRHRD, ERRgeneral, NT_STATUS_INTERNAL_DB_ERROR}, {
- ERRHRD, ERRgeneral, NT_STATUS_FULLSCREEN_MODE}, {
- ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_CONTEXT_IDS}, {
- ERRDOS, ERRnoaccess, NT_STATUS_LOGON_TYPE_NOT_GRANTED}, {
- ERRHRD, ERRgeneral, NT_STATUS_NOT_REGISTRY_FILE}, {
- ERRHRD, ERRgeneral, NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED}, {
- ERRHRD, ERRgeneral, NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR}, {
- ERRHRD, ERRgeneral, NT_STATUS_FT_MISSING_MEMBER}, {
- ERRHRD, ERRgeneral, NT_STATUS_ILL_FORMED_SERVICE_ENTRY}, {
- ERRHRD, ERRgeneral, NT_STATUS_ILLEGAL_CHARACTER}, {
- ERRHRD, ERRgeneral, NT_STATUS_UNMAPPABLE_CHARACTER}, {
- ERRHRD, ERRgeneral, NT_STATUS_UNDEFINED_CHARACTER}, {
- ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_VOLUME}, {
- ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND}, {
- ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_WRONG_CYLINDER}, {
- ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_UNKNOWN_ERROR}, {
- ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_BAD_REGISTERS}, {
- ERRHRD, ERRgeneral, NT_STATUS_DISK_RECALIBRATE_FAILED}, {
- ERRHRD, ERRgeneral, NT_STATUS_DISK_OPERATION_FAILED}, {
- ERRHRD, ERRgeneral, NT_STATUS_DISK_RESET_FAILED}, {
- ERRHRD, ERRgeneral, NT_STATUS_SHARED_IRQ_BUSY}, {
- ERRHRD, ERRgeneral, NT_STATUS_FT_ORPHANING}, {
- ERRHRD, ERRgeneral, 0xc000016e}, {
- ERRHRD, ERRgeneral, 0xc000016f}, {
- ERRHRD, ERRgeneral, 0xc0000170}, {
- ERRHRD, ERRgeneral, 0xc0000171}, {
- ERRHRD, ERRgeneral, NT_STATUS_PARTITION_FAILURE}, {
- ERRHRD, ERRgeneral, NT_STATUS_INVALID_BLOCK_LENGTH}, {
- ERRHRD, ERRgeneral, NT_STATUS_DEVICE_NOT_PARTITIONED}, {
- ERRHRD, ERRgeneral, NT_STATUS_UNABLE_TO_LOCK_MEDIA}, {
- ERRHRD, ERRgeneral, NT_STATUS_UNABLE_TO_UNLOAD_MEDIA}, {
- ERRHRD, ERRgeneral, NT_STATUS_EOM_OVERFLOW}, {
- ERRHRD, ERRgeneral, NT_STATUS_NO_MEDIA}, {
- ERRHRD, ERRgeneral, 0xc0000179}, {
- ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_MEMBER}, {
- ERRHRD, ERRgeneral, NT_STATUS_INVALID_MEMBER}, {
- ERRHRD, ERRgeneral, NT_STATUS_KEY_DELETED}, {
- ERRHRD, ERRgeneral, NT_STATUS_NO_LOG_SPACE}, {
- ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_SIDS}, {
- ERRHRD, ERRgeneral, NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED}, {
- ERRHRD, ERRgeneral, NT_STATUS_KEY_HAS_CHILDREN}, {
- ERRHRD, ERRgeneral, NT_STATUS_CHILD_MUST_BE_VOLATILE}, {
- ERRDOS, 87, NT_STATUS_DEVICE_CONFIGURATION_ERROR}, {
- ERRHRD, ERRgeneral, NT_STATUS_DRIVER_INTERNAL_ERROR}, {
- ERRDOS, 22, NT_STATUS_INVALID_DEVICE_STATE}, {
- ERRHRD, ERRgeneral, NT_STATUS_IO_DEVICE_ERROR}, {
- ERRHRD, ERRgeneral, NT_STATUS_DEVICE_PROTOCOL_ERROR}, {
- ERRHRD, ERRgeneral, NT_STATUS_BACKUP_CONTROLLER}, {
- ERRHRD, ERRgeneral, NT_STATUS_LOG_FILE_FULL}, {
- ERRDOS, 19, NT_STATUS_TOO_LATE}, {
- ERRDOS, ERRnoaccess, NT_STATUS_NO_TRUST_LSA_SECRET},
-/* { This NT error code was 'sqashed'
- from NT_STATUS_NO_TRUST_SAM_ACCOUNT to
- NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE during the session setup } */
- {
- ERRDOS, ERRnoaccess, NT_STATUS_NO_TRUST_SAM_ACCOUNT}, {
- ERRDOS, ERRnoaccess, NT_STATUS_TRUSTED_DOMAIN_FAILURE}, {
- ERRDOS, ERRnoaccess, NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE}, {
- ERRHRD, ERRgeneral, NT_STATUS_EVENTLOG_FILE_CORRUPT}, {
- ERRHRD, ERRgeneral, NT_STATUS_EVENTLOG_CANT_START}, {
- ERRDOS, ERRnoaccess, NT_STATUS_TRUST_FAILURE}, {
- ERRHRD, ERRgeneral, NT_STATUS_MUTANT_LIMIT_EXCEEDED}, {
- ERRDOS, ERRnetlogonNotStarted, NT_STATUS_NETLOGON_NOT_STARTED}, {
- ERRSRV, ERRaccountexpired, NT_STATUS_ACCOUNT_EXPIRED}, {
- ERRHRD, ERRgeneral, NT_STATUS_POSSIBLE_DEADLOCK}, {
- ERRHRD, ERRgeneral, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT}, {
- ERRHRD, ERRgeneral, NT_STATUS_REMOTE_SESSION_LIMIT}, {
- ERRHRD, ERRgeneral, NT_STATUS_EVENTLOG_FILE_CHANGED}, {
- ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT}, {
- ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT}, {
- ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT},
-/* { This NT error code was 'sqashed'
- from NT_STATUS_DOMAIN_TRUST_INCONSISTENT to NT_STATUS_LOGON_FAILURE
- during the session setup } */
- {
- ERRDOS, ERRnoaccess, NT_STATUS_DOMAIN_TRUST_INCONSISTENT}, {
- ERRHRD, ERRgeneral, NT_STATUS_FS_DRIVER_REQUIRED}, {
- ERRHRD, ERRgeneral, NT_STATUS_NO_USER_SESSION_KEY}, {
- ERRDOS, 59, NT_STATUS_USER_SESSION_DELETED}, {
- ERRHRD, ERRgeneral, NT_STATUS_RESOURCE_LANG_NOT_FOUND}, {
- ERRDOS, ERRnomem, NT_STATUS_INSUFF_SERVER_RESOURCES}, {
- ERRHRD, ERRgeneral, NT_STATUS_INVALID_BUFFER_SIZE}, {
- ERRHRD, ERRgeneral, NT_STATUS_INVALID_ADDRESS_COMPONENT}, {
- ERRHRD, ERRgeneral, NT_STATUS_INVALID_ADDRESS_WILDCARD}, {
- ERRDOS, 68, NT_STATUS_TOO_MANY_ADDRESSES}, {
- ERRDOS, 52, NT_STATUS_ADDRESS_ALREADY_EXISTS}, {
- ERRDOS, 64, NT_STATUS_ADDRESS_CLOSED}, {
- ERRDOS, 64, NT_STATUS_CONNECTION_DISCONNECTED}, {
- ERRDOS, 64, NT_STATUS_CONNECTION_RESET}, {
- ERRDOS, 68, NT_STATUS_TOO_MANY_NODES}, {
- ERRDOS, 59, NT_STATUS_TRANSACTION_ABORTED}, {
- ERRDOS, 59, NT_STATUS_TRANSACTION_TIMED_OUT}, {
- ERRDOS, 59, NT_STATUS_TRANSACTION_NO_RELEASE}, {
- ERRDOS, 59, NT_STATUS_TRANSACTION_NO_MATCH}, {
- ERRDOS, 59, NT_STATUS_TRANSACTION_RESPONDED}, {
- ERRDOS, 59, NT_STATUS_TRANSACTION_INVALID_ID}, {
- ERRDOS, 59, NT_STATUS_TRANSACTION_INVALID_TYPE}, {
- ERRDOS, ERRunsup, NT_STATUS_NOT_SERVER_SESSION}, {
- ERRDOS, ERRunsup, NT_STATUS_NOT_CLIENT_SESSION}, {
- ERRHRD, ERRgeneral, NT_STATUS_CANNOT_LOAD_REGISTRY_FILE}, {
- ERRHRD, ERRgeneral, NT_STATUS_DEBUG_ATTACH_FAILED}, {
- ERRHRD, ERRgeneral, NT_STATUS_SYSTEM_PROCESS_TERMINATED}, {
- ERRHRD, ERRgeneral, NT_STATUS_DATA_NOT_ACCEPTED}, {
- ERRHRD, ERRgeneral, NT_STATUS_NO_BROWSER_SERVERS_FOUND}, {
- ERRHRD, ERRgeneral, NT_STATUS_VDM_HARD_ERROR}, {
- ERRHRD, ERRgeneral, NT_STATUS_DRIVER_CANCEL_TIMEOUT}, {
- ERRHRD, ERRgeneral, NT_STATUS_REPLY_MESSAGE_MISMATCH}, {
- ERRHRD, ERRgeneral, NT_STATUS_MAPPED_ALIGNMENT}, {
- ERRDOS, 193, NT_STATUS_IMAGE_CHECKSUM_MISMATCH}, {
- ERRHRD, ERRgeneral, NT_STATUS_LOST_WRITEBEHIND_DATA}, {
- ERRHRD, ERRgeneral, NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID}, {
- ERRSRV, ERRpasswordExpired, NT_STATUS_PASSWORD_MUST_CHANGE}, {
- ERRHRD, ERRgeneral, NT_STATUS_NOT_FOUND}, {
- ERRHRD, ERRgeneral, NT_STATUS_NOT_TINY_STREAM}, {
- ERRHRD, ERRgeneral, NT_STATUS_RECOVERY_FAILURE}, {
- ERRHRD, ERRgeneral, NT_STATUS_STACK_OVERFLOW_READ}, {
- ERRHRD, ERRgeneral, NT_STATUS_FAIL_CHECK}, {
- ERRHRD, ERRgeneral, NT_STATUS_DUPLICATE_OBJECTID}, {
- ERRHRD, ERRgeneral, NT_STATUS_OBJECTID_EXISTS}, {
- ERRHRD, ERRgeneral, NT_STATUS_CONVERT_TO_LARGE}, {
- ERRHRD, ERRgeneral, NT_STATUS_RETRY}, {
- ERRHRD, ERRgeneral, NT_STATUS_FOUND_OUT_OF_SCOPE}, {
- ERRHRD, ERRgeneral, NT_STATUS_ALLOCATE_BUCKET}, {
- ERRHRD, ERRgeneral, NT_STATUS_PROPSET_NOT_FOUND}, {
- ERRHRD, ERRgeneral, NT_STATUS_MARSHALL_OVERFLOW}, {
- ERRHRD, ERRgeneral, NT_STATUS_INVALID_VARIANT}, {
- ERRHRD, ERRgeneral, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND}, {
- ERRDOS, ERRnoaccess, NT_STATUS_ACCOUNT_LOCKED_OUT}, {
- ERRDOS, ERRbadfid, NT_STATUS_HANDLE_NOT_CLOSABLE}, {
- ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_REFUSED}, {
- ERRHRD, ERRgeneral, NT_STATUS_GRACEFUL_DISCONNECT}, {
- ERRHRD, ERRgeneral, NT_STATUS_ADDRESS_ALREADY_ASSOCIATED}, {
- ERRHRD, ERRgeneral, NT_STATUS_ADDRESS_NOT_ASSOCIATED}, {
- ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_INVALID}, {
- ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_ACTIVE}, {
- ERRHRD, ERRgeneral, NT_STATUS_NETWORK_UNREACHABLE}, {
- ERRHRD, ERRgeneral, NT_STATUS_HOST_UNREACHABLE}, {
- ERRHRD, ERRgeneral, NT_STATUS_PROTOCOL_UNREACHABLE}, {
- ERRHRD, ERRgeneral, NT_STATUS_PORT_UNREACHABLE}, {
- ERRHRD, ERRgeneral, NT_STATUS_REQUEST_ABORTED}, {
- ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_ABORTED}, {
- ERRHRD, ERRgeneral, NT_STATUS_BAD_COMPRESSION_BUFFER}, {
- ERRHRD, ERRgeneral, NT_STATUS_USER_MAPPED_FILE}, {
- ERRHRD, ERRgeneral, NT_STATUS_AUDIT_FAILED}, {
- ERRHRD, ERRgeneral, NT_STATUS_TIMER_RESOLUTION_NOT_SET}, {
- ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_COUNT_LIMIT}, {
- ERRHRD, ERRgeneral, NT_STATUS_LOGIN_TIME_RESTRICTION}, {
- ERRHRD, ERRgeneral, NT_STATUS_LOGIN_WKSTA_RESTRICTION}, {
- ERRDOS, 193, NT_STATUS_IMAGE_MP_UP_MISMATCH}, {
- ERRHRD, ERRgeneral, 0xc000024a}, {
- ERRHRD, ERRgeneral, 0xc000024b}, {
- ERRHRD, ERRgeneral, 0xc000024c}, {
- ERRHRD, ERRgeneral, 0xc000024d}, {
- ERRHRD, ERRgeneral, 0xc000024e}, {
- ERRHRD, ERRgeneral, 0xc000024f}, {
- ERRHRD, ERRgeneral, NT_STATUS_INSUFFICIENT_LOGON_INFO}, {
- ERRHRD, ERRgeneral, NT_STATUS_BAD_DLL_ENTRYPOINT}, {
- ERRHRD, ERRgeneral, NT_STATUS_BAD_SERVICE_ENTRYPOINT}, {
- ERRHRD, ERRgeneral, NT_STATUS_LPC_REPLY_LOST}, {
- ERRHRD, ERRgeneral, NT_STATUS_IP_ADDRESS_CONFLICT1}, {
- ERRHRD, ERRgeneral, NT_STATUS_IP_ADDRESS_CONFLICT2}, {
- ERRHRD, ERRgeneral, NT_STATUS_REGISTRY_QUOTA_LIMIT}, {
- ERRSRV, 3, NT_STATUS_PATH_NOT_COVERED}, {
- ERRHRD, ERRgeneral, NT_STATUS_NO_CALLBACK_ACTIVE}, {
- ERRHRD, ERRgeneral, NT_STATUS_LICENSE_QUOTA_EXCEEDED}, {
- ERRHRD, ERRgeneral, NT_STATUS_PWD_TOO_SHORT}, {
- ERRHRD, ERRgeneral, NT_STATUS_PWD_TOO_RECENT}, {
- ERRHRD, ERRgeneral, NT_STATUS_PWD_HISTORY_CONFLICT}, {
- ERRHRD, ERRgeneral, 0xc000025d}, {
- ERRHRD, ERRgeneral, NT_STATUS_PLUGPLAY_NO_DEVICE}, {
- ERRHRD, ERRgeneral, NT_STATUS_UNSUPPORTED_COMPRESSION}, {
- ERRHRD, ERRgeneral, NT_STATUS_INVALID_HW_PROFILE}, {
- ERRHRD, ERRgeneral, NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH}, {
- ERRDOS, 182, NT_STATUS_DRIVER_ORDINAL_NOT_FOUND}, {
- ERRDOS, 127, NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND}, {
- ERRDOS, 288, NT_STATUS_RESOURCE_NOT_OWNED}, {
- ERRDOS, ErrTooManyLinks, NT_STATUS_TOO_MANY_LINKS}, {
- ERRHRD, ERRgeneral, NT_STATUS_QUOTA_LIST_INCONSISTENT}, {
- ERRHRD, ERRgeneral, NT_STATUS_FILE_IS_OFFLINE}, {
- ERRDOS, 21, 0xc000026e}, {
- ERRDOS, 161, 0xc0000281}, {
- ERRDOS, ERRnoaccess, 0xc000028a}, {
- ERRDOS, ERRnoaccess, 0xc000028b}, {
- ERRHRD, ERRgeneral, 0xc000028c}, {
- ERRDOS, ERRnoaccess, 0xc000028d}, {
- ERRDOS, ERRnoaccess, 0xc000028e}, {
- ERRDOS, ERRnoaccess, 0xc000028f}, {
- ERRDOS, ERRnoaccess, 0xc0000290}, {
- ERRDOS, ERRbadfunc, 0xc000029c}, {
- ERRDOS, ERRsymlink, NT_STATUS_STOPPED_ON_SYMLINK}, {
- ERRDOS, ERRinvlevel, 0x007c0001}, };
-
-/*****************************************************************************
- Print an error message from the status code
- *****************************************************************************/
-static void
-cifs_print_status(__u32 status_code)
-{
- int idx = 0;
-
- while (nt_errs[idx].nt_errstr != NULL) {
- if (((nt_errs[idx].nt_errcode) & 0xFFFFFF) ==
- (status_code & 0xFFFFFF)) {
- printk(KERN_NOTICE "Status code returned 0x%08x %s\n",
- status_code, nt_errs[idx].nt_errstr);
- }
- idx++;
- }
- return;
-}
-
-
-static void
-ntstatus_to_dos(__u32 ntstatus, __u8 *eclass, __u16 *ecode)
-{
- int i;
- if (ntstatus == 0) {
- *eclass = 0;
- *ecode = 0;
- return;
- }
- for (i = 0; ntstatus_to_dos_map[i].ntstatus; i++) {
- if (ntstatus == ntstatus_to_dos_map[i].ntstatus) {
- *eclass = ntstatus_to_dos_map[i].dos_class;
- *ecode = ntstatus_to_dos_map[i].dos_code;
- return;
- }
- }
- *eclass = ERRHRD;
- *ecode = ERRgeneral;
-}
-
-int
-map_smb_to_linux_error(char *buf, bool logErr)
-{
- struct smb_hdr *smb = (struct smb_hdr *)buf;
- unsigned int i;
- int rc = -EIO; /* if transport error smb error may not be set */
- __u8 smberrclass;
- __u16 smberrcode;
-
- /* BB if NT Status codes - map NT BB */
-
- /* old style smb error codes */
- if (smb->Status.CifsError == 0)
- return 0;
-
- if (smb->Flags2 & SMBFLG2_ERR_STATUS) {
- /* translate the newer STATUS codes to old style SMB errors
- * and then to POSIX errors */
- __u32 err = le32_to_cpu(smb->Status.CifsError);
- if (logErr && (err != (NT_STATUS_MORE_PROCESSING_REQUIRED)))
- cifs_print_status(err);
- else if (cifsFYI & CIFS_RC)
- cifs_print_status(err);
- ntstatus_to_dos(err, &smberrclass, &smberrcode);
- } else {
- smberrclass = smb->Status.DosError.ErrorClass;
- smberrcode = le16_to_cpu(smb->Status.DosError.Error);
- }
-
- /* old style errors */
-
- /* DOS class smb error codes - map DOS */
- if (smberrclass == ERRDOS) {
- /* 1 byte field no need to byte reverse */
- for (i = 0;
- i <
- sizeof(mapping_table_ERRDOS) /
- sizeof(struct smb_to_posix_error); i++) {
- if (mapping_table_ERRDOS[i].smb_err == 0)
- break;
- else if (mapping_table_ERRDOS[i].smb_err ==
- smberrcode) {
- rc = mapping_table_ERRDOS[i].posix_code;
- break;
- }
- /* else try next error mapping one to see if match */
- }
- } else if (smberrclass == ERRSRV) {
- /* server class of error codes */
- for (i = 0;
- i <
- sizeof(mapping_table_ERRSRV) /
- sizeof(struct smb_to_posix_error); i++) {
- if (mapping_table_ERRSRV[i].smb_err == 0)
- break;
- else if (mapping_table_ERRSRV[i].smb_err ==
- smberrcode) {
- rc = mapping_table_ERRSRV[i].posix_code;
- break;
- }
- /* else try next error mapping to see if match */
- }
- }
- /* else ERRHRD class errors or junk - return EIO */
-
- cFYI(1, "Mapping smb error code 0x%x to POSIX err %d",
- le32_to_cpu(smb->Status.CifsError), rc);
-
- /* generic corrective action e.g. reconnect SMB session on
- * ERRbaduid could be added */
-
- return rc;
-}
-
-/*
- * calculate the size of the SMB message based on the fixed header
- * portion, the number of word parameters and the data portion of the message
- */
-unsigned int
-smbCalcSize(struct smb_hdr *ptr)
-{
- return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) +
- 2 /* size of the bcc field */ + get_bcc(ptr));
-}
-
-/* The following are taken from fs/ntfs/util.c */
-
-#define NTFS_TIME_OFFSET ((u64)(369*365 + 89) * 24 * 3600 * 10000000)
-
-/*
- * Convert the NT UTC (based 1601-01-01, in hundred nanosecond units)
- * into Unix UTC (based 1970-01-01, in seconds).
- */
-struct timespec
-cifs_NTtimeToUnix(__le64 ntutc)
-{
- struct timespec ts;
- /* BB what about the timezone? BB */
-
- /* Subtract the NTFS time offset, then convert to 1s intervals. */
- u64 t;
-
- t = le64_to_cpu(ntutc) - NTFS_TIME_OFFSET;
- ts.tv_nsec = do_div(t, 10000000) * 100;
- ts.tv_sec = t;
- return ts;
-}
-
-/* Convert the Unix UTC into NT UTC. */
-u64
-cifs_UnixTimeToNT(struct timespec t)
-{
- /* Convert to 100ns intervals and then add the NTFS time offset. */
- return (u64) t.tv_sec * 10000000 + t.tv_nsec/100 + NTFS_TIME_OFFSET;
-}
-
-static int total_days_of_prev_months[] =
-{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
-
-struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset)
-{
- struct timespec ts;
- int sec, min, days, month, year;
- u16 date = le16_to_cpu(le_date);
- u16 time = le16_to_cpu(le_time);
- SMB_TIME *st = (SMB_TIME *)&time;
- SMB_DATE *sd = (SMB_DATE *)&date;
-
- cFYI(1, "date %d time %d", date, time);
-
- sec = 2 * st->TwoSeconds;
- min = st->Minutes;
- if ((sec > 59) || (min > 59))
- cERROR(1, "illegal time min %d sec %d", min, sec);
- sec += (min * 60);
- sec += 60 * 60 * st->Hours;
- if (st->Hours > 24)
- cERROR(1, "illegal hours %d", st->Hours);
- days = sd->Day;
- month = sd->Month;
- if ((days > 31) || (month > 12)) {
- cERROR(1, "illegal date, month %d day: %d", month, days);
- if (month > 12)
- month = 12;
- }
- month -= 1;
- days += total_days_of_prev_months[month];
- days += 3652; /* account for difference in days between 1980 and 1970 */
- year = sd->Year;
- days += year * 365;
- days += (year/4); /* leap year */
- /* generalized leap year calculation is more complex, ie no leap year
- for years/100 except for years/400, but since the maximum number for DOS
- year is 2**7, the last year is 1980+127, which means we need only
- consider 2 special case years, ie the years 2000 and 2100, and only
- adjust for the lack of leap year for the year 2100, as 2000 was a
- leap year (divisable by 400) */
- if (year >= 120) /* the year 2100 */
- days = days - 1; /* do not count leap year for the year 2100 */
-
- /* adjust for leap year where we are still before leap day */
- if (year != 120)
- days -= ((year & 0x03) == 0) && (month < 2 ? 1 : 0);
- sec += 24 * 60 * 60 * days;
-
- ts.tv_sec = sec + offset;
-
- /* cFYI(1, "sec after cnvrt dos to unix time %d",sec); */
-
- ts.tv_nsec = 0;
- return ts;
-}
diff --git a/ANDROID_3.4.5/fs/cifs/nterr.c b/ANDROID_3.4.5/fs/cifs/nterr.c
deleted file mode 100644
index 819fd994..00000000
--- a/ANDROID_3.4.5/fs/cifs/nterr.c
+++ /dev/null
@@ -1,687 +0,0 @@
-/*
- * Unix SMB/Netbios implementation.
- * Version 1.9.
- * RPC Pipe client / server routines
- * Copyright (C) Luke Kenneth Casson Leighton 1997-2001.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/* NT error codes - see nterr.h */
-#include <linux/types.h>
-#include <linux/fs.h>
-#include "nterr.h"
-
-const struct nt_err_code_struct nt_errs[] = {
- {"NT_STATUS_OK", NT_STATUS_OK},
- {"NT_STATUS_UNSUCCESSFUL", NT_STATUS_UNSUCCESSFUL},
- {"NT_STATUS_NOT_IMPLEMENTED", NT_STATUS_NOT_IMPLEMENTED},
- {"NT_STATUS_INVALID_INFO_CLASS", NT_STATUS_INVALID_INFO_CLASS},
- {"NT_STATUS_INFO_LENGTH_MISMATCH", NT_STATUS_INFO_LENGTH_MISMATCH},
- {"NT_STATUS_ACCESS_VIOLATION", NT_STATUS_ACCESS_VIOLATION},
- {"STATUS_BUFFER_OVERFLOW", STATUS_BUFFER_OVERFLOW},
- {"NT_STATUS_IN_PAGE_ERROR", NT_STATUS_IN_PAGE_ERROR},
- {"NT_STATUS_PAGEFILE_QUOTA", NT_STATUS_PAGEFILE_QUOTA},
- {"NT_STATUS_INVALID_HANDLE", NT_STATUS_INVALID_HANDLE},
- {"NT_STATUS_BAD_INITIAL_STACK", NT_STATUS_BAD_INITIAL_STACK},
- {"NT_STATUS_BAD_INITIAL_PC", NT_STATUS_BAD_INITIAL_PC},
- {"NT_STATUS_INVALID_CID", NT_STATUS_INVALID_CID},
- {"NT_STATUS_TIMER_NOT_CANCELED", NT_STATUS_TIMER_NOT_CANCELED},
- {"NT_STATUS_INVALID_PARAMETER", NT_STATUS_INVALID_PARAMETER},
- {"NT_STATUS_NO_SUCH_DEVICE", NT_STATUS_NO_SUCH_DEVICE},
- {"NT_STATUS_NO_SUCH_FILE", NT_STATUS_NO_SUCH_FILE},
- {"NT_STATUS_INVALID_DEVICE_REQUEST",
- NT_STATUS_INVALID_DEVICE_REQUEST},
- {"NT_STATUS_END_OF_FILE", NT_STATUS_END_OF_FILE},
- {"NT_STATUS_WRONG_VOLUME", NT_STATUS_WRONG_VOLUME},
- {"NT_STATUS_NO_MEDIA_IN_DEVICE", NT_STATUS_NO_MEDIA_IN_DEVICE},
- {"NT_STATUS_UNRECOGNIZED_MEDIA", NT_STATUS_UNRECOGNIZED_MEDIA},
- {"NT_STATUS_NONEXISTENT_SECTOR", NT_STATUS_NONEXISTENT_SECTOR},
- {"NT_STATUS_MORE_PROCESSING_REQUIRED",
- NT_STATUS_MORE_PROCESSING_REQUIRED},
- {"NT_STATUS_NO_MEMORY", NT_STATUS_NO_MEMORY},
- {"NT_STATUS_CONFLICTING_ADDRESSES",
- NT_STATUS_CONFLICTING_ADDRESSES},
- {"NT_STATUS_NOT_MAPPED_VIEW", NT_STATUS_NOT_MAPPED_VIEW},
- {"NT_STATUS_UNABLE_TO_FREE_VM", NT_STATUS_UNABLE_TO_FREE_VM},
- {"NT_STATUS_UNABLE_TO_DELETE_SECTION",
- NT_STATUS_UNABLE_TO_DELETE_SECTION},
- {"NT_STATUS_INVALID_SYSTEM_SERVICE",
- NT_STATUS_INVALID_SYSTEM_SERVICE},
- {"NT_STATUS_ILLEGAL_INSTRUCTION", NT_STATUS_ILLEGAL_INSTRUCTION},
- {"NT_STATUS_INVALID_LOCK_SEQUENCE",
- NT_STATUS_INVALID_LOCK_SEQUENCE},
- {"NT_STATUS_INVALID_VIEW_SIZE", NT_STATUS_INVALID_VIEW_SIZE},
- {"NT_STATUS_INVALID_FILE_FOR_SECTION",
- NT_STATUS_INVALID_FILE_FOR_SECTION},
- {"NT_STATUS_ALREADY_COMMITTED", NT_STATUS_ALREADY_COMMITTED},
- {"NT_STATUS_ACCESS_DENIED", NT_STATUS_ACCESS_DENIED},
- {"NT_STATUS_BUFFER_TOO_SMALL", NT_STATUS_BUFFER_TOO_SMALL},
- {"NT_STATUS_OBJECT_TYPE_MISMATCH", NT_STATUS_OBJECT_TYPE_MISMATCH},
- {"NT_STATUS_NONCONTINUABLE_EXCEPTION",
- NT_STATUS_NONCONTINUABLE_EXCEPTION},
- {"NT_STATUS_INVALID_DISPOSITION", NT_STATUS_INVALID_DISPOSITION},
- {"NT_STATUS_UNWIND", NT_STATUS_UNWIND},
- {"NT_STATUS_BAD_STACK", NT_STATUS_BAD_STACK},
- {"NT_STATUS_INVALID_UNWIND_TARGET",
- NT_STATUS_INVALID_UNWIND_TARGET},
- {"NT_STATUS_NOT_LOCKED", NT_STATUS_NOT_LOCKED},
- {"NT_STATUS_PARITY_ERROR", NT_STATUS_PARITY_ERROR},
- {"NT_STATUS_UNABLE_TO_DECOMMIT_VM",
- NT_STATUS_UNABLE_TO_DECOMMIT_VM},
- {"NT_STATUS_NOT_COMMITTED", NT_STATUS_NOT_COMMITTED},
- {"NT_STATUS_INVALID_PORT_ATTRIBUTES",
- NT_STATUS_INVALID_PORT_ATTRIBUTES},
- {"NT_STATUS_PORT_MESSAGE_TOO_LONG",
- NT_STATUS_PORT_MESSAGE_TOO_LONG},
- {"NT_STATUS_INVALID_PARAMETER_MIX",
- NT_STATUS_INVALID_PARAMETER_MIX},
- {"NT_STATUS_INVALID_QUOTA_LOWER", NT_STATUS_INVALID_QUOTA_LOWER},
- {"NT_STATUS_DISK_CORRUPT_ERROR", NT_STATUS_DISK_CORRUPT_ERROR},
- {"NT_STATUS_OBJECT_NAME_INVALID", NT_STATUS_OBJECT_NAME_INVALID},
- {"NT_STATUS_OBJECT_NAME_NOT_FOUND",
- NT_STATUS_OBJECT_NAME_NOT_FOUND},
- {"NT_STATUS_OBJECT_NAME_COLLISION",
- NT_STATUS_OBJECT_NAME_COLLISION},
- {"NT_STATUS_HANDLE_NOT_WAITABLE", NT_STATUS_HANDLE_NOT_WAITABLE},
- {"NT_STATUS_PORT_DISCONNECTED", NT_STATUS_PORT_DISCONNECTED},
- {"NT_STATUS_DEVICE_ALREADY_ATTACHED",
- NT_STATUS_DEVICE_ALREADY_ATTACHED},
- {"NT_STATUS_OBJECT_PATH_INVALID", NT_STATUS_OBJECT_PATH_INVALID},
- {"NT_STATUS_OBJECT_PATH_NOT_FOUND",
- NT_STATUS_OBJECT_PATH_NOT_FOUND},
- {"NT_STATUS_OBJECT_PATH_SYNTAX_BAD",
- NT_STATUS_OBJECT_PATH_SYNTAX_BAD},
- {"NT_STATUS_DATA_OVERRUN", NT_STATUS_DATA_OVERRUN},
- {"NT_STATUS_DATA_LATE_ERROR", NT_STATUS_DATA_LATE_ERROR},
- {"NT_STATUS_DATA_ERROR", NT_STATUS_DATA_ERROR},
- {"NT_STATUS_CRC_ERROR", NT_STATUS_CRC_ERROR},
- {"NT_STATUS_SECTION_TOO_BIG", NT_STATUS_SECTION_TOO_BIG},
- {"NT_STATUS_PORT_CONNECTION_REFUSED",
- NT_STATUS_PORT_CONNECTION_REFUSED},
- {"NT_STATUS_INVALID_PORT_HANDLE", NT_STATUS_INVALID_PORT_HANDLE},
- {"NT_STATUS_SHARING_VIOLATION", NT_STATUS_SHARING_VIOLATION},
- {"NT_STATUS_QUOTA_EXCEEDED", NT_STATUS_QUOTA_EXCEEDED},
- {"NT_STATUS_INVALID_PAGE_PROTECTION",
- NT_STATUS_INVALID_PAGE_PROTECTION},
- {"NT_STATUS_MUTANT_NOT_OWNED", NT_STATUS_MUTANT_NOT_OWNED},
- {"NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED",
- NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED},
- {"NT_STATUS_PORT_ALREADY_SET", NT_STATUS_PORT_ALREADY_SET},
- {"NT_STATUS_SECTION_NOT_IMAGE", NT_STATUS_SECTION_NOT_IMAGE},
- {"NT_STATUS_SUSPEND_COUNT_EXCEEDED",
- NT_STATUS_SUSPEND_COUNT_EXCEEDED},
- {"NT_STATUS_THREAD_IS_TERMINATING",
- NT_STATUS_THREAD_IS_TERMINATING},
- {"NT_STATUS_BAD_WORKING_SET_LIMIT",
- NT_STATUS_BAD_WORKING_SET_LIMIT},
- {"NT_STATUS_INCOMPATIBLE_FILE_MAP",
- NT_STATUS_INCOMPATIBLE_FILE_MAP},
- {"NT_STATUS_SECTION_PROTECTION", NT_STATUS_SECTION_PROTECTION},
- {"NT_STATUS_EAS_NOT_SUPPORTED", NT_STATUS_EAS_NOT_SUPPORTED},
- {"NT_STATUS_EA_TOO_LARGE", NT_STATUS_EA_TOO_LARGE},
- {"NT_STATUS_NONEXISTENT_EA_ENTRY", NT_STATUS_NONEXISTENT_EA_ENTRY},
- {"NT_STATUS_NO_EAS_ON_FILE", NT_STATUS_NO_EAS_ON_FILE},
- {"NT_STATUS_EA_CORRUPT_ERROR", NT_STATUS_EA_CORRUPT_ERROR},
- {"NT_STATUS_FILE_LOCK_CONFLICT", NT_STATUS_FILE_LOCK_CONFLICT},
- {"NT_STATUS_LOCK_NOT_GRANTED", NT_STATUS_LOCK_NOT_GRANTED},
- {"NT_STATUS_DELETE_PENDING", NT_STATUS_DELETE_PENDING},
- {"NT_STATUS_CTL_FILE_NOT_SUPPORTED",
- NT_STATUS_CTL_FILE_NOT_SUPPORTED},
- {"NT_STATUS_UNKNOWN_REVISION", NT_STATUS_UNKNOWN_REVISION},
- {"NT_STATUS_REVISION_MISMATCH", NT_STATUS_REVISION_MISMATCH},
- {"NT_STATUS_INVALID_OWNER", NT_STATUS_INVALID_OWNER},
- {"NT_STATUS_INVALID_PRIMARY_GROUP",
- NT_STATUS_INVALID_PRIMARY_GROUP},
- {"NT_STATUS_NO_IMPERSONATION_TOKEN",
- NT_STATUS_NO_IMPERSONATION_TOKEN},
- {"NT_STATUS_CANT_DISABLE_MANDATORY",
- NT_STATUS_CANT_DISABLE_MANDATORY},
- {"NT_STATUS_NO_LOGON_SERVERS", NT_STATUS_NO_LOGON_SERVERS},
- {"NT_STATUS_NO_SUCH_LOGON_SESSION",
- NT_STATUS_NO_SUCH_LOGON_SESSION},
- {"NT_STATUS_NO_SUCH_PRIVILEGE", NT_STATUS_NO_SUCH_PRIVILEGE},
- {"NT_STATUS_PRIVILEGE_NOT_HELD", NT_STATUS_PRIVILEGE_NOT_HELD},
- {"NT_STATUS_INVALID_ACCOUNT_NAME", NT_STATUS_INVALID_ACCOUNT_NAME},
- {"NT_STATUS_USER_EXISTS", NT_STATUS_USER_EXISTS},
- {"NT_STATUS_NO_SUCH_USER", NT_STATUS_NO_SUCH_USER},
- {"NT_STATUS_GROUP_EXISTS", NT_STATUS_GROUP_EXISTS},
- {"NT_STATUS_NO_SUCH_GROUP", NT_STATUS_NO_SUCH_GROUP},
- {"NT_STATUS_MEMBER_IN_GROUP", NT_STATUS_MEMBER_IN_GROUP},
- {"NT_STATUS_MEMBER_NOT_IN_GROUP", NT_STATUS_MEMBER_NOT_IN_GROUP},
- {"NT_STATUS_LAST_ADMIN", NT_STATUS_LAST_ADMIN},
- {"NT_STATUS_WRONG_PASSWORD", NT_STATUS_WRONG_PASSWORD},
- {"NT_STATUS_ILL_FORMED_PASSWORD", NT_STATUS_ILL_FORMED_PASSWORD},
- {"NT_STATUS_PASSWORD_RESTRICTION", NT_STATUS_PASSWORD_RESTRICTION},
- {"NT_STATUS_LOGON_FAILURE", NT_STATUS_LOGON_FAILURE},
- {"NT_STATUS_ACCOUNT_RESTRICTION", NT_STATUS_ACCOUNT_RESTRICTION},
- {"NT_STATUS_INVALID_LOGON_HOURS", NT_STATUS_INVALID_LOGON_HOURS},
- {"NT_STATUS_INVALID_WORKSTATION", NT_STATUS_INVALID_WORKSTATION},
- {"NT_STATUS_PASSWORD_EXPIRED", NT_STATUS_PASSWORD_EXPIRED},
- {"NT_STATUS_ACCOUNT_DISABLED", NT_STATUS_ACCOUNT_DISABLED},
- {"NT_STATUS_NONE_MAPPED", NT_STATUS_NONE_MAPPED},
- {"NT_STATUS_TOO_MANY_LUIDS_REQUESTED",
- NT_STATUS_TOO_MANY_LUIDS_REQUESTED},
- {"NT_STATUS_LUIDS_EXHAUSTED", NT_STATUS_LUIDS_EXHAUSTED},
- {"NT_STATUS_INVALID_SUB_AUTHORITY",
- NT_STATUS_INVALID_SUB_AUTHORITY},
- {"NT_STATUS_INVALID_ACL", NT_STATUS_INVALID_ACL},
- {"NT_STATUS_INVALID_SID", NT_STATUS_INVALID_SID},
- {"NT_STATUS_INVALID_SECURITY_DESCR",
- NT_STATUS_INVALID_SECURITY_DESCR},
- {"NT_STATUS_PROCEDURE_NOT_FOUND", NT_STATUS_PROCEDURE_NOT_FOUND},
- {"NT_STATUS_INVALID_IMAGE_FORMAT", NT_STATUS_INVALID_IMAGE_FORMAT},
- {"NT_STATUS_NO_TOKEN", NT_STATUS_NO_TOKEN},
- {"NT_STATUS_BAD_INHERITANCE_ACL", NT_STATUS_BAD_INHERITANCE_ACL},
- {"NT_STATUS_RANGE_NOT_LOCKED", NT_STATUS_RANGE_NOT_LOCKED},
- {"NT_STATUS_DISK_FULL", NT_STATUS_DISK_FULL},
- {"NT_STATUS_SERVER_DISABLED", NT_STATUS_SERVER_DISABLED},
- {"NT_STATUS_SERVER_NOT_DISABLED", NT_STATUS_SERVER_NOT_DISABLED},
- {"NT_STATUS_TOO_MANY_GUIDS_REQUESTED",
- NT_STATUS_TOO_MANY_GUIDS_REQUESTED},
- {"NT_STATUS_GUIDS_EXHAUSTED", NT_STATUS_GUIDS_EXHAUSTED},
- {"NT_STATUS_INVALID_ID_AUTHORITY", NT_STATUS_INVALID_ID_AUTHORITY},
- {"NT_STATUS_AGENTS_EXHAUSTED", NT_STATUS_AGENTS_EXHAUSTED},
- {"NT_STATUS_INVALID_VOLUME_LABEL", NT_STATUS_INVALID_VOLUME_LABEL},
- {"NT_STATUS_SECTION_NOT_EXTENDED", NT_STATUS_SECTION_NOT_EXTENDED},
- {"NT_STATUS_NOT_MAPPED_DATA", NT_STATUS_NOT_MAPPED_DATA},
- {"NT_STATUS_RESOURCE_DATA_NOT_FOUND",
- NT_STATUS_RESOURCE_DATA_NOT_FOUND},
- {"NT_STATUS_RESOURCE_TYPE_NOT_FOUND",
- NT_STATUS_RESOURCE_TYPE_NOT_FOUND},
- {"NT_STATUS_RESOURCE_NAME_NOT_FOUND",
- NT_STATUS_RESOURCE_NAME_NOT_FOUND},
- {"NT_STATUS_ARRAY_BOUNDS_EXCEEDED",
- NT_STATUS_ARRAY_BOUNDS_EXCEEDED},
- {"NT_STATUS_FLOAT_DENORMAL_OPERAND",
- NT_STATUS_FLOAT_DENORMAL_OPERAND},
- {"NT_STATUS_FLOAT_DIVIDE_BY_ZERO", NT_STATUS_FLOAT_DIVIDE_BY_ZERO},
- {"NT_STATUS_FLOAT_INEXACT_RESULT", NT_STATUS_FLOAT_INEXACT_RESULT},
- {"NT_STATUS_FLOAT_INVALID_OPERATION",
- NT_STATUS_FLOAT_INVALID_OPERATION},
- {"NT_STATUS_FLOAT_OVERFLOW", NT_STATUS_FLOAT_OVERFLOW},
- {"NT_STATUS_FLOAT_STACK_CHECK", NT_STATUS_FLOAT_STACK_CHECK},
- {"NT_STATUS_FLOAT_UNDERFLOW", NT_STATUS_FLOAT_UNDERFLOW},
- {"NT_STATUS_INTEGER_DIVIDE_BY_ZERO",
- NT_STATUS_INTEGER_DIVIDE_BY_ZERO},
- {"NT_STATUS_INTEGER_OVERFLOW", NT_STATUS_INTEGER_OVERFLOW},
- {"NT_STATUS_PRIVILEGED_INSTRUCTION",
- NT_STATUS_PRIVILEGED_INSTRUCTION},
- {"NT_STATUS_TOO_MANY_PAGING_FILES",
- NT_STATUS_TOO_MANY_PAGING_FILES},
- {"NT_STATUS_FILE_INVALID", NT_STATUS_FILE_INVALID},
- {"NT_STATUS_ALLOTTED_SPACE_EXCEEDED",
- NT_STATUS_ALLOTTED_SPACE_EXCEEDED},
- {"NT_STATUS_INSUFFICIENT_RESOURCES",
- NT_STATUS_INSUFFICIENT_RESOURCES},
- {"NT_STATUS_DFS_EXIT_PATH_FOUND", NT_STATUS_DFS_EXIT_PATH_FOUND},
- {"NT_STATUS_DEVICE_DATA_ERROR", NT_STATUS_DEVICE_DATA_ERROR},
- {"NT_STATUS_DEVICE_NOT_CONNECTED", NT_STATUS_DEVICE_NOT_CONNECTED},
- {"NT_STATUS_DEVICE_POWER_FAILURE", NT_STATUS_DEVICE_POWER_FAILURE},
- {"NT_STATUS_FREE_VM_NOT_AT_BASE", NT_STATUS_FREE_VM_NOT_AT_BASE},
- {"NT_STATUS_MEMORY_NOT_ALLOCATED", NT_STATUS_MEMORY_NOT_ALLOCATED},
- {"NT_STATUS_WORKING_SET_QUOTA", NT_STATUS_WORKING_SET_QUOTA},
- {"NT_STATUS_MEDIA_WRITE_PROTECTED",
- NT_STATUS_MEDIA_WRITE_PROTECTED},
- {"NT_STATUS_DEVICE_NOT_READY", NT_STATUS_DEVICE_NOT_READY},
- {"NT_STATUS_INVALID_GROUP_ATTRIBUTES",
- NT_STATUS_INVALID_GROUP_ATTRIBUTES},
- {"NT_STATUS_BAD_IMPERSONATION_LEVEL",
- NT_STATUS_BAD_IMPERSONATION_LEVEL},
- {"NT_STATUS_CANT_OPEN_ANONYMOUS", NT_STATUS_CANT_OPEN_ANONYMOUS},
- {"NT_STATUS_BAD_VALIDATION_CLASS", NT_STATUS_BAD_VALIDATION_CLASS},
- {"NT_STATUS_BAD_TOKEN_TYPE", NT_STATUS_BAD_TOKEN_TYPE},
- {"NT_STATUS_BAD_MASTER_BOOT_RECORD",
- NT_STATUS_BAD_MASTER_BOOT_RECORD},
- {"NT_STATUS_INSTRUCTION_MISALIGNMENT",
- NT_STATUS_INSTRUCTION_MISALIGNMENT},
- {"NT_STATUS_INSTANCE_NOT_AVAILABLE",
- NT_STATUS_INSTANCE_NOT_AVAILABLE},
- {"NT_STATUS_PIPE_NOT_AVAILABLE", NT_STATUS_PIPE_NOT_AVAILABLE},
- {"NT_STATUS_INVALID_PIPE_STATE", NT_STATUS_INVALID_PIPE_STATE},
- {"NT_STATUS_PIPE_BUSY", NT_STATUS_PIPE_BUSY},
- {"NT_STATUS_ILLEGAL_FUNCTION", NT_STATUS_ILLEGAL_FUNCTION},
- {"NT_STATUS_PIPE_DISCONNECTED", NT_STATUS_PIPE_DISCONNECTED},
- {"NT_STATUS_PIPE_CLOSING", NT_STATUS_PIPE_CLOSING},
- {"NT_STATUS_PIPE_CONNECTED", NT_STATUS_PIPE_CONNECTED},
- {"NT_STATUS_PIPE_LISTENING", NT_STATUS_PIPE_LISTENING},
- {"NT_STATUS_INVALID_READ_MODE", NT_STATUS_INVALID_READ_MODE},
- {"NT_STATUS_IO_TIMEOUT", NT_STATUS_IO_TIMEOUT},
- {"NT_STATUS_FILE_FORCED_CLOSED", NT_STATUS_FILE_FORCED_CLOSED},
- {"NT_STATUS_PROFILING_NOT_STARTED",
- NT_STATUS_PROFILING_NOT_STARTED},
- {"NT_STATUS_PROFILING_NOT_STOPPED",
- NT_STATUS_PROFILING_NOT_STOPPED},
- {"NT_STATUS_COULD_NOT_INTERPRET", NT_STATUS_COULD_NOT_INTERPRET},
- {"NT_STATUS_FILE_IS_A_DIRECTORY", NT_STATUS_FILE_IS_A_DIRECTORY},
- {"NT_STATUS_NOT_SUPPORTED", NT_STATUS_NOT_SUPPORTED},
- {"NT_STATUS_REMOTE_NOT_LISTENING", NT_STATUS_REMOTE_NOT_LISTENING},
- {"NT_STATUS_DUPLICATE_NAME", NT_STATUS_DUPLICATE_NAME},
- {"NT_STATUS_BAD_NETWORK_PATH", NT_STATUS_BAD_NETWORK_PATH},
- {"NT_STATUS_NETWORK_BUSY", NT_STATUS_NETWORK_BUSY},
- {"NT_STATUS_DEVICE_DOES_NOT_EXIST",
- NT_STATUS_DEVICE_DOES_NOT_EXIST},
- {"NT_STATUS_TOO_MANY_COMMANDS", NT_STATUS_TOO_MANY_COMMANDS},
- {"NT_STATUS_ADAPTER_HARDWARE_ERROR",
- NT_STATUS_ADAPTER_HARDWARE_ERROR},
- {"NT_STATUS_INVALID_NETWORK_RESPONSE",
- NT_STATUS_INVALID_NETWORK_RESPONSE},
- {"NT_STATUS_UNEXPECTED_NETWORK_ERROR",
- NT_STATUS_UNEXPECTED_NETWORK_ERROR},
- {"NT_STATUS_BAD_REMOTE_ADAPTER", NT_STATUS_BAD_REMOTE_ADAPTER},
- {"NT_STATUS_PRINT_QUEUE_FULL", NT_STATUS_PRINT_QUEUE_FULL},
- {"NT_STATUS_NO_SPOOL_SPACE", NT_STATUS_NO_SPOOL_SPACE},
- {"NT_STATUS_PRINT_CANCELLED", NT_STATUS_PRINT_CANCELLED},
- {"NT_STATUS_NETWORK_NAME_DELETED", NT_STATUS_NETWORK_NAME_DELETED},
- {"NT_STATUS_NETWORK_ACCESS_DENIED",
- NT_STATUS_NETWORK_ACCESS_DENIED},
- {"NT_STATUS_BAD_DEVICE_TYPE", NT_STATUS_BAD_DEVICE_TYPE},
- {"NT_STATUS_BAD_NETWORK_NAME", NT_STATUS_BAD_NETWORK_NAME},
- {"NT_STATUS_TOO_MANY_NAMES", NT_STATUS_TOO_MANY_NAMES},
- {"NT_STATUS_TOO_MANY_SESSIONS", NT_STATUS_TOO_MANY_SESSIONS},
- {"NT_STATUS_SHARING_PAUSED", NT_STATUS_SHARING_PAUSED},
- {"NT_STATUS_REQUEST_NOT_ACCEPTED", NT_STATUS_REQUEST_NOT_ACCEPTED},
- {"NT_STATUS_REDIRECTOR_PAUSED", NT_STATUS_REDIRECTOR_PAUSED},
- {"NT_STATUS_NET_WRITE_FAULT", NT_STATUS_NET_WRITE_FAULT},
- {"NT_STATUS_PROFILING_AT_LIMIT", NT_STATUS_PROFILING_AT_LIMIT},
- {"NT_STATUS_NOT_SAME_DEVICE", NT_STATUS_NOT_SAME_DEVICE},
- {"NT_STATUS_FILE_RENAMED", NT_STATUS_FILE_RENAMED},
- {"NT_STATUS_VIRTUAL_CIRCUIT_CLOSED",
- NT_STATUS_VIRTUAL_CIRCUIT_CLOSED},
- {"NT_STATUS_NO_SECURITY_ON_OBJECT",
- NT_STATUS_NO_SECURITY_ON_OBJECT},
- {"NT_STATUS_CANT_WAIT", NT_STATUS_CANT_WAIT},
- {"NT_STATUS_PIPE_EMPTY", NT_STATUS_PIPE_EMPTY},
- {"NT_STATUS_CANT_ACCESS_DOMAIN_INFO",
- NT_STATUS_CANT_ACCESS_DOMAIN_INFO},
- {"NT_STATUS_CANT_TERMINATE_SELF", NT_STATUS_CANT_TERMINATE_SELF},
- {"NT_STATUS_INVALID_SERVER_STATE", NT_STATUS_INVALID_SERVER_STATE},
- {"NT_STATUS_INVALID_DOMAIN_STATE", NT_STATUS_INVALID_DOMAIN_STATE},
- {"NT_STATUS_INVALID_DOMAIN_ROLE", NT_STATUS_INVALID_DOMAIN_ROLE},
- {"NT_STATUS_NO_SUCH_DOMAIN", NT_STATUS_NO_SUCH_DOMAIN},
- {"NT_STATUS_DOMAIN_EXISTS", NT_STATUS_DOMAIN_EXISTS},
- {"NT_STATUS_DOMAIN_LIMIT_EXCEEDED",
- NT_STATUS_DOMAIN_LIMIT_EXCEEDED},
- {"NT_STATUS_OPLOCK_NOT_GRANTED", NT_STATUS_OPLOCK_NOT_GRANTED},
- {"NT_STATUS_INVALID_OPLOCK_PROTOCOL",
- NT_STATUS_INVALID_OPLOCK_PROTOCOL},
- {"NT_STATUS_INTERNAL_DB_CORRUPTION",
- NT_STATUS_INTERNAL_DB_CORRUPTION},
- {"NT_STATUS_INTERNAL_ERROR", NT_STATUS_INTERNAL_ERROR},
- {"NT_STATUS_GENERIC_NOT_MAPPED", NT_STATUS_GENERIC_NOT_MAPPED},
- {"NT_STATUS_BAD_DESCRIPTOR_FORMAT",
- NT_STATUS_BAD_DESCRIPTOR_FORMAT},
- {"NT_STATUS_INVALID_USER_BUFFER", NT_STATUS_INVALID_USER_BUFFER},
- {"NT_STATUS_UNEXPECTED_IO_ERROR", NT_STATUS_UNEXPECTED_IO_ERROR},
- {"NT_STATUS_UNEXPECTED_MM_CREATE_ERR",
- NT_STATUS_UNEXPECTED_MM_CREATE_ERR},
- {"NT_STATUS_UNEXPECTED_MM_MAP_ERROR",
- NT_STATUS_UNEXPECTED_MM_MAP_ERROR},
- {"NT_STATUS_UNEXPECTED_MM_EXTEND_ERR",
- NT_STATUS_UNEXPECTED_MM_EXTEND_ERR},
- {"NT_STATUS_NOT_LOGON_PROCESS", NT_STATUS_NOT_LOGON_PROCESS},
- {"NT_STATUS_LOGON_SESSION_EXISTS", NT_STATUS_LOGON_SESSION_EXISTS},
- {"NT_STATUS_INVALID_PARAMETER_1", NT_STATUS_INVALID_PARAMETER_1},
- {"NT_STATUS_INVALID_PARAMETER_2", NT_STATUS_INVALID_PARAMETER_2},
- {"NT_STATUS_INVALID_PARAMETER_3", NT_STATUS_INVALID_PARAMETER_3},
- {"NT_STATUS_INVALID_PARAMETER_4", NT_STATUS_INVALID_PARAMETER_4},
- {"NT_STATUS_INVALID_PARAMETER_5", NT_STATUS_INVALID_PARAMETER_5},
- {"NT_STATUS_INVALID_PARAMETER_6", NT_STATUS_INVALID_PARAMETER_6},
- {"NT_STATUS_INVALID_PARAMETER_7", NT_STATUS_INVALID_PARAMETER_7},
- {"NT_STATUS_INVALID_PARAMETER_8", NT_STATUS_INVALID_PARAMETER_8},
- {"NT_STATUS_INVALID_PARAMETER_9", NT_STATUS_INVALID_PARAMETER_9},
- {"NT_STATUS_INVALID_PARAMETER_10", NT_STATUS_INVALID_PARAMETER_10},
- {"NT_STATUS_INVALID_PARAMETER_11", NT_STATUS_INVALID_PARAMETER_11},
- {"NT_STATUS_INVALID_PARAMETER_12", NT_STATUS_INVALID_PARAMETER_12},
- {"NT_STATUS_REDIRECTOR_NOT_STARTED",
- NT_STATUS_REDIRECTOR_NOT_STARTED},
- {"NT_STATUS_REDIRECTOR_STARTED", NT_STATUS_REDIRECTOR_STARTED},
- {"NT_STATUS_STACK_OVERFLOW", NT_STATUS_STACK_OVERFLOW},
- {"NT_STATUS_NO_SUCH_PACKAGE", NT_STATUS_NO_SUCH_PACKAGE},
- {"NT_STATUS_BAD_FUNCTION_TABLE", NT_STATUS_BAD_FUNCTION_TABLE},
- {"NT_STATUS_DIRECTORY_NOT_EMPTY", NT_STATUS_DIRECTORY_NOT_EMPTY},
- {"NT_STATUS_FILE_CORRUPT_ERROR", NT_STATUS_FILE_CORRUPT_ERROR},
- {"NT_STATUS_NOT_A_DIRECTORY", NT_STATUS_NOT_A_DIRECTORY},
- {"NT_STATUS_BAD_LOGON_SESSION_STATE",
- NT_STATUS_BAD_LOGON_SESSION_STATE},
- {"NT_STATUS_LOGON_SESSION_COLLISION",
- NT_STATUS_LOGON_SESSION_COLLISION},
- {"NT_STATUS_NAME_TOO_LONG", NT_STATUS_NAME_TOO_LONG},
- {"NT_STATUS_FILES_OPEN", NT_STATUS_FILES_OPEN},
- {"NT_STATUS_CONNECTION_IN_USE", NT_STATUS_CONNECTION_IN_USE},
- {"NT_STATUS_MESSAGE_NOT_FOUND", NT_STATUS_MESSAGE_NOT_FOUND},
- {"NT_STATUS_PROCESS_IS_TERMINATING",
- NT_STATUS_PROCESS_IS_TERMINATING},
- {"NT_STATUS_INVALID_LOGON_TYPE", NT_STATUS_INVALID_LOGON_TYPE},
- {"NT_STATUS_NO_GUID_TRANSLATION", NT_STATUS_NO_GUID_TRANSLATION},
- {"NT_STATUS_CANNOT_IMPERSONATE", NT_STATUS_CANNOT_IMPERSONATE},
- {"NT_STATUS_IMAGE_ALREADY_LOADED", NT_STATUS_IMAGE_ALREADY_LOADED},
- {"NT_STATUS_ABIOS_NOT_PRESENT", NT_STATUS_ABIOS_NOT_PRESENT},
- {"NT_STATUS_ABIOS_LID_NOT_EXIST", NT_STATUS_ABIOS_LID_NOT_EXIST},
- {"NT_STATUS_ABIOS_LID_ALREADY_OWNED",
- NT_STATUS_ABIOS_LID_ALREADY_OWNED},
- {"NT_STATUS_ABIOS_NOT_LID_OWNER", NT_STATUS_ABIOS_NOT_LID_OWNER},
- {"NT_STATUS_ABIOS_INVALID_COMMAND",
- NT_STATUS_ABIOS_INVALID_COMMAND},
- {"NT_STATUS_ABIOS_INVALID_LID", NT_STATUS_ABIOS_INVALID_LID},
- {"NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE",
- NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE},
- {"NT_STATUS_ABIOS_INVALID_SELECTOR",
- NT_STATUS_ABIOS_INVALID_SELECTOR},
- {"NT_STATUS_NO_LDT", NT_STATUS_NO_LDT},
- {"NT_STATUS_INVALID_LDT_SIZE", NT_STATUS_INVALID_LDT_SIZE},
- {"NT_STATUS_INVALID_LDT_OFFSET", NT_STATUS_INVALID_LDT_OFFSET},
- {"NT_STATUS_INVALID_LDT_DESCRIPTOR",
- NT_STATUS_INVALID_LDT_DESCRIPTOR},
- {"NT_STATUS_INVALID_IMAGE_NE_FORMAT",
- NT_STATUS_INVALID_IMAGE_NE_FORMAT},
- {"NT_STATUS_RXACT_INVALID_STATE", NT_STATUS_RXACT_INVALID_STATE},
- {"NT_STATUS_RXACT_COMMIT_FAILURE", NT_STATUS_RXACT_COMMIT_FAILURE},
- {"NT_STATUS_MAPPED_FILE_SIZE_ZERO",
- NT_STATUS_MAPPED_FILE_SIZE_ZERO},
- {"NT_STATUS_TOO_MANY_OPENED_FILES",
- NT_STATUS_TOO_MANY_OPENED_FILES},
- {"NT_STATUS_CANCELLED", NT_STATUS_CANCELLED},
- {"NT_STATUS_CANNOT_DELETE", NT_STATUS_CANNOT_DELETE},
- {"NT_STATUS_INVALID_COMPUTER_NAME",
- NT_STATUS_INVALID_COMPUTER_NAME},
- {"NT_STATUS_FILE_DELETED", NT_STATUS_FILE_DELETED},
- {"NT_STATUS_SPECIAL_ACCOUNT", NT_STATUS_SPECIAL_ACCOUNT},
- {"NT_STATUS_SPECIAL_GROUP", NT_STATUS_SPECIAL_GROUP},
- {"NT_STATUS_SPECIAL_USER", NT_STATUS_SPECIAL_USER},
- {"NT_STATUS_MEMBERS_PRIMARY_GROUP",
- NT_STATUS_MEMBERS_PRIMARY_GROUP},
- {"NT_STATUS_FILE_CLOSED", NT_STATUS_FILE_CLOSED},
- {"NT_STATUS_TOO_MANY_THREADS", NT_STATUS_TOO_MANY_THREADS},
- {"NT_STATUS_THREAD_NOT_IN_PROCESS",
- NT_STATUS_THREAD_NOT_IN_PROCESS},
- {"NT_STATUS_TOKEN_ALREADY_IN_USE", NT_STATUS_TOKEN_ALREADY_IN_USE},
- {"NT_STATUS_PAGEFILE_QUOTA_EXCEEDED",
- NT_STATUS_PAGEFILE_QUOTA_EXCEEDED},
- {"NT_STATUS_COMMITMENT_LIMIT", NT_STATUS_COMMITMENT_LIMIT},
- {"NT_STATUS_INVALID_IMAGE_LE_FORMAT",
- NT_STATUS_INVALID_IMAGE_LE_FORMAT},
- {"NT_STATUS_INVALID_IMAGE_NOT_MZ", NT_STATUS_INVALID_IMAGE_NOT_MZ},
- {"NT_STATUS_INVALID_IMAGE_PROTECT",
- NT_STATUS_INVALID_IMAGE_PROTECT},
- {"NT_STATUS_INVALID_IMAGE_WIN_16", NT_STATUS_INVALID_IMAGE_WIN_16},
- {"NT_STATUS_LOGON_SERVER_CONFLICT",
- NT_STATUS_LOGON_SERVER_CONFLICT},
- {"NT_STATUS_TIME_DIFFERENCE_AT_DC",
- NT_STATUS_TIME_DIFFERENCE_AT_DC},
- {"NT_STATUS_SYNCHRONIZATION_REQUIRED",
- NT_STATUS_SYNCHRONIZATION_REQUIRED},
- {"NT_STATUS_DLL_NOT_FOUND", NT_STATUS_DLL_NOT_FOUND},
- {"NT_STATUS_OPEN_FAILED", NT_STATUS_OPEN_FAILED},
- {"NT_STATUS_IO_PRIVILEGE_FAILED", NT_STATUS_IO_PRIVILEGE_FAILED},
- {"NT_STATUS_ORDINAL_NOT_FOUND", NT_STATUS_ORDINAL_NOT_FOUND},
- {"NT_STATUS_ENTRYPOINT_NOT_FOUND", NT_STATUS_ENTRYPOINT_NOT_FOUND},
- {"NT_STATUS_CONTROL_C_EXIT", NT_STATUS_CONTROL_C_EXIT},
- {"NT_STATUS_LOCAL_DISCONNECT", NT_STATUS_LOCAL_DISCONNECT},
- {"NT_STATUS_REMOTE_DISCONNECT", NT_STATUS_REMOTE_DISCONNECT},
- {"NT_STATUS_REMOTE_RESOURCES", NT_STATUS_REMOTE_RESOURCES},
- {"NT_STATUS_LINK_FAILED", NT_STATUS_LINK_FAILED},
- {"NT_STATUS_LINK_TIMEOUT", NT_STATUS_LINK_TIMEOUT},
- {"NT_STATUS_INVALID_CONNECTION", NT_STATUS_INVALID_CONNECTION},
- {"NT_STATUS_INVALID_ADDRESS", NT_STATUS_INVALID_ADDRESS},
- {"NT_STATUS_DLL_INIT_FAILED", NT_STATUS_DLL_INIT_FAILED},
- {"NT_STATUS_MISSING_SYSTEMFILE", NT_STATUS_MISSING_SYSTEMFILE},
- {"NT_STATUS_UNHANDLED_EXCEPTION", NT_STATUS_UNHANDLED_EXCEPTION},
- {"NT_STATUS_APP_INIT_FAILURE", NT_STATUS_APP_INIT_FAILURE},
- {"NT_STATUS_PAGEFILE_CREATE_FAILED",
- NT_STATUS_PAGEFILE_CREATE_FAILED},
- {"NT_STATUS_NO_PAGEFILE", NT_STATUS_NO_PAGEFILE},
- {"NT_STATUS_INVALID_LEVEL", NT_STATUS_INVALID_LEVEL},
- {"NT_STATUS_WRONG_PASSWORD_CORE", NT_STATUS_WRONG_PASSWORD_CORE},
- {"NT_STATUS_ILLEGAL_FLOAT_CONTEXT",
- NT_STATUS_ILLEGAL_FLOAT_CONTEXT},
- {"NT_STATUS_PIPE_BROKEN", NT_STATUS_PIPE_BROKEN},
- {"NT_STATUS_REGISTRY_CORRUPT", NT_STATUS_REGISTRY_CORRUPT},
- {"NT_STATUS_REGISTRY_IO_FAILED", NT_STATUS_REGISTRY_IO_FAILED},
- {"NT_STATUS_NO_EVENT_PAIR", NT_STATUS_NO_EVENT_PAIR},
- {"NT_STATUS_UNRECOGNIZED_VOLUME", NT_STATUS_UNRECOGNIZED_VOLUME},
- {"NT_STATUS_SERIAL_NO_DEVICE_INITED",
- NT_STATUS_SERIAL_NO_DEVICE_INITED},
- {"NT_STATUS_NO_SUCH_ALIAS", NT_STATUS_NO_SUCH_ALIAS},
- {"NT_STATUS_MEMBER_NOT_IN_ALIAS", NT_STATUS_MEMBER_NOT_IN_ALIAS},
- {"NT_STATUS_MEMBER_IN_ALIAS", NT_STATUS_MEMBER_IN_ALIAS},
- {"NT_STATUS_ALIAS_EXISTS", NT_STATUS_ALIAS_EXISTS},
- {"NT_STATUS_LOGON_NOT_GRANTED", NT_STATUS_LOGON_NOT_GRANTED},
- {"NT_STATUS_TOO_MANY_SECRETS", NT_STATUS_TOO_MANY_SECRETS},
- {"NT_STATUS_SECRET_TOO_LONG", NT_STATUS_SECRET_TOO_LONG},
- {"NT_STATUS_INTERNAL_DB_ERROR", NT_STATUS_INTERNAL_DB_ERROR},
- {"NT_STATUS_FULLSCREEN_MODE", NT_STATUS_FULLSCREEN_MODE},
- {"NT_STATUS_TOO_MANY_CONTEXT_IDS", NT_STATUS_TOO_MANY_CONTEXT_IDS},
- {"NT_STATUS_LOGON_TYPE_NOT_GRANTED",
- NT_STATUS_LOGON_TYPE_NOT_GRANTED},
- {"NT_STATUS_NOT_REGISTRY_FILE", NT_STATUS_NOT_REGISTRY_FILE},
- {"NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED",
- NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED},
- {"NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR",
- NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR},
- {"NT_STATUS_FT_MISSING_MEMBER", NT_STATUS_FT_MISSING_MEMBER},
- {"NT_STATUS_ILL_FORMED_SERVICE_ENTRY",
- NT_STATUS_ILL_FORMED_SERVICE_ENTRY},
- {"NT_STATUS_ILLEGAL_CHARACTER", NT_STATUS_ILLEGAL_CHARACTER},
- {"NT_STATUS_UNMAPPABLE_CHARACTER", NT_STATUS_UNMAPPABLE_CHARACTER},
- {"NT_STATUS_UNDEFINED_CHARACTER", NT_STATUS_UNDEFINED_CHARACTER},
- {"NT_STATUS_FLOPPY_VOLUME", NT_STATUS_FLOPPY_VOLUME},
- {"NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND",
- NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND},
- {"NT_STATUS_FLOPPY_WRONG_CYLINDER",
- NT_STATUS_FLOPPY_WRONG_CYLINDER},
- {"NT_STATUS_FLOPPY_UNKNOWN_ERROR", NT_STATUS_FLOPPY_UNKNOWN_ERROR},
- {"NT_STATUS_FLOPPY_BAD_REGISTERS", NT_STATUS_FLOPPY_BAD_REGISTERS},
- {"NT_STATUS_DISK_RECALIBRATE_FAILED",
- NT_STATUS_DISK_RECALIBRATE_FAILED},
- {"NT_STATUS_DISK_OPERATION_FAILED",
- NT_STATUS_DISK_OPERATION_FAILED},
- {"NT_STATUS_DISK_RESET_FAILED", NT_STATUS_DISK_RESET_FAILED},
- {"NT_STATUS_SHARED_IRQ_BUSY", NT_STATUS_SHARED_IRQ_BUSY},
- {"NT_STATUS_FT_ORPHANING", NT_STATUS_FT_ORPHANING},
- {"NT_STATUS_PARTITION_FAILURE", NT_STATUS_PARTITION_FAILURE},
- {"NT_STATUS_INVALID_BLOCK_LENGTH", NT_STATUS_INVALID_BLOCK_LENGTH},
- {"NT_STATUS_DEVICE_NOT_PARTITIONED",
- NT_STATUS_DEVICE_NOT_PARTITIONED},
- {"NT_STATUS_UNABLE_TO_LOCK_MEDIA", NT_STATUS_UNABLE_TO_LOCK_MEDIA},
- {"NT_STATUS_UNABLE_TO_UNLOAD_MEDIA",
- NT_STATUS_UNABLE_TO_UNLOAD_MEDIA},
- {"NT_STATUS_EOM_OVERFLOW", NT_STATUS_EOM_OVERFLOW},
- {"NT_STATUS_NO_MEDIA", NT_STATUS_NO_MEDIA},
- {"NT_STATUS_NO_SUCH_MEMBER", NT_STATUS_NO_SUCH_MEMBER},
- {"NT_STATUS_INVALID_MEMBER", NT_STATUS_INVALID_MEMBER},
- {"NT_STATUS_KEY_DELETED", NT_STATUS_KEY_DELETED},
- {"NT_STATUS_NO_LOG_SPACE", NT_STATUS_NO_LOG_SPACE},
- {"NT_STATUS_TOO_MANY_SIDS", NT_STATUS_TOO_MANY_SIDS},
- {"NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED",
- NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED},
- {"NT_STATUS_KEY_HAS_CHILDREN", NT_STATUS_KEY_HAS_CHILDREN},
- {"NT_STATUS_CHILD_MUST_BE_VOLATILE",
- NT_STATUS_CHILD_MUST_BE_VOLATILE},
- {"NT_STATUS_DEVICE_CONFIGURATION_ERROR",
- NT_STATUS_DEVICE_CONFIGURATION_ERROR},
- {"NT_STATUS_DRIVER_INTERNAL_ERROR",
- NT_STATUS_DRIVER_INTERNAL_ERROR},
- {"NT_STATUS_INVALID_DEVICE_STATE", NT_STATUS_INVALID_DEVICE_STATE},
- {"NT_STATUS_IO_DEVICE_ERROR", NT_STATUS_IO_DEVICE_ERROR},
- {"NT_STATUS_DEVICE_PROTOCOL_ERROR",
- NT_STATUS_DEVICE_PROTOCOL_ERROR},
- {"NT_STATUS_BACKUP_CONTROLLER", NT_STATUS_BACKUP_CONTROLLER},
- {"NT_STATUS_LOG_FILE_FULL", NT_STATUS_LOG_FILE_FULL},
- {"NT_STATUS_TOO_LATE", NT_STATUS_TOO_LATE},
- {"NT_STATUS_NO_TRUST_LSA_SECRET", NT_STATUS_NO_TRUST_LSA_SECRET},
- {"NT_STATUS_NO_TRUST_SAM_ACCOUNT", NT_STATUS_NO_TRUST_SAM_ACCOUNT},
- {"NT_STATUS_TRUSTED_DOMAIN_FAILURE",
- NT_STATUS_TRUSTED_DOMAIN_FAILURE},
- {"NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE",
- NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE},
- {"NT_STATUS_EVENTLOG_FILE_CORRUPT",
- NT_STATUS_EVENTLOG_FILE_CORRUPT},
- {"NT_STATUS_EVENTLOG_CANT_START", NT_STATUS_EVENTLOG_CANT_START},
- {"NT_STATUS_TRUST_FAILURE", NT_STATUS_TRUST_FAILURE},
- {"NT_STATUS_MUTANT_LIMIT_EXCEEDED",
- NT_STATUS_MUTANT_LIMIT_EXCEEDED},
- {"NT_STATUS_NETLOGON_NOT_STARTED", NT_STATUS_NETLOGON_NOT_STARTED},
- {"NT_STATUS_ACCOUNT_EXPIRED", NT_STATUS_ACCOUNT_EXPIRED},
- {"NT_STATUS_POSSIBLE_DEADLOCK", NT_STATUS_POSSIBLE_DEADLOCK},
- {"NT_STATUS_NETWORK_CREDENTIAL_CONFLICT",
- NT_STATUS_NETWORK_CREDENTIAL_CONFLICT},
- {"NT_STATUS_REMOTE_SESSION_LIMIT", NT_STATUS_REMOTE_SESSION_LIMIT},
- {"NT_STATUS_EVENTLOG_FILE_CHANGED",
- NT_STATUS_EVENTLOG_FILE_CHANGED},
- {"NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT",
- NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT},
- {"NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT",
- NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT},
- {"NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT",
- NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT},
- {"NT_STATUS_DOMAIN_TRUST_INCONSISTENT",
- NT_STATUS_DOMAIN_TRUST_INCONSISTENT},
- {"NT_STATUS_FS_DRIVER_REQUIRED", NT_STATUS_FS_DRIVER_REQUIRED},
- {"NT_STATUS_NO_USER_SESSION_KEY", NT_STATUS_NO_USER_SESSION_KEY},
- {"NT_STATUS_USER_SESSION_DELETED", NT_STATUS_USER_SESSION_DELETED},
- {"NT_STATUS_RESOURCE_LANG_NOT_FOUND",
- NT_STATUS_RESOURCE_LANG_NOT_FOUND},
- {"NT_STATUS_INSUFF_SERVER_RESOURCES",
- NT_STATUS_INSUFF_SERVER_RESOURCES},
- {"NT_STATUS_INVALID_BUFFER_SIZE", NT_STATUS_INVALID_BUFFER_SIZE},
- {"NT_STATUS_INVALID_ADDRESS_COMPONENT",
- NT_STATUS_INVALID_ADDRESS_COMPONENT},
- {"NT_STATUS_INVALID_ADDRESS_WILDCARD",
- NT_STATUS_INVALID_ADDRESS_WILDCARD},
- {"NT_STATUS_TOO_MANY_ADDRESSES", NT_STATUS_TOO_MANY_ADDRESSES},
- {"NT_STATUS_ADDRESS_ALREADY_EXISTS",
- NT_STATUS_ADDRESS_ALREADY_EXISTS},
- {"NT_STATUS_ADDRESS_CLOSED", NT_STATUS_ADDRESS_CLOSED},
- {"NT_STATUS_CONNECTION_DISCONNECTED",
- NT_STATUS_CONNECTION_DISCONNECTED},
- {"NT_STATUS_CONNECTION_RESET", NT_STATUS_CONNECTION_RESET},
- {"NT_STATUS_TOO_MANY_NODES", NT_STATUS_TOO_MANY_NODES},
- {"NT_STATUS_TRANSACTION_ABORTED", NT_STATUS_TRANSACTION_ABORTED},
- {"NT_STATUS_TRANSACTION_TIMED_OUT",
- NT_STATUS_TRANSACTION_TIMED_OUT},
- {"NT_STATUS_TRANSACTION_NO_RELEASE",
- NT_STATUS_TRANSACTION_NO_RELEASE},
- {"NT_STATUS_TRANSACTION_NO_MATCH", NT_STATUS_TRANSACTION_NO_MATCH},
- {"NT_STATUS_TRANSACTION_RESPONDED",
- NT_STATUS_TRANSACTION_RESPONDED},
- {"NT_STATUS_TRANSACTION_INVALID_ID",
- NT_STATUS_TRANSACTION_INVALID_ID},
- {"NT_STATUS_TRANSACTION_INVALID_TYPE",
- NT_STATUS_TRANSACTION_INVALID_TYPE},
- {"NT_STATUS_NOT_SERVER_SESSION", NT_STATUS_NOT_SERVER_SESSION},
- {"NT_STATUS_NOT_CLIENT_SESSION", NT_STATUS_NOT_CLIENT_SESSION},
- {"NT_STATUS_CANNOT_LOAD_REGISTRY_FILE",
- NT_STATUS_CANNOT_LOAD_REGISTRY_FILE},
- {"NT_STATUS_DEBUG_ATTACH_FAILED", NT_STATUS_DEBUG_ATTACH_FAILED},
- {"NT_STATUS_SYSTEM_PROCESS_TERMINATED",
- NT_STATUS_SYSTEM_PROCESS_TERMINATED},
- {"NT_STATUS_DATA_NOT_ACCEPTED", NT_STATUS_DATA_NOT_ACCEPTED},
- {"NT_STATUS_NO_BROWSER_SERVERS_FOUND",
- NT_STATUS_NO_BROWSER_SERVERS_FOUND},
- {"NT_STATUS_VDM_HARD_ERROR", NT_STATUS_VDM_HARD_ERROR},
- {"NT_STATUS_DRIVER_CANCEL_TIMEOUT",
- NT_STATUS_DRIVER_CANCEL_TIMEOUT},
- {"NT_STATUS_REPLY_MESSAGE_MISMATCH",
- NT_STATUS_REPLY_MESSAGE_MISMATCH},
- {"NT_STATUS_MAPPED_ALIGNMENT", NT_STATUS_MAPPED_ALIGNMENT},
- {"NT_STATUS_IMAGE_CHECKSUM_MISMATCH",
- NT_STATUS_IMAGE_CHECKSUM_MISMATCH},
- {"NT_STATUS_LOST_WRITEBEHIND_DATA",
- NT_STATUS_LOST_WRITEBEHIND_DATA},
- {"NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID",
- NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID},
- {"NT_STATUS_PASSWORD_MUST_CHANGE", NT_STATUS_PASSWORD_MUST_CHANGE},
- {"NT_STATUS_NOT_FOUND", NT_STATUS_NOT_FOUND},
- {"NT_STATUS_NOT_TINY_STREAM", NT_STATUS_NOT_TINY_STREAM},
- {"NT_STATUS_RECOVERY_FAILURE", NT_STATUS_RECOVERY_FAILURE},
- {"NT_STATUS_STACK_OVERFLOW_READ", NT_STATUS_STACK_OVERFLOW_READ},
- {"NT_STATUS_FAIL_CHECK", NT_STATUS_FAIL_CHECK},
- {"NT_STATUS_DUPLICATE_OBJECTID", NT_STATUS_DUPLICATE_OBJECTID},
- {"NT_STATUS_OBJECTID_EXISTS", NT_STATUS_OBJECTID_EXISTS},
- {"NT_STATUS_CONVERT_TO_LARGE", NT_STATUS_CONVERT_TO_LARGE},
- {"NT_STATUS_RETRY", NT_STATUS_RETRY},
- {"NT_STATUS_FOUND_OUT_OF_SCOPE", NT_STATUS_FOUND_OUT_OF_SCOPE},
- {"NT_STATUS_ALLOCATE_BUCKET", NT_STATUS_ALLOCATE_BUCKET},
- {"NT_STATUS_PROPSET_NOT_FOUND", NT_STATUS_PROPSET_NOT_FOUND},
- {"NT_STATUS_MARSHALL_OVERFLOW", NT_STATUS_MARSHALL_OVERFLOW},
- {"NT_STATUS_INVALID_VARIANT", NT_STATUS_INVALID_VARIANT},
- {"NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND",
- NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND},
- {"NT_STATUS_ACCOUNT_LOCKED_OUT", NT_STATUS_ACCOUNT_LOCKED_OUT},
- {"NT_STATUS_HANDLE_NOT_CLOSABLE", NT_STATUS_HANDLE_NOT_CLOSABLE},
- {"NT_STATUS_CONNECTION_REFUSED", NT_STATUS_CONNECTION_REFUSED},
- {"NT_STATUS_GRACEFUL_DISCONNECT", NT_STATUS_GRACEFUL_DISCONNECT},
- {"NT_STATUS_ADDRESS_ALREADY_ASSOCIATED",
- NT_STATUS_ADDRESS_ALREADY_ASSOCIATED},
- {"NT_STATUS_ADDRESS_NOT_ASSOCIATED",
- NT_STATUS_ADDRESS_NOT_ASSOCIATED},
- {"NT_STATUS_CONNECTION_INVALID", NT_STATUS_CONNECTION_INVALID},
- {"NT_STATUS_CONNECTION_ACTIVE", NT_STATUS_CONNECTION_ACTIVE},
- {"NT_STATUS_NETWORK_UNREACHABLE", NT_STATUS_NETWORK_UNREACHABLE},
- {"NT_STATUS_HOST_UNREACHABLE", NT_STATUS_HOST_UNREACHABLE},
- {"NT_STATUS_PROTOCOL_UNREACHABLE", NT_STATUS_PROTOCOL_UNREACHABLE},
- {"NT_STATUS_PORT_UNREACHABLE", NT_STATUS_PORT_UNREACHABLE},
- {"NT_STATUS_REQUEST_ABORTED", NT_STATUS_REQUEST_ABORTED},
- {"NT_STATUS_CONNECTION_ABORTED", NT_STATUS_CONNECTION_ABORTED},
- {"NT_STATUS_BAD_COMPRESSION_BUFFER",
- NT_STATUS_BAD_COMPRESSION_BUFFER},
- {"NT_STATUS_USER_MAPPED_FILE", NT_STATUS_USER_MAPPED_FILE},
- {"NT_STATUS_AUDIT_FAILED", NT_STATUS_AUDIT_FAILED},
- {"NT_STATUS_TIMER_RESOLUTION_NOT_SET",
- NT_STATUS_TIMER_RESOLUTION_NOT_SET},
- {"NT_STATUS_CONNECTION_COUNT_LIMIT",
- NT_STATUS_CONNECTION_COUNT_LIMIT},
- {"NT_STATUS_LOGIN_TIME_RESTRICTION",
- NT_STATUS_LOGIN_TIME_RESTRICTION},
- {"NT_STATUS_LOGIN_WKSTA_RESTRICTION",
- NT_STATUS_LOGIN_WKSTA_RESTRICTION},
- {"NT_STATUS_IMAGE_MP_UP_MISMATCH", NT_STATUS_IMAGE_MP_UP_MISMATCH},
- {"NT_STATUS_INSUFFICIENT_LOGON_INFO",
- NT_STATUS_INSUFFICIENT_LOGON_INFO},
- {"NT_STATUS_BAD_DLL_ENTRYPOINT", NT_STATUS_BAD_DLL_ENTRYPOINT},
- {"NT_STATUS_BAD_SERVICE_ENTRYPOINT",
- NT_STATUS_BAD_SERVICE_ENTRYPOINT},
- {"NT_STATUS_LPC_REPLY_LOST", NT_STATUS_LPC_REPLY_LOST},
- {"NT_STATUS_IP_ADDRESS_CONFLICT1", NT_STATUS_IP_ADDRESS_CONFLICT1},
- {"NT_STATUS_IP_ADDRESS_CONFLICT2", NT_STATUS_IP_ADDRESS_CONFLICT2},
- {"NT_STATUS_REGISTRY_QUOTA_LIMIT", NT_STATUS_REGISTRY_QUOTA_LIMIT},
- {"NT_STATUS_PATH_NOT_COVERED", NT_STATUS_PATH_NOT_COVERED},
- {"NT_STATUS_NO_CALLBACK_ACTIVE", NT_STATUS_NO_CALLBACK_ACTIVE},
- {"NT_STATUS_LICENSE_QUOTA_EXCEEDED",
- NT_STATUS_LICENSE_QUOTA_EXCEEDED},
- {"NT_STATUS_PWD_TOO_SHORT", NT_STATUS_PWD_TOO_SHORT},
- {"NT_STATUS_PWD_TOO_RECENT", NT_STATUS_PWD_TOO_RECENT},
- {"NT_STATUS_PWD_HISTORY_CONFLICT", NT_STATUS_PWD_HISTORY_CONFLICT},
- {"NT_STATUS_PLUGPLAY_NO_DEVICE", NT_STATUS_PLUGPLAY_NO_DEVICE},
- {"NT_STATUS_UNSUPPORTED_COMPRESSION",
- NT_STATUS_UNSUPPORTED_COMPRESSION},
- {"NT_STATUS_INVALID_HW_PROFILE", NT_STATUS_INVALID_HW_PROFILE},
- {"NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH",
- NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH},
- {"NT_STATUS_DRIVER_ORDINAL_NOT_FOUND",
- NT_STATUS_DRIVER_ORDINAL_NOT_FOUND},
- {"NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND",
- NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND},
- {"NT_STATUS_RESOURCE_NOT_OWNED", NT_STATUS_RESOURCE_NOT_OWNED},
- {"NT_STATUS_TOO_MANY_LINKS", NT_STATUS_TOO_MANY_LINKS},
- {"NT_STATUS_QUOTA_LIST_INCONSISTENT",
- NT_STATUS_QUOTA_LIST_INCONSISTENT},
- {"NT_STATUS_FILE_IS_OFFLINE", NT_STATUS_FILE_IS_OFFLINE},
- {"NT_STATUS_NO_MORE_ENTRIES", NT_STATUS_NO_MORE_ENTRIES},
- {"STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES},
- {"STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED},
- {NULL, 0}
-};
diff --git a/ANDROID_3.4.5/fs/cifs/nterr.h b/ANDROID_3.4.5/fs/cifs/nterr.h
deleted file mode 100644
index 25726736..00000000
--- a/ANDROID_3.4.5/fs/cifs/nterr.h
+++ /dev/null
@@ -1,561 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- NT error code constants
- Copyright (C) Andrew Tridgell 1992-2000
- Copyright (C) John H Terpstra 1996-2000
- Copyright (C) Luke Kenneth Casson Leighton 1996-2000
- Copyright (C) Paul Ashton 1998-2000
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-
-
-#ifndef _NTERR_H
-#define _NTERR_H
-
-struct nt_err_code_struct {
- char *nt_errstr;
- __u32 nt_errcode;
-};
-
-extern const struct nt_err_code_struct nt_errs[];
-
-/* Win32 Status codes. */
-#define STATUS_MORE_ENTRIES 0x0105
-#define ERROR_INVALID_PARAMETER 0x0057
-#define ERROR_INSUFFICIENT_BUFFER 0x007a
-#define STATUS_1804 0x070c
-#define STATUS_NOTIFY_ENUM_DIR 0x010c
-
-/* Win32 Error codes extracted using a loop in smbclient then printing a
- netmon sniff to a file. */
-
-#define NT_STATUS_OK 0x0000
-#define STATUS_SOME_UNMAPPED 0x0107
-#define STATUS_BUFFER_OVERFLOW 0x80000005
-#define NT_STATUS_NO_MORE_ENTRIES 0x8000001a
-#define NT_STATUS_MEDIA_CHANGED 0x8000001c
-#define NT_STATUS_END_OF_MEDIA 0x8000001e
-#define NT_STATUS_MEDIA_CHECK 0x80000020
-#define NT_STATUS_NO_DATA_DETECTED 0x8000001c
-#define NT_STATUS_STOPPED_ON_SYMLINK 0x8000002d
-#define NT_STATUS_DEVICE_REQUIRES_CLEANING 0x80000288
-#define NT_STATUS_DEVICE_DOOR_OPEN 0x80000288
-#define NT_STATUS_UNSUCCESSFUL 0xC0000000 | 0x0001
-#define NT_STATUS_NOT_IMPLEMENTED 0xC0000000 | 0x0002
-#define NT_STATUS_INVALID_INFO_CLASS 0xC0000000 | 0x0003
-#define NT_STATUS_INFO_LENGTH_MISMATCH 0xC0000000 | 0x0004
-#define NT_STATUS_ACCESS_VIOLATION 0xC0000000 | 0x0005
-#define NT_STATUS_IN_PAGE_ERROR 0xC0000000 | 0x0006
-#define NT_STATUS_PAGEFILE_QUOTA 0xC0000000 | 0x0007
-#define NT_STATUS_INVALID_HANDLE 0xC0000000 | 0x0008
-#define NT_STATUS_BAD_INITIAL_STACK 0xC0000000 | 0x0009
-#define NT_STATUS_BAD_INITIAL_PC 0xC0000000 | 0x000a
-#define NT_STATUS_INVALID_CID 0xC0000000 | 0x000b
-#define NT_STATUS_TIMER_NOT_CANCELED 0xC0000000 | 0x000c
-#define NT_STATUS_INVALID_PARAMETER 0xC0000000 | 0x000d
-#define NT_STATUS_NO_SUCH_DEVICE 0xC0000000 | 0x000e
-#define NT_STATUS_NO_SUCH_FILE 0xC0000000 | 0x000f
-#define NT_STATUS_INVALID_DEVICE_REQUEST 0xC0000000 | 0x0010
-#define NT_STATUS_END_OF_FILE 0xC0000000 | 0x0011
-#define NT_STATUS_WRONG_VOLUME 0xC0000000 | 0x0012
-#define NT_STATUS_NO_MEDIA_IN_DEVICE 0xC0000000 | 0x0013
-#define NT_STATUS_UNRECOGNIZED_MEDIA 0xC0000000 | 0x0014
-#define NT_STATUS_NONEXISTENT_SECTOR 0xC0000000 | 0x0015
-#define NT_STATUS_MORE_PROCESSING_REQUIRED 0xC0000000 | 0x0016
-#define NT_STATUS_NO_MEMORY 0xC0000000 | 0x0017
-#define NT_STATUS_CONFLICTING_ADDRESSES 0xC0000000 | 0x0018
-#define NT_STATUS_NOT_MAPPED_VIEW 0xC0000000 | 0x0019
-#define NT_STATUS_UNABLE_TO_FREE_VM 0x80000000 | 0x001a
-#define NT_STATUS_UNABLE_TO_DELETE_SECTION 0xC0000000 | 0x001b
-#define NT_STATUS_INVALID_SYSTEM_SERVICE 0xC0000000 | 0x001c
-#define NT_STATUS_ILLEGAL_INSTRUCTION 0xC0000000 | 0x001d
-#define NT_STATUS_INVALID_LOCK_SEQUENCE 0xC0000000 | 0x001e
-#define NT_STATUS_INVALID_VIEW_SIZE 0xC0000000 | 0x001f
-#define NT_STATUS_INVALID_FILE_FOR_SECTION 0xC0000000 | 0x0020
-#define NT_STATUS_ALREADY_COMMITTED 0xC0000000 | 0x0021
-#define NT_STATUS_ACCESS_DENIED 0xC0000000 | 0x0022
-#define NT_STATUS_BUFFER_TOO_SMALL 0xC0000000 | 0x0023
-#define NT_STATUS_OBJECT_TYPE_MISMATCH 0xC0000000 | 0x0024
-#define NT_STATUS_NONCONTINUABLE_EXCEPTION 0xC0000000 | 0x0025
-#define NT_STATUS_INVALID_DISPOSITION 0xC0000000 | 0x0026
-#define NT_STATUS_UNWIND 0xC0000000 | 0x0027
-#define NT_STATUS_BAD_STACK 0xC0000000 | 0x0028
-#define NT_STATUS_INVALID_UNWIND_TARGET 0xC0000000 | 0x0029
-#define NT_STATUS_NOT_LOCKED 0xC0000000 | 0x002a
-#define NT_STATUS_PARITY_ERROR 0xC0000000 | 0x002b
-#define NT_STATUS_UNABLE_TO_DECOMMIT_VM 0xC0000000 | 0x002c
-#define NT_STATUS_NOT_COMMITTED 0xC0000000 | 0x002d
-#define NT_STATUS_INVALID_PORT_ATTRIBUTES 0xC0000000 | 0x002e
-#define NT_STATUS_PORT_MESSAGE_TOO_LONG 0xC0000000 | 0x002f
-#define NT_STATUS_INVALID_PARAMETER_MIX 0xC0000000 | 0x0030
-#define NT_STATUS_INVALID_QUOTA_LOWER 0xC0000000 | 0x0031
-#define NT_STATUS_DISK_CORRUPT_ERROR 0xC0000000 | 0x0032
-#define NT_STATUS_OBJECT_NAME_INVALID 0xC0000000 | 0x0033
-#define NT_STATUS_OBJECT_NAME_NOT_FOUND 0xC0000000 | 0x0034
-#define NT_STATUS_OBJECT_NAME_COLLISION 0xC0000000 | 0x0035
-#define NT_STATUS_HANDLE_NOT_WAITABLE 0xC0000000 | 0x0036
-#define NT_STATUS_PORT_DISCONNECTED 0xC0000000 | 0x0037
-#define NT_STATUS_DEVICE_ALREADY_ATTACHED 0xC0000000 | 0x0038
-#define NT_STATUS_OBJECT_PATH_INVALID 0xC0000000 | 0x0039
-#define NT_STATUS_OBJECT_PATH_NOT_FOUND 0xC0000000 | 0x003a
-#define NT_STATUS_OBJECT_PATH_SYNTAX_BAD 0xC0000000 | 0x003b
-#define NT_STATUS_DATA_OVERRUN 0xC0000000 | 0x003c
-#define NT_STATUS_DATA_LATE_ERROR 0xC0000000 | 0x003d
-#define NT_STATUS_DATA_ERROR 0xC0000000 | 0x003e
-#define NT_STATUS_CRC_ERROR 0xC0000000 | 0x003f
-#define NT_STATUS_SECTION_TOO_BIG 0xC0000000 | 0x0040
-#define NT_STATUS_PORT_CONNECTION_REFUSED 0xC0000000 | 0x0041
-#define NT_STATUS_INVALID_PORT_HANDLE 0xC0000000 | 0x0042
-#define NT_STATUS_SHARING_VIOLATION 0xC0000000 | 0x0043
-#define NT_STATUS_QUOTA_EXCEEDED 0xC0000000 | 0x0044
-#define NT_STATUS_INVALID_PAGE_PROTECTION 0xC0000000 | 0x0045
-#define NT_STATUS_MUTANT_NOT_OWNED 0xC0000000 | 0x0046
-#define NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED 0xC0000000 | 0x0047
-#define NT_STATUS_PORT_ALREADY_SET 0xC0000000 | 0x0048
-#define NT_STATUS_SECTION_NOT_IMAGE 0xC0000000 | 0x0049
-#define NT_STATUS_SUSPEND_COUNT_EXCEEDED 0xC0000000 | 0x004a
-#define NT_STATUS_THREAD_IS_TERMINATING 0xC0000000 | 0x004b
-#define NT_STATUS_BAD_WORKING_SET_LIMIT 0xC0000000 | 0x004c
-#define NT_STATUS_INCOMPATIBLE_FILE_MAP 0xC0000000 | 0x004d
-#define NT_STATUS_SECTION_PROTECTION 0xC0000000 | 0x004e
-#define NT_STATUS_EAS_NOT_SUPPORTED 0xC0000000 | 0x004f
-#define NT_STATUS_EA_TOO_LARGE 0xC0000000 | 0x0050
-#define NT_STATUS_NONEXISTENT_EA_ENTRY 0xC0000000 | 0x0051
-#define NT_STATUS_NO_EAS_ON_FILE 0xC0000000 | 0x0052
-#define NT_STATUS_EA_CORRUPT_ERROR 0xC0000000 | 0x0053
-#define NT_STATUS_FILE_LOCK_CONFLICT 0xC0000000 | 0x0054
-#define NT_STATUS_LOCK_NOT_GRANTED 0xC0000000 | 0x0055
-#define NT_STATUS_DELETE_PENDING 0xC0000000 | 0x0056
-#define NT_STATUS_CTL_FILE_NOT_SUPPORTED 0xC0000000 | 0x0057
-#define NT_STATUS_UNKNOWN_REVISION 0xC0000000 | 0x0058
-#define NT_STATUS_REVISION_MISMATCH 0xC0000000 | 0x0059
-#define NT_STATUS_INVALID_OWNER 0xC0000000 | 0x005a
-#define NT_STATUS_INVALID_PRIMARY_GROUP 0xC0000000 | 0x005b
-#define NT_STATUS_NO_IMPERSONATION_TOKEN 0xC0000000 | 0x005c
-#define NT_STATUS_CANT_DISABLE_MANDATORY 0xC0000000 | 0x005d
-#define NT_STATUS_NO_LOGON_SERVERS 0xC0000000 | 0x005e
-#define NT_STATUS_NO_SUCH_LOGON_SESSION 0xC0000000 | 0x005f
-#define NT_STATUS_NO_SUCH_PRIVILEGE 0xC0000000 | 0x0060
-#define NT_STATUS_PRIVILEGE_NOT_HELD 0xC0000000 | 0x0061
-#define NT_STATUS_INVALID_ACCOUNT_NAME 0xC0000000 | 0x0062
-#define NT_STATUS_USER_EXISTS 0xC0000000 | 0x0063
-#define NT_STATUS_NO_SUCH_USER 0xC0000000 | 0x0064
-#define NT_STATUS_GROUP_EXISTS 0xC0000000 | 0x0065
-#define NT_STATUS_NO_SUCH_GROUP 0xC0000000 | 0x0066
-#define NT_STATUS_MEMBER_IN_GROUP 0xC0000000 | 0x0067
-#define NT_STATUS_MEMBER_NOT_IN_GROUP 0xC0000000 | 0x0068
-#define NT_STATUS_LAST_ADMIN 0xC0000000 | 0x0069
-#define NT_STATUS_WRONG_PASSWORD 0xC0000000 | 0x006a
-#define NT_STATUS_ILL_FORMED_PASSWORD 0xC0000000 | 0x006b
-#define NT_STATUS_PASSWORD_RESTRICTION 0xC0000000 | 0x006c
-#define NT_STATUS_LOGON_FAILURE 0xC0000000 | 0x006d
-#define NT_STATUS_ACCOUNT_RESTRICTION 0xC0000000 | 0x006e
-#define NT_STATUS_INVALID_LOGON_HOURS 0xC0000000 | 0x006f
-#define NT_STATUS_INVALID_WORKSTATION 0xC0000000 | 0x0070
-#define NT_STATUS_PASSWORD_EXPIRED 0xC0000000 | 0x0071
-#define NT_STATUS_ACCOUNT_DISABLED 0xC0000000 | 0x0072
-#define NT_STATUS_NONE_MAPPED 0xC0000000 | 0x0073
-#define NT_STATUS_TOO_MANY_LUIDS_REQUESTED 0xC0000000 | 0x0074
-#define NT_STATUS_LUIDS_EXHAUSTED 0xC0000000 | 0x0075
-#define NT_STATUS_INVALID_SUB_AUTHORITY 0xC0000000 | 0x0076
-#define NT_STATUS_INVALID_ACL 0xC0000000 | 0x0077
-#define NT_STATUS_INVALID_SID 0xC0000000 | 0x0078
-#define NT_STATUS_INVALID_SECURITY_DESCR 0xC0000000 | 0x0079
-#define NT_STATUS_PROCEDURE_NOT_FOUND 0xC0000000 | 0x007a
-#define NT_STATUS_INVALID_IMAGE_FORMAT 0xC0000000 | 0x007b
-#define NT_STATUS_NO_TOKEN 0xC0000000 | 0x007c
-#define NT_STATUS_BAD_INHERITANCE_ACL 0xC0000000 | 0x007d
-#define NT_STATUS_RANGE_NOT_LOCKED 0xC0000000 | 0x007e
-#define NT_STATUS_DISK_FULL 0xC0000000 | 0x007f
-#define NT_STATUS_SERVER_DISABLED 0xC0000000 | 0x0080
-#define NT_STATUS_SERVER_NOT_DISABLED 0xC0000000 | 0x0081
-#define NT_STATUS_TOO_MANY_GUIDS_REQUESTED 0xC0000000 | 0x0082
-#define NT_STATUS_GUIDS_EXHAUSTED 0xC0000000 | 0x0083
-#define NT_STATUS_INVALID_ID_AUTHORITY 0xC0000000 | 0x0084
-#define NT_STATUS_AGENTS_EXHAUSTED 0xC0000000 | 0x0085
-#define NT_STATUS_INVALID_VOLUME_LABEL 0xC0000000 | 0x0086
-#define NT_STATUS_SECTION_NOT_EXTENDED 0xC0000000 | 0x0087
-#define NT_STATUS_NOT_MAPPED_DATA 0xC0000000 | 0x0088
-#define NT_STATUS_RESOURCE_DATA_NOT_FOUND 0xC0000000 | 0x0089
-#define NT_STATUS_RESOURCE_TYPE_NOT_FOUND 0xC0000000 | 0x008a
-#define NT_STATUS_RESOURCE_NAME_NOT_FOUND 0xC0000000 | 0x008b
-#define NT_STATUS_ARRAY_BOUNDS_EXCEEDED 0xC0000000 | 0x008c
-#define NT_STATUS_FLOAT_DENORMAL_OPERAND 0xC0000000 | 0x008d
-#define NT_STATUS_FLOAT_DIVIDE_BY_ZERO 0xC0000000 | 0x008e
-#define NT_STATUS_FLOAT_INEXACT_RESULT 0xC0000000 | 0x008f
-#define NT_STATUS_FLOAT_INVALID_OPERATION 0xC0000000 | 0x0090
-#define NT_STATUS_FLOAT_OVERFLOW 0xC0000000 | 0x0091
-#define NT_STATUS_FLOAT_STACK_CHECK 0xC0000000 | 0x0092
-#define NT_STATUS_FLOAT_UNDERFLOW 0xC0000000 | 0x0093
-#define NT_STATUS_INTEGER_DIVIDE_BY_ZERO 0xC0000000 | 0x0094
-#define NT_STATUS_INTEGER_OVERFLOW 0xC0000000 | 0x0095
-#define NT_STATUS_PRIVILEGED_INSTRUCTION 0xC0000000 | 0x0096
-#define NT_STATUS_TOO_MANY_PAGING_FILES 0xC0000000 | 0x0097
-#define NT_STATUS_FILE_INVALID 0xC0000000 | 0x0098
-#define NT_STATUS_ALLOTTED_SPACE_EXCEEDED 0xC0000000 | 0x0099
-#define NT_STATUS_INSUFFICIENT_RESOURCES 0xC0000000 | 0x009a
-#define NT_STATUS_DFS_EXIT_PATH_FOUND 0xC0000000 | 0x009b
-#define NT_STATUS_DEVICE_DATA_ERROR 0xC0000000 | 0x009c
-#define NT_STATUS_DEVICE_NOT_CONNECTED 0xC0000000 | 0x009d
-#define NT_STATUS_DEVICE_POWER_FAILURE 0xC0000000 | 0x009e
-#define NT_STATUS_FREE_VM_NOT_AT_BASE 0xC0000000 | 0x009f
-#define NT_STATUS_MEMORY_NOT_ALLOCATED 0xC0000000 | 0x00a0
-#define NT_STATUS_WORKING_SET_QUOTA 0xC0000000 | 0x00a1
-#define NT_STATUS_MEDIA_WRITE_PROTECTED 0xC0000000 | 0x00a2
-#define NT_STATUS_DEVICE_NOT_READY 0xC0000000 | 0x00a3
-#define NT_STATUS_INVALID_GROUP_ATTRIBUTES 0xC0000000 | 0x00a4
-#define NT_STATUS_BAD_IMPERSONATION_LEVEL 0xC0000000 | 0x00a5
-#define NT_STATUS_CANT_OPEN_ANONYMOUS 0xC0000000 | 0x00a6
-#define NT_STATUS_BAD_VALIDATION_CLASS 0xC0000000 | 0x00a7
-#define NT_STATUS_BAD_TOKEN_TYPE 0xC0000000 | 0x00a8
-#define NT_STATUS_BAD_MASTER_BOOT_RECORD 0xC0000000 | 0x00a9
-#define NT_STATUS_INSTRUCTION_MISALIGNMENT 0xC0000000 | 0x00aa
-#define NT_STATUS_INSTANCE_NOT_AVAILABLE 0xC0000000 | 0x00ab
-#define NT_STATUS_PIPE_NOT_AVAILABLE 0xC0000000 | 0x00ac
-#define NT_STATUS_INVALID_PIPE_STATE 0xC0000000 | 0x00ad
-#define NT_STATUS_PIPE_BUSY 0xC0000000 | 0x00ae
-#define NT_STATUS_ILLEGAL_FUNCTION 0xC0000000 | 0x00af
-#define NT_STATUS_PIPE_DISCONNECTED 0xC0000000 | 0x00b0
-#define NT_STATUS_PIPE_CLOSING 0xC0000000 | 0x00b1
-#define NT_STATUS_PIPE_CONNECTED 0xC0000000 | 0x00b2
-#define NT_STATUS_PIPE_LISTENING 0xC0000000 | 0x00b3
-#define NT_STATUS_INVALID_READ_MODE 0xC0000000 | 0x00b4
-#define NT_STATUS_IO_TIMEOUT 0xC0000000 | 0x00b5
-#define NT_STATUS_FILE_FORCED_CLOSED 0xC0000000 | 0x00b6
-#define NT_STATUS_PROFILING_NOT_STARTED 0xC0000000 | 0x00b7
-#define NT_STATUS_PROFILING_NOT_STOPPED 0xC0000000 | 0x00b8
-#define NT_STATUS_COULD_NOT_INTERPRET 0xC0000000 | 0x00b9
-#define NT_STATUS_FILE_IS_A_DIRECTORY 0xC0000000 | 0x00ba
-#define NT_STATUS_NOT_SUPPORTED 0xC0000000 | 0x00bb
-#define NT_STATUS_REMOTE_NOT_LISTENING 0xC0000000 | 0x00bc
-#define NT_STATUS_DUPLICATE_NAME 0xC0000000 | 0x00bd
-#define NT_STATUS_BAD_NETWORK_PATH 0xC0000000 | 0x00be
-#define NT_STATUS_NETWORK_BUSY 0xC0000000 | 0x00bf
-#define NT_STATUS_DEVICE_DOES_NOT_EXIST 0xC0000000 | 0x00c0
-#define NT_STATUS_TOO_MANY_COMMANDS 0xC0000000 | 0x00c1
-#define NT_STATUS_ADAPTER_HARDWARE_ERROR 0xC0000000 | 0x00c2
-#define NT_STATUS_INVALID_NETWORK_RESPONSE 0xC0000000 | 0x00c3
-#define NT_STATUS_UNEXPECTED_NETWORK_ERROR 0xC0000000 | 0x00c4
-#define NT_STATUS_BAD_REMOTE_ADAPTER 0xC0000000 | 0x00c5
-#define NT_STATUS_PRINT_QUEUE_FULL 0xC0000000 | 0x00c6
-#define NT_STATUS_NO_SPOOL_SPACE 0xC0000000 | 0x00c7
-#define NT_STATUS_PRINT_CANCELLED 0xC0000000 | 0x00c8
-#define NT_STATUS_NETWORK_NAME_DELETED 0xC0000000 | 0x00c9
-#define NT_STATUS_NETWORK_ACCESS_DENIED 0xC0000000 | 0x00ca
-#define NT_STATUS_BAD_DEVICE_TYPE 0xC0000000 | 0x00cb
-#define NT_STATUS_BAD_NETWORK_NAME 0xC0000000 | 0x00cc
-#define NT_STATUS_TOO_MANY_NAMES 0xC0000000 | 0x00cd
-#define NT_STATUS_TOO_MANY_SESSIONS 0xC0000000 | 0x00ce
-#define NT_STATUS_SHARING_PAUSED 0xC0000000 | 0x00cf
-#define NT_STATUS_REQUEST_NOT_ACCEPTED 0xC0000000 | 0x00d0
-#define NT_STATUS_REDIRECTOR_PAUSED 0xC0000000 | 0x00d1
-#define NT_STATUS_NET_WRITE_FAULT 0xC0000000 | 0x00d2
-#define NT_STATUS_PROFILING_AT_LIMIT 0xC0000000 | 0x00d3
-#define NT_STATUS_NOT_SAME_DEVICE 0xC0000000 | 0x00d4
-#define NT_STATUS_FILE_RENAMED 0xC0000000 | 0x00d5
-#define NT_STATUS_VIRTUAL_CIRCUIT_CLOSED 0xC0000000 | 0x00d6
-#define NT_STATUS_NO_SECURITY_ON_OBJECT 0xC0000000 | 0x00d7
-#define NT_STATUS_CANT_WAIT 0xC0000000 | 0x00d8
-#define NT_STATUS_PIPE_EMPTY 0xC0000000 | 0x00d9
-#define NT_STATUS_CANT_ACCESS_DOMAIN_INFO 0xC0000000 | 0x00da
-#define NT_STATUS_CANT_TERMINATE_SELF 0xC0000000 | 0x00db
-#define NT_STATUS_INVALID_SERVER_STATE 0xC0000000 | 0x00dc
-#define NT_STATUS_INVALID_DOMAIN_STATE 0xC0000000 | 0x00dd
-#define NT_STATUS_INVALID_DOMAIN_ROLE 0xC0000000 | 0x00de
-#define NT_STATUS_NO_SUCH_DOMAIN 0xC0000000 | 0x00df
-#define NT_STATUS_DOMAIN_EXISTS 0xC0000000 | 0x00e0
-#define NT_STATUS_DOMAIN_LIMIT_EXCEEDED 0xC0000000 | 0x00e1
-#define NT_STATUS_OPLOCK_NOT_GRANTED 0xC0000000 | 0x00e2
-#define NT_STATUS_INVALID_OPLOCK_PROTOCOL 0xC0000000 | 0x00e3
-#define NT_STATUS_INTERNAL_DB_CORRUPTION 0xC0000000 | 0x00e4
-#define NT_STATUS_INTERNAL_ERROR 0xC0000000 | 0x00e5
-#define NT_STATUS_GENERIC_NOT_MAPPED 0xC0000000 | 0x00e6
-#define NT_STATUS_BAD_DESCRIPTOR_FORMAT 0xC0000000 | 0x00e7
-#define NT_STATUS_INVALID_USER_BUFFER 0xC0000000 | 0x00e8
-#define NT_STATUS_UNEXPECTED_IO_ERROR 0xC0000000 | 0x00e9
-#define NT_STATUS_UNEXPECTED_MM_CREATE_ERR 0xC0000000 | 0x00ea
-#define NT_STATUS_UNEXPECTED_MM_MAP_ERROR 0xC0000000 | 0x00eb
-#define NT_STATUS_UNEXPECTED_MM_EXTEND_ERR 0xC0000000 | 0x00ec
-#define NT_STATUS_NOT_LOGON_PROCESS 0xC0000000 | 0x00ed
-#define NT_STATUS_LOGON_SESSION_EXISTS 0xC0000000 | 0x00ee
-#define NT_STATUS_INVALID_PARAMETER_1 0xC0000000 | 0x00ef
-#define NT_STATUS_INVALID_PARAMETER_2 0xC0000000 | 0x00f0
-#define NT_STATUS_INVALID_PARAMETER_3 0xC0000000 | 0x00f1
-#define NT_STATUS_INVALID_PARAMETER_4 0xC0000000 | 0x00f2
-#define NT_STATUS_INVALID_PARAMETER_5 0xC0000000 | 0x00f3
-#define NT_STATUS_INVALID_PARAMETER_6 0xC0000000 | 0x00f4
-#define NT_STATUS_INVALID_PARAMETER_7 0xC0000000 | 0x00f5
-#define NT_STATUS_INVALID_PARAMETER_8 0xC0000000 | 0x00f6
-#define NT_STATUS_INVALID_PARAMETER_9 0xC0000000 | 0x00f7
-#define NT_STATUS_INVALID_PARAMETER_10 0xC0000000 | 0x00f8
-#define NT_STATUS_INVALID_PARAMETER_11 0xC0000000 | 0x00f9
-#define NT_STATUS_INVALID_PARAMETER_12 0xC0000000 | 0x00fa
-#define NT_STATUS_REDIRECTOR_NOT_STARTED 0xC0000000 | 0x00fb
-#define NT_STATUS_REDIRECTOR_STARTED 0xC0000000 | 0x00fc
-#define NT_STATUS_STACK_OVERFLOW 0xC0000000 | 0x00fd
-#define NT_STATUS_NO_SUCH_PACKAGE 0xC0000000 | 0x00fe
-#define NT_STATUS_BAD_FUNCTION_TABLE 0xC0000000 | 0x00ff
-#define NT_STATUS_DIRECTORY_NOT_EMPTY 0xC0000000 | 0x0101
-#define NT_STATUS_FILE_CORRUPT_ERROR 0xC0000000 | 0x0102
-#define NT_STATUS_NOT_A_DIRECTORY 0xC0000000 | 0x0103
-#define NT_STATUS_BAD_LOGON_SESSION_STATE 0xC0000000 | 0x0104
-#define NT_STATUS_LOGON_SESSION_COLLISION 0xC0000000 | 0x0105
-#define NT_STATUS_NAME_TOO_LONG 0xC0000000 | 0x0106
-#define NT_STATUS_FILES_OPEN 0xC0000000 | 0x0107
-#define NT_STATUS_CONNECTION_IN_USE 0xC0000000 | 0x0108
-#define NT_STATUS_MESSAGE_NOT_FOUND 0xC0000000 | 0x0109
-#define NT_STATUS_PROCESS_IS_TERMINATING 0xC0000000 | 0x010a
-#define NT_STATUS_INVALID_LOGON_TYPE 0xC0000000 | 0x010b
-#define NT_STATUS_NO_GUID_TRANSLATION 0xC0000000 | 0x010c
-#define NT_STATUS_CANNOT_IMPERSONATE 0xC0000000 | 0x010d
-#define NT_STATUS_IMAGE_ALREADY_LOADED 0xC0000000 | 0x010e
-#define NT_STATUS_ABIOS_NOT_PRESENT 0xC0000000 | 0x010f
-#define NT_STATUS_ABIOS_LID_NOT_EXIST 0xC0000000 | 0x0110
-#define NT_STATUS_ABIOS_LID_ALREADY_OWNED 0xC0000000 | 0x0111
-#define NT_STATUS_ABIOS_NOT_LID_OWNER 0xC0000000 | 0x0112
-#define NT_STATUS_ABIOS_INVALID_COMMAND 0xC0000000 | 0x0113
-#define NT_STATUS_ABIOS_INVALID_LID 0xC0000000 | 0x0114
-#define NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE 0xC0000000 | 0x0115
-#define NT_STATUS_ABIOS_INVALID_SELECTOR 0xC0000000 | 0x0116
-#define NT_STATUS_NO_LDT 0xC0000000 | 0x0117
-#define NT_STATUS_INVALID_LDT_SIZE 0xC0000000 | 0x0118
-#define NT_STATUS_INVALID_LDT_OFFSET 0xC0000000 | 0x0119
-#define NT_STATUS_INVALID_LDT_DESCRIPTOR 0xC0000000 | 0x011a
-#define NT_STATUS_INVALID_IMAGE_NE_FORMAT 0xC0000000 | 0x011b
-#define NT_STATUS_RXACT_INVALID_STATE 0xC0000000 | 0x011c
-#define NT_STATUS_RXACT_COMMIT_FAILURE 0xC0000000 | 0x011d
-#define NT_STATUS_MAPPED_FILE_SIZE_ZERO 0xC0000000 | 0x011e
-#define NT_STATUS_TOO_MANY_OPENED_FILES 0xC0000000 | 0x011f
-#define NT_STATUS_CANCELLED 0xC0000000 | 0x0120
-#define NT_STATUS_CANNOT_DELETE 0xC0000000 | 0x0121
-#define NT_STATUS_INVALID_COMPUTER_NAME 0xC0000000 | 0x0122
-#define NT_STATUS_FILE_DELETED 0xC0000000 | 0x0123
-#define NT_STATUS_SPECIAL_ACCOUNT 0xC0000000 | 0x0124
-#define NT_STATUS_SPECIAL_GROUP 0xC0000000 | 0x0125
-#define NT_STATUS_SPECIAL_USER 0xC0000000 | 0x0126
-#define NT_STATUS_MEMBERS_PRIMARY_GROUP 0xC0000000 | 0x0127
-#define NT_STATUS_FILE_CLOSED 0xC0000000 | 0x0128
-#define NT_STATUS_TOO_MANY_THREADS 0xC0000000 | 0x0129
-#define NT_STATUS_THREAD_NOT_IN_PROCESS 0xC0000000 | 0x012a
-#define NT_STATUS_TOKEN_ALREADY_IN_USE 0xC0000000 | 0x012b
-#define NT_STATUS_PAGEFILE_QUOTA_EXCEEDED 0xC0000000 | 0x012c
-#define NT_STATUS_COMMITMENT_LIMIT 0xC0000000 | 0x012d
-#define NT_STATUS_INVALID_IMAGE_LE_FORMAT 0xC0000000 | 0x012e
-#define NT_STATUS_INVALID_IMAGE_NOT_MZ 0xC0000000 | 0x012f
-#define NT_STATUS_INVALID_IMAGE_PROTECT 0xC0000000 | 0x0130
-#define NT_STATUS_INVALID_IMAGE_WIN_16 0xC0000000 | 0x0131
-#define NT_STATUS_LOGON_SERVER_CONFLICT 0xC0000000 | 0x0132
-#define NT_STATUS_TIME_DIFFERENCE_AT_DC 0xC0000000 | 0x0133
-#define NT_STATUS_SYNCHRONIZATION_REQUIRED 0xC0000000 | 0x0134
-#define NT_STATUS_DLL_NOT_FOUND 0xC0000000 | 0x0135
-#define NT_STATUS_OPEN_FAILED 0xC0000000 | 0x0136
-#define NT_STATUS_IO_PRIVILEGE_FAILED 0xC0000000 | 0x0137
-#define NT_STATUS_ORDINAL_NOT_FOUND 0xC0000000 | 0x0138
-#define NT_STATUS_ENTRYPOINT_NOT_FOUND 0xC0000000 | 0x0139
-#define NT_STATUS_CONTROL_C_EXIT 0xC0000000 | 0x013a
-#define NT_STATUS_LOCAL_DISCONNECT 0xC0000000 | 0x013b
-#define NT_STATUS_REMOTE_DISCONNECT 0xC0000000 | 0x013c
-#define NT_STATUS_REMOTE_RESOURCES 0xC0000000 | 0x013d
-#define NT_STATUS_LINK_FAILED 0xC0000000 | 0x013e
-#define NT_STATUS_LINK_TIMEOUT 0xC0000000 | 0x013f
-#define NT_STATUS_INVALID_CONNECTION 0xC0000000 | 0x0140
-#define NT_STATUS_INVALID_ADDRESS 0xC0000000 | 0x0141
-#define NT_STATUS_DLL_INIT_FAILED 0xC0000000 | 0x0142
-#define NT_STATUS_MISSING_SYSTEMFILE 0xC0000000 | 0x0143
-#define NT_STATUS_UNHANDLED_EXCEPTION 0xC0000000 | 0x0144
-#define NT_STATUS_APP_INIT_FAILURE 0xC0000000 | 0x0145
-#define NT_STATUS_PAGEFILE_CREATE_FAILED 0xC0000000 | 0x0146
-#define NT_STATUS_NO_PAGEFILE 0xC0000000 | 0x0147
-#define NT_STATUS_INVALID_LEVEL 0xC0000000 | 0x0148
-#define NT_STATUS_WRONG_PASSWORD_CORE 0xC0000000 | 0x0149
-#define NT_STATUS_ILLEGAL_FLOAT_CONTEXT 0xC0000000 | 0x014a
-#define NT_STATUS_PIPE_BROKEN 0xC0000000 | 0x014b
-#define NT_STATUS_REGISTRY_CORRUPT 0xC0000000 | 0x014c
-#define NT_STATUS_REGISTRY_IO_FAILED 0xC0000000 | 0x014d
-#define NT_STATUS_NO_EVENT_PAIR 0xC0000000 | 0x014e
-#define NT_STATUS_UNRECOGNIZED_VOLUME 0xC0000000 | 0x014f
-#define NT_STATUS_SERIAL_NO_DEVICE_INITED 0xC0000000 | 0x0150
-#define NT_STATUS_NO_SUCH_ALIAS 0xC0000000 | 0x0151
-#define NT_STATUS_MEMBER_NOT_IN_ALIAS 0xC0000000 | 0x0152
-#define NT_STATUS_MEMBER_IN_ALIAS 0xC0000000 | 0x0153
-#define NT_STATUS_ALIAS_EXISTS 0xC0000000 | 0x0154
-#define NT_STATUS_LOGON_NOT_GRANTED 0xC0000000 | 0x0155
-#define NT_STATUS_TOO_MANY_SECRETS 0xC0000000 | 0x0156
-#define NT_STATUS_SECRET_TOO_LONG 0xC0000000 | 0x0157
-#define NT_STATUS_INTERNAL_DB_ERROR 0xC0000000 | 0x0158
-#define NT_STATUS_FULLSCREEN_MODE 0xC0000000 | 0x0159
-#define NT_STATUS_TOO_MANY_CONTEXT_IDS 0xC0000000 | 0x015a
-#define NT_STATUS_LOGON_TYPE_NOT_GRANTED 0xC0000000 | 0x015b
-#define NT_STATUS_NOT_REGISTRY_FILE 0xC0000000 | 0x015c
-#define NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED 0xC0000000 | 0x015d
-#define NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR 0xC0000000 | 0x015e
-#define NT_STATUS_FT_MISSING_MEMBER 0xC0000000 | 0x015f
-#define NT_STATUS_ILL_FORMED_SERVICE_ENTRY 0xC0000000 | 0x0160
-#define NT_STATUS_ILLEGAL_CHARACTER 0xC0000000 | 0x0161
-#define NT_STATUS_UNMAPPABLE_CHARACTER 0xC0000000 | 0x0162
-#define NT_STATUS_UNDEFINED_CHARACTER 0xC0000000 | 0x0163
-#define NT_STATUS_FLOPPY_VOLUME 0xC0000000 | 0x0164
-#define NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND 0xC0000000 | 0x0165
-#define NT_STATUS_FLOPPY_WRONG_CYLINDER 0xC0000000 | 0x0166
-#define NT_STATUS_FLOPPY_UNKNOWN_ERROR 0xC0000000 | 0x0167
-#define NT_STATUS_FLOPPY_BAD_REGISTERS 0xC0000000 | 0x0168
-#define NT_STATUS_DISK_RECALIBRATE_FAILED 0xC0000000 | 0x0169
-#define NT_STATUS_DISK_OPERATION_FAILED 0xC0000000 | 0x016a
-#define NT_STATUS_DISK_RESET_FAILED 0xC0000000 | 0x016b
-#define NT_STATUS_SHARED_IRQ_BUSY 0xC0000000 | 0x016c
-#define NT_STATUS_FT_ORPHANING 0xC0000000 | 0x016d
-#define NT_STATUS_PARTITION_FAILURE 0xC0000000 | 0x0172
-#define NT_STATUS_INVALID_BLOCK_LENGTH 0xC0000000 | 0x0173
-#define NT_STATUS_DEVICE_NOT_PARTITIONED 0xC0000000 | 0x0174
-#define NT_STATUS_UNABLE_TO_LOCK_MEDIA 0xC0000000 | 0x0175
-#define NT_STATUS_UNABLE_TO_UNLOAD_MEDIA 0xC0000000 | 0x0176
-#define NT_STATUS_EOM_OVERFLOW 0xC0000000 | 0x0177
-#define NT_STATUS_NO_MEDIA 0xC0000000 | 0x0178
-#define NT_STATUS_NO_SUCH_MEMBER 0xC0000000 | 0x017a
-#define NT_STATUS_INVALID_MEMBER 0xC0000000 | 0x017b
-#define NT_STATUS_KEY_DELETED 0xC0000000 | 0x017c
-#define NT_STATUS_NO_LOG_SPACE 0xC0000000 | 0x017d
-#define NT_STATUS_TOO_MANY_SIDS 0xC0000000 | 0x017e
-#define NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED 0xC0000000 | 0x017f
-#define NT_STATUS_KEY_HAS_CHILDREN 0xC0000000 | 0x0180
-#define NT_STATUS_CHILD_MUST_BE_VOLATILE 0xC0000000 | 0x0181
-#define NT_STATUS_DEVICE_CONFIGURATION_ERROR 0xC0000000 | 0x0182
-#define NT_STATUS_DRIVER_INTERNAL_ERROR 0xC0000000 | 0x0183
-#define NT_STATUS_INVALID_DEVICE_STATE 0xC0000000 | 0x0184
-#define NT_STATUS_IO_DEVICE_ERROR 0xC0000000 | 0x0185
-#define NT_STATUS_DEVICE_PROTOCOL_ERROR 0xC0000000 | 0x0186
-#define NT_STATUS_BACKUP_CONTROLLER 0xC0000000 | 0x0187
-#define NT_STATUS_LOG_FILE_FULL 0xC0000000 | 0x0188
-#define NT_STATUS_TOO_LATE 0xC0000000 | 0x0189
-#define NT_STATUS_NO_TRUST_LSA_SECRET 0xC0000000 | 0x018a
-#define NT_STATUS_NO_TRUST_SAM_ACCOUNT 0xC0000000 | 0x018b
-#define NT_STATUS_TRUSTED_DOMAIN_FAILURE 0xC0000000 | 0x018c
-#define NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE 0xC0000000 | 0x018d
-#define NT_STATUS_EVENTLOG_FILE_CORRUPT 0xC0000000 | 0x018e
-#define NT_STATUS_EVENTLOG_CANT_START 0xC0000000 | 0x018f
-#define NT_STATUS_TRUST_FAILURE 0xC0000000 | 0x0190
-#define NT_STATUS_MUTANT_LIMIT_EXCEEDED 0xC0000000 | 0x0191
-#define NT_STATUS_NETLOGON_NOT_STARTED 0xC0000000 | 0x0192
-#define NT_STATUS_ACCOUNT_EXPIRED 0xC0000000 | 0x0193
-#define NT_STATUS_POSSIBLE_DEADLOCK 0xC0000000 | 0x0194
-#define NT_STATUS_NETWORK_CREDENTIAL_CONFLICT 0xC0000000 | 0x0195
-#define NT_STATUS_REMOTE_SESSION_LIMIT 0xC0000000 | 0x0196
-#define NT_STATUS_EVENTLOG_FILE_CHANGED 0xC0000000 | 0x0197
-#define NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT 0xC0000000 | 0x0198
-#define NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT 0xC0000000 | 0x0199
-#define NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT 0xC0000000 | 0x019a
-#define NT_STATUS_DOMAIN_TRUST_INCONSISTENT 0xC0000000 | 0x019b
-#define NT_STATUS_FS_DRIVER_REQUIRED 0xC0000000 | 0x019c
-#define NT_STATUS_NO_USER_SESSION_KEY 0xC0000000 | 0x0202
-#define NT_STATUS_USER_SESSION_DELETED 0xC0000000 | 0x0203
-#define NT_STATUS_RESOURCE_LANG_NOT_FOUND 0xC0000000 | 0x0204
-#define NT_STATUS_INSUFF_SERVER_RESOURCES 0xC0000000 | 0x0205
-#define NT_STATUS_INVALID_BUFFER_SIZE 0xC0000000 | 0x0206
-#define NT_STATUS_INVALID_ADDRESS_COMPONENT 0xC0000000 | 0x0207
-#define NT_STATUS_INVALID_ADDRESS_WILDCARD 0xC0000000 | 0x0208
-#define NT_STATUS_TOO_MANY_ADDRESSES 0xC0000000 | 0x0209
-#define NT_STATUS_ADDRESS_ALREADY_EXISTS 0xC0000000 | 0x020a
-#define NT_STATUS_ADDRESS_CLOSED 0xC0000000 | 0x020b
-#define NT_STATUS_CONNECTION_DISCONNECTED 0xC0000000 | 0x020c
-#define NT_STATUS_CONNECTION_RESET 0xC0000000 | 0x020d
-#define NT_STATUS_TOO_MANY_NODES 0xC0000000 | 0x020e
-#define NT_STATUS_TRANSACTION_ABORTED 0xC0000000 | 0x020f
-#define NT_STATUS_TRANSACTION_TIMED_OUT 0xC0000000 | 0x0210
-#define NT_STATUS_TRANSACTION_NO_RELEASE 0xC0000000 | 0x0211
-#define NT_STATUS_TRANSACTION_NO_MATCH 0xC0000000 | 0x0212
-#define NT_STATUS_TRANSACTION_RESPONDED 0xC0000000 | 0x0213
-#define NT_STATUS_TRANSACTION_INVALID_ID 0xC0000000 | 0x0214
-#define NT_STATUS_TRANSACTION_INVALID_TYPE 0xC0000000 | 0x0215
-#define NT_STATUS_NOT_SERVER_SESSION 0xC0000000 | 0x0216
-#define NT_STATUS_NOT_CLIENT_SESSION 0xC0000000 | 0x0217
-#define NT_STATUS_CANNOT_LOAD_REGISTRY_FILE 0xC0000000 | 0x0218
-#define NT_STATUS_DEBUG_ATTACH_FAILED 0xC0000000 | 0x0219
-#define NT_STATUS_SYSTEM_PROCESS_TERMINATED 0xC0000000 | 0x021a
-#define NT_STATUS_DATA_NOT_ACCEPTED 0xC0000000 | 0x021b
-#define NT_STATUS_NO_BROWSER_SERVERS_FOUND 0xC0000000 | 0x021c
-#define NT_STATUS_VDM_HARD_ERROR 0xC0000000 | 0x021d
-#define NT_STATUS_DRIVER_CANCEL_TIMEOUT 0xC0000000 | 0x021e
-#define NT_STATUS_REPLY_MESSAGE_MISMATCH 0xC0000000 | 0x021f
-#define NT_STATUS_MAPPED_ALIGNMENT 0xC0000000 | 0x0220
-#define NT_STATUS_IMAGE_CHECKSUM_MISMATCH 0xC0000000 | 0x0221
-#define NT_STATUS_LOST_WRITEBEHIND_DATA 0xC0000000 | 0x0222
-#define NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID 0xC0000000 | 0x0223
-#define NT_STATUS_PASSWORD_MUST_CHANGE 0xC0000000 | 0x0224
-#define NT_STATUS_NOT_FOUND 0xC0000000 | 0x0225
-#define NT_STATUS_NOT_TINY_STREAM 0xC0000000 | 0x0226
-#define NT_STATUS_RECOVERY_FAILURE 0xC0000000 | 0x0227
-#define NT_STATUS_STACK_OVERFLOW_READ 0xC0000000 | 0x0228
-#define NT_STATUS_FAIL_CHECK 0xC0000000 | 0x0229
-#define NT_STATUS_DUPLICATE_OBJECTID 0xC0000000 | 0x022a
-#define NT_STATUS_OBJECTID_EXISTS 0xC0000000 | 0x022b
-#define NT_STATUS_CONVERT_TO_LARGE 0xC0000000 | 0x022c
-#define NT_STATUS_RETRY 0xC0000000 | 0x022d
-#define NT_STATUS_FOUND_OUT_OF_SCOPE 0xC0000000 | 0x022e
-#define NT_STATUS_ALLOCATE_BUCKET 0xC0000000 | 0x022f
-#define NT_STATUS_PROPSET_NOT_FOUND 0xC0000000 | 0x0230
-#define NT_STATUS_MARSHALL_OVERFLOW 0xC0000000 | 0x0231
-#define NT_STATUS_INVALID_VARIANT 0xC0000000 | 0x0232
-#define NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND 0xC0000000 | 0x0233
-#define NT_STATUS_ACCOUNT_LOCKED_OUT 0xC0000000 | 0x0234
-#define NT_STATUS_HANDLE_NOT_CLOSABLE 0xC0000000 | 0x0235
-#define NT_STATUS_CONNECTION_REFUSED 0xC0000000 | 0x0236
-#define NT_STATUS_GRACEFUL_DISCONNECT 0xC0000000 | 0x0237
-#define NT_STATUS_ADDRESS_ALREADY_ASSOCIATED 0xC0000000 | 0x0238
-#define NT_STATUS_ADDRESS_NOT_ASSOCIATED 0xC0000000 | 0x0239
-#define NT_STATUS_CONNECTION_INVALID 0xC0000000 | 0x023a
-#define NT_STATUS_CONNECTION_ACTIVE 0xC0000000 | 0x023b
-#define NT_STATUS_NETWORK_UNREACHABLE 0xC0000000 | 0x023c
-#define NT_STATUS_HOST_UNREACHABLE 0xC0000000 | 0x023d
-#define NT_STATUS_PROTOCOL_UNREACHABLE 0xC0000000 | 0x023e
-#define NT_STATUS_PORT_UNREACHABLE 0xC0000000 | 0x023f
-#define NT_STATUS_REQUEST_ABORTED 0xC0000000 | 0x0240
-#define NT_STATUS_CONNECTION_ABORTED 0xC0000000 | 0x0241
-#define NT_STATUS_BAD_COMPRESSION_BUFFER 0xC0000000 | 0x0242
-#define NT_STATUS_USER_MAPPED_FILE 0xC0000000 | 0x0243
-#define NT_STATUS_AUDIT_FAILED 0xC0000000 | 0x0244
-#define NT_STATUS_TIMER_RESOLUTION_NOT_SET 0xC0000000 | 0x0245
-#define NT_STATUS_CONNECTION_COUNT_LIMIT 0xC0000000 | 0x0246
-#define NT_STATUS_LOGIN_TIME_RESTRICTION 0xC0000000 | 0x0247
-#define NT_STATUS_LOGIN_WKSTA_RESTRICTION 0xC0000000 | 0x0248
-#define NT_STATUS_IMAGE_MP_UP_MISMATCH 0xC0000000 | 0x0249
-#define NT_STATUS_INSUFFICIENT_LOGON_INFO 0xC0000000 | 0x0250
-#define NT_STATUS_BAD_DLL_ENTRYPOINT 0xC0000000 | 0x0251
-#define NT_STATUS_BAD_SERVICE_ENTRYPOINT 0xC0000000 | 0x0252
-#define NT_STATUS_LPC_REPLY_LOST 0xC0000000 | 0x0253
-#define NT_STATUS_IP_ADDRESS_CONFLICT1 0xC0000000 | 0x0254
-#define NT_STATUS_IP_ADDRESS_CONFLICT2 0xC0000000 | 0x0255
-#define NT_STATUS_REGISTRY_QUOTA_LIMIT 0xC0000000 | 0x0256
-#define NT_STATUS_PATH_NOT_COVERED 0xC0000000 | 0x0257
-#define NT_STATUS_NO_CALLBACK_ACTIVE 0xC0000000 | 0x0258
-#define NT_STATUS_LICENSE_QUOTA_EXCEEDED 0xC0000000 | 0x0259
-#define NT_STATUS_PWD_TOO_SHORT 0xC0000000 | 0x025a
-#define NT_STATUS_PWD_TOO_RECENT 0xC0000000 | 0x025b
-#define NT_STATUS_PWD_HISTORY_CONFLICT 0xC0000000 | 0x025c
-#define NT_STATUS_PLUGPLAY_NO_DEVICE 0xC0000000 | 0x025e
-#define NT_STATUS_UNSUPPORTED_COMPRESSION 0xC0000000 | 0x025f
-#define NT_STATUS_INVALID_HW_PROFILE 0xC0000000 | 0x0260
-#define NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH 0xC0000000 | 0x0261
-#define NT_STATUS_DRIVER_ORDINAL_NOT_FOUND 0xC0000000 | 0x0262
-#define NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND 0xC0000000 | 0x0263
-#define NT_STATUS_RESOURCE_NOT_OWNED 0xC0000000 | 0x0264
-#define NT_STATUS_TOO_MANY_LINKS 0xC0000000 | 0x0265
-#define NT_STATUS_QUOTA_LIST_INCONSISTENT 0xC0000000 | 0x0266
-#define NT_STATUS_FILE_IS_OFFLINE 0xC0000000 | 0x0267
-#define NT_STATUS_NO_SUCH_JOB 0xC0000000 | 0xEDE /* scheduler */
-
-#endif /* _NTERR_H */
diff --git a/ANDROID_3.4.5/fs/cifs/ntlmssp.h b/ANDROID_3.4.5/fs/cifs/ntlmssp.h
deleted file mode 100644
index 5d52e4a3..00000000
--- a/ANDROID_3.4.5/fs/cifs/ntlmssp.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * fs/cifs/ntlmssp.h
- *
- * Copyright (c) International Business Machines Corp., 2002,2007
- * Author(s): Steve French (sfrench@us.ibm.com)
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define NTLMSSP_SIGNATURE "NTLMSSP"
-/* Message Types */
-#define NtLmNegotiate cpu_to_le32(1)
-#define NtLmChallenge cpu_to_le32(2)
-#define NtLmAuthenticate cpu_to_le32(3)
-#define UnknownMessage cpu_to_le32(8)
-
-/* Negotiate Flags */
-#define NTLMSSP_NEGOTIATE_UNICODE 0x01 /* Text strings are unicode */
-#define NTLMSSP_NEGOTIATE_OEM 0x02 /* Text strings are in OEM */
-#define NTLMSSP_REQUEST_TARGET 0x04 /* Srv returns its auth realm */
-/* define reserved9 0x08 */
-#define NTLMSSP_NEGOTIATE_SIGN 0x0010 /* Request signing capability */
-#define NTLMSSP_NEGOTIATE_SEAL 0x0020 /* Request confidentiality */
-#define NTLMSSP_NEGOTIATE_DGRAM 0x0040
-#define NTLMSSP_NEGOTIATE_LM_KEY 0x0080 /* Use LM session key */
-/* defined reserved 8 0x0100 */
-#define NTLMSSP_NEGOTIATE_NTLM 0x0200 /* NTLM authentication */
-#define NTLMSSP_NEGOTIATE_NT_ONLY 0x0400 /* Lanman not allowed */
-#define NTLMSSP_ANONYMOUS 0x0800
-#define NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED 0x1000 /* reserved6 */
-#define NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED 0x2000
-#define NTLMSSP_NEGOTIATE_LOCAL_CALL 0x4000 /* client/server same machine */
-#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x8000 /* Sign. All security levels */
-#define NTLMSSP_TARGET_TYPE_DOMAIN 0x10000
-#define NTLMSSP_TARGET_TYPE_SERVER 0x20000
-#define NTLMSSP_TARGET_TYPE_SHARE 0x40000
-#define NTLMSSP_NEGOTIATE_EXTENDED_SEC 0x80000 /* NB:not related to NTLMv2 pwd*/
-/* #define NTLMSSP_REQUEST_INIT_RESP 0x100000 */
-#define NTLMSSP_NEGOTIATE_IDENTIFY 0x100000
-#define NTLMSSP_REQUEST_ACCEPT_RESP 0x200000 /* reserved5 */
-#define NTLMSSP_REQUEST_NON_NT_KEY 0x400000
-#define NTLMSSP_NEGOTIATE_TARGET_INFO 0x800000
-/* #define reserved4 0x1000000 */
-#define NTLMSSP_NEGOTIATE_VERSION 0x2000000 /* we do not set */
-/* #define reserved3 0x4000000 */
-/* #define reserved2 0x8000000 */
-/* #define reserved1 0x10000000 */
-#define NTLMSSP_NEGOTIATE_128 0x20000000
-#define NTLMSSP_NEGOTIATE_KEY_XCH 0x40000000
-#define NTLMSSP_NEGOTIATE_56 0x80000000
-
-/* Define AV Pair Field IDs */
-enum av_field_type {
- NTLMSSP_AV_EOL = 0,
- NTLMSSP_AV_NB_COMPUTER_NAME,
- NTLMSSP_AV_NB_DOMAIN_NAME,
- NTLMSSP_AV_DNS_COMPUTER_NAME,
- NTLMSSP_AV_DNS_DOMAIN_NAME,
- NTLMSSP_AV_DNS_TREE_NAME,
- NTLMSSP_AV_FLAGS,
- NTLMSSP_AV_TIMESTAMP,
- NTLMSSP_AV_RESTRICTION,
- NTLMSSP_AV_TARGET_NAME,
- NTLMSSP_AV_CHANNEL_BINDINGS
-};
-
-/* Although typedefs are not commonly used for structure definitions */
-/* in the Linux kernel, in this particular case they are useful */
-/* to more closely match the standards document for NTLMSSP from */
-/* OpenGroup and to make the code more closely match the standard in */
-/* appearance */
-
-typedef struct _SECURITY_BUFFER {
- __le16 Length;
- __le16 MaximumLength;
- __le32 BufferOffset; /* offset to buffer */
-} __attribute__((packed)) SECURITY_BUFFER;
-
-typedef struct _NEGOTIATE_MESSAGE {
- __u8 Signature[sizeof(NTLMSSP_SIGNATURE)];
- __le32 MessageType; /* NtLmNegotiate = 1 */
- __le32 NegotiateFlags;
- SECURITY_BUFFER DomainName; /* RFC 1001 style and ASCII */
- SECURITY_BUFFER WorkstationName; /* RFC 1001 and ASCII */
- /* SECURITY_BUFFER for version info not present since we
- do not set the version is present flag */
- char DomainString[0];
- /* followed by WorkstationString */
-} __attribute__((packed)) NEGOTIATE_MESSAGE, *PNEGOTIATE_MESSAGE;
-
-typedef struct _CHALLENGE_MESSAGE {
- __u8 Signature[sizeof(NTLMSSP_SIGNATURE)];
- __le32 MessageType; /* NtLmChallenge = 2 */
- SECURITY_BUFFER TargetName;
- __le32 NegotiateFlags;
- __u8 Challenge[CIFS_CRYPTO_KEY_SIZE];
- __u8 Reserved[8];
- SECURITY_BUFFER TargetInfoArray;
- /* SECURITY_BUFFER for version info not present since we
- do not set the version is present flag */
-} __attribute__((packed)) CHALLENGE_MESSAGE, *PCHALLENGE_MESSAGE;
-
-typedef struct _AUTHENTICATE_MESSAGE {
- __u8 Signature[sizeof(NTLMSSP_SIGNATURE)];
- __le32 MessageType; /* NtLmsAuthenticate = 3 */
- SECURITY_BUFFER LmChallengeResponse;
- SECURITY_BUFFER NtChallengeResponse;
- SECURITY_BUFFER DomainName;
- SECURITY_BUFFER UserName;
- SECURITY_BUFFER WorkstationName;
- SECURITY_BUFFER SessionKey;
- __le32 NegotiateFlags;
- /* SECURITY_BUFFER for version info not present since we
- do not set the version is present flag */
- char UserString[0];
-} __attribute__((packed)) AUTHENTICATE_MESSAGE, *PAUTHENTICATE_MESSAGE;
diff --git a/ANDROID_3.4.5/fs/cifs/readdir.c b/ANDROID_3.4.5/fs/cifs/readdir.c
deleted file mode 100644
index 0a8224d1..00000000
--- a/ANDROID_3.4.5/fs/cifs/readdir.c
+++ /dev/null
@@ -1,842 +0,0 @@
-/*
- * fs/cifs/readdir.c
- *
- * Directory search handling
- *
- * Copyright (C) International Business Machines Corp., 2004, 2008
- * Copyright (C) Red Hat, Inc., 2011
- * Author(s): Steve French (sfrench@us.ibm.com)
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#include <linux/fs.h>
-#include <linux/pagemap.h>
-#include <linux/slab.h>
-#include <linux/stat.h>
-#include "cifspdu.h"
-#include "cifsglob.h"
-#include "cifsproto.h"
-#include "cifs_unicode.h"
-#include "cifs_debug.h"
-#include "cifs_fs_sb.h"
-#include "cifsfs.h"
-
-/*
- * To be safe - for UCS to UTF-8 with strings loaded with the rare long
- * characters alloc more to account for such multibyte target UTF-8
- * characters.
- */
-#define UNICODE_NAME_MAX ((4 * NAME_MAX) + 2)
-
-#ifdef CONFIG_CIFS_DEBUG2
-static void dump_cifs_file_struct(struct file *file, char *label)
-{
- struct cifsFileInfo *cf;
-
- if (file) {
- cf = file->private_data;
- if (cf == NULL) {
- cFYI(1, "empty cifs private file data");
- return;
- }
- if (cf->invalidHandle)
- cFYI(1, "invalid handle");
- if (cf->srch_inf.endOfSearch)
- cFYI(1, "end of search");
- if (cf->srch_inf.emptyDir)
- cFYI(1, "empty dir");
- }
-}
-#else
-static inline void dump_cifs_file_struct(struct file *file, char *label)
-{
-}
-#endif /* DEBUG2 */
-
-/*
- * Find the dentry that matches "name". If there isn't one, create one. If it's
- * a negative dentry or the uniqueid changed, then drop it and recreate it.
- */
-static struct dentry *
-cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
- struct cifs_fattr *fattr)
-{
- struct dentry *dentry, *alias;
- struct inode *inode;
- struct super_block *sb = parent->d_inode->i_sb;
-
- cFYI(1, "For %s", name->name);
-
- if (parent->d_op && parent->d_op->d_hash)
- parent->d_op->d_hash(parent, parent->d_inode, name);
- else
- name->hash = full_name_hash(name->name, name->len);
-
- dentry = d_lookup(parent, name);
- if (dentry) {
- /* FIXME: check for inode number changes? */
- if (dentry->d_inode != NULL)
- return dentry;
- d_drop(dentry);
- dput(dentry);
- }
-
- dentry = d_alloc(parent, name);
- if (dentry == NULL)
- return NULL;
-
- inode = cifs_iget(sb, fattr);
- if (!inode) {
- dput(dentry);
- return NULL;
- }
-
- alias = d_materialise_unique(dentry, inode);
- if (alias != NULL) {
- dput(dentry);
- if (IS_ERR(alias))
- return NULL;
- dentry = alias;
- }
-
- return dentry;
-}
-
-static void
-cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb)
-{
- fattr->cf_uid = cifs_sb->mnt_uid;
- fattr->cf_gid = cifs_sb->mnt_gid;
-
- if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
- fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode;
- fattr->cf_dtype = DT_DIR;
- } else {
- fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode;
- fattr->cf_dtype = DT_REG;
- }
-
- if (fattr->cf_cifsattrs & ATTR_READONLY)
- fattr->cf_mode &= ~S_IWUGO;
-
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL &&
- fattr->cf_cifsattrs & ATTR_SYSTEM) {
- if (fattr->cf_eof == 0) {
- fattr->cf_mode &= ~S_IFMT;
- fattr->cf_mode |= S_IFIFO;
- fattr->cf_dtype = DT_FIFO;
- } else {
- /*
- * trying to get the type and mode via SFU can be slow,
- * so just call those regular files for now, and mark
- * for reval
- */
- fattr->cf_flags |= CIFS_FATTR_NEED_REVAL;
- }
- }
-}
-
-static void
-cifs_dir_info_to_fattr(struct cifs_fattr *fattr, FILE_DIRECTORY_INFO *info,
- struct cifs_sb_info *cifs_sb)
-{
- memset(fattr, 0, sizeof(*fattr));
- fattr->cf_cifsattrs = le32_to_cpu(info->ExtFileAttributes);
- fattr->cf_eof = le64_to_cpu(info->EndOfFile);
- fattr->cf_bytes = le64_to_cpu(info->AllocationSize);
- fattr->cf_createtime = le64_to_cpu(info->CreationTime);
- fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);
- fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime);
- fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime);
-
- cifs_fill_common_info(fattr, cifs_sb);
-}
-
-static void
-cifs_std_info_to_fattr(struct cifs_fattr *fattr, FIND_FILE_STANDARD_INFO *info,
- struct cifs_sb_info *cifs_sb)
-{
- int offset = cifs_sb_master_tcon(cifs_sb)->ses->server->timeAdj;
-
- memset(fattr, 0, sizeof(*fattr));
- fattr->cf_atime = cnvrtDosUnixTm(info->LastAccessDate,
- info->LastAccessTime, offset);
- fattr->cf_ctime = cnvrtDosUnixTm(info->LastWriteDate,
- info->LastWriteTime, offset);
- fattr->cf_mtime = cnvrtDosUnixTm(info->LastWriteDate,
- info->LastWriteTime, offset);
-
- fattr->cf_cifsattrs = le16_to_cpu(info->Attributes);
- fattr->cf_bytes = le32_to_cpu(info->AllocationSize);
- fattr->cf_eof = le32_to_cpu(info->DataSize);
-
- cifs_fill_common_info(fattr, cifs_sb);
-}
-
-/* BB eventually need to add the following helper function to
- resolve NT_STATUS_STOPPED_ON_SYMLINK return code when
- we try to do FindFirst on (NTFS) directory symlinks */
-/*
-int get_symlink_reparse_path(char *full_path, struct cifs_sb_info *cifs_sb,
- int xid)
-{
- __u16 fid;
- int len;
- int oplock = 0;
- int rc;
- struct cifs_tcon *ptcon = cifs_sb_tcon(cifs_sb);
- char *tmpbuffer;
-
- rc = CIFSSMBOpen(xid, ptcon, full_path, FILE_OPEN, GENERIC_READ,
- OPEN_REPARSE_POINT, &fid, &oplock, NULL,
- cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
- if (!rc) {
- tmpbuffer = kmalloc(maxpath);
- rc = CIFSSMBQueryReparseLinkInfo(xid, ptcon, full_path,
- tmpbuffer,
- maxpath -1,
- fid,
- cifs_sb->local_nls);
- if (CIFSSMBClose(xid, ptcon, fid)) {
- cFYI(1, "Error closing temporary reparsepoint open");
- }
- }
-}
- */
-
-static int initiate_cifs_search(const int xid, struct file *file)
-{
- __u16 search_flags;
- int rc = 0;
- char *full_path = NULL;
- struct cifsFileInfo *cifsFile;
- struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
- struct tcon_link *tlink = NULL;
- struct cifs_tcon *pTcon;
-
- if (file->private_data == NULL) {
- tlink = cifs_sb_tlink(cifs_sb);
- if (IS_ERR(tlink))
- return PTR_ERR(tlink);
-
- cifsFile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
- if (cifsFile == NULL) {
- rc = -ENOMEM;
- goto error_exit;
- }
- file->private_data = cifsFile;
- cifsFile->tlink = cifs_get_tlink(tlink);
- pTcon = tlink_tcon(tlink);
- } else {
- cifsFile = file->private_data;
- pTcon = tlink_tcon(cifsFile->tlink);
- }
-
- cifsFile->invalidHandle = true;
- cifsFile->srch_inf.endOfSearch = false;
-
- full_path = build_path_from_dentry(file->f_path.dentry);
- if (full_path == NULL) {
- rc = -ENOMEM;
- goto error_exit;
- }
-
- cFYI(1, "Full path: %s start at: %lld", full_path, file->f_pos);
-
-ffirst_retry:
- /* test for Unix extensions */
- /* but now check for them on the share/mount not on the SMB session */
-/* if (pTcon->ses->capabilities & CAP_UNIX) { */
- if (pTcon->unix_ext)
- cifsFile->srch_inf.info_level = SMB_FIND_FILE_UNIX;
- else if ((pTcon->ses->capabilities &
- (CAP_NT_SMBS | CAP_NT_FIND)) == 0) {
- cifsFile->srch_inf.info_level = SMB_FIND_FILE_INFO_STANDARD;
- } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
- cifsFile->srch_inf.info_level = SMB_FIND_FILE_ID_FULL_DIR_INFO;
- } else /* not srvinos - BB fixme add check for backlevel? */ {
- cifsFile->srch_inf.info_level = SMB_FIND_FILE_DIRECTORY_INFO;
- }
-
- search_flags = CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME;
- if (backup_cred(cifs_sb))
- search_flags |= CIFS_SEARCH_BACKUP_SEARCH;
-
- rc = CIFSFindFirst(xid, pTcon, full_path, cifs_sb->local_nls,
- &cifsFile->netfid, search_flags, &cifsFile->srch_inf,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb));
- if (rc == 0)
- cifsFile->invalidHandle = false;
- /* BB add following call to handle readdir on new NTFS symlink errors
- else if STATUS_STOPPED_ON_SYMLINK
- call get_symlink_reparse_path and retry with new path */
- else if ((rc == -EOPNOTSUPP) &&
- (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) {
- cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM;
- goto ffirst_retry;
- }
-error_exit:
- kfree(full_path);
- cifs_put_tlink(tlink);
- return rc;
-}
-
-/* return length of unicode string in bytes */
-static int cifs_unicode_bytelen(const char *str)
-{
- int len;
- const __le16 *ustr = (const __le16 *)str;
-
- for (len = 0; len <= PATH_MAX; len++) {
- if (ustr[len] == 0)
- return len << 1;
- }
- cFYI(1, "Unicode string longer than PATH_MAX found");
- return len << 1;
-}
-
-static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level)
-{
- char *new_entry;
- FILE_DIRECTORY_INFO *pDirInfo = (FILE_DIRECTORY_INFO *)old_entry;
-
- if (level == SMB_FIND_FILE_INFO_STANDARD) {
- FIND_FILE_STANDARD_INFO *pfData;
- pfData = (FIND_FILE_STANDARD_INFO *)pDirInfo;
-
- new_entry = old_entry + sizeof(FIND_FILE_STANDARD_INFO) +
- pfData->FileNameLength;
- } else
- new_entry = old_entry + le32_to_cpu(pDirInfo->NextEntryOffset);
- cFYI(1, "new entry %p old entry %p", new_entry, old_entry);
- /* validate that new_entry is not past end of SMB */
- if (new_entry >= end_of_smb) {
- cERROR(1, "search entry %p began after end of SMB %p old entry %p",
- new_entry, end_of_smb, old_entry);
- return NULL;
- } else if (((level == SMB_FIND_FILE_INFO_STANDARD) &&
- (new_entry + sizeof(FIND_FILE_STANDARD_INFO) > end_of_smb))
- || ((level != SMB_FIND_FILE_INFO_STANDARD) &&
- (new_entry + sizeof(FILE_DIRECTORY_INFO) > end_of_smb))) {
- cERROR(1, "search entry %p extends after end of SMB %p",
- new_entry, end_of_smb);
- return NULL;
- } else
- return new_entry;
-
-}
-
-struct cifs_dirent {
- const char *name;
- size_t namelen;
- u32 resume_key;
- u64 ino;
-};
-
-static void cifs_fill_dirent_unix(struct cifs_dirent *de,
- const FILE_UNIX_INFO *info, bool is_unicode)
-{
- de->name = &info->FileName[0];
- if (is_unicode)
- de->namelen = cifs_unicode_bytelen(de->name);
- else
- de->namelen = strnlen(de->name, PATH_MAX);
- de->resume_key = info->ResumeKey;
- de->ino = le64_to_cpu(info->basic.UniqueId);
-}
-
-static void cifs_fill_dirent_dir(struct cifs_dirent *de,
- const FILE_DIRECTORY_INFO *info)
-{
- de->name = &info->FileName[0];
- de->namelen = le32_to_cpu(info->FileNameLength);
- de->resume_key = info->FileIndex;
-}
-
-static void cifs_fill_dirent_full(struct cifs_dirent *de,
- const FILE_FULL_DIRECTORY_INFO *info)
-{
- de->name = &info->FileName[0];
- de->namelen = le32_to_cpu(info->FileNameLength);
- de->resume_key = info->FileIndex;
-}
-
-static void cifs_fill_dirent_search(struct cifs_dirent *de,
- const SEARCH_ID_FULL_DIR_INFO *info)
-{
- de->name = &info->FileName[0];
- de->namelen = le32_to_cpu(info->FileNameLength);
- de->resume_key = info->FileIndex;
- de->ino = le64_to_cpu(info->UniqueId);
-}
-
-static void cifs_fill_dirent_both(struct cifs_dirent *de,
- const FILE_BOTH_DIRECTORY_INFO *info)
-{
- de->name = &info->FileName[0];
- de->namelen = le32_to_cpu(info->FileNameLength);
- de->resume_key = info->FileIndex;
-}
-
-static void cifs_fill_dirent_std(struct cifs_dirent *de,
- const FIND_FILE_STANDARD_INFO *info)
-{
- de->name = &info->FileName[0];
- /* one byte length, no endianess conversion */
- de->namelen = info->FileNameLength;
- de->resume_key = info->ResumeKey;
-}
-
-static int cifs_fill_dirent(struct cifs_dirent *de, const void *info,
- u16 level, bool is_unicode)
-{
- memset(de, 0, sizeof(*de));
-
- switch (level) {
- case SMB_FIND_FILE_UNIX:
- cifs_fill_dirent_unix(de, info, is_unicode);
- break;
- case SMB_FIND_FILE_DIRECTORY_INFO:
- cifs_fill_dirent_dir(de, info);
- break;
- case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
- cifs_fill_dirent_full(de, info);
- break;
- case SMB_FIND_FILE_ID_FULL_DIR_INFO:
- cifs_fill_dirent_search(de, info);
- break;
- case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
- cifs_fill_dirent_both(de, info);
- break;
- case SMB_FIND_FILE_INFO_STANDARD:
- cifs_fill_dirent_std(de, info);
- break;
- default:
- cFYI(1, "Unknown findfirst level %d", level);
- return -EINVAL;
- }
-
- return 0;
-}
-
-#define UNICODE_DOT cpu_to_le16(0x2e)
-
-/* return 0 if no match and 1 for . (current directory) and 2 for .. (parent) */
-static int cifs_entry_is_dot(struct cifs_dirent *de, bool is_unicode)
-{
- int rc = 0;
-
- if (!de->name)
- return 0;
-
- if (is_unicode) {
- __le16 *ufilename = (__le16 *)de->name;
- if (de->namelen == 2) {
- /* check for . */
- if (ufilename[0] == UNICODE_DOT)
- rc = 1;
- } else if (de->namelen == 4) {
- /* check for .. */
- if (ufilename[0] == UNICODE_DOT &&
- ufilename[1] == UNICODE_DOT)
- rc = 2;
- }
- } else /* ASCII */ {
- if (de->namelen == 1) {
- if (de->name[0] == '.')
- rc = 1;
- } else if (de->namelen == 2) {
- if (de->name[0] == '.' && de->name[1] == '.')
- rc = 2;
- }
- }
-
- return rc;
-}
-
-/* Check if directory that we are searching has changed so we can decide
- whether we can use the cached search results from the previous search */
-static int is_dir_changed(struct file *file)
-{
- struct inode *inode = file->f_path.dentry->d_inode;
- struct cifsInodeInfo *cifsInfo = CIFS_I(inode);
-
- if (cifsInfo->time == 0)
- return 1; /* directory was changed, perhaps due to unlink */
- else
- return 0;
-
-}
-
-static int cifs_save_resume_key(const char *current_entry,
- struct cifsFileInfo *file_info)
-{
- struct cifs_dirent de;
- int rc;
-
- rc = cifs_fill_dirent(&de, current_entry, file_info->srch_inf.info_level,
- file_info->srch_inf.unicode);
- if (!rc) {
- file_info->srch_inf.presume_name = de.name;
- file_info->srch_inf.resume_name_len = de.namelen;
- file_info->srch_inf.resume_key = de.resume_key;
- }
- return rc;
-}
-
-/* find the corresponding entry in the search */
-/* Note that the SMB server returns search entries for . and .. which
- complicates logic here if we choose to parse for them and we do not
- assume that they are located in the findfirst return buffer.*/
-/* We start counting in the buffer with entry 2 and increment for every
- entry (do not increment for . or .. entry) */
-static int find_cifs_entry(const int xid, struct cifs_tcon *pTcon,
- struct file *file, char **ppCurrentEntry, int *num_to_ret)
-{
- __u16 search_flags;
- int rc = 0;
- int pos_in_buf = 0;
- loff_t first_entry_in_buffer;
- loff_t index_to_find = file->f_pos;
- struct cifsFileInfo *cifsFile = file->private_data;
- struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
- /* check if index in the buffer */
-
- if ((cifsFile == NULL) || (ppCurrentEntry == NULL) ||
- (num_to_ret == NULL))
- return -ENOENT;
-
- *ppCurrentEntry = NULL;
- first_entry_in_buffer =
- cifsFile->srch_inf.index_of_last_entry -
- cifsFile->srch_inf.entries_in_buffer;
-
- /* if first entry in buf is zero then is first buffer
- in search response data which means it is likely . and ..
- will be in this buffer, although some servers do not return
- . and .. for the root of a drive and for those we need
- to start two entries earlier */
-
- dump_cifs_file_struct(file, "In fce ");
- if (((index_to_find < cifsFile->srch_inf.index_of_last_entry) &&
- is_dir_changed(file)) ||
- (index_to_find < first_entry_in_buffer)) {
- /* close and restart search */
- cFYI(1, "search backing up - close and restart search");
- spin_lock(&cifs_file_list_lock);
- if (!cifsFile->srch_inf.endOfSearch &&
- !cifsFile->invalidHandle) {
- cifsFile->invalidHandle = true;
- spin_unlock(&cifs_file_list_lock);
- CIFSFindClose(xid, pTcon, cifsFile->netfid);
- } else
- spin_unlock(&cifs_file_list_lock);
- if (cifsFile->srch_inf.ntwrk_buf_start) {
- cFYI(1, "freeing SMB ff cache buf on search rewind");
- if (cifsFile->srch_inf.smallBuf)
- cifs_small_buf_release(cifsFile->srch_inf.
- ntwrk_buf_start);
- else
- cifs_buf_release(cifsFile->srch_inf.
- ntwrk_buf_start);
- cifsFile->srch_inf.ntwrk_buf_start = NULL;
- }
- rc = initiate_cifs_search(xid, file);
- if (rc) {
- cFYI(1, "error %d reinitiating a search on rewind",
- rc);
- return rc;
- }
- /* FindFirst/Next set last_entry to NULL on malformed reply */
- if (cifsFile->srch_inf.last_entry)
- cifs_save_resume_key(cifsFile->srch_inf.last_entry,
- cifsFile);
- }
-
- search_flags = CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME;
- if (backup_cred(cifs_sb))
- search_flags |= CIFS_SEARCH_BACKUP_SEARCH;
-
- while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) &&
- (rc == 0) && !cifsFile->srch_inf.endOfSearch) {
- cFYI(1, "calling findnext2");
- rc = CIFSFindNext(xid, pTcon, cifsFile->netfid, search_flags,
- &cifsFile->srch_inf);
- /* FindFirst/Next set last_entry to NULL on malformed reply */
- if (cifsFile->srch_inf.last_entry)
- cifs_save_resume_key(cifsFile->srch_inf.last_entry,
- cifsFile);
- if (rc)
- return -ENOENT;
- }
- if (index_to_find < cifsFile->srch_inf.index_of_last_entry) {
- /* we found the buffer that contains the entry */
- /* scan and find it */
- int i;
- char *current_entry;
- char *end_of_smb = cifsFile->srch_inf.ntwrk_buf_start +
- smbCalcSize((struct smb_hdr *)
- cifsFile->srch_inf.ntwrk_buf_start);
-
- current_entry = cifsFile->srch_inf.srch_entries_start;
- first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry
- - cifsFile->srch_inf.entries_in_buffer;
- pos_in_buf = index_to_find - first_entry_in_buffer;
- cFYI(1, "found entry - pos_in_buf %d", pos_in_buf);
-
- for (i = 0; (i < (pos_in_buf)) && (current_entry != NULL); i++) {
- /* go entry by entry figuring out which is first */
- current_entry = nxt_dir_entry(current_entry, end_of_smb,
- cifsFile->srch_inf.info_level);
- }
- if ((current_entry == NULL) && (i < pos_in_buf)) {
- /* BB fixme - check if we should flag this error */
- cERROR(1, "reached end of buf searching for pos in buf"
- " %d index to find %lld rc %d",
- pos_in_buf, index_to_find, rc);
- }
- rc = 0;
- *ppCurrentEntry = current_entry;
- } else {
- cFYI(1, "index not in buffer - could not findnext into it");
- return 0;
- }
-
- if (pos_in_buf >= cifsFile->srch_inf.entries_in_buffer) {
- cFYI(1, "can not return entries pos_in_buf beyond last");
- *num_to_ret = 0;
- } else
- *num_to_ret = cifsFile->srch_inf.entries_in_buffer - pos_in_buf;
-
- return rc;
-}
-
-static int cifs_filldir(char *find_entry, struct file *file, filldir_t filldir,
- void *dirent, char *scratch_buf, unsigned int max_len)
-{
- struct cifsFileInfo *file_info = file->private_data;
- struct super_block *sb = file->f_path.dentry->d_sb;
- struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
- struct cifs_dirent de = { NULL, };
- struct cifs_fattr fattr;
- struct dentry *dentry;
- struct qstr name;
- int rc = 0;
- ino_t ino;
-
- rc = cifs_fill_dirent(&de, find_entry, file_info->srch_inf.info_level,
- file_info->srch_inf.unicode);
- if (rc)
- return rc;
-
- if (de.namelen > max_len) {
- cERROR(1, "bad search response length %zd past smb end",
- de.namelen);
- return -EINVAL;
- }
-
- /* skip . and .. since we added them first */
- if (cifs_entry_is_dot(&de, file_info->srch_inf.unicode))
- return 0;
-
- if (file_info->srch_inf.unicode) {
- struct nls_table *nlt = cifs_sb->local_nls;
-
- name.name = scratch_buf;
- name.len =
- cifs_from_utf16((char *)name.name, (__le16 *)de.name,
- UNICODE_NAME_MAX,
- min_t(size_t, de.namelen,
- (size_t)max_len), nlt,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- name.len -= nls_nullsize(nlt);
- } else {
- name.name = de.name;
- name.len = de.namelen;
- }
-
- switch (file_info->srch_inf.info_level) {
- case SMB_FIND_FILE_UNIX:
- cifs_unix_basic_to_fattr(&fattr,
- &((FILE_UNIX_INFO *)find_entry)->basic,
- cifs_sb);
- break;
- case SMB_FIND_FILE_INFO_STANDARD:
- cifs_std_info_to_fattr(&fattr,
- (FIND_FILE_STANDARD_INFO *)find_entry,
- cifs_sb);
- break;
- default:
- cifs_dir_info_to_fattr(&fattr,
- (FILE_DIRECTORY_INFO *)find_entry,
- cifs_sb);
- break;
- }
-
- if (de.ino && (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) {
- fattr.cf_uniqueid = de.ino;
- } else {
- fattr.cf_uniqueid = iunique(sb, ROOT_I);
- cifs_autodisable_serverino(cifs_sb);
- }
-
- if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) &&
- CIFSCouldBeMFSymlink(&fattr))
- /*
- * trying to get the type and mode can be slow,
- * so just call those regular files for now, and mark
- * for reval
- */
- fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
-
- ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid);
- dentry = cifs_readdir_lookup(file->f_dentry, &name, &fattr);
-
- rc = filldir(dirent, name.name, name.len, file->f_pos, ino,
- fattr.cf_dtype);
-
- dput(dentry);
- return rc;
-}
-
-
-int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
-{
- int rc = 0;
- int xid, i;
- struct cifs_tcon *pTcon;
- struct cifsFileInfo *cifsFile = NULL;
- char *current_entry;
- int num_to_fill = 0;
- char *tmp_buf = NULL;
- char *end_of_smb;
- unsigned int max_len;
-
- xid = GetXid();
-
- /*
- * Ensure FindFirst doesn't fail before doing filldir() for '.' and
- * '..'. Otherwise we won't be able to notify VFS in case of failure.
- */
- if (file->private_data == NULL) {
- rc = initiate_cifs_search(xid, file);
- cFYI(1, "initiate cifs search rc %d", rc);
- if (rc)
- goto rddir2_exit;
- }
-
- switch ((int) file->f_pos) {
- case 0:
- if (filldir(direntry, ".", 1, file->f_pos,
- file->f_path.dentry->d_inode->i_ino, DT_DIR) < 0) {
- cERROR(1, "Filldir for current dir failed");
- rc = -ENOMEM;
- break;
- }
- file->f_pos++;
- case 1:
- if (filldir(direntry, "..", 2, file->f_pos,
- parent_ino(file->f_path.dentry), DT_DIR) < 0) {
- cERROR(1, "Filldir for parent dir failed");
- rc = -ENOMEM;
- break;
- }
- file->f_pos++;
- default:
- /* 1) If search is active,
- is in current search buffer?
- if it before then restart search
- if after then keep searching till find it */
-
- if (file->private_data == NULL) {
- rc = -EINVAL;
- FreeXid(xid);
- return rc;
- }
- cifsFile = file->private_data;
- if (cifsFile->srch_inf.endOfSearch) {
- if (cifsFile->srch_inf.emptyDir) {
- cFYI(1, "End of search, empty dir");
- rc = 0;
- break;
- }
- } /* else {
- cifsFile->invalidHandle = true;
- CIFSFindClose(xid, pTcon, cifsFile->netfid);
- } */
-
- pTcon = tlink_tcon(cifsFile->tlink);
- rc = find_cifs_entry(xid, pTcon, file,
- &current_entry, &num_to_fill);
- if (rc) {
- cFYI(1, "fce error %d", rc);
- goto rddir2_exit;
- } else if (current_entry != NULL) {
- cFYI(1, "entry %lld found", file->f_pos);
- } else {
- cFYI(1, "could not find entry");
- goto rddir2_exit;
- }
- cFYI(1, "loop through %d times filling dir for net buf %p",
- num_to_fill, cifsFile->srch_inf.ntwrk_buf_start);
- max_len = smbCalcSize((struct smb_hdr *)
- cifsFile->srch_inf.ntwrk_buf_start);
- end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + max_len;
-
- tmp_buf = kmalloc(UNICODE_NAME_MAX, GFP_KERNEL);
- if (tmp_buf == NULL) {
- rc = -ENOMEM;
- break;
- }
-
- for (i = 0; (i < num_to_fill) && (rc == 0); i++) {
- if (current_entry == NULL) {
- /* evaluate whether this case is an error */
- cERROR(1, "past SMB end, num to fill %d i %d",
- num_to_fill, i);
- break;
- }
- /* if buggy server returns . and .. late do
- we want to check for that here? */
- rc = cifs_filldir(current_entry, file,
- filldir, direntry, tmp_buf, max_len);
- if (rc == -EOVERFLOW) {
- rc = 0;
- break;
- }
-
- file->f_pos++;
- if (file->f_pos ==
- cifsFile->srch_inf.index_of_last_entry) {
- cFYI(1, "last entry in buf at pos %lld %s",
- file->f_pos, tmp_buf);
- cifs_save_resume_key(current_entry, cifsFile);
- break;
- } else
- current_entry =
- nxt_dir_entry(current_entry, end_of_smb,
- cifsFile->srch_inf.info_level);
- }
- kfree(tmp_buf);
- break;
- } /* end switch */
-
-rddir2_exit:
- FreeXid(xid);
- return rc;
-}
diff --git a/ANDROID_3.4.5/fs/cifs/rfc1002pdu.h b/ANDROID_3.4.5/fs/cifs/rfc1002pdu.h
deleted file mode 100644
index 8b69fcce..00000000
--- a/ANDROID_3.4.5/fs/cifs/rfc1002pdu.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * fs/cifs/rfc1002pdu.h
- *
- * Protocol Data Unit definitions for RFC 1001/1002 support
- *
- * Copyright (c) International Business Machines Corp., 2004
- * Author(s): Steve French (sfrench@us.ibm.com)
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* NB: unlike smb/cifs packets, the RFC1002 structures are big endian */
-
- /* RFC 1002 session packet types */
-#define RFC1002_SESSION_MESSAGE 0x00
-#define RFC1002_SESSION_REQUEST 0x81
-#define RFC1002_POSITIVE_SESSION_RESPONSE 0x82
-#define RFC1002_NEGATIVE_SESSION_RESPONSE 0x83
-#define RFC1002_RETARGET_SESSION_RESPONSE 0x84
-#define RFC1002_SESSION_KEEP_ALIVE 0x85
-
- /* RFC 1002 flags (only one defined */
-#define RFC1002_LENGTH_EXTEND 0x80 /* high order bit of length (ie +64K) */
-
-struct rfc1002_session_packet {
- __u8 type;
- __u8 flags;
- __u16 length;
- union {
- struct {
- __u8 called_len;
- __u8 called_name[32];
- __u8 scope1; /* null */
- __u8 calling_len;
- __u8 calling_name[32];
- __u8 scope2; /* null */
- } __attribute__((packed)) session_req;
- struct {
- __u32 retarget_ip_addr;
- __u16 port;
- } __attribute__((packed)) retarget_resp;
- __u8 neg_ses_resp_error_code;
- /* POSITIVE_SESSION_RESPONSE packet does not include trailer.
- SESSION_KEEP_ALIVE packet also does not include a trailer.
- Trailer for the SESSION_MESSAGE packet is SMB/CIFS header */
- } __attribute__((packed)) trailer;
-} __attribute__((packed));
-
-/* Negative Session Response error codes */
-#define RFC1002_NOT_LISTENING_CALLED 0x80 /* not listening on called name */
-#define RFC1002_NOT_LISTENING_CALLING 0x81 /* not listening on calling name */
-#define RFC1002_NOT_PRESENT 0x82 /* called name not present */
-#define RFC1002_INSUFFICIENT_RESOURCE 0x83
-#define RFC1002_UNSPECIFIED_ERROR 0x8F
-
-/* RFC 1002 Datagram service packets are not defined here as they
-are not needed for the network filesystem client unless we plan on
-implementing broadcast resolution of the server ip address (from
-server netbios name). Currently server names are resolved only via DNS
-(tcp name) or ip address or an /etc/hosts equivalent mapping to ip address.*/
-
-#define DEFAULT_CIFS_CALLED_NAME "*SMBSERVER "
diff --git a/ANDROID_3.4.5/fs/cifs/sess.c b/ANDROID_3.4.5/fs/cifs/sess.c
deleted file mode 100644
index 551d0c2b..00000000
--- a/ANDROID_3.4.5/fs/cifs/sess.c
+++ /dev/null
@@ -1,958 +0,0 @@
-/*
- * fs/cifs/sess.c
- *
- * SMB/CIFS session setup handling routines
- *
- * Copyright (c) International Business Machines Corp., 2006, 2009
- * Author(s): Steve French (sfrench@us.ibm.com)
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "cifspdu.h"
-#include "cifsglob.h"
-#include "cifsproto.h"
-#include "cifs_unicode.h"
-#include "cifs_debug.h"
-#include "ntlmssp.h"
-#include "nterr.h"
-#include <linux/utsname.h>
-#include <linux/slab.h>
-#include "cifs_spnego.h"
-
-/*
- * Checks if this is the first smb session to be reconnected after
- * the socket has been reestablished (so we know whether to use vc 0).
- * Called while holding the cifs_tcp_ses_lock, so do not block
- */
-static bool is_first_ses_reconnect(struct cifs_ses *ses)
-{
- struct list_head *tmp;
- struct cifs_ses *tmp_ses;
-
- list_for_each(tmp, &ses->server->smb_ses_list) {
- tmp_ses = list_entry(tmp, struct cifs_ses,
- smb_ses_list);
- if (tmp_ses->need_reconnect == false)
- return false;
- }
- /* could not find a session that was already connected,
- this must be the first one we are reconnecting */
- return true;
-}
-
-/*
- * vc number 0 is treated specially by some servers, and should be the
- * first one we request. After that we can use vcnumbers up to maxvcs,
- * one for each smb session (some Windows versions set maxvcs incorrectly
- * so maxvc=1 can be ignored). If we have too many vcs, we can reuse
- * any vc but zero (some servers reset the connection on vcnum zero)
- *
- */
-static __le16 get_next_vcnum(struct cifs_ses *ses)
-{
- __u16 vcnum = 0;
- struct list_head *tmp;
- struct cifs_ses *tmp_ses;
- __u16 max_vcs = ses->server->max_vcs;
- __u16 i;
- int free_vc_found = 0;
-
- /* Quoting the MS-SMB specification: "Windows-based SMB servers set this
- field to one but do not enforce this limit, which allows an SMB client
- to establish more virtual circuits than allowed by this value ... but
- other server implementations can enforce this limit." */
- if (max_vcs < 2)
- max_vcs = 0xFFFF;
-
- spin_lock(&cifs_tcp_ses_lock);
- if ((ses->need_reconnect) && is_first_ses_reconnect(ses))
- goto get_vc_num_exit; /* vcnum will be zero */
- for (i = ses->server->srv_count - 1; i < max_vcs; i++) {
- if (i == 0) /* this is the only connection, use vc 0 */
- break;
-
- free_vc_found = 1;
-
- list_for_each(tmp, &ses->server->smb_ses_list) {
- tmp_ses = list_entry(tmp, struct cifs_ses,
- smb_ses_list);
- if (tmp_ses->vcnum == i) {
- free_vc_found = 0;
- break; /* found duplicate, try next vcnum */
- }
- }
- if (free_vc_found)
- break; /* we found a vcnumber that will work - use it */
- }
-
- if (i == 0)
- vcnum = 0; /* for most common case, ie if one smb session, use
- vc zero. Also for case when no free vcnum, zero
- is safest to send (some clients only send zero) */
- else if (free_vc_found == 0)
- vcnum = 1; /* we can not reuse vc=0 safely, since some servers
- reset all uids on that, but 1 is ok. */
- else
- vcnum = i;
- ses->vcnum = vcnum;
-get_vc_num_exit:
- spin_unlock(&cifs_tcp_ses_lock);
-
- return cpu_to_le16(vcnum);
-}
-
-static __u32 cifs_ssetup_hdr(struct cifs_ses *ses, SESSION_SETUP_ANDX *pSMB)
-{
- __u32 capabilities = 0;
-
- /* init fields common to all four types of SessSetup */
- /* Note that offsets for first seven fields in req struct are same */
- /* in CIFS Specs so does not matter which of 3 forms of struct */
- /* that we use in next few lines */
- /* Note that header is initialized to zero in header_assemble */
- pSMB->req.AndXCommand = 0xFF;
- pSMB->req.MaxBufferSize = cpu_to_le16(min_t(u32,
- CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4,
- USHRT_MAX));
- pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
- pSMB->req.VcNumber = get_next_vcnum(ses);
-
- /* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */
-
- /* BB verify whether signing required on neg or just on auth frame
- (and NTLM case) */
-
- capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
- CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
-
- if (ses->server->sec_mode &
- (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
- pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
-
- if (ses->capabilities & CAP_UNICODE) {
- pSMB->req.hdr.Flags2 |= SMBFLG2_UNICODE;
- capabilities |= CAP_UNICODE;
- }
- if (ses->capabilities & CAP_STATUS32) {
- pSMB->req.hdr.Flags2 |= SMBFLG2_ERR_STATUS;
- capabilities |= CAP_STATUS32;
- }
- if (ses->capabilities & CAP_DFS) {
- pSMB->req.hdr.Flags2 |= SMBFLG2_DFS;
- capabilities |= CAP_DFS;
- }
- if (ses->capabilities & CAP_UNIX)
- capabilities |= CAP_UNIX;
-
- return capabilities;
-}
-
-static void
-unicode_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp)
-{
- char *bcc_ptr = *pbcc_area;
- int bytes_ret = 0;
-
- /* Copy OS version */
- bytes_ret = cifs_strtoUTF16((__le16 *)bcc_ptr, "Linux version ", 32,
- nls_cp);
- bcc_ptr += 2 * bytes_ret;
- bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, init_utsname()->release,
- 32, nls_cp);
- bcc_ptr += 2 * bytes_ret;
- bcc_ptr += 2; /* trailing null */
-
- bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
- 32, nls_cp);
- bcc_ptr += 2 * bytes_ret;
- bcc_ptr += 2; /* trailing null */
-
- *pbcc_area = bcc_ptr;
-}
-
-static void unicode_domain_string(char **pbcc_area, struct cifs_ses *ses,
- const struct nls_table *nls_cp)
-{
- char *bcc_ptr = *pbcc_area;
- int bytes_ret = 0;
-
- /* copy domain */
- if (ses->domainName == NULL) {
- /* Sending null domain better than using a bogus domain name (as
- we did briefly in 2.6.18) since server will use its default */
- *bcc_ptr = 0;
- *(bcc_ptr+1) = 0;
- bytes_ret = 0;
- } else
- bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, ses->domainName,
- 256, nls_cp);
- bcc_ptr += 2 * bytes_ret;
- bcc_ptr += 2; /* account for null terminator */
-
- *pbcc_area = bcc_ptr;
-}
-
-
-static void unicode_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
- const struct nls_table *nls_cp)
-{
- char *bcc_ptr = *pbcc_area;
- int bytes_ret = 0;
-
- /* BB FIXME add check that strings total less
- than 335 or will need to send them as arrays */
-
- /* unicode strings, must be word aligned before the call */
-/* if ((long) bcc_ptr % 2) {
- *bcc_ptr = 0;
- bcc_ptr++;
- } */
- /* copy user */
- if (ses->user_name == NULL) {
- /* null user mount */
- *bcc_ptr = 0;
- *(bcc_ptr+1) = 0;
- } else {
- bytes_ret = cifs_strtoUTF16((__le16 *) bcc_ptr, ses->user_name,
- MAX_USERNAME_SIZE, nls_cp);
- }
- bcc_ptr += 2 * bytes_ret;
- bcc_ptr += 2; /* account for null termination */
-
- unicode_domain_string(&bcc_ptr, ses, nls_cp);
- unicode_oslm_strings(&bcc_ptr, nls_cp);
-
- *pbcc_area = bcc_ptr;
-}
-
-static void ascii_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
- const struct nls_table *nls_cp)
-{
- char *bcc_ptr = *pbcc_area;
-
- /* copy user */
- /* BB what about null user mounts - check that we do this BB */
- /* copy user */
- if (ses->user_name != NULL) {
- strncpy(bcc_ptr, ses->user_name, MAX_USERNAME_SIZE);
- bcc_ptr += strnlen(ses->user_name, MAX_USERNAME_SIZE);
- }
- /* else null user mount */
- *bcc_ptr = 0;
- bcc_ptr++; /* account for null termination */
-
- /* copy domain */
- if (ses->domainName != NULL) {
- strncpy(bcc_ptr, ses->domainName, 256);
- bcc_ptr += strnlen(ses->domainName, 256);
- } /* else we will send a null domain name
- so the server will default to its own domain */
- *bcc_ptr = 0;
- bcc_ptr++;
-
- /* BB check for overflow here */
-
- strcpy(bcc_ptr, "Linux version ");
- bcc_ptr += strlen("Linux version ");
- strcpy(bcc_ptr, init_utsname()->release);
- bcc_ptr += strlen(init_utsname()->release) + 1;
-
- strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
- bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
-
- *pbcc_area = bcc_ptr;
-}
-
-static void
-decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifs_ses *ses,
- const struct nls_table *nls_cp)
-{
- int len;
- char *data = *pbcc_area;
-
- cFYI(1, "bleft %d", bleft);
-
- kfree(ses->serverOS);
- ses->serverOS = cifs_strndup_from_utf16(data, bleft, true, nls_cp);
- cFYI(1, "serverOS=%s", ses->serverOS);
- len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
- data += len;
- bleft -= len;
- if (bleft <= 0)
- return;
-
- kfree(ses->serverNOS);
- ses->serverNOS = cifs_strndup_from_utf16(data, bleft, true, nls_cp);
- cFYI(1, "serverNOS=%s", ses->serverNOS);
- len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;
- data += len;
- bleft -= len;
- if (bleft <= 0)
- return;
-
- kfree(ses->serverDomain);
- ses->serverDomain = cifs_strndup_from_utf16(data, bleft, true, nls_cp);
- cFYI(1, "serverDomain=%s", ses->serverDomain);
-
- return;
-}
-
-static int decode_ascii_ssetup(char **pbcc_area, __u16 bleft,
- struct cifs_ses *ses,
- const struct nls_table *nls_cp)
-{
- int rc = 0;
- int len;
- char *bcc_ptr = *pbcc_area;
-
- cFYI(1, "decode sessetup ascii. bleft %d", bleft);
-
- len = strnlen(bcc_ptr, bleft);
- if (len >= bleft)
- return rc;
-
- kfree(ses->serverOS);
-
- ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
- if (ses->serverOS)
- strncpy(ses->serverOS, bcc_ptr, len);
- if (strncmp(ses->serverOS, "OS/2", 4) == 0) {
- cFYI(1, "OS/2 server");
- ses->flags |= CIFS_SES_OS2;
- }
-
- bcc_ptr += len + 1;
- bleft -= len + 1;
-
- len = strnlen(bcc_ptr, bleft);
- if (len >= bleft)
- return rc;
-
- kfree(ses->serverNOS);
-
- ses->serverNOS = kzalloc(len + 1, GFP_KERNEL);
- if (ses->serverNOS)
- strncpy(ses->serverNOS, bcc_ptr, len);
-
- bcc_ptr += len + 1;
- bleft -= len + 1;
-
- len = strnlen(bcc_ptr, bleft);
- if (len > bleft)
- return rc;
-
- /* No domain field in LANMAN case. Domain is
- returned by old servers in the SMB negprot response */
- /* BB For newer servers which do not support Unicode,
- but thus do return domain here we could add parsing
- for it later, but it is not very important */
- cFYI(1, "ascii: bytes left %d", bleft);
-
- return rc;
-}
-
-static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
- struct cifs_ses *ses)
-{
- unsigned int tioffset; /* challenge message target info area */
- unsigned int tilen; /* challenge message target info area length */
-
- CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr;
-
- if (blob_len < sizeof(CHALLENGE_MESSAGE)) {
- cERROR(1, "challenge blob len %d too small", blob_len);
- return -EINVAL;
- }
-
- if (memcmp(pblob->Signature, "NTLMSSP", 8)) {
- cERROR(1, "blob signature incorrect %s", pblob->Signature);
- return -EINVAL;
- }
- if (pblob->MessageType != NtLmChallenge) {
- cERROR(1, "Incorrect message type %d", pblob->MessageType);
- return -EINVAL;
- }
-
- memcpy(ses->ntlmssp->cryptkey, pblob->Challenge, CIFS_CRYPTO_KEY_SIZE);
- /* BB we could decode pblob->NegotiateFlags; some may be useful */
- /* In particular we can examine sign flags */
- /* BB spec says that if AvId field of MsvAvTimestamp is populated then
- we must set the MIC field of the AUTHENTICATE_MESSAGE */
- ses->ntlmssp->server_flags = le32_to_cpu(pblob->NegotiateFlags);
- tioffset = le32_to_cpu(pblob->TargetInfoArray.BufferOffset);
- tilen = le16_to_cpu(pblob->TargetInfoArray.Length);
- if (tioffset > blob_len || tioffset + tilen > blob_len) {
- cERROR(1, "tioffset + tilen too high %u + %u", tioffset, tilen);
- return -EINVAL;
- }
- if (tilen) {
- ses->auth_key.response = kmalloc(tilen, GFP_KERNEL);
- if (!ses->auth_key.response) {
- cERROR(1, "Challenge target info allocation failure");
- return -ENOMEM;
- }
- memcpy(ses->auth_key.response, bcc_ptr + tioffset, tilen);
- ses->auth_key.len = tilen;
- }
-
- return 0;
-}
-
-/* BB Move to ntlmssp.c eventually */
-
-/* We do not malloc the blob, it is passed in pbuffer, because
- it is fixed size, and small, making this approach cleaner */
-static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
- struct cifs_ses *ses)
-{
- NEGOTIATE_MESSAGE *sec_blob = (NEGOTIATE_MESSAGE *)pbuffer;
- __u32 flags;
-
- memset(pbuffer, 0, sizeof(NEGOTIATE_MESSAGE));
- memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
- sec_blob->MessageType = NtLmNegotiate;
-
- /* BB is NTLMV2 session security format easier to use here? */
- flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET |
- NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
- NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
- if (ses->server->sec_mode &
- (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
- flags |= NTLMSSP_NEGOTIATE_SIGN;
- if (!ses->server->session_estab)
- flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
- }
-
- sec_blob->NegotiateFlags = cpu_to_le32(flags);
-
- sec_blob->WorkstationName.BufferOffset = 0;
- sec_blob->WorkstationName.Length = 0;
- sec_blob->WorkstationName.MaximumLength = 0;
-
- /* Domain name is sent on the Challenge not Negotiate NTLMSSP request */
- sec_blob->DomainName.BufferOffset = 0;
- sec_blob->DomainName.Length = 0;
- sec_blob->DomainName.MaximumLength = 0;
-}
-
-/* We do not malloc the blob, it is passed in pbuffer, because its
- maximum possible size is fixed and small, making this approach cleaner.
- This function returns the length of the data in the blob */
-static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
- u16 *buflen,
- struct cifs_ses *ses,
- const struct nls_table *nls_cp)
-{
- int rc;
- AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer;
- __u32 flags;
- unsigned char *tmp;
-
- memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
- sec_blob->MessageType = NtLmAuthenticate;
-
- flags = NTLMSSP_NEGOTIATE_56 |
- NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO |
- NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
- NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
- if (ses->server->sec_mode &
- (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
- flags |= NTLMSSP_NEGOTIATE_SIGN;
- if (!ses->server->session_estab)
- flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
- }
-
- tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE);
- sec_blob->NegotiateFlags = cpu_to_le32(flags);
-
- sec_blob->LmChallengeResponse.BufferOffset =
- cpu_to_le32(sizeof(AUTHENTICATE_MESSAGE));
- sec_blob->LmChallengeResponse.Length = 0;
- sec_blob->LmChallengeResponse.MaximumLength = 0;
-
- sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer);
- rc = setup_ntlmv2_rsp(ses, nls_cp);
- if (rc) {
- cERROR(1, "Error %d during NTLMSSP authentication", rc);
- goto setup_ntlmv2_ret;
- }
- memcpy(tmp, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
- ses->auth_key.len - CIFS_SESS_KEY_SIZE);
- tmp += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
-
- sec_blob->NtChallengeResponse.Length =
- cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
- sec_blob->NtChallengeResponse.MaximumLength =
- cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
-
- if (ses->domainName == NULL) {
- sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
- sec_blob->DomainName.Length = 0;
- sec_blob->DomainName.MaximumLength = 0;
- tmp += 2;
- } else {
- int len;
- len = cifs_strtoUTF16((__le16 *)tmp, ses->domainName,
- MAX_USERNAME_SIZE, nls_cp);
- len *= 2; /* unicode is 2 bytes each */
- sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
- sec_blob->DomainName.Length = cpu_to_le16(len);
- sec_blob->DomainName.MaximumLength = cpu_to_le16(len);
- tmp += len;
- }
-
- if (ses->user_name == NULL) {
- sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
- sec_blob->UserName.Length = 0;
- sec_blob->UserName.MaximumLength = 0;
- tmp += 2;
- } else {
- int len;
- len = cifs_strtoUTF16((__le16 *)tmp, ses->user_name,
- MAX_USERNAME_SIZE, nls_cp);
- len *= 2; /* unicode is 2 bytes each */
- sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
- sec_blob->UserName.Length = cpu_to_le16(len);
- sec_blob->UserName.MaximumLength = cpu_to_le16(len);
- tmp += len;
- }
-
- sec_blob->WorkstationName.BufferOffset = cpu_to_le32(tmp - pbuffer);
- sec_blob->WorkstationName.Length = 0;
- sec_blob->WorkstationName.MaximumLength = 0;
- tmp += 2;
-
- if (((ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) ||
- (ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
- && !calc_seckey(ses)) {
- memcpy(tmp, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
- sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
- sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE);
- sec_blob->SessionKey.MaximumLength =
- cpu_to_le16(CIFS_CPHTXT_SIZE);
- tmp += CIFS_CPHTXT_SIZE;
- } else {
- sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
- sec_blob->SessionKey.Length = 0;
- sec_blob->SessionKey.MaximumLength = 0;
- }
-
-setup_ntlmv2_ret:
- *buflen = tmp - pbuffer;
- return rc;
-}
-
-int
-CIFS_SessSetup(unsigned int xid, struct cifs_ses *ses,
- const struct nls_table *nls_cp)
-{
- int rc = 0;
- int wct;
- struct smb_hdr *smb_buf;
- char *bcc_ptr;
- char *str_area;
- SESSION_SETUP_ANDX *pSMB;
- __u32 capabilities;
- __u16 count;
- int resp_buf_type;
- struct kvec iov[3];
- enum securityEnum type;
- __u16 action, bytes_remaining;
- struct key *spnego_key = NULL;
- __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */
- u16 blob_len;
- char *ntlmsspblob = NULL;
-
- if (ses == NULL)
- return -EINVAL;
-
- type = ses->server->secType;
- cFYI(1, "sess setup type %d", type);
- if (type == RawNTLMSSP) {
- /* if memory allocation is successful, caller of this function
- * frees it.
- */
- ses->ntlmssp = kmalloc(sizeof(struct ntlmssp_auth), GFP_KERNEL);
- if (!ses->ntlmssp)
- return -ENOMEM;
- }
-
-ssetup_ntlmssp_authenticate:
- if (phase == NtLmChallenge)
- phase = NtLmAuthenticate; /* if ntlmssp, now final phase */
-
- if (type == LANMAN) {
-#ifndef CONFIG_CIFS_WEAK_PW_HASH
- /* LANMAN and plaintext are less secure and off by default.
- So we make this explicitly be turned on in kconfig (in the
- build) and turned on at runtime (changed from the default)
- in proc/fs/cifs or via mount parm. Unfortunately this is
- needed for old Win (e.g. Win95), some obscure NAS and OS/2 */
- return -EOPNOTSUPP;
-#endif
- wct = 10; /* lanman 2 style sessionsetup */
- } else if ((type == NTLM) || (type == NTLMv2)) {
- /* For NTLMv2 failures eventually may need to retry NTLM */
- wct = 13; /* old style NTLM sessionsetup */
- } else /* same size: negotiate or auth, NTLMSSP or extended security */
- wct = 12;
-
- rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,
- (void **)&smb_buf);
- if (rc)
- return rc;
-
- pSMB = (SESSION_SETUP_ANDX *)smb_buf;
-
- capabilities = cifs_ssetup_hdr(ses, pSMB);
-
- /* we will send the SMB in three pieces:
- a fixed length beginning part, an optional
- SPNEGO blob (which can be zero length), and a
- last part which will include the strings
- and rest of bcc area. This allows us to avoid
- a large buffer 17K allocation */
- iov[0].iov_base = (char *)pSMB;
- iov[0].iov_len = be32_to_cpu(smb_buf->smb_buf_length) + 4;
-
- /* setting this here allows the code at the end of the function
- to free the request buffer if there's an error */
- resp_buf_type = CIFS_SMALL_BUFFER;
-
- /* 2000 big enough to fit max user, domain, NOS name etc. */
- str_area = kmalloc(2000, GFP_KERNEL);
- if (str_area == NULL) {
- rc = -ENOMEM;
- goto ssetup_exit;
- }
- bcc_ptr = str_area;
-
- ses->flags &= ~CIFS_SES_LANMAN;
-
- iov[1].iov_base = NULL;
- iov[1].iov_len = 0;
-
- if (type == LANMAN) {
-#ifdef CONFIG_CIFS_WEAK_PW_HASH
- char lnm_session_key[CIFS_AUTH_RESP_SIZE];
-
- pSMB->req.hdr.Flags2 &= ~SMBFLG2_UNICODE;
-
- /* no capabilities flags in old lanman negotiation */
-
- pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE);
-
- /* Calculate hash with password and copy into bcc_ptr.
- * Encryption Key (stored as in cryptkey) gets used if the
- * security mode bit in Negottiate Protocol response states
- * to use challenge/response method (i.e. Password bit is 1).
- */
-
- rc = calc_lanman_hash(ses->password, ses->server->cryptkey,
- ses->server->sec_mode & SECMODE_PW_ENCRYPT ?
- true : false, lnm_session_key);
-
- ses->flags |= CIFS_SES_LANMAN;
- memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_AUTH_RESP_SIZE);
- bcc_ptr += CIFS_AUTH_RESP_SIZE;
-
- /* can not sign if LANMAN negotiated so no need
- to calculate signing key? but what if server
- changed to do higher than lanman dialect and
- we reconnected would we ever calc signing_key? */
-
- cFYI(1, "Negotiating LANMAN setting up strings");
- /* Unicode not allowed for LANMAN dialects */
- ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
-#endif
- } else if (type == NTLM) {
- pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
- pSMB->req_no_secext.CaseInsensitivePasswordLength =
- cpu_to_le16(CIFS_AUTH_RESP_SIZE);
- pSMB->req_no_secext.CaseSensitivePasswordLength =
- cpu_to_le16(CIFS_AUTH_RESP_SIZE);
-
- /* calculate ntlm response and session key */
- rc = setup_ntlm_response(ses, nls_cp);
- if (rc) {
- cERROR(1, "Error %d during NTLM authentication", rc);
- goto ssetup_exit;
- }
-
- /* copy ntlm response */
- memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
- CIFS_AUTH_RESP_SIZE);
- bcc_ptr += CIFS_AUTH_RESP_SIZE;
- memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
- CIFS_AUTH_RESP_SIZE);
- bcc_ptr += CIFS_AUTH_RESP_SIZE;
-
- if (ses->capabilities & CAP_UNICODE) {
- /* unicode strings must be word aligned */
- if (iov[0].iov_len % 2) {
- *bcc_ptr = 0;
- bcc_ptr++;
- }
- unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
- } else
- ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
- } else if (type == NTLMv2) {
- pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
-
- /* LM2 password would be here if we supported it */
- pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
-
- /* calculate nlmv2 response and session key */
- rc = setup_ntlmv2_rsp(ses, nls_cp);
- if (rc) {
- cERROR(1, "Error %d during NTLMv2 authentication", rc);
- goto ssetup_exit;
- }
- memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
- ses->auth_key.len - CIFS_SESS_KEY_SIZE);
- bcc_ptr += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
-
- /* set case sensitive password length after tilen may get
- * assigned, tilen is 0 otherwise.
- */
- pSMB->req_no_secext.CaseSensitivePasswordLength =
- cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
-
- if (ses->capabilities & CAP_UNICODE) {
- if (iov[0].iov_len % 2) {
- *bcc_ptr = 0;
- bcc_ptr++;
- }
- unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
- } else
- ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
- } else if (type == Kerberos) {
-#ifdef CONFIG_CIFS_UPCALL
- struct cifs_spnego_msg *msg;
-
- spnego_key = cifs_get_spnego_key(ses);
- if (IS_ERR(spnego_key)) {
- rc = PTR_ERR(spnego_key);
- spnego_key = NULL;
- goto ssetup_exit;
- }
-
- msg = spnego_key->payload.data;
- /* check version field to make sure that cifs.upcall is
- sending us a response in an expected form */
- if (msg->version != CIFS_SPNEGO_UPCALL_VERSION) {
- cERROR(1, "incorrect version of cifs.upcall (expected"
- " %d but got %d)",
- CIFS_SPNEGO_UPCALL_VERSION, msg->version);
- rc = -EKEYREJECTED;
- goto ssetup_exit;
- }
-
- ses->auth_key.response = kmalloc(msg->sesskey_len, GFP_KERNEL);
- if (!ses->auth_key.response) {
- cERROR(1, "Kerberos can't allocate (%u bytes) memory",
- msg->sesskey_len);
- rc = -ENOMEM;
- goto ssetup_exit;
- }
- memcpy(ses->auth_key.response, msg->data, msg->sesskey_len);
- ses->auth_key.len = msg->sesskey_len;
-
- pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
- capabilities |= CAP_EXTENDED_SECURITY;
- pSMB->req.Capabilities = cpu_to_le32(capabilities);
- iov[1].iov_base = msg->data + msg->sesskey_len;
- iov[1].iov_len = msg->secblob_len;
- pSMB->req.SecurityBlobLength = cpu_to_le16(iov[1].iov_len);
-
- if (ses->capabilities & CAP_UNICODE) {
- /* unicode strings must be word aligned */
- if ((iov[0].iov_len + iov[1].iov_len) % 2) {
- *bcc_ptr = 0;
- bcc_ptr++;
- }
- unicode_oslm_strings(&bcc_ptr, nls_cp);
- unicode_domain_string(&bcc_ptr, ses, nls_cp);
- } else
- /* BB: is this right? */
- ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
-#else /* ! CONFIG_CIFS_UPCALL */
- cERROR(1, "Kerberos negotiated but upcall support disabled!");
- rc = -ENOSYS;
- goto ssetup_exit;
-#endif /* CONFIG_CIFS_UPCALL */
- } else if (type == RawNTLMSSP) {
- if ((pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) == 0) {
- cERROR(1, "NTLMSSP requires Unicode support");
- rc = -ENOSYS;
- goto ssetup_exit;
- }
-
- cFYI(1, "ntlmssp session setup phase %d", phase);
- pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
- capabilities |= CAP_EXTENDED_SECURITY;
- pSMB->req.Capabilities |= cpu_to_le32(capabilities);
- switch(phase) {
- case NtLmNegotiate:
- build_ntlmssp_negotiate_blob(
- pSMB->req.SecurityBlob, ses);
- iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE);
- iov[1].iov_base = pSMB->req.SecurityBlob;
- pSMB->req.SecurityBlobLength =
- cpu_to_le16(sizeof(NEGOTIATE_MESSAGE));
- break;
- case NtLmAuthenticate:
- /*
- * 5 is an empirical value, large enough to hold
- * authenticate message plus max 10 of av paris,
- * domain, user, workstation names, flags, etc.
- */
- ntlmsspblob = kzalloc(
- 5*sizeof(struct _AUTHENTICATE_MESSAGE),
- GFP_KERNEL);
- if (!ntlmsspblob) {
- cERROR(1, "Can't allocate NTLMSSP blob");
- rc = -ENOMEM;
- goto ssetup_exit;
- }
-
- rc = build_ntlmssp_auth_blob(ntlmsspblob,
- &blob_len, ses, nls_cp);
- if (rc)
- goto ssetup_exit;
- iov[1].iov_len = blob_len;
- iov[1].iov_base = ntlmsspblob;
- pSMB->req.SecurityBlobLength = cpu_to_le16(blob_len);
- /*
- * Make sure that we tell the server that we are using
- * the uid that it just gave us back on the response
- * (challenge)
- */
- smb_buf->Uid = ses->Suid;
- break;
- default:
- cERROR(1, "invalid phase %d", phase);
- rc = -ENOSYS;
- goto ssetup_exit;
- }
- /* unicode strings must be word aligned */
- if ((iov[0].iov_len + iov[1].iov_len) % 2) {
- *bcc_ptr = 0;
- bcc_ptr++;
- }
- unicode_oslm_strings(&bcc_ptr, nls_cp);
- } else {
- cERROR(1, "secType %d not supported!", type);
- rc = -ENOSYS;
- goto ssetup_exit;
- }
-
- iov[2].iov_base = str_area;
- iov[2].iov_len = (long) bcc_ptr - (long) str_area;
-
- count = iov[1].iov_len + iov[2].iov_len;
- smb_buf->smb_buf_length =
- cpu_to_be32(be32_to_cpu(smb_buf->smb_buf_length) + count);
-
- put_bcc(count, smb_buf);
-
- rc = SendReceive2(xid, ses, iov, 3 /* num_iovecs */, &resp_buf_type,
- CIFS_LOG_ERROR);
- /* SMB request buf freed in SendReceive2 */
-
- pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base;
- smb_buf = (struct smb_hdr *)iov[0].iov_base;
-
- if ((type == RawNTLMSSP) && (smb_buf->Status.CifsError ==
- cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))) {
- if (phase != NtLmNegotiate) {
- cERROR(1, "Unexpected more processing error");
- goto ssetup_exit;
- }
- /* NTLMSSP Negotiate sent now processing challenge (response) */
- phase = NtLmChallenge; /* process ntlmssp challenge */
- rc = 0; /* MORE_PROC rc is not an error here, but expected */
- }
- if (rc)
- goto ssetup_exit;
-
- if ((smb_buf->WordCount != 3) && (smb_buf->WordCount != 4)) {
- rc = -EIO;
- cERROR(1, "bad word count %d", smb_buf->WordCount);
- goto ssetup_exit;
- }
- action = le16_to_cpu(pSMB->resp.Action);
- if (action & GUEST_LOGIN)
- cFYI(1, "Guest login"); /* BB mark SesInfo struct? */
- ses->Suid = smb_buf->Uid; /* UID left in wire format (le) */
- cFYI(1, "UID = %d ", ses->Suid);
- /* response can have either 3 or 4 word count - Samba sends 3 */
- /* and lanman response is 3 */
- bytes_remaining = get_bcc(smb_buf);
- bcc_ptr = pByteArea(smb_buf);
-
- if (smb_buf->WordCount == 4) {
- blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
- if (blob_len > bytes_remaining) {
- cERROR(1, "bad security blob length %d", blob_len);
- rc = -EINVAL;
- goto ssetup_exit;
- }
- if (phase == NtLmChallenge) {
- rc = decode_ntlmssp_challenge(bcc_ptr, blob_len, ses);
- /* now goto beginning for ntlmssp authenticate phase */
- if (rc)
- goto ssetup_exit;
- }
- bcc_ptr += blob_len;
- bytes_remaining -= blob_len;
- }
-
- /* BB check if Unicode and decode strings */
- if (bytes_remaining == 0) {
- /* no string area to decode, do nothing */
- } else if (smb_buf->Flags2 & SMBFLG2_UNICODE) {
- /* unicode string area must be word-aligned */
- if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) {
- ++bcc_ptr;
- --bytes_remaining;
- }
- decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses, nls_cp);
- } else {
- rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining,
- ses, nls_cp);
- }
-
-ssetup_exit:
- if (spnego_key) {
- key_revoke(spnego_key);
- key_put(spnego_key);
- }
- kfree(str_area);
- kfree(ntlmsspblob);
- ntlmsspblob = NULL;
- if (resp_buf_type == CIFS_SMALL_BUFFER) {
- cFYI(1, "ssetup freeing small buf %p", iov[0].iov_base);
- cifs_small_buf_release(iov[0].iov_base);
- } else if (resp_buf_type == CIFS_LARGE_BUFFER)
- cifs_buf_release(iov[0].iov_base);
-
- /* if ntlmssp, and negotiate succeeded, proceed to authenticate phase */
- if ((phase == NtLmChallenge) && (rc == 0))
- goto ssetup_ntlmssp_authenticate;
-
- return rc;
-}
diff --git a/ANDROID_3.4.5/fs/cifs/smbencrypt.c b/ANDROID_3.4.5/fs/cifs/smbencrypt.c
deleted file mode 100644
index d5cd9aa7..00000000
--- a/ANDROID_3.4.5/fs/cifs/smbencrypt.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- SMB parameters and setup
- Copyright (C) Andrew Tridgell 1992-2000
- Copyright (C) Luke Kenneth Casson Leighton 1996-2000
- Modified by Jeremy Allison 1995.
- Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003
- Modified by Steve French (sfrench@us.ibm.com) 2002-2003
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/fs.h>
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/random.h>
-#include "cifs_unicode.h"
-#include "cifspdu.h"
-#include "cifsglob.h"
-#include "cifs_debug.h"
-#include "cifsproto.h"
-
-#ifndef false
-#define false 0
-#endif
-#ifndef true
-#define true 1
-#endif
-
-/* following came from the other byteorder.h to avoid include conflicts */
-#define CVAL(buf,pos) (((unsigned char *)(buf))[pos])
-#define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8)
-#define SSVAL(buf,pos,val) SSVALX((buf),(pos),((__u16)(val)))
-
-static void
-str_to_key(unsigned char *str, unsigned char *key)
-{
- int i;
-
- key[0] = str[0] >> 1;
- key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2);
- key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3);
- key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4);
- key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5);
- key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6);
- key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7);
- key[7] = str[6] & 0x7F;
- for (i = 0; i < 8; i++)
- key[i] = (key[i] << 1);
-}
-
-static int
-smbhash(unsigned char *out, const unsigned char *in, unsigned char *key)
-{
- int rc;
- unsigned char key2[8];
- struct crypto_blkcipher *tfm_des;
- struct scatterlist sgin, sgout;
- struct blkcipher_desc desc;
-
- str_to_key(key, key2);
-
- tfm_des = crypto_alloc_blkcipher("ecb(des)", 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(tfm_des)) {
- rc = PTR_ERR(tfm_des);
- cERROR(1, "could not allocate des crypto API\n");
- goto smbhash_err;
- }
-
- desc.tfm = tfm_des;
-
- crypto_blkcipher_setkey(tfm_des, key2, 8);
-
- sg_init_one(&sgin, in, 8);
- sg_init_one(&sgout, out, 8);
-
- rc = crypto_blkcipher_encrypt(&desc, &sgout, &sgin, 8);
- if (rc)
- cERROR(1, "could not encrypt crypt key rc: %d\n", rc);
-
- crypto_free_blkcipher(tfm_des);
-smbhash_err:
- return rc;
-}
-
-static int
-E_P16(unsigned char *p14, unsigned char *p16)
-{
- int rc;
- unsigned char sp8[8] =
- { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
-
- rc = smbhash(p16, sp8, p14);
- if (rc)
- return rc;
- rc = smbhash(p16 + 8, sp8, p14 + 7);
- return rc;
-}
-
-static int
-E_P24(unsigned char *p21, const unsigned char *c8, unsigned char *p24)
-{
- int rc;
-
- rc = smbhash(p24, c8, p21);
- if (rc)
- return rc;
- rc = smbhash(p24 + 8, c8, p21 + 7);
- if (rc)
- return rc;
- rc = smbhash(p24 + 16, c8, p21 + 14);
- return rc;
-}
-
-/* produce a md4 message digest from data of length n bytes */
-int
-mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len)
-{
- int rc;
- unsigned int size;
- struct crypto_shash *md4;
- struct sdesc *sdescmd4;
-
- md4 = crypto_alloc_shash("md4", 0, 0);
- if (IS_ERR(md4)) {
- rc = PTR_ERR(md4);
- cERROR(1, "%s: Crypto md4 allocation error %d\n", __func__, rc);
- return rc;
- }
- size = sizeof(struct shash_desc) + crypto_shash_descsize(md4);
- sdescmd4 = kmalloc(size, GFP_KERNEL);
- if (!sdescmd4) {
- rc = -ENOMEM;
- cERROR(1, "%s: Memory allocation failure\n", __func__);
- goto mdfour_err;
- }
- sdescmd4->shash.tfm = md4;
- sdescmd4->shash.flags = 0x0;
-
- rc = crypto_shash_init(&sdescmd4->shash);
- if (rc) {
- cERROR(1, "%s: Could not init md4 shash\n", __func__);
- goto mdfour_err;
- }
- rc = crypto_shash_update(&sdescmd4->shash, link_str, link_len);
- if (rc) {
- cERROR(1, "%s: Could not update with link_str\n", __func__);
- goto mdfour_err;
- }
- rc = crypto_shash_final(&sdescmd4->shash, md4_hash);
- if (rc)
- cERROR(1, "%s: Could not genereate md4 hash\n", __func__);
-
-mdfour_err:
- crypto_free_shash(md4);
- kfree(sdescmd4);
-
- return rc;
-}
-
-/*
- This implements the X/Open SMB password encryption
- It takes a password, a 8 byte "crypt key" and puts 24 bytes of
- encrypted password into p24 */
-/* Note that password must be uppercased and null terminated */
-int
-SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24)
-{
- int rc;
- unsigned char p14[14], p16[16], p21[21];
-
- memset(p14, '\0', 14);
- memset(p16, '\0', 16);
- memset(p21, '\0', 21);
-
- memcpy(p14, passwd, 14);
- rc = E_P16(p14, p16);
- if (rc)
- return rc;
-
- memcpy(p21, p16, 16);
- rc = E_P24(p21, c8, p24);
-
- return rc;
-}
-
-/*
- * Creates the MD4 Hash of the users password in NT UNICODE.
- */
-
-int
-E_md4hash(const unsigned char *passwd, unsigned char *p16,
- const struct nls_table *codepage)
-{
- int rc;
- int len;
- __le16 wpwd[129];
-
- /* Password cannot be longer than 128 characters */
- if (passwd) /* Password must be converted to NT unicode */
- len = cifs_strtoUTF16(wpwd, passwd, 128, codepage);
- else {
- len = 0;
- *wpwd = 0; /* Ensure string is null terminated */
- }
-
- rc = mdfour(p16, (unsigned char *) wpwd, len * sizeof(__le16));
- memset(wpwd, 0, 129 * sizeof(__le16));
-
- return rc;
-}
-
-/* Does the NT MD4 hash then des encryption. */
-int
-SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24,
- const struct nls_table *codepage)
-{
- int rc;
- unsigned char p16[16], p21[21];
-
- memset(p16, '\0', 16);
- memset(p21, '\0', 21);
-
- rc = E_md4hash(passwd, p16, codepage);
- if (rc) {
- cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc);
- return rc;
- }
- memcpy(p21, p16, 16);
- rc = E_P24(p21, c8, p24);
- return rc;
-}
diff --git a/ANDROID_3.4.5/fs/cifs/smberr.h b/ANDROID_3.4.5/fs/cifs/smberr.h
deleted file mode 100644
index 7f16cb82..00000000
--- a/ANDROID_3.4.5/fs/cifs/smberr.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * fs/cifs/smberr.h
- *
- * Copyright (c) International Business Machines Corp., 2002,2004
- * Author(s): Steve French (sfrench@us.ibm.com)
- *
- * See Error Codes section of the SNIA CIFS Specification
- * for more information
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#define SUCCESS 0x00 /* The request was successful. */
-#define ERRDOS 0x01 /* Error is from the core DOS operating system set */
-#define ERRSRV 0x02 /* Error is generated by the file server daemon */
-#define ERRHRD 0x03 /* Error is a hardware error. */
-#define ERRCMD 0xFF /* Command was not in the "SMB" format. */
-
-/* The following error codes may be generated with the SUCCESS error class.*/
-
-/*#define SUCCESS 0 The request was successful. */
-
-/* The following error codes may be generated with the ERRDOS error class.*/
-
-#define ERRbadfunc 1 /* Invalid function. The server did not
- recognize or could not perform a
- system call generated by the server,
- e.g., set the DIRECTORY attribute on
- a data file, invalid seek mode. */
-#define ERRbadfile 2 /* File not found. The last component
- of a file's pathname could not be
- found. */
-#define ERRbadpath 3 /* Directory invalid. A directory
- component in a pathname could not be
- found. */
-#define ERRnofids 4 /* Too many open files. The server has
- no file handles available. */
-#define ERRnoaccess 5 /* Access denied, the client's context
- does not permit the requested
- function. This includes the
- following conditions: invalid rename
- command, write to Fid open for read
- only, read on Fid open for write
- only, attempt to delete a non-empty
- directory */
-#define ERRbadfid 6 /* Invalid file handle. The file handle
- specified was not recognized by the
- server. */
-#define ERRbadmcb 7 /* Memory control blocks destroyed. */
-#define ERRnomem 8 /* Insufficient server memory to
- perform the requested function. */
-#define ERRbadmem 9 /* Invalid memory block address. */
-#define ERRbadenv 10 /* Invalid environment. */
-#define ERRbadformat 11 /* Invalid format. */
-#define ERRbadaccess 12 /* Invalid open mode. */
-#define ERRbaddata 13 /* Invalid data (generated only by
- IOCTL calls within the server). */
-#define ERRbaddrive 15 /* Invalid drive specified. */
-#define ERRremcd 16 /* A Delete Directory request attempted
- to remove the server's current
- directory. */
-#define ERRdiffdevice 17 /* Not same device (e.g., a cross
- volume rename was attempted */
-#define ERRnofiles 18 /* A File Search command can find no
- more files matching the specified
- criteria. */
-#define ERRwriteprot 19 /* media is write protected */
-#define ERRgeneral 31
-#define ERRbadshare 32 /* The sharing mode specified for an
- Open conflicts with existing FIDs on
- the file. */
-#define ERRlock 33 /* A Lock request conflicted with an
- existing lock or specified an
- invalid mode, or an Unlock requested
- attempted to remove a lock held by
- another process. */
-#define ERRunsup 50
-#define ERRnosuchshare 67
-#define ERRfilexists 80 /* The file named in the request
- already exists. */
-#define ERRinvparm 87
-#define ERRdiskfull 112
-#define ERRinvname 123
-#define ERRinvlevel 124
-#define ERRdirnotempty 145
-#define ERRnotlocked 158
-#define ERRcancelviolation 173
-#define ERRalreadyexists 183
-#define ERRbadpipe 230
-#define ERRpipebusy 231
-#define ERRpipeclosing 232
-#define ERRnotconnected 233
-#define ERRmoredata 234
-#define ERReasnotsupported 282
-#define ErrQuota 0x200 /* The operation would cause a quota
- limit to be exceeded. */
-#define ErrNotALink 0x201 /* A link operation was performed on a
- pathname that was not a link. */
-
-/* Below errors are used internally (do not come over the wire) for passthrough
- from STATUS codes to POSIX only */
-#define ERRsymlink 0xFFFD
-#define ErrTooManyLinks 0xFFFE
-
-/* Following error codes may be generated with the ERRSRV error class.*/
-
-#define ERRerror 1 /* Non-specific error code. It is
- returned under the following
- conditions: resource other than disk
- space exhausted (e.g. TIDs), first
- SMB command was not negotiate,
- multiple negotiates attempted, and
- internal server error. */
-#define ERRbadpw 2 /* Bad password - name/password pair in
- a TreeConnect or Session Setup are
- invalid. */
-#define ERRbadtype 3 /* used for indicating DFS referral
- needed */
-#define ERRaccess 4 /* The client does not have the
- necessary access rights within the
- specified context for requested
- function. */
-#define ERRinvtid 5 /* The Tid specified in a command was
- invalid. */
-#define ERRinvnetname 6 /* Invalid network name in tree
- connect. */
-#define ERRinvdevice 7 /* Invalid device - printer request
- made to non-printer connection or
- non-printer request made to printer
- connection. */
-#define ERRqfull 49 /* Print queue full (files) -- returned
- by open print file. */
-#define ERRqtoobig 50 /* Print queue full -- no space. */
-#define ERRqeof 51 /* EOF on print queue dump */
-#define ERRinvpfid 52 /* Invalid print file FID. */
-#define ERRsmbcmd 64 /* The server did not recognize the
- command received. */
-#define ERRsrverror 65 /* The server encountered an internal
- error, e.g., system file
- unavailable. */
-#define ERRbadBID 66 /* (obsolete) */
-#define ERRfilespecs 67 /* The Fid and pathname parameters
- contained an invalid combination of
- values. */
-#define ERRbadLink 68 /* (obsolete) */
-#define ERRbadpermits 69 /* The access permissions specified for
- a file or directory are not a valid
- combination. */
-#define ERRbadPID 70
-#define ERRsetattrmode 71 /* attribute (mode) is invalid */
-#define ERRpaused 81 /* Server is paused */
-#define ERRmsgoff 82 /* reserved - messaging off */
-#define ERRnoroom 83 /* reserved - no room for message */
-#define ERRrmuns 87 /* reserved - too many remote names */
-#define ERRtimeout 88 /* operation timed out */
-#define ERRnoresource 89 /* No resources available for request
- */
-#define ERRtoomanyuids 90 /* Too many UIDs active on this session
- */
-#define ERRbaduid 91 /* The UID is not known as a valid user
- */
-#define ERRusempx 250 /* temporarily unable to use raw */
-#define ERRusestd 251 /* temporarily unable to use either raw
- or mpx */
-#define ERR_NOTIFY_ENUM_DIR 1024
-#define ERRnoSuchUser 2238 /* user account does not exist */
-#define ERRaccountexpired 2239
-#define ERRbadclient 2240 /* can not logon from this client */
-#define ERRbadLogonTime 2241 /* logon hours do not allow this */
-#define ERRpasswordExpired 2242
-#define ERRnetlogonNotStarted 2455
-#define ERRnosupport 0xFFFF
diff --git a/ANDROID_3.4.5/fs/cifs/smbfsctl.h b/ANDROID_3.4.5/fs/cifs/smbfsctl.h
deleted file mode 100644
index 7056b891..00000000
--- a/ANDROID_3.4.5/fs/cifs/smbfsctl.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * fs/cifs/smbfsctl.h: SMB, CIFS, SMB2 FSCTL definitions
- *
- * Copyright (c) International Business Machines Corp., 2002,2009
- * Author(s): Steve French (sfrench@us.ibm.com)
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* IOCTL information */
-/*
- * List of ioctl/fsctl function codes that are or could be useful in the
- * future to remote clients like cifs or SMB2 client. There is probably
- * a slightly larger set of fsctls that NTFS local filesystem could handle,
- * including the seven below that we do not have struct definitions for.
- * Even with protocol definitions for most of these now available, we still
- * need to do some experimentation to identify which are practical to do
- * remotely. Some of the following, such as the encryption/compression ones
- * could be invoked from tools via a specialized hook into the VFS rather
- * than via the standard vfs entry points
- */
-#define FSCTL_REQUEST_OPLOCK_LEVEL_1 0x00090000
-#define FSCTL_REQUEST_OPLOCK_LEVEL_2 0x00090004
-#define FSCTL_REQUEST_BATCH_OPLOCK 0x00090008
-#define FSCTL_LOCK_VOLUME 0x00090018
-#define FSCTL_UNLOCK_VOLUME 0x0009001C
-#define FSCTL_IS_PATHNAME_VALID 0x0009002C /* BB add struct */
-#define FSCTL_GET_COMPRESSION 0x0009003C /* BB add struct */
-#define FSCTL_SET_COMPRESSION 0x0009C040 /* BB add struct */
-#define FSCTL_QUERY_FAT_BPB 0x00090058 /* BB add struct */
-/* Verify the next FSCTL number, we had it as 0x00090090 before */
-#define FSCTL_FILESYSTEM_GET_STATS 0x00090060 /* BB add struct */
-#define FSCTL_GET_NTFS_VOLUME_DATA 0x00090064 /* BB add struct */
-#define FSCTL_GET_RETRIEVAL_POINTERS 0x00090073 /* BB add struct */
-#define FSCTL_IS_VOLUME_DIRTY 0x00090078 /* BB add struct */
-#define FSCTL_ALLOW_EXTENDED_DASD_IO 0x00090083 /* BB add struct */
-#define FSCTL_REQUEST_FILTER_OPLOCK 0x0009008C
-#define FSCTL_FIND_FILES_BY_SID 0x0009008F /* BB add struct */
-#define FSCTL_SET_OBJECT_ID 0x00090098 /* BB add struct */
-#define FSCTL_GET_OBJECT_ID 0x0009009C /* BB add struct */
-#define FSCTL_DELETE_OBJECT_ID 0x000900A0 /* BB add struct */
-#define FSCTL_SET_REPARSE_POINT 0x000900A4 /* BB add struct */
-#define FSCTL_GET_REPARSE_POINT 0x000900A8 /* BB add struct */
-#define FSCTL_DELETE_REPARSE_POINT 0x000900AC /* BB add struct */
-#define FSCTL_SET_OBJECT_ID_EXTENDED 0x000900BC /* BB add struct */
-#define FSCTL_CREATE_OR_GET_OBJECT_ID 0x000900C0 /* BB add struct */
-#define FSCTL_SET_SPARSE 0x000900C4 /* BB add struct */
-#define FSCTL_SET_ZERO_DATA 0x000900C8 /* BB add struct */
-#define FSCTL_SET_ENCRYPTION 0x000900D7 /* BB add struct */
-#define FSCTL_ENCRYPTION_FSCTL_IO 0x000900DB /* BB add struct */
-#define FSCTL_WRITE_RAW_ENCRYPTED 0x000900DF /* BB add struct */
-#define FSCTL_READ_RAW_ENCRYPTED 0x000900E3 /* BB add struct */
-#define FSCTL_READ_FILE_USN_DATA 0x000900EB /* BB add struct */
-#define FSCTL_WRITE_USN_CLOSE_RECORD 0x000900EF /* BB add struct */
-#define FSCTL_SIS_COPYFILE 0x00090100 /* BB add struct */
-#define FSCTL_RECALL_FILE 0x00090117 /* BB add struct */
-#define FSCTL_QUERY_SPARING_INFO 0x00090138 /* BB add struct */
-#define FSCTL_SET_ZERO_ON_DEALLOC 0x00090194 /* BB add struct */
-#define FSCTL_SET_SHORT_NAME_BEHAVIOR 0x000901B4 /* BB add struct */
-#define FSCTL_QUERY_ALLOCATED_RANGES 0x000940CF /* BB add struct */
-#define FSCTL_SET_DEFECT_MANAGEMENT 0x00098134 /* BB add struct */
-#define FSCTL_SIS_LINK_FILES 0x0009C104
-#define FSCTL_PIPE_PEEK 0x0011400C /* BB add struct */
-#define FSCTL_PIPE_TRANSCEIVE 0x0011C017 /* BB add struct */
-/* strange that the number for this op is not sequential with previous op */
-#define FSCTL_PIPE_WAIT 0x00110018 /* BB add struct */
-#define FSCTL_LMR_GET_LINK_TRACK_INF 0x001400E8 /* BB add struct */
-#define FSCTL_LMR_SET_LINK_TRACK_INF 0x001400EC /* BB add struct */
-
-#define IO_REPARSE_TAG_MOUNT_POINT 0xA0000003
-#define IO_REPARSE_TAG_HSM 0xC0000004
-#define IO_REPARSE_TAG_SIS 0x80000007
diff --git a/ANDROID_3.4.5/fs/cifs/transport.c b/ANDROID_3.4.5/fs/cifs/transport.c
deleted file mode 100644
index 09613365..00000000
--- a/ANDROID_3.4.5/fs/cifs/transport.c
+++ /dev/null
@@ -1,956 +0,0 @@
-/*
- * fs/cifs/transport.c
- *
- * Copyright (C) International Business Machines Corp., 2002,2008
- * Author(s): Steve French (sfrench@us.ibm.com)
- * Jeremy Allison (jra@samba.org) 2006.
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/fs.h>
-#include <linux/list.h>
-#include <linux/gfp.h>
-#include <linux/wait.h>
-#include <linux/net.h>
-#include <linux/delay.h>
-#include <linux/freezer.h>
-#include <asm/uaccess.h>
-#include <asm/processor.h>
-#include <linux/mempool.h>
-#include "cifspdu.h"
-#include "cifsglob.h"
-#include "cifsproto.h"
-#include "cifs_debug.h"
-
-extern mempool_t *cifs_mid_poolp;
-
-static void
-wake_up_task(struct mid_q_entry *mid)
-{
- wake_up_process(mid->callback_data);
-}
-
-struct mid_q_entry *
-AllocMidQEntry(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)
-{
- struct mid_q_entry *temp;
-
- if (server == NULL) {
- cERROR(1, "Null TCP session in AllocMidQEntry");
- return NULL;
- }
-
- temp = mempool_alloc(cifs_mid_poolp, GFP_NOFS);
- if (temp == NULL)
- return temp;
- else {
- memset(temp, 0, sizeof(struct mid_q_entry));
- temp->mid = smb_buffer->Mid; /* always LE */
- temp->pid = current->pid;
- temp->command = cpu_to_le16(smb_buffer->Command);
- cFYI(1, "For smb_command %d", smb_buffer->Command);
- /* do_gettimeofday(&temp->when_sent);*/ /* easier to use jiffies */
- /* when mid allocated can be before when sent */
- temp->when_alloc = jiffies;
-
- /*
- * The default is for the mid to be synchronous, so the
- * default callback just wakes up the current task.
- */
- temp->callback = wake_up_task;
- temp->callback_data = current;
- }
-
- atomic_inc(&midCount);
- temp->mid_state = MID_REQUEST_ALLOCATED;
- return temp;
-}
-
-void
-DeleteMidQEntry(struct mid_q_entry *midEntry)
-{
-#ifdef CONFIG_CIFS_STATS2
- unsigned long now;
-#endif
- midEntry->mid_state = MID_FREE;
- atomic_dec(&midCount);
- if (midEntry->large_buf)
- cifs_buf_release(midEntry->resp_buf);
- else
- cifs_small_buf_release(midEntry->resp_buf);
-#ifdef CONFIG_CIFS_STATS2
- now = jiffies;
- /* commands taking longer than one second are indications that
- something is wrong, unless it is quite a slow link or server */
- if ((now - midEntry->when_alloc) > HZ) {
- if ((cifsFYI & CIFS_TIMER) &&
- (midEntry->command != cpu_to_le16(SMB_COM_LOCKING_ANDX))) {
- printk(KERN_DEBUG " CIFS slow rsp: cmd %d mid %llu",
- midEntry->command, midEntry->mid);
- printk(" A: 0x%lx S: 0x%lx R: 0x%lx\n",
- now - midEntry->when_alloc,
- now - midEntry->when_sent,
- now - midEntry->when_received);
- }
- }
-#endif
- mempool_free(midEntry, cifs_mid_poolp);
-}
-
-static void
-delete_mid(struct mid_q_entry *mid)
-{
- spin_lock(&GlobalMid_Lock);
- list_del(&mid->qhead);
- spin_unlock(&GlobalMid_Lock);
-
- DeleteMidQEntry(mid);
-}
-
-static int
-smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
-{
- int rc = 0;
- int i = 0;
- struct msghdr smb_msg;
- __be32 *buf_len = (__be32 *)(iov[0].iov_base);
- unsigned int len = iov[0].iov_len;
- unsigned int total_len;
- int first_vec = 0;
- unsigned int smb_buf_length = get_rfc1002_length(iov[0].iov_base);
- struct socket *ssocket = server->ssocket;
-
- if (ssocket == NULL)
- return -ENOTSOCK; /* BB eventually add reconnect code here */
-
- smb_msg.msg_name = (struct sockaddr *) &server->dstaddr;
- smb_msg.msg_namelen = sizeof(struct sockaddr);
- smb_msg.msg_control = NULL;
- smb_msg.msg_controllen = 0;
- if (server->noblocksnd)
- smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL;
- else
- smb_msg.msg_flags = MSG_NOSIGNAL;
-
- total_len = 0;
- for (i = 0; i < n_vec; i++)
- total_len += iov[i].iov_len;
-
- cFYI(1, "Sending smb: total_len %d", total_len);
- dump_smb(iov[0].iov_base, len);
-
- i = 0;
- while (total_len) {
- rc = kernel_sendmsg(ssocket, &smb_msg, &iov[first_vec],
- n_vec - first_vec, total_len);
- if ((rc == -ENOSPC) || (rc == -EAGAIN)) {
- i++;
- /*
- * If blocking send we try 3 times, since each can block
- * for 5 seconds. For nonblocking we have to try more
- * but wait increasing amounts of time allowing time for
- * socket to clear. The overall time we wait in either
- * case to send on the socket is about 15 seconds.
- * Similarly we wait for 15 seconds for a response from
- * the server in SendReceive[2] for the server to send
- * a response back for most types of requests (except
- * SMB Write past end of file which can be slow, and
- * blocking lock operations). NFS waits slightly longer
- * than CIFS, but this can make it take longer for
- * nonresponsive servers to be detected and 15 seconds
- * is more than enough time for modern networks to
- * send a packet. In most cases if we fail to send
- * after the retries we will kill the socket and
- * reconnect which may clear the network problem.
- */
- if ((i >= 14) || (!server->noblocksnd && (i > 2))) {
- cERROR(1, "sends on sock %p stuck for 15 seconds",
- ssocket);
- rc = -EAGAIN;
- break;
- }
- msleep(1 << i);
- continue;
- }
- if (rc < 0)
- break;
-
- if (rc == total_len) {
- total_len = 0;
- break;
- } else if (rc > total_len) {
- cERROR(1, "sent %d requested %d", rc, total_len);
- break;
- }
- if (rc == 0) {
- /* should never happen, letting socket clear before
- retrying is our only obvious option here */
- cERROR(1, "tcp sent no data");
- msleep(500);
- continue;
- }
- total_len -= rc;
- /* the line below resets i */
- for (i = first_vec; i < n_vec; i++) {
- if (iov[i].iov_len) {
- if (rc > iov[i].iov_len) {
- rc -= iov[i].iov_len;
- iov[i].iov_len = 0;
- } else {
- iov[i].iov_base += rc;
- iov[i].iov_len -= rc;
- first_vec = i;
- break;
- }
- }
- }
- i = 0; /* in case we get ENOSPC on the next send */
- }
-
- if ((total_len > 0) && (total_len != smb_buf_length + 4)) {
- cFYI(1, "partial send (%d remaining), terminating session",
- total_len);
- /* If we have only sent part of an SMB then the next SMB
- could be taken as the remainder of this one. We need
- to kill the socket so the server throws away the partial
- SMB */
- server->tcpStatus = CifsNeedReconnect;
- }
-
- if (rc < 0 && rc != -EINTR)
- cERROR(1, "Error %d sending data on socket to server", rc);
- else
- rc = 0;
-
- /* Don't want to modify the buffer as a side effect of this call. */
- *buf_len = cpu_to_be32(smb_buf_length);
-
- return rc;
-}
-
-int
-smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer,
- unsigned int smb_buf_length)
-{
- struct kvec iov;
-
- iov.iov_base = smb_buffer;
- iov.iov_len = smb_buf_length + 4;
-
- return smb_sendv(server, &iov, 1);
-}
-
-static int
-wait_for_free_credits(struct TCP_Server_Info *server, const int optype,
- int *credits)
-{
- int rc;
-
- spin_lock(&server->req_lock);
- if (optype == CIFS_ASYNC_OP) {
- /* oplock breaks must not be held up */
- server->in_flight++;
- *credits -= 1;
- spin_unlock(&server->req_lock);
- return 0;
- }
-
- while (1) {
- if (*credits <= 0) {
- spin_unlock(&server->req_lock);
- cifs_num_waiters_inc(server);
- rc = wait_event_killable(server->request_q,
- has_credits(server, credits));
- cifs_num_waiters_dec(server);
- if (rc)
- return rc;
- spin_lock(&server->req_lock);
- } else {
- if (server->tcpStatus == CifsExiting) {
- spin_unlock(&server->req_lock);
- return -ENOENT;
- }
-
- /*
- * Can not count locking commands against total
- * as they are allowed to block on server.
- */
-
- /* update # of requests on the wire to server */
- if (optype != CIFS_BLOCKING_OP) {
- *credits -= 1;
- server->in_flight++;
- }
- spin_unlock(&server->req_lock);
- break;
- }
- }
- return 0;
-}
-
-static int
-wait_for_free_request(struct TCP_Server_Info *server, const int optype)
-{
- return wait_for_free_credits(server, optype, get_credits_field(server));
-}
-
-static int allocate_mid(struct cifs_ses *ses, struct smb_hdr *in_buf,
- struct mid_q_entry **ppmidQ)
-{
- if (ses->server->tcpStatus == CifsExiting) {
- return -ENOENT;
- }
-
- if (ses->server->tcpStatus == CifsNeedReconnect) {
- cFYI(1, "tcp session dead - return to caller to retry");
- return -EAGAIN;
- }
-
- if (ses->status != CifsGood) {
- /* check if SMB session is bad because we are setting it up */
- if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) &&
- (in_buf->Command != SMB_COM_NEGOTIATE))
- return -EAGAIN;
- /* else ok - we are setting up session */
- }
- *ppmidQ = AllocMidQEntry(in_buf, ses->server);
- if (*ppmidQ == NULL)
- return -ENOMEM;
- spin_lock(&GlobalMid_Lock);
- list_add_tail(&(*ppmidQ)->qhead, &ses->server->pending_mid_q);
- spin_unlock(&GlobalMid_Lock);
- return 0;
-}
-
-static int
-wait_for_response(struct TCP_Server_Info *server, struct mid_q_entry *midQ)
-{
- int error;
-
- error = wait_event_freezekillable(server->response_q,
- midQ->mid_state != MID_REQUEST_SUBMITTED);
- if (error < 0)
- return -ERESTARTSYS;
-
- return 0;
-}
-
-static int
-cifs_setup_async_request(struct TCP_Server_Info *server, struct kvec *iov,
- unsigned int nvec, struct mid_q_entry **ret_mid)
-{
- int rc;
- struct smb_hdr *hdr = (struct smb_hdr *)iov[0].iov_base;
- struct mid_q_entry *mid;
-
- /* enable signing if server requires it */
- if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
- hdr->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
-
- mid = AllocMidQEntry(hdr, server);
- if (mid == NULL)
- return -ENOMEM;
-
- /* put it on the pending_mid_q */
- spin_lock(&GlobalMid_Lock);
- list_add_tail(&mid->qhead, &server->pending_mid_q);
- spin_unlock(&GlobalMid_Lock);
-
- rc = cifs_sign_smb2(iov, nvec, server, &mid->sequence_number);
- if (rc)
- delete_mid(mid);
- *ret_mid = mid;
- return rc;
-}
-
-/*
- * Send a SMB request and set the callback function in the mid to handle
- * the result. Caller is responsible for dealing with timeouts.
- */
-int
-cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov,
- unsigned int nvec, mid_receive_t *receive,
- mid_callback_t *callback, void *cbdata, bool ignore_pend)
-{
- int rc;
- struct mid_q_entry *mid;
-
- rc = wait_for_free_request(server, ignore_pend ? CIFS_ASYNC_OP : 0);
- if (rc)
- return rc;
-
- mutex_lock(&server->srv_mutex);
- rc = cifs_setup_async_request(server, iov, nvec, &mid);
- if (rc) {
- mutex_unlock(&server->srv_mutex);
- cifs_add_credits(server, 1);
- wake_up(&server->request_q);
- return rc;
- }
-
- mid->receive = receive;
- mid->callback = callback;
- mid->callback_data = cbdata;
- mid->mid_state = MID_REQUEST_SUBMITTED;
-
- cifs_in_send_inc(server);
- rc = smb_sendv(server, iov, nvec);
- cifs_in_send_dec(server);
- cifs_save_when_sent(mid);
- mutex_unlock(&server->srv_mutex);
-
- if (rc)
- goto out_err;
-
- return rc;
-out_err:
- delete_mid(mid);
- cifs_add_credits(server, 1);
- wake_up(&server->request_q);
- return rc;
-}
-
-/*
- *
- * Send an SMB Request. No response info (other than return code)
- * needs to be parsed.
- *
- * flags indicate the type of request buffer and how long to wait
- * and whether to log NT STATUS code (error) before mapping it to POSIX error
- *
- */
-int
-SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses,
- char *in_buf, int flags)
-{
- int rc;
- struct kvec iov[1];
- int resp_buf_type;
-
- iov[0].iov_base = in_buf;
- iov[0].iov_len = get_rfc1002_length(in_buf) + 4;
- flags |= CIFS_NO_RESP;
- rc = SendReceive2(xid, ses, iov, 1, &resp_buf_type, flags);
- cFYI(DBG2, "SendRcvNoRsp flags %d rc %d", flags, rc);
-
- return rc;
-}
-
-static int
-cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server)
-{
- int rc = 0;
-
- cFYI(1, "%s: cmd=%d mid=%llu state=%d", __func__,
- le16_to_cpu(mid->command), mid->mid, mid->mid_state);
-
- spin_lock(&GlobalMid_Lock);
- switch (mid->mid_state) {
- case MID_RESPONSE_RECEIVED:
- spin_unlock(&GlobalMid_Lock);
- return rc;
- case MID_RETRY_NEEDED:
- rc = -EAGAIN;
- break;
- case MID_RESPONSE_MALFORMED:
- rc = -EIO;
- break;
- case MID_SHUTDOWN:
- rc = -EHOSTDOWN;
- break;
- default:
- list_del_init(&mid->qhead);
- cERROR(1, "%s: invalid mid state mid=%llu state=%d", __func__,
- mid->mid, mid->mid_state);
- rc = -EIO;
- }
- spin_unlock(&GlobalMid_Lock);
-
- DeleteMidQEntry(mid);
- return rc;
-}
-
-/*
- * An NT cancel request header looks just like the original request except:
- *
- * The Command is SMB_COM_NT_CANCEL
- * The WordCount is zeroed out
- * The ByteCount is zeroed out
- *
- * This function mangles an existing request buffer into a
- * SMB_COM_NT_CANCEL request and then sends it.
- */
-static int
-send_nt_cancel(struct TCP_Server_Info *server, struct smb_hdr *in_buf,
- struct mid_q_entry *mid)
-{
- int rc = 0;
-
- /* -4 for RFC1001 length and +2 for BCC field */
- in_buf->smb_buf_length = cpu_to_be32(sizeof(struct smb_hdr) - 4 + 2);
- in_buf->Command = SMB_COM_NT_CANCEL;
- in_buf->WordCount = 0;
- put_bcc(0, in_buf);
-
- mutex_lock(&server->srv_mutex);
- rc = cifs_sign_smb(in_buf, server, &mid->sequence_number);
- if (rc) {
- mutex_unlock(&server->srv_mutex);
- return rc;
- }
- rc = smb_send(server, in_buf, be32_to_cpu(in_buf->smb_buf_length));
- mutex_unlock(&server->srv_mutex);
-
- cFYI(1, "issued NT_CANCEL for mid %u, rc = %d",
- in_buf->Mid, rc);
-
- return rc;
-}
-
-int
-cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server,
- bool log_error)
-{
- unsigned int len = get_rfc1002_length(mid->resp_buf) + 4;
-
- dump_smb(mid->resp_buf, min_t(u32, 92, len));
-
- /* convert the length into a more usable form */
- if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
- struct kvec iov;
-
- iov.iov_base = mid->resp_buf;
- iov.iov_len = len;
- /* FIXME: add code to kill session */
- if (cifs_verify_signature(&iov, 1, server,
- mid->sequence_number + 1) != 0)
- cERROR(1, "Unexpected SMB signature");
- }
-
- /* BB special case reconnect tid and uid here? */
- return map_smb_to_linux_error(mid->resp_buf, log_error);
-}
-
-static int
-cifs_setup_request(struct cifs_ses *ses, struct kvec *iov,
- unsigned int nvec, struct mid_q_entry **ret_mid)
-{
- int rc;
- struct smb_hdr *hdr = (struct smb_hdr *)iov[0].iov_base;
- struct mid_q_entry *mid;
-
- rc = allocate_mid(ses, hdr, &mid);
- if (rc)
- return rc;
- rc = cifs_sign_smb2(iov, nvec, ses->server, &mid->sequence_number);
- if (rc)
- delete_mid(mid);
- *ret_mid = mid;
- return rc;
-}
-
-int
-SendReceive2(const unsigned int xid, struct cifs_ses *ses,
- struct kvec *iov, int n_vec, int *pRespBufType /* ret */,
- const int flags)
-{
- int rc = 0;
- int long_op;
- struct mid_q_entry *midQ;
- char *buf = iov[0].iov_base;
-
- long_op = flags & CIFS_TIMEOUT_MASK;
-
- *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */
-
- if ((ses == NULL) || (ses->server == NULL)) {
- cifs_small_buf_release(buf);
- cERROR(1, "Null session");
- return -EIO;
- }
-
- if (ses->server->tcpStatus == CifsExiting) {
- cifs_small_buf_release(buf);
- return -ENOENT;
- }
-
- /*
- * Ensure that we do not send more than 50 overlapping requests
- * to the same server. We may make this configurable later or
- * use ses->maxReq.
- */
-
- rc = wait_for_free_request(ses->server, long_op);
- if (rc) {
- cifs_small_buf_release(buf);
- return rc;
- }
-
- /*
- * Make sure that we sign in the same order that we send on this socket
- * and avoid races inside tcp sendmsg code that could cause corruption
- * of smb data.
- */
-
- mutex_lock(&ses->server->srv_mutex);
-
- rc = cifs_setup_request(ses, iov, n_vec, &midQ);
- if (rc) {
- mutex_unlock(&ses->server->srv_mutex);
- cifs_small_buf_release(buf);
- /* Update # of requests on wire to server */
- cifs_add_credits(ses->server, 1);
- return rc;
- }
-
- midQ->mid_state = MID_REQUEST_SUBMITTED;
- cifs_in_send_inc(ses->server);
- rc = smb_sendv(ses->server, iov, n_vec);
- cifs_in_send_dec(ses->server);
- cifs_save_when_sent(midQ);
-
- mutex_unlock(&ses->server->srv_mutex);
-
- if (rc < 0) {
- cifs_small_buf_release(buf);
- goto out;
- }
-
- if (long_op == CIFS_ASYNC_OP) {
- cifs_small_buf_release(buf);
- goto out;
- }
-
- rc = wait_for_response(ses->server, midQ);
- if (rc != 0) {
- send_nt_cancel(ses->server, (struct smb_hdr *)buf, midQ);
- spin_lock(&GlobalMid_Lock);
- if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
- midQ->callback = DeleteMidQEntry;
- spin_unlock(&GlobalMid_Lock);
- cifs_small_buf_release(buf);
- cifs_add_credits(ses->server, 1);
- return rc;
- }
- spin_unlock(&GlobalMid_Lock);
- }
-
- cifs_small_buf_release(buf);
-
- rc = cifs_sync_mid_result(midQ, ses->server);
- if (rc != 0) {
- cifs_add_credits(ses->server, 1);
- return rc;
- }
-
- if (!midQ->resp_buf || midQ->mid_state != MID_RESPONSE_RECEIVED) {
- rc = -EIO;
- cFYI(1, "Bad MID state?");
- goto out;
- }
-
- buf = (char *)midQ->resp_buf;
- iov[0].iov_base = buf;
- iov[0].iov_len = get_rfc1002_length(buf) + 4;
- if (midQ->large_buf)
- *pRespBufType = CIFS_LARGE_BUFFER;
- else
- *pRespBufType = CIFS_SMALL_BUFFER;
-
- rc = cifs_check_receive(midQ, ses->server, flags & CIFS_LOG_ERROR);
-
- /* mark it so buf will not be freed by delete_mid */
- if ((flags & CIFS_NO_RESP) == 0)
- midQ->resp_buf = NULL;
-out:
- delete_mid(midQ);
- cifs_add_credits(ses->server, 1);
-
- return rc;
-}
-
-int
-SendReceive(const unsigned int xid, struct cifs_ses *ses,
- struct smb_hdr *in_buf, struct smb_hdr *out_buf,
- int *pbytes_returned, const int long_op)
-{
- int rc = 0;
- struct mid_q_entry *midQ;
-
- if (ses == NULL) {
- cERROR(1, "Null smb session");
- return -EIO;
- }
- if (ses->server == NULL) {
- cERROR(1, "Null tcp session");
- return -EIO;
- }
-
- if (ses->server->tcpStatus == CifsExiting)
- return -ENOENT;
-
- /* Ensure that we do not send more than 50 overlapping requests
- to the same server. We may make this configurable later or
- use ses->maxReq */
-
- if (be32_to_cpu(in_buf->smb_buf_length) > CIFSMaxBufSize +
- MAX_CIFS_HDR_SIZE - 4) {
- cERROR(1, "Illegal length, greater than maximum frame, %d",
- be32_to_cpu(in_buf->smb_buf_length));
- return -EIO;
- }
-
- rc = wait_for_free_request(ses->server, long_op);
- if (rc)
- return rc;
-
- /* make sure that we sign in the same order that we send on this socket
- and avoid races inside tcp sendmsg code that could cause corruption
- of smb data */
-
- mutex_lock(&ses->server->srv_mutex);
-
- rc = allocate_mid(ses, in_buf, &midQ);
- if (rc) {
- mutex_unlock(&ses->server->srv_mutex);
- /* Update # of requests on wire to server */
- cifs_add_credits(ses->server, 1);
- return rc;
- }
-
- rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
- if (rc) {
- mutex_unlock(&ses->server->srv_mutex);
- goto out;
- }
-
- midQ->mid_state = MID_REQUEST_SUBMITTED;
-
- cifs_in_send_inc(ses->server);
- rc = smb_send(ses->server, in_buf, be32_to_cpu(in_buf->smb_buf_length));
- cifs_in_send_dec(ses->server);
- cifs_save_when_sent(midQ);
- mutex_unlock(&ses->server->srv_mutex);
-
- if (rc < 0)
- goto out;
-
- if (long_op == CIFS_ASYNC_OP)
- goto out;
-
- rc = wait_for_response(ses->server, midQ);
- if (rc != 0) {
- send_nt_cancel(ses->server, in_buf, midQ);
- spin_lock(&GlobalMid_Lock);
- if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
- /* no longer considered to be "in-flight" */
- midQ->callback = DeleteMidQEntry;
- spin_unlock(&GlobalMid_Lock);
- cifs_add_credits(ses->server, 1);
- return rc;
- }
- spin_unlock(&GlobalMid_Lock);
- }
-
- rc = cifs_sync_mid_result(midQ, ses->server);
- if (rc != 0) {
- cifs_add_credits(ses->server, 1);
- return rc;
- }
-
- if (!midQ->resp_buf || !out_buf ||
- midQ->mid_state != MID_RESPONSE_RECEIVED) {
- rc = -EIO;
- cERROR(1, "Bad MID state?");
- goto out;
- }
-
- *pbytes_returned = get_rfc1002_length(midQ->resp_buf);
- memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
- rc = cifs_check_receive(midQ, ses->server, 0);
-out:
- delete_mid(midQ);
- cifs_add_credits(ses->server, 1);
-
- return rc;
-}
-
-/* We send a LOCKINGX_CANCEL_LOCK to cause the Windows
- blocking lock to return. */
-
-static int
-send_lock_cancel(const unsigned int xid, struct cifs_tcon *tcon,
- struct smb_hdr *in_buf,
- struct smb_hdr *out_buf)
-{
- int bytes_returned;
- struct cifs_ses *ses = tcon->ses;
- LOCK_REQ *pSMB = (LOCK_REQ *)in_buf;
-
- /* We just modify the current in_buf to change
- the type of lock from LOCKING_ANDX_SHARED_LOCK
- or LOCKING_ANDX_EXCLUSIVE_LOCK to
- LOCKING_ANDX_CANCEL_LOCK. */
-
- pSMB->LockType = LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES;
- pSMB->Timeout = 0;
- pSMB->hdr.Mid = GetNextMid(ses->server);
-
- return SendReceive(xid, ses, in_buf, out_buf,
- &bytes_returned, 0);
-}
-
-int
-SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
- struct smb_hdr *in_buf, struct smb_hdr *out_buf,
- int *pbytes_returned)
-{
- int rc = 0;
- int rstart = 0;
- struct mid_q_entry *midQ;
- struct cifs_ses *ses;
-
- if (tcon == NULL || tcon->ses == NULL) {
- cERROR(1, "Null smb session");
- return -EIO;
- }
- ses = tcon->ses;
-
- if (ses->server == NULL) {
- cERROR(1, "Null tcp session");
- return -EIO;
- }
-
- if (ses->server->tcpStatus == CifsExiting)
- return -ENOENT;
-
- /* Ensure that we do not send more than 50 overlapping requests
- to the same server. We may make this configurable later or
- use ses->maxReq */
-
- if (be32_to_cpu(in_buf->smb_buf_length) > CIFSMaxBufSize +
- MAX_CIFS_HDR_SIZE - 4) {
- cERROR(1, "Illegal length, greater than maximum frame, %d",
- be32_to_cpu(in_buf->smb_buf_length));
- return -EIO;
- }
-
- rc = wait_for_free_request(ses->server, CIFS_BLOCKING_OP);
- if (rc)
- return rc;
-
- /* make sure that we sign in the same order that we send on this socket
- and avoid races inside tcp sendmsg code that could cause corruption
- of smb data */
-
- mutex_lock(&ses->server->srv_mutex);
-
- rc = allocate_mid(ses, in_buf, &midQ);
- if (rc) {
- mutex_unlock(&ses->server->srv_mutex);
- return rc;
- }
-
- rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number);
- if (rc) {
- delete_mid(midQ);
- mutex_unlock(&ses->server->srv_mutex);
- return rc;
- }
-
- midQ->mid_state = MID_REQUEST_SUBMITTED;
- cifs_in_send_inc(ses->server);
- rc = smb_send(ses->server, in_buf, be32_to_cpu(in_buf->smb_buf_length));
- cifs_in_send_dec(ses->server);
- cifs_save_when_sent(midQ);
- mutex_unlock(&ses->server->srv_mutex);
-
- if (rc < 0) {
- delete_mid(midQ);
- return rc;
- }
-
- /* Wait for a reply - allow signals to interrupt. */
- rc = wait_event_interruptible(ses->server->response_q,
- (!(midQ->mid_state == MID_REQUEST_SUBMITTED)) ||
- ((ses->server->tcpStatus != CifsGood) &&
- (ses->server->tcpStatus != CifsNew)));
-
- /* Were we interrupted by a signal ? */
- if ((rc == -ERESTARTSYS) &&
- (midQ->mid_state == MID_REQUEST_SUBMITTED) &&
- ((ses->server->tcpStatus == CifsGood) ||
- (ses->server->tcpStatus == CifsNew))) {
-
- if (in_buf->Command == SMB_COM_TRANSACTION2) {
- /* POSIX lock. We send a NT_CANCEL SMB to cause the
- blocking lock to return. */
- rc = send_nt_cancel(ses->server, in_buf, midQ);
- if (rc) {
- delete_mid(midQ);
- return rc;
- }
- } else {
- /* Windows lock. We send a LOCKINGX_CANCEL_LOCK
- to cause the blocking lock to return. */
-
- rc = send_lock_cancel(xid, tcon, in_buf, out_buf);
-
- /* If we get -ENOLCK back the lock may have
- already been removed. Don't exit in this case. */
- if (rc && rc != -ENOLCK) {
- delete_mid(midQ);
- return rc;
- }
- }
-
- rc = wait_for_response(ses->server, midQ);
- if (rc) {
- send_nt_cancel(ses->server, in_buf, midQ);
- spin_lock(&GlobalMid_Lock);
- if (midQ->mid_state == MID_REQUEST_SUBMITTED) {
- /* no longer considered to be "in-flight" */
- midQ->callback = DeleteMidQEntry;
- spin_unlock(&GlobalMid_Lock);
- return rc;
- }
- spin_unlock(&GlobalMid_Lock);
- }
-
- /* We got the response - restart system call. */
- rstart = 1;
- }
-
- rc = cifs_sync_mid_result(midQ, ses->server);
- if (rc != 0)
- return rc;
-
- /* rcvd frame is ok */
- if (out_buf == NULL || midQ->mid_state != MID_RESPONSE_RECEIVED) {
- rc = -EIO;
- cERROR(1, "Bad MID state?");
- goto out;
- }
-
- *pbytes_returned = get_rfc1002_length(midQ->resp_buf);
- memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4);
- rc = cifs_check_receive(midQ, ses->server, 0);
-out:
- delete_mid(midQ);
- if (rstart && rc == -EACCES)
- return -ERESTARTSYS;
- return rc;
-}
diff --git a/ANDROID_3.4.5/fs/cifs/xattr.c b/ANDROID_3.4.5/fs/cifs/xattr.c
deleted file mode 100644
index 10d92cf5..00000000
--- a/ANDROID_3.4.5/fs/cifs/xattr.c
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * fs/cifs/xattr.c
- *
- * Copyright (c) International Business Machines Corp., 2003, 2007
- * Author(s): Steve French (sfrench@us.ibm.com)
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published
- * by the Free Software Foundation; either version 2.1 of the License, or
- * (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/fs.h>
-#include <linux/posix_acl_xattr.h>
-#include <linux/slab.h>
-#include <linux/xattr.h>
-#include "cifsfs.h"
-#include "cifspdu.h"
-#include "cifsglob.h"
-#include "cifsproto.h"
-#include "cifs_debug.h"
-
-#define MAX_EA_VALUE_SIZE 65535
-#define CIFS_XATTR_DOS_ATTRIB "user.DosAttrib"
-#define CIFS_XATTR_CIFS_ACL "system.cifs_acl"
-
-/* BB need to add server (Samba e.g) support for security and trusted prefix */
-
-int cifs_removexattr(struct dentry *direntry, const char *ea_name)
-{
- int rc = -EOPNOTSUPP;
-#ifdef CONFIG_CIFS_XATTR
- int xid;
- struct cifs_sb_info *cifs_sb;
- struct tcon_link *tlink;
- struct cifs_tcon *pTcon;
- struct super_block *sb;
- char *full_path = NULL;
-
- if (direntry == NULL)
- return -EIO;
- if (direntry->d_inode == NULL)
- return -EIO;
- sb = direntry->d_inode->i_sb;
- if (sb == NULL)
- return -EIO;
-
- cifs_sb = CIFS_SB(sb);
- tlink = cifs_sb_tlink(cifs_sb);
- if (IS_ERR(tlink))
- return PTR_ERR(tlink);
- pTcon = tlink_tcon(tlink);
-
- xid = GetXid();
-
- full_path = build_path_from_dentry(direntry);
- if (full_path == NULL) {
- rc = -ENOMEM;
- goto remove_ea_exit;
- }
- if (ea_name == NULL) {
- cFYI(1, "Null xattr names not supported");
- } else if (strncmp(ea_name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)
- && (strncmp(ea_name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN))) {
- cFYI(1,
- "illegal xattr request %s (only user namespace supported)",
- ea_name);
- /* BB what if no namespace prefix? */
- /* Should we just pass them to server, except for
- system and perhaps security prefixes? */
- } else {
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
- goto remove_ea_exit;
-
- ea_name += XATTR_USER_PREFIX_LEN; /* skip past user. prefix */
- rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, NULL,
- (__u16)0, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
- }
-remove_ea_exit:
- kfree(full_path);
- FreeXid(xid);
- cifs_put_tlink(tlink);
-#endif
- return rc;
-}
-
-int cifs_setxattr(struct dentry *direntry, const char *ea_name,
- const void *ea_value, size_t value_size, int flags)
-{
- int rc = -EOPNOTSUPP;
-#ifdef CONFIG_CIFS_XATTR
- int xid;
- struct cifs_sb_info *cifs_sb;
- struct tcon_link *tlink;
- struct cifs_tcon *pTcon;
- struct super_block *sb;
- char *full_path;
-
- if (direntry == NULL)
- return -EIO;
- if (direntry->d_inode == NULL)
- return -EIO;
- sb = direntry->d_inode->i_sb;
- if (sb == NULL)
- return -EIO;
-
- cifs_sb = CIFS_SB(sb);
- tlink = cifs_sb_tlink(cifs_sb);
- if (IS_ERR(tlink))
- return PTR_ERR(tlink);
- pTcon = tlink_tcon(tlink);
-
- xid = GetXid();
-
- full_path = build_path_from_dentry(direntry);
- if (full_path == NULL) {
- rc = -ENOMEM;
- goto set_ea_exit;
- }
- /* return dos attributes as pseudo xattr */
- /* return alt name if available as pseudo attr */
-
- /* if proc/fs/cifs/streamstoxattr is set then
- search server for EAs or streams to
- returns as xattrs */
- if (value_size > MAX_EA_VALUE_SIZE) {
- cFYI(1, "size of EA value too large");
- rc = -EOPNOTSUPP;
- goto set_ea_exit;
- }
-
- if (ea_name == NULL) {
- cFYI(1, "Null xattr names not supported");
- } else if (strncmp(ea_name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)
- == 0) {
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
- goto set_ea_exit;
- if (strncmp(ea_name, CIFS_XATTR_DOS_ATTRIB, 14) == 0)
- cFYI(1, "attempt to set cifs inode metadata");
-
- ea_name += XATTR_USER_PREFIX_LEN; /* skip past user. prefix */
- rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, ea_value,
- (__u16)value_size, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
- } else if (strncmp(ea_name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN)
- == 0) {
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
- goto set_ea_exit;
-
- ea_name += XATTR_OS2_PREFIX_LEN; /* skip past os2. prefix */
- rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, ea_value,
- (__u16)value_size, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
- } else if (strncmp(ea_name, CIFS_XATTR_CIFS_ACL,
- strlen(CIFS_XATTR_CIFS_ACL)) == 0) {
-#ifdef CONFIG_CIFS_ACL
- struct cifs_ntsd *pacl;
- pacl = kmalloc(value_size, GFP_KERNEL);
- if (!pacl) {
- cFYI(1, "%s: Can't allocate memory for ACL",
- __func__);
- rc = -ENOMEM;
- } else {
- memcpy(pacl, ea_value, value_size);
- rc = set_cifs_acl(pacl, value_size,
- direntry->d_inode, full_path, CIFS_ACL_DACL);
- if (rc == 0) /* force revalidate of the inode */
- CIFS_I(direntry->d_inode)->time = 0;
- kfree(pacl);
- }
-#else
- cFYI(1, "Set CIFS ACL not supported yet");
-#endif /* CONFIG_CIFS_ACL */
- } else {
- int temp;
- temp = strncmp(ea_name, POSIX_ACL_XATTR_ACCESS,
- strlen(POSIX_ACL_XATTR_ACCESS));
- if (temp == 0) {
-#ifdef CONFIG_CIFS_POSIX
- if (sb->s_flags & MS_POSIXACL)
- rc = CIFSSMBSetPosixACL(xid, pTcon, full_path,
- ea_value, (const int)value_size,
- ACL_TYPE_ACCESS, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- cFYI(1, "set POSIX ACL rc %d", rc);
-#else
- cFYI(1, "set POSIX ACL not supported");
-#endif
- } else if (strncmp(ea_name, POSIX_ACL_XATTR_DEFAULT,
- strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) {
-#ifdef CONFIG_CIFS_POSIX
- if (sb->s_flags & MS_POSIXACL)
- rc = CIFSSMBSetPosixACL(xid, pTcon, full_path,
- ea_value, (const int)value_size,
- ACL_TYPE_DEFAULT, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
- cFYI(1, "set POSIX default ACL rc %d", rc);
-#else
- cFYI(1, "set default POSIX ACL not supported");
-#endif
- } else {
- cFYI(1, "illegal xattr request %s (only user namespace"
- " supported)", ea_name);
- /* BB what if no namespace prefix? */
- /* Should we just pass them to server, except for
- system and perhaps security prefixes? */
- }
- }
-
-set_ea_exit:
- kfree(full_path);
- FreeXid(xid);
- cifs_put_tlink(tlink);
-#endif
- return rc;
-}
-
-ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
- void *ea_value, size_t buf_size)
-{
- ssize_t rc = -EOPNOTSUPP;
-#ifdef CONFIG_CIFS_XATTR
- int xid;
- struct cifs_sb_info *cifs_sb;
- struct tcon_link *tlink;
- struct cifs_tcon *pTcon;
- struct super_block *sb;
- char *full_path;
-
- if (direntry == NULL)
- return -EIO;
- if (direntry->d_inode == NULL)
- return -EIO;
- sb = direntry->d_inode->i_sb;
- if (sb == NULL)
- return -EIO;
-
- cifs_sb = CIFS_SB(sb);
- tlink = cifs_sb_tlink(cifs_sb);
- if (IS_ERR(tlink))
- return PTR_ERR(tlink);
- pTcon = tlink_tcon(tlink);
-
- xid = GetXid();
-
- full_path = build_path_from_dentry(direntry);
- if (full_path == NULL) {
- rc = -ENOMEM;
- goto get_ea_exit;
- }
- /* return dos attributes as pseudo xattr */
- /* return alt name if available as pseudo attr */
- if (ea_name == NULL) {
- cFYI(1, "Null xattr names not supported");
- } else if (strncmp(ea_name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)
- == 0) {
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
- goto get_ea_exit;
-
- if (strncmp(ea_name, CIFS_XATTR_DOS_ATTRIB, 14) == 0) {
- cFYI(1, "attempt to query cifs inode metadata");
- /* revalidate/getattr then populate from inode */
- } /* BB add else when above is implemented */
- ea_name += XATTR_USER_PREFIX_LEN; /* skip past user. prefix */
- rc = CIFSSMBQAllEAs(xid, pTcon, full_path, ea_name, ea_value,
- buf_size, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
- } else if (strncmp(ea_name, XATTR_OS2_PREFIX, XATTR_OS2_PREFIX_LEN) == 0) {
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
- goto get_ea_exit;
-
- ea_name += XATTR_OS2_PREFIX_LEN; /* skip past os2. prefix */
- rc = CIFSSMBQAllEAs(xid, pTcon, full_path, ea_name, ea_value,
- buf_size, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
- } else if (strncmp(ea_name, POSIX_ACL_XATTR_ACCESS,
- strlen(POSIX_ACL_XATTR_ACCESS)) == 0) {
-#ifdef CONFIG_CIFS_POSIX
- if (sb->s_flags & MS_POSIXACL)
- rc = CIFSSMBGetPosixACL(xid, pTcon, full_path,
- ea_value, buf_size, ACL_TYPE_ACCESS,
- cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
-#else
- cFYI(1, "Query POSIX ACL not supported yet");
-#endif /* CONFIG_CIFS_POSIX */
- } else if (strncmp(ea_name, POSIX_ACL_XATTR_DEFAULT,
- strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) {
-#ifdef CONFIG_CIFS_POSIX
- if (sb->s_flags & MS_POSIXACL)
- rc = CIFSSMBGetPosixACL(xid, pTcon, full_path,
- ea_value, buf_size, ACL_TYPE_DEFAULT,
- cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
-#else
- cFYI(1, "Query POSIX default ACL not supported yet");
-#endif /* CONFIG_CIFS_POSIX */
- } else if (strncmp(ea_name, CIFS_XATTR_CIFS_ACL,
- strlen(CIFS_XATTR_CIFS_ACL)) == 0) {
-#ifdef CONFIG_CIFS_ACL
- u32 acllen;
- struct cifs_ntsd *pacl;
-
- pacl = get_cifs_acl(cifs_sb, direntry->d_inode,
- full_path, &acllen);
- if (IS_ERR(pacl)) {
- rc = PTR_ERR(pacl);
- cERROR(1, "%s: error %zd getting sec desc",
- __func__, rc);
- } else {
- if (ea_value) {
- if (acllen > buf_size)
- acllen = -ERANGE;
- else
- memcpy(ea_value, pacl, acllen);
- }
- rc = acllen;
- kfree(pacl);
- }
-#else
- cFYI(1, "Query CIFS ACL not supported yet");
-#endif /* CONFIG_CIFS_ACL */
- } else if (strncmp(ea_name,
- XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) == 0) {
- cFYI(1, "Trusted xattr namespace not supported yet");
- } else if (strncmp(ea_name,
- XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) == 0) {
- cFYI(1, "Security xattr namespace not supported yet");
- } else
- cFYI(1,
- "illegal xattr request %s (only user namespace supported)",
- ea_name);
-
- /* We could add an additional check for streams ie
- if proc/fs/cifs/streamstoxattr is set then
- search server for EAs or streams to
- returns as xattrs */
-
- if (rc == -EINVAL)
- rc = -EOPNOTSUPP;
-
-get_ea_exit:
- kfree(full_path);
- FreeXid(xid);
- cifs_put_tlink(tlink);
-#endif
- return rc;
-}
-
-ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size)
-{
- ssize_t rc = -EOPNOTSUPP;
-#ifdef CONFIG_CIFS_XATTR
- int xid;
- struct cifs_sb_info *cifs_sb;
- struct tcon_link *tlink;
- struct cifs_tcon *pTcon;
- struct super_block *sb;
- char *full_path;
-
- if (direntry == NULL)
- return -EIO;
- if (direntry->d_inode == NULL)
- return -EIO;
- sb = direntry->d_inode->i_sb;
- if (sb == NULL)
- return -EIO;
-
- cifs_sb = CIFS_SB(sb);
- if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
- return -EOPNOTSUPP;
-
- tlink = cifs_sb_tlink(cifs_sb);
- if (IS_ERR(tlink))
- return PTR_ERR(tlink);
- pTcon = tlink_tcon(tlink);
-
- xid = GetXid();
-
- full_path = build_path_from_dentry(direntry);
- if (full_path == NULL) {
- rc = -ENOMEM;
- goto list_ea_exit;
- }
- /* return dos attributes as pseudo xattr */
- /* return alt name if available as pseudo attr */
-
- /* if proc/fs/cifs/streamstoxattr is set then
- search server for EAs or streams to
- returns as xattrs */
- rc = CIFSSMBQAllEAs(xid, pTcon, full_path, NULL, data,
- buf_size, cifs_sb->local_nls,
- cifs_sb->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
-
-list_ea_exit:
- kfree(full_path);
- FreeXid(xid);
- cifs_put_tlink(tlink);
-#endif
- return rc;
-}