diff mbox

[CIFS] Add structure definitions for SMB2 PDUs

Message ID AANLkTin7S9baWgbaHXXVFWx50kj2bsDj-XqdQ-OZ=zzY@mail.gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Steve French Feb. 26, 2011, 5:25 a.m. UTC
None
diff mbox

Patch

diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
index 2ff2921..7198de1 100644
--- a/fs/cifs/cifs_debug.c
+++ b/fs/cifs/cifs_debug.c
@@ -251,14 +251,14 @@  static const struct file_operations
cifs_debug_data_proc_fops = {
 #ifdef CONFIG_CIFS_STATS

 #ifdef CONFIG_CIFS_SMB2
-static void smb2_clear_stats(struct smb2_tcon *tcon)
+static void smb2_clear_stats(struct cifsTconInfo *tcon)
 {
 	int i;

 	atomic_set(&tcon->num_smbs_sent, 0);
 	for (i = 0; i < NUMBER_OF_SMB2_COMMANDS; i++) {
-		atomic_set(&tcon->stats->smb2_stats->smb2_com_sent[i], 0);
-		atomic_set(&tcon->stats->smb2_stats->smb2_com_fail[i], 0);
+		atomic_set(&tcon->stats.smb2_stats.smb2_com_sent[i], 0);
+		atomic_set(&tcon->stats.smb2_stats.smb2_com_fail[i], 0);
 	}
 }
 #endif /* CONFIG_CIFS_SMB2 */
@@ -268,8 +268,10 @@  static void clear_cifs_stats(struct cifsTconInfo *tcon)
 	atomic_set(&tcon->num_smbs_sent, 0);

 #ifdef CONFIG_CIFS_SMB2
-	if (tcon->ses->server->is_smb2)
-		return smb2_clear_smb2_stats;
+	if (tcon->ses->server->is_smb2) {
+		smb2_clear_stats(tcon);
+		return;
+	}
 #endif /* CONFIG_CIFS_SMB2 */

 	/* cifs specific statistics, not applicable to smb2 sessions */
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 232b790..854784a 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -27,6 +27,9 @@ 
 #include "cifsacl.h"
 #include <crypto/internal/hash.h>
 #include <linux/scatterlist.h>
+#ifdef CONFIG_CIFS_SMB2
+#include "smb2glob.h"
+#endif /* CONFIG_CIFS_SMB2 */

 /*
  * The sizes of various internal tables and strings
@@ -223,9 +226,9 @@  struct TCP_Server_Info {
 	wait_queue_head_t read_q; /* used by readpages */
 	atomic_t active_readpage_req; /* used by readpages */
 	atomic_t resp_rdy; /* used by readpages and demultiplex */
-	__le16 smb21_minor version; /* SMB2.0 implemented, but 2.1 recognized */
+	__le16 smb21_minor_version; /* SMB2.0 implemented, but 2.1 recognized */
 	struct task_struct *observe;
-	char smb2_crypt_key[SMB2_CRYPTO_KEY_SIZE]; /* BB can we use cifs key */
+/*	char smb2_crypt_key[SMB2_CRYPTO_KEY_SIZE];  BB can we use cifs key? */
 	__u64 current_smb2_mid;         /* multiplex id - rotating counter */
 	__u8  speed;  /* helps us identify if this is a slow link */
 #endif /* CONFIG_CIFS_SMB2 */
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 6354ed5..38510ac 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1036,7 +1036,7 @@  cifs_parse_mount_options(char *options, const
char *devname,
 			} else if ((strnicmp(value, "smb2", 4) == 0) ||
 				   (strnicmp(value, "2", 1) == 0)) {
 #ifdef CONFIG_CIFS_SMB2
-				use_smb2 = true;
+				vol->use_smb2 = true;
 #else
 				cERROR(1, "smb2 support not enabled");
 #endif /* CONFIG_CIFS_SMB2 */
diff --git a/fs/cifs/smb2glob.h b/fs/cifs/smb2glob.h
new file mode 100644
index 0000000..68bf07b
--- /dev/null
+++ b/fs/cifs/smb2glob.h
@@ -0,0 +1,255 @@ 
+/*
+ *   fs/smb2/smb2glob.h
+ *
+ *   Definitions for various global variables and structures
+ *
+ *   Copyright (C) International Business Machines  Corp., 2002,2011
+ *   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.
+ *
+ */
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/workqueue.h>
+#include "smb2pdu.h"
+
+/*
+ * The sizes of various internal tables and strings
+ */
+
+#define SMB2_MIN_RCV_POOL 4
+
+
+/*
+ *****************************************************************
+ * Except the SMB2 PDUs themselves all the
+ * globally interesting structs should go here
+ *****************************************************************
+ */
+
+#define SMB2_OBSERVE_CHECK_TIME	20
+#define SMB2_OBSERVE_DELETE_TIME	45
+
+/* Values for tcon->speed set by echo command */
+#define SMB2_ECHO_FAST		1	/* Less than 3 jiffies, 12ms	     */
+#define SMB2_ECHO_OK		2	/* Less than 15 jiffies, 60ms	     */
+#define SMB2_ECHO_SLOW		3	/* Less than 125 jiffies, 1/2 sec    */
+#define SMB2_ECHO_VERY_SLOW	4	/* Less than 1000 jiffies, 4 seconds */
+#define SMB2_ECHO_TIMEOUT	5	/* Else Too long, server is sick ... */
+
+/*
+ * This info hangs off the smb2_file structure, pointed to by llist.
+ * This is used to track byte stream locks on the file
+ */
+struct smb2_lock {
+	struct list_head llist;	/* pointer to next smb2_lock */
+	__u64 offset;
+	__u64 length;
+	__u32 flags;
+};
+
+/*
+ * One of these for each open instance of a file
+ */
+struct smb2_search {
+	loff_t index_of_last_entry;
+	__u16 entries_in_buf;
+	__u32 resume_key;
+	char *ntwrk_buf_start;
+	char *srch_entries_start;
+	char *last_entry;
+	char *presume_name;
+	unsigned int resume_name_len;
+	bool search_end:1;
+	bool empty_dir:1;
+	bool small_buf:1; /* so we know which buf_release function to call */
+};
+
+struct smb2_file {
+	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 */
+	u64 persist_fid;
+	u64 volatile_fid;
+	/* BB add lock scope info here if needed */ ;
+	/* lock scope id (0 if none) */
+	struct dentry *dentry; /* needed for writepage and oplock break */
+	struct mutex lock_mutex;
+	struct list_head llist; /* list of byte range locks we have. */
+	unsigned int f_flags;
+	bool close_pend:1;	/* file is marked to close */
+	bool invalid_handle:1;	/* file closed via session abend */
+	bool message_mode:1;	/* for pipes: message vs byte mode */
+	bool is_dir:1;		/* Open directory rather than file */
+	bool oplock_break_cancelled:1;
+	atomic_t count;		/* reference count */
+	atomic_t wrt_pending;   /* handle in use - defer close */
+	struct work_struct oplock_break; /* work for oplock breaks */
+	struct mutex fh_mutex; /* prevents reopen race after dead ses*/
+	struct smb2_search srch_inf;
+};
+
+/*
+ * One of these for each file inode
+ */
+
+struct smb2_inode {
+	struct list_head lock_list;
+	/* BB add in lists for dirty pages i.e. write caching info for oplock */
+	struct list_head open_file_list;
+	int write_behind_rc;
+	__u32 dos_attrs; /* e.g. DOS archive bit, sparse, compressed, system */
+	__u32 ea_size;
+	unsigned long time;	/* jiffies of last update/check of inode */
+	u64 server_eof;  /* current file size on server */
+	bool can_cache_read:1;	/* read oplock */
+	bool can_cache_all:1;	/* read and writebehind oplock */
+	bool can_defer_close:1; /* batch oplock: as above but can defer close */
+	bool oplock_pending:1;
+	bool delete_pending:1;	/* DELETE_ON_CLOSE is set */
+	u64 uniqueid; /* server inode number */
+	struct fscache_cookie *fscache;
+	struct inode vfs_inode;
+};
+
+static inline struct smb2_inode *
+SMB2_I(struct inode *inode)
+{
+	return container_of(inode, struct smb2_inode, vfs_inode);
+}
+
+
+static inline void smb2_file_get(struct smb2_file *smb2_file)
+{
+	atomic_inc(&smb2_file->count);
+}
+
+/* Release a reference on the file private data */
+/* BB see file.c cifsFileInfo_put MUSTFIX BB */
+static inline void smb2_file_put(struct smb2_file *smb2_file)
+{
+	if (atomic_dec_and_test(&smb2_file->count)) {
+		iput(smb2_file->dentry->d_inode);
+		kfree(smb2_file);
+	}
+}
+
+/* Represents a read request in page sized blocks.
+ * Used by smb2_readpages().*/
+struct page_req {
+	struct list_head req_node; /* list of page_req's */
+	struct list_head *page_list_index; /* list of pages */
+	struct address_space *mapping;
+	int num_pages;
+	int read_size;
+	int start_page_index; /* first expected index */
+	int end_page_index; /* last expected index */
+	struct mid_q_entry *midq; /* queue structure for demultiplex */
+};
+
+/* one of these for every pending SMB2 request to the server */
+struct smb2_mid_entry {
+	struct list_head qhead;	/* mids waiting on reply from this server */
+	__u64 mid;		/* multiplex id(s) */
+	__u16 pid;		/* process id */
+	__u32 sequence_number;	/* for signing */ /* BB check if needed */
+	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
+	struct task_struct *tsk;	/* task waiting for response */
+	struct smb2_hdr *resp_buf;	/* response buffer */
+	char **pagebuf_list;	        /* response buffer */
+	int num_pages;
+	int mid_state;	/* wish this were enum but can not pass to wait_event */
+	__le16 command;	/* smb command code */
+	bool async_resp_rcvd:1; /* if server has responded with interim resp */
+	bool large_buf:1;	/* if valid response, is pointer to large buf */
+	bool is_kmap_buf:1;
+/*	bool multi_rsp:1; BB do we have to account for something in SMB2 like
+	we saw multiple trans2 responses for one request (possible in CIFS) */
+	/* Async things */
+	__u64 *mid_list;	/* multiplex id(s) */
+	int *mid_state_list;
+	short int *large_buf_list;
+	unsigned int num_mid;
+	unsigned int act_num_mid;
+	unsigned int num_received;
+	unsigned int cur_id;
+	struct smb2_hdr **resp_buf_list;	/* response buffer */
+	__le16 *command_list;
+	bool async:1;
+	bool complex_mid:1; /* complex entry - consists of several messages */
+	int result;
+	unsigned long last_rsp_time;
+	int (*callback)(struct smb2_mid_entry * , void *);
+	void *callback_data;
+};
+
+
+#define   SMB2SEC_DEF (SMB2SEC_MAY_SIGN | SMB2SEC_MAY_NTLM |
SMB2SEC_MAY_NTLMV2)
+#define   SMB2SEC_MAX (SMB2SEC_MUST_SIGN | SMB2SEC_MUST_NTLMV2)
+#define   SMB2SEC_AUTH_MASK (SMB2SEC_MAY_NTLM | SMB2SEC_MAY_NTLMV2 | \
+			     SMB2SEC_MAY_PLNTXT | SMB2SEC_MAY_KRB5)
+/*
+ *****************************************************************
+ * Constants go here
+ *****************************************************************
+ */
+
+
+/* BB since num credits could be negotiated higher, override with
max_pending */
+#define SMB2_MAX_REQ 256
+
+/* Identifiers for functions that use the open, operation, close pattern
+ * in inode.c:open_op_close() */
+#define SMB2_OP_SET_DELETE 1
+#define SMB2_OP_SET_INFO 2
+#define SMB2_OP_QUERY_INFO 3
+#define SMB2_OP_QUERY_DIR 4
+#define SMB2_OP_MKDIR 5
+#define SMB2_OP_RENAME 6
+
+/* Used when constructing chained read requests. */
+#define CHAINED_REQUEST 1
+#define START_OF_CHAIN 2
+#define END_OF_CHAIN 4
+#define RELATED_REQUEST 8
+
+/*
+ * The externs for various global variables put here.  The actual declarations
+ * of these should be mostly placed at the front of smb2fs.c to be easy to spot
+ */
+
+
+/*
+ *  Global counters, updated atomically
+ */
+extern atomic_t smb2_tcon_reconnect_count;
+
+/* Various Debug counters */
+extern atomic_t smb2_buf_alloc_count;    /* current number allocated */
+#ifdef CONFIG_SMB2_STATS2
+extern atomic_t smb2_total_buf_alloc; /* total allocated over all time */
+extern atomic_t smb2_total_smbuf_alloc;
+#endif
+extern atomic_t smb2_smbuf_alloc_count;
+extern atomic_t smb2_mid_count;
+
+/* Misc globals */
+extern unsigned int SMB2_max_buf_size;  /* max size not including hdr */
+extern unsigned int smb2_min_rcv;    /* min size of big ntwrk buf pool */
+extern unsigned int smb2_min_small;  /* min size of small buf pool */
+extern unsigned int smb2_max_pending; /* MAX requests at once to server*/
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h
new file mode 100644
index 0000000..472496c
--- /dev/null
+++ b/fs/cifs/smb2pdu.h
@@ -0,0 +1,996 @@ 
+/*
+ *   fs/smb2/smb2pdu.h
+ *
+ *   Copyright (c) International Business Machines  Corp., 2009, 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
+ */
+
+#ifndef _SMB2PDU_H
+#define _SMB2PDU_H
+
+#include <net/sock.h>
+
+#define SMB2_PORT 445
+#define RFC1001_PORT 139
+
+/*
+ * Note that, due to trying to use names similar to the protocol
specifications,
+ * there are many mixed case field names in the structures below.  Although
+ * this does not match typical Linux kernel style, it is necessary to be
+ * be able to match against the protocol specfication.
+ *
+ * SMB2 commands
+ * Some commands have minimal (wct=0,bcc=0), or uninteresting, responses
+ * (ie no useful data other than the SMB error code itself) and are marked such
+ * Knowing this helps avoid response buffer allocations and copy in some cases
+ */
+
+/* List is sent on wire as little endian */
+#define SMB2_NEGOTIATE		cpu_to_le16(0x0000)
+#define SMB2_SESSION_SETUP	cpu_to_le16(0x0001)
+#define SMB2_LOGOFF		cpu_to_le16(0x0002) /* trivial request/resp */
+#define SMB2_TREE_CONNECT	cpu_to_le16(0x0003)
+#define SMB2_TREE_DISCONNECT	cpu_to_le16(0x0004) /* trivial req/resp */
+#define SMB2_CREATE		cpu_to_le16(0x0005)
+#define SMB2_CLOSE		cpu_to_le16(0x0006)
+#define SMB2_FLUSH		cpu_to_le16(0x0007) /* trivial resp */
+#define SMB2_READ		cpu_to_le16(0x0008)
+#define SMB2_WRITE		cpu_to_le16(0x0009)
+#define SMB2_LOCK		cpu_to_le16(0x000A)
+#define SMB2_IOCTL		cpu_to_le16(0x000B)
+#define SMB2_CANCEL		cpu_to_le16(0x000C)
+#define SMB2_ECHO		cpu_to_le16(0x000D)
+#define SMB2_QUERY_DIRECTORY	cpu_to_le16(0x000E)
+#define SMB2_CHANGE_NOTIFY	cpu_to_le16(0x000F)
+#define SMB2_QUERY_INFO		cpu_to_le16(0x0010)
+#define SMB2_SET_INFO		cpu_to_le16(0x0011)
+#define SMB2_OPLOCK_BREAK	cpu_to_le16(0x0012)
+
+/* Same List of commands in host endian */
+#define SMB2NEGOTIATE		0x0000
+#define SMB2SESSION_SETUP	0x0001
+#define SMB2LOGOFF		0x0002 /* trivial request/resp */
+#define SMB2TREE_CONNECT	0x0003
+#define SMB2TREE_DISCONNECT	0x0004 /* trivial req/resp */
+#define SMB2CREATE		0x0005
+#define SMB2CLOSE		0x0006
+#define SMB2FLUSH		0x0007 /* trivial resp */
+#define SMB2READ		0x0008
+#define SMB2WRITE		0x0009
+#define SMB2LOCK		0x000A
+#define SMB2IOCTL		0x000B
+#define SMB2CANCEL		0x000C
+#define SMB2ECHO		0x000D
+#define SMB2QUERY_DIRECTORY	0x000E
+#define SMB2CHANGE_NOTIFY	0x000F
+#define SMB2QUERY_INFO		0x0010
+#define SMB2SET_INFO		0x0011
+#define SMB2OPLOCK_BREAK	0x0012
+
+#define NUMBER_OF_SMB2_COMMANDS	0x0013
+
+/*  BB FIXME - analyze following three length fields BB */
+#define MAX_SMB2_SMALL_BUFFER_SIZE 460 /* big enough for most */
+#define MAX_SMB2_HDR_SIZE 0x78 /* 4 len + 64 hdr + (2*24 wct) + 2 bct
+ 2 pad */
+#define SMB2_SMALL_PATH 112 /* allows for one fewer than (460-120)/3 */
+
+/* File Attrubutes */
+
+#define FILE_ATTRIBUTE_READONLY			0x00000001
+#define FILE_ATTRIBUTE_HIDDEN			0x00000002
+#define FILE_ATTRIBUTE_SYSTEM			0x00000004
+#define FILE_ATTRIBUTE_DIRECTORY		0x00000010
+#define FILE_ATTRIBUTE_ARCHIVE			0x00000020
+#define FILE_ATTRIBUTE_NORMAL			0x00000080
+#define FILE_ATTRIBUTE_TEMPORARY		0x00000100
+#define FILE_ATTRIBUTE_SPARSE_FILE		0x00000200
+#define FILE_ATTRIBUTE_REPARSE_POINT		0x00000400
+#define FILE_ATTRIBUTE_COMPRESSED		0x00000800
+#define FILE_ATTRIBUTE_OFFLINE			0x00001000
+#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED	0x00002000
+#define FILE_ATTRIBUTE_ENCRYPTED		0x00004000
+
+/*
+ * SMB2 flag definitions
+ */
+
+#define SMB2FLG_RESPONSE 0x0001    /* this PDU is a response from server */
+
+/*
+ *	SMB2 Header Definition
+ *
+ *	"MBZ" :  Must be Zero
+ *      "BB"  :  BugBug, Something to check/review/analyze later
+ *      "PDU" :  "Protocol Data Unit" (ie a network "frame")
+ *
+ */
+struct smb2_hdr {
+	__be32 smb2_buf_length;	/* big endian on wire */
+				/* length is only two or three bytes - with
+				 one or two byte type preceding it that MBZ */
+	__u8   ProtocolId[4];	/* 0xFE 'S' 'M' 'B' */
+	__le16 StructureSize;	/* 64 */
+	__le16 CreditCharge;	/* MBZ */
+	__le32 Status;		/* Error from server */
+	__le16 Command;
+	__le16 CreditRequest;  /* CreditResponse */
+	__le32 Flags;
+	__le32 NextCommand;
+	__u64  MessageId; 	/* opaque - so can stay little endian */
+	__le32 ProcessId;
+	__u32  TreeId;		/* opaque - so do not make little endian */
+	__u64  SessionId;	/* opaque - so do not make little endian */
+	__u8   Signature[16];
+	/* Usually followed by __le16 StructureSize of request or response
+	   structure which follows */
+} __attribute__((packed));
+
+struct smb2_async_hdr {
+	__be32 smb2_buf_length;	/* big endian on wire */
+				/* length is only two or three bytes - with
+				 one or two byte type preceding it that MBZ */
+	__u8   ProtocolId[4];	/* 0xFE 'S' 'M' 'B' */
+	__le16 StructureSize;	/* 64 */
+	__le16 CreditCharge;	/* MBZ */
+	__le32 Status;		/* Error from server */
+	__le16 Command;
+	__le16 CreditResponse;
+	__le32 Flags;
+	__le32 NextCommand;
+	__u64  MessageId;	/* opaque - so can stay little endian */
+	__u64  AsyncId;
+	__u64  SessionId;	/* opaque - so do not make little endian */
+	__u8   Signature[16];
+	/* Usually followed by __le16 StructureSize of request or response
+	   structure which follows */
+} __attribute__((packed));
+
+struct smb2_pdu {
+	struct smb2_hdr hdr;
+	__le16 StructureSize2; /* size of wct area (varies, request specific) */
+} __attribute__((packed));
+
+/*
+ *	SMB2 flag definitions
+ */
+#define SMB2_FLAGS_SERVER_TO_REDIR	cpu_to_le32(0x00000001) /* Response */
+#define SMB2_FLAGS_ASYNC_COMMAND	cpu_to_le32(0x00000002)
+#define SMB2_FLAGS_RELATED_OPERATIONS	cpu_to_le32(0x00000004)
+#define SMB2_FLAGS_SIGNED		cpu_to_le32(0x00000008)
+#define SMB2_FLAGS_DFS_OPERATIONS	cpu_to_le32(0x10000000)
+
+/*
+ *	Definitions for SMB2 Protocol Data Units (network frames)
+ *
+ *  See MS-SMB2.PDF specification for protocol details.
+ *  The Naming convention is the lower case version of the SMB2
+ *  command code name for the struct. Note that structures must be packed.
+ *
+ */
+struct smb2_err_rsp {
+	struct	smb2_hdr hdr;
+	__le16	StructureSize;
+	__le16	Reserved; /* MBZ */
+	__le32	ByteCount;  /* even if zero, at least one byte follows */
+	__u8	ErrorData[1];  /* variable length */
+}  __attribute__((packed));
+
+/* Symlink error response for error STATUS_STOPPED_ON_SYMLINK
+   Following is the ErrorData structure */
+struct symlink_err_data {
+	__le32	SymLinkLength;
+	__le32	SymLinkErrorTag;
+	__le32	ReparseTag;
+	__le16	ReparseDataLength;
+	__le16	Reserved;	/* MBZ */
+	__le16	SubstituteNameOffset;
+	__le16	SubstituteNameLength;
+	__le16	PrintNameOffset;
+	__le16	PrintNameLength;
+	__le32	Flags;
+	__u8	PathBuffer[0]; /* variable length */
+} __attribute__((packed));
+
+struct smb2_negotiate_req {
+	struct	smb2_hdr hdr;
+	__le16 StructureSize; /* Must be 36 */
+	__le16 DialectCount;
+	__le16 SecurityMode;
+	__le16 Reserved;	/* MBZ */
+	__le32 Capabilities;
+	__u8   ClientGUID[16];	/* MBZ */
+	__le64 ClientStartTime;	/* MBZ */
+	__le16 Dialects[2]; /* variable length */ /* Must include 0x0202 */
+} __attribute__((packed));
+/* SecurityMode flags */
+#define	SMB2_NEGOTIATE_SIGNING_ENABLED	0x0001
+#define SMB2_NEGOTIATE_SIGNING_REQUIRED	0x0002
+/* Capabilities flags */
+#define SMB2_GLOBAL_CAP_DFS		0x00000001
+#define SMB2_GLOBAL_CAP_LEASING		0x00000002 /* Resp only New to SMB2.1 */
+#define SMB2_GLOBAL_CAP_LARGE_MTU	0X00000004 /* Resp only New to SMB2.1 */
+
+struct smb2_negotiate_rsp {
+	struct	smb2_hdr hdr;
+	__le16 StructureSize;	/* Must be 65 */
+	__le16 SecurityMode;
+	__le16 DialectRevision; /* Should be 0x0202 */
+	__le16 Reserved;	/* MBZ */
+	__u8   ServerGUID[16];
+	__le32 Capabilities;
+	__le32 MaxTransactSize;
+	__le32 MaxReadSize;
+	__le32 MaxWriteSize;
+	__le64 SystemTime;	/* MBZ */
+	__le64 ServerStartTime;
+	__le16 SecurityBufferOffset;
+	__le16 SecurityBufferLength;
+	__le32 Reserved2;	/* may be any value, Ignore */
+	__u8   Buffer[1]; 	/* variable length GSS security buffer */
+} __attribute__((packed));
+
+struct sess_setup_req {
+	struct smb2_hdr hdr;
+	__le16 StructureSize; /* Must be 25 */
+	__u8   VcNumber;
+	__u8   SecurityMode;
+	__le32 Capabilities;
+	__le32 Channel;
+	__le16 SecurityBufferOffset;
+	__le16 SecurityBufferLength;
+	__le64 PreviousSessionId;
+	__u8   Buffer[1];	/* variable length GSS security buffer */
+}  __attribute__((packed));
+
+/* Currently defined SessionFlags */
+#define SMB2_SESSION_FLAG_IS_GUEST	0x0001
+#define SMB2_SESSION_FLAG_IS_NULL	0x0002
+struct sess_setup_rsp {
+	struct smb2_hdr hdr;
+	__le16 StructureSize; /* Must be 9 */
+	__le16 SessionFlags;
+	__le16 SecurityBufferOffset;
+	__le16 SecurityBufferLength;
+	__u8   Buffer[1];	/* variable length GSS security buffer */
+}  __attribute__((packed));
+
+struct logoff_req {
+	struct	smb2_hdr hdr;
+	__le16 StructureSize;	/* Must be 4 */
+	__le16 Reserved;
+} __attribute__((packed));
+
+struct logoff_rsp {
+	struct	smb2_hdr hdr;
+	__le16 StructureSize;	/* Must be 4 */
+	__le16 Reserved;
+} __attribute__((packed));
+
+struct tree_connect_req {
+	struct	smb2_hdr hdr;
+	__le16 StructureSize;	/* Must be 9 */
+	__le16 Reserved;
+	__le16 PathOffset;
+	__le16 PathLength;
+	__u8   Buffer[1];	/* variable length */
+} __attribute__((packed));
+
+struct tree_connect_rsp {
+	struct	smb2_hdr hdr;
+	__le16 StructureSize;	/* Must be 16 */
+	__u8   ShareType;  /* see below */
+	__u8   Reserved;
+	__le32 ShareFlags; /* see below */
+	__le32 Capabilities; /* see below */
+	__le32 MaximalAccess;
+} __attribute__((packed));
+
+/* Possible ShareType values */
+#define SMB2_SHARE_TYPE_DISK	0x01
+#define SMB2_SHARE_TYPE_PIPE	0x02
+#define	SMB2_SHARE_TYPE_PRINT	0x03
+
+/* Possible ShareFlags - exactly one and only one of the first 4 caching flags
+   must be set (any of the remaining, SHI1005, flags may be set individually
+   or in combination */
+#define SMB2_SHAREFLAG_MANUAL_CACHING			0x00000000
+#define SMB2_SHAREFLAG_AUTO_CACHING			0x00000010
+#define SMB2_SHAREFLAG_VDO_CACHING			0x00000020
+#define SMB2_SHAREFLAG_NO_CACHING			0x00000030
+#define SHI1005_FLAGS_DFS				0x00000001
+#define SHI1005_FLAGS_DFS_ROOT				0x00000002
+#define SHI1005_FLAGS_RESTRICT_EXCLUSIVE_OPENS		0x00000100
+#define SHI1005_FLAGS_FORCE_SHARED_DELETE		0x00000200
+#define SHI1005_FLAGS_ALLOW_NAMESPACE_CACHING		0x00000400
+#define SHI1005_FLAGS_ACCESS_BASED_DIRECTORY_ENUM	0x00000800
+#define SHI1005_FLAGS_FORCE_LEVELII_OPLOCK		0x00001000
+#define SHI1005_FLAGS_ENABLE_HASH			0x00002000
+
+/* Possible share capabilities */
+#define SMB2_SHARE_CAP_DFS	cpu_to_le32(0x00000008)
+
+struct tree_disconnect_req {
+	struct	smb2_hdr hdr;
+	__le16 StructureSize;	/* Must be 4 */
+	__le16 Reserved;
+}  __attribute__((packed));
+
+struct tree_disconnect_rsp {
+	struct	smb2_hdr hdr;
+	__le16 StructureSize;	/* Must be 4 */
+	__le16 Reserved;
+}  __attribute__((packed));
+
+/* Oplock levels */
+#define SMB2_OPLOCK_LEVEL_NONE		0x00
+#define SMB2_OPLOCK_LEVEL_II		0x01
+#define SMB2_OPLOCK_LEVEL_EXCLUSIVE	0x08
+#define SMB2_OPLOCK_LEVEL_BATCH		0x09
+#define SMB2_OPLOCK_LEVEL_LEASE		0xFF
+
+/* Desired Access Flags */
+#define FILE_READ_DATA_LE		cpu_to_le32(0x00000001)
+#define FILE_WRITE_DATA_LE		cpu_to_le32(0x00000002)
+#define FILE_APPEND_DATA_LE		cpu_to_le32(0x00000004)
+#define FILE_READ_EA_LE			cpu_to_le32(0x00000008)
+#define FILE_WRITE_EA_LE		cpu_to_le32(0x00000010)
+#define FILE_EXECUTE_LE			cpu_to_le32(0x00000020)
+#define FILE_READ_ATTRIBUTES_LE		cpu_to_le32(0x00000080)
+#define FILE_WRITE_ATTRIBUTES_LE	cpu_to_le32(0x00000100)
+#define FILE_DELETE_LE			cpu_to_le32(0x00010000)
+#define FILE_READ_CONTROL_LE		cpu_to_le32(0x00020000)
+#define FILE_WRITE_DAC_LE		cpu_to_le32(0x00040000)
+#define FILE_WRITE_OWNER_LE		cpu_to_le32(0x00080000)
+#define FILE_SYNCHRONIZE_LE		cpu_to_le32(0x00100000)
+#define FILE_ACCESS_SYSTEM_SECURITY_LE	cpu_to_le32(0x01000000)
+#define FILE_MAXIMAL_ACCESS_LE		cpu_to_le32(0x02000000)
+#define FILE_GENERIC_ALL_LE		cpu_to_le32(0x10000000)
+#define FILE_GENERIC_EXECUTE_LE		cpu_to_le32(0x20000000)
+#define FILE_GENERIC_WRITE_LE		cpu_to_le32(0x40000000)
+#define FILE_GENERIC_READ_LE		cpu_to_le32(0x80000000)
+
+/* ShareAccess Flags */
+#define FILE_SHARE_READ_LE		cpu_to_le32(0x00000001)
+#define FILE_SHARE_WRITE_LE		cpu_to_le32(0x00000002)
+#define FILE_SHARE_DELETE_LE		cpu_to_le32(0x00000004)
+#define FILE_SHARE_ALL_LE		cpu_to_le32(0x00000007)
+
+/* CreateDisposition Flags */
+#define FILE_SUPERSEDE_LE		cpu_to_le32(0x00000000)
+#define FILE_OPEN_LE			cpu_to_le32(0x00000001)
+#define FILE_CREATE_LE			cpu_to_le32(0x00000002)
+#define	FILE_OPEN_IF_LE			cpu_to_le32(0x00000003)
+#define FILE_OVERWRITE_LE		cpu_to_le32(0x00000004)
+#define FILE_OVERWRITE_IF_LE		cpu_to_le32(0x00000005)
+
+/* CreateOptions Flags */
+#define FILE_DIRECTORY_FILE_LE		cpu_to_le32(0x00000001)
+#define FILE_WRITE_THROUGH_LE		cpu_to_le32(0x00000002)
+#define FILE_SEQUENTIAL_ONLY_LE		cpu_to_le32(0x00000004)
+#define FILE_NO_INTERMEDIATE_BUFFERRING_LE cpu_to_le32(0x00000008)
+#define FILE_SYNCHRONOUS_IO_ALERT_LE	cpu_to_le32(0x00000010)
+#define FILE_SYNCHRONOUS_IO_NON_ALERT_LE	cpu_to_le32(0x00000020)
+#define FILE_NON_DIRECTORY_FILE_LE	cpu_to_le32(0x00000040)
+#define FILE_COMPLETE_IF_OPLOCKED_LE	cpu_to_le32(0x00000100)
+#define FILE_NO_EA_KNOWLEDGE_LE		cpu_to_le32(0x00000200)
+#define FILE_RANDOM_ACCESS_LE		cpu_to_le32(0x00000800)
+#define FILE_DELETE_ON_CLOSE_LE		cpu_to_le32(0x00001000)
+#define FILE_OPEN_BY_FILE_ID_LE		cpu_to_le32(0x00002000)
+#define FILE_OPEN_FOR_BACKUP_INTENT_LE	cpu_to_le32(0x00004000)
+#define FILE_NO_COMPRESSION_LE		cpu_to_le32(0x00008000)
+#define FILE_RESERVE_OPFILTER_LE	cpu_to_le32(0x00100000)
+#define FILE_OPEN_REPARSE_POINT_LE	cpu_to_le32(0x00200000)
+#define FILE_OPEN_NO_RECALL_LE		cpu_to_le32(0x00400000)
+#define FILE_OPEN_FOR_FREE_SPACE_QUERY_LE cpu_to_le32(0x00800000)
+
+#define FILE_READ_RIGHTS_LE (FILE_READ_DATA_LE | FILE_READ_EA_LE \
+			| FILE_READ_ATTRIBUTES_LE)
+#define FILE_WRITE_RIGHTS_LE (FILE_WRITE_DATA_LE | FILE_APPEND_DATA_LE \
+			| FILE_WRITE_EA_LE | FILE_WRITE_ATTRIBUTES_LE)
+#define FILE_EXEC_RIGHTS_LE (FILE_EXECUTE_LE)
+
+/* Impersonation Levels */
+#define IL_ANONYMOUS		cpu_to_le32(0x00000000)
+#define IL_IDENTIFICATION	cpu_to_le32(0x00000001)
+#define IL_IMPERSONATION	cpu_to_le32(0x00000002)
+#define IL_DELEGATE		cpu_to_le32(0x00000003)
+
+/* Create Context Values */
+#define SMB2_CREATE_EA_BUFFER			"ExtA" /* extended attributes */
+#define SMB2_CREATE_SD_BUFFER			"SecD" /* security descriptor */
+#define SMB2_CREATE_DURABLE_HANDLE_REQUEST	"DHnQ"
+#define SMB2_CREATE_DURABLE_HANDLE_RECONNECT	"DHnC"
+#define SMB2_CREATE_ALLOCATION_SIZE		"AlSi"
+#define SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST "MxAc"
+#define SMB2_CREATE_TIMEWARP_REQUEST		"TWrp"
+#define SMB2_CREATE_QUERY_ON_DISK_ID		"QFid"
+#define SMB2_CREATE_REQUEST_LEASE		"RqLs"
+
+struct create_req {
+	struct	smb2_hdr hdr;
+	__le16 StructureSize;	/* Must be 57 */
+	__u8   SecurityFlags;
+	__u8   RequestedOplockLevel;
+	__le32 ImpersonationLevel;
+	__le64 SmbCreateFlags;
+	__le64 Reserved;
+	__le32 DesiredAccess;
+	__le32 FileAttributes;
+	__le32 ShareAccess;
+	__le32 CreateDisposition;
+	__le32 CreateOptions;
+	__le16 NameOffset;
+	__le16 NameLength;
+	__le32 CreateContextsOffset;
+	__le32 CreateContextsLength;
+	__u8    Buffer[1];
+}  __attribute__((packed));
+
+struct create_rsp {
+	struct	smb2_hdr hdr;
+	__le16 StructureSize;	/* Must be 89 */
+	__u8   OplockLevel;
+	__u8   Reserved;
+	__le32 CreateAction;
+	__le64 CreationTime;
+	__le64 LastAccessTime;
+	__le64 LastWriteTime;
+	__le64 ChangeTime;
+	__le64 AllocationSize;
+	__le64 EndofFile;
+	__le32 FileAttributes;
+	__le32 Reserved2;
+	__u64  PersistentFileId; /* opaque endianness */
+	__u64  VolatileFileId; /* opaque endianness */
+	__le32 CreateContextsOffset;
+	__le32 CreateContextsLength;
+	__u8   Buffer[1];
+}  __attribute__((packed));
+
+/* Currently defined values for close flags */
+#define SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB	cpu_to_le16(0x0001)
+struct close_req {
+	struct	smb2_hdr hdr;
+	__le16 StructureSize;	/* Must be 24 */
+	__le16 Flags;
+	__le32 Reserved;
+	__u64  PersistentFileId; /* opaque endianness */
+	__u64  VolatileFileId; /* opaque endianness */
+}  __attribute__((packed));
+
+struct close_rsp {
+	struct	smb2_hdr hdr;
+	__le16 StructureSize; /* 60 */
+	__le16 Flags;
+	__le32 Reserved;
+	__le64 CreationTime;
+	__le64 LastAccessTime;
+	__le64 LastWriteTime;
+	__le64 ChangeTime;
+	__le64 AllocationSize;	/* Beginning of FILE_STANDARD_INFO equivalent */
+	__le64 EndOfFile;
+	__le32 Attributes;
+} __attribute__((packed));
+
+struct flush_req {
+	struct	smb2_hdr hdr;
+	__le16 StructureSize;	/* Must be 24 */
+	__le16 Reserved1;
+	__le32 Reserved2;
+	__u64  PersistentFileId; /* opaque endianness */
+	__u64  VolatileFileId; /* opaque endianness */
+}  __attribute__((packed));
+
+struct flush_rsp {
+	struct	smb2_hdr hdr;
+	__le16 StructureSize;
+	__le16 Reserved;
+} __attribute__((packed));
+
+struct read_req {
+	struct smb2_hdr hdr;
+	__le16 StructureSize; /* Must be 49 */
+	__u8   Padding; /* offset from start of SMB2 header to place read */
+	__u8   Reserved;
+	__le32 Length;
+	__le64 Offset;
+	__u64  PersistentFileId; /* opaque endianness */
+	__u64  VolatileFileId; /* opaque endianness */
+	__le32 MinimumCount;
+	__le32 Channel; /* Reserved MBZ */
+	__le32 RemainingBytes;
+	__le16 ReadChannelInfoOffset; /* Reserved MBZ */
+	__le16 ReadChannelInfoLength; /* Reserved MBZ */
+	__u8   Buffer[1];
+} __attribute__((packed));
+
+struct read_rsp {
+	struct smb2_hdr hdr;
+	__le16 StructureSize; /* Must be 17 */
+	__u8   DataOffset;
+	__u8   Reserved;
+	__le32 DataLength;
+	__le32 DataRemaining;
+	__u32  Reserved2;
+	__u8   Buffer[1];
+} __attribute__((packed));
+
+/* For write request Flags field below the following flag is defined: */
+#define SMB2_WRITEFLAG_WRITE_THROUGH 0x00000001
+
+struct write_req {
+	struct smb2_hdr hdr;
+	__le16 StructureSize; /* Must be 49 */
+	__le16 DataOffset; /* offset from start of SMB2 header to write data */
+	__le32 Length;
+	__le64 Offset;
+	__u64  PersistentFileId; /* opaque endianness */
+	__u64  VolatileFileId; /* opaque endianness */
+	__le32 Channel; /* Reserved MBZ */
+	__le32 RemainingBytes;
+	__le16 WriteChannelInfoOffset; /* Reserved MBZ */
+	__le16 WriteChannelInfoLength; /* Reserved MBZ */
+	__le32 Flags;
+	__u8   Buffer[1];
+} __attribute__((packed));
+
+struct write_rsp {
+	struct smb2_hdr hdr;
+	__le16 StructureSize; /* Must be 17 */
+	__u8   DataOffset;
+	__u8   Reserved;
+	__le32 DataLength;
+	__le32 DataRemaining;
+	__u32  Reserved2;
+	__u8   Buffer[1];
+} __attribute__((packed));
+
+#define SMB2_LOCKFLAG_SHARED_LOCK	0x0001
+#define SMB2_LOCKFLAG_EXCLUSIVE_LOCK	0x0002
+#define SMB2_LOCKFLAG_UNLOCK		0x0004
+#define SMB2_LOCKFLAG_FAIL_IMMEDIATELY	0x0010
+
+struct smb2_lock_element {
+	__le64 Offset;
+	__le64 Length;
+	__le16 Flags;
+	__le16 Reserved;
+} __attribute__((packed));
+
+#define LOCKING_ANDX_OPLOCK_RELEASE  0x02
+
+struct lock_req {
+	struct smb2_hdr hdr;
+	__le16 StructureSize; /* Must be 48 */
+	__le16 LockCount;
+	__le32 Reserved;
+	__u64  PersistentFileId; /* opaque endianness */
+	__u64  VolatileFileId; /* opaque endianness */
+	/* Followed by at least one */
+	struct smb2_lock_element locks[1];
+} __attribute__((packed));
+
+struct lock_rsp {
+	struct smb2_hdr hdr;
+	__le16 StructureSize; /* Must be 4 */
+	__le16 Reserved;
+} __attribute__((packed));
+
+struct echo_req {
+	struct	smb2_hdr hdr;
+	__le16 StructureSize;	/* Must be 4 */
+	__u16  Reserved;
+} __attribute__((packed));
+
+struct echo_rsp {
+	struct	smb2_hdr hdr;
+	__le16 StructureSize;	/* Must be 4 */
+	__u16  Reserved;
+} __attribute__((packed));
+
+/* search (query_directory) Flags field */
+#define SMB2_RESTART_SCANS		0x01
+#define SMB2_RETURN_SINGLE_ENTRY	0x02
+#define SMB2_INDEX_SPECIFIED		0x04
+#define SMB2_REOPEN			0x10
+
+struct query_directory_req {
+	struct smb2_hdr hdr;
+	__le16 StructureSize; /* Must be 33 */
+	__u8 FileInformationClass;
+	__u8 Flags;
+	__le32 FileIndex;
+	__u64  PersistentFileId; /* opaque endianness */
+	__u64  VolatileFileId; /* opaque endianness */
+	__le16 FileNameOffset;
+	__le16 FileNameLength;
+	__le32 OutputBufferLength;
+	__u8   Buffer[1];
+} __attribute__((packed));
+
+struct query_directory_rsp {
+	struct smb2_hdr hdr;
+	__le16 StructureSize; /* Must be 9 */
+	__le16 OutputBufferOffset;
+	__le32 OutputBufferLength;
+	__u8   Buffer[1];
+} __attribute__((packed));
+
+/* Possible InfoType values */
+#define SMB2_O_INFO_FILE	0x01
+#define SMB2_O_INFO_FILESYSTEM	0x02
+#define SMB2_O_INFO_SECURITY	0x03
+#define SMB2_O_INFO_QUOTA	0x04
+
+struct query_info_req {
+	struct smb2_hdr hdr;
+	__le16 StructureSize; /* Must be 41 */
+	__u8 InfoType;
+	__u8 FileInfoClass;
+	__le32 OutputBufferLength;
+	__le16 InputBufferOffset;
+	__u16  Reserved;
+	__le32 InputBufferLength;
+	__le32 AdditionalInformation;
+	__le32 Flags;
+	__u64  PersistentFileId; /* opaque endianness */
+	__u64  VolatileFileId; /* opaque endianness */
+	__u8   Buffer[1];
+} __attribute__((packed));
+
+struct query_info_rsp {
+	struct smb2_hdr hdr;
+	__le16 StructureSize; /* Must be 9 */
+	__le16 OutputBufferOffset;
+	__le32 OutputBufferLength;
+	__u8   Buffer[1];
+} __attribute__((packed));
+
+struct set_info_req {
+	struct smb2_hdr hdr;
+	__le16 StructureSize; /* Must be 33 */
+	__u8 InfoType;
+	__u8 FileInfoClass;
+	__le32 BufferLength;
+	__le16 BufferOffset;
+	__u16 Reserved;
+	__le32 AdditionalInformation;
+	__u64  PersistentFileId; /* opaque endianness */
+	__u64  VolatileFileId; /* opaque endianness */
+	__u8 Buffer[1];
+} __attribute__((packed));
+
+struct set_info_rsp {
+	struct smb2_hdr hdr;
+	__le16 StructureSize; /* Must be 2 */
+} __attribute__((packed));
+
+struct ioctl_req {
+	struct	smb2_hdr hdr;
+	__le16 StructureSize;	/* Must be 57 */
+	__le16 Reserved;
+	__le32 Ctlcode;
+	__le64 Fileid[2];	/* persistent and volatile */
+	__le32 Inputoffset;
+	__le32 Inputcount;
+	__le32 Maxinputresp;
+	__le32 Outputoffset;
+	__le32 Outputcount;
+	__le32 Maxoutputresp;
+	__le32 Flags;
+	__le32 Reserved2;
+	__u8   Buffer[1];
+}  __attribute__((packed));
+
+struct ioctl_rsp {
+	struct	smb2_hdr hdr;
+	__le16 StructureSize;	/* Must be 49 */
+	__le16 Reserved;
+	__le32 Ctlcode;
+	__le16 Fileid[2];	/* persistent and volatile */
+	__le32 Inputoffset;
+	__le32 Inputcount;
+	__le32 Outputoffset;
+	__le32 Outputcount;
+	__le32 Flags;
+	__le32 Reserved2;
+	__u8   Buffer[1];
+}  __attribute__((packed));
+
+/*****************************************************************
+ * All constants go here
+ *****************************************************************
+ */
+
+/*
+ * Starting value for maximum SMB size negotiation
+ */
+#define SMB2_MAX_MSGSIZE (4*4096)
+
+
+#define SMB2_NETWORK_OPSYS "SMB2 VFS Client for Linux"
+
+/*
+ *	PDU infolevel structure definitions
+ *	BB consider moving to a different header
+ */
+
+/* File System Information Classes */
+#define FS_VOLUME_INFORMATION	1 /* Query */
+#define FS_LABEL_INFORMATION	2 /* Set */
+#define FS_SIZE_INFORMATION	3 /* Query */
+#define FS_DEVICE_INFORMATION	4 /* Query */
+#define FS_ATTRIBUTE_INFORMATION 5 /* Query */
+#define FS_CONTROL_INFORMATION	6 /* Query, Set */
+#define FS_FULL_SIZE_INFORMATION 7 /* Query */
+#define FS_OBJECT_ID_INFORMATION 8 /* Query, Set */
+#define FS_DRIVER_PATH_INFORMATION 9 /* Query */
+
+struct fs_full_size_info {
+	__le64 TotalAllocationUnits;
+	__le64 CallerAvailableAllocationUnits;
+	__le64 ActualAvailableAllocationUnits;
+	__le32 SectorsPerAllocationUnit;
+	__le32 BytesPerSector;
+};
+
+struct fs_volume_info {
+	__le64 VolumeCreationTime;
+	__le32 VolumeSerialNumber;
+	__le32 VolumeLabelLength;
+	__u8   SupportsObjects;  /* 1 = supports object oriented fs objects */
+	__u8   Reserved;
+	/* Variable Length VolumeLabel follows */
+};
+
+struct fs_device_info {
+	__le32 DeviceType; /* see below */
+	__le32 DeviceCharacteristics;
+} __attribute__((packed)); /* device info level 0x104 */
+
+/* DeviceType Flags (remember to endian convert them) */
+#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
+
+#define MAX_FS_NAME 20 /* twice size of longest name ("FAT32") is plenty */
+/* this field is for debugging/informational purposes anyway, so could be
+truncated if extremely long fs names were later created */
+struct fs_attribute_info {
+	__le32 Attributes;
+	__le32 MaximumComponentNameLength;
+	__le32 FileSystemNameLength;
+	char FileSystemName[MAX_FS_NAME]; /* not null terminated */
+} __attribute__((packed));
+
+/* Attributes  (remember to endian convert them) */
+#define FILE_CASE_SENSITIVE_SEARCH	0x00000001
+#define FILE_CASE_PRESERVED_NAMES	0x00000002
+#define FILE_UNICODE_ON_DISK		0x00000004
+#define FILE_PERSISTENT_ACLS		0x00000008
+#define FILE_FILE_COMPRESSION		0x00000010
+#define FILE_VOLUME_QUOTAS		0x00000020
+#define FILE_SUPPORTS_SPARSE_FILES	0x00000040
+#define FILE_SUPPORTS_REPARSE_POINTS	0x00000080
+#define FILE_SUPPORTS_REMOTE_STORAGE	0x00000100
+#define FILE_VOLUME_IS_COMPRESSED	0x00008000
+#define FILE_SUPPORTS_OBJECT_IDS	0x00010000
+#define FILE_SUPPORTS_ENCRYPTION	0x00020000
+#define FILE_NAMED_STREAMS		0x00040000
+#define FILE_READ_ONLY_VOLUME		0x00080000
+#define FILE_SEQUENTIAL_WRITE_ONCE	0x00100000
+#define FILE_SUPPORTS_TRANSACTIONS	0x00200000
+#define FILE_SUPPORTS_HARD_LINKS	0x00400000
+#define FILE_SUPPORTS_EXTENDED_ATTRS	0x00800000
+#define FILE_SUPPORTS_OPEN_BY_FILE_ID	0x01000000
+#define FILE_SUPPORTS_USN_JOURNAL	0x02000000
+
+/* partial list of QUERY INFO levels */
+#define FILE_DIRECTORY_INFORMATION	1
+#define FILE_FULL_DIRECTORY_INFORMATION 2
+#define FILE_BOTH_DIRECTORY_INFORMATION 3
+#define FILE_BASIC_INFORMATION		4
+#define FILE_STANDARD_INFORMATION	5
+#define FILE_INTERNAL_INFORMATION	6
+#define FILE_EA_INFORMATION	        7
+#define FILE_ACCESS_INFORMATION		8
+#define FILE_NAME_INFORMATION		9
+#define FILE_RENAME_INFORMATION		10
+#define FILE_LINK_INFORMATION		11
+#define FILE_NAMES_INFORMATION		12
+#define FILE_DISPOSITION_INFORMATION	13
+#define FILE_POSITION_INFORMATION	14
+#define FILE_FULL_EA_INFORMATION	15
+#define FILE_MODE_INFORMATION		16
+#define FILE_ALIGNMENT_INFORMATION	17
+#define FILE_ALL_INFORMATION		18
+#define FILE_ALLOCATION_INFORMATION	19
+#define FILE_END_OF_FILE_INFORMATION	20
+#define FILE_ALTERNATE_NAME_INFORMATION 21
+#define FILE_STREAM_INFORMATION		22
+#define FILE_PIPE_INFORMATION		23
+#define FILE_PIPE_LOCAL_INFORMATION	24
+#define FILE_PIPE_REMOTE_INFORMATION	25
+#define FILE_MAILSLOT_QUERY_INFORMATION 26
+#define FILE_MAILSLOT_SET_INFORMATION	27
+#define FILE_COMPRESSION_INFORMATION	28
+#define FILE_OBJECT_ID_INFORMATION	29
+/* Number 30 not defined in documents */
+#define FILE_MOVE_CLUSTER_INFORMATION	31
+#define FILE_QUOTA_INFORMATION		32
+#define FILE_REPARSE_POINT_INFORMATION	33
+#define FILE_NETWORK_OPEN_INFORMATION	34
+#define FILE_ATTRIBUTE_TAG_INFORMATION	35
+#define FILE_TRACKING_INFORMATION	36
+#define FILEID_BOTH_DIRECTORY_INFORMATION 37
+#define FILEID_FULL_DIRECTORY_INFORMATION 38
+#define FILE_VALID_DATA_LENGTH_INFORMATION 39
+#define FILE_SHORT_NAME_INFORMATION	40
+#define FILE_SFIO_RESERVE_INFORMATION	44
+#define FILE_SFIO_VOLUME_INFORMATION	45
+#define FILE_HARD_LINK_INFORMATION	46
+#define FILE_NORMALIZED_NAME_INFORMATION 48
+#define FILEID_GLOBAL_TX_DIRECTORY_INFORMATION 50
+#define FILE_STANDARD_LINK_INFORMATION	54
+
+struct file_both_directory_info {
+	__le32 next_entry_offset;
+	__u32 file_index;
+	__le64 creation_time;
+	__le64 last_access_time;
+	__le64 last_write_time;
+	__le64 change_time;
+	__le64 end_of_file;
+	__le64 allocation_size;
+	__le32 file_attribute;
+	__le32 filename_length;
+	__le32 easize;
+	__u8 shortname_length;
+	__u8 reserved1;
+	__u8 short_name[24];
+	__u16 reserved2;
+	__le64 file_id;
+	char filename[0];
+}  __attribute__((packed));
+
+struct file_full_directory_info {
+	__le32 next_entry_offset;
+	__u32 file_index;
+	__le64 creation_time;
+	__le64 last_access_time;
+	__le64 last_write_time;
+	__le64 change_time;
+	__le64 end_of_file;
+	__le64 allocation_size;
+	__le32 file_attribute;
+	__le32 filename_length;
+	__le32 easize;
+	__u32 reserved2;
+	__le64 file_id;
+	char filename[0];
+}  __attribute__((packed));
+
+typedef struct { /* data block encoding of response to level 5 query */
+	__le64 AllocationSize;
+	__le64 EndOfFile;	/* size ie offset to first free byte in file */
+	__le32 NumberOfLinks;	/* hard links */
+	__u8 DeletePending;
+	__u8 Directory;
+	__u16 Pad2;
+} __attribute__((packed)) FILE_STANDARD_INFO;	/* level 5 QPathInfo */
+
+struct FileRenameInformation { /* encoding of request for level 10 */
+	__u8 ReplaceIfExists; /* 1 = replace existing file with new */
+			      /* 0 = fail if target file already exists */
+	__u8 Reserved[7];
+	__u64 RootDirectory;  /* MBZ for network operations (why says spec?) */
+	__le32 FileNameLength;
+	char FileName[0];     /* New name to be assigned */
+} __attribute__((packed)); /* level 10 set */
+
+struct FileLinkInformation { /* encoding of request for level 11 */
+	__u8 ReplaceIfExists; /* 1 = replace existing link with new */
+			      /* 0 = fail if link already exists */
+	__u8 Reserved[7];
+	__u64 RootDirectory;  /* MBZ for network operations (why says spec?) */
+	__le32 FileNameLength;
+	char FileName[0];     /* Name to be assigned to new link */
+} __attribute__((packed)); /* level 11 set */
+
+
+/* This level 18, although with struct with same name is different from cifs
+   level 0x107.  level 0x107 has an extra u64 between AccessFlags and
+   CurrentByteOffset */
+typedef struct { /* data block encoding of response to level 18 */
+	__le64 CreationTime;	/* Beginning of FILE_BASIC_INFO equivalent */
+	__le64 LastAccessTime;
+	__le64 LastWriteTime;
+	__le64 ChangeTime;
+	__le32 Attributes;
+	__u32 Pad1;		/* End of FILE_BASIC_INFO_INFO equivalent */
+	__le64 AllocationSize;	/* Beginning of FILE_STANDARD_INFO equivalent */
+	__le64 EndOfFile;	/* size ie offset to first free byte in file */
+	__le32 NumberOfLinks;	/* hard links */
+	__u8 DeletePending;
+	__u8 Directory;
+	__u16 Pad2;		/* End of FILE_STANDARD_INFO equivalent */
+	__le64 IndexNumber;
+	__le32 EASize;
+	__le32 AccessFlags;
+	__le64 CurrentByteOffset;
+	__le32 Mode;
+	__le32 AlignmentRequirement;
+	__le32 FileNameLength;
+	char FileName[1];
+} __attribute__((packed)) FILE_ALL_INFO_SMB2;	/* level 18 Query */
+
+typedef struct { /* data block encoding of request to level 15 */
+	__le64 NextEntryOffset;
+	__u8 EaNameLength;
+	char EaName[1];
+} __attribute__((packed)) FILE_GET_EA_INFO; /* level 15 Query */
+
+typedef struct { /* data block encoding of response to level 15 */
+	__le32 NextEntryOffset;
+	__u8 Flags;
+	__u8 EaNameLength;
+	__le16 EaValueLength;
+	char EaName[1];
+	char EaValue[1];
+} __attribute__((packed)) FILE_FULL_EA_INFO; /* level 15 Query */
+
+/* DFS Flags */  /* BB check if these changed in SMB2 from old transact2
+   get DFS referral flags BB */
+#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 */
+
+/* BB note that various other infolevels are defined in cifspdu.h,
although most
+   are obsolete now (for SMB2) or unneeded, some may be useful to move here */
+
+#define SMB2_IOCTL_IS_FSCTL 0x1
+#define SYMLINK_FLAG_RELATIVE 0x1
+#define MS_REPARSE_TAG 0xA000000C
+
+struct symlink_reparse_data_buf {
+	__le32 reparse_tag;
+	__le16 reparse_datalength;
+	__le16 reserved1;
+	__le16 sub_nameoffset;
+	__le16 sub_namelength;
+	__le16 print_nameoffset;
+	__le16 print_namelength;
+	__le32 flags;