remove generic linux 2.4 support
[openwrt/svn-archive/archive.git] / target / linux / generic-2.4 / patches / 107-cifs.patch
diff --git a/target/linux/generic-2.4/patches/107-cifs.patch b/target/linux/generic-2.4/patches/107-cifs.patch
deleted file mode 100644 (file)
index e2ff33d..0000000
+++ /dev/null
@@ -1,21977 +0,0 @@
---- a/Documentation/Configure.help
-+++ b/Documentation/Configure.help
-@@ -18007,6 +18007,34 @@ CONFIG_UNIXWARE_DISKLABEL
-   If you don't know what all this is about, say N.
-+CIFS (Common Internet File System) support
-+CONFIG_CIFS
-+  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.  CIFS is fully supported by current network
-+  file servers such as Windows 2000, Windows 2003 (including  
-+  Windows XP) as well by Samba (which provides excellent CIFS
-+  server support for Linux and many other operating systems).  
-+  The smbfs module should be used instead of this cifs module for
-+  mounting to older SMB servers such as OS/2.  The smbfs and cifs
-+  modules can coexist and do not conflict.
-+
-+  The intent of this module is to provide the most advanced network
-+  file system function for CIFS compliant servers, including better
-+  POSIX compliance, secure per-user session establishment, high
-+  performance safe distributed caching (oplock), optional packet
-+  signing, Unicode support and other internationalization improvements
-+  For more information see the project page at
-+  http://us1.samba.org/samba/Linux_CIFS_client.html 
-+
-+CIFS Debugging
-+CONFIG_CIFS_DEBUG
-+  If you are experiencing any problems with the CIFS filesystem, say
-+  Y here.  This will result in additional debugging messages to be
-+  written to the system log.  Under normal circumstances, this
-+  results in very little overhead.  
-+
- SMB file system support (to mount Windows shares etc.)
- CONFIG_SMB_FS
-   SMB (Server Message Block) is the protocol Windows for Workgroups
---- a/Documentation/filesystems/00-INDEX
-+++ b/Documentation/filesystems/00-INDEX
-@@ -10,6 +10,8 @@ befs.txt
-       - info for the BeOS file system (BFS)
- bfs.txt
-       - info for the SCO UnixWare Boot Filesystem (BFS).
-+cifs.txt
-+      - info on the Common Internet File System (CIFS)
- coda.txt
-       - description of the CODA filesystem.
- cramfs.txt
---- /dev/null
-+++ b/Documentation/filesystems/cifs.txt
-@@ -0,0 +1,51 @@
-+  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.  CIFS is fully supported by current network
-+  file servers such as Windows 2000, Windows 2003 (including  
-+  Windows XP) as well by Samba (which provides excellent CIFS
-+  server support for Linux and many other operating systems), so
-+  this network filesystem client can mount to a wide variety of
-+  servers.  The smbfs module should be used instead of this cifs module
-+  for mounting to older SMB servers such as OS/2.  The smbfs and cifs
-+  modules can coexist and do not conflict.  The CIFS VFS filesystem
-+  module is designed to work well with servers that implement the
-+  newer versions (dialects) of the SMB/CIFS protocol such as Samba, 
-+  the program written by Andrew Tridgell that turns any Unix host 
-+  into a SMB/CIFS file server.
-+
-+  The intent of this module is to provide the most advanced network
-+  file system function for CIFS compliant servers, including better
-+  POSIX compliance, secure per-user session establishment, high
-+  performance safe distributed caching (oplock), optional packet
-+  signing, large files, Unicode support and other internationalization
-+  improvements. Since both Samba server and this filesystem client support
-+  the CIFS Unix extensions, the combination can provide a reasonable 
-+  alternative to NFSv4 for fileserving in some Linux to Linux environments,
-+  not just in Linux to Windows environments.
-+
-+  This filesystem has an optional mount utility (mount.cifs) that can
-+  be obtained from the project page and installed in the path in the same
-+  directory with the other mount helpers (such as mount.smbfs). 
-+  Mounting using the cifs filesystem without installing the mount helper
-+  requires specifying the server's ip address.
-+
-+  For Linux 2.4:
-+    mount //anything/here /mnt_target -o
-+            user=username,pass=password,unc=//ip_address_of_server/sharename
-+
-+  For Linux 2.5: 
-+    mount //ip_address_of_server/sharename /mnt_target -o user=username, pass=password
-+
-+
-+  For more information on the module see the project page at
-+
-+      http://us1.samba.org/samba/Linux_CIFS_client.html 
-+
-+  For more information on CIFS see:
-+
-+      http://www.snia.org/tech_activities/CIFS
-+
-+  or the Samba site:
-+     
-+      http://www.samba.org
---- /dev/null
-+++ b/fs/cifs/asn1.c
-@@ -0,0 +1,614 @@
-+/* 
-+ * 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/config.h>
-+#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"
-+
-+/*****************************************************************************
-+ *
-+ * 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_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
-+unsigned long SPNEGO_OID[7] = { 1, 3, 6, 1, 5, 5, 2 };
-+unsigned long NTLMSSP_OID[10] = { 1, 3, 6, 1, 4, 1, 311, 2, 2, 10 };
-+
-+/* 
-+ * 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;
-+}
-+
-+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--;
-+                      }
-+              }
-+      }
-+      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, len;
-+
-+      if (!asn1_id_decode(ctx, cls, con, tag))
-+              return 0;
-+
-+      if (!asn1_length_decode(ctx, &def, &len))
-+              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 == 0) {
-+              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 unsigned char
-+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;
-+      *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,
-+                  enum securityEnum *secType)
-+{
-+      struct asn1_ctx ctx;
-+      unsigned char *end;
-+      unsigned char *sequence_end;
-+      unsigned long *oid;
-+      unsigned int cls, con, tag, oidlen, rc;
-+      int use_ntlmssp = FALSE;
-+
-+    *secType = NTLM; /* BB eventually make Kerberos or NLTMSSP the default */
-+
-+      /* cifs_dump_mem(" Received SecBlob ", security_blob, length); */
-+
-+      asn1_open(&ctx, security_blob, length);
-+
-+      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;
-+      } else {
-+              /*      remember to free obj->oid */
-+              rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag);
-+              if (rc) {
-+                      if ((tag == ASN1_OJI) && (cls == ASN1_PRI)) {
-+                              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;
-+              }
-+
-+              if (!rc) {
-+                      cFYI(1, ("Error decoding negTokenInit header"));
-+                      return 0;
-+              }
-+
-+              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;
-+              }
-+
-+              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;
-+              }
-+
-+              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;
-+              }
-+
-+              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;
-+              }
-+
-+              while (!asn1_eoc_decode(&ctx, sequence_end)) {
-+                      rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag);
-+                      if (!rc) {
-+                              cFYI(1,
-+                                   ("Error 1 decoding negTokenInit header exit 2"));
-+                              return 0;
-+                      }
-+                      if ((tag == ASN1_OJI) && (con == ASN1_PRI)) {
-+                              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)));
-+                              rc = compare_oid(oid, oidlen, NTLMSSP_OID,
-+                                               NTLMSSP_OID_LEN);
-+                              kfree(oid);
-+                              if (rc)
-+                                      use_ntlmssp = TRUE;
-+                      } else {
-+                              cFYI(1,("This should be an oid what is going on? "));
-+                      }
-+              }
-+
-+              if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
-+                      cFYI(1,
-+                           ("Error decoding last part of negTokenInit exit 3"));
-+                      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;
-+              }
-+              if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
-+                      cFYI(1,
-+                           ("Error decoding last part of negTokenInit exit 5"));
-+                      return 0;
-+              } else if ((cls != ASN1_UNI) || (con != ASN1_CON)
-+                         || (tag != ASN1_SEQ)) {
-+                      cFYI(1,
-+                           ("Exit 6 cls = %d con = %d tag = %d end = %p (%d)",
-+                            cls, con, tag, end, *end));
-+              }
-+
-+              if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
-+                      cFYI(1,
-+                           ("Error decoding last part of 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;
-+              }
-+              if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
-+                      cFYI(1,
-+                           ("Error decoding last part of negTokenInit exit 9"));
-+                      return 0;
-+              } else if ((cls != ASN1_UNI) || (con != ASN1_PRI)
-+                         || (tag != ASN1_GENSTR)) {
-+                      cFYI(1,
-+                           ("Exit 10 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 this %s", ctx.pointer));       /* is this UTF-8 or ASCII? */
-+      }
-+
-+      /* if (use_kerberos) 
-+         *secType = Kerberos 
-+         else */
-+      if (use_ntlmssp) {
-+              *secType = NTLMSSP;
-+      }
-+
-+      return 1;
-+}
---- /dev/null
-+++ b/fs/cifs/AUTHORS
-@@ -0,0 +1,37 @@
-+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 the time and test resources to pursue
-+this project. Jim McDonough from IBM (and the Samba Team) for his help.
-+The IBM Linux JFS team for explaining many esoteric Linux filesystem features.
-+Dave Boutcher of IBM Rochester (author of the OS/400 smb/cifs filesystem client)
-+for proving years ago that a very good smb/cifs client could be done on a Unix like 
-+operating system.  Volker Lendecke, Andrew Tridgell, Urban Widmark, John Newbigin 
-+and others for their work on the Linux smbfs module over the years. 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
-+
-+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. 
-+
-+And thanks to the IBM LTC and Power test teams and SuSE testers for
-+finding multiple bugs during excellent stress test runs.
---- /dev/null
-+++ b/fs/cifs/CHANGES
-@@ -0,0 +1,572 @@
-+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 overrride 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 prototocol 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 roepen_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 rumber 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 exentions) 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
-+
---- /dev/null
-+++ b/fs/cifs/cifs_debug.c
-@@ -0,0 +1,797 @@
-+/*
-+ *   fs/cifs_debug.c
-+ *
-+ *   Copyright (C) International Business Machines  Corp., 2000,2003
-+ *
-+ *   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"
-+
-+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\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_PROC_FS
-+int
-+cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset,
-+                   int count, int *eof, void *data)
-+{
-+      struct list_head *tmp;
-+      struct list_head *tmp1;
-+      struct mid_q_entry * mid_entry;
-+      struct cifsSesInfo *ses;
-+      struct cifsTconInfo *tcon;
-+      int i;
-+      int length = 0;
-+      char * original_buf = buf;
-+
-+      *beginBuffer = buf + offset;
-+
-+      
-+      length =
-+          sprintf(buf,
-+                  "Display Internal CIFS Data Structures for Debugging\n"
-+                  "---------------------------------------------------\n");
-+      buf += length;
-+
-+      length = sprintf(buf, "Servers:\n");
-+      buf += length;
-+
-+      i = 0;
-+      read_lock(&GlobalSMBSeslock);
-+      list_for_each(tmp, &GlobalSMBSessionList) {
-+              i++;
-+              ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
-+              length =
-+                  sprintf(buf,
-+                          "\n%d) Name: %s  Domain: %s Mounts: %d ServerOS: %s  \n\tServerNOS: %s\tCapabilities: 0x%x\n\tSMB session status: %d\tTCP status: %d",
-+                              i, ses->serverName, ses->serverDomain, atomic_read(&ses->inUse),
-+                              ses->serverOS, ses->serverNOS, ses->capabilities,ses->status,ses->server->tcpStatus);
-+              buf += length;
-+              if(ses->server) {
-+                      buf += sprintf(buf, "\n\tLocal Users To Server: %d SecMode: 0x%x Req Active: %d",
-+                              atomic_read(&ses->server->socketUseCount),
-+                              ses->server->secMode,
-+                              atomic_read(&ses->server->inFlight));
-+                      
-+                      length = sprintf(buf, "\nMIDs: \n");
-+                      buf += length;
-+
-+                      spin_lock(&GlobalMid_Lock);
-+                      list_for_each(tmp1, &ses->server->pending_mid_q) {
-+                              mid_entry = list_entry(tmp1, struct
-+                                      mid_q_entry,
-+                                      qhead);
-+                              if(mid_entry) {
-+                                      length = sprintf(buf,"State: %d com: %d pid: %d tsk: %p mid %d\n",mid_entry->midState,mid_entry->command,mid_entry->pid,mid_entry->tsk,mid_entry->mid);
-+                                      buf += length;
-+                              }
-+                      }
-+                      spin_unlock(&GlobalMid_Lock); 
-+              }
-+
-+      }
-+      read_unlock(&GlobalSMBSeslock);
-+      sprintf(buf, "\n");
-+      buf++;
-+
-+      length = sprintf(buf, "\nShares:\n");
-+      buf += length;
-+
-+      i = 0;
-+      read_lock(&GlobalSMBSeslock);
-+      list_for_each(tmp, &GlobalTreeConnectionList) {
-+              i++;
-+              tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
-+              length =
-+                  sprintf(buf,
-+                          "\n%d) %s Uses: %d Type: %s Characteristics: 0x%x Attributes: 0x%x\nPathComponentMax: %d Status: %d",
-+                          i, tcon->treeName,
-+                          atomic_read(&tcon->useCount),
-+                          tcon->nativeFileSystem,
-+                          tcon->fsDevInfo.DeviceCharacteristics,
-+                          tcon->fsAttrInfo.Attributes,
-+                          tcon->fsAttrInfo.MaxPathNameComponentLength,tcon->tidStatus);
-+              buf += length;        
-+              if (tcon->fsDevInfo.DeviceType == FILE_DEVICE_DISK)
-+                      length = sprintf(buf, " type: DISK ");
-+              else if (tcon->fsDevInfo.DeviceType == FILE_DEVICE_CD_ROM)
-+                      length = sprintf(buf, " type: CDROM ");
-+              else
-+                      length =
-+                          sprintf(buf, " type: %d ",
-+                                  tcon->fsDevInfo.DeviceType);
-+              buf += length;
-+              if(tcon->tidStatus == CifsNeedReconnect) {
-+                      buf += sprintf(buf, "\tDISCONNECTED ");
-+                      length += 14;
-+              }
-+      }
-+      read_unlock(&GlobalSMBSeslock);
-+
-+      length = sprintf(buf, "\n");
-+      buf += length;
-+
-+      /* BB add code to dump additional info such as TCP session info now */
-+      /* Now calculate total size of returned data */
-+      length = buf - original_buf;
-+
-+      if(offset + count >= length)
-+              *eof = 1;
-+      if(length < offset) {
-+              *eof = 1;
-+              return 0;
-+      } else {
-+              length = length - offset;
-+      }
-+      if (length > count)
-+              length = count;
-+
-+      return length;
-+}
-+
-+#ifdef CONFIG_CIFS_STATS
-+int
-+cifs_stats_read(char *buf, char **beginBuffer, off_t offset,
-+                int count, int *eof, void *data)
-+{
-+      int item_length,i,length;
-+      struct list_head *tmp;
-+      struct cifsTconInfo *tcon;
-+
-+      *beginBuffer = buf + offset;
-+
-+      length = sprintf(buf,
-+                      "Resources in use\nCIFS Session: %d\n",
-+                      sesInfoAllocCount.counter);
-+      buf += length;
-+      item_length = 
-+              sprintf(buf,"Share (unique mount targets): %d\n",
-+                      tconInfoAllocCount.counter);
-+      length += item_length;
-+      buf += item_length;      
-+      item_length = 
-+              sprintf(buf,"SMB Request/Response Buffer: %d\n",
-+                      bufAllocCount.counter);
-+      length += item_length;
-+      buf += item_length;      
-+      item_length = 
-+              sprintf(buf,"Operations (MIDs): %d\n",
-+                      midCount.counter);
-+      length += item_length;
-+      buf += item_length;
-+      item_length = sprintf(buf,
-+              "\n%d session %d share reconnects\n",
-+              tcpSesReconnectCount.counter,tconInfoReconnectCount.counter);
-+      length += item_length;
-+      buf += item_length;
-+
-+      item_length = sprintf(buf,
-+              "Total vfs operations: %d maximum at one time: %d\n",
-+              GlobalCurrentXid,GlobalMaxActiveXid);
-+      length += item_length;
-+      buf += item_length;
-+
-+      i = 0;
-+      read_lock(&GlobalSMBSeslock);
-+      list_for_each(tmp, &GlobalTreeConnectionList) {
-+              i++;
-+              tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
-+              item_length = sprintf(buf,"\n%d) %s",i, tcon->treeName);
-+              buf += item_length;
-+              length += item_length;
-+              if(tcon->tidStatus == CifsNeedReconnect) {
-+                      buf += sprintf(buf, "\tDISCONNECTED ");
-+                      length += 14;
-+              }
-+              item_length = sprintf(buf,"\nSMBs: %d Oplock Breaks: %d",
-+                      atomic_read(&tcon->num_smbs_sent),
-+                      atomic_read(&tcon->num_oplock_brks));
-+              buf += item_length;
-+              length += item_length;
-+              item_length = sprintf(buf,"\nReads: %d Bytes %lld",
-+                      atomic_read(&tcon->num_reads),
-+                      (long long)(tcon->bytes_read));
-+              buf += item_length;
-+              length += item_length;
-+              item_length = sprintf(buf,"\nWrites: %d Bytes: %lld",
-+                      atomic_read(&tcon->num_writes),
-+                      (long long)(tcon->bytes_written));
-+              buf += item_length;
-+              length += item_length;
-+              item_length = sprintf(buf,
-+                      "\nOpens: %d Deletes: %d\nMkdirs: %d Rmdirs: %d",
-+                      atomic_read(&tcon->num_opens),
-+                      atomic_read(&tcon->num_deletes),
-+                      atomic_read(&tcon->num_mkdirs),
-+                      atomic_read(&tcon->num_rmdirs));
-+              buf += item_length;
-+              length += item_length;
-+              item_length = sprintf(buf,
-+                      "\nRenames: %d T2 Renames %d",
-+                      atomic_read(&tcon->num_renames),
-+                      atomic_read(&tcon->num_t2renames));
-+              buf += item_length;
-+              length += item_length;
-+      }
-+      read_unlock(&GlobalSMBSeslock);
-+
-+      buf += sprintf(buf,"\n");
-+      length++;
-+
-+      if(offset + count >= length)
-+              *eof = 1;
-+      if(length < offset) {
-+              *eof = 1;
-+              return 0;
-+      } else {
-+              length = length - offset;
-+      }
-+      if (length > count)
-+              length = count;
-+              
-+      return length;
-+}
-+#endif
-+
-+struct proc_dir_entry *proc_fs_cifs;
-+read_proc_t cifs_txanchor_read;
-+static read_proc_t cifsFYI_read;
-+static write_proc_t cifsFYI_write;
-+static read_proc_t oplockEnabled_read;
-+static write_proc_t oplockEnabled_write;
-+static read_proc_t lookupFlag_read;
-+static write_proc_t lookupFlag_write;
-+static read_proc_t traceSMB_read;
-+static write_proc_t traceSMB_write;
-+static read_proc_t multiuser_mount_read;
-+static write_proc_t multiuser_mount_write;
-+static read_proc_t extended_security_read;
-+static write_proc_t extended_security_write;
-+static read_proc_t ntlmv2_enabled_read;
-+static write_proc_t ntlmv2_enabled_write;
-+static read_proc_t packet_signing_enabled_read;
-+static write_proc_t packet_signing_enabled_write;
-+static read_proc_t quotaEnabled_read;
-+static write_proc_t quotaEnabled_write;
-+static read_proc_t linuxExtensionsEnabled_read;
-+static write_proc_t linuxExtensionsEnabled_write;
-+
-+void
-+cifs_proc_init(void)
-+{
-+      struct proc_dir_entry *pde;
-+
-+      proc_fs_cifs = proc_mkdir("cifs", proc_root_fs);
-+      if (proc_fs_cifs == NULL)
-+              return;
-+
-+      proc_fs_cifs->owner = THIS_MODULE;
-+      create_proc_read_entry("DebugData", 0, proc_fs_cifs,
-+                              cifs_debug_data_read, NULL);
-+
-+#ifdef CONFIG_CIFS_STATS
-+      create_proc_read_entry("Stats", 0, proc_fs_cifs,
-+                              cifs_stats_read, NULL);
-+#endif
-+      pde = create_proc_read_entry("cifsFYI", 0, proc_fs_cifs,
-+                              cifsFYI_read, NULL);
-+      if (pde)
-+              pde->write_proc = cifsFYI_write;
-+
-+      pde =
-+          create_proc_read_entry("traceSMB", 0, proc_fs_cifs,
-+                              traceSMB_read, NULL);
-+      if (pde)
-+              pde->write_proc = traceSMB_write;
-+
-+      pde = create_proc_read_entry("OplockEnabled", 0, proc_fs_cifs,
-+                              oplockEnabled_read, NULL);
-+      if (pde)
-+              pde->write_proc = oplockEnabled_write;
-+
-+      pde = create_proc_read_entry("QuotaEnabled", 0, proc_fs_cifs,
-+                              quotaEnabled_read, NULL);
-+      if (pde)
-+              pde->write_proc = quotaEnabled_write;
-+
-+      pde = create_proc_read_entry("LinuxExtensionsEnabled", 0, proc_fs_cifs,
-+                              linuxExtensionsEnabled_read, NULL);
-+      if (pde)
-+              pde->write_proc = linuxExtensionsEnabled_write;
-+
-+      pde =
-+          create_proc_read_entry("MultiuserMount", 0, proc_fs_cifs,
-+                              multiuser_mount_read, NULL);
-+      if (pde)
-+              pde->write_proc = multiuser_mount_write;
-+
-+      pde =
-+          create_proc_read_entry("ExtendedSecurity", 0, proc_fs_cifs,
-+                              extended_security_read, NULL);
-+      if (pde)
-+              pde->write_proc = extended_security_write;
-+
-+      pde =
-+      create_proc_read_entry("LookupCacheEnabled", 0, proc_fs_cifs,
-+                              lookupFlag_read, NULL);
-+      if (pde)
-+              pde->write_proc = lookupFlag_write;
-+
-+      pde =
-+          create_proc_read_entry("NTLMV2Enabled", 0, proc_fs_cifs,
-+                              ntlmv2_enabled_read, NULL);
-+      if (pde)
-+              pde->write_proc = ntlmv2_enabled_write;
-+
-+      pde =
-+          create_proc_read_entry("PacketSigningEnabled", 0, proc_fs_cifs,
-+                              packet_signing_enabled_read, NULL);
-+      if (pde)
-+              pde->write_proc = packet_signing_enabled_write;
-+}
-+
-+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("OplockEnabled", proc_fs_cifs);
-+      remove_proc_entry("NTLMV2Enabled",proc_fs_cifs);
-+      remove_proc_entry("ExtendedSecurity",proc_fs_cifs);
-+      remove_proc_entry("PacketSigningEnabled",proc_fs_cifs);
-+      remove_proc_entry("LinuxExtensionsEnabled",proc_fs_cifs);
-+      remove_proc_entry("QuotaEnabled",proc_fs_cifs);
-+      remove_proc_entry("LookupCacheEnabled",proc_fs_cifs);
-+      remove_proc_entry("cifs", proc_root_fs);
-+}
-+
-+static int
-+cifsFYI_read(char *page, char **start, off_t off, int count,
-+           int *eof, void *data)
-+{
-+      int len;
-+
-+      len = sprintf(page, "%d\n", cifsFYI);
-+
-+      len -= off;
-+      *start = page + off;
-+
-+      if (len > count)
-+              len = count;
-+      else
-+              *eof = 1;
-+
-+      if (len < 0)
-+              len = 0;
-+
-+      return len;
-+}
-+static int
-+cifsFYI_write(struct file *file, const char *buffer,
-+            unsigned long count, void *data)
-+{
-+      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;
-+
-+      return count;
-+}
-+
-+static int
-+oplockEnabled_read(char *page, char **start, off_t off,
-+                 int count, int *eof, void *data)
-+{
-+      int len;
-+
-+      len = sprintf(page, "%d\n", oplockEnabled);
-+
-+      len -= off;
-+      *start = page + off;
-+
-+      if (len > count)
-+              len = count;
-+      else
-+              *eof = 1;
-+
-+      if (len < 0)
-+              len = 0;
-+
-+      return len;
-+}
-+static int
-+oplockEnabled_write(struct file *file, const char *buffer,
-+                  unsigned long count, void *data)
-+{
-+      char c;
-+      int rc;
-+
-+      rc = get_user(c, buffer);
-+      if (rc)
-+              return rc;
-+      if (c == '0' || c == 'n' || c == 'N')
-+              oplockEnabled = 0;
-+      else if (c == '1' || c == 'y' || c == 'Y')
-+              oplockEnabled = 1;
-+
-+      return count;
-+}
-+
-+static int
-+quotaEnabled_read(char *page, char **start, off_t off,
-+                   int count, int *eof, void *data)
-+{
-+        int len;
-+
-+        len = sprintf(page, "%d\n", quotaEnabled);
-+/* could also check if quotas are enabled in kernel
-+      as a whole first */
-+        len -= off;
-+        *start = page + off;
-+
-+        if (len > count)
-+                len = count;
-+        else
-+                *eof = 1;
-+
-+        if (len < 0)
-+                len = 0;
-+
-+        return len;
-+}
-+static int
-+quotaEnabled_write(struct file *file, const char *buffer,
-+                    unsigned long count, void *data)
-+{
-+        char c;
-+        int rc;
-+
-+        rc = get_user(c, buffer);
-+        if (rc)
-+                return rc;
-+        if (c == '0' || c == 'n' || c == 'N')
-+                quotaEnabled = 0;
-+        else if (c == '1' || c == 'y' || c == 'Y')
-+                quotaEnabled = 1;
-+
-+        return count;
-+}
-+
-+static int
-+linuxExtensionsEnabled_read(char *page, char **start, off_t off,
-+                   int count, int *eof, void *data)
-+{
-+        int len;
-+
-+        len = sprintf(page, "%d\n", linuxExtEnabled);
-+/* could also check if quotas are enabled in kernel
-+      as a whole first */
-+        len -= off;
-+        *start = page + off;
-+
-+        if (len > count)
-+                len = count;
-+        else
-+                *eof = 1;
-+
-+        if (len < 0)
-+                len = 0;
-+
-+        return len;
-+}
-+static int
-+linuxExtensionsEnabled_write(struct file *file, const char *buffer,
-+                    unsigned long count, void *data)
-+{
-+        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 int
-+lookupFlag_read(char *page, char **start, off_t off,
-+                 int count, int *eof, void *data)
-+{
-+      int len;
-+
-+      len = sprintf(page, "%d\n", lookupCacheEnabled);
-+
-+      len -= off;
-+      *start = page + off;
-+
-+      if (len > count)
-+              len = count;
-+      else
-+              *eof = 1;
-+
-+      if (len < 0)
-+              len = 0;
-+
-+      return len;
-+}
-+static int
-+lookupFlag_write(struct file *file, const char *buffer,
-+                  unsigned long count, void *data)
-+{
-+      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 int
-+traceSMB_read(char *page, char **start, off_t off, int count,
-+            int *eof, void *data)
-+{
-+      int len;
-+
-+      len = sprintf(page, "%d\n", traceSMB);
-+
-+      len -= off;
-+      *start = page + off;
-+
-+      if (len > count)
-+              len = count;
-+      else
-+              *eof = 1;
-+
-+      if (len < 0)
-+              len = 0;
-+
-+      return len;
-+}
-+static int
-+traceSMB_write(struct file *file, const char *buffer,
-+             unsigned long count, void *data)
-+{
-+      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 int
-+multiuser_mount_read(char *page, char **start, off_t off,
-+                   int count, int *eof, void *data)
-+{
-+      int len;
-+
-+      len = sprintf(page, "%d\n", multiuser_mount);
-+
-+      len -= off;
-+      *start = page + off;
-+
-+      if (len > count)
-+              len = count;
-+      else
-+              *eof = 1;
-+
-+      if (len < 0)
-+              len = 0;
-+
-+      return len;
-+}
-+static int
-+multiuser_mount_write(struct file *file, const char *buffer,
-+                    unsigned long count, void *data)
-+{
-+      char c;
-+      int rc;
-+
-+      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;
-+
-+      return count;
-+}
-+
-+static int
-+extended_security_read(char *page, char **start, off_t off,
-+                     int count, int *eof, void *data)
-+{
-+      int len;
-+
-+      len = sprintf(page, "%d\n", extended_security);
-+
-+      len -= off;
-+      *start = page + off;
-+
-+      if (len > count)
-+              len = count;
-+      else
-+              *eof = 1;
-+
-+      if (len < 0)
-+              len = 0;
-+
-+      return len;
-+}
-+static int
-+extended_security_write(struct file *file, const char *buffer,
-+                      unsigned long count, void *data)
-+{
-+      char c;
-+      int rc;
-+
-+      rc = get_user(c, buffer);
-+      if (rc)
-+              return rc;
-+      if (c == '0' || c == 'n' || c == 'N')
-+              extended_security = 0;
-+      else if (c == '1' || c == 'y' || c == 'Y')
-+              extended_security = 1;
-+
-+      return count;
-+}
-+
-+static int
-+ntlmv2_enabled_read(char *page, char **start, off_t off,
-+                     int count, int *eof, void *data)
-+{
-+      int len;
-+
-+      len = sprintf(page, "%d\n", ntlmv2_support);
-+
-+      len -= off;
-+      *start = page + off;
-+
-+      if (len > count)
-+              len = count;
-+      else
-+              *eof = 1;
-+
-+      if (len < 0)
-+              len = 0;
-+
-+      return len;
-+}
-+static int
-+ntlmv2_enabled_write(struct file *file, const char *buffer,
-+                      unsigned long count, void *data)
-+{
-+      char c;
-+      int rc;
-+
-+      rc = get_user(c, buffer);
-+      if (rc)
-+              return rc;
-+      if (c == '0' || c == 'n' || c == 'N')
-+              ntlmv2_support = 0;
-+      else if (c == '1' || c == 'y' || c == 'Y')
-+              ntlmv2_support = 1;
-+
-+      return count;
-+}
-+
-+static int
-+packet_signing_enabled_read(char *page, char **start, off_t off,
-+                     int count, int *eof, void *data)
-+{
-+      int len;
-+
-+      len = sprintf(page, "%d\n", sign_CIFS_PDUs);
-+
-+      len -= off;
-+      *start = page + off;
-+
-+      if (len > count)
-+              len = count;
-+      else
-+              *eof = 1;
-+
-+      if (len < 0)
-+              len = 0;
-+
-+      return len;
-+}
-+static int
-+packet_signing_enabled_write(struct file *file, const char *buffer,
-+                      unsigned long count, void *data)
-+{
-+      char c;
-+      int rc;
-+
-+      rc = get_user(c, buffer);
-+      if (rc)
-+              return rc;
-+      if (c == '0' || c == 'n' || c == 'N')
-+              sign_CIFS_PDUs = 0;
-+      else if (c == '1' || c == 'y' || c == 'Y')
-+              sign_CIFS_PDUs = 1;
-+      else if (c == '2')
-+              sign_CIFS_PDUs = 2;
-+
-+      return count;
-+}
-+
-+
-+#endif
---- /dev/null
-+++ b/fs/cifs/cifs_debug.h
-@@ -0,0 +1,66 @@
-+/*
-+ *
-+ *   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);
-+extern int traceSMB;          /* flag which enables the function below */
-+void dump_smb(struct smb_hdr *, int);
-+
-+/*
-+ *    debug ON
-+ *    --------
-+ */
-+#ifdef CIFS_DEBUG
-+
-+
-+/* information message: e.g., configuration, major event */
-+extern int cifsFYI;
-+#define cifsfyi(format,arg...) if (cifsFYI) printk(KERN_DEBUG " " __FILE__ ": " format "\n" "" , ## arg)
-+
-+#define cFYI(button,prspec) if (button) cifsfyi prspec
-+
-+#define cifswarn(format, arg...) printk(KERN_WARNING ": " format "\n" , ## arg)
-+
-+/* debug event message: */
-+extern int cifsERROR;
-+
-+#define cEVENT(format,arg...) if (cifsERROR) printk(KERN_EVENT __FILE__ ": " format "\n" , ## arg)
-+
-+/* error event message: e.g., i/o error */
-+#define cifserror(format,arg...) if (cifsERROR) printk(KERN_ERR " CIFS VFS: " format "\n" "" , ## arg)
-+
-+#define cERROR(button, prspec) if (button) cifserror prspec
-+
-+/*
-+ *    debug OFF
-+ *    ---------
-+ */
-+#else         /* _CIFS_DEBUG */
-+#define cERROR(button,prspec)
-+#define cEVENT(format,arg...)
-+#define cFYI(button, prspec)
-+#define cifserror(format,arg...)
-+#endif                /* _CIFS_DEBUG */
-+
-+#endif                                /* _H_CIFS_DEBUG */
---- /dev/null
-+++ b/fs/cifs/cifsencrypt.c
-@@ -0,0 +1,204 @@
-+/*
-+ *   fs/cifs/cifsencrypt.c
-+ *
-+ *   Copyright (C) International Business Machines  Corp., 2003
-+ *   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 "cifs_debug.h"
-+#include "md5.h"
-+#include "cifs_unicode.h"
-+
-+/* Calculate and return the CIFS signature based on the mac key and the smb pdu */
-+/* the 16 byte signature must be allocated by the caller  */
-+/* Note we only use the 1st eight bytes */
-+/* Note that the smb header signature field on input contains the  
-+      sequence number before this function is called */
-+
-+extern void mdfour(unsigned char *out, unsigned char *in, int n);
-+extern void E_md4hash(const unsigned char *passwd, unsigned char *p16);
-+      
-+static int cifs_calculate_signature(const struct smb_hdr * cifs_pdu, const char * key, char * signature)
-+{
-+      struct  MD5Context context;
-+
-+      if((cifs_pdu == NULL) || (signature == NULL))
-+              return -EINVAL;
-+
-+      MD5Init(&context);
-+      MD5Update(&context,key,CIFS_SESSION_KEY_SIZE+16);
-+      MD5Update(&context,cifs_pdu->Protocol,cifs_pdu->smb_buf_length);
-+      MD5Final(signature,&context);
-+      return 0;
-+}
-+
-+int cifs_sign_smb(struct smb_hdr * cifs_pdu, struct cifsSesInfo * ses,
-+      __u32 * pexpected_response_sequence_number)
-+{
-+      int rc = 0;
-+      char smb_signature[20];
-+
-+      /* BB remember to initialize sequence number elsewhere and initialize mac_signing key elsewhere BB */
-+      /* BB remember to add code to save expected sequence number in midQ entry BB */
-+
-+      if((cifs_pdu == NULL) || (ses == NULL))
-+              return -EINVAL;
-+
-+      if((le32_to_cpu(cifs_pdu->Flags2) & SMBFLG2_SECURITY_SIGNATURE) == 0) 
-+              return rc;
-+
-+      spin_lock(&GlobalMid_Lock);
-+      cifs_pdu->Signature.Sequence.SequenceNumber = cpu_to_le32(ses->sequence_number);
-+      cifs_pdu->Signature.Sequence.Reserved = 0;
-+      
-+      *pexpected_response_sequence_number = ses->sequence_number++;
-+      ses->sequence_number++;
-+      spin_unlock(&GlobalMid_Lock);
-+
-+      rc = cifs_calculate_signature(cifs_pdu, ses->mac_signing_key,smb_signature);
-+      if(rc)
-+              memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
-+      else
-+              memcpy(cifs_pdu->Signature.SecuritySignature, smb_signature, 8);
-+
-+      return rc;
-+}
-+
-+int cifs_verify_signature(struct smb_hdr * cifs_pdu, const char * mac_key,
-+      __u32 expected_sequence_number)
-+{
-+      unsigned int rc;
-+      char server_response_sig[8];
-+      char what_we_think_sig_should_be[20];
-+
-+      if((cifs_pdu == NULL) || (mac_key == NULL))
-+              return -EINVAL;
-+
-+      if (cifs_pdu->Command == SMB_COM_NEGOTIATE)
-+              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));
-+
-+      expected_sequence_number = cpu_to_le32(expected_sequence_number);
-+
-+      /* 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 = expected_sequence_number;
-+      cifs_pdu->Signature.Sequence.Reserved = 0;
-+
-+      rc = cifs_calculate_signature(cifs_pdu, mac_key,
-+              what_we_think_sig_should_be);
-+
-+      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;
-+
-+}
-+
-+/* We fill in key by putting in 40 byte array which was allocated by caller */
-+int cifs_calculate_mac_key(char * key, const char * rn, const char * password)
-+{
-+      char temp_key[16];
-+      if ((key == NULL) || (rn == NULL))
-+              return -EINVAL;
-+
-+      E_md4hash(password, temp_key);
-+      mdfour(key,temp_key,16);
-+      memcpy(key+16,rn, CIFS_SESSION_KEY_SIZE);
-+      return 0;
-+}
-+
-+int CalcNTLMv2_partial_mac_key(struct cifsSesInfo * ses, struct nls_table * nls_info)
-+{
-+      char temp_hash[16];
-+      struct HMACMD5Context ctx;
-+      char * ucase_buf;
-+      wchar_t * unicode_buf;
-+      unsigned int i,user_name_len,dom_name_len;
-+
-+      if(ses)
-+              return -EINVAL;
-+
-+      E_md4hash(ses->password, temp_hash);
-+
-+      hmac_md5_init_limK_to_64(temp_hash, 16, &ctx);
-+      user_name_len = strlen(ses->userName);
-+      if(user_name_len > MAX_USERNAME_SIZE)
-+              return -EINVAL;
-+      dom_name_len = strlen(ses->domainName);
-+      if(dom_name_len > MAX_USERNAME_SIZE)
-+              return -EINVAL;
-+  
-+      ucase_buf = kmalloc((MAX_USERNAME_SIZE+1), GFP_KERNEL);
-+      unicode_buf = kmalloc((MAX_USERNAME_SIZE+1)*4, GFP_KERNEL);
-+   
-+      for(i=0;i<user_name_len;i++)
-+              ucase_buf[i] = nls_info->charset2upper[(int)ses->userName[i]];
-+      ucase_buf[i] = 0;
-+      user_name_len = cifs_strtoUCS(unicode_buf, ucase_buf, MAX_USERNAME_SIZE*2, nls_info);
-+      unicode_buf[user_name_len] = 0;
-+      user_name_len++;
-+
-+      for(i=0;i<dom_name_len;i++)
-+              ucase_buf[i] = nls_info->charset2upper[(int)ses->domainName[i]];
-+      ucase_buf[i] = 0;
-+      dom_name_len = cifs_strtoUCS(unicode_buf+user_name_len, ucase_buf, MAX_USERNAME_SIZE*2, nls_info);
-+
-+      unicode_buf[user_name_len + dom_name_len] = 0;
-+      hmac_md5_update((const unsigned char *) unicode_buf,
-+              (user_name_len+dom_name_len)*2,&ctx);
-+
-+      hmac_md5_final(ses->mac_signing_key,&ctx);
-+      kfree(ucase_buf);
-+      kfree(unicode_buf);
-+      return 0;
-+}
-+void CalcNTLMv2_response(const struct cifsSesInfo * ses,char * v2_session_response)
-+{
-+      struct HMACMD5Context context;
-+      memcpy(v2_session_response + 8, ses->server->cryptKey,8);
-+      /* gen_blob(v2_session_response + 16); */
-+      hmac_md5_init_limK_to_64(ses->mac_signing_key, 16, &context);
-+
-+      hmac_md5_update(ses->server->cryptKey,8,&context);
-+/*    hmac_md5_update(v2_session_response+16)client thing,8,&context); */ /* BB fix */
-+
-+      hmac_md5_final(v2_session_response,&context);
-+}
---- /dev/null
-+++ b/fs/cifs/cifserr.c
-@@ -0,0 +1,70 @@
-+/*
-+ *   fs/cifserr.c
-+ *
-+ *   Copyright (c) International Business Machines  Corp., 2002
-+ *   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/errno.h>
-+#include <linux/fs.h>
-+#include <linux/smbno.h>
-+#include "cifsfs.h"
-+
-+int map_cifs_error(int error_class, int error_code,
-+                 int status_codes_negotiated)
-+{
-+
-+
-+      if (status_codes_negotiated) {
-+              switch (error_code) {
-+              default:
-+                      return EIO;
-+              }
-+      } else
-+              switch (error_class) {
-+              case SUCCESS:
-+                      return 0;
-+
-+              case ERRDOS:
-+                      switch (error_code) {
-+                      case ERRbadfunc:
-+                              return EINVAL;
-+                      default:
-+                              return EIO;
-+                      }
-+
-+              case ERRSRV:
-+                      switch (error_code) {
-+                      default:
-+                              return EIO;
-+                      }
-+
-+              case ERRHRD:
-+                      switch (error_code) {
-+                      default:
-+                              return EIO;
-+                      }
-+              default:
-+                      return EIO;
-+              }
-+      return 0;
-+}
-+
-+int map_smb_error(int error_class, int error_code)
-+{
-+      return map_cifs_error(error_class, error_code, FALSE);
-+}
---- /dev/null
-+++ b/fs/cifs/cifsfs.c
-@@ -0,0 +1,769 @@
-+/*
-+ *   fs/cifs/cifsfs.c
-+ *
-+ *   Copyright (C) International Business Machines  Corp., 2002,2004
-+ *   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/version.h>
-+#include <linux/list.h>
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,15))
-+#include <linux/seq_file.h>
-+#endif
-+#include <linux/vfs.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>
-+#define CIFS_MAGIC_NUMBER 0xFF534D42  /* the first four bytes of SMB PDUs */
-+/* BB when mempool_resize is added back in, we will resize pool on new mount */
-+#define CIFS_MIN_RCV_POOL 11 /* enough for progress to five servers */
-+
-+#ifdef CONFIG_CIFS_QUOTA
-+static struct quotactl_ops cifs_quotactl_ops;
-+#endif
-+
-+extern struct file_system_type cifs_fs_type;
-+
-+int cifsFYI = 0;
-+int cifsERROR = 1;
-+int traceSMB = 0;
-+unsigned int oplockEnabled = 1;
-+unsigned int quotaEnabled = 0;
-+unsigned int linuxExtEnabled = 1;
-+unsigned int lookupCacheEnabled = 1;
-+unsigned int multiuser_mount = 0;
-+unsigned int extended_security = 0;
-+unsigned int ntlmv2_support = 0;
-+unsigned int sign_CIFS_PDUs = 1;
-+unsigned int CIFSMaximumBufferSize = CIFS_MAX_MSGSIZE;
-+struct task_struct * oplockThread = NULL;
-+
-+extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *,
-+                      const char *);
-+extern int cifs_umount(struct super_block *, struct cifs_sb_info *);
-+void cifs_proc_init(void);
-+void cifs_proc_clean(void);
-+
-+static DECLARE_COMPLETION(cifs_oplock_exited);
-+
-+
-+struct super_block *
-+cifs_read_super(struct super_block *sb, void *data, int silent)
-+{
-+      struct inode *inode;
-+      struct cifs_sb_info *cifs_sb;
-+      int rc = 0;
-+
-+      sb->s_flags |= MS_NODIRATIME; /* and probably even noatime */
-+      cifs_sb = CIFS_SB(sb);
-+      if(cifs_sb == NULL)
-+              return 0;
-+      else
-+              memset(cifs_sb,0,sizeof(struct cifs_sb_info));
-+      
-+
-+      rc = cifs_mount(sb, cifs_sb, data, NULL);
-+
-+      if (rc) {
-+              if (!silent)
-+                      cERROR(1,
-+                             ("cifs_mount failed w/return code = %d", rc));
-+              goto out_mount_failed;
-+      }
-+
-+      sb->s_magic = CIFS_MAGIC_NUMBER;
-+      sb->s_op = &cifs_super_ops;
-+/*    if(cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512)
-+          sb->s_blocksize = cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */
-+#ifdef CONFIG_CIFS_QUOTA
-+      sb->s_qcop = &cifs_quotactl_ops;
-+#endif
-+      sb->s_blocksize = CIFS_MAX_MSGSIZE;
-+      sb->s_blocksize_bits = 14;      /* default 2**14 = CIFS_MAX_MSGSIZE */
-+      inode = iget(sb, ROOT_I);
-+
-+      if (!inode) {
-+              goto out_no_root;
-+      }
-+
-+      sb->s_root = d_alloc_root(inode);
-+
-+      if (!sb->s_root) {
-+              goto out_no_root;
-+      }
-+
-+      return sb;
-+
-+out_no_root:
-+      cERROR(1, ("cifs_read_super: get root inode failed"));
-+      if (inode)
-+              iput(inode);
-+
-+out_mount_failed:
-+      if(cifs_sb->local_nls)
-+              unload_nls(cifs_sb->local_nls);
-+      sb->s_dev = 0;
-+      return 0;
-+}
-+
-+static void
-+cifs_put_super(struct super_block *sb)
-+{
-+      int rc = 0;
-+      struct cifs_sb_info *cifs_sb;
-+
-+      cFYI(1, ("In cifs_put_super"));
-+      cifs_sb = CIFS_SB(sb);
-+      if(cifs_sb == NULL) {
-+              cFYI(1,("Empty cifs superblock info passed to unmount"));
-+              return;
-+      }
-+      rc = cifs_umount(sb, cifs_sb); 
-+      if (rc) {
-+              cERROR(1, ("cifs_umount failed with return code %d", rc));
-+      }
-+      unload_nls(cifs_sb->local_nls);
-+      return;
-+}
-+
-+static int
-+cifs_statfs(struct super_block *sb, struct statfs *buf)
-+{
-+      int xid, rc;
-+      struct cifs_sb_info *cifs_sb;
-+      struct cifsTconInfo *pTcon;
-+
-+      xid = GetXid();
-+
-+      cifs_sb = CIFS_SB(sb);
-+      pTcon = cifs_sb->tcon;
-+
-+      buf->f_type = CIFS_MAGIC_NUMBER;
-+
-+      /* instead could get the real value via SMB_QUERY_FS_ATTRIBUTE_INFO */
-+      buf->f_namelen = PATH_MAX;      /* PATH_MAX may be too long - it would presumably
-+                                         be length of total path, note that some servers may be 
-+                                         able to support more than this, but best to be safe
-+                                         since Win2k and others can not handle very long filenames */
-+      buf->f_files = 0;       /* undefined */
-+      buf->f_ffree = 0;       /* unlimited */
-+
-+      rc = CIFSSMBQFSInfo(xid, pTcon, buf, cifs_sb->local_nls);
-+
-+      /*     
-+         int f_type;
-+         __fsid_t f_fsid;
-+         int f_namelen;  */
-+      /* BB get from info put in tcon struct at mount time with call to QFSAttrInfo */
-+      FreeXid(xid);
-+      return 0;               /* always return success? what if volume is no longer available? */
-+}
-+
-+static int cifs_permission(struct inode * inode, int mask)
-+{
-+      /* the server does permission checks, we do not need to do it here */
-+      return 0;
-+}
-+
-+kmem_cache_t *cifs_req_cachep;
-+kmem_cache_t *cifs_mid_cachep;
-+kmem_cache_t *cifs_oplock_cachep;
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-+static struct inode *
-+cifs_alloc_inode(struct super_block *sb)
-+{
-+        struct cifsInodeInfo *cifs_inode;
-+        cifs_inode =
-+            (struct cifsInodeInfo *) kmem_cache_alloc(cifs_inode_cachep,
-+                                                      SLAB_KERNEL);
-+        if (!cifs_inode)
-+                return NULL;
-+        cifs_inode->cifsAttrs = 0x20;   /* default */
-+        atomic_set(&cifs_inode->inUse, 0);
-+        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_inode->clientCanCacheRead = FALSE;
-+        cifs_inode->clientCanCacheAll = FALSE;
-+        INIT_LIST_HEAD(&cifs_inode->openFileList);
-+        return &cifs_inode->vfs_inode;
-+}
-+
-+static void
-+cifs_destroy_inode(struct inode *inode)
-+{
-+      kmem_cache_free(cifs_inode_cachep, CIFS_I(inode));
-+}
-+#endif
-+
-+/*
-+ * cifs_show_options() is for displaying mount options in /proc/mounts.
-+ * Not all settable options are displayed but most of the important
-+ * ones are.
-+ */
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,15))
-+static int
-+cifs_show_options(struct seq_file *s, struct vfsmount *m)
-+{
-+      struct cifs_sb_info *cifs_sb;
-+
-+      cifs_sb = CIFS_SB(m->mnt_sb);
-+
-+      if (cifs_sb) {
-+              if (cifs_sb->tcon) {
-+                      seq_printf(s, ",unc=%s", cifs_sb->tcon->treeName);
-+                      if ((cifs_sb->tcon->ses) && (cifs_sb->tcon->ses->userName))
-+                              seq_printf(s, ",username=%s",
-+                                         cifs_sb->tcon->ses->userName);
-+                      if(cifs_sb->tcon->ses->domainName)
-+                              seq_printf(s, ",domain=%s",
-+                                      cifs_sb->tcon->ses->domainName);
-+              }
-+              seq_printf(s, ",rsize=%d",cifs_sb->rsize);
-+              seq_printf(s, ",wsize=%d",cifs_sb->wsize);
-+      }
-+      return 0;
-+}
-+#endif
-+
-+#ifdef CONFIG_CIFS_QUOTA
-+int cifs_xquota_set(struct super_block * sb, int quota_type, qid_t qid,
-+              struct fs_disk_quota * pdquota)
-+{
-+      int xid;
-+      int rc = 0;
-+      struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
-+      struct cifsTconInfo *pTcon;
-+      
-+      if(cifs_sb)
-+              pTcon = cifs_sb->tcon;
-+      else
-+              return -EIO;
-+
-+
-+      xid = GetXid();
-+      if(pTcon) {
-+              cFYI(1,("set type: 0x%x id: %d",quota_type,qid));               
-+      } else {
-+              return -EIO;
-+      }
-+
-+      FreeXid(xid);
-+      return rc;
-+}
-+
-+int cifs_xquota_get(struct super_block * sb, int quota_type, qid_t qid,
-+                struct fs_disk_quota * pdquota)
-+{
-+      int xid;
-+      int rc = 0;
-+      struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
-+      struct cifsTconInfo *pTcon;
-+
-+      if(cifs_sb)
-+              pTcon = cifs_sb->tcon;
-+      else
-+              return -EIO;
-+
-+      xid = GetXid();
-+      if(pTcon) {
-+                cFYI(1,("set type: 0x%x id: %d",quota_type,qid));
-+      } else {
-+              rc = -EIO;
-+      }
-+
-+      FreeXid(xid);
-+      return rc;
-+}
-+
-+int cifs_xstate_set(struct super_block * sb, unsigned int flags, int operation)
-+{
-+      int xid; 
-+      int rc = 0;
-+      struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
-+      struct cifsTconInfo *pTcon;
-+
-+      if(cifs_sb)
-+              pTcon = cifs_sb->tcon;
-+      else
-+              return -EIO;
-+
-+      xid = GetXid();
-+      if(pTcon) {
-+                cFYI(1,("flags: 0x%x operation: 0x%x",flags,operation));
-+      } else {
-+              rc = -EIO;
-+      }
-+
-+      FreeXid(xid);
-+      return rc;
-+}
-+
-+int cifs_xstate_get(struct super_block * sb, struct fs_quota_stat *qstats)
-+{
-+      int xid;
-+      int rc = 0;
-+      struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
-+      struct cifsTconInfo *pTcon;
-+
-+      if(cifs_sb) {
-+              pTcon = cifs_sb->tcon;
-+      } else {
-+              return -EIO;
-+      }
-+      xid = GetXid();
-+      if(pTcon) {
-+              cFYI(1,("pqstats %p",qstats));          
-+      } else {
-+              rc = -EIO;
-+      }
-+
-+      FreeXid(xid);
-+      return rc;
-+}
-+
-+static struct quotactl_ops cifs_quotactl_ops = {
-+      .set_xquota     = cifs_xquota_set,
-+      .get_xquota     = cifs_xquota_set,
-+      .set_xstate     = cifs_xstate_set,
-+      .get_xstate     = cifs_xstate_get,
-+};
-+#endif
-+
-+static int cifs_remount(struct super_block *sb, int *flags, char *data)
-+{
-+      *flags |= MS_NODIRATIME;
-+      return 0;
-+}
-+
-+struct super_operations cifs_super_ops = {
-+      .read_inode = cifs_read_inode,
-+      .put_super = cifs_put_super,
-+      .statfs = cifs_statfs,
-+/*    .alloc_inode = cifs_alloc_inode,
-+      .destroy_inode = cifs_destroy_inode, */
-+/*    .drop_inode         = generic_delete_inode, 
-+      .delete_inode   = cifs_delete_inode,  *//* Do not need the above two functions     
-+   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 */
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,15))
-+      .show_options = cifs_show_options,
-+#endif
-+/*    .umount_begin   = cifs_umount_begin, *//* consider adding in the future */
-+};
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-+static struct super_block *
-+cifs_get_sb(struct file_system_type *fs_type,
-+          int flags, const char *dev_name, void *data)
-+{
-+      int rc;
-+      struct super_block *sb = sget(fs_type, NULL, set_anon_super, NULL);
-+
-+      cFYI(1, ("Devname: %s flags: %d ", dev_name, flags));
-+
-+      if (IS_ERR(sb))
-+              return sb;
-+
-+      sb->s_flags = flags;
-+
-+      rc = cifs_read_super(sb, data, dev_name, flags & MS_VERBOSE ? 1 : 0);
-+      if (rc) {
-+              up_write(&sb->s_umount);
-+              deactivate_super(sb);
-+              return ERR_PTR(rc);
-+      }
-+      sb->s_flags |= MS_ACTIVE;
-+      return sb;
-+}
-+#endif
-+
-+static ssize_t
-+cifs_read_wrapper(struct file * file, char *read_data, size_t read_size,
-+          loff_t * poffset)
-+{
-+      if(file == NULL)
-+              return -EIO;
-+      else if(file->f_dentry == NULL)
-+              return -EIO;
-+      else if(file->f_dentry->d_inode == NULL)
-+              return -EIO;
-+
-+      if(CIFS_I(file->f_dentry->d_inode)->clientCanCacheRead) {
-+              return generic_file_read(file,read_data,read_size,poffset);
-+      } else {
-+              /* BB do we need to lock inode from here until after invalidate? */
-+/*            if(file->f_dentry->d_inode->i_mapping) {
-+                      filemap_fdatawrite(file->f_dentry->d_inode->i_mapping);
-+                      filemap_fdatawait(file->f_dentry->d_inode->i_mapping);
-+              }*/
-+/*            cifs_revalidate(file->f_dentry);*/ /* BB fixme */
-+
-+              /* BB we should make timer configurable - perhaps 
-+                 by simply calling cifs_revalidate here */
-+              /* invalidate_remote_inode(file->f_dentry->d_inode);*/
-+              return generic_file_read(file,read_data,read_size,poffset);
-+      }
-+}
-+
-+static ssize_t
-+cifs_write_wrapper(struct file * file, const char *write_data,
-+           size_t write_size, loff_t * poffset) 
-+{
-+      ssize_t written;
-+
-+      if(file == NULL)
-+              return -EIO;
-+      else if(file->f_dentry == NULL)
-+              return -EIO;
-+      else if(file->f_dentry->d_inode == NULL)
-+              return -EIO;
-+
-+      /* check whether we can cache writes locally */
-+      written = generic_file_write(file,write_data,write_size,poffset);
-+      if(!CIFS_I(file->f_dentry->d_inode)->clientCanCacheAll)  {
-+              if(file->f_dentry->d_inode->i_mapping) {
-+                      filemap_fdatasync(file->f_dentry->d_inode->i_mapping);
-+              }
-+      }
-+      return written;
-+}
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-+static struct file_system_type cifs_fs_type = {
-+      .owner = THIS_MODULE,
-+      .name = "cifs",
-+      .get_sb = cifs_get_sb,
-+      .kill_sb = kill_anon_super,
-+      /*  .fs_flags */
-+};
-+#endif
-+
-+static DECLARE_FSTYPE(cifs_fs_type, "cifs", cifs_read_super,0);
-+
-+
-+struct inode_operations cifs_dir_inode_ops = {
-+      .create = cifs_create,
-+      .lookup = cifs_lookup,
-+      .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,
-+};
-+
-+struct inode_operations cifs_file_inode_ops = {
-+      .revalidate = cifs_revalidate,
-+      .setattr = cifs_setattr,
-+/*    .getattr = cifs_getattr,*/
-+      .rename = cifs_rename,
-+      .permission = cifs_permission,
-+#ifdef CONFIG_CIFS_XATTR
-+      .setxattr = cifs_setxattr,
-+      .getxattr = cifs_getxattr,
-+      .listxattr = cifs_listxattr,
-+      .removexattr = cifs_removexattr,
-+#endif 
-+};
-+
-+struct inode_operations cifs_symlink_inode_ops = {
-+      .readlink = cifs_readlink,
-+      .follow_link = cifs_follow_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 
-+};
-+
-+struct file_operations cifs_file_ops = {
-+      .read = cifs_read_wrapper,
-+      .write = cifs_write_wrapper, 
-+      .open = cifs_open,
-+      .release = cifs_close,
-+      .lock = cifs_lock,
-+      .fsync = cifs_fsync,
-+      .flush = cifs_flush,
-+      .mmap  = cifs_file_mmap,
-+/*    .sendfile = generic_file_sendfile,*/
-+#ifdef CONFIG_CIFS_FCNTL
-+      .fcntl = cifs_fcntl,
-+#endif
-+};
-+
-+struct file_operations cifs_dir_ops = {
-+      .readdir = cifs_readdir,
-+      .release = cifs_closedir,
-+      .read    = generic_read_dir,
-+#ifdef CONFIG_CIFS_FCNTL
-+      .fcntl   = cifs_fcntl,
-+#endif
-+};
-+/*
-+static void
-+cifs_init_once(void *inode, kmem_cache_t * cachep, unsigned long flags)
-+{
-+      struct cifsInodeInfo *cifsi = (struct cifsInodeInfo *) inode;
-+
-+      if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) ==
-+          SLAB_CTOR_CONSTRUCTOR) {
-+              inode_init_once(&cifsi->vfs_inode);
-+              INIT_LIST_HEAD(&cifsi->lockList);
-+      }
-+}
-+
-+static int
-+cifs_init_inodecache(void)
-+{
-+      cifs_inode_cachep = kmem_cache_create("cifs_inode_cache",
-+                                            sizeof (struct cifsInodeInfo),
-+                                            0, SLAB_HWCACHE_ALIGN,
-+                                            cifs_init_once, NULL);
-+      if (cifs_inode_cachep == NULL)
-+              return -ENOMEM;
-+      
-+
-+      return 0;
-+}
-+
-+static void
-+cifs_destroy_inodecache(void)
-+{
-+      if (kmem_cache_destroy(cifs_inode_cachep))
-+              printk(KERN_WARNING "cifs_inode_cache: error freeing\n");
-+} */
-+
-+static int
-+cifs_init_request_bufs(void)
-+{
-+      cifs_req_cachep = kmem_cache_create("cifs_request",
-+                                          CIFS_MAX_MSGSIZE +
-+                                          MAX_CIFS_HDR_SIZE, 0,
-+                                          SLAB_HWCACHE_ALIGN, NULL, NULL);
-+      if (cifs_req_cachep == NULL)
-+              return -ENOMEM;
-+
-+      return 0;
-+}
-+
-+static void
-+cifs_destroy_request_bufs(void)
-+{
-+      if (kmem_cache_destroy(cifs_req_cachep))
-+              printk(KERN_WARNING
-+                     "cifs_destroy_request_cache: error not all structures were freed\n");
-+}
-+
-+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, NULL);
-+      if (cifs_mid_cachep == NULL)
-+              return -ENOMEM;
-+      cifs_oplock_cachep = kmem_cache_create("cifs_oplock_struct",
-+                              sizeof (struct oplock_q_entry), 0,
-+                              SLAB_HWCACHE_ALIGN, NULL, NULL);
-+      if (cifs_oplock_cachep == NULL) {
-+              kmem_cache_destroy(cifs_mid_cachep);
-+              return -ENOMEM;
-+      }
-+
-+      return 0;
-+}
-+
-+static void
-+cifs_destroy_mids(void)
-+{
-+      if (kmem_cache_destroy(cifs_mid_cachep))
-+              printk(KERN_WARNING
-+                     "cifs_destroy_mids: error not all structures were freed\n");
-+      if (kmem_cache_destroy(cifs_oplock_cachep))
-+              printk(KERN_WARNING
-+                     "error not all oplock structures were freed\n");
-+}
-+
-+static int cifs_oplock_thread(void * dummyarg)
-+{
-+      struct oplock_q_entry * oplock_item;
-+      struct cifsTconInfo *pTcon;
-+      struct inode * inode;
-+      __u16  netfid;
-+      int rc = 0;
-+
-+      daemonize();
-+      sprintf(current->comm,"cifsoplockd");
-+
-+      oplockThread = current;
-+      do {
-+              set_current_state(TASK_INTERRUPTIBLE);
-+              
-+              schedule_timeout(1*HZ);  
-+              spin_lock(&GlobalMid_Lock);
-+              if(list_empty(&GlobalOplock_Q)) {
-+                      spin_unlock(&GlobalMid_Lock);
-+                      set_current_state(TASK_INTERRUPTIBLE);
-+                      schedule_timeout(39*HZ);
-+              } else {
-+                      oplock_item = list_entry(GlobalOplock_Q.next, 
-+                              struct oplock_q_entry, qhead);
-+                      if(oplock_item) {
-+                              cFYI(1,("found oplock item to write out")); 
-+                              pTcon = oplock_item->tcon;
-+                              inode = oplock_item->pinode;
-+                              netfid = oplock_item->netfid;
-+                              spin_unlock(&GlobalMid_Lock);
-+                              DeleteOplockQEntry(oplock_item);
-+                              /* can not grab inode sem here since it would
-+                              deadlock when oplock received on delete 
-+                              since vfs_unlink holds the i_sem across
-+                              the call */
-+                              /* down(&inode->i_sem);*/
-+                              if (S_ISREG(inode->i_mode)) {
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,17))
-+                                      rc = filemap_fdatasync(inode->i_mapping);
-+                                      if(rc)
-+                                              CIFS_I(inode)->write_behind_rc = rc;
-+#else 
-+                                      filemap_fdatasync(inode->i_mapping);
-+#endif
-+                                      if(CIFS_I(inode)->clientCanCacheRead == 0) 
-+                                              invalidate_inode_pages(inode);
-+                              } else
-+                                      rc = 0;
-+                              /* releasing a stale oplock after recent reconnection 
-+                              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 in that case */
-+                              if(pTcon->tidStatus != CifsNeedReconnect) {
-+                                      rc = CIFSSMBLock(0, pTcon, 
-+                                              netfid,
-+                                              0 /* len */ , 0 /* offset */, 0, 
-+                                              0, LOCKING_ANDX_OPLOCK_RELEASE,
-+                                              0 /* wait flag */);
-+                                      cFYI(1,("Oplock release rc = %d ",rc));
-+                              }
-+                      } else
-+                              spin_unlock(&GlobalMid_Lock);
-+              }
-+      } while(!signal_pending(current));
-+      complete_and_exit (&cifs_oplock_exited, 0);
-+}
-+
-+static int __init
-+init_cifs(void)
-+{
-+      int rc = 0;
-+#if CONFIG_PROC_FS
-+      cifs_proc_init();
-+#endif
-+      INIT_LIST_HEAD(&GlobalServerList);      /* BB not implemented yet */
-+      INIT_LIST_HEAD(&GlobalSMBSessionList);
-+      INIT_LIST_HEAD(&GlobalTreeConnectionList);
-+      INIT_LIST_HEAD(&GlobalOplock_Q);
-+/*
-+ *  Initialize Global counters
-+ */
-+      atomic_set(&sesInfoAllocCount, 0);
-+      atomic_set(&tconInfoAllocCount, 0);
-+      atomic_set(&tcpSesReconnectCount, 0);
-+      atomic_set(&tconInfoReconnectCount, 0);
-+
-+      atomic_set(&bufAllocCount, 0);
-+      atomic_set(&midCount, 0);
-+      GlobalCurrentXid = 0;
-+      GlobalTotalActiveXid = 0;
-+      GlobalMaxActiveXid = 0;
-+      GlobalSMBSeslock = RW_LOCK_UNLOCKED;
-+      GlobalMid_Lock = SPIN_LOCK_UNLOCKED;
-+
-+/*    rc = cifs_init_inodecache();*/
-+      if (!rc) {
-+              rc = cifs_init_mids();
-+              if (!rc) {
-+                      rc = cifs_init_request_bufs();
-+                      if (!rc) {
-+                              rc = register_filesystem(&cifs_fs_type);
-+                              if (!rc) {                
-+                                      kernel_thread(cifs_oplock_thread, NULL, 
-+                                              CLONE_FS | CLONE_FILES | CLONE_VM);
-+                                      return rc; /* Success */
-+                              } else
-+                                      cifs_destroy_request_bufs();
-+                      }
-+                      cifs_destroy_mids();
-+              }
-+/*            cifs_destroy_inodecache(); */
-+      }
-+#if CONFIG_PROC_FS
-+      cifs_proc_clean();
-+#endif
-+      return rc;
-+}
-+
-+static void __exit
-+exit_cifs(void)
-+{
-+      cFYI(0, ("In unregister ie exit_cifs"));
-+#if CONFIG_PROC_FS
-+      cifs_proc_clean();
-+#endif
-+      unregister_filesystem(&cifs_fs_type);
-+/*    cifs_destroy_inodecache();*/
-+      cifs_destroy_mids();
-+      cifs_destroy_request_bufs();
-+      if(oplockThread) {
-+              send_sig(SIGTERM, oplockThread, 1);
-+              wait_for_completion(&cifs_oplock_exited);
-+      }
-+}
-+
-+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_init(init_cifs)
-+module_exit(exit_cifs)
---- /dev/null
-+++ b/fs/cifs/cifsfs.h
-@@ -0,0 +1,97 @@
-+/*
-+ *   fs/cifs/cifsfs.h
-+ *
-+ *   Copyright (c) International Business Machines  Corp., 2002
-+ *   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
-+
-+#ifndef FALSE
-+#define FALSE 0
-+#endif
-+
-+#ifndef TRUE
-+#define TRUE 1
-+#endif
-+
-+extern int map_cifs_error(int error_class, int error_code,
-+                        int status_codes_negotiated);
-+
-+extern struct address_space_operations cifs_addr_ops;
-+
-+/* Functions related to super block operations */
-+extern struct super_operations cifs_super_ops;
-+extern void cifs_put_inode(struct inode *);
-+extern void cifs_read_inode(struct inode *);
-+extern void cifs_delete_inode(struct inode *);
-+/* extern void cifs_write_inode(struct inode *); *//* BB not needed yet */
-+
-+/* Functions related to inodes */
-+extern struct inode_operations cifs_dir_inode_ops;
-+extern int cifs_create(struct inode *, struct dentry *, int);
-+extern struct dentry *cifs_lookup(struct inode *, struct dentry *);
-+extern int cifs_unlink(struct inode *, struct dentry *);
-+extern int cifs_hardlink(struct dentry *, struct inode *, struct dentry *);
-+extern int cifs_mknod(struct inode *, struct dentry *, int, int);
-+extern int cifs_mkdir(struct inode *, struct dentry *, int);
-+extern int cifs_rmdir(struct inode *, struct dentry *);
-+extern int cifs_rename(struct inode *, struct dentry *, struct inode *,
-+                     struct dentry *);
-+extern int cifs_revalidate(struct dentry *);
-+extern int cifs_setattr(struct dentry *, struct iattr *);
-+
-+extern struct inode_operations cifs_file_inode_ops;
-+extern void cifs_truncate_file(struct inode *);
-+extern struct inode_operations cifs_symlink_inode_ops;
-+
-+/* Functions related to files and directories */
-+extern struct file_operations cifs_file_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_read(struct file *file, char *read_data,
-+                       size_t read_size, loff_t * poffset);
-+extern ssize_t cifs_write(struct file *file, const char *write_data,
-+                        size_t write_size, loff_t * poffset);
-+extern int cifs_lock(struct file *, int, struct file_lock *);
-+extern int cifs_fsync(struct file *, struct dentry *, int);
-+extern int cifs_flush(struct file *);
-+extern int cifs_file_mmap(struct file * , struct vm_area_struct *);
-+extern 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);
-+extern long cifs_fcntl(int, unsigned int, unsigned long, struct file *);
-+
-+/* Functions related to dir entries */
-+extern struct dentry_operations cifs_dentry_ops;
-+
-+/* Functions related to symlinks */
-+extern int cifs_follow_link(struct dentry *direntry, struct nameidata *nd);
-+extern int cifs_readlink(struct dentry *direntry, char *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);
-+#define CIFS_VERSION   "1.20"
-+#endif                                /* _CIFSFS_H */
---- /dev/null
-+++ b/fs/cifs/cifs_fs_sb.h
-@@ -0,0 +1,32 @@
-+/*
-+ *   fs/cifs/cifs_fs_sb.h
-+ *
-+ *   Copyright (c) International Business Machines  Corp., 2002
-+ *   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.
-+ *
-+ */
-+#ifndef _CIFS_FS_SB_H
-+#define _CIFS_FS_SB_H
-+
-+struct cifs_sb_info {
-+      struct cifsTconInfo *tcon;      /* primary mount */
-+      struct list_head nested_tcon_q;
-+      struct nls_table *local_nls;
-+      unsigned int rsize;
-+      unsigned int wsize;
-+      uid_t   mnt_uid;
-+      gid_t   mnt_gid;
-+      mode_t  mnt_file_mode;
-+      mode_t  mnt_dir_mode;
-+};
-+#endif                                /* _CIFS_FS_SB_H */
---- /dev/null
-+++ b/fs/cifs/cifsglob.h
-@@ -0,0 +1,413 @@
-+/*
-+ *   fs/cifs/cifsglob.h
-+ *
-+ *   Copyright (C) International Business Machines  Corp., 2002,2003
-+ *   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/in.h>
-+#include <linux/in6.h>
-+#include "cifs_fs_sb.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  64    /* used to be 20 - this should still be enough */
-+#define MAX_USERNAME_SIZE 32  /* 32 is to allow for 15 char names + null
-+                                 termination then *2 for unicode versions */
-+#define MAX_PASSWORD_SIZE 16
-+
-+/*
-+ * MAX_REQ is the maximum number of requests that WE will send
-+ * on one socket concurently. It also matches the most common
-+ * value of max multiplex returned by servers.  We may 
-+ * eventually want to use the negotiated value (in case
-+ * future servers can handle more) when we are more confident that
-+ * we will not have problems oveloading the socket with pending
-+ * write data.
-+ */
-+#define CIFS_MAX_REQ 50 
-+
-+#define SERVER_NAME_LENGTH 15
-+#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 FALSE
-+#define FALSE 0
-+#endif
-+
-+#ifndef TRUE
-+#define TRUE 1
-+#endif
-+
-+#ifndef XATTR_DOS_ATTRIB
-+#define XATTR_DOS_ATTRIB "user.DOSATTRIB"
-+#endif
-+
-+/*
-+ * This information is kept on every Server we know about.
-+ *
-+ * Some things to note:
-+ *
-+ */
-+#define SERVER_NAME_LEN_WITH_NULL     (SERVER_NAME_LENGTH + 1)
-+
-+/*
-+ * CIFS vfs client Status information (based on what we know.)
-+ */
-+
-+ /* associated with each tcp and smb session */
-+enum statusEnum {
-+      CifsNew = 0,
-+      CifsGood,
-+      CifsExiting,
-+      CifsNeedReconnect
-+};
-+
-+enum securityEnum {
-+      NTLM = 0,               /* Legacy NTLM012 auth with NTLM hash */
-+      NTLMv2,                 /* Legacy NTLM auth with NTLMv2 hash */
-+      RawNTLMSSP,             /* NTLMSSP without SPNEGO */
-+      NTLMSSP,                /* NTLMSSP via SPNEGO */
-+      Kerberos                /* Kerberos via SPNEGO */
-+};
-+
-+enum protocolEnum {
-+      IPV4 = 0,
-+      IPV6,
-+      SCTP
-+      /* Netbios frames protocol not supported at this time */
-+};
-+
-+/*
-+ *****************************************************************
-+ * Except the CIFS PDUs themselves all the
-+ * globally interesting structs should go here
-+ *****************************************************************
-+ */
-+
-+struct TCP_Server_Info {
-+      char server_Name[SERVER_NAME_LEN_WITH_NULL];    /* 15 chars + X'20'in 16th */
-+      char unicode_server_Name[SERVER_NAME_LEN_WITH_NULL * 2];        /* Unicode version of server_Name */
-+      struct socket *ssocket;
-+      union {
-+              struct sockaddr_in sockAddr;
-+              struct sockaddr_in6 sockAddr6;
-+      } addr;
-+      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;
-+      void *Server_NlsInfo;   /* BB - placeholder for future NLS info  */
-+      unsigned short server_codepage; /* codepage for the server    */
-+      unsigned long ip_address;       /* IP addr for the server if known     */
-+      enum protocolEnum protocolType; 
-+      char versionMajor;
-+      char versionMinor;
-+      int svlocal:1;          /* local server or remote */
-+      atomic_t socketUseCount; /* number of open cifs sessions on socket */
-+      atomic_t inFlight;  /* number of requests on the wire to server */
-+      enum statusEnum tcpStatus; /* what we think the status is */
-+      struct semaphore tcpSem;
-+      struct task_struct *tsk;
-+      char server_GUID[16];
-+      char secMode;
-+      enum securityEnum secType;
-+      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 */
-+      unsigned int maxRw;     /* maxRw specifies the maximum */
-+      /* message size the server can send or receive for */
-+      /* SMB_COM_WRITE_RAW or SMB_COM_READ_RAW. */
-+      char sessid[4];         /* unique token id for this session */
-+      /* (returned on Negotiate */
-+      int capabilities; /* allow selective disabling of caps by smb sess */
-+      __u16 timeZone;
-+      char cryptKey[CIFS_CRYPTO_KEY_SIZE];
-+      char workstation_RFC1001_name[16]; /* 16th byte is always zero */
-+};
-+
-+/*
-+ * The following is our shortcut to user information.  We surface the uid,
-+ * and name. We always get the password on the fly in case it
-+ * has changed. We also hang a list of sessions owned by this user off here. 
-+ */
-+struct cifsUidInfo {
-+      struct list_head userList;
-+      struct list_head sessionList; /* SMB sessions for this user */
-+      uid_t linux_uid;
-+      char user[MAX_USERNAME_SIZE + 1];       /* ascii name of user */
-+      /* BB may need ptr or callback for PAM or WinBind info */
-+};
-+
-+/*
-+ * Session structure.  One of these for each uid session with a particular host
-+ */
-+struct cifsSesInfo {
-+      struct list_head cifsSessionList;
-+      struct semaphore sesSem;
-+      struct cifsUidInfo *uidInfo;    /* pointer to user info */
-+      struct TCP_Server_Info *server; /* pointer to server info */
-+      atomic_t inUse; /* # of mounts (tree connections) on this ses */
-+      enum statusEnum status;
-+      __u32 sequence_number;  /* needed for CIFS PDU signature */
-+      __u16 ipc_tid;          /* special tid for connection to IPC share */
-+      char mac_signing_key[CIFS_SESSION_KEY_SIZE + 16];       
-+      char *serverOS;         /* name of operating system underlying the server */
-+      char *serverNOS;        /* name of network operating system that the server is running */
-+      char *serverDomain;     /* security realm of server */
-+      int Suid;               /* remote smb uid  */
-+      uid_t linux_uid;        /* local Linux uid */
-+      int capabilities;
-+      char serverName[SERVER_NAME_LEN_WITH_NULL * 2]; /* BB make bigger for tcp names - will ipv6 and sctp addresses fit here?? */
-+      char userName[MAX_USERNAME_SIZE + 1];
-+      char domainName[MAX_USERNAME_SIZE + 1];
-+      char * password;
-+};
-+
-+/*
-+ * there is one of these for each connection to a resource on a particular
-+ * session 
-+ */
-+struct cifsTconInfo {
-+      struct list_head cifsConnectionList;
-+      struct list_head openFileList;
-+      struct semaphore tconSem;
-+      struct cifsSesInfo *ses;        /* pointer to session associated with */
-+      char treeName[MAX_TREE_SIZE + 1]; /* UNC name of resource (in ASCII not UTF) */
-+      char *nativeFileSystem;
-+      __u16 tid;              /* The 2 byte tree id */
-+      __u16 Flags;            /* optional support bits */
-+      enum statusEnum tidStatus;
-+      atomic_t useCount;      /* how many mounts (explicit or implicit) to this share */
-+#ifdef CONFIG_CIFS_STATS
-+      atomic_t num_smbs_sent;
-+      atomic_t num_writes;
-+      atomic_t num_reads;
-+      atomic_t num_oplock_brks;
-+      atomic_t num_opens;
-+      atomic_t num_deletes;
-+      atomic_t num_mkdirs;
-+      atomic_t num_rmdirs;
-+      atomic_t num_renames;
-+      atomic_t num_t2renames;
-+      __u64    bytes_read;
-+      __u64    bytes_written;
-+      spinlock_t stat_lock;
-+#endif
-+      FILE_SYSTEM_DEVICE_INFO fsDevInfo;
-+      FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo;  /* ok if file system name truncated */
-+      FILE_SYSTEM_UNIX_INFO fsUnixInfo;
-+      int retry:1;
-+      /* BB add field for back pointer to sb struct? */
-+};
-+
-+/*
-+ * This info hangs off the cifsFileInfo structure.  This is used to track
-+ * byte stream locks on the file
-+ */
-+struct cifsLockInfo {
-+      struct cifsLockInfo *next;
-+      int start;
-+      int length;
-+      int type;
-+};
-+
-+/*
-+ * One of these for each open instance of a file
-+ */
-+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 file * pfile; /* needed for writepage */
-+      struct inode * pInode; /* needed for oplock break */
-+      int endOfSearch:1;      /* we have reached end of search */
-+      int closePend:1;        /* file is marked to close */
-+      int emptyDir:1;
-+      int invalidHandle:1;  /* file closed via session abend */
-+      struct semaphore fh_sem; /* prevents reopen race after dead ses*/
-+      char * search_resume_name;
-+      unsigned int resume_name_length;
-+      __u32 resume_key;
-+};
-+
-+/*
-+ * One of these for each file inode
-+ */
-+
-+struct cifsInodeInfo {
-+      struct list_head lockList;
-+      /* BB add in lists for dirty pages - i.e. write caching info for oplock */
-+      struct list_head openFileList;
-+      int write_behind_rc;
-+      __u32 cifsAttrs; /* e.g. DOS archive bit, sparse, compressed, system */
-+      atomic_t inUse;  /* num concurrent users (local openers cifs) of file*/
-+      unsigned long time;     /* jiffies of last update/check of inode */
-+      int clientCanCacheRead:1; /* read oplock */
-+      int clientCanCacheAll:1;  /* read and writebehind oplock */
-+      int oplockPending:1;
-+      struct inode vfs_inode;
-+};
-+
-+static inline struct cifsInodeInfo * CIFS_I(struct inode *inode)
-+{
-+        return (struct cifsInodeInfo *)&(inode->u);
-+}
-+
-+static inline struct cifs_sb_info * CIFS_SB(struct super_block *sb)
-+{
-+        return (struct cifs_sb_info *) &(sb->u);
-+}
-+
-+
-+/* 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 */
-+      __u16 mid;              /* multiplex id */
-+      __u16 pid;              /* process id */
-+      __u32 sequence_number;  /* for CIFS signing */
-+      __u16 command;          /* smb command code */
-+      struct timeval when_sent;       /* time when smb sent */
-+      struct cifsSesInfo *ses;        /* smb was sent to this server */
-+      struct task_struct *tsk;        /* task waiting for response */
-+      struct smb_hdr *resp_buf;       /* response buffer */
-+      int midState;   /* wish this were enum but can not pass to wait_event */
-+};
-+
-+struct oplock_q_entry {
-+      struct list_head qhead;
-+      struct inode * pinode;
-+      struct cifsTconInfo * tcon; 
-+      __u16 netfid;
-+};
-+
-+#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 */
-+
-+/*
-+ *****************************************************************
-+ * 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
-+ *  GlobalSMBSesLock 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 servers that did not respond with NT LM 0.12.
-+ * This list helps improve performance and eliminate the messages indicating
-+ * that we had a communications error talking to the server in this list. 
-+ */
-+GLOBAL_EXTERN struct servers_not_supported *NotSuppList;      /*@z4a */
-+
-+/*
-+ * The following is a hash table of all the users we know about.
-+ */
-+GLOBAL_EXTERN struct smbUidInfo *GlobalUidList[UID_HASH];
-+
-+GLOBAL_EXTERN struct list_head GlobalServerList; /* BB not implemented yet */
-+GLOBAL_EXTERN struct list_head GlobalSMBSessionList;
-+GLOBAL_EXTERN struct list_head GlobalTreeConnectionList;
-+GLOBAL_EXTERN rwlock_t GlobalSMBSeslock;  /* protects list inserts on 3 above */
-+
-+GLOBAL_EXTERN struct list_head GlobalOplock_Q;
-+
-+/*
-+ * 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 and list operations */
-+                                      /* on midQ entries */
-+GLOBAL_EXTERN char Local_System_Name[15];
-+
-+/*
-+ *  Global counters, updated atomically
-+ */
-+GLOBAL_EXTERN atomic_t sesInfoAllocCount;
-+GLOBAL_EXTERN atomic_t tconInfoAllocCount;
-+
-+GLOBAL_EXTERN atomic_t tcpSesReconnectCount;
-+GLOBAL_EXTERN atomic_t tconInfoReconnectCount;
-+
-+/* Various Debug counters to remove someday (BB) */
-+GLOBAL_EXTERN atomic_t bufAllocCount;
-+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 */
-+GLOBAL_EXTERN unsigned int oplockEnabled;
-+GLOBAL_EXTERN unsigned int quotaEnabled;
-+GLOBAL_EXTERN unsigned int lookupCacheEnabled;
-+GLOBAL_EXTERN unsigned int extended_security; /* if on, session setup sent 
-+                              with more secure ntlmssp2 challenge/resp */
-+GLOBAL_EXTERN unsigned int ntlmv2_support;  /* better optional password hash */
-+GLOBAL_EXTERN unsigned int sign_CIFS_PDUs;  /* enable smb packet signing */
-+GLOBAL_EXTERN unsigned int linuxExtEnabled;  /* enable Linux/Unix CIFS extensions */
-+
---- /dev/null
-+++ b/fs/cifs/cifspdu.h
-@@ -0,0 +1,1793 @@
-+/*
-+ *   fs/cifs/cifspdu.h
-+ *
-+ *   Copyright (c) International Business Machines  Corp., 2002
-+ *   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>
-+
-+#define CIFS_PROT   0
-+#define BAD_PROT    CIFS_PROT+1
-+
-+/* SMB command codes */
-+#define SMB_COM_CREATE_DIRECTORY      0x00
-+#define SMB_COM_DELETE_DIRECTORY      0x01
-+#define SMB_COM_CLOSE                 0x04
-+#define SMB_COM_DELETE                0x06
-+#define SMB_COM_RENAME                0x07
-+#define SMB_COM_LOCKING_ANDX          0x24
-+#define SMB_COM_COPY                  0x29
-+#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
-+#define SMB_COM_TREE_DISCONNECT       0x71
-+#define SMB_COM_NEGOTIATE             0x72
-+#define SMB_COM_SESSION_SETUP_ANDX    0x73
-+#define SMB_COM_LOGOFF_ANDX           0x74
-+#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_RENAME             0xA5
-+
-+/* 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_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
-+
-+/* 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_HDR_SIZE 256 /* chained NTCreateXReadX will probably be biggest */
-+
-+/* 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 session key (crypto key encrypted with the password
-+ */
-+#define CIFS_SESSION_KEY_SIZE (24)
-+
-+/*
-+ * 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 primitives */
-+#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 requested) */
-+#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 0x0001       /* can send long (non-8.3) path names in response */
-+#define SMBFLG2_KNOWS_EAS 0x0002
-+#define SMBFLG2_SECURITY_SIGNATURE 0x0004
-+#define SMBFLG2_IS_LONG_NAME 0x0040
-+#define SMBFLG2_EXT_SEC 0x0800
-+#define SMBFLG2_DFS 0x1000
-+#define SMBFLG2_PAGING_IO 0x2000
-+#define SMBFLG2_ERR_STATUS 0x4000
-+#define SMBFLG2_UNICODE 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.           */
-+
-+/*
-+ * Invalid readdir handle
-+ */
-+#define CIFS_NO_HANDLE        0xFFFF
-+
-+/* 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 - 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 */
-+#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_NOT_DIR                0x00000040      /* if set must not be directory */
-+#define CREATE_RANDOM_ACCESS  0x00000800
-+#define CREATE_DELETE_ON_CLOSE        0x00001000
-+#define OPEN_REPARSE_POINT    0x00200000
-+
-+/* 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 */
-+
-+#pragma pack(1)
-+
-+struct smb_hdr {
-+      __u32 smb_buf_length;   /* big endian on wire *//* BB length is only two or three bytes - with one or two byte type preceding it but that is always zero - we could mask the type byte off just in case BB */
-+      __u8 Protocol[4];
-+      __u8 Command;
-+      union {
-+              struct {
-+                      __u8 ErrorClass;
-+                      __u8 Reserved;
-+                      __u16 Error;    /* note: treated as little endian (le) on wire */
-+              } DosError;
-+              __u32 CifsError;        /* note: le */
-+      } Status;
-+      __u8 Flags;
-+      __u16 Flags2;           /* note: le */
-+      __u16 PidHigh;          /* note: le */
-+      union {
-+              struct {
-+                      __u32 SequenceNumber;  /* le */
-+                      __u32 Reserved; /* zero */
-+              } Sequence;
-+              __u8 SecuritySignature[8];      /* le */
-+      } Signature;
-+      __u8 pad[2];
-+      __u16 Tid;
-+      __u16 Pid;              /* note: le */
-+      __u16 Uid;
-+      __u16 Mid;
-+      __u8 WordCount;
-+};
-+/* given a pointer to an smb_hdr retrieve the value of byte count */
-+#define BCC(smb_var) ( *(__u16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) ) )
-+
-+/* given a pointer to an smb_hdr retrieve the pointer to the byte area */
-+#define pByteArea(smb_var) ((char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) + 2 )
-+
-+/*
-+ * Computer Name Length
-+ */
-+#define CNLEN 15
-+
-+/*
-+ * Share Name Length                                    @S8A
-+ * Note:  This length is limited by the SMB used to get   @S8A
-+ *        the Share info.   NetShareEnum only returns 13  @S8A
-+ *        chars, including the null termination.          @S8A 
-+ */
-+#define SNLEN 12              /*@S8A */
-+
-+/*
-+ * 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 */
-+      __u16 ByteCount;
-+      unsigned char DialectsArray[1];
-+} NEGOTIATE_REQ;
-+
-+typedef struct negotiate_rsp {
-+      struct smb_hdr hdr;     /* wct = 17 */
-+      __u16 DialectIndex;
-+      __u8 SecurityMode;
-+      __u16 MaxMpxCount;
-+      __u16 MaxNumberVcs;
-+      __u32 MaxBufferSize;
-+      __u32 MaxRawSize;
-+      __u32 SessionKey;
-+      __u32 Capabilities;     /* see below */
-+      __u32 SystemTimeLow;
-+      __u32 SystemTimeHigh;
-+      __u16 ServerTimeZone;
-+      __u8 EncryptionKeyLength;
-+      __u16 ByteCount;
-+      union {
-+              unsigned char EncryptionKey[1]; /* if cap extended security is off */
-+              /* followed by Domain name - if extended security is off */
-+              /* followed by 16 bytes of server GUID */
-+              /* followed by security blob if cap_extended_security negotiated */
-+              struct {
-+                      unsigned char GUID[16];
-+                      unsigned char SecurityBlob[1];
-+              } extended_response;
-+      } u;
-+} 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_UNIX               0x00800000
-+#define CAP_RESERVED           0x02000000
-+#define CAP_BULK_TRANSFER      0x20000000
-+#define CAP_COMPRESSED_DATA    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;
-+              __u16 AndXOffset;
-+              __u16 MaxBufferSize;
-+              __u16 MaxMpxCount;
-+              __u16 VcNumber;
-+              __u32 SessionKey;
-+              __u16 SecurityBlobLength;
-+              __u32 Reserved;
-+              __u32 Capabilities;     /* see below */
-+              __u16 ByteCount;
-+              unsigned char SecurityBlob[1];  /* followed by */
-+              /* STRING NativeOS */
-+              /* STRING NativeLanMan */
-+      } req;                  /* NTLM request format (with extended security */
-+
-+      struct {                /* request format */
-+              struct smb_hdr hdr;     /* wct = 13 */
-+              __u8 AndXCommand;
-+              __u8 AndXReserved;
-+              __u16 AndXOffset;
-+              __u16 MaxBufferSize;
-+              __u16 MaxMpxCount;
-+              __u16 VcNumber;
-+              __u32 SessionKey;
-+              __u16 CaseInsensitivePasswordLength;    /* ASCII password length */
-+              __u16 CaseSensitivePasswordLength;      /* Unicode password length */
-+              __u32 Reserved; /* see below */
-+              __u32 Capabilities;
-+              __u16 ByteCount;
-+              unsigned char CaseInsensitivePassword[1];       /* followed by: */
-+              /* unsigned char * CaseSensitivePassword; */
-+              /* STRING AccountName */
-+              /* STRING PrimaryDomain */
-+              /* STRING NativeOS */
-+              /* STRING NativeLanMan */
-+      } req_no_secext;        /* NTLM request format (without extended security */
-+
-+      struct {                /* default (NTLM) response format */
-+              struct smb_hdr hdr;     /* wct = 4 */
-+              __u8 AndXCommand;
-+              __u8 AndXReserved;
-+              __u16 AndXOffset;
-+              __u16 Action;   /* see below */
-+              __u16 SecurityBlobLength;
-+              __u16 ByteCount;
-+              unsigned char SecurityBlob[1];  /* followed by */
-+/*      unsigned char  * NativeOS;      */
-+/*    unsigned char  * NativeLanMan;  */
-+/*      unsigned char  * PrimaryDomain; */
-+      } resp;                 /* NTLM response format (with or without extended security */
-+
-+      struct {                /* request format */
-+              struct smb_hdr hdr;     /* wct = 10 */
-+              __u8 AndXCommand;
-+              __u8 AndXReserved;
-+              __u16 AndXOffset;
-+              __u16 MaxBufferSize;
-+              __u16 MaxMpxCount;
-+              __u16 VcNumber;
-+              __u32 SessionKey;
-+              __u16 PassswordLength;
-+              __u32 Reserved;
-+              __u16 ByteCount;
-+              unsigned char AccountPassword[1];       /* followed by */
-+              /* STRING AccountName */
-+              /* STRING PrimaryDomain */
-+              /* STRING NativeOS */
-+              /* STRING NativeLanMan */
-+      } old_req;              /* pre-NTLM (LANMAN2.1) request format */
-+
-+      struct {                /* default (NTLM) response format */
-+              struct smb_hdr hdr;     /* wct = 3 */
-+              __u8 AndXCommand;
-+              __u8 AndXReserved;
-+              __u16 AndXOffset;
-+              __u16 Action;   /* see below */
-+              __u16 ByteCount;
-+              unsigned char NativeOS[1];      /* followed by */
-+/*    unsigned char * NativeLanMan; */
-+/*      unsigned char * PrimaryDomain; */
-+      } old_resp;             /* pre-NTLM (LANMAN2.1) response format */
-+} SESSION_SETUP_ANDX;
-+
-+#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 (presumably 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;
-+      __u16 AndXOffset;
-+      __u16 Flags;            /* see below */
-+      __u16 PasswordLength;
-+      __u16 ByteCount;
-+      unsigned char Password[1];      /* followed by */
-+/* STRING Path    *//* \\server\share name */
-+      /* STRING Service */
-+} TCONX_REQ;
-+
-+typedef struct smb_com_tconx_rsp {
-+      struct smb_hdr hdr;     /* wct = 3 *//* note that Win2000 has sent wct=7 in some cases on responses. Four unspecified words followed OptionalSupport */
-+      __u8 AndXCommand;
-+      __u8 AndXReserved;
-+      __u16 AndXOffset;
-+      __u16 OptionalSupport;  /* see below */
-+      __u16 ByteCount;
-+      unsigned char Service[1];       /* always ASCII, not Unicode */
-+      /* STRING NativeFileSystem */
-+} TCONX_RSP;
-+
-+/* tree connect Flags */
-+#define DISCONNECT_TID          0x0001
-+#define TCON_EXTENDED_SECINFO   0x0008
-+/* OptionalSupport bits */
-+#define SMB_SUPPORT_SEARCH_BITS 0x0001        /* must have bits (exclusive searches suppt. */
-+#define SMB_SHARE_IS_IN_DFS     0x0002
-+
-+typedef struct smb_com_logoff_andx_req {
-+
-+      struct smb_hdr hdr;     /* wct = 2 */
-+      __u8 AndXCommand;
-+      __u8 AndXReserved;
-+      __u16 AndXOffset;
-+      __u16 ByteCount;
-+} LOGOFF_ANDX_REQ;
-+
-+typedef struct smb_com_logoff_andx_rsp {
-+      struct smb_hdr hdr;     /* wct = 2 */
-+      __u8 AndXCommand;
-+      __u8 AndXReserved;
-+      __u16 AndXOffset;
-+      __u16 ByteCount;
-+} LOGOFF_ANDX_RSP;
-+
-+typedef union smb_com_tree_disconnect {       /* as an altetnative can use flag on tree_connect PDU to effect disconnect *//* probably the simplest SMB PDU */
-+      struct {
-+              struct smb_hdr hdr;     /* wct = 0 */
-+              __u16 ByteCount;        /* bcc = 0 */
-+      } req;
-+      struct {
-+              struct smb_hdr hdr;     /* wct = 0 */
-+              __u16 ByteCount;        /* bcc = 0 */
-+      } resp;
-+} TREE_DISCONNECT;
-+
-+typedef struct smb_com_close_req {
-+      struct smb_hdr hdr;     /* wct = 3 */
-+      __u16 FileID;
-+      __u32 LastWriteTime;    /* should be zero */
-+      __u16 ByteCount;        /* 0 */
-+} CLOSE_REQ;
-+
-+typedef struct smb_com_close_rsp {
-+      struct smb_hdr hdr;     /* wct = 0 */
-+      __u16 ByteCount;        /* bct = 0 */
-+} CLOSE_RSP;
-+
-+typedef struct smb_com_findclose_req {
-+      struct smb_hdr hdr; /* wct = 1 */
-+      __u16 FileID;
-+      __u16 ByteCount;    /* 0 */
-+} FINDCLOSE_REQ;
-+
-+/* OpenFlags */
-+#define REQ_OPLOCK         0x00000002
-+#define REQ_BATCHOPLOCK    0x00000004
-+#define REQ_OPENDIRONLY    0x00000008
-+
-+typedef struct smb_com_open_req {     /* also handles create */
-+      struct smb_hdr hdr;     /* wct = 24 */
-+      __u8 AndXCommand;
-+      __u8 AndXReserved;
-+      __u16 AndXOffset;
-+      __u8 Reserved;          /* Must Be Zero */
-+      __u16 NameLength;
-+      __u32 OpenFlags;
-+      __u32 RootDirectoryFid;
-+      __u32 DesiredAccess;
-+      __u64 AllocationSize;
-+      __u32 FileAttributes;
-+      __u32 ShareAccess;
-+      __u32 CreateDisposition;
-+      __u32 CreateOptions;
-+      __u32 ImpersonationLevel;
-+      __u8 SecurityFlags;
-+      __u16 ByteCount;
-+      char fileName[1];
-+} 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;
-+      __u16 AndXOffset;
-+      __u8 OplockLevel;
-+      __u16 Fid;
-+      __u32 CreateAction;
-+      __u64 CreationTime;
-+      __u64 LastAccessTime;
-+      __u64 LastWriteTime;
-+      __u64 ChangeTime;
-+      __u32 FileAttributes;
-+      __u64 AllocationSize;
-+      __u64 EndOfFile;
-+      __u16 FileType;
-+      __u16 DeviceState;
-+      __u8 DirectoryFlag;
-+      __u16 ByteCount;        /* bct = 0 */
-+} OPEN_RSP;
-+
-+typedef struct smb_com_write_req {
-+      struct smb_hdr hdr;     /* wct = 14 */
-+      __u8 AndXCommand;
-+      __u8 AndXReserved;
-+      __u16 AndXOffset;
-+      __u16 Fid;
-+      __u32 OffsetLow;
-+      __u32 Reserved;
-+      __u16 WriteMode;
-+      __u16 Remaining;
-+      __u16 DataLengthHigh;
-+      __u16 DataLengthLow;
-+      __u16 DataOffset;
-+      __u32 OffsetHigh;
-+      __u16 ByteCount;
-+      __u8 Pad;               /* BB check for whether padded to DWORD boundary and optimum performance here */
-+      char Data[1];
-+} WRITE_REQ;
-+
-+typedef struct smb_com_write_rsp {
-+      struct smb_hdr hdr;     /* wct = 6 */
-+      __u8 AndXCommand;
-+      __u8 AndXReserved;
-+      __u16 AndXOffset;
-+      __u16 Count;
-+      __u16 Remaining;
-+      __u32 Reserved;
-+      __u16 ByteCount;
-+} WRITE_RSP;
-+
-+typedef struct smb_com_read_req {
-+      struct smb_hdr hdr;     /* wct = 12 */
-+      __u8 AndXCommand;
-+      __u8 AndXReserved;
-+      __u16 AndXOffset;
-+      __u16 Fid;
-+      __u32 OffsetLow;
-+      __u16 MaxCount;
-+      __u16 MinCount;         /* obsolete */
-+      __u32 MaxCountHigh;
-+      __u16 Remaining;
-+      __u32 OffsetHigh;
-+      __u16 ByteCount;
-+} READ_REQ;
-+
-+typedef struct smb_com_read_rsp {
-+      struct smb_hdr hdr;     /* wct = 12 */
-+      __u8 AndXCommand;
-+      __u8 AndXReserved;
-+      __u16 AndXOffset;
-+      __u16 Remaining;
-+      __u16 DataCompactionMode;
-+      __u16 Reserved;
-+      __u16 DataLength;
-+      __u16 DataOffset;
-+      __u16 DataLengthHigh;
-+      __u64 Reserved2;
-+      __u16 ByteCount;
-+      __u8 Pad;               /* BB check for whether padded to DWORD boundary and optimum performance here */
-+      char Data[1];
-+} READ_RSP;
-+
-+typedef struct locking_andx_range {
-+      __u16 Pid;
-+      __u16 Pad;
-+      __u32 OffsetHigh;
-+      __u32 OffsetLow;
-+      __u32 LengthHigh;
-+      __u32 LengthLow;
-+} 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;
-+      __u16 AndXOffset;
-+      __u16 Fid;
-+      __u8 LockType;
-+      __u8 OplockLevel;
-+      __u32 Timeout;
-+      __u16 NumberOfUnlocks;
-+      __u16 NumberOfLocks;
-+      __u16 ByteCount;
-+      LOCKING_ANDX_RANGE Locks[1];
-+} LOCK_REQ;
-+
-+typedef struct smb_com_lock_rsp {
-+      struct smb_hdr hdr;     /* wct = 2 */
-+      __u8 AndXCommand;
-+      __u8 AndXReserved;
-+      __u16 AndXOffset;
-+      __u16 ByteCount;
-+} LOCK_RSP;
-+
-+typedef struct smb_com_rename_req {
-+      struct smb_hdr hdr;     /* wct = 1 */
-+      __u16 SearchAttributes; /* target file attributes */
-+      __u16 ByteCount;
-+      __u8 BufferFormat;      /* 4 = ASCII or Unicode */
-+      unsigned char OldFileName[1];
-+      /* followed by __u8 BufferFormat2 */
-+      /* followed by NewFileName */
-+} 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;
-+      __u16 OpenFunction;
-+      __u16 Flags;
-+      __u16 ByteCount;
-+      __u8 BufferFormat;      /* 4 = ASCII or Unicode */ 
-+      unsigned char OldFileName[1];
-+      /* followed by __u8 BufferFormat2 */
-+      /* followed by NewFileName string */
-+} COPY_REQ;
-+
-+typedef struct smb_com_copy_rsp {
-+      struct smb_hdr hdr;     /* wct = 1 */
-+      __u16 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 */
-+} 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 */
-+      __u16 SearchAttributes; /* target file attributes */
-+      __u16 Flags;            /* spec says Information Level */
-+      __u32 ClusterCount;
-+      __u16 ByteCount;
-+      __u8 BufferFormat;      /* 4 = ASCII or Unicode */
-+      unsigned char OldFileName[1];
-+      /* followed by __u8 BufferFormat2 */
-+      /* followed by NewFileName */
-+} NT_RENAME_REQ;
-+
-+typedef struct smb_com_rename_rsp {
-+      struct smb_hdr hdr;     /* wct = 0 */
-+      __u16 ByteCount;        /* bct = 0 */
-+} RENAME_RSP;
-+
-+typedef struct smb_com_delete_file_req {
-+      struct smb_hdr hdr;     /* wct = 1 */
-+      __u16 SearchAttributes;
-+      __u16 ByteCount;
-+      __u8 BufferFormat;      /* 4 = ASCII */
-+      unsigned char fileName[1];
-+} DELETE_FILE_REQ;
-+
-+typedef struct smb_com_delete_file_rsp {
-+      struct smb_hdr hdr;     /* wct = 0 */
-+      __u16 ByteCount;        /* bct = 0 */
-+} DELETE_FILE_RSP;
-+
-+typedef struct smb_com_delete_directory_req {
-+      struct smb_hdr hdr;     /* wct = 0 */
-+      __u16 ByteCount;
-+      __u8 BufferFormat;      /* 4 = ASCII */
-+      unsigned char DirName[1];
-+} DELETE_DIRECTORY_REQ;
-+
-+typedef struct smb_com_delete_directory_rsp {
-+      struct smb_hdr hdr;     /* wct = 0 */
-+      __u16 ByteCount;        /* bct = 0 */
-+} DELETE_DIRECTORY_RSP;
-+
-+typedef struct smb_com_create_directory_req {
-+      struct smb_hdr hdr;     /* wct = 0 */
-+      __u16 ByteCount;
-+      __u8 BufferFormat;      /* 4 = ASCII */
-+      unsigned char DirName[1];
-+} CREATE_DIRECTORY_REQ;
-+
-+typedef struct smb_com_create_directory_rsp {
-+      struct smb_hdr hdr;     /* wct = 0 */
-+      __u16 ByteCount;        /* bct = 0 */
-+} CREATE_DIRECTORY_RSP;
-+
-+/***************************************************/
-+/* NT Transact structure defintions follow         */
-+/* Currently only ioctl and notify are implemented */
-+/***************************************************/
-+typedef struct smb_com_transaction_ioctl_req {
-+      struct smb_hdr hdr;     /* wct = 23 */
-+      __u8 MaxSetupCount;
-+      __u16 Reserved;
-+      __u32 TotalParameterCount;
-+      __u32 TotalDataCount;
-+      __u32 MaxParameterCount;
-+      __u32 MaxDataCount;
-+      __u32 ParameterCount;
-+      __u32 ParameterOffset;
-+      __u32 DataCount;
-+      __u32 DataOffset;
-+      __u8 SetupCount; /* four setup words follow subcommand */
-+      /* SNIA spec incorrectly included spurious pad here */
-+      __u16 SubCommand;/* 2 = IOCTL/FSCTL */
-+      __u32 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 share)*/
-+      __u16 ByteCount;
-+      __u8 Pad[3];
-+      __u8 Data[1];
-+} TRANSACT_IOCTL_REQ;
-+
-+typedef struct smb_com_transaction_ioctl_rsp {
-+      struct smb_hdr hdr;     /* wct = 19 */
-+      __u8 Reserved[3];
-+      __u32 TotalParameterCount;
-+      __u32 TotalDataCount;
-+      __u32 ParameterCount;
-+      __u32 ParameterOffset;
-+      __u32 ParameterDisplacement;
-+      __u32 DataCount;
-+      __u32 DataOffset;
-+      __u32 DataDisplacement;
-+      __u8 SetupCount;        /* 1 */
-+      __u16 ReturnedDataLen;
-+      __u16 ByteCount;
-+      __u8 Pad[3];
-+} TRANSACT_IOCTL_RSP;
-+
-+typedef struct smb_com_transaction_change_notify_req {
-+      struct smb_hdr hdr;     /* wct = 23 */
-+      __u8 MaxSetupCount;
-+      __u16 Reserved;
-+      __u32 TotalParameterCount;
-+      __u32 TotalDataCount;
-+      __u32 MaxParameterCount;
-+      __u32 MaxDataCount;
-+      __u32 ParameterCount;
-+      __u32 ParameterOffset;
-+      __u32 DataCount;
-+      __u32 DataOffset;
-+      __u8 SetupCount; /* four setup words follow subcommand */
-+      /* SNIA spec incorrectly included spurious pad here */
-+      __u16 SubCommand;/* 4 = Change Notify */
-+      __u32 CompletionFilter;  /* operation to monitor */
-+      __u16 Fid;
-+      __u8 WatchTree;  /* 1 = Monitor subdirectories */
-+      __u8 Reserved2;
-+      __u16 ByteCount;
-+/* __u8 Pad[3];*/
-+/*    __u8 Data[1];*/
-+} TRANSACT_CHANGE_NOTIFY_REQ;
-+
-+typedef struct smb_com_transaction_change_notify_rsp {
-+      struct smb_hdr hdr;     /* wct = 18 */
-+      __u8 Reserved[3];
-+      __u32 TotalParameterCount;
-+      __u32 TotalDataCount;
-+      __u32 ParameterCount;
-+      __u32 ParameterOffset;
-+      __u32 ParameterDisplacement;
-+      __u32 DataCount;
-+      __u32 DataOffset;
-+      __u32 DataDisplacement;
-+      __u8 SetupCount;   /* 0 */
-+      __u16 ByteCount;
-+      /* __u8 Pad[3]; */
-+} 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 {
-+      __u32 NextEntryOffset;
-+      __u32 Action;
-+      __u32 FileNameLength;
-+      __u8  FileName[1];
-+}; 
-+
-+struct reparse_data {
-+      __u32   ReparseTag;
-+      __u16   ReparseDataLength;
-+      __u16   Reserved;
-+      __u16   AltNameOffset;
-+      __u16   AltNameLen;
-+      __u16   TargetNameOffset;
-+      __u16   TargetNameLen;
-+      char    LinkNamesBuf[1];
-+};
-+
-+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? */
-+};
-+
-+/* quota sub commands */
-+#define QUOTA_LIST_CONTINUE       0
-+#define QUOTA_LIST_START      0x100
-+#define QUOTA_FOR_SID         0x101
-+
-+typedef union smb_com_transaction2 {
-+      struct {
-+              struct smb_hdr hdr;     /* wct = 14+ */
-+              __u16 TotalParameterCount;
-+              __u16 TotalDataCount;
-+              __u16 MaxParameterCount;
-+              __u16 MaxDataCount;
-+              __u8 MaxSetupCount;
-+              __u8 Reserved;
-+              __u16 Flags;
-+              __u32 Timeout;
-+              __u16 Reserved2;
-+              __u16 ParameterCount;
-+              __u16 ParameterOffset;
-+              __u16 DataCount;
-+              __u16 DataOffset;
-+              __u8 SetupCount;
-+              __u8 Reserved3;
-+              __u16 SubCommand;       /* 1st setup word - can be followed by SetupCount words */
-+              __u16 ByteCount;        /* careful - setupcount is not always one */
-+      } req;
-+      struct {
-+              struct smb_hdr hdr;     /* wct = 0 */
-+              __u16 TotalParameterCount;
-+              __u16 TotalDataCount;
-+              __u16 Reserved;
-+              __u16 ParameterCount;
-+              __u16 ParamterOffset;
-+              __u16 ParameterDisplacement;
-+              __u16 DataCount;
-+              __u16 DataOffset;
-+              __u16 DataDisplacement;
-+              __u8 SetupCount;
-+              __u8 Reserved1; /* should be zero setup words following */
-+              __u16 ByteCount;
-+              __u16 Reserved2;        /* parameter word reserved - present for infolevels > 100 */
-+              /* data area follows */
-+      } resp;
-+} TRANSACTION2;
-+
-+/* PathInfo/FileInfo infolevels */
-+#define SMB_INFO_STANDARD                   1
-+#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_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_FILE_BASIC_INFO2        0x3ec
-+#define SMB_SET_FILE_RENAME_INFORMATION 0x3f2
-+#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_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_UNIX                0x202
-+
-+typedef struct smb_com_transaction2_qpi_req {
-+      struct smb_hdr hdr;     /* wct = 14+ */
-+      __u16 TotalParameterCount;
-+      __u16 TotalDataCount;
-+      __u16 MaxParameterCount;
-+      __u16 MaxDataCount;
-+      __u8 MaxSetupCount;
-+      __u8 Reserved;
-+      __u16 Flags;
-+      __u32 Timeout;
-+      __u16 Reserved2;
-+      __u16 ParameterCount;
-+      __u16 ParameterOffset;
-+      __u16 DataCount;
-+      __u16 DataOffset;
-+      __u8 SetupCount;
-+      __u8 Reserved3;
-+      __u16 SubCommand;       /* one setup word */
-+      __u16 ByteCount;
-+      __u8 Pad;
-+      __u16 InformationLevel;
-+      __u32 Reserved4;
-+      char FileName[1];
-+} TRANSACTION2_QPI_REQ;
-+
-+typedef struct smb_com_transaction2_qpi_rsp {
-+      struct smb_hdr hdr;     /* wct = 10 + SetupCount */
-+      __u16 TotalParameterCount;
-+      __u16 TotalDataCount;
-+      __u16 Reserved;
-+      __u16 ParameterCount;
-+      __u16 ParameterOffset;
-+      __u16 ParameterDisplacement;
-+      __u16 DataCount;
-+      __u16 DataOffset;
-+      __u16 DataDisplacement;
-+      __u8 SetupCount;
-+      __u8 Reserved1;         /* should be zero setup words following */
-+      __u16 ByteCount;
-+      __u16 Reserved2;        /* parameter word reserved - present for infolevels > 100 */
-+} TRANSACTION2_QPI_RSP;
-+
-+typedef struct smb_com_transaction2_spi_req {
-+      struct smb_hdr hdr;     /* wct = 15 */
-+      __u16 TotalParameterCount;
-+      __u16 TotalDataCount;
-+      __u16 MaxParameterCount;
-+      __u16 MaxDataCount;
-+      __u8 MaxSetupCount;
-+      __u8 Reserved;
-+      __u16 Flags;
-+      __u32 Timeout;
-+      __u16 Reserved2;
-+      __u16 ParameterCount;
-+      __u16 ParameterOffset;
-+      __u16 DataCount;
-+      __u16 DataOffset;
-+      __u8 SetupCount;
-+      __u8 Reserved3;
-+      __u16 SubCommand;       /* one setup word */
-+      __u16 ByteCount;
-+      __u8 Pad;
-+      __u16 Pad1;
-+      __u16 InformationLevel;
-+      __u32 Reserved4;
-+      char FileName[1];
-+} TRANSACTION2_SPI_REQ;
-+
-+typedef struct smb_com_transaction2_spi_rsp {
-+      struct smb_hdr hdr;     /* wct = 10 + SetupCount */
-+      __u16 TotalParameterCount;
-+      __u16 TotalDataCount;
-+      __u16 Reserved;
-+      __u16 ParameterCount;
-+      __u16 ParameterOffset;
-+      __u16 ParameterDisplacement;
-+      __u16 DataCount;
-+      __u16 DataOffset;
-+      __u16 DataDisplacement;
-+      __u8 SetupCount;
-+      __u8 Reserved1;         /* should be zero setup words following */
-+      __u16 ByteCount;
-+      __u16 Reserved2;        /* parameter word reserved - present for infolevels > 100 */
-+} TRANSACTION2_SPI_RSP;
-+
-+struct set_file_rename {
-+      __u32 overwrite;   /* 1 = overwrite dest */
-+      __u32 root_fid;   /* zero */
-+      __u32 target_name_len;
-+      char  target_name[0];  /* Must be unicode */
-+};
-+
-+struct smb_com_transaction2_sfi_req {
-+      struct smb_hdr hdr;     /* wct = 15 */
-+      __u16 TotalParameterCount;
-+      __u16 TotalDataCount;
-+      __u16 MaxParameterCount;
-+      __u16 MaxDataCount;
-+      __u8 MaxSetupCount;
-+      __u8 Reserved;
-+      __u16 Flags;
-+      __u32 Timeout;
-+      __u16 Reserved2;
-+      __u16 ParameterCount;
-+      __u16 ParameterOffset;
-+      __u16 DataCount;
-+      __u16 DataOffset;
-+      __u8 SetupCount;
-+      __u8 Reserved3;
-+      __u16 SubCommand;       /* one setup word */
-+      __u16 ByteCount;
-+      __u8 Pad;
-+      __u16 Pad1;
-+      __u16 Fid;
-+      __u16 InformationLevel;
-+      __u16 Reserved4;        
-+};
-+
-+struct smb_com_transaction2_sfi_rsp {
-+      struct smb_hdr hdr;     /* wct = 10 + SetupCount */
-+      __u16 TotalParameterCount;
-+      __u16 TotalDataCount;
-+      __u16 Reserved;
-+      __u16 ParameterCount;
-+      __u16 ParameterOffset;
-+      __u16 ParameterDisplacement;
-+      __u16 DataCount;
-+      __u16 DataOffset;
-+      __u16 DataDisplacement;
-+      __u8 SetupCount;
-+      __u8 Reserved1;         /* should be zero setup words following */
-+      __u16 ByteCount;
-+      __u16 Reserved2;        /* parameter word reserved - present for infolevels > 100 */
-+};
-+
-+
-+/*
-+ * 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 */
-+      __u16 TotalParameterCount;
-+      __u16 TotalDataCount;
-+      __u16 MaxParameterCount;
-+      __u16 MaxDataCount;
-+      __u8 MaxSetupCount;
-+      __u8 Reserved;
-+      __u16 Flags;
-+      __u32 Timeout;
-+      __u16 Reserved2;
-+      __u16 ParameterCount;
-+      __u16 ParameterOffset;
-+      __u16 DataCount;
-+      __u16 DataOffset;
-+      __u8 SetupCount;        /* one */
-+      __u8 Reserved3;
-+      __u16 SubCommand;       /* TRANS2_FIND_FIRST */
-+      __u16 ByteCount;
-+      __u8 Pad;
-+      __u16 SearchAttributes;
-+      __u16 SearchCount;
-+      __u16 SearchFlags;
-+      __u16 InformationLevel;
-+      __u32 SearchStorageType;
-+      char FileName[1];
-+} TRANSACTION2_FFIRST_REQ;
-+
-+typedef struct smb_com_transaction2_ffirst_rsp {
-+      struct smb_hdr hdr;     /* wct = 10 */
-+      __u16 TotalParameterCount;
-+      __u16 TotalDataCount;
-+      __u16 Reserved;
-+      __u16 ParameterCount;
-+      __u16 ParameterOffset;
-+      __u16 ParameterDisplacement;
-+      __u16 DataCount;
-+      __u16 DataOffset;
-+      __u16 DataDisplacement;
-+      __u8 SetupCount;
-+      __u8 Reserved1;         /* should be zero setup words following */
-+      __u16 ByteCount;
-+} TRANSACTION2_FFIRST_RSP;
-+
-+typedef struct smb_com_transaction2_ffirst_rsp_parms {
-+      __u16 SearchHandle;
-+      __u16 SearchCount;
-+      __u16 EndofSearch;
-+      __u16 EAErrorOffset;
-+      __u16 LastNameOffset;
-+} T2_FFIRST_RSP_PARMS;
-+
-+typedef struct smb_com_transaction2_fnext_req {
-+      struct smb_hdr hdr;     /* wct = 15 */
-+      __u16 TotalParameterCount;
-+      __u16 TotalDataCount;
-+      __u16 MaxParameterCount;
-+      __u16 MaxDataCount;
-+      __u8 MaxSetupCount;
-+      __u8 Reserved;
-+      __u16 Flags;
-+      __u32 Timeout;
-+      __u16 Reserved2;
-+      __u16 ParameterCount;
-+      __u16 ParameterOffset;
-+      __u16 DataCount;
-+      __u16 DataOffset;
-+      __u8 SetupCount;        /* one */
-+      __u8 Reserved3;
-+      __u16 SubCommand;       /* TRANS2_FIND_NEXT */
-+      __u16 ByteCount;
-+      __u8 Pad;
-+      __u16 SearchHandle;
-+      __u16 SearchCount;
-+      __u16 InformationLevel;
-+      __u32 ResumeKey;
-+      __u16 SearchFlags;
-+      char ResumeFileName[1];
-+} TRANSACTION2_FNEXT_REQ;
-+
-+typedef struct smb_com_transaction2_fnext_rsp {
-+      struct smb_hdr hdr;     /* wct = 10 */
-+      __u16 TotalParameterCount;
-+      __u16 TotalDataCount;
-+      __u16 Reserved;
-+      __u16 ParameterCount;
-+      __u16 ParameterOffset;
-+      __u16 ParameterDisplacement;
-+      __u16 DataCount;
-+      __u16 DataOffset;
-+      __u16 DataDisplacement;
-+      __u8 SetupCount;
-+      __u8 Reserved1;         /* should be zero setup words following */
-+      __u16 ByteCount;
-+} TRANSACTION2_FNEXT_RSP;
-+
-+typedef struct smb_com_transaction2_fnext_rsp_parms {
-+      __u16 SearchCount;
-+      __u16 EndofSearch;
-+      __u16 EAErrorOffset;
-+      __u16 LastNameOffset;
-+} 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_LABEL_INFO        0x3ea
-+#define SMB_QUERY_FS_QUOTA_INFO     0x3ee
-+
-+typedef struct smb_com_transaction2_qfsi_req {
-+      struct smb_hdr hdr;     /* wct = 14+ */
-+      __u16 TotalParameterCount;
-+      __u16 TotalDataCount;
-+      __u16 MaxParameterCount;
-+      __u16 MaxDataCount;
-+      __u8 MaxSetupCount;
-+      __u8 Reserved;
-+      __u16 Flags;
-+      __u32 Timeout;
-+      __u16 Reserved2;
-+      __u16 ParameterCount;
-+      __u16 ParameterOffset;
-+      __u16 DataCount;
-+      __u16 DataOffset;
-+      __u8 SetupCount;
-+      __u8 Reserved3;
-+      __u16 SubCommand;       /* one setup word */
-+      __u16 ByteCount;
-+      __u8 Pad;
-+      __u16 InformationLevel;
-+} TRANSACTION2_QFSI_REQ;
-+
-+typedef struct smb_com_transaction_qfsi_rsp {
-+      struct smb_hdr hdr;     /* wct = 10 + SetupCount */
-+      __u16 TotalParameterCount;
-+      __u16 TotalDataCount;
-+      __u16 Reserved;
-+      __u16 ParameterCount;
-+      __u16 ParameterOffset;
-+      __u16 ParameterDisplacement;
-+      __u16 DataCount;
-+      __u16 DataOffset;
-+      __u16 DataDisplacement;
-+      __u8 SetupCount;
-+      __u8 Reserved1;         /* should be zero setup words following */
-+      __u16 ByteCount;
-+      __u8 Pad;               /* may be three bytes *//* followed by data area */
-+} TRANSACTION2_QFSI_RSP;
-+
-+typedef struct smb_com_transaction2_get_dfs_refer_req {
-+      struct smb_hdr hdr;     /* wct = 15 */
-+      __u16 TotalParameterCount;
-+      __u16 TotalDataCount;
-+      __u16 MaxParameterCount;
-+      __u16 MaxDataCount;
-+      __u8 MaxSetupCount;
-+      __u8 Reserved;
-+      __u16 Flags;
-+      __u32 Timeout;
-+      __u16 Reserved2;
-+      __u16 ParameterCount;
-+      __u16 ParameterOffset;
-+      __u16 DataCount;
-+      __u16 DataOffset;
-+      __u8 SetupCount;
-+      __u8 Reserved3;
-+      __u16 SubCommand;       /* one setup word */
-+      __u16 ByteCount;
-+      __u8 Pad[3];            /* Win2K has sent 0x0F01 (max resp length perhaps?) followed by one byte pad - doesn't seem to matter though */
-+      __u16 MaxReferralLevel;
-+      char RequestFileName[1];
-+} TRANSACTION2_GET_DFS_REFER_REQ;
-+
-+typedef struct dfs_referral_level_3 {
-+      __u16 VersionNumber;
-+      __u16 ReferralSize;
-+      __u16 ServerType;       /* 0x0001 = CIFS server */
-+      __u16 ReferralFlags;    /* or proximity - not clear which since always set to zero - SNIA spec says 0x01 means strip off PathConsumed chars before submitting RequestFileName to remote node */
-+      __u16 TimeToLive;
-+      __u16 Proximity;
-+      __u16 DfsPathOffset;
-+      __u16 DfsAlternatePathOffset;
-+      __u16 NetworkAddressOffset;
-+} REFERRAL3;
-+
-+typedef struct smb_com_transaction_get_dfs_refer_rsp {
-+      struct smb_hdr hdr;     /* wct = 10 */
-+      __u16 TotalParameterCount;
-+      __u16 TotalDataCount;
-+      __u16 Reserved;
-+      __u16 ParameterCount;
-+      __u16 ParameterOffset;
-+      __u16 ParameterDisplacement;
-+      __u16 DataCount;
-+      __u16 DataOffset;
-+      __u16 DataDisplacement;
-+      __u8 SetupCount;
-+      __u8 Reserved1;         /* zero setup words following */
-+      __u16 ByteCount;
-+      __u8 Pad;
-+      __u16 PathConsumed;
-+      __u16 NumberOfReferrals;
-+      __u16 DFSFlags;
-+      __u16 Pad2;
-+      REFERRAL3 referrals[1]; /* array of level 3 dfs_referral structures */
-+      /* followed by the strings pointed to by the referral structures */
-+} TRANSACTION2_GET_DFS_REFER_RSP;
-+
-+/* DFS Flags */
-+#define DFSREF_REFERRAL_SERVER  0x0001
-+#define DFSREF_STORAGE_SERVER   0x0002
-+
-+/* IOCTL information */
-+/* List of ioctl function codes that look to be of interest to remote clients like this. */
-+/* Need to do some experimentation to make sure they all work remotely.                  */
-+/* Some of the following such as the encryption/compression ones would 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_GET_COMPRESSION        0x0009003C
-+#define FSCTL_SET_COMPRESSION        0x0009C040
-+#define FSCTL_REQUEST_FILTER_OPLOCK  0x0009008C
-+#define FSCTL_FILESYS_GET_STATISTICS 0x00090090
-+#define FSCTL_SET_REPARSE_POINT      0x000900A4
-+#define FSCTL_GET_REPARSE_POINT      0x000900A8
-+#define FSCTL_DELETE_REPARSE_POINT   0x000900AC
-+#define FSCTL_SET_SPARSE             0x000900C4
-+#define FSCTL_SET_ZERO_DATA          0x000900C8
-+#define FSCTL_SET_ENCRYPTION         0x000900D7
-+#define FSCTL_ENCRYPTION_FSCTL_IO    0x000900DB
-+#define FSCTL_WRITE_RAW_ENCRYPTED    0x000900DF
-+#define FSCTL_READ_RAW_ENCRYPTED     0x000900E3
-+#define FSCTL_SIS_COPYFILE           0x00090100
-+#define FSCTL_SIS_LINK_FILES         0x0009C104
-+
-+#define IO_REPARSE_TAG_MOUNT_POINT   0xA0000003
-+#define IO_REPARSE_TAG_HSM           0xC0000004
-+#define IO_REPARSE_TAG_SIS           0x80000007
-+
-+/*
-+ ************************************************************************
-+ * 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;
-+};
-+
-+/*
-+ * 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;
-+};
-+
-+struct aliasInfo {
-+      char aliasName[9];
-+      char pad;
-+      unsigned int commentOffset;
-+      unsigned char type[2];
-+};
-+
-+struct aliasInfo92 {
-+      int aliasNameOffset;
-+      int serverNameOffset;
-+      int shareNameOffset;
-+};
-+
-+typedef struct {
-+      __u64 TotalAllocationUnits;
-+      __u64 FreeAllocationUnits;
-+      __u32 SectorsPerAllocationUnit;
-+      __u32 BytesPerSector;
-+} FILE_SYSTEM_INFO;           /* size info, level 0x103 */
-+
-+typedef struct {
-+      __u16 MajorVersionNumber;
-+      __u16 MinorVersionNumber;
-+      __u64 Capability;
-+} FILE_SYSTEM_UNIX_INFO;      /* Unix extensions info, level 0x200 */
-+/* Linux/Unix extensions capability flags */
-+#define CIFS_UNIX_FCNTL_CAP             0x00000001 /* support for fcntl locks */
-+#define CIFS_UNIX_POSIX_ACL_CAP         0x00000002
-+
-+/* 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 {
-+      __u32 DeviceType;
-+      __u32 DeviceCharacteristics;
-+} FILE_SYSTEM_DEVICE_INFO;    /* device info, level 0x104 */
-+
-+typedef struct {
-+      __u32 Attributes;
-+      __u32 MaxPathNameComponentLength;
-+      __u32 FileSystemNameLen;
-+      char FileSystemName[52];        /* do not really need to save this - so potentially get only subset of name */
-+} FILE_SYSTEM_ATTRIBUTE_INFO;
-+
-+typedef struct {              /* data block encoding of response to level 263 QPathInfo */
-+      __u64 CreationTime;
-+      __u64 LastAccessTime;
-+      __u64 LastWriteTime;
-+      __u64 ChangeTime;
-+      __u32 Attributes;
-+      __u32 Pad1;
-+      __u64 AllocationSize;
-+      __u64 EndOfFile;        /* size ie offset to first free byte in file */
-+      __u32 NumberOfLinks;    /* hard links */
-+      __u8 DeletePending;
-+      __u8 Directory;
-+      __u16 Pad2;
-+      __u64 IndexNumber;
-+      __u32 EASize;
-+      __u32 AccessFlags;
-+      __u64 IndexNumber1;
-+      __u64 CurrentByteOffset;
-+      __u32 Mode;
-+      __u32 AlignmentRequirement;
-+      __u32 FileNameLength;
-+      char FileName[1];
-+} FILE_ALL_INFO;              /* level 263 QPathInfo */
-+
-+typedef struct {
-+      __u64 EndOfFile;
-+      __u64 NumOfBytes;
-+      __u64 LastStatusChange; /*SNIA spec says DCE time for the three time fields */
-+      __u64 LastAccessTime;
-+      __u64 LastModificationTime;
-+      __u64 Uid;
-+      __u64 Gid;
-+      __u32 Type;
-+      __u64 DevMajor;
-+      __u64 DevMinor;
-+      __u64 UniqueId;
-+      __u64 Permissions;
-+      __u64 Nlinks;
-+} FILE_UNIX_BASIC_INFO;               /* level 512 QPathInfo */
-+
-+typedef struct {
-+      char LinkDest[1];
-+} FILE_UNIX_LINK_INFO;                /* level 513 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 {
-+      __u32 NextEntryOffset;
-+      __u32 ResumeKey;
-+      __u64 EndOfFile;
-+      __u64 NumOfBytes;
-+      __u64 LastStatusChange; /*SNIA spec says DCE time for the three time fields */
-+      __u64 LastAccessTime;
-+      __u64 LastModificationTime;
-+      __u64 Uid;
-+      __u64 Gid;
-+      __u32 Type;
-+      __u64 DevMajor;
-+      __u64 DevMinor;
-+      __u64 UniqueId;
-+      __u64 Permissions;
-+      __u64 Nlinks;
-+      char FileName[1];
-+} FILE_UNIX_INFO;
-+
-+typedef struct {
-+      __u64 CreationTime;
-+      __u64 LastAccessTime;
-+      __u64 LastWriteTime;
-+      __u64 ChangeTime;
-+      __u32 Attributes;
-+      __u32 Pad;
-+} FILE_BASIC_INFO;            /* size info, level 0x101 */
-+
-+struct file_allocation_info {
-+      __u64 AllocationSize;
-+};            /* size info, level 0x103 */
-+
-+struct file_end_of_file_info {
-+      __u64 FileSize;         /* offset to end of file */
-+};    /* size info, level 0x104 */
-+
-+typedef struct {
-+      __u32 NextEntryOffset;
-+      __u32 FileIndex;
-+      __u64 CreationTime;
-+      __u64 LastAccessTime;
-+      __u64 LastWriteTime;
-+      __u64 ChangeTime;
-+      __u64 EndOfFile;
-+      __u64 AllocationSize;
-+      __u32 ExtFileAttributes;
-+      __u32 FileNameLength;
-+      char FileName[1];
-+} FILE_DIRECTORY_INFO;   /* level 257 FF response data area */
-+
-+struct gea {
-+      unsigned char cbName;
-+      char szName[1];
-+};
-+
-+struct gealist {
-+      unsigned long cbList;
-+      struct gea list[1];
-+};
-+
-+struct fea {
-+      unsigned char EA_flags;
-+      __u8 name_len;
-+      __u16 value_len;
-+      char szName[1];
-+      /* optionally followed by value */
-+};
-+/* flags for _FEA.fEA */
-+#define FEA_NEEDEA         0x80       /* need EA bit */
-+
-+struct fealist {
-+      __u32 list_len;
-+      struct fea list[1];
-+};
-+
-+/* used to hold an arbitrary blob of data */
-+struct data_blob {
-+      __u8 *data;
-+      size_t length;
-+      void (*free) (struct data_blob * data_blob);
-+};
-+
-+#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) PosixQFSInfo - to return statfs info
-+      4) FindFirst return unique inode number - what about resume key, two forms short (matches readdir) and full (enough info to cache inodes)
-+      5) Mkdir - set mode
-+      
-+      And under consideration: 
-+      6) FindClose2 (return nanosecond timestamp ??)
-+      7) Use nanosecond timestamps throughout all time fields if 
-+         corresponding attribute flag is set
-+      8) sendfile - handle based copy
-+      9) Direct i/o
-+      10) "POSIX ACL" support
-+      11) Misc fcntls?
-+      
-+      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 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
-+      
-+      
-+ */
-+#endif 
-+
-+#pragma pack()                        /* resume default structure packing */
-+
-+#endif                                /* _CIFSPDU_H */
---- /dev/null
-+++ b/fs/cifs/cifsproto.h
-@@ -0,0 +1,254 @@
-+/*
-+ *   fs/cifs/cifsproto.h
-+ *
-+ *   Copyright (c) International Business Machines  Corp., 2002
-+ *   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;
-+
-+/*
-+ *****************************************************************
-+ * All Prototypes
-+ *****************************************************************
-+ */
-+
-+extern struct smb_hdr *cifs_buf_get(void);
-+extern void cifs_buf_release(void *);
-+extern int smb_send(struct socket *, struct smb_hdr *,
-+                      unsigned int /* length */ , struct sockaddr *);
-+extern unsigned int _GetXid(void);
-+extern void _FreeXid(unsigned int);
-+#define GetXid() (int)_GetXid(); cFYI(1,("CIFS VFS: in %s as Xid: %d with uid: %d",__FUNCTION__, xid,current->fsuid));
-+#define FreeXid(curr_xid) {_FreeXid(curr_xid); cFYI(1,("CIFS VFS: leaving %s (xid = %d) rc = %d",__FUNCTION__,curr_xid,rc));}
-+extern char *build_path_from_dentry(struct dentry *);
-+extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
-+extern void renew_parental_timestamps(struct dentry *direntry);
-+extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *,
-+                      struct smb_hdr * /* input */ ,
-+                      struct smb_hdr * /* out */ ,
-+                      int * /* bytes returned */ , const int long_op);
-+extern int checkSMBhdr(struct smb_hdr *smb, __u16 mid);
-+extern int checkSMB(struct smb_hdr *smb, __u16 mid, int length);
-+extern int is_valid_oplock_break(struct smb_hdr *smb);
-+extern unsigned int smbCalcSize(struct smb_hdr *ptr);
-+extern int decode_negTokenInit(unsigned char *security_blob, int length,
-+                      enum securityEnum *secType);
-+extern int map_smb_to_linux_error(struct smb_hdr *smb);
-+extern void header_assemble(struct smb_hdr *, char /* command */ ,
-+                      const struct cifsTconInfo *, int
-+                      /* length of fixed section (word count) in two byte units  */
-+                      );
-+struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16, struct cifsTconInfo *);
-+void DeleteOplockQEntry(struct oplock_q_entry *);
-+extern time_t cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ );
-+extern u64 cifs_UnixTimeToNT(time_t);
-+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);
-+extern int cifs_get_inode_info_unix(struct inode **pinode,
-+                      const unsigned char *search_path,
-+                      struct super_block *sb,int xid);
-+
-+extern int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, 
-+                      struct nls_table * nls_info);
-+extern int CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses);
-+
-+extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
-+                      const char *tree, struct cifsTconInfo *tcon,
-+                      const struct nls_table *);
-+
-+extern int CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
-+                      const char *searchName,
-+                      FILE_DIRECTORY_INFO * findData,
-+                      T2_FFIRST_RSP_PARMS * findParms,
-+                      const struct nls_table *nls_codepage,
-+                      int *pUnicodeFlag,
-+                      int *pUnixFlag /* if Unix extensions used */ );
-+extern int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
-+                      FILE_DIRECTORY_INFO * findData,
-+                      T2_FNEXT_RSP_PARMS * findParms,
-+                      const __u16 searchHandle, char * resume_name,
-+                      int name_length, __u32 resume_key,
-+                      int *UnicodeFlag, int *pUnixFlag);
-+
-+extern int CIFSFindClose(const int, struct cifsTconInfo *tcon,
-+                      const __u16 search_handle);
-+
-+extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
-+                      const unsigned char *searchName,
-+                      FILE_ALL_INFO * findData,
-+                      const struct nls_table *nls_codepage);
-+
-+extern int CIFSSMBUnixQPathInfo(const int xid,
-+                      struct cifsTconInfo *tcon,
-+                      const unsigned char *searchName,
-+                      FILE_UNIX_BASIC_INFO * pFindData,
-+                      const struct nls_table *nls_codepage);
-+
-+extern int CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
-+                      const unsigned char *searchName,
-+                      unsigned char **targetUNCs,
-+                      unsigned int *number_of_UNC_in_array,
-+                      const struct nls_table *nls_codepage);
-+
-+extern int connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
-+                      const char *old_path,
-+                      const struct nls_table *nls_codepage);
-+extern int get_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
-+                      const char *old_path, const struct nls_table *nls_codepage, 
-+                      unsigned int *pnum_referrals, unsigned char ** preferrals);
-+extern int CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon,
-+                      struct statfs *FSData,
-+                      const struct nls_table *nls_codepage);
-+extern int CIFSSMBQFSAttributeInfo(const int xid,
-+                      struct cifsTconInfo *tcon,
-+                      const struct nls_table *nls_codepage);
-+extern int CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon,
-+                      const struct nls_table *nls_codepage);
-+extern int CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon,
-+                      const struct nls_table *nls_codepage);
-+
-+extern int CIFSSMBSetTimes(const int xid, struct cifsTconInfo *tcon,
-+                      char *fileName, FILE_BASIC_INFO * data,
-+                      const struct nls_table *nls_codepage);
-+extern int CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon,
-+                      char *fileName, __u64 size,int setAllocationSizeFlag,
-+                      const struct nls_table *nls_codepage);
-+extern int CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon,
-+                       __u64 size, __u16 fileHandle,__u32 opener_pid, int AllocSizeFlag);
-+extern int CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *pTcon,
-+                      char *full_path, __u64 mode, __u64 uid,
-+                      __u64 gid, dev_t dev, const struct nls_table *nls_codepage);
-+
-+extern int CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon,
-+                      const char *newName,
-+                      const struct nls_table *nls_codepage);
-+extern int CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon,
-+                      const char *name, const struct nls_table *nls_codepage);
-+
-+extern int CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon,
-+                      const char *name,
-+                      const struct nls_table *nls_codepage);
-+extern int CIFSSMBRename(const int xid, struct cifsTconInfo *tcon,
-+                      const char *fromName, const char *toName,
-+                      const struct nls_table *nls_codepage);
-+extern int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
-+                      int netfid, char * target_name, const struct nls_table *nls_codepage);
-+extern int CIFSCreateHardLink(const int xid,
-+                      struct cifsTconInfo *tcon,
-+                      const char *fromName, const char *toName,
-+                      const struct nls_table *nls_codepage);
-+extern int CIFSUnixCreateHardLink(const int xid,
-+                      struct cifsTconInfo *tcon,
-+                      const char *fromName, const char *toName,
-+                      const struct nls_table *nls_codepage);
-+extern int CIFSUnixCreateSymLink(const int xid,
-+                      struct cifsTconInfo *tcon,
-+                      const char *fromName, const char *toName,
-+                      const struct nls_table *nls_codepage);
-+extern int CIFSSMBUnixQuerySymLink(const int xid,
-+                      struct cifsTconInfo *tcon,
-+                      const unsigned char *searchName,
-+                      char *syminfo, const int buflen,
-+                      const struct nls_table *nls_codepage);
-+extern int CIFSSMBQueryReparseLinkInfo(const int xid, 
-+                      struct cifsTconInfo *tcon,
-+                      const unsigned char *searchName,
-+                      char *symlinkinfo, const int buflen, __u16 fid,
-+                      const struct nls_table *nls_codepage);
-+
-+extern int CIFSSMBOpen(const int xid, struct cifsTconInfo *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);
-+extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon,
-+                      const int smb_file_id);
-+
-+extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
-+                      const int netfid, unsigned int count,
-+                      const __u64 lseek, unsigned int *nbytes, char **buf);
-+extern int CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
-+                      const int netfid, const unsigned int count,
-+                      const __u64 lseek, unsigned int *nbytes,
-+                      const char *buf, const int long_op);
-+extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
-+                      const __u16 netfid, const __u64 len,
-+                      const __u64 offset, const __u32 numUnlock,
-+                      const __u32 numLock, const __u8 lockType,
-+                      const int waitFlag);
-+
-+extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon);
-+extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses);
-+
-+extern struct cifsSesInfo *sesInfoAlloc(void);
-+extern void sesInfoFree(struct cifsSesInfo *);
-+extern struct cifsTconInfo *tconInfoAlloc(void);
-+extern void tconInfoFree(struct cifsTconInfo *);
-+
-+extern int cifs_reconnect(struct TCP_Server_Info *server);
-+
-+extern int cifs_sign_smb(struct smb_hdr *, struct cifsSesInfo *,__u32 *);
-+extern int cifs_verify_signature(const struct smb_hdr *, const char * mac_key,
-+      __u32 expected_sequence_number);
-+extern int cifs_calculate_mac_key(char * key,const char * rn,const char * pass);
-+extern void CalcNTLMv2_partial_mac_key(struct cifsSesInfo *, struct nls_table *);
-+extern void CalcNTLMv2_response(const struct cifsSesInfo *,char * );
-+
-+extern int CIFSBuildServerList(int xid, char *serverBufferList,
-+                      int recordlength, int *entries,
-+                      int *totalEntries, int *topoChangedFlag);
-+extern int CIFSSMBQueryShares(int xid, struct cifsTconInfo *tcon,
-+                      struct shareInfo *shareList, int bufferLen,
-+                      int *entries, int *totalEntries);
-+extern int CIFSSMBQueryAlias(int xid, struct cifsTconInfo *tcon,
-+                      struct aliasInfo *aliasList, int bufferLen,
-+                      int *entries, int *totalEntries);
-+extern int CIFSSMBAliasInfo(int xid, struct cifsTconInfo *tcon,
-+                      char *aliasName, char *serverName,
-+                      char *shareName, char *comment);
-+extern int CIFSSMBGetShareInfo(int xid, struct cifsTconInfo *tcon,
-+                      char *share, char *comment);
-+extern int CIFSSMBGetUserPerms(int xid, struct cifsTconInfo *tcon,
-+                      char *userName, char *searchName, int *perms);
-+extern int CIFSSMBSync(int xid, struct cifsTconInfo *tcon, int netfid, int pid);
-+
-+extern int CIFSSMBSeek(int xid,
-+                      struct cifsTconInfo *tcon,
-+                      int netfid,
-+                      int pid,
-+                      int whence, unsigned long offset, long long *newoffset);
-+
-+extern int CIFSSMBCopy(int xid,
-+                      struct cifsTconInfo *source_tcon,
-+                      const char *fromName,
-+                      const __u16 target_tid,
-+                      const char *toName, const int flags,
-+                      const struct nls_table *nls_codepage);
-+extern int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, 
-+                      const int notify_subdirs,const __u16 netfid,__u32 filter,
-+                      const struct nls_table *nls_codepage);
-+extern int CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
-+               const unsigned char *searchName,
-+               char * EAData, size_t size,
-+               const struct nls_table *nls_codepage);
-+#endif                        /* _CIFSPROTO_H */
---- /dev/null
-+++ b/fs/cifs/cifssmb.c
-@@ -0,0 +1,3016 @@
-+/*
-+ *   fs/cifs/cifssmb.c
-+ *
-+ *   Copyright (C) International Business Machines  Corp., 2002,2003
-+ *   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 different for reconnection purposes since we never want  */
-+ /* to reuse a stale file handle and the caller knows the file handle */
-+
-+#include <linux/fs.h>
-+#include <linux/kernel.h>
-+#include <linux/vfs.h>
-+#include <asm/uaccess.h>
-+#include "cifspdu.h"
-+#include "cifsglob.h"
-+#include "cifsproto.h"
-+#include "cifs_unicode.h"
-+#include "cifs_debug.h"
-+
-+#ifdef CONFIG_CIFS_POSIX
-+static struct {
-+      int index;
-+      char *name;
-+} protocols[] = {
-+      {CIFS_PROT, "\2NT LM 0.12"}, 
-+      {CIFS_PROT, "\2POSIX 2"},
-+      {BAD_PROT, "\2"}
-+};
-+#else
-+static struct {
-+      int index;
-+      char *name;
-+} protocols[] = {
-+      {CIFS_PROT, "\2NT LM 0.12"}, 
-+      {BAD_PROT, "\2"}
-+};
-+#endif
-+
-+
-+/* 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 cifsTconInfo * 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 */
-+      write_lock(&GlobalSMBSeslock);
-+      list_for_each_safe(tmp, tmp1, &pTcon->openFileList) {
-+              open_file = list_entry(tmp,struct cifsFileInfo, tlist);
-+              if(open_file) {
-+                      open_file->invalidHandle = TRUE;
-+              }
-+      }
-+      write_unlock(&GlobalSMBSeslock);
-+      /* BB Add call to invalidate_inodes(sb) for all superblocks mounted to this tcon */
-+}
-+
-+static int
-+smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
-+       void **request_buf /* returned */ ,
-+       void **response_buf /* returned */ )
-+{
-+      int rc = 0;
-+      int timeout = 10 * HZ;
-+
-+      /* 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) {
-+              if((tcon->ses) && (tcon->ses->server)){
-+                      struct nls_table *nls_codepage;
-+                              /* Give Demultiplex thread up to 10 seconds to 
-+                                      reconnect, should be greater than cifs socket
-+                                      timeout which is 7 seconds */
-+                      while(tcon->ses->server->tcpStatus == CifsNeedReconnect) {
-+                              while ((tcon->ses->server->tcpStatus != CifsGood) && (timeout > 0)){
-+                                      timeout = interruptible_sleep_on_timeout(&tcon->ses->server->response_q,timeout);
-+                              }
-+                              if(tcon->ses->server->tcpStatus == CifsNeedReconnect) {
-+                                      /* on "soft" mounts we wait once */
-+                                      if((tcon->retry == FALSE) || 
-+                                         (tcon->ses->status == CifsExiting)) {
-+                                              cFYI(1,("gave up waiting on reconnect in smb_init"));
-+                                              return -EHOSTDOWN;
-+                                      } /* else "hard" mount - keep retrying until 
-+                                      process is killed or server comes back up */
-+                              } else /* TCP session is reestablished now */
-+                                      break;
-+                               
-+                      }
-+                      
-+                      nls_codepage = load_nls_default();
-+              /* need to prevent multiple threads trying to
-+              simultaneously reconnect the same SMB session */
-+                      down(&tcon->ses->sesSem);
-+                      if(tcon->ses->status == CifsNeedReconnect)
-+                              rc = cifs_setup_session(0, tcon->ses, nls_codepage);
-+                      if(!rc && (tcon->tidStatus == CifsNeedReconnect)) {
-+                              mark_open_files_invalid(tcon);
-+                              rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon,
-+                                      nls_codepage);
-+                              up(&tcon->ses->sesSem);
-+                              if(rc == 0)
-+                                      atomic_inc(&tconInfoReconnectCount);
-+
-+                              cFYI(1, ("reconnect tcon rc = %d", rc));
-+                              /* 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 */
-+
-+                              /* 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: {
-+                                              unload_nls(nls_codepage);
-+                                              return -EAGAIN;
-+                                      }
-+                              }
-+                      } else {
-+                              up(&tcon->ses->sesSem);
-+                      }
-+                      unload_nls(nls_codepage);
-+
-+              } else {
-+                      return -EIO;
-+              }
-+      }
-+      if(rc)
-+              return rc;
-+
-+      *request_buf = cifs_buf_get();
-+      if (*request_buf == 0) {
-+              /* 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 */
-+      *response_buf = *request_buf; 
-+
-+      header_assemble((struct smb_hdr *) *request_buf, smb_command, tcon,
-+                      wct /*wct */ );
-+
-+#ifdef CONFIG_CIFS_STATS
-+        if(tcon != NULL) {
-+                atomic_inc(&tcon->num_smbs_sent);
-+        }
-+#endif
-+      return rc;
-+}
-+
-+int
-+CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
-+{
-+      NEGOTIATE_REQ *pSMB;
-+      NEGOTIATE_RSP *pSMBr;
-+      int rc = 0;
-+      int bytes_returned;
-+      struct TCP_Server_Info * server;
-+
-+      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;
-+
-+      pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
-+      if (extended_security)
-+              pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
-+
-+      pSMB->ByteCount = strlen(protocols[0].name) + 1;
-+      strncpy(pSMB->DialectsArray, protocols[0].name, 30);    
-+    /* null guaranteed to be at end of source and target buffers anyway */
-+
-+      pSMB->hdr.smb_buf_length += pSMB->ByteCount;
-+      pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
-+
-+      rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
-+                       (struct smb_hdr *) pSMBr, &bytes_returned, 0);
-+      if (rc == 0) {
-+              server->secMode = pSMBr->SecurityMode;  
-+              server->secType = NTLM; /* BB override default for NTLMv2 or krb*/
-+              /* one byte - no need to convert this or EncryptionKeyLen from le,*/
-+              server->maxReq = le16_to_cpu(pSMBr->MaxMpxCount);
-+              /* probably no need to store and check maxvcs */
-+              server->maxBuf =
-+                      min(le32_to_cpu(pSMBr->MaxBufferSize),
-+                      (__u32) CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE);
-+              server->maxRw = le32_to_cpu(pSMBr->MaxRawSize);
-+              cFYI(0, ("Max buf = %d ", ses->server->maxBuf));
-+              GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey);
-+              server->capabilities = le32_to_cpu(pSMBr->Capabilities);
-+              server->timeZone = le16_to_cpu(pSMBr->ServerTimeZone);  
-+        /* BB with UTC do we ever need to be using srvr timezone? */
-+              if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
-+                      memcpy(server->cryptKey, pSMBr->u.EncryptionKey,
-+                             CIFS_CRYPTO_KEY_SIZE);
-+              } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC)
-+                         && (pSMBr->EncryptionKeyLength == 0)) {
-+                      /* decode security blob */
-+              } else
-+                      rc = -EIO;
-+
-+              /* BB might be helpful to save off the domain of server here */
-+
-+              if (pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) {
-+                      if (pSMBr->ByteCount < 16)
-+                              rc = -EIO;
-+                      else if (pSMBr->ByteCount == 16) {
-+                              server->secType = RawNTLMSSP;
-+                              if (server->socketUseCount.counter > 1) {
-+                                      if (memcmp
-+                                              (server->server_GUID,
-+                                              pSMBr->u.extended_response.
-+                                              GUID, 16) != 0) {
-+                                              cFYI(1,
-+                                                      ("UID of server does not match previous connection to same ip address"));
-+                                              memcpy(server->
-+                                                      server_GUID,
-+                                                      pSMBr->u.
-+                                                      extended_response.
-+                                                      GUID, 16);
-+                                      }
-+                              } else
-+                                      memcpy(server->server_GUID,
-+                                             pSMBr->u.extended_response.
-+                                             GUID, 16);
-+                      } else {
-+                              rc = decode_negTokenInit(pSMBr->u.
-+                                                       extended_response.
-+                                                       SecurityBlob,
-+                                                       pSMBr->ByteCount -
-+                                                       16, &server->secType);
-+                      }
-+              } else
-+                      server->capabilities &= ~CAP_EXTENDED_SECURITY;
-+              if(sign_CIFS_PDUs == FALSE) {        
-+                      if(server->secMode & SECMODE_SIGN_REQUIRED)
-+                              cERROR(1,
-+                               ("Server requires /proc/fs/cifs/PacketSigningEnabled"));
-+                      server->secMode &= ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
-+              } else if(sign_CIFS_PDUs == 1) {
-+                      if((server->secMode & SECMODE_SIGN_REQUIRED) == 0)
-+                              server->secMode &= ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
-+              }
-+                              
-+      }
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+      return rc;
-+}
-+
-+int
-+CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
-+{
-+      struct smb_hdr *smb_buffer;
-+      struct smb_hdr *smb_buffer_response;
-+      int rc = 0;
-+      int length;
-+
-+      cFYI(1, ("In tree disconnect"));
-+      /*
-+       *  If last user of the connection and
-+       *  connection alive - disconnect it
-+       *  If this is the last connection on the server session disconnect it
-+       *  (and inside session disconnect we should check if tcp socket needs 
-+       *  to be freed and kernel thread woken up).
-+       */
-+      if (tcon)
-+              down(&tcon->tconSem);
-+      else
-+              return -EIO;
-+
-+      atomic_dec(&tcon->useCount);
-+      if (atomic_read(&tcon->useCount) > 0) {
-+              up(&tcon->tconSem);
-+              return -EBUSY;
-+      }
-+
-+      /* No need to return error on this operation if tid invalidated and 
-+      closed on server already e.g. due to tcp session crashing */
-+      if(tcon->tidStatus == CifsNeedReconnect) {
-+              up(&tcon->tconSem);
-+              return 0;  
-+      }
-+
-+      if((tcon->ses == 0) || (tcon->ses->server == 0)) {    
-+              up(&tcon->tconSem);
-+              return -EIO;
-+      }
-+
-+      rc = smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
-+                    (void **) &smb_buffer, (void **) &smb_buffer_response);
-+      if (rc) {
-+              up(&tcon->tconSem);
-+              return rc;
-+      }
-+      rc = SendReceive(xid, tcon->ses, smb_buffer, smb_buffer_response,
-+                       &length, 0);
-+      if (rc)
-+              cFYI(1, (" Tree disconnect failed %d", rc));
-+
-+      if (smb_buffer)
-+              cifs_buf_release(smb_buffer);
-+      up(&tcon->tconSem);
-+
-+      /* 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;
-+}
-+
-+int
-+CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
-+{
-+      struct smb_hdr *smb_buffer_response;
-+      LOGOFF_ANDX_REQ *pSMB;
-+      int rc = 0;
-+      int length;
-+
-+      cFYI(1, ("In SMBLogoff for session disconnect"));
-+      if (ses)
-+              down(&ses->sesSem);
-+      else
-+              return -EIO;
-+
-+      atomic_dec(&ses->inUse);
-+      if (atomic_read(&ses->inUse) > 0) {
-+              up(&ses->sesSem);
-+              return -EBUSY;
-+      }
-+
-+      rc = smb_init(SMB_COM_LOGOFF_ANDX, 2, NULL /* no tcon anymore */,
-+               (void **) &pSMB, (void **) &smb_buffer_response);
-+
-+      if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
-+              pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
-+
-+      if (rc) {
-+              up(&ses->sesSem);
-+              return rc;
-+      }
-+
-+      pSMB->hdr.Uid = ses->Suid;
-+
-+      pSMB->AndXCommand = 0xFF;
-+      rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
-+                       smb_buffer_response, &length, 0);
-+      if (ses->server) {
-+              atomic_dec(&ses->server->socketUseCount);
-+              if (atomic_read(&ses->server->socketUseCount) == 0) {
-+                      spin_lock(&GlobalMid_Lock);
-+                      ses->server->tcpStatus = CifsExiting;
-+                      spin_unlock(&GlobalMid_Lock);
-+                      rc = -ESHUTDOWN;
-+              }
-+      }
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+      up(&ses->sesSem);
-+
-+      /* 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
-+CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon,
-+             const char *fileName, const struct nls_table *nls_codepage)
-+{
-+      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 =
-+                  cifs_strtoUCS((wchar_t *) pSMB->fileName, fileName, 530
-+                                /* find define for this maxpathcomponent */
-+                                , nls_codepage);
-+              name_len++;     /* trailing null */
-+              name_len *= 2;
-+      } else {                /* BB improve the check for buffer overruns BB */
-+              name_len = strnlen(fileName, 530);
-+              name_len++;     /* trailing null */
-+              strncpy(pSMB->fileName, fileName, name_len);
-+      }
-+      pSMB->SearchAttributes =
-+          cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
-+      pSMB->ByteCount = name_len + 1;
-+      pSMB->BufferFormat = 0x04;
-+      pSMB->hdr.smb_buf_length += pSMB->ByteCount;
-+      pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
-+      rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
-+                       (struct smb_hdr *) pSMBr, &bytes_returned, 0);
-+      if (rc) {
-+              cFYI(1, ("Error in RMFile = %d", rc));
-+      } 
-+#ifdef CONFIG_CIFS_STATS
-+        else {
-+              atomic_inc(&tcon->num_deletes);
-+        }
-+#endif
-+
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+      if (rc == -EAGAIN)
-+              goto DelFileRetry;
-+
-+      return rc;
-+}
-+
-+int
-+CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon,
-+           const char *dirName, const struct nls_table *nls_codepage)
-+{
-+      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 = cifs_strtoUCS((wchar_t *) pSMB->DirName, dirName, 530
-+                              /* find define for this maxpathcomponent */
-+                              , nls_codepage);
-+              name_len++;     /* trailing null */
-+              name_len *= 2;
-+      } else {                /* BB improve the check for buffer overruns BB */
-+              name_len = strnlen(dirName, 530);
-+              name_len++;     /* trailing null */
-+              strncpy(pSMB->DirName, dirName, name_len);
-+      }
-+
-+      pSMB->ByteCount = name_len + 1;
-+      pSMB->BufferFormat = 0x04;
-+      pSMB->hdr.smb_buf_length += pSMB->ByteCount;
-+      pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
-+      rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
-+                       (struct smb_hdr *) pSMBr, &bytes_returned, 0);
-+      if (rc) {
-+              cFYI(1, ("Error in RMDir = %d", rc));
-+      }
-+#ifdef CONFIG_CIFS_STATS
-+        else {
-+              atomic_inc(&tcon->num_rmdirs);
-+        }
-+#endif
-+
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+      if (rc == -EAGAIN)
-+              goto RmDirRetry;
-+      return rc;
-+}
-+
-+int
-+CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon,
-+           const char *name, const struct nls_table *nls_codepage)
-+{
-+      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 = cifs_strtoUCS((wchar_t *) pSMB->DirName, name, 530
-+                                       /* find define for this maxpathcomponent */
-+                                       , nls_codepage);
-+              name_len++;     /* trailing null */
-+              name_len *= 2;
-+      } else {                /* BB improve the check for buffer overruns BB */
-+              name_len = strnlen(name, 530);
-+              name_len++;     /* trailing null */
-+              strncpy(pSMB->DirName, name, name_len);
-+      }
-+
-+      pSMB->ByteCount = name_len + 1 /* for buf format */ ;
-+      pSMB->BufferFormat = 0x04;
-+      pSMB->hdr.smb_buf_length += pSMB->ByteCount;
-+      pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
-+      rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
-+                       (struct smb_hdr *) pSMBr, &bytes_returned, 0);
-+      if (rc) {
-+              cFYI(1, ("Error in Mkdir = %d", rc));
-+      }
-+#ifdef CONFIG_CIFS_STATS
-+        else {
-+              atomic_inc(&tcon->num_mkdirs);
-+        }
-+#endif
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+      if (rc == -EAGAIN)
-+              goto MkDirRetry;
-+      return rc;
-+}
-+
-+int
-+CIFSSMBOpen(const int xid, struct cifsTconInfo *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 rc = -EACCES;
-+      OPEN_REQ *pSMB = NULL;
-+      OPEN_RSP *pSMBr = NULL;
-+      int bytes_returned;
-+      int name_len;
-+
-+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) {
-+              pSMB->ByteCount = 1;    /* account for one byte pad to word boundary */
-+              name_len =
-+                  cifs_strtoUCS((wchar_t *) (pSMB->fileName + 1),
-+                                fileName, 530
-+                                /* find define for this maxpathcomponent */
-+                                , nls_codepage);
-+              name_len++;     /* trailing null */
-+              name_len *= 2;
-+              pSMB->NameLength = cpu_to_le16(name_len);
-+      } else {                /* BB improve the check for buffer overruns BB */
-+              pSMB->ByteCount = 0;    /* no pad */
-+              name_len = strnlen(fileName, 530);
-+              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;
-+      pSMB->FileAttributes = 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 |= ATTR_POSIX_SEMANTICS;
-+
-+      /* if ((omode & S_IWUGO) == 0)
-+              pSMB->FileAttributes |= ATTR_READONLY;*/
-+      /*  Above line causes problems due to vfs splitting create into two
-+              pieces - need to set mode after file created not while it is
-+              being created */
-+      pSMB->FileAttributes = cpu_to_le32(pSMB->FileAttributes);
-+      pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
-+      pSMB->CreateDisposition = cpu_to_le32(openDisposition);
-+      pSMB->CreateOptions = cpu_to_le32(create_options);
-+      pSMB->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION); /* BB ??*/
-+      pSMB->SecurityFlags =
-+          cpu_to_le32(SECURITY_CONTEXT_TRACKING | SECURITY_EFFECTIVE_ONLY);
-+
-+      pSMB->ByteCount += name_len;
-+      pSMB->hdr.smb_buf_length += pSMB->ByteCount;
-+
-+      pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
-+      /* 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, 1);
-+      if (rc) {
-+              cFYI(1, ("Error in Open = %d", rc));
-+      } else {
-+              *pOplock = pSMBr->OplockLevel;  /* one 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);
-+              }
-+
-+#ifdef CONFIG_CIFS_STATS
-+              atomic_inc(&tcon->num_opens);
-+#endif
-+      }
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+      if (rc == -EAGAIN)
-+              goto openRetry;
-+      return rc;
-+}
-+
-+/* If no buffer passed in, then caller wants to do the copy
-+      as in the case of readpages so the SMB buffer must be
-+      freed by the caller */
-+
-+int
-+CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
-+          const int netfid, const unsigned int count,
-+          const __u64 lseek, unsigned int *nbytes, char **buf)
-+{
-+      int rc = -EACCES;
-+      READ_REQ *pSMB = NULL;
-+      READ_RSP *pSMBr = NULL;
-+      char *pReadData = NULL;
-+      int bytes_returned;
-+
-+      *nbytes = 0;
-+      rc = smb_init(SMB_COM_READ_ANDX, 12, tcon, (void **) &pSMB,
-+                    (void **) &pSMBr);
-+      if (rc)
-+              return rc;
-+
-+      /* 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(lseek & 0xFFFFFFFF);
-+      pSMB->OffsetHigh = cpu_to_le32(lseek >> 32);
-+      pSMB->Remaining = 0;
-+      pSMB->MaxCount = cpu_to_le16(count);
-+      pSMB->MaxCountHigh = 0;
-+      pSMB->ByteCount = 0;  /* no need to do le conversion since it is 0 */
-+
-+      rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
-+                       (struct smb_hdr *) pSMBr, &bytes_returned, 0);
-+      if (rc) {
-+              cERROR(1, ("Send error in read = %d", rc));
-+      } else {
-+              pSMBr->DataLength = le16_to_cpu(pSMBr->DataLength);
-+              *nbytes = pSMBr->DataLength;
-+              /*check that DataLength would not go beyond end of SMB */
-+              if ((pSMBr->DataLength > CIFS_MAX_MSGSIZE) 
-+                              || (pSMBr->DataLength > count)) {
-+                      cFYI(1,("bad length %d for count %d",pSMBr->DataLength,count));
-+                      rc = -EIO;
-+                      *nbytes = 0;
-+              } else {
-+                      pReadData =
-+                          (char *) (&pSMBr->hdr.Protocol) +
-+                          le16_to_cpu(pSMBr->DataOffset);
-+/*                    if(rc = copy_to_user(buf, pReadData, pSMBr->DataLength)) {
-+                              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,pSMBr->DataLength);
-+              }
-+      }
-+      if (pSMB) {
-+              if(*buf)
-+                      cifs_buf_release(pSMB);
-+              else
-+                      *buf = (char *)pSMB;
-+      }
-+
-+      /* Note: On -EAGAIN error only caller can retry on handle based calls 
-+              since file handle passed in no longer valid */
-+      return rc;
-+}
-+
-+int
-+CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
-+           const int netfid, const unsigned int count,
-+           const __u64 offset, unsigned int *nbytes, const char *buf,
-+           const int long_op)
-+{
-+      int rc = -EACCES;
-+      WRITE_REQ *pSMB = NULL;
-+      WRITE_RSP *pSMBr = NULL;
-+      int bytes_returned;
-+
-+      rc = smb_init(SMB_COM_WRITE_ANDX, 14, tcon, (void **) &pSMB,
-+                    (void **) &pSMBr);
-+      if (rc)
-+              return rc;
-+      /* 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);
-+      pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
-+      pSMB->Remaining = 0;
-+      if (count > ((tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFF00))
-+              pSMB->DataLengthLow =
-+                  (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFF00;
-+      else
-+              pSMB->DataLengthLow = count;
-+      pSMB->DataLengthHigh = 0;
-+      pSMB->DataOffset =
-+          cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4);
-+
-+      memcpy(pSMB->Data,buf,pSMB->DataLengthLow);
-+
-+      pSMB->ByteCount += pSMB->DataLengthLow + 1 /* pad */ ;
-+      pSMB->DataLengthLow = cpu_to_le16(pSMB->DataLengthLow);
-+      pSMB->hdr.smb_buf_length += pSMB->ByteCount;
-+      pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
-+
-+      rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
-+                       (struct smb_hdr *) pSMBr, &bytes_returned, long_op);
-+      if (rc) {
-+              cFYI(1, ("Send error in write = %d", rc));
-+              *nbytes = 0;
-+      } else
-+              *nbytes = le16_to_cpu(pSMBr->Count);
-+
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+
-+      /* Note: On -EAGAIN error only caller can retry on handle based calls 
-+              since file handle passed in no longer valid */
-+
-+      return rc;
-+}
-+
-+int
-+CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
-+          const __u16 smb_file_id, const __u64 len,
-+          const __u64 offset, const __u32 numUnlock,
-+          const __u32 numLock, const __u8 lockType, const int waitFlag)
-+{
-+      int rc = 0;
-+      LOCK_REQ *pSMB = NULL;
-+      LOCK_RSP *pSMBr = NULL;
-+      int bytes_returned;
-+      int timeout = 0;
-+      __u64 temp;
-+
-+      cFYI(1, ("In CIFSSMBLock - timeout %d numLock %d",waitFlag,numLock));
-+      rc = smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB,
-+                    (void **) &pSMBr);
-+      if (rc)
-+              return rc;
-+
-+      if(lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
-+              timeout = -1; /* no response expected */
-+              pSMB->Timeout = 0;
-+      } else if (waitFlag == TRUE) {
-+              timeout = 3;  /* blocking operation, no timeout */
-+              pSMB->Timeout = -1; /* blocking - do not time out */
-+      } else {
-+              pSMB->Timeout = 0;
-+      }
-+
-+      pSMB->NumberOfLocks = cpu_to_le32(numLock);
-+      pSMB->NumberOfUnlocks = cpu_to_le32(numUnlock);
-+      pSMB->LockType = lockType;
-+      pSMB->AndXCommand = 0xFF;       /* none */
-+      pSMB->Fid = smb_file_id; /* netfid stays le */
-+
-+      if(numLock != 0) {
-+              pSMB->Locks[0].Pid = cpu_to_le16(current->tgid);
-+              /* BB where to store pid high? */
-+              temp = cpu_to_le64(len);
-+              pSMB->Locks[0].LengthLow = (__u32)(temp & 0xFFFFFFFF);
-+              pSMB->Locks[0].LengthHigh =  (__u32)(temp>>32);
-+              temp = cpu_to_le64(offset);
-+              pSMB->Locks[0].OffsetLow = (__u32)(temp & 0xFFFFFFFF);
-+              pSMB->Locks[0].OffsetHigh = (__u32)(temp>>32);
-+              pSMB->ByteCount = sizeof (LOCKING_ANDX_RANGE);
-+      } else {
-+              /* oplock break */
-+              pSMB->ByteCount = 0;
-+      }
-+      pSMB->hdr.smb_buf_length += pSMB->ByteCount;
-+      pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
-+
-+      rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
-+                       (struct smb_hdr *) pSMBr, &bytes_returned, timeout);
-+
-+      if (rc) {
-+              cFYI(1, ("Send error in Lock = %d", rc));
-+      }
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+
-+      /* Note: On -EAGAIN error only caller can retry on handle based calls 
-+      since file handle passed in no longer valid */
-+      return rc;
-+}
-+
-+int
-+CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
-+{
-+      int rc = 0;
-+      CLOSE_REQ *pSMB = NULL;
-+      CLOSE_RSP *pSMBr = NULL;
-+      int bytes_returned;
-+      cFYI(1, ("In CIFSSMBClose"));
-+
-+/* do not retry on dead session on close */
-+      rc = smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB,
-+                    (void **) &pSMBr);
-+      if(rc == -EAGAIN)
-+              return 0;
-+      if (rc)
-+              return rc;
-+
-+      pSMB->FileID = (__u16) smb_file_id;
-+      pSMB->LastWriteTime = 0;
-+      pSMB->ByteCount = 0;
-+      rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
-+                       (struct smb_hdr *) pSMBr, &bytes_returned, 0);
-+      if (rc) {
-+              if(rc!=-EINTR) {
-+                      /* EINTR is expected when user ctl-c to kill app */
-+                      cERROR(1, ("Send error in Close = %d", rc));
-+              }
-+      }
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+
-+      /* Since session is dead, file will be closed on server already */
-+      if(rc == -EAGAIN)
-+              rc = 0;
-+
-+      return rc;
-+}
-+
-+int
-+CIFSSMBRename(const int xid, struct cifsTconInfo *tcon,
-+            const char *fromName, const char *toName,
-+            const struct nls_table *nls_codepage)
-+{
-+      int rc = 0;
-+      RENAME_REQ *pSMB = NULL;
-+      RENAME_RSP *pSMBr = NULL;
-+      int bytes_returned;
-+      int name_len, name_len2;
-+
-+      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 =
-+                  cifs_strtoUCS((wchar_t *) pSMB->OldFileName, fromName, 530
-+                                /* find define for this maxpathcomponent */
-+                                , nls_codepage);
-+              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 =
-+                  cifs_strtoUCS((wchar_t *) & pSMB->
-+                                OldFileName[name_len + 2], toName, 530,
-+                                nls_codepage);
-+              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, 530);
-+              name_len++;     /* trailing null */
-+              strncpy(pSMB->OldFileName, fromName, name_len);
-+              name_len2 = strnlen(toName, 530);
-+              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 */
-+      }
-+
-+      pSMB->ByteCount = 1 /* 1st signature byte */  + name_len + name_len2;
-+      pSMB->hdr.smb_buf_length += pSMB->ByteCount;
-+      pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
-+
-+      rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
-+                       (struct smb_hdr *) pSMBr, &bytes_returned, 0);
-+      if (rc) {
-+              cFYI(1, ("Send error in rename = %d", rc));
-+      } 
-+
-+#ifdef CONFIG_CIFS_STATS
-+        else {
-+              atomic_inc(&tcon->num_renames);
-+      }
-+#endif
-+
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+
-+      if (rc == -EAGAIN)
-+              goto renameRetry;
-+
-+      return rc;
-+}
-+
-+int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon, 
-+              int netfid, char * target_name, const struct nls_table * nls_codepage) 
-+{
-+      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;
-+
-+      cFYI(1, ("Rename to File by handle"));
-+      rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
-+                      (void **) &pSMBr);
-+      if (rc)
-+              return rc;
-+
-+      pSMB->ParameterCount = 6;
-+      pSMB->MaxSetupCount = 0;
-+      pSMB->Reserved = 0;
-+      pSMB->Flags = 0;
-+      pSMB->Timeout = 0;
-+      pSMB->Reserved2 = 0;
-+      pSMB->ParameterOffset = offsetof(struct smb_com_transaction2_sfi_req,
-+                              Fid) - 4;
-+      pSMB->DataOffset = pSMB->ParameterOffset + pSMB->ParameterCount;
-+
-+      data_offset = (char *) (&pSMB->hdr.Protocol) + pSMB->DataOffset;
-+      rename_info = (struct set_file_rename *) data_offset;
-+      pSMB->MaxParameterCount = cpu_to_le16(2);
-+      pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */
-+      pSMB->SetupCount = 1;
-+      pSMB->Reserved3 = 0;
-+      pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
-+      pSMB->ByteCount = 3 /* pad */  + pSMB->ParameterCount;
-+      pSMB->ParameterCount = cpu_to_le16(pSMB->ParameterCount);
-+      pSMB->TotalParameterCount = pSMB->ParameterCount;
-+      pSMB->ParameterOffset = cpu_to_le16(pSMB->ParameterOffset);
-+      pSMB->DataOffset = cpu_to_le16(pSMB->DataOffset);
-+      /* 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 = cifs_strtoUCS((wchar_t *) rename_info->target_name, dummy_string, 24, nls_codepage);
-+      } else {
-+              len_of_str = cifs_strtoUCS((wchar_t *) rename_info->target_name, target_name, 530, nls_codepage);
-+      }
-+      rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
-+      pSMB->DataCount = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str) + 2;
-+      pSMB->ByteCount += pSMB->DataCount;
-+      pSMB->DataCount = cpu_to_le16(pSMB->DataCount);
-+      pSMB->TotalDataCount = pSMB->DataCount;
-+      pSMB->Fid = netfid;
-+      pSMB->InformationLevel =
-+              cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
-+      pSMB->Reserved4 = 0;
-+      pSMB->hdr.smb_buf_length += pSMB->ByteCount;
-+      pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
-+      rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
-+                         (struct smb_hdr *) pSMBr, &bytes_returned, 0);
-+      if (rc) {
-+              cFYI(1,("Send error in Rename (by file handle) = %d", rc));
-+      }
-+#ifdef CONFIG_CIFS_STATS
-+        else {
-+              atomic_inc(&pTcon->num_t2renames);
-+      }
-+#endif
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+
-+      /* Note: On -EAGAIN error only caller can retry on handle based calls
-+              since file handle passed in no longer valid */
-+
-+      return rc;
-+}
-+
-+int
-+CIFSSMBCopy(const int xid, struct cifsTconInfo *tcon, const char * fromName, 
-+            const __u16 target_tid, const char *toName, const int flags,
-+            const struct nls_table *nls_codepage)
-+{
-+      int rc = 0;
-+      COPY_REQ *pSMB = NULL;
-+      COPY_RSP *pSMBr = NULL;
-+      int bytes_returned;
-+      int name_len, name_len2;
-+
-+      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;
-+
-+      if(flags & COPY_TREE)
-+              pSMB->Flags |= COPY_TREE;
-+      pSMB->Flags = cpu_to_le16(pSMB->Flags);
-+
-+      if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
-+              name_len = cifs_strtoUCS((wchar_t *) pSMB->OldFileName, 
-+                              fromName, 
-+                              530 /* find define for this maxpathcomponent */,
-+                              nls_codepage);
-+              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 = cifs_strtoUCS((wchar_t *) & pSMB->
-+                              OldFileName[name_len + 2], toName, 530,
-+                              nls_codepage);
-+              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, 530);
-+              name_len++;     /* trailing null */
-+              strncpy(pSMB->OldFileName, fromName, name_len);
-+              name_len2 = strnlen(toName, 530);
-+              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 */
-+      }
-+
-+      pSMB->ByteCount = 1 /* 1st signature byte */  + name_len + name_len2;
-+      pSMB->hdr.smb_buf_length += pSMB->ByteCount;
-+      pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
-+
-+      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, pSMBr->CopyCount));
-+      }
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+
-+      if (rc == -EAGAIN)
-+              goto copyRetry;
-+
-+      return rc;
-+}
-+
-+int
-+CIFSUnixCreateSymLink(const int xid, struct cifsTconInfo *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;
-+
-+      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_strtoUCS((wchar_t *) pSMB->FileName, fromName, 530
-+                                /* find define for this maxpathcomponent */
-+                                , nls_codepage);
-+              name_len++;     /* trailing null */
-+              name_len *= 2;
-+
-+      } else {                /* BB improve the check for buffer overruns BB */
-+              name_len = strnlen(fromName, 530);
-+              name_len++;     /* trailing null */
-+              strncpy(pSMB->FileName, fromName, name_len);
-+      }
-+      pSMB->ParameterCount = 6 + name_len;
-+      pSMB->MaxSetupCount = 0;
-+      pSMB->Reserved = 0;
-+      pSMB->Flags = 0;
-+      pSMB->Timeout = 0;
-+      pSMB->Reserved2 = 0;
-+      pSMB->ParameterOffset = offsetof(struct smb_com_transaction2_spi_req,
-+                                     InformationLevel) - 4;
-+      pSMB->DataOffset = pSMB->ParameterOffset + pSMB->ParameterCount;
-+
-+      data_offset = (char *) (&pSMB->hdr.Protocol) + pSMB->DataOffset;
-+      if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
-+              name_len_target =
-+                  cifs_strtoUCS((wchar_t *) data_offset, toName, 530
-+                                /* 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, 530);
-+              name_len_target++;      /* trailing null */
-+              strncpy(data_offset, toName, name_len_target);
-+      }
-+
-+      pSMB->DataCount = 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);
-+      pSMB->ByteCount = 3 /* pad */  + pSMB->ParameterCount + pSMB->DataCount;
-+      pSMB->DataCount = cpu_to_le16(pSMB->DataCount);
-+      pSMB->ParameterCount = cpu_to_le16(pSMB->ParameterCount);
-+      pSMB->TotalDataCount = pSMB->DataCount;
-+      pSMB->TotalParameterCount = pSMB->ParameterCount;
-+      pSMB->ParameterOffset = cpu_to_le16(pSMB->ParameterOffset);
-+      pSMB->DataOffset = cpu_to_le16(pSMB->DataOffset);
-+      pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
-+      pSMB->Reserved4 = 0;
-+      pSMB->hdr.smb_buf_length += pSMB->ByteCount;
-+      pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
-+      rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
-+                       (struct smb_hdr *) pSMBr, &bytes_returned, 0);
-+      if (rc) {
-+              cFYI(1,
-+                   ("Send error in SetPathInfo (create symlink) = %d",
-+                    rc));
-+      }
-+
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+
-+      if (rc == -EAGAIN)
-+              goto createSymLinkRetry;
-+
-+      return rc;
-+}
-+
-+int
-+CIFSUnixCreateHardLink(const int xid, struct cifsTconInfo *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;
-+
-+      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 = cifs_strtoUCS((wchar_t *) pSMB->FileName, toName, 530
-+                                       /* find define for this maxpathcomponent */
-+                                       , nls_codepage);
-+              name_len++;     /* trailing null */
-+              name_len *= 2;
-+
-+      } else {                /* BB improve the check for buffer overruns BB */
-+              name_len = strnlen(toName, 530);
-+              name_len++;     /* trailing null */
-+              strncpy(pSMB->FileName, toName, name_len);
-+      }
-+      pSMB->ParameterCount = 6 + name_len;
-+      pSMB->MaxSetupCount = 0;
-+      pSMB->Reserved = 0;
-+      pSMB->Flags = 0;
-+      pSMB->Timeout = 0;
-+      pSMB->Reserved2 = 0;
-+      pSMB->ParameterOffset = offsetof(struct smb_com_transaction2_spi_req,
-+                                     InformationLevel) - 4;
-+      pSMB->DataOffset = pSMB->ParameterOffset + pSMB->ParameterCount;
-+
-+      data_offset = (char *) (&pSMB->hdr.Protocol) + pSMB->DataOffset;
-+      if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
-+              name_len_target =
-+                  cifs_strtoUCS((wchar_t *) data_offset, fromName, 530
-+                                /* 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(fromName, 530);
-+              name_len_target++;      /* trailing null */
-+              strncpy(data_offset, fromName, name_len_target);
-+      }
-+
-+      pSMB->DataCount = 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);
-+      pSMB->ByteCount = 3 /* pad */  + pSMB->ParameterCount + pSMB->DataCount;
-+      pSMB->ParameterCount = cpu_to_le16(pSMB->ParameterCount);
-+      pSMB->TotalParameterCount = pSMB->ParameterCount;
-+      pSMB->DataCount = cpu_to_le16(pSMB->DataCount);
-+      pSMB->TotalDataCount = pSMB->DataCount;
-+      pSMB->ParameterOffset = cpu_to_le16(pSMB->ParameterOffset);
-+      pSMB->DataOffset = cpu_to_le16(pSMB->DataOffset);
-+      pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
-+      pSMB->Reserved4 = 0;
-+      pSMB->hdr.smb_buf_length += pSMB->ByteCount;
-+      pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
-+      rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
-+                       (struct smb_hdr *) pSMBr, &bytes_returned, 0);
-+      if (rc) {
-+              cFYI(1, ("Send error in SetPathInfo (hard link) = %d", rc));
-+      }
-+
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+      if (rc == -EAGAIN)
-+              goto createHardLinkRetry;
-+
-+      return rc;
-+}
-+
-+int
-+CIFSCreateHardLink(const int xid, struct cifsTconInfo *tcon,
-+                 const char *fromName, const char *toName,
-+                 const struct nls_table *nls_codepage)
-+{
-+      int rc = 0;
-+      NT_RENAME_REQ *pSMB = NULL;
-+      RENAME_RSP *pSMBr = NULL;
-+      int bytes_returned;
-+      int name_len, name_len2;
-+
-+      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 =
-+                  cifs_strtoUCS((wchar_t *) pSMB->OldFileName, fromName, 530
-+                                /* find define for this maxpathcomponent */
-+                                , nls_codepage);
-+              name_len++;     /* trailing null */
-+              name_len *= 2;
-+              pSMB->OldFileName[name_len] = 0;        /* pad */
-+              pSMB->OldFileName[name_len + 1] = 0x04; 
-+              name_len2 =
-+                  cifs_strtoUCS((wchar_t *) & pSMB->
-+                                OldFileName[name_len + 2], toName, 530,
-+                                nls_codepage);
-+              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, 530);
-+              name_len++;     /* trailing null */
-+              strncpy(pSMB->OldFileName, fromName, name_len);
-+              name_len2 = strnlen(toName, 530);
-+              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 */
-+      }
-+
-+      pSMB->ByteCount = 1 /* string type byte */  + name_len + name_len2;
-+      pSMB->hdr.smb_buf_length += pSMB->ByteCount;
-+      pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
-+
-+      rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
-+                       (struct smb_hdr *) pSMBr, &bytes_returned, 0);
-+      if (rc) {
-+              cFYI(1, ("Send error in hard link (NT rename) = %d", rc));
-+      }
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+      if (rc == -EAGAIN)
-+              goto winCreateHardLinkRetry;
-+
-+      return rc;
-+}
-+
-+int
-+CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon,
-+                      const unsigned char *searchName,
-+                      char *symlinkinfo, const int buflen,
-+                      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;
-+
-+      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_strtoUCS((wchar_t *) pSMB->FileName, searchName, 530
-+                                /* find define for this maxpathcomponent */
-+                                , nls_codepage);
-+              name_len++;     /* trailing null */
-+              name_len *= 2;
-+      } else {                /* BB improve the check for buffer overruns BB */
-+              name_len = strnlen(searchName, 530);
-+              name_len++;     /* trailing null */
-+              strncpy(pSMB->FileName, searchName, name_len);
-+      }
-+
-+      pSMB->TotalParameterCount =
-+          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);
-+      pSMB->ByteCount = pSMB->TotalParameterCount + 1 /* pad */ ;
-+      pSMB->TotalParameterCount = cpu_to_le16(pSMB->TotalParameterCount);
-+      pSMB->ParameterCount = pSMB->TotalParameterCount;
-+      pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
-+      pSMB->Reserved4 = 0;
-+      pSMB->hdr.smb_buf_length += pSMB->ByteCount;
-+      pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
-+
-+      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 */
-+              pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
-+              pSMBr->DataCount = le16_to_cpu(pSMBr->DataCount);
-+              if ((pSMBr->ByteCount < 2) || (pSMBr->DataOffset > 512))
-+              /* BB also check enough total bytes returned */
-+                      rc = -EIO;      /* bad smb */
-+              else {
-+                      if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
-+                              name_len = UniStrnlen((wchar_t *) ((char *)
-+                                      &pSMBr->hdr.Protocol +pSMBr->DataOffset),
-+                                      min_t(const int, buflen,pSMBr->DataCount) / 2);
-+                              cifs_strfromUCS_le(symlinkinfo,
-+                                      (wchar_t *) ((char *)&pSMBr->hdr.Protocol +
-+                                              pSMBr->DataOffset),
-+                                      name_len, nls_codepage);
-+                      } else {
-+                              strncpy(symlinkinfo,
-+                                      (char *) &pSMBr->hdr.Protocol + 
-+                                              pSMBr->DataOffset,
-+                                      min_t(const int, buflen, pSMBr->DataCount));
-+                      }
-+                      symlinkinfo[buflen] = 0;
-+      /* just in case so calling code does not go off the end of buffer */
-+              }
-+      }
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+      if (rc == -EAGAIN)
-+              goto querySymLinkRetry;
-+      return rc;
-+}
-+
-+
-+
-+int
-+CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
-+                      const unsigned char *searchName,
-+                      char *symlinkinfo, const int buflen,__u16 fid,
-+                      const struct nls_table *nls_codepage)
-+{
-+      int rc = 0;
-+      int bytes_returned;
-+      int name_len;
-+      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(4000);
-+      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 */
-+              pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
-+              pSMBr->DataCount = le16_to_cpu(pSMBr->DataCount);
-+              if ((pSMBr->ByteCount < 2) || (pSMBr->DataOffset > 512))
-+              /* BB also check enough total bytes returned */
-+                      rc = -EIO;      /* bad smb */
-+              else {
-+                      if(pSMBr->DataCount && (pSMBr->DataCount < 2048)) {
-+              /* could also validate reparse tag && better check name length */
-+                              struct reparse_data * reparse_buf = (struct reparse_data *)
-+                                      ((char *)&pSMBr->hdr.Protocol + pSMBr->DataOffset);
-+                              if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
-+                                      name_len = UniStrnlen((wchar_t *)
-+                                                      (reparse_buf->LinkNamesBuf + 
-+                                                      reparse_buf->TargetNameOffset),
-+                                                      min(buflen/2, reparse_buf->TargetNameLen / 2)); 
-+                                      cifs_strfromUCS_le(symlinkinfo,
-+                                              (wchar_t *) (reparse_buf->LinkNamesBuf + 
-+                                              reparse_buf->TargetNameOffset),
-+                                              name_len, nls_codepage);
-+                              } 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));
-+              }
-+      }
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+
-+      /* Note: On -EAGAIN error only caller can retry on handle based calls
-+              since file handle passed in no longer valid */
-+
-+      return rc;
-+}
-+
-+int
-+CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
-+               const unsigned char *searchName,
-+               FILE_ALL_INFO * pFindData,
-+               const struct nls_table *nls_codepage)
-+{
-+/* 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;
-+
-+      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 =
-+                  cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, 530
-+                                /* find define for this maxpathcomponent */
-+                                , nls_codepage);
-+              name_len++;     /* trailing null */
-+              name_len *= 2;
-+      } else {                /* BB improve the check for buffer overruns BB */
-+              name_len = strnlen(searchName, 530);
-+              name_len++;     /* trailing null */
-+              strncpy(pSMB->FileName, searchName, name_len);
-+      }
-+
-+      pSMB->TotalParameterCount = 2 /* level */  + 4 /* reserved */  +
-+          name_len /* includes null */ ;
-+      pSMB->TotalDataCount = 0;
-+      pSMB->MaxParameterCount = cpu_to_le16(2);
-+      pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */
-+      pSMB->MaxSetupCount = 0;
-+      pSMB->Reserved = 0;
-+      pSMB->Flags = 0;
-+      pSMB->Timeout = 0;
-+      pSMB->Reserved2 = 0;
-+      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);
-+      pSMB->ByteCount = pSMB->TotalParameterCount + 1 /* pad */ ;
-+      pSMB->TotalParameterCount = cpu_to_le16(pSMB->TotalParameterCount);
-+      pSMB->ParameterCount = pSMB->TotalParameterCount;
-+      pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
-+      pSMB->Reserved4 = 0;
-+      pSMB->hdr.smb_buf_length += pSMB->ByteCount;
-+      pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
-+
-+      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 */
-+              pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
-+              /* BB also check enough total bytes returned */
-+              /* BB we need to improve the validity checking
-+              of these trans2 responses */
-+              if ((pSMBr->ByteCount < 40) || (pSMBr->DataOffset > 512)) 
-+                      rc = -EIO;      /* bad smb */
-+              else if (pFindData){
-+                      memcpy((char *) pFindData,
-+                             (char *) &pSMBr->hdr.Protocol +
-+                             pSMBr->DataOffset, sizeof (FILE_ALL_INFO));
-+              } else
-+                  rc = -ENOMEM;
-+      }
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+      if (rc == -EAGAIN)
-+              goto QPathInfoRetry;
-+
-+      return rc;
-+}
-+
-+int
-+CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon,
-+                   const unsigned char *searchName,
-+                   FILE_UNIX_BASIC_INFO * pFindData,
-+                   const struct nls_table *nls_codepage)
-+{
-+/* 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;
-+
-+      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 =
-+                  cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, 530
-+                                /* find define for this maxpathcomponent */
-+                                , nls_codepage);
-+              name_len++;     /* trailing null */
-+              name_len *= 2;
-+      } else {                /* BB improve the check for buffer overruns BB */
-+              name_len = strnlen(searchName, 530);
-+              name_len++;     /* trailing null */
-+              strncpy(pSMB->FileName, searchName, name_len);
-+      }
-+
-+      pSMB->TotalParameterCount = 2 /* level */  + 4 /* reserved */  +
-+          name_len /* includes null */ ;
-+      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);
-+      pSMB->ByteCount = pSMB->TotalParameterCount + 1 /* pad */ ;
-+      pSMB->TotalParameterCount = cpu_to_le16(pSMB->TotalParameterCount);
-+      pSMB->ParameterCount = pSMB->TotalParameterCount;
-+      pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
-+      pSMB->Reserved4 = 0;
-+      pSMB->hdr.smb_buf_length += pSMB->ByteCount;
-+      pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
-+
-+      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 */
-+              pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
-+              /* BB also check if enough total bytes returned */
-+              if ((pSMBr->ByteCount < sizeof(FILE_UNIX_BASIC_INFO)) || 
-+                      (pSMBr->DataOffset > 512) || 
-+                      (pSMBr->DataOffset < sizeof(struct smb_hdr))) {
-+                      cFYI(1,("UnixQPathinfo invalid data offset %d bytes returned %d",
-+                                      (int)pSMBr->DataOffset,bytes_returned));
-+                      rc = -EIO;      /* bad smb */
-+              } else {
-+                      memcpy((char *) pFindData,
-+                             (char *) &pSMBr->hdr.Protocol +
-+                             pSMBr->DataOffset,
-+                             sizeof (FILE_UNIX_BASIC_INFO));
-+              }
-+      }
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+      if (rc == -EAGAIN)
-+              goto UnixQPathInfoRetry;
-+
-+      return rc;
-+}
-+
-+int
-+CIFSFindSingle(const int xid, struct cifsTconInfo *tcon,
-+             const char *searchName, FILE_ALL_INFO * findData,
-+             const struct nls_table *nls_codepage)
-+{
-+/* level 257 SMB_ */
-+      TRANSACTION2_FFIRST_REQ *pSMB = NULL;
-+      TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
-+      int rc = 0;
-+      int bytes_returned;
-+      int name_len;
-+
-+      cFYI(1, ("In FindUnique"));
-+findUniqueRetry:
-+      rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
-+                    (void **) &pSMBr);
-+      if (rc)
-+              return rc;
-+
-+      if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
-+              name_len =
-+                  cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, 530
-+                                /* find define for this maxpathcomponent */
-+                                , nls_codepage);
-+              name_len++;     /* trailing null */
-+              name_len *= 2;
-+      } else {                /* BB improve the check for buffer overruns BB */
-+              name_len = strnlen(searchName, 530);
-+              name_len++;     /* trailing null */
-+              strncpy(pSMB->FileName, searchName, name_len);
-+      }
-+
-+      pSMB->TotalParameterCount = 12 + name_len /* includes null */ ;
-+      pSMB->TotalDataCount = 0;       /* no EAs */
-+      pSMB->MaxParameterCount = cpu_to_le16(2);
-+      pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */
-+      pSMB->MaxSetupCount = 0;
-+      pSMB->Reserved = 0;
-+      pSMB->Flags = 0;
-+      pSMB->Timeout = 0;
-+      pSMB->Reserved2 = 0;
-+      pSMB->ParameterOffset = cpu_to_le16(
-+        offsetof(struct smb_com_transaction2_ffirst_req,InformationLevel) - 4);
-+      pSMB->DataCount = 0;
-+      pSMB->DataOffset = 0;
-+      pSMB->SetupCount = 1;   /* one byte, no need to le convert */
-+      pSMB->Reserved3 = 0;
-+      pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
-+      pSMB->ByteCount = pSMB->TotalParameterCount + 1 /* pad */ ;
-+      pSMB->TotalParameterCount = cpu_to_le16(pSMB->TotalDataCount);
-+      pSMB->ParameterCount = pSMB->TotalParameterCount;
-+      pSMB->SearchAttributes =
-+          cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
-+                      ATTR_DIRECTORY);
-+      pSMB->SearchCount = cpu_to_le16(16);    /* BB increase */
-+      pSMB->SearchFlags = cpu_to_le16(1);
-+      pSMB->InformationLevel = cpu_to_le16(SMB_FIND_FILE_DIRECTORY_INFO);
-+      pSMB->SearchStorageType = 0;    /* BB what should we set this to? BB */
-+      pSMB->hdr.smb_buf_length += pSMB->ByteCount;
-+      pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
-+
-+      rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
-+                       (struct smb_hdr *) pSMBr, &bytes_returned, 0);
-+
-+      if (rc) {
-+              cFYI(1, ("Send error in FindFileDirInfo = %d", rc));
-+      } else {                /* decode response */
-+
-+              /* BB fill in */
-+      }
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+      if (rc == -EAGAIN)
-+              goto findUniqueRetry;
-+
-+      return rc;
-+}
-+
-+int
-+CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
-+            const char *searchName, FILE_DIRECTORY_INFO * findData,
-+            T2_FFIRST_RSP_PARMS * findParms,
-+            const struct nls_table *nls_codepage, int *pUnicodeFlag,
-+            int *pUnixFlag)
-+{
-+/* level 257 SMB_ */
-+      TRANSACTION2_FFIRST_REQ *pSMB = NULL;
-+      TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
-+      char *response_data;
-+      int rc = 0;
-+      int bytes_returned;
-+      int name_len;
-+
-+      cFYI(1, ("In FindFirst"));
-+findFirstRetry:
-+      rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
-+                    (void **) &pSMBr);
-+      if (rc)
-+              return rc;
-+
-+      if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
-+              name_len =
-+                  cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, 530
-+                                /* find define for this maxpathcomponent */
-+                                , nls_codepage);
-+              name_len++;     /* trailing null */
-+              name_len *= 2;
-+      } else {                /* BB improve the check for buffer overruns BB */
-+              name_len = strnlen(searchName, 530);
-+              name_len++;     /* trailing null */
-+              strncpy(pSMB->FileName, searchName, name_len);
-+      }
-+
-+      pSMB->TotalParameterCount = 12 + name_len /* includes null */ ;
-+      pSMB->TotalDataCount = 0;       /* no EAs */
-+      pSMB->MaxParameterCount = cpu_to_le16(10);
-+      pSMB->MaxDataCount = cpu_to_le16((tcon->ses->server->maxBuf -
-+                                        MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
-+      pSMB->MaxSetupCount = 0;
-+      pSMB->Reserved = 0;
-+      pSMB->Flags = 0;
-+      pSMB->Timeout = 0;
-+      pSMB->Reserved2 = 0;
-+      pSMB->ByteCount = pSMB->TotalParameterCount + 1 /* pad */ ;
-+      pSMB->TotalParameterCount = cpu_to_le16(pSMB->TotalParameterCount);
-+      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(CIFS_MAX_MSGSIZE / sizeof (FILE_DIRECTORY_INFO));       /* should this be shrunk even more ? */
-+      pSMB->SearchFlags = cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME);
-+
-+      /* test for Unix extensions */
-+      if (tcon->ses->capabilities & CAP_UNIX) {
-+              pSMB->InformationLevel = cpu_to_le16(SMB_FIND_FILE_UNIX);
-+              *pUnixFlag = TRUE;
-+      } else {
-+              pSMB->InformationLevel =
-+                  cpu_to_le16(SMB_FIND_FILE_DIRECTORY_INFO);
-+              *pUnixFlag = FALSE;
-+      }
-+      pSMB->SearchStorageType = 0;    /* BB what should we set this to? It is not clear if it matters BB */
-+      pSMB->hdr.smb_buf_length += pSMB->ByteCount;
-+      pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
-+
-+      rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
-+                       (struct smb_hdr *) pSMBr, &bytes_returned, 0);
-+
-+      if (rc) {               /* BB add logic to retry regular search if Unix search rejected unexpectedly by server */
-+              cFYI(1, ("Error in FindFirst = %d", rc));
-+      } else {                /* decode response */
-+              /* BB add safety checks for these memcpys */
-+              if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
-+                      *pUnicodeFlag = TRUE;
-+              else
-+                      *pUnicodeFlag = FALSE;
-+              memcpy(findParms,
-+                     (char *) &pSMBr->hdr.Protocol +
-+                     le16_to_cpu(pSMBr->ParameterOffset),
-+                     sizeof (T2_FFIRST_RSP_PARMS));
-+              /* search handle can stay LE and EAoffset not needed so not converted */
-+              findParms->EndofSearch = le16_to_cpu(findParms->EndofSearch);
-+              findParms->LastNameOffset =
-+                  le16_to_cpu(findParms->LastNameOffset);
-+              findParms->SearchCount = le16_to_cpu(findParms->SearchCount);
-+              response_data =
-+                  (char *) &pSMBr->hdr.Protocol +
-+                  le16_to_cpu(pSMBr->DataOffset);
-+              memcpy(findData, response_data, le16_to_cpu(pSMBr->DataCount));
-+      }
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+
-+      if (rc == -EAGAIN)
-+              goto findFirstRetry;
-+
-+      return rc;
-+}
-+
-+int
-+CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
-+              FILE_DIRECTORY_INFO * findData, T2_FNEXT_RSP_PARMS * findParms,
-+              const __u16 searchHandle, char * resume_file_name, int name_len,
-+              __u32 resume_key, int *pUnicodeFlag, int *pUnixFlag)
-+{
-+/* level 257 SMB_ */
-+      TRANSACTION2_FNEXT_REQ *pSMB = NULL;
-+      TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
-+      char *response_data;
-+      int rc = 0;
-+      int bytes_returned;
-+
-+      cFYI(1, ("In FindNext"));
-+
-+      if(resume_file_name == NULL) {
-+              return -EIO;
-+      }
-+      rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
-+                    (void **) &pSMBr);
-+      if (rc)
-+              return rc;
-+
-+      pSMB->TotalParameterCount = 14; /* includes 2 bytes of null string, converted to LE below */
-+      pSMB->TotalDataCount = 0;       /* no EAs */
-+      pSMB->MaxParameterCount = cpu_to_le16(8);
-+      pSMB->MaxDataCount =
-+          cpu_to_le16((tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
-+      pSMB->MaxSetupCount = 0;
-+      pSMB->Reserved = 0;
-+      pSMB->Flags = 0;
-+      pSMB->Timeout = 0;
-+      pSMB->Reserved2 = 0;
-+      pSMB->ParameterOffset =  cpu_to_le16(offsetof(
-+        struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
-+      pSMB->DataCount = 0;
-+      pSMB->DataOffset = 0;
-+      pSMB->SetupCount = 1;
-+      pSMB->Reserved3 = 0;
-+      pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
-+      pSMB->SearchHandle = searchHandle;      /* always kept as le */
-+      findParms->SearchCount = 0;     /* set to zero in case of error */
-+      pSMB->SearchCount =
-+          cpu_to_le16(CIFS_MAX_MSGSIZE / sizeof (FILE_DIRECTORY_INFO));
-+      /* test for Unix extensions */
-+      if (tcon->ses->capabilities & CAP_UNIX) {
-+              pSMB->InformationLevel = cpu_to_le16(SMB_FIND_FILE_UNIX);
-+              *pUnixFlag = TRUE;
-+      } else {
-+              pSMB->InformationLevel =
-+                  cpu_to_le16(SMB_FIND_FILE_DIRECTORY_INFO);
-+              *pUnixFlag = FALSE;
-+      }
-+      pSMB->ResumeKey = resume_key;
-+      pSMB->SearchFlags =
-+          cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME);
-+      /* BB add check to make sure we do not cross end of smb */
-+      if(name_len < CIFS_MAX_MSGSIZE) {
-+              memcpy(pSMB->ResumeFileName, resume_file_name, name_len);
-+              pSMB->ByteCount += name_len;
-+      }
-+      pSMB->TotalParameterCount += name_len;
-+      pSMB->ByteCount = pSMB->TotalParameterCount + 1 /* pad */ ;
-+      pSMB->TotalParameterCount = cpu_to_le16(pSMB->TotalParameterCount);
-+      pSMB->ParameterCount = pSMB->TotalParameterCount;
-+      /* BB improve error handling here */
-+      pSMB->hdr.smb_buf_length += pSMB->ByteCount;
-+      pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
-+
-+      rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
-+                       (struct smb_hdr *) pSMBr, &bytes_returned, 0);
-+
-+      if (rc) {
-+              if (rc == -EBADF)
-+                      rc = 0; /* search probably was closed at end of search above */
-+              else
-+                      cFYI(1, ("FindNext returned = %d", rc));
-+      } else {                /* decode response */
-+              /* BB add safety checks for these memcpys */
-+              if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
-+                      *pUnicodeFlag = TRUE;
-+              else
-+                      *pUnicodeFlag = FALSE;
-+              memcpy(findParms,
-+                     (char *) &pSMBr->hdr.Protocol +
-+                     le16_to_cpu(pSMBr->ParameterOffset),
-+                     sizeof (T2_FNEXT_RSP_PARMS));
-+              findParms->EndofSearch = le16_to_cpu(findParms->EndofSearch);
-+              findParms->LastNameOffset =
-+                  le16_to_cpu(findParms->LastNameOffset);
-+              findParms->SearchCount = le16_to_cpu(findParms->SearchCount);
-+              response_data =
-+                  (char *) &pSMBr->hdr.Protocol +
-+                  le16_to_cpu(pSMBr->DataOffset);
-+              memcpy(findData, response_data, le16_to_cpu(pSMBr->DataCount));
-+      }
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+
-+      /* Note: On -EAGAIN error only caller can retry on handle based calls
-+              since file handle passed in no longer valid */
-+
-+      return rc;
-+}
-+
-+int
-+CIFSFindClose(const int xid, struct cifsTconInfo *tcon, const __u16 searchHandle)
-+{
-+      int rc = 0;
-+      FINDCLOSE_REQ *pSMB = NULL;
-+      CLOSE_RSP *pSMBr = NULL;
-+      int bytes_returned;
-+
-+      cFYI(1, ("In CIFSSMBFindClose"));
-+      rc = smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **) &pSMB,
-+                    (void **) &pSMBr);
-+      /* no sense returning error if session restarted
-+              file handle has been closed */
-+      if(rc == -EAGAIN)
-+              return 0;
-+      if (rc)
-+              return rc;
-+
-+      pSMB->FileID = searchHandle;
-+      pSMB->ByteCount = 0;
-+      rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
-+                       (struct smb_hdr *) pSMBr, &bytes_returned, 0);
-+      if (rc) {
-+              cERROR(1, ("Send error in FindClose = %d", rc));
-+      }
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+
-+      /* Since session is dead, search handle closed on server already */
-+      if (rc == -EAGAIN)
-+              rc = 0;
-+
-+      return rc;
-+}
-+
-+int
-+CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
-+              const unsigned char *searchName,
-+              unsigned char **targetUNCs,
-+              unsigned int *number_of_UNC_in_array,
-+              const struct nls_table *nls_codepage)
-+{
-+/* TRANS2_GET_DFS_REFERRAL */
-+      TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
-+      TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
-+      struct dfs_referral_level_3 * referrals = NULL;
-+      int rc = 0;
-+      int bytes_returned;
-+      int name_len;
-+      unsigned int i;
-+      char * temp;
-+      *number_of_UNC_in_array = 0;
-+      *targetUNCs = 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;
-+
-+      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 =
-+                  cifs_strtoUCS((wchar_t *) pSMB->RequestFileName,
-+                                searchName, 530
-+                                /* find define for this maxpathcomponent */
-+                                , nls_codepage);
-+              name_len++;     /* trailing null */
-+              name_len *= 2;
-+      } else {                /* BB improve the check for buffer overruns BB */
-+              name_len = strnlen(searchName, 530);
-+              name_len++;     /* trailing null */
-+              strncpy(pSMB->RequestFileName, searchName, name_len);
-+      }
-+
-+      pSMB->ParameterCount = 2 /* level */  + name_len /*includes null */ ;
-+      pSMB->TotalDataCount = 0;
-+      pSMB->DataCount = 0;
-+      pSMB->DataOffset = 0;
-+      pSMB->MaxParameterCount = 0;
-+      pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */
-+      pSMB->MaxSetupCount = 0;
-+      pSMB->Reserved = 0;
-+      pSMB->Flags = 0;
-+      pSMB->Timeout = 0;
-+      pSMB->Reserved2 = 0;
-+      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);
-+      pSMB->ByteCount = pSMB->ParameterCount + 3 /* pad */ ;
-+      pSMB->ParameterCount = cpu_to_le16(pSMB->ParameterCount);
-+      pSMB->TotalParameterCount = pSMB->ParameterCount;
-+      pSMB->MaxReferralLevel = cpu_to_le16(3);
-+      pSMB->hdr.smb_buf_length += pSMB->ByteCount;
-+      pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
-+
-+      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));
-+      } else {                /* decode response */
-+/* BB Add logic to parse referrals here */
-+              pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
-+              pSMBr->DataCount = le16_to_cpu(pSMBr->DataCount);
-+              cFYI(1,
-+                   ("Decoding GetDFSRefer response.  BCC: %d  Offset %d",
-+                    pSMBr->ByteCount, pSMBr->DataOffset));
-+              if ((pSMBr->ByteCount < 17) || (pSMBr->DataOffset > 512))       /* BB also check enough total bytes returned */
-+                      rc = -EIO;      /* bad smb */
-+              else {
-+                      referrals = 
-+                          (struct dfs_referral_level_3 *) 
-+                                      (8 /* sizeof start of data block */ +
-+                                      pSMBr->DataOffset +
-+                                      (char *) &pSMBr->hdr.Protocol); 
-+                      cFYI(1,("num_referrals: %d dfs flags: 0x%x ... \nfor referral one refer size: 0x%x srv type: 0x%x refer flags: 0x%x ttl: 0x%x",pSMBr->NumberOfReferrals,pSMBr->DFSFlags, referrals->ReferralSize,referrals->ServerType,referrals->ReferralFlags,referrals->TimeToLive));
-+                      /* BB This field is actually two bytes in from start of
-+                         data block so we could do safety check that DataBlock
-+                         begins at address of pSMBr->NumberOfReferrals */
-+                      *number_of_UNC_in_array = le16_to_cpu(pSMBr->NumberOfReferrals);
-+
-+                      /* BB Fix below so can return more than one referral */
-+                      if(*number_of_UNC_in_array > 1)
-+                              *number_of_UNC_in_array = 1;
-+
-+                      /* get the length of the strings describing refs */
-+                      name_len = 0;
-+                      for(i=0;i<*number_of_UNC_in_array;i++) {
-+                              /* make sure that DfsPathOffset not past end */
-+                              referrals->DfsPathOffset = le16_to_cpu(referrals->DfsPathOffset);
-+                              if(referrals->DfsPathOffset > pSMBr->DataCount) {
-+                                      /* if invalid referral, stop here and do 
-+                                      not try to copy any more */
-+                                      *number_of_UNC_in_array = i;
-+                                      break;
-+                              } 
-+                              temp = ((char *)referrals) + referrals->DfsPathOffset;
-+
-+                              if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
-+                                      name_len += UniStrnlen((wchar_t *)temp,pSMBr->DataCount);
-+                              } else {
-+                                      name_len += strnlen(temp,pSMBr->DataCount);
-+                              }
-+                              referrals++;
-+                              /* BB add check that referral pointer does not fall off end PDU */
-+                              
-+                      }
-+                      /* BB add check for name_len bigger than bcc */
-+                      *targetUNCs = 
-+                              kmalloc(name_len+1+ (*number_of_UNC_in_array),GFP_KERNEL);
-+                      /* copy the ref strings */
-+                      referrals =  
-+                          (struct dfs_referral_level_3 *) 
-+                                      (8 /* sizeof data hdr */ +
-+                                      pSMBr->DataOffset + 
-+                                      (char *) &pSMBr->hdr.Protocol);
-+
-+                      for(i=0;i<*number_of_UNC_in_array;i++) {
-+                              temp = ((char *)referrals) + referrals->DfsPathOffset;
-+                              if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
-+                                      cifs_strfromUCS_le(*targetUNCs,
-+                                              (wchar_t *) temp, name_len, nls_codepage);
-+                              } else {
-+                                      strncpy(*targetUNCs,temp,name_len);
-+                              }
-+                              /*  BB update target_uncs pointers */
-+                              referrals++;
-+                      }
-+                      temp = *targetUNCs;
-+                      temp[name_len] = 0;
-+              }
-+
-+      }
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+
-+      if (rc == -EAGAIN)
-+              goto getDFSRetry;
-+
-+      return rc;
-+}
-+
-+int
-+CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon,
-+             struct statfs *FSData, const struct nls_table *nls_codepage)
-+{
-+/* 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;
-+
-+      cFYI(1, ("In QFSInfo"));
-+QFSInfoRetry:
-+      rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
-+                    (void **) &pSMBr);
-+      if (rc)
-+              return rc;
-+
-+      pSMB->TotalParameterCount = 2;  /* level */
-+      pSMB->TotalDataCount = 0;
-+      pSMB->MaxParameterCount = cpu_to_le16(2);
-+      pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */
-+      pSMB->MaxSetupCount = 0;
-+      pSMB->Reserved = 0;
-+      pSMB->Flags = 0;
-+      pSMB->Timeout = 0;
-+      pSMB->Reserved2 = 0;
-+      pSMB->ByteCount = pSMB->TotalParameterCount + 1 /* pad */ ;
-+      pSMB->TotalParameterCount = cpu_to_le16(pSMB->TotalParameterCount);
-+      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);
-+      pSMB->hdr.smb_buf_length += pSMB->ByteCount;
-+      pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
-+
-+      rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
-+                       (struct smb_hdr *) pSMBr, &bytes_returned, 0);
-+      if (rc) {
-+              cERROR(1, ("Send error in QFSInfo = %d", rc));
-+      } else {                /* decode response */
-+              pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
-+              cFYI(1,
-+                   ("Decoding qfsinfo response.  BCC: %d  Offset %d",
-+                    pSMBr->ByteCount, pSMBr->DataOffset));
-+              if ((pSMBr->ByteCount < 24) || (pSMBr->DataOffset > 512))       /* BB also check enough total bytes returned */
-+                      rc = -EIO;      /* bad smb */
-+              else {
-+                      response_data =
-+                          (FILE_SYSTEM_INFO
-+                           *) (((char *) &pSMBr->hdr.Protocol) +
-+                               pSMBr->DataOffset);
-+                      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));
-+              }
-+      }
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+
-+      if (rc == -EAGAIN)
-+              goto QFSInfoRetry;
-+
-+      return rc;
-+}
-+
-+int
-+CIFSSMBQFSAttributeInfo(int xid, struct cifsTconInfo *tcon,
-+                      const struct nls_table *nls_codepage)
-+{
-+/* 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;
-+
-+      cFYI(1, ("In QFSAttributeInfo"));
-+QFSAttributeRetry:
-+      rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
-+                    (void **) &pSMBr);
-+      if (rc)
-+              return rc;
-+
-+      pSMB->TotalParameterCount = 2;  /* level */
-+      pSMB->TotalDataCount = 0;
-+      pSMB->MaxParameterCount = cpu_to_le16(2);
-+      pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */
-+      pSMB->MaxSetupCount = 0;
-+      pSMB->Reserved = 0;
-+      pSMB->Flags = 0;
-+      pSMB->Timeout = 0;
-+      pSMB->Reserved2 = 0;
-+      pSMB->ByteCount = pSMB->TotalParameterCount + 1 /* pad */ ;
-+      pSMB->TotalParameterCount = cpu_to_le16(pSMB->TotalParameterCount);
-+      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);
-+      pSMB->hdr.smb_buf_length += pSMB->ByteCount;
-+      pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
-+
-+      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 */
-+              pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
-+              if ((pSMBr->ByteCount < 13) || (pSMBr->DataOffset > 512)) {     /* BB also check enough bytes returned */
-+                      rc = -EIO;      /* bad smb */
-+              } else {
-+                      response_data =
-+                          (FILE_SYSTEM_ATTRIBUTE_INFO
-+                           *) (((char *) &pSMBr->hdr.Protocol) +
-+                               pSMBr->DataOffset);
-+                      response_data->Attributes = le32_to_cpu(response_data->Attributes);
-+                      response_data->MaxPathNameComponentLength = 
-+                              le32_to_cpu(response_data->MaxPathNameComponentLength);
-+                      response_data->FileSystemNameLen = 
-+                              le32_to_cpu(response_data->FileSystemNameLen);
-+                      memcpy(&tcon->fsAttrInfo, response_data,
-+                             sizeof (FILE_SYSTEM_ATTRIBUTE_INFO));
-+              }
-+      }
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+
-+      if (rc == -EAGAIN)
-+              goto QFSAttributeRetry;
-+
-+      return rc;
-+}
-+
-+int
-+CIFSSMBQFSDeviceInfo(int xid, struct cifsTconInfo *tcon,
-+                   const struct nls_table *nls_codepage)
-+{
-+/* 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;
-+
-+      cFYI(1, ("In QFSDeviceInfo"));
-+QFSDeviceRetry:
-+      rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
-+                    (void **) &pSMBr);
-+      if (rc)
-+              return rc;
-+
-+      pSMB->TotalParameterCount = 2;  /* level */
-+      pSMB->TotalDataCount = 0;
-+      pSMB->MaxParameterCount = cpu_to_le16(2);
-+      pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */
-+      pSMB->MaxSetupCount = 0;
-+      pSMB->Reserved = 0;
-+      pSMB->Flags = 0;
-+      pSMB->Timeout = 0;
-+      pSMB->Reserved2 = 0;
-+      pSMB->ByteCount = pSMB->TotalParameterCount + 1 /* pad */ ;
-+      pSMB->TotalParameterCount = cpu_to_le16(pSMB->TotalParameterCount);
-+      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);
-+      pSMB->hdr.smb_buf_length += pSMB->ByteCount;
-+      pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
-+
-+      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 */
-+              pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
-+              if ((pSMBr->ByteCount < sizeof (FILE_SYSTEM_DEVICE_INFO))
-+                 || (pSMBr->DataOffset > 512))
-+                      rc = -EIO;      /* bad smb */
-+              else {
-+                      response_data =
-+                          (FILE_SYSTEM_DEVICE_INFO
-+                           *) (((char *) &pSMBr->hdr.Protocol) +
-+                               pSMBr->DataOffset);
-+                      response_data->DeviceType = 
-+                              le32_to_cpu(response_data->DeviceType);
-+                      response_data->DeviceCharacteristics = 
-+                              le32_to_cpu(response_data->DeviceCharacteristics);
-+                      memcpy(&tcon->fsDevInfo, response_data,
-+                             sizeof (FILE_SYSTEM_DEVICE_INFO));
-+              }
-+      }
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+
-+      if (rc == -EAGAIN)
-+              goto QFSDeviceRetry;
-+
-+      return rc;
-+}
-+
-+int
-+CIFSSMBQFSUnixInfo(int xid, struct cifsTconInfo *tcon,
-+                 const struct nls_table *nls_codepage)
-+{
-+/* 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;
-+
-+      cFYI(1, ("In QFSUnixInfo"));
-+QFSUnixRetry:
-+      rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
-+                    (void **) &pSMBr);
-+      if (rc)
-+              return rc;
-+
-+      pSMB->ParameterCount = 2;       /* level */
-+      pSMB->TotalDataCount = 0;
-+      pSMB->DataCount = 0;
-+      pSMB->DataOffset = 0;
-+      pSMB->MaxParameterCount = cpu_to_le16(2);
-+      pSMB->MaxDataCount = cpu_to_le16(100);  /* BB find exact max SMB PDU from sess structure BB */
-+      pSMB->MaxSetupCount = 0;
-+      pSMB->Reserved = 0;
-+      pSMB->Flags = 0;
-+      pSMB->Timeout = 0;
-+      pSMB->Reserved2 = 0;
-+      pSMB->ByteCount = pSMB->ParameterCount + 1 /* pad */ ;
-+      pSMB->ParameterCount = cpu_to_le16(pSMB->ParameterCount);
-+      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);
-+      pSMB->hdr.smb_buf_length += pSMB->ByteCount;
-+      pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
-+
-+      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 */
-+              pSMBr->DataOffset = cpu_to_le16(pSMBr->DataOffset);
-+              if ((pSMBr->ByteCount < 13) || (pSMBr->DataOffset > 512)) {
-+                      rc = -EIO;      /* bad smb */
-+              } else {
-+                      response_data =
-+                          (FILE_SYSTEM_UNIX_INFO
-+                           *) (((char *) &pSMBr->hdr.Protocol) +
-+                               pSMBr->DataOffset);
-+                      response_data->MajorVersionNumber =
-+                              le16_to_cpu(response_data->MajorVersionNumber);
-+                      response_data->MinorVersionNumber =
-+                              le16_to_cpu(response_data->MinorVersionNumber);
-+                      response_data->Capability =
-+                              le64_to_cpu(response_data->Capability);
-+                      memcpy(&tcon->fsUnixInfo, response_data,
-+                             sizeof (FILE_SYSTEM_UNIX_INFO));
-+              }
-+      }
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+
-+      if (rc == -EAGAIN)
-+              goto QFSUnixRetry;
-+
-+
-+      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(int xid, struct cifsTconInfo *tcon, char *fileName,
-+            __u64 size, int SetAllocation, const struct nls_table *nls_codepage)
-+{
-+      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;
-+
-+      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 =
-+                  cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, 530
-+                                /* find define for this maxpathcomponent */
-+                                , nls_codepage);
-+              name_len++;     /* trailing null */
-+              name_len *= 2;
-+      } else {                /* BB improve the check for buffer overruns BB */
-+              name_len = strnlen(fileName, 530);
-+              name_len++;     /* trailing null */
-+              strncpy(pSMB->FileName, fileName, name_len);
-+      }
-+      pSMB->ParameterCount = 6 + name_len;
-+      pSMB->DataCount = sizeof (struct file_end_of_file_info);
-+      pSMB->MaxParameterCount = cpu_to_le16(2);
-+      pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB size from sess */
-+      pSMB->MaxSetupCount = 0;
-+      pSMB->Reserved = 0;
-+      pSMB->Flags = 0;
-+      pSMB->Timeout = 0;
-+      pSMB->Reserved2 = 0;
-+      pSMB->ParameterOffset = offsetof(struct smb_com_transaction2_spi_req,
-+                                     InformationLevel) - 4;
-+      pSMB->DataOffset = pSMB->ParameterOffset + pSMB->ParameterCount;
-+      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) +
-+                                     pSMB->DataOffset);
-+      pSMB->ParameterOffset = cpu_to_le16(pSMB->ParameterOffset);
-+      pSMB->DataOffset = cpu_to_le16(pSMB->DataOffset);
-+      pSMB->SetupCount = 1;
-+      pSMB->Reserved3 = 0;
-+      pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
-+      pSMB->ByteCount = 3 /* pad */  + pSMB->ParameterCount + pSMB->DataCount;
-+      pSMB->DataCount = cpu_to_le16(pSMB->DataCount);
-+      pSMB->TotalDataCount = pSMB->DataCount;
-+      pSMB->ParameterCount = cpu_to_le16(pSMB->ParameterCount);
-+      pSMB->TotalParameterCount = pSMB->ParameterCount;
-+      pSMB->Reserved4 = 0;
-+      pSMB->hdr.smb_buf_length += pSMB->ByteCount;
-+      parm_data->FileSize = cpu_to_le64(size);
-+      pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
-+      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));
-+      }
-+
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+
-+      if (rc == -EAGAIN)
-+              goto SetEOFRetry;
-+
-+      return rc;
-+}
-+
-+int
-+CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size, 
-+                   __u16 fid, __u32 pid_of_opener, int SetAllocation)
-+{
-+      struct smb_com_transaction2_sfi_req *pSMB  = NULL;
-+      struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
-+      char *data_offset;
-+      struct file_end_of_file_info *parm_data;
-+      int rc = 0;
-+      int bytes_returned = 0;
-+      __u32 tmp;
-+
-+      cFYI(1, ("SetFileSize (via SetFileInfo) %lld",
-+                      (long long)size));
-+      rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
-+                    (void **) &pSMBr);
-+      if (rc)
-+              return rc;
-+
-+      tmp = cpu_to_le32(pid_of_opener);  /* override pid of current process
-+                                         so network fid will be valid */
-+      pSMB->hdr.Pid = tmp & 0xFFFF;
-+      tmp >>= 16;
-+      pSMB->hdr.PidHigh = tmp & 0xFFFF;
-+    
-+      pSMB->ParameterCount = 6;
-+      pSMB->MaxSetupCount = 0;
-+      pSMB->Reserved = 0;
-+      pSMB->Flags = 0;
-+      pSMB->Timeout = 0;
-+      pSMB->Reserved2 = 0;
-+      pSMB->ParameterOffset = offsetof(struct smb_com_transaction2_sfi_req,
-+                                     Fid) - 4;
-+      pSMB->DataOffset = pSMB->ParameterOffset + pSMB->ParameterCount;
-+
-+      data_offset = (char *) (&pSMB->hdr.Protocol) + pSMB->DataOffset;        
-+
-+      pSMB->DataCount = sizeof(struct file_end_of_file_info);
-+      pSMB->MaxParameterCount = cpu_to_le16(2);
-+      pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */
-+      pSMB->SetupCount = 1;
-+      pSMB->Reserved3 = 0;
-+      pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
-+      pSMB->ByteCount = 3 /* pad */  + pSMB->ParameterCount + pSMB->DataCount;
-+      pSMB->DataCount = cpu_to_le16(pSMB->DataCount);
-+      pSMB->ParameterCount = cpu_to_le16(pSMB->ParameterCount);
-+      pSMB->TotalDataCount = pSMB->DataCount;
-+      pSMB->TotalParameterCount = pSMB->ParameterCount;
-+      pSMB->ParameterOffset = cpu_to_le16(pSMB->ParameterOffset);
-+      parm_data =
-+              (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
-+                      pSMB->DataOffset);
-+      pSMB->DataOffset = cpu_to_le16(pSMB->DataOffset); /* now safe to change to le */
-+      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;
-+      pSMB->hdr.smb_buf_length += pSMB->ByteCount;
-+      pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
-+      rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
-+                       (struct smb_hdr *) pSMBr, &bytes_returned, 0);
-+      if (rc) {
-+              cFYI(1,
-+                   ("Send error in SetFileInfo (SetFileSize) = %d",
-+                    rc));
-+      }
-+
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+
-+      /* Note: On -EAGAIN error only caller can retry on handle based calls 
-+              since file handle passed in no longer valid */
-+
-+      return rc;
-+}
-+
-+int
-+CIFSSMBSetTimes(int xid, struct cifsTconInfo *tcon, char *fileName,
-+              FILE_BASIC_INFO * data, const struct nls_table *nls_codepage)
-+{
-+      TRANSACTION2_SPI_REQ *pSMB = NULL;
-+      TRANSACTION2_SPI_RSP *pSMBr = NULL;
-+      int name_len;
-+      int rc = 0;
-+      int bytes_returned = 0;
-+      char *data_offset;
-+
-+      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 =
-+                  cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, 530
-+                                /* find define for this maxpathcomponent */
-+                                , nls_codepage);
-+              name_len++;     /* trailing null */
-+              name_len *= 2;
-+      } else {                /* BB improve the check for buffer overruns BB */
-+              name_len = strnlen(fileName, 530);
-+              name_len++;     /* trailing null */
-+              strncpy(pSMB->FileName, fileName, name_len);
-+      }
-+
-+      pSMB->ParameterCount = 6 + name_len;
-+      pSMB->DataCount = sizeof (FILE_BASIC_INFO);
-+      pSMB->MaxParameterCount = cpu_to_le16(2);
-+      pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */
-+      pSMB->MaxSetupCount = 0;
-+      pSMB->Reserved = 0;
-+      pSMB->Flags = 0;
-+      pSMB->Timeout = 0;
-+      pSMB->Reserved2 = 0;
-+      pSMB->ParameterOffset = offsetof(struct smb_com_transaction2_spi_req,
-+                                     InformationLevel) - 4;
-+      pSMB->DataOffset = pSMB->ParameterOffset + pSMB->ParameterCount;
-+      data_offset = (char *) (&pSMB->hdr.Protocol) + pSMB->DataOffset;
-+      pSMB->ParameterOffset = cpu_to_le16(pSMB->ParameterOffset);
-+      pSMB->DataOffset = cpu_to_le16(pSMB->DataOffset);
-+      pSMB->SetupCount = 1;
-+      pSMB->Reserved3 = 0;
-+      pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
-+      pSMB->ByteCount = 3 /* pad */  + pSMB->ParameterCount + pSMB->DataCount;
-+
-+      pSMB->DataCount = cpu_to_le16(pSMB->DataCount);
-+      pSMB->ParameterCount = cpu_to_le16(pSMB->ParameterCount);
-+      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;
-+      pSMB->hdr.smb_buf_length += pSMB->ByteCount;
-+      memcpy(data_offset, data, sizeof (FILE_BASIC_INFO));
-+      pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
-+      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));
-+      }
-+
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+
-+      if (rc == -EAGAIN)
-+              goto SetTimesRetry;
-+
-+      return rc;
-+}
-+
-+int
-+CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon,
-+                  char *fileName, __u64 mode, __u64 uid, __u64 gid,
-+                  dev_t device, const struct nls_table *nls_codepage)
-+{
-+      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;
-+
-+      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 =
-+                  cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, 530
-+                                /* find define for this maxpathcomponent */
-+                                , nls_codepage);
-+              name_len++;     /* trailing null */
-+              name_len *= 2;
-+      } else {                /* BB improve the check for buffer overruns BB */
-+              name_len = strnlen(fileName, 530);
-+              name_len++;     /* trailing null */
-+              strncpy(pSMB->FileName, fileName, name_len);
-+      }
-+
-+      pSMB->ParameterCount = 6 + name_len;
-+      pSMB->DataCount = sizeof (FILE_UNIX_BASIC_INFO);
-+      pSMB->MaxParameterCount = cpu_to_le16(2);
-+      pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */
-+      pSMB->MaxSetupCount = 0;
-+      pSMB->Reserved = 0;
-+      pSMB->Flags = 0;
-+      pSMB->Timeout = 0;
-+      pSMB->Reserved2 = 0;
-+      pSMB->ParameterOffset = offsetof(struct smb_com_transaction2_spi_req,
-+                                     InformationLevel) - 4;
-+      pSMB->DataOffset = pSMB->ParameterOffset + pSMB->ParameterCount;
-+      data_offset =
-+          (FILE_UNIX_BASIC_INFO *) ((char *) &pSMB->hdr.Protocol +
-+                                    pSMB->DataOffset);
-+      pSMB->DataOffset = cpu_to_le16(pSMB->DataOffset);
-+      pSMB->ParameterOffset = cpu_to_le16(pSMB->ParameterOffset);
-+      pSMB->SetupCount = 1;
-+      pSMB->Reserved3 = 0;
-+      pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
-+      pSMB->ByteCount = 3 /* pad */  + pSMB->ParameterCount + pSMB->DataCount;
-+      pSMB->ParameterCount = cpu_to_le16(pSMB->ParameterCount);
-+      pSMB->DataCount = cpu_to_le16(pSMB->DataCount);
-+      pSMB->TotalParameterCount = pSMB->ParameterCount;
-+      pSMB->TotalDataCount = pSMB->DataCount;
-+      pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
-+      pSMB->Reserved4 = 0;
-+      pSMB->hdr.smb_buf_length += pSMB->ByteCount;
-+      data_offset->Uid = cpu_to_le64(uid);
-+      data_offset->Gid = cpu_to_le64(gid);
-+      /* better to leave device as zero when it is  */
-+      data_offset->DevMajor = cpu_to_le64(MAJOR(device));
-+      data_offset->DevMinor = cpu_to_le64(MINOR(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);
-+
-+
-+      pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
-+      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));
-+      }
-+
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+      if (rc == -EAGAIN)
-+              goto setPermsRetry;
-+      return rc;
-+}
-+
-+int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon, 
-+                      const int notify_subdirs, const __u16 netfid,
-+                      __u32 filter, const struct nls_table *nls_codepage)
-+{
-+      int rc = 0;
-+      struct smb_com_transaction_change_notify_req * pSMB = NULL;
-+      struct smb_com_transaction_change_notify_rsp * pSMBr = NULL;
-+      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);
-+      /* BB find exact data count max from sess structure BB */
-+      pSMB->MaxDataCount = 0; /* same in little endian or be */
-+      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;
-+
-+      pSMB->hdr.smb_buf_length += pSMB->ByteCount;
-+      rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
-+                      (struct smb_hdr *) pSMBr, &bytes_returned, 0);
-+      if (rc) {
-+              cFYI(1, ("Error in Notify = %d", rc));
-+      }
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+/*            if (rc == -EAGAIN)
-+                      goto NotifyRetry; */
-+      return rc;      
-+}
-+#ifdef CONFIG_CIFS_XATTR
-+int
-+CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
-+               const unsigned char *searchName,
-+               char * EAData, size_t size,
-+               const struct nls_table *nls_codepage)
-+{
-+              /* BB assumes one setup word */
-+      TRANSACTION2_QPI_REQ *pSMB = NULL;
-+      TRANSACTION2_QPI_RSP *pSMBr = NULL;
-+      int rc = 0;
-+      int bytes_returned;
-+      int name_len;
-+
-+      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) {
-+              name_len =
-+                  cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, 530
-+                                /* find define for this maxpathcomponent */
-+                                , nls_codepage);
-+              name_len++;     /* trailing null */
-+              name_len *= 2;
-+      } else {                /* BB improve the check for buffer overruns BB */
-+              name_len = strnlen(searchName, 530);
-+              name_len++;     /* trailing null */
-+              strncpy(pSMB->FileName, searchName, name_len);
-+      }
-+
-+      pSMB->TotalParameterCount = 2 /* level */  + 4 /* reserved */  +
-+          name_len /* includes null */ ;
-+      pSMB->TotalDataCount = 0;
-+      pSMB->MaxParameterCount = cpu_to_le16(2);
-+      pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */
-+      pSMB->MaxSetupCount = 0;
-+      pSMB->Reserved = 0;
-+      pSMB->Flags = 0;
-+      pSMB->Timeout = 0;
-+      pSMB->Reserved2 = 0;
-+      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);
-+      pSMB->ByteCount = pSMB->TotalParameterCount + 1 /* pad */ ;
-+      pSMB->TotalParameterCount = cpu_to_le16(pSMB->TotalParameterCount);
-+      pSMB->ParameterCount = pSMB->TotalParameterCount;
-+      pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
-+      pSMB->Reserved4 = 0;
-+      pSMB->hdr.smb_buf_length += pSMB->ByteCount;
-+      pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
-+
-+      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));
-+      } else {                /* decode response */
-+              pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
-+              /* BB also check enough total bytes returned */
-+              /* BB we need to improve the validity checking
-+              of these trans2 responses */
-+              if ((pSMBr->ByteCount < 4) || (pSMBr->DataOffset > 512)) 
-+                      rc = -EIO;      /* bad smb */
-+         /* else if (pFindData){
-+                      memcpy((char *) pFindData,
-+                             (char *) &pSMBr->hdr.Protocol +
-+                             pSMBr->DataOffset, kl);
-+              }*/ else {
-+                      /* 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 */
-+                      struct fealist * ea_response_data;
-+                      rc = 0;
-+                      /* validate_trans2_offsets() */
-+                      /* BB to check if(start of smb + pSMBr->DataOffset > &bcc+ bcc)*/
-+                      ea_response_data = (struct fealist *)
-+                              (((char *) &pSMBr->hdr.Protocol) +
-+                              pSMBr->DataOffset);
-+                      cFYI(1,("ea length %d",ea_response_data->list_len));
-+              }
-+      }
-+      if (pSMB)
-+              cifs_buf_release(pSMB);
-+      if (rc == -EAGAIN)
-+              goto QAllEAsRetry;
-+
-+      return rc;
-+}
-+#endif
---- /dev/null
-+++ b/fs/cifs/cifs_unicode.c
-@@ -0,0 +1,87 @@
-+/*
-+ *   fs/cifs/cifs_unicode.c
-+ *
-+ *   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
-+ */
-+#include <linux/fs.h>
-+#include "cifs_unicode.h"
-+#include "cifs_uniupr.h"
-+#include "cifspdu.h"
-+#include "cifs_debug.h"
-+
-+/*
-+ * NAME:      cifs_strfromUCS()
-+ *
-+ * FUNCTION:  Convert little-endian unicode string to character string
-+ *
-+ */
-+int
-+cifs_strfromUCS_le(char *to, const wchar_t * from,    /* LITTLE ENDIAN */
-+                 int len, const struct nls_table *codepage)
-+{
-+      int i;
-+      int outlen = 0;
-+
-+      for (i = 0; (i < len) && from[i]; i++) {
-+              int charlen;
-+              /* 2.4.0 kernel or greater */
-+              charlen =
-+                  codepage->uni2char(le16_to_cpu(from[i]), &to[outlen],
-+                                     NLS_MAX_CHARSET_SIZE);
-+              if (charlen > 0) {
-+                      outlen += charlen;
-+              } else {
-+                      to[outlen++] = '?';
-+              }
-+      }
-+      to[outlen] = 0;
-+      return outlen;
-+}
-+
-+/*
-+ * NAME:      cifs_strtoUCS()
-+ *
-+ * FUNCTION:  Convert character string to unicode string
-+ *
-+ */
-+int
-+cifs_strtoUCS(wchar_t * to, const char *from, int len,
-+            const struct nls_table *codepage)
-+{
-+      int charlen;
-+      int i;
-+
-+      for (i = 0; len && *from; i++, from += charlen, len -= charlen) {
-+
-+              /* works for 2.4.0 kernel or later */
-+              charlen = codepage->char2uni(from, len, &to[i]);
-+              if (charlen < 1) {
-+                      cERROR(1,
-+                             ("cifs_strtoUCS: char2uni returned %d",
-+                              charlen));
-+                      to[i] = cpu_to_le16(0x003f);    /* a question mark */
-+                      charlen = 1;
-+              }
-+              to[i] = cpu_to_le16(to[i]);
-+
-+      }
-+
-+      to[i] = 0;
-+      return i;
-+}
-+
---- /dev/null
-+++ b/fs/cifs/cifs_unicode.h
-@@ -0,0 +1,353 @@
-+/*
-+ * 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,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
-+ *
-+ *
-+ * 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.
-+ *
-+ */
-+
-+#include <asm/byteorder.h>
-+#include <linux/types.h>
-+#include <linux/nls.h>
-+
-+#define  UNIUPR_NOLOWER               /* Example to not expand lower case tables */
-+
-+/* 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 UniLowerTable[512];
-+extern struct UniCaseRange UniLowerRange[];
-+#endif                                /* UNIUPR_NOLOWER */
-+
-+#ifdef __KERNEL__
-+int cifs_strfromUCS_le(char *, const wchar_t *, int, const struct nls_table *);
-+int cifs_strtoUCS(wchar_t *, const char *, int, const struct nls_table *);
-+#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(wchar_t uc)
-+{
-+      register struct UniCaseRange *rp;
-+
-+      if (uc < sizeof (UniLowerTable)) {      /* Latin characters */
-+              return uc + UniLowerTable[uc];  /* Use base tables */
-+      } else {
-+              rp = UniLowerRange;     /* 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
---- /dev/null
-+++ b/fs/cifs/cifs_uniupr.h
-@@ -0,0 +1,253 @@
-+/*
-+ *   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, 0, NULL}
-+};
-+#endif
-+
-+#ifndef UNIUPR_NOLOWER
-+/*
-+ * Latin lower case
-+ */
-+static 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 static struct UniCaseRange CifsUniLowerRange[] = {
-+      0x0380, 0x03ab, UniCaseRangeL0380,
-+      0x0400, 0x042f, UniCaseRangeL0400,
-+      0x0490, 0x04cb, UniCaseRangeL0490,
-+      0x1e00, 0x1ff7, UniCaseRangeL1e00,
-+      0xff20, 0xff3a, UniCaseRangeLff20,
-+      0, 0, 0
-+};
-+#endif
---- /dev/null
-+++ b/fs/cifs/connect.c
-@@ -0,0 +1,2924 @@
-+/*
-+ *   fs/cifs/connect.c
-+ *
-+ *   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.
-+ *
-+ *   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/version.h>
-+#include <linux/ipv6.h>
-+#include <linux/pagemap.h>
-+#include <linux/ctype.h>
-+#include <linux/utsname.h>
-+#include <asm/uaccess.h>
-+#include <asm/processor.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"
-+
-+#define CIFS_PORT 445
-+#define RFC1001_PORT 139
-+
-+extern void SMBencrypt(unsigned char *passwd, unsigned char *c8,
-+                     unsigned char *p24);
-+extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
-+                       unsigned char *p24);
-+extern int cifs_inet_pton(int, const char *, void *dst);
-+
-+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[16]; /* netbios name of client */
-+      uid_t linux_uid;
-+      gid_t linux_gid;
-+      mode_t file_mode;
-+      mode_t dir_mode;
-+      int rw:1;
-+      int retry:1;
-+      int intr:1;
-+      unsigned int rsize;
-+      unsigned int wsize;
-+      unsigned int sockopt;
-+      unsigned short int port;
-+};
-+
-+static int ipv4_connect(struct sockaddr_in *psin_server, 
-+                      struct socket **csocket,
-+                      char * netb_name);
-+static int ipv6_connect(struct sockaddr_in6 *psin_server, 
-+                      struct socket **csocket);
-+
-+
-+      /* 
-+       * 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)
-+       */
-+
-+int
-+cifs_reconnect(struct TCP_Server_Info *server)
-+{
-+      int rc = 0;
-+      struct list_head *tmp;
-+      struct cifsSesInfo *ses;
-+      struct cifsTconInfo *tcon;
-+      struct mid_q_entry * mid_entry;
-+      
-+      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 */
-+      read_lock(&GlobalSMBSeslock);
-+      list_for_each(tmp, &GlobalSMBSessionList) {
-+              ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
-+              if (ses->server) {
-+                      if (ses->server == server) {
-+                              ses->status = CifsNeedReconnect;
-+                              ses->ipc_tid = 0;
-+                      }
-+              }
-+              /* else tcp and smb sessions need reconnection */
-+      }
-+      list_for_each(tmp, &GlobalTreeConnectionList) {
-+              tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
-+              if((tcon) && (tcon->ses) && (tcon->ses->server == server)) {
-+                      tcon->tidStatus = CifsNeedReconnect;
-+              }
-+      }
-+      read_unlock(&GlobalSMBSeslock);
-+      /* do not want to be sending data on a socket we are freeing */
-+      down(&server->tcpSem); 
-+      if(server->ssocket) {
-+              cFYI(1,("State: 0x%x Flags: 0x%lx", server->ssocket->state,
-+                      server->ssocket->flags));
-+              server->ssocket->ops->shutdown(server->ssocket,SEND_SHUTDOWN);
-+              cFYI(1,("Post shutdown state: 0x%x Flags: 0x%lx", server->ssocket->state,
-+                      server->ssocket->flags));
-+              sock_release(server->ssocket);
-+              server->ssocket = NULL;
-+      }
-+
-+      spin_lock(&GlobalMid_Lock);
-+      list_for_each(tmp, &server->pending_mid_q) {
-+              mid_entry = list_entry(tmp, struct
-+                                      mid_q_entry,
-+                                      qhead);
-+              if(mid_entry) {
-+                      if(mid_entry->midState == MID_REQUEST_SUBMITTED) {
-+                              /* Mark other intransit requests as needing retry so 
-+                                we do not immediately mark the session bad again 
-+                                (ie after we reconnect below) as they timeout too */
-+                              mid_entry->midState = MID_RETRY_NEEDED;
-+                      }
-+              }
-+      }
-+      spin_unlock(&GlobalMid_Lock);
-+      up(&server->tcpSem); 
-+
-+      while ((server->tcpStatus != CifsExiting) && (server->tcpStatus != CifsGood))
-+      {
-+              if(server->protocolType == IPV6) {
-+                      rc = ipv6_connect(&server->addr.sockAddr6,&server->ssocket);
-+              } else {
-+                      rc = ipv4_connect(&server->addr.sockAddr, 
-+                                      &server->ssocket,
-+                                      server->workstation_RFC1001_name);
-+              }
-+              if(rc) {
-+                      set_current_state(TASK_INTERRUPTIBLE);
-+                      schedule_timeout(3 * HZ);
-+              } else {
-+                      atomic_inc(&tcpSesReconnectCount);
-+                      spin_lock(&GlobalMid_Lock);
-+                      if(server->tcpStatus != CifsExiting)
-+                              server->tcpStatus = CifsGood;
-+                      spin_unlock(&GlobalMid_Lock);
-+      /*              atomic_set(&server->inFlight,0);*/
-+                      wake_up(&server->response_q);
-+              }
-+      }
-+      return rc;
-+}
-+
-+static int
-+cifs_demultiplex_thread(struct TCP_Server_Info *server)
-+{
-+      int length;
-+      unsigned int pdu_length, total_read;
-+      struct smb_hdr *smb_buffer = NULL;
-+      struct msghdr smb_msg;
-+      mm_segment_t temp_fs;
-+      struct iovec iov;
-+      struct socket *csocket = server->ssocket;
-+      struct list_head *tmp;
-+      struct cifsSesInfo *ses;
-+      struct task_struct *task_to_wake = NULL;
-+      struct mid_q_entry *mid_entry;
-+      char *temp;
-+
-+      daemonize();
-+      sprintf(current->comm,"cifsd");
-+      /* allow_signal(SIGKILL);*/
-+      current->flags |= PF_MEMALLOC;
-+      server->tsk = current;  /* save process info to wake at shutdown */
-+      cFYI(1, ("Demultiplex PID: %d", current->pid));
-+
-+      temp_fs = get_fs();     /* we must turn off socket api parm checking */
-+      set_fs(get_ds());
-+
-+      while (server->tcpStatus != CifsExiting) {
-+              if (smb_buffer == NULL)
-+                      smb_buffer = cifs_buf_get();
-+              else
-+                      memset(smb_buffer, 0, sizeof (struct smb_hdr));
-+
-+              if (smb_buffer == NULL) {
-+                      cERROR(1,("Can not get memory for SMB response"));
-+                      set_current_state(TASK_INTERRUPTIBLE);
-+                      schedule_timeout(HZ * 3); /* give system time to free memory */
-+                      continue;
-+              }
-+              iov.iov_base = smb_buffer;
-+              iov.iov_len = sizeof (struct smb_hdr) - 1;      
-+        /* 1 byte less above since wct is not always returned in error cases */
-+              smb_msg.msg_iov = &iov;
-+              smb_msg.msg_iovlen = 1;
-+              smb_msg.msg_control = NULL;
-+              smb_msg.msg_controllen = 0;
-+
-+              length =
-+                  sock_recvmsg(csocket, &smb_msg,
-+                               sizeof (struct smb_hdr) -
-+                               1 /* RFC1001 header and SMB header */ ,
-+                               MSG_PEEK /* flags see socket.h */ );
-+
-+              if(server->tcpStatus == CifsExiting) {
-+                      break;
-+              } else if (server->tcpStatus == CifsNeedReconnect) {
-+                      cFYI(1,("Reconnecting after server stopped responding"));
-+                      cifs_reconnect(server);
-+                      cFYI(1,("call to reconnect done"));
-+                      csocket = server->ssocket;
-+                      continue;
-+              } else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) {
-+                      set_current_state(TASK_INTERRUPTIBLE);
-+                      schedule_timeout(1); /* minimum sleep to prevent looping
-+                              allowing socket to clear and app threads to set
-+                              tcpStatus CifsNeedReconnect if server hung */
-+                      continue;
-+              } else if (length <= 0) {
-+                      if(server->tcpStatus == CifsNew) {
-+                              cFYI(1,("tcp session abended prematurely (after SMBnegprot)"));
-+                              /* some servers kill tcp session rather than returning
-+                                      smb negprot error in which case reconnecting here is
-+                                      not going to help - return error to mount */
-+                              break;
-+                      }
-+                      if(length == -EINTR) { 
-+                              cFYI(1,("cifsd thread killed"));
-+                              break;
-+                      }
-+                      cFYI(1,("Reconnecting after unexpected peek error %d",length));
-+                      cifs_reconnect(server);
-+                      csocket = server->ssocket;
-+                      wake_up(&server->response_q);
-+                      continue;
-+              }
-+
-+              pdu_length = 4 + ntohl(smb_buffer->smb_buf_length);
-+              /* Ony read pdu_length after below checks for too short (due
-+                 to e.g. int overflow) and too long ie beyond end of buf */
-+              cFYI(1, ("Peek length rcvd: 0x%x beginning 0x%x)", length, pdu_length));
-+
-+              temp = (char *) smb_buffer;
-+              if (length > 3) {
-+                      if (temp[0] == (char) RFC1002_SESSION_KEEP_ALIVE) {
-+                              iov.iov_base = smb_buffer;
-+                              iov.iov_len = 4;
-+                              length = sock_recvmsg(csocket, &smb_msg, 4, 0);
-+                              cFYI(0,("Received 4 byte keep alive packet"));
-+                      } else if (temp[0] == (char) RFC1002_POSITIVE_SESSION_RESPONSE) {
-+                              iov.iov_base = smb_buffer;
-+                                      iov.iov_len = 4;
-+                                      length = sock_recvmsg(csocket, &smb_msg, 4, 0);
-+                                      cFYI(1,("Good RFC 1002 session rsp"));
-+                      } else if ((temp[0] == (char)RFC1002_NEGATIVE_SESSION_RESPONSE)
-+                                 && (length == 5)) {
-+                              /* we get this from Windows 98 instead of error on SMB negprot response */
-+                              cFYI(1,("Negative RFC 1002 Session Response Error 0x%x)",temp[4]));
-+                              if(server->tcpStatus == CifsNew) {
-+                                      /* if nack on negprot (rather than 
-+                                      ret of smb negprot error) reconnecting
-+                                      not going to help, ret error to mount */
-+                                      break;
-+                              } else {
-+                                      /* give server a second to
-+                                      clean up before reconnect attempt */
-+                                      set_current_state(TASK_INTERRUPTIBLE);
-+                                      schedule_timeout(HZ);
-+                                      /* 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) */
-+                                      server->addr.sockAddr.sin_port = CIFS_PORT;
-+                                      cifs_reconnect(server);
-+                                      csocket = server->ssocket;
-+                                      wake_up(&server->response_q);
-+                                      continue;
-+                              }
-+                      } else if (temp[0] != (char) 0) {
-+                              cERROR(1,("Unknown RFC 1002 frame"));
-+                              cifs_dump_mem(" Received Data: ", temp, length);
-+                              cifs_reconnect(server);
-+                              csocket = server->ssocket;
-+                              continue;
-+                      } else {
-+                              if ((length != sizeof (struct smb_hdr) - 1)
-+                                  || (pdu_length >
-+                                      CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE)
-+                                  || (pdu_length <
-+                                      sizeof (struct smb_hdr) - 1)
-+                                  ||
-+                                  (checkSMBhdr
-+                                   (smb_buffer, smb_buffer->Mid))) {
-+                                      cERROR(1,
-+                                          ("Invalid size or format for SMB found with length %d and pdu_lenght %d",
-+                                              length, pdu_length));
-+                                      cifs_dump_mem("Received Data is: ",temp,sizeof(struct smb_hdr));
-+                                      /* could we fix this network corruption by finding next 
-+                                              smb header (instead of killing the session) and
-+                                              restart reading from next valid SMB found? */
-+                                      cifs_reconnect(server);
-+                                      csocket = server->ssocket;
-+                                      continue;
-+                              } else {        /* length ok */
-+
-+                                      length = 0;
-+                                      iov.iov_base = smb_buffer;
-+                                      iov.iov_len = pdu_length;
-+                                      for (total_read = 0; 
-+                                           total_read < pdu_length;
-+                                           total_read += length) {    
-+                                              length = sock_recvmsg(csocket, &smb_msg, 
-+                                                      pdu_length - total_read, 0);
-+                                              if (length == 0) {
-+                                                      cERROR(1,
-+                                                             ("Zero length receive when expecting %d ",
-+                                                              pdu_length - total_read));
-+                                                      cifs_reconnect(server);
-+                                                      csocket = server->ssocket;
-+                                                      continue;
-+                                              }
-+                                      }
-+                              }
-+
-+                              dump_smb(smb_buffer, length);
-+                              if (checkSMB
-+                                  (smb_buffer, smb_buffer->Mid, total_read)) {
-+                                      cERROR(1, ("Bad SMB Received "));
-+                                      continue;
-+                              }
-+
-+                              task_to_wake = NULL;
-+                              spin_lock(&GlobalMid_Lock);
-+                              list_for_each(tmp, &server->pending_mid_q) {
-+                                      mid_entry = list_entry(tmp, struct
-+                                                             mid_q_entry,
-+                                                             qhead);
-+
-+                                      if ((mid_entry->mid == smb_buffer->Mid) && (mid_entry->midState == MID_REQUEST_SUBMITTED)) {
-+                                              cFYI(1,
-+                                                   (" Mid 0x%x matched - waking up ",mid_entry->mid));
-+                                              task_to_wake = mid_entry->tsk;
-+                                              mid_entry->resp_buf =
-+                                                  smb_buffer;
-+                                              mid_entry->midState =
-+                                                  MID_RESPONSE_RECEIVED;
-+                                      }
-+                              }
-+                              spin_unlock(&GlobalMid_Lock);
-+                              if (task_to_wake) {
-+                                      smb_buffer = NULL;      /* will be freed by users thread after he is done */
-+                                      wake_up_process(task_to_wake);
-+                              } else if (is_valid_oplock_break(smb_buffer) == FALSE) {                          
-+                                      cERROR(1, ("No task to wake, unknown frame rcvd!"));
-+                                      cifs_dump_mem("Received Data is: ",temp,sizeof(struct smb_hdr));
-+                              }
-+                      }
-+              } else {
-+                      cFYI(0,
-+                           ("Frame less than four bytes received  %d bytes long.",
-+                            length));
-+                      if (length > 0) {
-+                              length = sock_recvmsg(csocket, &smb_msg, length, 0);    /* throw away junk frame */
-+                              cFYI(1,
-+                                   (" with junk  0x%x in it ",
-+                                    *(__u32 *) smb_buffer));
-+                      }
-+              }
-+      }
-+      spin_lock(&GlobalMid_Lock);
-+      server->tcpStatus = CifsExiting;
-+      server->tsk = NULL;
-+      atomic_set(&server->inFlight, 0);
-+      spin_unlock(&GlobalMid_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 */
-+      set_current_state(TASK_INTERRUPTIBLE);
-+      schedule_timeout(HZ/8);
-+
-+      if(server->ssocket) {
-+              sock_release(csocket);
-+              server->ssocket = NULL;
-+      }
-+      set_fs(temp_fs);
-+      if (smb_buffer) /* buffer usually freed in free_mid - need to free it on error or exit */
-+              cifs_buf_release(smb_buffer);
-+
-+      read_lock(&GlobalSMBSeslock);
-+      if (list_empty(&server->pending_mid_q)) {
-+              /* loop through server session structures attached to this and mark them dead */
-+              list_for_each(tmp, &GlobalSMBSessionList) {
-+                      ses =
-+                          list_entry(tmp, struct cifsSesInfo,
-+                                     cifsSessionList);
-+                      if (ses->server == server) {
-+                              ses->status = CifsExiting;
-+                              ses->server = NULL;
-+                      }
-+              }
-+              read_unlock(&GlobalSMBSeslock);
-+      } else {
-+              spin_lock(&GlobalMid_Lock);
-+              list_for_each(tmp, &server->pending_mid_q) {
-+              mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
-+                      if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
-+                              cFYI(1,
-+                                       (" Clearing Mid 0x%x - waking up ",mid_entry->mid));
-+                              task_to_wake = mid_entry->tsk;
-+                              if(task_to_wake) {
-+                                      wake_up_process(task_to_wake);
-+                              }
-+                      }
-+              }
-+              spin_unlock(&GlobalMid_Lock);
-+              read_unlock(&GlobalSMBSeslock);
-+              set_current_state(TASK_INTERRUPTIBLE);
-+              /* 1/8th of sec is more than enough time for them to exit */
-+              schedule_timeout(HZ/8); 
-+      }
-+
-+      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 */
-+              cFYI(1, ("Wait for exit from demultiplex thread"));
-+              set_current_state(TASK_INTERRUPTIBLE);
-+              schedule_timeout(46 * HZ);      
-+              /* if threads still have not exited they are probably never
-+              coming home not much else we can do but free the memory */
-+      }
-+      kfree(server);
-+
-+      set_current_state(TASK_INTERRUPTIBLE);
-+      schedule_timeout(HZ/4);
-+      return 0;
-+}
-+
-+static void * 
-+cifs_kcalloc(size_t size, int type)
-+{
-+      void *addr;
-+      addr = kmalloc(size, type);
-+      if (addr)
-+              memset(addr, 0, size);
-+      return addr;
-+}
-+
-+static int
-+cifs_parse_mount_options(char *options, const char *devname, struct smb_vol *vol)
-+{
-+      char *value;
-+      char *data;
-+      unsigned int  temp_len, i, j;
-+      char separator[2];
-+
-+      separator[0] = ',';
-+      separator[1] = 0; 
-+
-+      memset(vol->source_rfc1001_name,0x20,15);
-+      for(i=0;i < strnlen(system_utsname.nodename,15);i++) {
-+              /* does not have to be a perfect mapping since the field is
-+              informational, only used for servers that do not support
-+              port 445 and it can be overridden at mount time */
-+              vol->source_rfc1001_name[i] = toupper(system_utsname.nodename[i]);
-+      }
-+      vol->source_rfc1001_name[15] = 0;
-+
-+      vol->linux_uid = current->uid;  /* current->euid instead? */
-+      vol->linux_gid = current->gid;
-+      vol->dir_mode = S_IRWXUGO;
-+      /* 2767 perms indicate mandatory locking support */
-+      vol->file_mode = S_IALLUGO & ~(S_ISUID | S_IXGRP);
-+
-+      /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
-+      vol->rw = TRUE;
-+
-+      if (!options)
-+              return 1;
-+
-+      if(strncmp(options,"sep=",4) == 0) {
-+              if(options[4] != 0) {
-+                      separator[0] = options[4];
-+                      options += 5;
-+              } else {
-+                      cFYI(1,("Null separator not allowed"));
-+              }
-+      }
-+              
-+      while ((data = strsep(&options, separator)) != NULL) {
-+              if (!*data)
-+                      continue;
-+              if ((value = strchr(data, '=')) != NULL)
-+                      *value++ = '\0';
-+              if (strnicmp(data, "user", 4) == 0) {
-+                      if (!value || !*value) {
-+                              printk(KERN_WARNING
-+                                     "CIFS: invalid or missing username\n");
-+                              return 1;       /* needs_arg; */
-+                      }
-+                      if (strnlen(value, 200) < 200) {
-+                              vol->username = value;
-+                      } else {
-+                              printk(KERN_WARNING "CIFS: username too long\n");
-+                              return 1;
-+                      }
-+              } else if (strnicmp(data, "pass", 4) == 0) {
-+                      if (!value || !*value) {
-+                              vol->password = NULL;
-+                              continue;
-+                      }
-+                      temp_len = strlen(value);
-+                      /* removed password length check, NTLM passwords
-+                              can be arbitrarily long */
-+
-+                      /* if comma in password, the string will be 
-+                      prematurely null terminated.  Commas in password are
-+                      specified across the cifs mount interface by a double
-+                      comma ie ,, and a comma used as in other cases ie ','
-+                      as a parameter delimiter/separator is single and due
-+                      to the strsep above is temporarily zeroed. */
-+
-+                      /* NB: password legally can have multiple commas and
-+                      the only illegal character in a password is null */
-+                              
-+                      if ((value[temp_len] == 0) && (value[temp_len+1] == separator[0])) {
-+                              /* reinsert comma */
-+                              value[temp_len] = separator[0];
-+                              temp_len+=2;  /* move after the second comma */
-+                              while(value[temp_len] != 0)  {
-+                                      if((value[temp_len] == separator[0]) && (value[temp_len+1] != separator[0])) {
-+                                              /* single comma indicating start of next parm */
-+                                              break;
-+                                      }
-+                                      temp_len++;
-+                              }
-+                              if(value[temp_len] == 0) {
-+                                      options = NULL;
-+                              } else {
-+                                      value[temp_len] = 0;
-+                                      /* move options to point to start of next parm */
-+                                      options = value + temp_len + 1;
-+                              }
-+                              /* go from value to (value + temp_len) condensing double commas to singles */
-+                              vol->password = cifs_kcalloc(temp_len, GFP_KERNEL);
-+                              for(i=0,j=0;i<temp_len;i++,j++) {
-+                                      vol->password[j] = value[i];
-+                                      if(value[i] == separator[0] && value[i+1] == separator[0]) {
-+                                              /* skip second comma */
-+                                              i++;
-+                                      }
-+                              }
-+                              /* value[temp_len] is zeroed above so
-+                                       vol->password[temp_len] guaranteed to be null */
-+                      } else {
-+                              vol->password = cifs_kcalloc(temp_len + 1, GFP_KERNEL);
-+                              strcpy(vol->password, value);
-+                      }
-+              } else if (strnicmp(data, "ip", 2) == 0) {
-+                      if (!value || !*value) {
-+                              vol->UNCip = NULL;
-+                      } else if (strnlen(value, 35) < 35) {
-+                              vol->UNCip = value;
-+                      } else {
-+                              printk(KERN_WARNING "CIFS: ip address too long\n");
-+                              return 1;
-+                      }
-+              } else if ((strnicmp(data, "unc", 3) == 0)
-+                         || (strnicmp(data, "target", 6) == 0)
-+                         || (strnicmp(data, "path", 4) == 0)) {
-+                      if (!value || !*value) {
-+                              printk(KERN_WARNING
-+                                     "CIFS: invalid path to network resource\n");
-+                              return 1;       /* needs_arg; */
-+                      }
-+                      if ((temp_len = strnlen(value, 300)) < 300) {
-+                              vol->UNC = kmalloc(temp_len+1,GFP_KERNEL);
-+                              if(vol->UNC == NULL)
-+                                      return 1;
-+                              strcpy(vol->UNC,value);
-+                              if (strncmp(vol->UNC, "//", 2) == 0) {
-+                                      vol->UNC[0] = '\\';
-+                                      vol->UNC[1] = '\\';
-+                              } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {                    
-+                                      printk(KERN_WARNING
-+                                             "CIFS: UNC Path does not begin with // or \\\\ \n");
-+                                      return 1;
-+                              }
-+                      } else {
-+                              printk(KERN_WARNING "CIFS: UNC name too long\n");
-+                              return 1;
-+                      }
-+              } else if ((strnicmp(data, "domain", 3) == 0)
-+                         || (strnicmp(data, "workgroup", 5) == 0)) {
-+                      if (!value || !*value) {
-+                              printk(KERN_WARNING "CIFS: invalid domain name\n");
-+                              return 1;       /* needs_arg; */
-+                      }
-+                      /* BB are there cases in which a comma can be valid in
-+                      a domain name and need special handling? */
-+                      if (strnlen(value, 65) < 65) {
-+                              vol->domainname = value;
-+                              cFYI(1, ("Domain name set"));
-+                      } else {
-+                              printk(KERN_WARNING "CIFS: domain name too long\n");
-+                              return 1;
-+                      }
-+              } else if (strnicmp(data, "iocharset", 9) == 0) {
-+                      if (!value || !*value) {
-+                              printk(KERN_WARNING "CIFS: invalid iocharset specified\n");
-+                              return 1;       /* needs_arg; */
-+                      }
-+                      if (strnlen(value, 65) < 65) {
-+                              if(strnicmp(value,"default",7))
-+                                      vol->iocharset = value;
-+                              /* if iocharset not set load_nls_default used by caller */
-+                              cFYI(1, ("iocharset set to %s",value));
-+                      } else {
-+                              printk(KERN_WARNING "CIFS: iocharset name too long.\n");
-+                              return 1;
-+                      }
-+              } else if (strnicmp(data, "uid", 3) == 0) {
-+                      if (value && *value) {
-+                              vol->linux_uid =
-+                                      simple_strtoul(value, &value, 0);
-+                      }
-+              } else if (strnicmp(data, "gid", 3) == 0) {
-+                      if (value && *value) {
-+                              vol->linux_gid =
-+                                      simple_strtoul(value, &value, 0);
-+                      }
-+              } else if (strnicmp(data, "file_mode", 4) == 0) {
-+                      if (value && *value) {
-+                              vol->file_mode =
-+                                      simple_strtoul(value, &value, 0);
-+                      }
-+              } else if (strnicmp(data, "dir_mode", 3) == 0) {
-+                      if (value && *value) {
-+                              vol->dir_mode =
-+                                      simple_strtoul(value, &value, 0);
-+                      }
-+              } else if (strnicmp(data, "port", 4) == 0) {
-+                      if (value && *value) {
-+                              vol->port =
-+                                      simple_strtoul(value, &value, 0);
-+                      }
-+              } else if (strnicmp(data, "rsize", 5) == 0) {
-+                      if (value && *value) {
-+                              vol->rsize =
-+                                      simple_strtoul(value, &value, 0);
-+                      }
-+              } else if (strnicmp(data, "wsize", 5) == 0) {
-+                      if (value && *value) {
-+                              vol->wsize =
-+                                      simple_strtoul(value, &value, 0);
-+                      }
-+              } else if (strnicmp(data, "sockopt", 5) == 0) {
-+                      if (value && *value) {
-+                              vol->sockopt =
-+                                      simple_strtoul(value, &value, 0);
-+                      }
-+              } else if (strnicmp(data, "netbiosname", 4) == 0) {
-+                      if (!value || !*value || (*value == ' ')) {
-+                              cFYI(1,("invalid (empty) netbiosname specified"));
-+                      } else {
-+                              memset(vol->source_rfc1001_name,0x20,15);
-+                              for(i=0;i<15;i++) {
-+                              /* BB are there cases in which a comma can be 
-+                              valid in this workstation netbios name (and need
-+                              special handling)? */
-+
-+                              /* We do not uppercase netbiosname for user */
-+                                      if (value[i]==0)
-+                                              break;
-+                                      else 
-+                                              vol->source_rfc1001_name[i] = value[i];
-+                              }
-+                              /* The string has 16th byte zero still from
-+                              set at top of the function  */
-+                              if((i==15) && (value[i] != 0))
-+                                      printk(KERN_WARNING "CIFS: netbiosname longer than 15 and was truncated.\n");
-+                      }
-+              } else if (strnicmp(data, "credentials", 4) == 0) {
-+                      /* ignore */
-+              } else if (strnicmp(data, "version", 3) == 0) {
-+                      /* ignore */
-+              } else if (strnicmp(data, "rw", 2) == 0) {
-+                      vol->rw = TRUE;
-+              } else if ((strnicmp(data, "suid", 4) == 0) ||
-+                                 (strnicmp(data, "nosuid", 6) == 0) ||
-+                                 (strnicmp(data, "exec", 4) == 0) ||
-+                                 (strnicmp(data, "noexec", 6) == 0) ||
-+                                 (strnicmp(data, "nodev", 5) == 0) ||
-+                                 (strnicmp(data, "noauto", 6) == 0) ||
-+                                 (strnicmp(data, "dev", 3) == 0)) {
-+                      /*  The mount tool or mount.cifs helper (if present)
-+                              uses these opts to set flags, and the flags are read
-+                              by the kernel vfs layer before we get here (ie
-+                              before read super) so there is no point trying to
-+                              parse these options again and set anything and it
-+                              is ok to just ignore them */
-+                      continue;
-+              } else if (strnicmp(data, "ro", 2) == 0) {
-+                      vol->rw = FALSE;
-+              } else if (strnicmp(data, "hard", 4) == 0) {
-+                      vol->retry = 1;
-+              } else if (strnicmp(data, "soft", 4) == 0) {
-+                      vol->retry = 0;
-+              } else if (strnicmp(data, "nohard", 6) == 0) {
-+                      vol->retry = 0;
-+              } else if (strnicmp(data, "nosoft", 6) == 0) {
-+                      vol->retry = 1;
-+              } else if (strnicmp(data, "nointr", 6) == 0) {
-+                      vol->intr = 0;
-+              } else if (strnicmp(data, "intr", 4) == 0) {
-+                      vol->intr = 1;
-+              } else if (strnicmp(data, "noac", 4) == 0) {
-+                      printk(KERN_WARNING "CIFS: Mount option noac not supported. Instead set /proc/fs/cifs/LookupCacheEnabled to 0\n");
-+              } else
-+                      printk(KERN_WARNING "CIFS: Unknown mount option %s\n",data);
-+      }
-+      if (vol->UNC == NULL) {
-+              if(devname == NULL) {
-+                      printk(KERN_WARNING "CIFS: Missing UNC name for mount target\n");
-+                      return 1;
-+              }
-+              if ((temp_len = strnlen(devname, 300)) < 300) {
-+                      vol->UNC = kmalloc(temp_len+1,GFP_KERNEL);
-+                      if(vol->UNC == NULL)
-+                              return 1;
-+                      strcpy(vol->UNC,devname);
-+                      if (strncmp(vol->UNC, "//", 2) == 0) {
-+                              vol->UNC[0] = '\\';
-+                              vol->UNC[1] = '\\';
-+                      } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
-+                              printk(KERN_WARNING "CIFS: UNC Path does not begin with // or \\\\ \n");
-+                              return 1;
-+                      }
-+              } else {
-+                      printk(KERN_WARNING "CIFS: UNC name too long\n");
-+                      return 1;
-+              }
-+      }
-+      if(vol->UNCip == 0)
-+              vol->UNCip = &vol->UNC[2];
-+
-+      return 0;
-+}
-+
-+static struct cifsSesInfo *
-+cifs_find_tcp_session(__u32 new_target_ip_addr,
-+               char *userName, struct TCP_Server_Info **psrvTcp)
-+{
-+      struct list_head *tmp;
-+      struct cifsSesInfo *ses;
-+
-+      *psrvTcp = NULL;
-+      read_lock(&GlobalSMBSeslock);
-+      list_for_each(tmp, &GlobalSMBSessionList) {
-+              ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
-+              if (ses->server) {
-+                      if (ses->server->addr.sockAddr.sin_addr.s_addr ==
-+                          new_target_ip_addr) {
-+                              /* BB lock server and tcp session and increment use count here?? */
-+                              *psrvTcp = ses->server; /* found a match on the TCP session */
-+                              /* BB check if reconnection needed */
-+                              if (strncmp
-+                                  (ses->userName, userName,
-+                                   MAX_USERNAME_SIZE) == 0){
-+                                      read_unlock(&GlobalSMBSeslock);
-+                                      return ses;     /* found exact match on both tcp and SMB sessions */
-+                              }
-+                      }
-+              }
-+              /* else tcp and smb sessions need reconnection */
-+      }
-+      read_unlock(&GlobalSMBSeslock);
-+      return NULL;
-+}
-+
-+static struct cifsTconInfo *
-+find_unc(__u32 new_target_ip_addr, char *uncName, char *userName)
-+{
-+      struct list_head *tmp;
-+      struct cifsTconInfo *tcon;
-+
-+      read_lock(&GlobalSMBSeslock);
-+      list_for_each(tmp, &GlobalTreeConnectionList) {
-+              cFYI(1, ("Next tcon - "));
-+              tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
-+              if (tcon->ses) {
-+                      if (tcon->ses->server) {
-+                              cFYI(1,
-+                                   (" old ip addr: %x == new ip %x ?",
-+                                    tcon->ses->server->addr.sockAddr.sin_addr.
-+                                    s_addr, new_target_ip_addr));
-+                              if (tcon->ses->server->addr.sockAddr.sin_addr.
-+                                  s_addr == new_target_ip_addr) {
-+      /* BB lock tcon and server and tcp session and increment use count here? */
-+                                      /* found a match on the TCP session */
-+                                      /* BB check if reconnection needed */
-+                                      cFYI(1,("Matched ip, old UNC: %s == new: %s ?",
-+                                            tcon->treeName, uncName));
-+                                      if (strncmp
-+                                          (tcon->treeName, uncName,
-+                                           MAX_TREE_SIZE) == 0) {
-+                                              cFYI(1,
-+                                                   ("Matched UNC, old user: %s == new: %s ?",
-+                                                    tcon->treeName, uncName));
-+                                              if (strncmp
-+                                                  (tcon->ses->userName,
-+                                                   userName,
-+                                                   MAX_USERNAME_SIZE) == 0) {
-+                                                      read_unlock(&GlobalSMBSeslock);
-+                                                      return tcon;/* also matched user (smb session)*/
-+                                              }
-+                                      }
-+                              }
-+                      }
-+              }
-+      }
-+      read_unlock(&GlobalSMBSeslock);
-+      return NULL;
-+}
-+
-+int
-+connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
-+                  const char *old_path, const struct nls_table *nls_codepage)
-+{
-+      unsigned char *referrals = NULL;
-+      unsigned int num_referrals;
-+      int rc = 0;
-+
-+      rc = get_dfs_path(xid, pSesInfo,old_path, nls_codepage, 
-+                      &num_referrals, &referrals);
-+
-+      /* BB Add in code to: if valid refrl, if not ip address contact
-+              the helper that resolves tcp names, mount to it, try to 
-+              tcon to it unmount it if fail */
-+
-+      if(referrals)
-+              kfree(referrals);
-+
-+      return rc;
-+}
-+
-+int
-+get_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
-+                      const char *old_path, const struct nls_table *nls_codepage, 
-+                      unsigned int *pnum_referrals, unsigned char ** preferrals)
-+{
-+      char *temp_unc;
-+      int rc = 0;
-+
-+      *pnum_referrals = 0;
-+
-+      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);
-+
-+      return rc;
-+}
-+
-+/* 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
-+ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, 
-+                       char * netbios_name)
-+{
-+      int rc = 0;
-+      int connected = 0;
-+      unsigned short int orig_port = 0;
-+
-+      if(*csocket == NULL) {
-+              rc = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, csocket);
-+              if (rc < 0) {
-+                      cERROR(1, ("Error %d creating socket",rc));
-+                      *csocket = NULL;
-+                      return rc;
-+              } else {
-+              /* BB other socket options to set KEEPALIVE, NODELAY? */
-+                      cFYI(1,("Socket created"));
-+                      (*csocket)->sk->allocation = GFP_NOFS; 
-+              }
-+      }
-+
-+      psin_server->sin_family = AF_INET;
-+      if(psin_server->sin_port) { /* user overrode default port */
-+              rc = (*csocket)->ops->connect(*csocket,
-+                              (struct sockaddr *) psin_server,
-+                              sizeof (struct sockaddr_in),0);
-+              if (rc >= 0)
-+                      connected = 1;
-+      } 
-+
-+      if(!connected) {
-+              /* save original port so we can retry user specified port  
-+                      later if fall back ports fail this time  */
-+              orig_port = psin_server->sin_port;
-+
-+              /* do not retry on the same port we just failed on */
-+              if(psin_server->sin_port != htons(CIFS_PORT)) {
-+                      psin_server->sin_port = htons(CIFS_PORT);
-+
-+                      rc = (*csocket)->ops->connect(*csocket,
-+                                      (struct sockaddr *) psin_server,
-+                                      sizeof (struct sockaddr_in),0);
-+                      if (rc >= 0)
-+                              connected = 1;
-+              }
-+      }
-+      if (!connected) {
-+              psin_server->sin_port = htons(RFC1001_PORT);
-+              rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
-+                                            psin_server, sizeof (struct sockaddr_in),0);
-+              if (rc >= 0) 
-+                      connected = 1;
-+      }
-+
-+      /* give up here - unless we want to retry on different
-+              protocol families some day */
-+      if (!connected) {
-+              if(orig_port)
-+                      psin_server->sin_port = orig_port;
-+              cFYI(1,("Error %d connecting to server via ipv4",rc));
-+              sock_release(*csocket);
-+              *csocket = NULL;
-+              return rc;
-+      }
-+      /* Eventually check for other socket options to change from 
-+              the default. sock_setsockopt not used because it expects 
-+              user space buffer */
-+      (*csocket)->sk->rcvtimeo = 7 * HZ;
-+                      
-+      /* send RFC1001 sessinit */
-+
-+      if(psin_server->sin_port == htons(139)) {
-+              /* 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 = cifs_kcalloc(sizeof(struct rfc1002_session_packet), GFP_KERNEL);
-+              if(ses_init_buf) {
-+                      ses_init_buf->trailer.session_req.called_len = 32;
-+                      rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
-+                              DEFAULT_CIFS_CALLED_NAME,16);
-+                      ses_init_buf->trailer.session_req.calling_len = 32;
-+                      /* calling name ends in null (byte 16) from old smb
-+                      convention. */
-+                      if(netbios_name && (netbios_name[0] !=0)) {
-+                              rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
-+                                      netbios_name,16);
-+                      } else {
-+                              rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
-+                                      "LINUX_CIFS_CLNT",16);
-+                      }
-+                      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 = 0x81000044;
-+                      rc = smb_send(*csocket, smb_buf, 0x44,
-+                              (struct sockaddr *)psin_server);
-+                      kfree(ses_init_buf);
-+              }
-+              /* else the negprot may still work without this 
-+              even though malloc failed */
-+              
-+      }
-+              
-+      return rc;
-+}
-+
-+static int
-+ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
-+{
-+      int rc = 0;
-+      int connected = 0;
-+
-+      if(*csocket == NULL) {
-+              rc = sock_create(PF_INET6, SOCK_STREAM, IPPROTO_TCP, csocket);
-+              if (rc < 0) {
-+                      cERROR(1, ("Error %d creating ipv6 socket",rc));
-+                      *csocket = NULL;
-+                      return rc;
-+              } else {
-+              /* BB other socket options to set KEEPALIVE, NODELAY? */
-+                       cFYI(1,("ipv6 Socket created"));
-+                      (*csocket)->sk->allocation = GFP_NOFS;
-+              }
-+      }
-+
-+      psin_server->sin6_family = AF_INET6;
-+
-+      if(psin_server->sin6_port) { /* user overrode default port */
-+              rc = (*csocket)->ops->connect(*csocket,
-+                              (struct sockaddr *) psin_server,
-+                              sizeof (struct sockaddr_in6),0);
-+              if (rc >= 0)
-+                      connected = 1;
-+      } 
-+
-+      if(!connected) {
-+              /* do not retry on the same port we just failed on */
-+              if(psin_server->sin6_port != htons(CIFS_PORT)) {
-+                      psin_server->sin6_port = htons(CIFS_PORT);
-+
-+                      rc = (*csocket)->ops->connect(*csocket,
-+                                      (struct sockaddr *) psin_server,
-+                                      sizeof (struct sockaddr_in6),0);
-+                      if (rc >= 0)
-+                              connected = 1;
-+              }
-+      }
-+      if (!connected) {
-+              psin_server->sin6_port = htons(RFC1001_PORT);
-+              rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
-+                                       psin_server, sizeof (struct sockaddr_in6),0);
-+              if (rc >= 0) 
-+                      connected = 1;
-+      }
-+
-+      /* give up here - unless we want to retry on different
-+              protocol families some day */
-+      if (!connected) {
-+              cFYI(1,("Error %d connecting to server via ipv6",rc));
-+              sock_release(*csocket);
-+              *csocket = NULL;
-+              return rc;
-+      }
-+      /* Eventually check for other socket options to change from 
-+              the default. sock_setsockopt not used because it expects 
-+              user space buffer */
-+      (*csocket)->sk->rcvtimeo = 7 * HZ;
-+              
-+      return rc;
-+}
-+
-+int
-+cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
-+         char *mount_data, const char *devname)
-+{
-+      int rc = 0;
-+      int xid;
-+      struct socket *csocket = NULL;
-+      struct sockaddr_in sin_server;
-+      struct sockaddr_in6 sin_server6;
-+      struct smb_vol volume_info;
-+      struct cifsSesInfo *pSesInfo = NULL;
-+      struct cifsSesInfo *existingCifsSes = NULL;
-+      struct cifsTconInfo *tcon = NULL;
-+      struct TCP_Server_Info *srvTcp = NULL;
-+
-+      xid = GetXid();
-+
-+      cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); /* BB removeme BB fixme */
-+      
-+      memset(&volume_info,0,sizeof(struct smb_vol));
-+      if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
-+              if(volume_info.UNC)
-+                      kfree(volume_info.UNC);
-+              if(volume_info.password)
-+                      kfree(volume_info.password);
-+              FreeXid(xid);
-+              return -EINVAL;
-+      }
-+
-+      if (volume_info.username) {
-+              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 */
-+              if(volume_info.UNC)
-+                      kfree(volume_info.UNC);
-+              if(volume_info.password)
-+                      kfree(volume_info.password);
-+              FreeXid(xid);
-+              return -EINVAL;
-+      }
-+
-+      if (volume_info.UNCip && volume_info.UNC) {
-+              rc = cifs_inet_pton(AF_INET, volume_info.UNCip,&sin_server.sin_addr.s_addr);
-+
-+              if(rc == 0) {
-+                      /* not ipv4 address, try ipv6 */
-+                      rc = cifs_inet_pton(AF_INET6,volume_info.UNCip,&sin_server6.sin6_addr.in6_u); 
-+              } 
-+       
-+              if(rc != 1) {
-+                      /* we failed translating address */
-+                      if(volume_info.UNC)
-+                              kfree(volume_info.UNC);
-+                      if(volume_info.password)
-+                              kfree(volume_info.password);
-+                      FreeXid(xid);
-+                      return -EINVAL;
-+              }
-+
-+              cFYI(1, ("UNC: %s ip: %s", volume_info.UNC, volume_info.UNCip));
-+              /* success */
-+              rc = 0;
-+      } else if (volume_info.UNCip){
-+              /* BB using ip addr as server name connect to the DFS root below */
-+              cERROR(1,("Connecting to DFS root not implemented yet"));
-+              if(volume_info.UNC)
-+                      kfree(volume_info.UNC);
-+              if(volume_info.password)
-+                      kfree(volume_info.password);
-+              FreeXid(xid);
-+              return -EINVAL;
-+      } else /* which servers DFS root would we conect to */ {
-+              cERROR(1,
-+                     ("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified  "));
-+              if(volume_info.UNC)
-+                      kfree(volume_info.UNC);
-+              if(volume_info.password)
-+                      kfree(volume_info.password);
-+              FreeXid(xid);
-+              return -EINVAL;
-+      }
-+
-+      /* this is needed for ASCII cp to Unicode converts */
-+      if(volume_info.iocharset == NULL) {
-+              cifs_sb->local_nls = load_nls_default();
-+      /* load_nls_default can not return null */
-+      } else {
-+              cifs_sb->local_nls = load_nls(volume_info.iocharset);
-+              if(cifs_sb->local_nls == NULL) {
-+                      cERROR(1,("CIFS mount error: iocharset %s not found",volume_info.iocharset));
-+                      if(volume_info.UNC)
-+                              kfree(volume_info.UNC);
-+                      if(volume_info.password)
-+                              kfree(volume_info.password);
-+                      FreeXid(xid);
-+                      return -ELIBACC;
-+              }
-+      }
-+
-+      existingCifsSes =
-+          cifs_find_tcp_session(sin_server.sin_addr.s_addr,
-+                           volume_info.username, &srvTcp);
-+      if (srvTcp) {
-+              cFYI(1, ("Existing tcp session with server found "));                
-+      } else {        /* create socket */
-+              if(volume_info.port)
-+                      sin_server.sin_port = htons(volume_info.port);
-+              else
-+                      sin_server.sin_port = 0;
-+              rc = ipv4_connect(&sin_server,&csocket,volume_info.source_rfc1001_name);
-+              if (rc < 0) {
-+                      cERROR(1,
-+                             ("Error connecting to IPv4 socket. Aborting operation"));
-+                      if(csocket != NULL)
-+                              sock_release(csocket);
-+                      if(volume_info.UNC)
-+                              kfree(volume_info.UNC);
-+                      if(volume_info.password)
-+                              kfree(volume_info.password);
-+                      FreeXid(xid);
-+                      return rc;
-+              }
-+
-+              srvTcp = kmalloc(sizeof (struct TCP_Server_Info), GFP_KERNEL);
-+              if (srvTcp == NULL) {
-+                      rc = -ENOMEM;
-+                      sock_release(csocket);
-+                      if(volume_info.UNC)
-+                              kfree(volume_info.UNC);
-+                      if(volume_info.password)
-+                              kfree(volume_info.password);
-+                      FreeXid(xid);
-+                      return rc;
-+              } else {
-+                      memset(srvTcp, 0, sizeof (struct TCP_Server_Info));
-+                      memcpy(&srvTcp->addr.sockAddr, &sin_server, sizeof (struct sockaddr_in));
-+                      atomic_set(&srvTcp->inFlight,0);
-+                      /* BB Add code for ipv6 case too */
-+                      srvTcp->ssocket = csocket;
-+                      srvTcp->protocolType = IPV4;
-+                      init_waitqueue_head(&srvTcp->response_q);
-+                      init_waitqueue_head(&srvTcp->request_q);
-+                      INIT_LIST_HEAD(&srvTcp->pending_mid_q);
-+                      /* at this point we are the only ones with the pointer
-+                      to the struct since the kernel thread not created yet
-+                      so no need to spinlock this init of tcpStatus */
-+                      srvTcp->tcpStatus = CifsNew;
-+                      init_MUTEX(&srvTcp->tcpSem);
-+                      kernel_thread((void *)(void *)cifs_demultiplex_thread, srvTcp,
-+                                    CLONE_FS | CLONE_FILES | CLONE_VM);
-+                      memcpy(srvTcp->workstation_RFC1001_name, volume_info.source_rfc1001_name,16);
-+              }
-+      }
-+
-+      if (existingCifsSes) {
-+              pSesInfo = existingCifsSes;
-+              cFYI(1, ("Existing smb sess found "));
-+              if(volume_info.password)
-+                      kfree(volume_info.password);
-+              /* volume_info.UNC freed at end of function */
-+      } else if (!rc) {
-+              cFYI(1, ("Existing smb sess not found "));
-+              pSesInfo = sesInfoAlloc();
-+              if (pSesInfo == NULL)
-+                      rc = -ENOMEM;
-+              else {
-+                      pSesInfo->server = srvTcp;
-+                      sprintf(pSesInfo->serverName, "%u.%u.%u.%u",
-+                              NIPQUAD(sin_server.sin_addr.s_addr));
-+              }
-+
-+              if (!rc){
-+                      /* volume_info.password freed at unmount */   
-+                      if (volume_info.password)
-+                              pSesInfo->password = volume_info.password;
-+                      if (volume_info.username)
-+                              strncpy(pSesInfo->userName,
-+                                      volume_info.username,MAX_USERNAME_SIZE);
-+                      if (volume_info.domainname)
-+                              strncpy(pSesInfo->domainName,
-+                                      volume_info.domainname,MAX_USERNAME_SIZE);
-+                      pSesInfo->linux_uid = volume_info.linux_uid;
-+                      down(&pSesInfo->sesSem);
-+                      rc = cifs_setup_session(xid,pSesInfo, cifs_sb->local_nls);
-+                      up(&pSesInfo->sesSem);
-+                      if(!rc)
-+                              atomic_inc(&srvTcp->socketUseCount);
-+              } else
-+                      if(volume_info.password)
-+                              kfree(volume_info.password);
-+      }
-+    
-+      /* search for existing tcon to this server share */
-+      if (!rc) {
-+              if((volume_info.rsize) && (volume_info.rsize + MAX_CIFS_HDR_SIZE < srvTcp->maxBuf))
-+                      cifs_sb->rsize = volume_info.rsize;
-+              else
-+                      cifs_sb->rsize = srvTcp->maxBuf - MAX_CIFS_HDR_SIZE; /* default */
-+              if((volume_info.wsize) && (volume_info.wsize + MAX_CIFS_HDR_SIZE < srvTcp->maxBuf))
-+                      cifs_sb->wsize = volume_info.wsize;
-+              else
-+                      cifs_sb->wsize = srvTcp->maxBuf - MAX_CIFS_HDR_SIZE; /* default */
-+              if(cifs_sb->rsize < PAGE_CACHE_SIZE) {
-+                      cifs_sb->rsize = PAGE_CACHE_SIZE;
-+                      cERROR(1,("Attempt to set readsize for mount to less than one page (4096)"));
-+              }
-+              cifs_sb->mnt_uid = volume_info.linux_uid;
-+              cifs_sb->mnt_gid = volume_info.linux_gid;
-+              cifs_sb->mnt_file_mode = volume_info.file_mode;
-+              cifs_sb->mnt_dir_mode = volume_info.dir_mode;
-+              cFYI(1,("file mode: 0x%x  dir mode: 0x%x",cifs_sb->mnt_file_mode,cifs_sb->mnt_dir_mode));
-+              tcon =
-+                  find_unc(sin_server.sin_addr.s_addr, volume_info.UNC,
-+                           volume_info.username);
-+              if (tcon) {
-+                      cFYI(1, ("Found match on UNC path "));
-+                      /* 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;
-+              } else {
-+                      tcon = tconInfoAlloc();
-+                      if (tcon == NULL)
-+                              rc = -ENOMEM;
-+                      else {
-+                              /* check for null share name ie connect to dfs root */
-+
-+                              /* BB check if this works for exactly length three strings */
-+                              if ((strchr(volume_info.UNC + 3, '\\') == NULL)
-+                                  && (strchr(volume_info.UNC + 3, '/') ==
-+                                      NULL)) {
-+                                      rc = connect_to_dfs_path(xid,
-+                                                               pSesInfo,
-+                                                               "",
-+                                                               cifs_sb->
-+                                                               local_nls);
-+                                      if(volume_info.UNC)
-+                                              kfree(volume_info.UNC);
-+                                      FreeXid(xid);
-+                                      return -ENODEV;
-+                              } else {
-+                                      rc = CIFSTCon(xid, pSesInfo, 
-+                                              volume_info.UNC,
-+                                              tcon, cifs_sb->local_nls);
-+                                      cFYI(1, ("CIFS Tcon rc = %d", rc));
-+                              }
-+                              if (!rc) {
-+                                      atomic_inc(&pSesInfo->inUse);
-+                                      tcon->retry = volume_info.retry;
-+                              }
-+                      }
-+              }
-+      }
-+      if(pSesInfo) {
-+              if (pSesInfo->capabilities & CAP_LARGE_FILES) {
-+                      sb->s_maxbytes = (u64) 1 << 63;
-+              } else
-+                      sb->s_maxbytes = (u64) 1 << 31; /* 2 GB */
-+      }
-+
-+/* on error free sesinfo and tcon struct if needed */
-+      if (rc) {
-+              /* if session setup failed, use count is zero but
-+              we still need to free cifsd thread */
-+              if(atomic_read(&srvTcp->socketUseCount) == 0) {
-+                      spin_lock(&GlobalMid_Lock);
-+                      srvTcp->tcpStatus = CifsExiting;
-+                      spin_unlock(&GlobalMid_Lock);
-+                      if(srvTcp->tsk)
-+                              send_sig(SIGKILL,srvTcp->tsk,1);
-+              }
-+               /* If find_unc succeeded then rc == 0 so we can not end */
-+              if (tcon)  /* up accidently freeing someone elses tcon struct */
-+                      tconInfoFree(tcon);
-+              if (existingCifsSes == 0) {
-+                      if (pSesInfo) {
-+                              if ((pSesInfo->server) && 
-+                                  (pSesInfo->status == CifsGood)) {
-+                                      int temp_rc;
-+                                      temp_rc = CIFSSMBLogoff(xid, pSesInfo);
-+                                      /* if the socketUseCount is now zero */
-+                                      if((temp_rc == -ESHUTDOWN) &&
-+                                         (pSesInfo->server->tsk))
-+                                              send_sig(SIGKILL,pSesInfo->server->tsk,1);
-+                              } else
-+                                      cFYI(1, ("No session or bad tcon"));
-+                              sesInfoFree(pSesInfo);
-+                              /* pSesInfo = NULL; */
-+                      }
-+              }
-+      } else {
-+              atomic_inc(&tcon->useCount);
-+              cifs_sb->tcon = tcon;
-+              tcon->ses = pSesInfo;
-+
-+              /* do not care if following two calls succeed - informational only */
-+              CIFSSMBQFSDeviceInfo(xid, tcon, cifs_sb->local_nls);
-+              CIFSSMBQFSAttributeInfo(xid, tcon, cifs_sb->local_nls);
-+              if (tcon->ses->capabilities & CAP_UNIX)
-+                      CIFSSMBQFSUnixInfo(xid, tcon, cifs_sb->local_nls);
-+      }
-+
-+      /* volume_info.password is freed above when existing session found
-+      (in which case it is not needed anymore) but when new sesion is created
-+      the password ptr is put in the new session structure (in which case the
-+      password will be freed at unmount time) */
-+      if(volume_info.UNC)
-+              kfree(volume_info.UNC);
-+      FreeXid(xid);
-+      return rc;
-+}
-+
-+static int
-+CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
-+            char session_key[CIFS_SESSION_KEY_SIZE],
-+            const struct nls_table *nls_codepage)
-+{
-+      struct smb_hdr *smb_buffer;
-+      struct smb_hdr *smb_buffer_response;
-+      SESSION_SETUP_ANDX *pSMB;
-+      SESSION_SETUP_ANDX *pSMBr;
-+      char *bcc_ptr;
-+      char *user = ses->userName;
-+      char *domain = ses->domainName;
-+      int rc = 0;
-+      int remaining_words = 0;
-+      int bytes_returned = 0;
-+      int len;
-+
-+      cFYI(1, ("In sesssetup "));
-+
-+      smb_buffer = cifs_buf_get();
-+      if (smb_buffer == 0) {
-+              return -ENOMEM;
-+      }
-+      smb_buffer_response = smb_buffer;
-+      pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
-+
-+      /* send SMBsessionSetup here */
-+      header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
-+                      NULL /* no tCon exists yet */ , 13 /* wct */ );
-+
-+      pSMB->req_no_secext.AndXCommand = 0xFF;
-+      pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
-+      pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
-+
-+      if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
-+              smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
-+
-+      pSMB->req_no_secext.Capabilities =
-+          CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS;
-+      if (ses->capabilities & CAP_UNICODE) {
-+              smb_buffer->Flags2 |= SMBFLG2_UNICODE;
-+              pSMB->req_no_secext.Capabilities |= CAP_UNICODE;
-+      }
-+      if (ses->capabilities & CAP_STATUS32) {
-+              smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
-+              pSMB->req_no_secext.Capabilities |= CAP_STATUS32;
-+      }
-+      if (ses->capabilities & CAP_DFS) {
-+              smb_buffer->Flags2 |= SMBFLG2_DFS;
-+              pSMB->req_no_secext.Capabilities |= CAP_DFS;
-+      }
-+      pSMB->req_no_secext.Capabilities =
-+          cpu_to_le32(pSMB->req_no_secext.Capabilities);
-+      /* pSMB->req_no_secext.CaseInsensitivePasswordLength =
-+         CIFS_SESSION_KEY_SIZE; */
-+      pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
-+      pSMB->req_no_secext.CaseSensitivePasswordLength =
-+          cpu_to_le16(CIFS_SESSION_KEY_SIZE);
-+      bcc_ptr = pByteArea(smb_buffer);
-+      /* memcpy(bcc_ptr, (char *) lm_session_key, CIFS_SESSION_KEY_SIZE);
-+         bcc_ptr += CIFS_SESSION_KEY_SIZE; */
-+      memcpy(bcc_ptr, (char *) session_key, CIFS_SESSION_KEY_SIZE);
-+      bcc_ptr += CIFS_SESSION_KEY_SIZE;
-+
-+      if (ses->capabilities & CAP_UNICODE) {
-+              if ((long) bcc_ptr % 2) {       /* must be word aligned for Unicode */
-+                      *bcc_ptr = 0;
-+                      bcc_ptr++;
-+              }
-+              if(user == NULL)
-+                      bytes_returned = 0; /* skill null user */
-+              else
-+                      bytes_returned =
-+                              cifs_strtoUCS((wchar_t *) bcc_ptr, user, 100,
-+                                      nls_codepage);
-+              bcc_ptr += 2 * bytes_returned;  /* convert num 16 bit words to bytes */
-+              bcc_ptr += 2;   /* trailing null */
-+              if (domain == NULL)
-+                      bytes_returned =
-+                          cifs_strtoUCS((wchar_t *) bcc_ptr,
-+                                        "CIFS_LINUX_DOM", 32, nls_codepage);
-+              else
-+                      bytes_returned =
-+                          cifs_strtoUCS((wchar_t *) bcc_ptr, domain, 64,
-+                                        nls_codepage);
-+              bcc_ptr += 2 * bytes_returned;
-+              bcc_ptr += 2;
-+              bytes_returned =
-+                  cifs_strtoUCS((wchar_t *) bcc_ptr, "Linux version ",
-+                                32, nls_codepage);
-+              bcc_ptr += 2 * bytes_returned;
-+              bytes_returned =
-+                  cifs_strtoUCS((wchar_t *) bcc_ptr, UTS_RELEASE, 32,
-+                                nls_codepage);
-+              bcc_ptr += 2 * bytes_returned;
-+              bcc_ptr += 2;
-+              bytes_returned =
-+                  cifs_strtoUCS((wchar_t *) bcc_ptr, CIFS_NETWORK_OPSYS,
-+                                64, nls_codepage);
-+              bcc_ptr += 2 * bytes_returned;
-+              bcc_ptr += 2;
-+      } else {
-+              if(user != NULL) {                
-+                  strncpy(bcc_ptr, user, 200);
-+                  bcc_ptr += strnlen(user, 200);
-+              }
-+              *bcc_ptr = 0;
-+              bcc_ptr++;
-+              if (domain == NULL) {
-+                      strcpy(bcc_ptr, "CIFS_LINUX_DOM");
-+                      bcc_ptr += strlen("CIFS_LINUX_DOM") + 1;
-+              } else {
-+                      strncpy(bcc_ptr, domain, 64);
-+                      bcc_ptr += strnlen(domain, 64);
-+                      *bcc_ptr = 0;
-+                      bcc_ptr++;
-+              }
-+              strcpy(bcc_ptr, "Linux version ");
-+              bcc_ptr += strlen("Linux version ");
-+              strcpy(bcc_ptr, UTS_RELEASE);
-+              bcc_ptr += strlen(UTS_RELEASE) + 1;
-+              strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
-+              bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
-+      }
-+      BCC(smb_buffer) = (long) bcc_ptr - (long) pByteArea(smb_buffer);
-+      smb_buffer->smb_buf_length += BCC(smb_buffer);
-+      BCC(smb_buffer) = cpu_to_le16(BCC(smb_buffer));
-+
-+      rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
-+                       &bytes_returned, 1);
-+      if (rc) {
-+/* rc = map_smb_to_linux_error(smb_buffer_response); now done in SendReceive */
-+      } else if ((smb_buffer_response->WordCount == 3)
-+                 || (smb_buffer_response->WordCount == 4)) {
-+              pSMBr->resp.Action = le16_to_cpu(pSMBr->resp.Action);
-+              if (pSMBr->resp.Action & GUEST_LOGIN)
-+                      cFYI(1, (" Guest login"));      /* do we want to mark SesInfo struct ? */
-+              if (ses) {
-+                      ses->Suid = smb_buffer_response->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 */
-+                      bcc_ptr = pByteArea(smb_buffer_response);       
-+                      if ((pSMBr->resp.hdr.WordCount == 3)
-+                          || ((pSMBr->resp.hdr.WordCount == 4)
-+                              && (pSMBr->resp.SecurityBlobLength <
-+                                  pSMBr->resp.ByteCount))) {
-+                              if (pSMBr->resp.hdr.WordCount == 4)
-+                                      bcc_ptr +=
-+                                          pSMBr->resp.SecurityBlobLength;
-+
-+                              if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
-+                                      if ((long) (bcc_ptr) % 2) {
-+                                              remaining_words =
-+                                                  (BCC(smb_buffer_response)
-+                                                   - 1) / 2;
-+                                              bcc_ptr++;      /* Unicode strings must be word aligned */
-+                                      } else {
-+                                              remaining_words =
-+                                                  BCC
-+                                                  (smb_buffer_response) / 2;
-+                                      }
-+                                      len =
-+                                          UniStrnlen((wchar_t *) bcc_ptr,
-+                                                     remaining_words - 1);
-+/* We look for obvious messed up bcc or strings in response so we do not go off
-+   the end since (at least) WIN2K and Windows XP have a major bug in not null
-+   terminating last Unicode string in response  */
-+                                      ses->serverOS = cifs_kcalloc(2 * (len + 1), GFP_KERNEL);
-+                                      cifs_strfromUCS_le(ses->serverOS,
-+                                                         (wchar_t *)bcc_ptr, len,nls_codepage);
-+                                      bcc_ptr += 2 * (len + 1);
-+                                      remaining_words -= len + 1;
-+                                      ses->serverOS[2 * len] = 0;
-+                                      ses->serverOS[1 + (2 * len)] = 0;
-+                                      if (remaining_words > 0) {
-+                                              len = UniStrnlen((wchar_t *)bcc_ptr,
-+                                                               remaining_words
-+                                                               - 1);
-+                                              ses->serverNOS =cifs_kcalloc(2 * (len + 1),GFP_KERNEL);
-+                                              cifs_strfromUCS_le(ses->serverNOS,
-+                                                                 (wchar_t *)bcc_ptr,len,nls_codepage);
-+                                              bcc_ptr += 2 * (len + 1);
-+                                              ses->serverNOS[2 * len] = 0;
-+                                              ses->serverNOS[1 + (2 * len)] = 0;
-+                                              remaining_words -= len + 1;
-+                                              if (remaining_words > 0) {
-+                                                      len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); 
-+          /* last string is not always null terminated (for e.g. for Windows XP & 2000) */
-+                                                      ses->serverDomain =
-+                                                          cifs_kcalloc(2*(len+1),GFP_KERNEL);
-+                                                      cifs_strfromUCS_le(ses->serverDomain,
-+                                                           (wchar_t *)bcc_ptr,len,nls_codepage);
-+                                                      bcc_ptr += 2 * (len + 1);
-+                                                      ses->serverDomain[2*len] = 0;
-+                                                      ses->serverDomain[1+(2*len)] = 0;
-+                                              } /* else no more room so create dummy domain string */
-+                                              else
-+                                                      ses->serverDomain =
-+                                                          cifs_kcalloc(2,
-+                                                                  GFP_KERNEL);
-+                                      } else {        /* no room so create dummy domain and NOS string */
-+                                              ses->serverDomain =
-+                                                  cifs_kcalloc(2, GFP_KERNEL);
-+                                              ses->serverNOS =
-+                                                  cifs_kcalloc(2, GFP_KERNEL);
-+                                      }
-+                              } else {        /* ASCII */
-+                                      len = strnlen(bcc_ptr, 1024);
-+                                      if (((long) bcc_ptr + len) - (long)
-+                                          pByteArea(smb_buffer_response)
-+                                          <= BCC(smb_buffer_response)) {
-+                                              ses->serverOS = cifs_kcalloc(len + 1,GFP_KERNEL);
-+                                              strncpy(ses->serverOS,bcc_ptr, len);
-+
-+                                              bcc_ptr += len;
-+                                              bcc_ptr[0] = 0; /* null terminate the string */
-+                                              bcc_ptr++;
-+
-+                                              len = strnlen(bcc_ptr, 1024);
-+                                              ses->serverNOS = cifs_kcalloc(len + 1,GFP_KERNEL);
-+                                              strncpy(ses->serverNOS, bcc_ptr, len);
-+                                              bcc_ptr += len;
-+                                              bcc_ptr[0] = 0;
-+                                              bcc_ptr++;
-+
-+                                              len = strnlen(bcc_ptr, 1024);
-+                                              ses->serverDomain = cifs_kcalloc(len + 1,GFP_KERNEL);
-+                                              strncpy(ses->serverDomain, bcc_ptr, len);
-+                                              bcc_ptr += len;
-+                                              bcc_ptr[0] = 0;
-+                                              bcc_ptr++;
-+                                      } else
-+                                              cFYI(1,
-+                                                   ("Variable field of length %d extends beyond end of smb ",
-+                                                    len));
-+                              }
-+                      } else {
-+                              cERROR(1,
-+                                     (" Security Blob Length extends beyond end of SMB"));
-+                      }
-+              } else {
-+                      cERROR(1, ("No session structure passed in."));
-+              }
-+      } else {
-+              cERROR(1,
-+                     (" Invalid Word count %d: ",
-+                      smb_buffer_response->WordCount));
-+              rc = -EIO;
-+      }
-+      
-+      if (smb_buffer)
-+              cifs_buf_release(smb_buffer);
-+
-+      return rc;
-+}
-+
-+static int
-+CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
-+              char *SecurityBlob,int SecurityBlobLength,
-+              const struct nls_table *nls_codepage)
-+{
-+      struct smb_hdr *smb_buffer;
-+      struct smb_hdr *smb_buffer_response;
-+      SESSION_SETUP_ANDX *pSMB;
-+      SESSION_SETUP_ANDX *pSMBr;
-+      char *bcc_ptr;
-+      char *user = ses->userName;
-+      char *domain = ses->domainName;
-+      int rc = 0;
-+      int remaining_words = 0;
-+      int bytes_returned = 0;
-+      int len;
-+
-+      cFYI(1, ("In spnego sesssetup "));
-+
-+      smb_buffer = cifs_buf_get();
-+      if (smb_buffer == 0) {
-+              return -ENOMEM;
-+      }
-+      smb_buffer_response = smb_buffer;
-+      pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
-+
-+      /* send SMBsessionSetup here */
-+      header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
-+                      NULL /* no tCon exists yet */ , 12 /* wct */ );
-+      pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
-+      pSMB->req.AndXCommand = 0xFF;
-+      pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
-+      pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
-+
-+      if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
-+              smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
-+
-+      pSMB->req.Capabilities =
-+          CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
-+          CAP_EXTENDED_SECURITY;
-+      if (ses->capabilities & CAP_UNICODE) {
-+              smb_buffer->Flags2 |= SMBFLG2_UNICODE;
-+              pSMB->req.Capabilities |= CAP_UNICODE;
-+      }
-+      if (ses->capabilities & CAP_STATUS32) {
-+              smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
-+              pSMB->req.Capabilities |= CAP_STATUS32;
-+      }
-+      if (ses->capabilities & CAP_DFS) {
-+              smb_buffer->Flags2 |= SMBFLG2_DFS;
-+              pSMB->req.Capabilities |= CAP_DFS;
-+      }
-+      pSMB->req.Capabilities = cpu_to_le32(pSMB->req.Capabilities);
-+
-+      pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
-+      bcc_ptr = pByteArea(smb_buffer);
-+      memcpy(bcc_ptr, SecurityBlob, SecurityBlobLength);
-+      bcc_ptr += SecurityBlobLength;
-+
-+      if (ses->capabilities & CAP_UNICODE) {
-+              if ((long) bcc_ptr % 2) {       /* must be word aligned for Unicode strings */
-+                      *bcc_ptr = 0;
-+                      bcc_ptr++;
-+              }
-+              bytes_returned =
-+                  cifs_strtoUCS((wchar_t *) bcc_ptr, user, 100, nls_codepage);
-+              bcc_ptr += 2 * bytes_returned;  /* convert num of 16 bit words to bytes */
-+              bcc_ptr += 2;   /* trailing null */
-+              if (domain == NULL)
-+                      bytes_returned =
-+                          cifs_strtoUCS((wchar_t *) bcc_ptr,
-+                                        "CIFS_LINUX_DOM", 32, nls_codepage);
-+              else
-+                      bytes_returned =
-+                          cifs_strtoUCS((wchar_t *) bcc_ptr, domain, 64,
-+                                        nls_codepage);
-+              bcc_ptr += 2 * bytes_returned;
-+              bcc_ptr += 2;
-+              bytes_returned =
-+                  cifs_strtoUCS((wchar_t *) bcc_ptr, "Linux version ",
-+                                32, nls_codepage);
-+              bcc_ptr += 2 * bytes_returned;
-+              bytes_returned =
-+                  cifs_strtoUCS((wchar_t *) bcc_ptr, UTS_RELEASE, 32,
-+                                nls_codepage);
-+              bcc_ptr += 2 * bytes_returned;
-+              bcc_ptr += 2;
-+              bytes_returned =
-+                  cifs_strtoUCS((wchar_t *) bcc_ptr, CIFS_NETWORK_OPSYS,
-+                                64, nls_codepage);
-+              bcc_ptr += 2 * bytes_returned;
-+              bcc_ptr += 2;
-+      } else {
-+              strncpy(bcc_ptr, user, 200);
-+              bcc_ptr += strnlen(user, 200);
-+              *bcc_ptr = 0;
-+              bcc_ptr++;
-+              if (domain == NULL) {
-+                      strcpy(bcc_ptr, "CIFS_LINUX_DOM");
-+                      bcc_ptr += strlen("CIFS_LINUX_DOM") + 1;
-+              } else {
-+                      strncpy(bcc_ptr, domain, 64);
-+                      bcc_ptr += strnlen(domain, 64);
-+                      *bcc_ptr = 0;
-+                      bcc_ptr++;
-+              }
-+              strcpy(bcc_ptr, "Linux version ");
-+              bcc_ptr += strlen("Linux version ");
-+              strcpy(bcc_ptr, UTS_RELEASE);
-+              bcc_ptr += strlen(UTS_RELEASE) + 1;
-+              strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
-+              bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
-+      }
-+      BCC(smb_buffer) = (long) bcc_ptr - (long) pByteArea(smb_buffer);
-+      smb_buffer->smb_buf_length += BCC(smb_buffer);
-+      BCC(smb_buffer) = cpu_to_le16(BCC(smb_buffer));
-+
-+      rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
-+                       &bytes_returned, 1);
-+      if (rc) {
-+/*    rc = map_smb_to_linux_error(smb_buffer_response);  *//* done in SendReceive now */
-+      } else if ((smb_buffer_response->WordCount == 3)
-+                 || (smb_buffer_response->WordCount == 4)) {
-+              pSMBr->resp.Action = le16_to_cpu(pSMBr->resp.Action);
-+              pSMBr->resp.SecurityBlobLength =
-+                  le16_to_cpu(pSMBr->resp.SecurityBlobLength);
-+              if (pSMBr->resp.Action & GUEST_LOGIN)
-+                      cFYI(1, (" Guest login"));      /* BB do we want to set anything in SesInfo struct ? */
-+              if (ses) {
-+                      ses->Suid = smb_buffer_response->Uid;   /* UID left in wire format (le) */
-+                      cFYI(1, ("UID = %d ", ses->Suid));
-+                      bcc_ptr = pByteArea(smb_buffer_response);       /* response can have either 3 or 4 word count - Samba sends 3 */
-+
-+                      /* BB Fix below to make endian neutral !! */
-+
-+                      if ((pSMBr->resp.hdr.WordCount == 3)
-+                          || ((pSMBr->resp.hdr.WordCount == 4)
-+                              && (pSMBr->resp.SecurityBlobLength <
-+                                  pSMBr->resp.ByteCount))) {
-+                              if (pSMBr->resp.hdr.WordCount == 4) {
-+                                      bcc_ptr +=
-+                                          pSMBr->resp.SecurityBlobLength;
-+                                      cFYI(1,
-+                                           ("Security Blob Length %d ",
-+                                            pSMBr->resp.SecurityBlobLength));
-+                              }
-+
-+                              if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
-+                                      if ((long) (bcc_ptr) % 2) {
-+                                              remaining_words =
-+                                                  (BCC(smb_buffer_response)
-+                                                   - 1) / 2;
-+                                              bcc_ptr++;      /* Unicode strings must be word aligned */
-+                                      } else {
-+                                              remaining_words =
-+                                                  BCC
-+                                                  (smb_buffer_response) / 2;
-+                                      }
-+                                      len =
-+                                          UniStrnlen((wchar_t *) bcc_ptr,
-+                                                     remaining_words - 1);
-+/* We look for obvious messed up bcc or strings in response so we do not go off
-+   the end since (at least) WIN2K and Windows XP have a major bug in not null
-+   terminating last Unicode string in response  */
-+                                      ses->serverOS =
-+                                          cifs_kcalloc(2 * (len + 1), GFP_KERNEL);
-+                                      cifs_strfromUCS_le(ses->serverOS,
-+                                                         (wchar_t *)
-+                                                         bcc_ptr, len,
-+                                                         nls_codepage);
-+                                      bcc_ptr += 2 * (len + 1);
-+                                      remaining_words -= len + 1;
-+                                      ses->serverOS[2 * len] = 0;
-+                                      ses->serverOS[1 + (2 * len)] = 0;
-+                                      if (remaining_words > 0) {
-+                                              len = UniStrnlen((wchar_t *)bcc_ptr,
-+                                                               remaining_words
-+                                                               - 1);
-+                                              ses->serverNOS =
-+                                                  cifs_kcalloc(2 * (len + 1),
-+                                                          GFP_KERNEL);
-+                                              cifs_strfromUCS_le(ses->serverNOS,
-+                                                                 (wchar_t *)bcc_ptr,
-+                                                                 len,
-+                                                                 nls_codepage);
-+                                              bcc_ptr += 2 * (len + 1);
-+                                              ses->serverNOS[2 * len] = 0;
-+                                              ses->serverNOS[1 + (2 * len)] = 0;
-+                                              remaining_words -= len + 1;
-+                                              if (remaining_words > 0) {
-+                                                      len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); 
-+                            /* last string is not always null terminated (for e.g. for Windows XP & 2000) */
-+                                                      ses->serverDomain = cifs_kcalloc(2*(len+1),GFP_KERNEL);
-+                                                      cifs_strfromUCS_le(ses->serverDomain,
-+                                                           (wchar_t *)bcc_ptr, 
-+                                 len,
-+                                                           nls_codepage);
-+                                                      bcc_ptr += 2*(len+1);
-+                                                      ses->serverDomain[2*len] = 0;
-+                                                      ses->serverDomain[1+(2*len)] = 0;
-+                                              } /* else no more room so create dummy domain string */
-+                                              else
-+                                                      ses->serverDomain =
-+                                                          cifs_kcalloc(2,GFP_KERNEL);
-+                                      } else {        /* no room so create dummy domain and NOS string */
-+                                              ses->serverDomain = cifs_kcalloc(2, GFP_KERNEL);
-+                                              ses->serverNOS = cifs_kcalloc(2, GFP_KERNEL);
-+                                      }
-+                              } else {        /* ASCII */
-+
-+                                      len = strnlen(bcc_ptr, 1024);
-+                                      if (((long) bcc_ptr + len) - (long)
-+                                          pByteArea(smb_buffer_response)
-+                                          <= BCC(smb_buffer_response)) {
-+                                              ses->serverOS = cifs_kcalloc(len + 1, GFP_KERNEL);
-+                                              strncpy(ses->serverOS, bcc_ptr, len);
-+
-+                                              bcc_ptr += len;
-+                                              bcc_ptr[0] = 0; /* null terminate the string */
-+                                              bcc_ptr++;
-+
-+                                              len = strnlen(bcc_ptr, 1024);
-+                                              ses->serverNOS = cifs_kcalloc(len + 1,GFP_KERNEL);
-+                                              strncpy(ses->serverNOS, bcc_ptr, len);
-+                                              bcc_ptr += len;
-+                                              bcc_ptr[0] = 0;
-+                                              bcc_ptr++;
-+
-+                                              len = strnlen(bcc_ptr, 1024);
-+                                              ses->serverDomain = cifs_kcalloc(len + 1, GFP_KERNEL);
-+                                              strncpy(ses->serverDomain, bcc_ptr, len);
-+                                              bcc_ptr += len;
-+                                              bcc_ptr[0] = 0;
-+                                              bcc_ptr++;
-+                                      } else
-+                                              cFYI(1,
-+                                                   ("Variable field of length %d extends beyond end of smb ",
-+                                                    len));
-+                              }
-+                      } else {
-+                              cERROR(1,
-+                                     (" Security Blob Length extends beyond end of SMB"));
-+                      }
-+              } else {
-+                      cERROR(1, ("No session structure passed in."));
-+              }
-+      } else {
-+              cERROR(1,
-+                     (" Invalid Word count %d: ",
-+                      smb_buffer_response->WordCount));
-+              rc = -EIO;
-+      }
-+
-+      if (smb_buffer)
-+              cifs_buf_release(smb_buffer);
-+
-+      return rc;
-+}
-+
-+static int
-+CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
-+                            struct cifsSesInfo *ses, int * pNTLMv2_flag,
-+                            const struct nls_table *nls_codepage)
-+{
-+      struct smb_hdr *smb_buffer;
-+      struct smb_hdr *smb_buffer_response;
-+      SESSION_SETUP_ANDX *pSMB;
-+      SESSION_SETUP_ANDX *pSMBr;
-+      char *bcc_ptr;
-+      char *domain = ses->domainName;
-+      int rc = 0;
-+      int remaining_words = 0;
-+      int bytes_returned = 0;
-+      int len;
-+      int SecurityBlobLength = sizeof (NEGOTIATE_MESSAGE);
-+      PNEGOTIATE_MESSAGE SecurityBlob;
-+      PCHALLENGE_MESSAGE SecurityBlob2;
-+
-+      cFYI(1, ("In NTLMSSP sesssetup (negotiate) "));
-+      *pNTLMv2_flag = FALSE;
-+      smb_buffer = cifs_buf_get();
-+      if (smb_buffer == 0) {
-+              return -ENOMEM;
-+      }
-+      smb_buffer_response = smb_buffer;
-+      pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
-+      pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
-+
-+      /* send SMBsessionSetup here */
-+      header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
-+                      NULL /* no tCon exists yet */ , 12 /* wct */ );
-+      pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
-+      pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
-+
-+      pSMB->req.AndXCommand = 0xFF;
-+      pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
-+      pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
-+
-+      if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
-+              smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
-+
-+      pSMB->req.Capabilities =
-+          CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
-+          CAP_EXTENDED_SECURITY;
-+      if (ses->capabilities & CAP_UNICODE) {
-+              smb_buffer->Flags2 |= SMBFLG2_UNICODE;
-+              pSMB->req.Capabilities |= CAP_UNICODE;
-+      }
-+      if (ses->capabilities & CAP_STATUS32) {
-+              smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
-+              pSMB->req.Capabilities |= CAP_STATUS32;
-+      }
-+      if (ses->capabilities & CAP_DFS) {
-+              smb_buffer->Flags2 |= SMBFLG2_DFS;
-+              pSMB->req.Capabilities |= CAP_DFS;
-+      }
-+      pSMB->req.Capabilities = cpu_to_le32(pSMB->req.Capabilities);
-+
-+      bcc_ptr = (char *) &pSMB->req.SecurityBlob;
-+      SecurityBlob = (PNEGOTIATE_MESSAGE) bcc_ptr;
-+      strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
-+      SecurityBlob->MessageType = NtLmNegotiate;
-+      SecurityBlob->NegotiateFlags =
-+          NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM |
-+          NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM | 0x80000000 |
-+          /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128;
-+      if(sign_CIFS_PDUs)
-+              SecurityBlob->NegotiateFlags |= NTLMSSP_NEGOTIATE_SIGN;
-+      if(ntlmv2_support)
-+              SecurityBlob->NegotiateFlags |= NTLMSSP_NEGOTIATE_NTLMV2;
-+      /* setup pointers to domain name and workstation name */
-+      bcc_ptr += SecurityBlobLength;
-+
-+      SecurityBlob->WorkstationName.Buffer = 0;
-+      SecurityBlob->WorkstationName.Length = 0;
-+      SecurityBlob->WorkstationName.MaximumLength = 0;
-+
-+      if (domain == NULL) {
-+              SecurityBlob->DomainName.Buffer = 0;
-+              SecurityBlob->DomainName.Length = 0;
-+              SecurityBlob->DomainName.MaximumLength = 0;
-+      } else {
-+              SecurityBlob->NegotiateFlags |=
-+                  NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
-+              strncpy(bcc_ptr, domain, 63);
-+              SecurityBlob->DomainName.Length = strnlen(domain, 64);
-+              SecurityBlob->DomainName.MaximumLength =
-+                  cpu_to_le16(SecurityBlob->DomainName.Length);
-+              SecurityBlob->DomainName.Buffer =
-+                  cpu_to_le32((long) &SecurityBlob->
-+                              DomainString -
-+                              (long) &SecurityBlob->Signature);
-+              bcc_ptr += SecurityBlob->DomainName.Length;
-+              SecurityBlobLength += SecurityBlob->DomainName.Length;
-+              SecurityBlob->DomainName.Length =
-+                  cpu_to_le16(SecurityBlob->DomainName.Length);
-+      }
-+      if (ses->capabilities & CAP_UNICODE) {
-+              if ((long) bcc_ptr % 2) {
-+                      *bcc_ptr = 0;
-+                      bcc_ptr++;
-+              }
-+
-+              bytes_returned =
-+                  cifs_strtoUCS((wchar_t *) bcc_ptr, "Linux version ",
-+                                32, nls_codepage);
-+              bcc_ptr += 2 * bytes_returned;
-+              bytes_returned =
-+                  cifs_strtoUCS((wchar_t *) bcc_ptr, UTS_RELEASE, 32,
-+                                nls_codepage);
-+              bcc_ptr += 2 * bytes_returned;
-+              bcc_ptr += 2;   /* null terminate Linux version */
-+              bytes_returned =
-+                  cifs_strtoUCS((wchar_t *) bcc_ptr, CIFS_NETWORK_OPSYS,
-+                                64, nls_codepage);
-+              bcc_ptr += 2 * bytes_returned;
-+              *(bcc_ptr + 1) = 0;
-+              *(bcc_ptr + 2) = 0;
-+              bcc_ptr += 2;   /* null terminate network opsys string */
-+              *(bcc_ptr + 1) = 0;
-+              *(bcc_ptr + 2) = 0;
-+              bcc_ptr += 2;   /* null domain */
-+      } else {                /* ASCII */
-+              strcpy(bcc_ptr, "Linux version ");
-+              bcc_ptr += strlen("Linux version ");
-+              strcpy(bcc_ptr, UTS_RELEASE);
-+              bcc_ptr += strlen(UTS_RELEASE) + 1;
-+              strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
-+              bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
-+              bcc_ptr++;      /* empty domain field */
-+              *bcc_ptr = 0;
-+      }
-+      SecurityBlob->NegotiateFlags =
-+          cpu_to_le32(SecurityBlob->NegotiateFlags);
-+      pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
-+      BCC(smb_buffer) = (long) bcc_ptr - (long) pByteArea(smb_buffer);
-+      smb_buffer->smb_buf_length += BCC(smb_buffer);
-+      BCC(smb_buffer) = cpu_to_le16(BCC(smb_buffer));
-+
-+      rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
-+                       &bytes_returned, 1);
-+
-+      if (smb_buffer_response->Status.CifsError ==
-+          (NT_STATUS_MORE_PROCESSING_REQUIRED))
-+              rc = 0;
-+
-+      if (rc) {
-+/*    rc = map_smb_to_linux_error(smb_buffer_response);  *//* done in SendReceive now */
-+      } else if ((smb_buffer_response->WordCount == 3)
-+                 || (smb_buffer_response->WordCount == 4)) {
-+              pSMBr->resp.Action = le16_to_cpu(pSMBr->resp.Action);
-+              pSMBr->resp.SecurityBlobLength =
-+                  le16_to_cpu(pSMBr->resp.SecurityBlobLength);
-+              if (pSMBr->resp.Action & GUEST_LOGIN)
-+                      cFYI(1, (" Guest login"));      
-+        /* Do we want to set anything in SesInfo struct when guest login? */
-+
-+              bcc_ptr = pByteArea(smb_buffer_response);       
-+        /* response can have either 3 or 4 word count - Samba sends 3 */
-+
-+              SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr;
-+              if (SecurityBlob2->MessageType != NtLmChallenge) {
-+                      cFYI(1,
-+                           ("Unexpected NTLMSSP message type received %d",
-+                            SecurityBlob2->MessageType));
-+              } else if (ses) {
-+                      ses->Suid = smb_buffer_response->Uid; /* UID left in le format */ 
-+                      cFYI(1, ("UID = %d ", ses->Suid));
-+                      if ((pSMBr->resp.hdr.WordCount == 3)
-+                          || ((pSMBr->resp.hdr.WordCount == 4)
-+                              && (pSMBr->resp.SecurityBlobLength <
-+                                  pSMBr->resp.ByteCount))) {
-+                              if (pSMBr->resp.hdr.WordCount == 4) {
-+                                      bcc_ptr +=
-+                                          pSMBr->resp.SecurityBlobLength;
-+                                      cFYI(1,
-+                                           ("Security Blob Length %d ",
-+                                            pSMBr->resp.SecurityBlobLength));
-+                              }
-+
-+                              cFYI(1, ("NTLMSSP Challenge rcvd "));
-+
-+                              memcpy(ses->server->cryptKey,
-+                                     SecurityBlob2->Challenge,
-+                                     CIFS_CRYPTO_KEY_SIZE);
-+                              if(SecurityBlob2->NegotiateFlags & NTLMSSP_NEGOTIATE_NTLMV2)
-+                                      *pNTLMv2_flag = TRUE;
-+
-+                              if((SecurityBlob2->NegotiateFlags & 
-+                                      NTLMSSP_NEGOTIATE_ALWAYS_SIGN) 
-+                                      || (sign_CIFS_PDUs > 1))
-+                                              ses->server->secMode |= 
-+                                                      SECMODE_SIGN_REQUIRED;  
-+                              if ((SecurityBlob2->NegotiateFlags & 
-+                                      NTLMSSP_NEGOTIATE_SIGN) && (sign_CIFS_PDUs))
-+                                              ses->server->secMode |= 
-+                                                      SECMODE_SIGN_ENABLED;
-+
-+                              if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
-+                                      if ((long) (bcc_ptr) % 2) {
-+                                              remaining_words =
-+                                                  (BCC(smb_buffer_response)
-+                                                   - 1) / 2;
-+                                              bcc_ptr++;      /* Unicode strings must be word aligned */
-+                                      } else {
-+                                              remaining_words =
-+                                                  BCC
-+                                                  (smb_buffer_response) / 2;
-+                                      }
-+                                      len =
-+                                          UniStrnlen((wchar_t *) bcc_ptr,
-+                                                     remaining_words - 1);
-+/* We look for obvious messed up bcc or strings in response so we do not go off
-+   the end since (at least) WIN2K and Windows XP have a major bug in not null
-+   terminating last Unicode string in response  */
-+                                      ses->serverOS =
-+                                          cifs_kcalloc(2 * (len + 1), GFP_KERNEL);
-+                                      cifs_strfromUCS_le(ses->serverOS,
-+                                                         (wchar_t *)
-+                                                         bcc_ptr, len,
-+                                                         nls_codepage);
-+                                      bcc_ptr += 2 * (len + 1);
-+                                      remaining_words -= len + 1;
-+                                      ses->serverOS[2 * len] = 0;
-+                                      ses->serverOS[1 + (2 * len)] = 0;
-+                                      if (remaining_words > 0) {
-+                                              len = UniStrnlen((wchar_t *)
-+                                                               bcc_ptr,
-+                                                               remaining_words
-+                                                               - 1);
-+                                              ses->serverNOS =
-+                                                  cifs_kcalloc(2 * (len + 1),
-+                                                          GFP_KERNEL);
-+                                              cifs_strfromUCS_le(ses->
-+                                                                 serverNOS,
-+                                                                 (wchar_t *)
-+                                                                 bcc_ptr,
-+                                                                 len,
-+                                                                 nls_codepage);
-+                                              bcc_ptr += 2 * (len + 1);
-+                                              ses->serverNOS[2 * len] = 0;
-+                                              ses->serverNOS[1 +
-+                                                             (2 * len)] = 0;
-+                                              remaining_words -= len + 1;
-+                                              if (remaining_words > 0) {
-+                                                      len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); 
-+           /* last string is not always null terminated (for e.g. for Windows XP & 2000) */
-+                                                      ses->serverDomain =
-+                                                          cifs_kcalloc(2 *
-+                                                                  (len +
-+                                                                   1),
-+                                                                  GFP_KERNEL);
-+                                                      cifs_strfromUCS_le
-+                                                          (ses->
-+                                                           serverDomain,
-+                                                           (wchar_t *)
-+                                                           bcc_ptr, len,
-+                                                           nls_codepage);
-+                                                      bcc_ptr +=
-+                                                          2 * (len + 1);
-+                                                      ses->
-+                                                          serverDomain[2
-+                                                                       * len]
-+                                                          = 0;
-+                                                      ses->
-+                                                          serverDomain[1
-+                                                                       +
-+                                                                       (2
-+                                                                        *
-+                                                                        len)]
-+                                                          = 0;
-+                                              } /* else no more room so create dummy domain string */
-+                                              else
-+                                                      ses->serverDomain =
-+                                                          cifs_kcalloc(2,
-+                                                                  GFP_KERNEL);
-+                                      } else {        /* no room so create dummy domain and NOS string */
-+                                              ses->serverDomain =
-+                                                  cifs_kcalloc(2, GFP_KERNEL);
-+                                              ses->serverNOS =
-+                                                  cifs_kcalloc(2, GFP_KERNEL);
-+                                      }
-+                              } else {        /* ASCII */
-+                                      len = strnlen(bcc_ptr, 1024);
-+                                      if (((long) bcc_ptr + len) - (long)
-+                                          pByteArea(smb_buffer_response)
-+                                          <= BCC(smb_buffer_response)) {
-+                                              ses->serverOS =
-+                                                  cifs_kcalloc(len + 1,
-+                                                          GFP_KERNEL);
-+                                              strncpy(ses->serverOS,
-+                                                      bcc_ptr, len);
-+
-+                                              bcc_ptr += len;
-+                                              bcc_ptr[0] = 0; /* null terminate string */
-+                                              bcc_ptr++;
-+
-+                                              len = strnlen(bcc_ptr, 1024);
-+                                              ses->serverNOS =
-+                                                  cifs_kcalloc(len + 1,
-+                                                          GFP_KERNEL);
-+                                              strncpy(ses->serverNOS, bcc_ptr, len);
-+                                              bcc_ptr += len;
-+                                              bcc_ptr[0] = 0;
-+                                              bcc_ptr++;
-+
-+                                              len = strnlen(bcc_ptr, 1024);
-+                                              ses->serverDomain =
-+                                                  cifs_kcalloc(len + 1,
-+                                                          GFP_KERNEL);
-+                                              strncpy(ses->serverDomain, bcc_ptr, len);       
-+                                              bcc_ptr += len;
-+                                              bcc_ptr[0] = 0;
-+                                              bcc_ptr++;
-+                                      } else
-+                                              cFYI(1,
-+                                                   ("Variable field of length %d extends beyond end of smb ",
-+                                                    len));
-+                              }
-+                      } else {
-+                              cERROR(1,
-+                                     (" Security Blob Length extends beyond end of SMB"));
-+                      }
-+              } else {
-+                      cERROR(1, ("No session structure passed in."));
-+              }
-+      } else {
-+              cERROR(1,
-+                     (" Invalid Word count %d: ",
-+                      smb_buffer_response->WordCount));
-+              rc = -EIO;
-+      }
-+
-+      if (smb_buffer)
-+              cifs_buf_release(smb_buffer);
-+
-+      return rc;
-+}
-+
-+static int
-+CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
-+              char *ntlm_session_key, int ntlmv2_flag,
-+              const struct nls_table *nls_codepage)
-+{
-+      struct smb_hdr *smb_buffer;
-+      struct smb_hdr *smb_buffer_response;
-+      SESSION_SETUP_ANDX *pSMB;
-+      SESSION_SETUP_ANDX *pSMBr;
-+      char *bcc_ptr;
-+      char *user = ses->userName;
-+      char *domain = ses->domainName;
-+      int rc = 0;
-+      int remaining_words = 0;
-+      int bytes_returned = 0;
-+      int len;
-+      int SecurityBlobLength = sizeof (AUTHENTICATE_MESSAGE);
-+      PAUTHENTICATE_MESSAGE SecurityBlob;
-+
-+      cFYI(1, ("In NTLMSSPSessSetup (Authenticate)"));
-+
-+      smb_buffer = cifs_buf_get();
-+      if (smb_buffer == 0) {
-+              return -ENOMEM;
-+      }
-+      smb_buffer_response = smb_buffer;
-+      pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
-+      pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
-+
-+      /* send SMBsessionSetup here */
-+      header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
-+                      NULL /* no tCon exists yet */ , 12 /* wct */ );
-+      pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
-+      pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
-+      pSMB->req.AndXCommand = 0xFF;
-+      pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
-+      pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
-+
-+      pSMB->req.hdr.Uid = ses->Suid;
-+
-+      if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
-+              smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
-+
-+      pSMB->req.Capabilities =
-+          CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
-+          CAP_EXTENDED_SECURITY;
-+      if (ses->capabilities & CAP_UNICODE) {
-+              smb_buffer->Flags2 |= SMBFLG2_UNICODE;
-+              pSMB->req.Capabilities |= CAP_UNICODE;
-+      }
-+      if (ses->capabilities & CAP_STATUS32) {
-+              smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
-+              pSMB->req.Capabilities |= CAP_STATUS32;
-+      }
-+      if (ses->capabilities & CAP_DFS) {
-+              smb_buffer->Flags2 |= SMBFLG2_DFS;
-+              pSMB->req.Capabilities |= CAP_DFS;
-+      }
-+      pSMB->req.Capabilities = cpu_to_le32(pSMB->req.Capabilities);
-+
-+      bcc_ptr = (char *) &pSMB->req.SecurityBlob;
-+      SecurityBlob = (PAUTHENTICATE_MESSAGE) bcc_ptr;
-+      strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
-+      SecurityBlob->MessageType = NtLmAuthenticate;
-+      bcc_ptr += SecurityBlobLength;
-+      SecurityBlob->NegotiateFlags =
-+          NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
-+          NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
-+          0x80000000 | NTLMSSP_NEGOTIATE_128;
-+      if(sign_CIFS_PDUs)
-+              SecurityBlob->NegotiateFlags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN;
-+      if(ntlmv2_flag)
-+              SecurityBlob->NegotiateFlags |= NTLMSSP_NEGOTIATE_NTLMV2;
-+
-+/* setup pointers to domain name and workstation name */
-+
-+      SecurityBlob->WorkstationName.Buffer = 0;
-+      SecurityBlob->WorkstationName.Length = 0;
-+      SecurityBlob->WorkstationName.MaximumLength = 0;
-+      SecurityBlob->SessionKey.Length = 0;
-+      SecurityBlob->SessionKey.MaximumLength = 0;
-+      SecurityBlob->SessionKey.Buffer = 0;
-+
-+      SecurityBlob->LmChallengeResponse.Length = 0;
-+      SecurityBlob->LmChallengeResponse.MaximumLength = 0;
-+      SecurityBlob->LmChallengeResponse.Buffer = 0;
-+
-+      SecurityBlob->NtChallengeResponse.Length =
-+          cpu_to_le16(CIFS_SESSION_KEY_SIZE);
-+      SecurityBlob->NtChallengeResponse.MaximumLength =
-+          cpu_to_le16(CIFS_SESSION_KEY_SIZE);
-+      memcpy(bcc_ptr, ntlm_session_key, CIFS_SESSION_KEY_SIZE);
-+      SecurityBlob->NtChallengeResponse.Buffer =
-+          cpu_to_le32(SecurityBlobLength);
-+      SecurityBlobLength += CIFS_SESSION_KEY_SIZE;
-+      bcc_ptr += CIFS_SESSION_KEY_SIZE;
-+
-+      if (ses->capabilities & CAP_UNICODE) {
-+              if (domain == NULL) {
-+                      SecurityBlob->DomainName.Buffer = 0;
-+                      SecurityBlob->DomainName.Length = 0;
-+                      SecurityBlob->DomainName.MaximumLength = 0;
-+              } else {
-+                      SecurityBlob->DomainName.Length =
-+                          cifs_strtoUCS((wchar_t *) bcc_ptr, domain, 64,
-+                                        nls_codepage);
-+                      SecurityBlob->DomainName.Length *= 2;
-+                      SecurityBlob->DomainName.MaximumLength =
-+                          cpu_to_le16(SecurityBlob->DomainName.Length);
-+                      SecurityBlob->DomainName.Buffer =
-+                          cpu_to_le32(SecurityBlobLength);
-+                      bcc_ptr += SecurityBlob->DomainName.Length;
-+                      SecurityBlobLength += SecurityBlob->DomainName.Length;
-+                      SecurityBlob->DomainName.Length =
-+                          cpu_to_le16(SecurityBlob->DomainName.Length);
-+              }
-+              if (user == NULL) {
-+                      SecurityBlob->UserName.Buffer = 0;
-+                      SecurityBlob->UserName.Length = 0;
-+                      SecurityBlob->UserName.MaximumLength = 0;
-+              } else {
-+                      SecurityBlob->UserName.Length =
-+                          cifs_strtoUCS((wchar_t *) bcc_ptr, user, 64,
-+                                        nls_codepage);
-+                      SecurityBlob->UserName.Length *= 2;
-+                      SecurityBlob->UserName.MaximumLength =
-+                          cpu_to_le16(SecurityBlob->UserName.Length);
-+                      SecurityBlob->UserName.Buffer =
-+                          cpu_to_le32(SecurityBlobLength);
-+                      bcc_ptr += SecurityBlob->UserName.Length;
-+                      SecurityBlobLength += SecurityBlob->UserName.Length;
-+                      SecurityBlob->UserName.Length =
-+                          cpu_to_le16(SecurityBlob->UserName.Length);
-+              }
-+
-+              /* SecurityBlob->WorkstationName.Length = cifs_strtoUCS((wchar_t *) bcc_ptr, "AMACHINE",64, nls_codepage);
-+                 SecurityBlob->WorkstationName.Length *= 2;
-+                 SecurityBlob->WorkstationName.MaximumLength = cpu_to_le16(SecurityBlob->WorkstationName.Length);
-+                 SecurityBlob->WorkstationName.Buffer = cpu_to_le32(SecurityBlobLength);
-+                 bcc_ptr += SecurityBlob->WorkstationName.Length;
-+                 SecurityBlobLength += SecurityBlob->WorkstationName.Length;
-+                 SecurityBlob->WorkstationName.Length = cpu_to_le16(SecurityBlob->WorkstationName.Length);  */
-+
-+              if ((long) bcc_ptr % 2) {
-+                      *bcc_ptr = 0;
-+                      bcc_ptr++;
-+              }
-+              bytes_returned =
-+                  cifs_strtoUCS((wchar_t *) bcc_ptr, "Linux version ",
-+                                32, nls_codepage);
-+              bcc_ptr += 2 * bytes_returned;
-+              bytes_returned =
-+                  cifs_strtoUCS((wchar_t *) bcc_ptr, UTS_RELEASE, 32,
-+                                nls_codepage);
-+              bcc_ptr += 2 * bytes_returned;
-+              bcc_ptr += 2;   /* null term version string */
-+              bytes_returned =
-+                  cifs_strtoUCS((wchar_t *) bcc_ptr, CIFS_NETWORK_OPSYS,
-+                                64, nls_codepage);
-+              bcc_ptr += 2 * bytes_returned;
-+              *(bcc_ptr + 1) = 0;
-+              *(bcc_ptr + 2) = 0;
-+              bcc_ptr += 2;   /* null terminate network opsys string */
-+              *(bcc_ptr + 1) = 0;
-+              *(bcc_ptr + 2) = 0;
-+              bcc_ptr += 2;   /* null domain */
-+      } else {                /* ASCII */
-+              if (domain == NULL) {
-+                      SecurityBlob->DomainName.Buffer = 0;
-+                      SecurityBlob->DomainName.Length = 0;
-+                      SecurityBlob->DomainName.MaximumLength = 0;
-+              } else {
-+                      SecurityBlob->NegotiateFlags |=
-+                          NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
-+                      strncpy(bcc_ptr, domain, 63);
-+                      SecurityBlob->DomainName.Length = strnlen(domain, 64);
-+                      SecurityBlob->DomainName.MaximumLength =
-+                          cpu_to_le16(SecurityBlob->DomainName.Length);
-+                      SecurityBlob->DomainName.Buffer =
-+                          cpu_to_le32(SecurityBlobLength);
-+                      bcc_ptr += SecurityBlob->DomainName.Length;
-+                      SecurityBlobLength += SecurityBlob->DomainName.Length;
-+                      SecurityBlob->DomainName.Length =
-+                          cpu_to_le16(SecurityBlob->DomainName.Length);
-+              }
-+              if (user == NULL) {
-+                      SecurityBlob->UserName.Buffer = 0;
-+                      SecurityBlob->UserName.Length = 0;
-+                      SecurityBlob->UserName.MaximumLength = 0;
-+              } else {
-+                      strncpy(bcc_ptr, user, 63);
-+                      SecurityBlob->UserName.Length = strnlen(user, 64);
-+                      SecurityBlob->UserName.MaximumLength =
-+                          cpu_to_le16(SecurityBlob->UserName.Length);
-+                      SecurityBlob->UserName.Buffer =
-+                          cpu_to_le32(SecurityBlobLength);
-+                      bcc_ptr += SecurityBlob->UserName.Length;
-+                      SecurityBlobLength += SecurityBlob->UserName.Length;
-+                      SecurityBlob->UserName.Length =
-+                          cpu_to_le16(SecurityBlob->UserName.Length);
-+              }
-+              /* BB fill in our workstation name if known BB */
-+
-+              strcpy(bcc_ptr, "Linux version ");
-+              bcc_ptr += strlen("Linux version ");
-+              strcpy(bcc_ptr, UTS_RELEASE);
-+              bcc_ptr += strlen(UTS_RELEASE) + 1;
-+              strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
-+              bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
-+              bcc_ptr++;      /* null domain */
-+              *bcc_ptr = 0;
-+      }
-+      SecurityBlob->NegotiateFlags =
-+          cpu_to_le32(SecurityBlob->NegotiateFlags);
-+      pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
-+      BCC(smb_buffer) = (long) bcc_ptr - (long) pByteArea(smb_buffer);
-+      smb_buffer->smb_buf_length += BCC(smb_buffer);
-+      BCC(smb_buffer) = cpu_to_le16(BCC(smb_buffer));
-+
-+      rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
-+                       &bytes_returned, 1);
-+      if (rc) {
-+/*    rc = map_smb_to_linux_error(smb_buffer_response);  *//* done in SendReceive now */
-+      } else if ((smb_buffer_response->WordCount == 3)
-+                 || (smb_buffer_response->WordCount == 4)) {
-+              pSMBr->resp.Action = le16_to_cpu(pSMBr->resp.Action);
-+              pSMBr->resp.SecurityBlobLength =
-+                  le16_to_cpu(pSMBr->resp.SecurityBlobLength);
-+              if (pSMBr->resp.Action & GUEST_LOGIN)
-+                      cFYI(1, (" Guest login"));      /* BB do we want to set anything in SesInfo struct ? */
-+/*        if(SecurityBlob2->MessageType != NtLm??){                               
-+                 cFYI("Unexpected message type on auth response is %d ")); 
-+        } */
-+              if (ses) {
-+                      cFYI(1,
-+                           ("Does UID on challenge %d match auth response UID %d ",
-+                            ses->Suid, smb_buffer_response->Uid));
-+                      ses->Suid = smb_buffer_response->Uid; /* UID left in wire format */
-+                      bcc_ptr = pByteArea(smb_buffer_response);       
-+            /* response can have either 3 or 4 word count - Samba sends 3 */
-+                      if ((pSMBr->resp.hdr.WordCount == 3)
-+                          || ((pSMBr->resp.hdr.WordCount == 4)
-+                              && (pSMBr->resp.SecurityBlobLength <
-+                                  pSMBr->resp.ByteCount))) {
-+                              if (pSMBr->resp.hdr.WordCount == 4) {
-+                                      bcc_ptr +=
-+                                          pSMBr->resp.SecurityBlobLength;
-+                                      cFYI(1,
-+                                           ("Security Blob Length %d ",
-+                                            pSMBr->resp.SecurityBlobLength));
-+                              }
-+
-+                              cFYI(1,
-+                                   ("NTLMSSP response to Authenticate "));
-+
-+                              if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
-+                                      if ((long) (bcc_ptr) % 2) {
-+                                              remaining_words =
-+                                                  (BCC(smb_buffer_response)
-+                                                   - 1) / 2;
-+                                              bcc_ptr++;      /* Unicode strings must be word aligned */
-+                                      } else {
-+                                              remaining_words = BCC(smb_buffer_response) / 2;
-+                                      }
-+                                      len =
-+                                          UniStrnlen((wchar_t *) bcc_ptr,remaining_words - 1);
-+/* We look for obvious messed up bcc or strings in response so we do not go off
-+  the end since (at least) WIN2K and Windows XP have a major bug in not null
-+  terminating last Unicode string in response  */
-+                                      ses->serverOS =
-+                                          cifs_kcalloc(2 * (len + 1), GFP_KERNEL);
-+                                      cifs_strfromUCS_le(ses->serverOS,
-+                                                         (wchar_t *)
-+                                                         bcc_ptr, len,
-+                                                         nls_codepage);
-+                                      bcc_ptr += 2 * (len + 1);
-+                                      remaining_words -= len + 1;
-+                                      ses->serverOS[2 * len] = 0;
-+                                      ses->serverOS[1 + (2 * len)] = 0;
-+                                      if (remaining_words > 0) {
-+                                              len = UniStrnlen((wchar_t *)
-+                                                               bcc_ptr,
-+                                                               remaining_words
-+                                                               - 1);
-+                                              ses->serverNOS =
-+                                                  cifs_kcalloc(2 * (len + 1),
-+                                                          GFP_KERNEL);
-+                                              cifs_strfromUCS_le(ses->
-+                                                                 serverNOS,
-+                                                                 (wchar_t *)
-+                                                                 bcc_ptr,
-+                                                                 len,
-+                                                                 nls_codepage);
-+                                              bcc_ptr += 2 * (len + 1);
-+                                              ses->serverNOS[2 * len] = 0;
-+                                              ses->serverNOS[1+(2*len)] = 0;
-+                                              remaining_words -= len + 1;
-+                                              if (remaining_words > 0) {
-+                                                      len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words); 
-+     /* last string not always null terminated (e.g. for Windows XP & 2000) */
-+                                                      ses->serverDomain =
-+                                                          cifs_kcalloc(2 *
-+                                                                  (len +
-+                                                                   1),
-+                                                                  GFP_KERNEL);
-+                                                      cifs_strfromUCS_le
-+                                                          (ses->
-+                                                           serverDomain,
-+                                                           (wchar_t *)
-+                                                           bcc_ptr, len,
-+                                                           nls_codepage);
-+                                                      bcc_ptr +=
-+                                                          2 * (len + 1);
-+                                                      ses->
-+                                                          serverDomain[2
-+                                                                       * len]
-+                                                          = 0;
-+                                                      ses->
-+                                                          serverDomain[1
-+                                                                       +
-+                                                                       (2
-+                                                                        *
-+                                                                        len)]
-+                                                          = 0;
-+                                              } /* else no more room so create dummy domain string */
-+                                              else
-+                                                      ses->serverDomain = cifs_kcalloc(2,GFP_KERNEL);
-+                                      } else {  /* no room so create dummy domain and NOS string */
-+                                              ses->serverDomain = cifs_kcalloc(2, GFP_KERNEL);
-+                                              ses->serverNOS = cifs_kcalloc(2, GFP_KERNEL);
-+                                      }
-+                              } else {        /* ASCII */
-+                                      len = strnlen(bcc_ptr, 1024);
-+                                      if (((long) bcc_ptr + len) - 
-+                        (long) pByteArea(smb_buffer_response) 
-+                            <= BCC(smb_buffer_response)) {
-+                                              ses->serverOS = cifs_kcalloc(len + 1,GFP_KERNEL);
-+                                              strncpy(ses->serverOS,bcc_ptr, len);
-+
-+                                              bcc_ptr += len;
-+                                              bcc_ptr[0] = 0; /* null terminate the string */
-+                                              bcc_ptr++;
-+
-+                                              len = strnlen(bcc_ptr, 1024);
-+                                              ses->serverNOS = cifs_kcalloc(len+1,GFP_KERNEL);
-+                                              strncpy(ses->serverNOS, bcc_ptr, len);  
-+                                              bcc_ptr += len;
-+                                              bcc_ptr[0] = 0;
-+                                              bcc_ptr++;
-+
-+                                              len = strnlen(bcc_ptr, 1024);
-+                                              ses->serverDomain = cifs_kcalloc(len+1,GFP_KERNEL);
-+                                              strncpy(ses->serverDomain, bcc_ptr, len);
-+                                              bcc_ptr += len;
-+                                              bcc_ptr[0] = 0;
-+                                              bcc_ptr++;
-+                                      } else
-+                                              cFYI(1,
-+                                                   ("Variable field of length %d extends beyond end of smb ",
-+                                                    len));
-+                              }
-+                      } else {
-+                              cERROR(1,
-+                                     (" Security Blob Length extends beyond end of SMB"));
-+                      }
-+              } else {
-+                      cERROR(1, ("No session structure passed in."));
-+              }
-+      } else {
-+              cERROR(1,
-+                     (" Invalid Word count %d: ",
-+                      smb_buffer_response->WordCount));
-+              rc = -EIO;
-+      }
-+
-+      if (smb_buffer)
-+              cifs_buf_release(smb_buffer);
-+
-+      return rc;
-+}
-+
-+int
-+CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
-+       const char *tree, struct cifsTconInfo *tcon,
-+       const struct nls_table *nls_codepage)
-+{
-+      struct smb_hdr *smb_buffer;
-+      struct smb_hdr *smb_buffer_response;
-+      TCONX_REQ *pSMB;
-+      TCONX_RSP *pSMBr;
-+      char *bcc_ptr;
-+      int rc = 0;
-+      int length;
-+
-+      if (ses == NULL)
-+              return -EIO;
-+
-+      smb_buffer = cifs_buf_get();
-+      if (smb_buffer == 0) {
-+              return -ENOMEM;
-+      }
-+      smb_buffer_response = smb_buffer;
-+
-+      header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
-+                      NULL /*no tid */ , 4 /*wct */ );
-+      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);
-+      pSMB->PasswordLength = cpu_to_le16(1);  /* minimum */
-+      bcc_ptr = &(pSMB->Password[0]);
-+      bcc_ptr++;              /* skip password */
-+
-+      if(ses->server->secMode & (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_strtoUCS((wchar_t *) bcc_ptr, tree, 100, nls_codepage);
-+              bcc_ptr += 2 * length;  /* convert num of 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;
-+      BCC(smb_buffer) = (long) bcc_ptr - (long) pByteArea(smb_buffer);
-+      smb_buffer->smb_buf_length += BCC(smb_buffer);
-+      BCC(smb_buffer) = cpu_to_le16(BCC(smb_buffer));
-+
-+      rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length, 0);
-+
-+      /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */
-+      /* above now done in SendReceive */
-+      if ((rc == 0) && (tcon != NULL)) {
-+        tcon->tidStatus = CifsGood;
-+              tcon->tid = smb_buffer_response->Tid;
-+              bcc_ptr = pByteArea(smb_buffer_response);
-+              length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
-+        /* skip service field (NB: this field is always ASCII) */
-+              bcc_ptr += length + 1;  
-+              strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
-+              if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
-+                      length = UniStrnlen((wchar_t *) bcc_ptr, 512);
-+                      if (((long) bcc_ptr + (2 * length)) -
-+                          (long) pByteArea(smb_buffer_response) <=
-+                          BCC(smb_buffer_response)) {
-+                              if(tcon->nativeFileSystem)
-+                                      kfree(tcon->nativeFileSystem);
-+                              tcon->nativeFileSystem =
-+                                  cifs_kcalloc(length + 2, GFP_KERNEL);
-+                              cifs_strfromUCS_le(tcon->nativeFileSystem,
-+                                                 (wchar_t *) bcc_ptr,
-+                                                 length, nls_codepage);
-+                              bcc_ptr += 2 * length;
-+                              bcc_ptr[0] = 0; /* null terminate the string */
-+                              bcc_ptr[1] = 0;
-+                              bcc_ptr += 2;
-+                      }
-+                      /* else do not bother copying these informational fields */
-+              } else {
-+                      length = strnlen(bcc_ptr, 1024);
-+                      if (((long) bcc_ptr + length) -
-+                          (long) pByteArea(smb_buffer_response) <=
-+                          BCC(smb_buffer_response)) {
-+                              if(tcon->nativeFileSystem)
-+                                      kfree(tcon->nativeFileSystem);
-+                              tcon->nativeFileSystem =
-+                                  cifs_kcalloc(length + 1, GFP_KERNEL);
-+                              strncpy(tcon->nativeFileSystem, bcc_ptr,
-+                                      length);
-+                      }
-+                      /* else do not bother copying these informational fields */
-+              }
-+              tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
-+              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;
-+      }
-+
-+      if (smb_buffer)
-+              cifs_buf_release(smb_buffer);
-+      return rc;
-+}
-+
-+int
-+cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
-+{
-+      int rc = 0;
-+      int xid;
-+      struct cifsSesInfo *ses = NULL;
-+      struct task_struct *cifsd_task;
-+
-+      xid = GetXid();
-+
-+      if (cifs_sb->tcon) {
-+              ses = cifs_sb->tcon->ses; /* save ptr to ses before delete tcon!*/
-+              rc = CIFSSMBTDis(xid, cifs_sb->tcon);
-+              if (rc == -EBUSY) {
-+                      FreeXid(xid);
-+                      return 0;
-+              }
-+              tconInfoFree(cifs_sb->tcon);
-+              if ((ses) && (ses->server)) {
-+                      /* save off task so we do not refer to ses later */
-+                      cifsd_task = ses->server->tsk;
-+                      cFYI(1, ("About to do SMBLogoff "));
-+                      rc = CIFSSMBLogoff(xid, ses);
-+                      if (rc == -EBUSY) {
-+                              FreeXid(xid);
-+                              return 0;
-+                      } else if (rc == -ESHUTDOWN) {
-+                              cFYI(1,("Waking up socket by sending it signal"));
-+                              send_sig(SIGKILL,cifsd_task,1);
-+                              rc = 0;
-+                      } /* else - we have an smb session
-+                              left on this socket do not kill cifsd */
-+              } else
-+                      cFYI(1, ("No session or bad tcon"));
-+      }
-+      
-+      cifs_sb->tcon = NULL;
-+      if (ses) {
-+              set_current_state(TASK_INTERRUPTIBLE);
-+              schedule_timeout(HZ / 2);
-+      }
-+      if (ses)
-+              sesInfoFree(ses);
-+
-+      FreeXid(xid);
-+      return rc;              /* BB check if we should always return zero here */
-+} 
-+
-+int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
-+                                         struct nls_table * nls_info)
-+{
-+      int rc = 0;
-+      char ntlm_session_key[CIFS_SESSION_KEY_SIZE];
-+      int ntlmv2_flag = FALSE;
-+
-+      /* what if server changes its buffer size after dropping the session? */
-+      if(pSesInfo->server->maxBuf == 0) /* no need to send on reconnect */ {
-+              rc = CIFSSMBNegotiate(xid, pSesInfo);
-+              if(rc == -EAGAIN) /* retry only once on 1st time connection */ {
-+                      rc = CIFSSMBNegotiate(xid, pSesInfo);
-+                      if(rc == -EAGAIN) 
-+                              rc = -EHOSTDOWN;
-+              }
-+              if(rc == 0) {
-+                      spin_lock(&GlobalMid_Lock);
-+                      if(pSesInfo->server->tcpStatus != CifsExiting)
-+                              pSesInfo->server->tcpStatus = CifsGood;
-+                      else
-+                              rc = -EHOSTDOWN;
-+                      spin_unlock(&GlobalMid_Lock);
-+
-+              }
-+      }
-+      if (!rc) {
-+              pSesInfo->capabilities = pSesInfo->server->capabilities;
-+              if(linuxExtEnabled == 0)
-+                      pSesInfo->capabilities &= (~CAP_UNIX);
-+              pSesInfo->sequence_number = 0;
-+              cFYI(1,("Security Mode: 0x%x Capabilities: 0x%x Time Zone: %d",
-+                      pSesInfo->server->secMode,
-+                      pSesInfo->server->capabilities,
-+                      pSesInfo->server->timeZone));
-+              if (extended_security
-+                              && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
-+                              && (pSesInfo->server->secType == NTLMSSP)) {
-+                      cFYI(1, ("New style sesssetup "));
-+                      rc = CIFSSpnegoSessSetup(xid, pSesInfo,
-+                              NULL /* security blob */, 
-+                              0 /* blob length */,
-+                              nls_info);
-+              } else if (extended_security
-+                         && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
-+                         && (pSesInfo->server->secType == RawNTLMSSP)) {
-+                      cFYI(1, ("NTLMSSP sesssetup "));
-+                      rc = CIFSNTLMSSPNegotiateSessSetup(xid,
-+                                              pSesInfo,
-+                                              &ntlmv2_flag,
-+                                              nls_info);
-+                      if (!rc) {
-+                              if(ntlmv2_flag) {
-+                                      char * v2_response;
-+                                      cFYI(1,("Can use more secure NTLM version 2 password hash"));
-+                                      CalcNTLMv2_partial_mac_key(pSesInfo, 
-+                                              nls_info);
-+                                      v2_response = kmalloc(16 + 64 /* blob */, GFP_KERNEL);
-+                                      if(v2_response) {
-+                                              CalcNTLMv2_response(pSesInfo,v2_response);
-+/*                                            cifs_calculate_ntlmv2_mac_key(pSesInfo->mac_signing_key, response, ntlm_session_key, */
-+                                              kfree(v2_response);
-+                                      /* BB Put dummy sig in SessSetup PDU? */
-+                                      } else
-+                                              rc = -ENOMEM;
-+
-+                              } else {
-+                                      SMBNTencrypt(pSesInfo->password,
-+                                              pSesInfo->server->cryptKey,
-+                                              ntlm_session_key);
-+
-+                                      cifs_calculate_mac_key(pSesInfo->mac_signing_key,
-+                                              ntlm_session_key,
-+                                              pSesInfo->password);
-+                              }
-+                      /* for better security the weaker lanman hash not sent
-+                         in AuthSessSetup so we no longer calculate it */
-+
-+                              rc = CIFSNTLMSSPAuthSessSetup(xid,
-+                                      pSesInfo,
-+                                      ntlm_session_key,
-+                                      ntlmv2_flag,
-+                                      nls_info);
-+                      }
-+              } else { /* old style NTLM 0.12 session setup */
-+                      SMBNTencrypt(pSesInfo->password,
-+                              pSesInfo->server->cryptKey,
-+                              ntlm_session_key);
-+
-+                      cifs_calculate_mac_key(pSesInfo->mac_signing_key, 
-+                              ntlm_session_key, pSesInfo->password);
-+                      rc = CIFSSessSetup(xid, pSesInfo,
-+                              ntlm_session_key, nls_info);
-+              }
-+              if (rc) {
-+                      cERROR(1,("Send error in SessSetup = %d",rc));
-+              } else {
-+                      cFYI(1,("CIFS Session Established successfully"));
-+                      pSesInfo->status = CifsGood;
-+              }
-+      }
-+      return rc;
-+}
-+
---- /dev/null
-+++ b/fs/cifs/dir.c
-@@ -0,0 +1,425 @@
-+/*
-+ *   fs/cifs/dir.c
-+ *
-+ *   vfs operations that deal with dentries
-+ * 
-+ *   Copyright (C) International Business Machines  Corp., 2002,2003
-+ *   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 "cifsfs.h"
-+#include "cifspdu.h"
-+#include "cifsglob.h"
-+#include "cifsproto.h"
-+#include "cifs_debug.h"
-+#include "cifs_fs_sb.h"
-+
-+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 = 0;
-+      char *full_path;
-+
-+      if(direntry == NULL)
-+              return NULL;  /* not much we can do if dentry is freed and
-+              we need to reopen the file after it was closed implicitly
-+              when the server crashed */
-+
-+cifs_bp_rename_retry:
-+      for (temp = direntry; !IS_ROOT(temp);) {
-+              namelen += (1 + temp->d_name.len);
-+              temp = temp->d_parent;
-+              if(temp == NULL) {
-+                      cERROR(1,("corrupt dentry"));
-+                      return NULL;
-+              }
-+      }
-+
-+      full_path = kmalloc(namelen+1, GFP_KERNEL);
-+      if(full_path == NULL)
-+              return full_path;
-+      full_path[namelen] = 0; /* trailing null */
-+
-+      for (temp = direntry; !IS_ROOT(temp);) {
-+              namelen -= 1 + temp->d_name.len;
-+              if (namelen < 0) {
-+                      break;
-+              } else {
-+                      full_path[namelen] = '\\';
-+                      strncpy(full_path + namelen + 1, temp->d_name.name,
-+                              temp->d_name.len);
-+                      cFYI(0, (" name: %s ", full_path + namelen));
-+              }
-+              temp = temp->d_parent;
-+              if(temp == NULL) {
-+                      cERROR(1,("corrupt dentry"));
-+                      kfree(full_path);
-+                      return NULL;
-+              }
-+      }
-+      if (namelen != 0) {
-+              cERROR(1,
-+                     ("We did not end path lookup where we expected namelen is %d",
-+                      namelen));
-+              /* presumably this is only possible if we were 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);
-+              namelen = 0;
-+              goto cifs_bp_rename_retry;
-+      }
-+
-+      return full_path;
-+}
-+
-+/* Note: caller must free return buffer */
-+char *
-+build_wildcard_path_from_dentry(struct dentry *direntry)
-+{
-+      struct dentry *temp;
-+      int namelen = 0;
-+      char *full_path;
-+
-+      if(direntry == NULL)
-+              return NULL;  /* not much we can do if dentry is freed and
-+              we need to reopen the file after it was closed implicitly
-+              when the server crashed */
-+
-+cifs_bwp_rename_retry:
-+      for (temp = direntry; !IS_ROOT(temp);) {
-+              namelen += (1 + temp->d_name.len);
-+              temp = temp->d_parent;
-+              if(temp == NULL) {
-+                      cERROR(1,("corrupt dentry"));
-+                      return NULL;
-+              }
-+      }
-+
-+      full_path = kmalloc(namelen+3, GFP_KERNEL);
-+      if(full_path == NULL)
-+              return full_path;
-+
-+      full_path[namelen] = '\\';
-+      full_path[namelen+1] = '*';
-+      full_path[namelen+2] = 0;  /* trailing null */
-+
-+      for (temp = direntry; !IS_ROOT(temp);) {
-+              namelen -= 1 + temp->d_name.len;
-+              if (namelen < 0) {
-+                      break;
-+              } else {
-+                      full_path[namelen] = '\\';
-+                      strncpy(full_path + namelen + 1, temp->d_name.name,
-+                              temp->d_name.len);
-+                      cFYI(0, (" name: %s ", full_path + namelen));
-+              }
-+              temp = temp->d_parent;
-+              if(temp == NULL) {
-+                      cERROR(1,("corrupt dentry"));
-+                      kfree(full_path);
-+                      return NULL;
-+              }
-+      }
-+      if (namelen != 0) {
-+              cERROR(1,
-+                     ("We did not end path lookup where we expected namelen is %d",
-+                      namelen));
-+              /* presumably this is only possible if we were 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);
-+              namelen = 0;
-+              goto cifs_bwp_rename_retry;
-+      }
-+
-+      return full_path;
-+}
-+
-+/* Inode operations in similar order to how they appear in the Linux file fs.h */
-+
-+int
-+cifs_create(struct inode *inode, struct dentry *direntry, int mode)
-+{
-+      int rc = -ENOENT;
-+      int xid;
-+      int oplock = 0; /* no sense requested oplock if we are just going to
-+                       immediately  close the file */
-+      __u16 fileHandle;
-+      struct cifs_sb_info *cifs_sb;
-+      struct cifsTconInfo *pTcon;
-+      char *full_path = NULL;
-+      FILE_ALL_INFO * buf = NULL;
-+      struct inode *newinode = NULL;
-+
-+      xid = GetXid();
-+
-+      cifs_sb = CIFS_SB(inode->i_sb);
-+      pTcon = cifs_sb->tcon;
-+
-+      down(&direntry->d_sb->s_vfs_rename_sem);
-+      full_path = build_path_from_dentry(direntry);
-+      up(&direntry->d_sb->s_vfs_rename_sem);
-+      if(full_path == NULL) {
-+              FreeXid(xid);
-+              return -ENOMEM;
-+      }
-+
-+      /* BB add processing to set equivalent of mode - e.g. via CreateX with ACLs */
-+
-+        buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL);
-+      rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OVERWRITE_IF,
-+                      GENERIC_WRITE, CREATE_NOT_DIR,
-+                      &fileHandle, &oplock, buf, cifs_sb->local_nls);
-+      if (rc) {
-+              cFYI(1, ("cifs_create returned 0x%x ", rc));
-+      } else {
-+      /* BB for case of overwriting existing file can we use the inode that was
-+               passed in rather than creating new one?? */
-+              if (pTcon->ses->capabilities & CAP_UNIX)
-+                      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);
-+
-+              if (rc != 0) {
-+                      cFYI(1,("Create worked but get_inode_info failed with rc = %d",
-+                            rc));
-+              } else {
-+                      direntry->d_op = &cifs_dentry_ops;
-+                      d_instantiate(direntry, newinode);
-+              }
-+              CIFSSMBClose(xid, pTcon, fileHandle);
-+
-+              if(newinode) {
-+                      newinode->i_mode = mode;
-+                      if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)                
-+                              CIFSSMBUnixSetPerms(xid, pTcon, full_path, inode->i_mode,
-+                                      (__u64)-1, 
-+                                      (__u64)-1,
-+                                      0 /* dev */,
-+                                      cifs_sb->local_nls);
-+                      else { /* BB implement via Windows security descriptors */
-+                      /* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/
-+                      /* in the meantime could set r/o dos attribute when perms are eg:
-+                              mode & 0222 == 0 */
-+                      }
-+              }
-+      } 
-+
-+      if (buf)
-+          kfree(buf);
-+      if (full_path)
-+          kfree(full_path);
-+      FreeXid(xid);
-+
-+      return rc;
-+}
-+
-+int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, int device_number) 
-+{
-+      int rc = -EPERM;
-+      int xid;
-+      struct cifs_sb_info *cifs_sb;
-+      struct cifsTconInfo *pTcon;
-+      char *full_path = NULL;
-+      struct inode * newinode = NULL;
-+
-+      xid = GetXid();
-+
-+      cifs_sb = CIFS_SB(inode->i_sb);
-+      pTcon = cifs_sb->tcon;
-+
-+      down(&direntry->d_sb->s_vfs_rename_sem);
-+      full_path = build_path_from_dentry(direntry);
-+      up(&direntry->d_sb->s_vfs_rename_sem);
-+      if(full_path == NULL)
-+              rc = -ENOMEM;
-+      
-+      if (full_path && (pTcon->ses->capabilities & CAP_UNIX)) {
-+              rc = CIFSSMBUnixSetPerms(xid, pTcon,
-+                      full_path, mode, current->euid, current->egid,
-+                      device_number, cifs_sb->local_nls);
-+              if(!rc) {
-+                      rc = cifs_get_inode_info_unix(&newinode, full_path,
-+                                              inode->i_sb,xid);
-+                      direntry->d_op = &cifs_dentry_ops;
-+                      if(rc == 0)
-+                              d_instantiate(direntry, newinode);
-+              }
-+      }
-+
-+      if (full_path)
-+              kfree(full_path);
-+      FreeXid(xid);
-+
-+      return rc;
-+}
-+
-+
-+struct dentry *
-+cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry)
-+{
-+      int xid;
-+      int rc = 0; /* to get around spurious gcc warning, set to zero here */
-+      struct cifs_sb_info *cifs_sb;
-+      struct cifsTconInfo *pTcon;
-+      struct inode *newInode = NULL;
-+      char *full_path = NULL;
-+
-+      xid = GetXid();
-+
-+      cFYI(1,
-+           (" parent inode = 0x%p name is: %s and dentry = 0x%p",
-+            parent_dir_inode, direntry->d_name.name, direntry));
-+
-+      /* BB Add check of incoming data - e.g. frame not longer than maximum SMB - let server check the namelen BB */
-+
-+      /* check whether path exists */
-+
-+      cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
-+      pTcon = cifs_sb->tcon;
-+
-+      /* 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) {
-+              FreeXid(xid);
-+              return ERR_PTR(-ENOMEM);
-+      }
-+
-+      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));
-+
-+      if (pTcon->ses->capabilities & CAP_UNIX)
-+              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);
-+
-+      if ((rc == 0) && (newInode != NULL)) {
-+              direntry->d_op = &cifs_dentry_ops;
-+              d_add(direntry, newInode);
-+
-+              /* 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;
-+              d_add(direntry, NULL);
-+      } else {
-+              cERROR(1,("Error 0x%x or on cifs_get_inode_info in lookup",rc));
-+              /* BB special case check for Access Denied - watch security 
-+              exposure of returning dir info implicitly via different rc 
-+              if file exists or not but no access BB */
-+      }
-+
-+      if (full_path)
-+              kfree(full_path);
-+      FreeXid(xid);
-+      return ERR_PTR(rc);
-+}
-+
-+int
-+cifs_dir_open(struct inode *inode, struct file *file)
-+{                             /* NB: currently unused since searches are opened in readdir */
-+      int rc = 0;
-+      int xid;
-+      struct cifs_sb_info *cifs_sb;
-+      struct cifsTconInfo *pTcon;
-+      char *full_path = NULL;
-+
-+      xid = GetXid();
-+
-+      cifs_sb = CIFS_SB(inode->i_sb);
-+      pTcon = cifs_sb->tcon;
-+
-+      if(file->f_dentry) {
-+              down(&file->f_dentry->d_sb->s_vfs_rename_sem);
-+              full_path = build_wildcard_path_from_dentry(file->f_dentry);
-+              up(&file->f_dentry->d_sb->s_vfs_rename_sem);
-+      } else {
-+              FreeXid(xid);
-+              return -EIO;
-+      }
-+
-+      cFYI(1, ("inode = 0x%p and full path is %s", inode, full_path));
-+
-+      if (full_path)
-+              kfree(full_path);
-+      FreeXid(xid);
-+      return rc;
-+}
-+
-+static int
-+cifs_d_revalidate(struct dentry *direntry, int flags)
-+{
-+      int isValid = 1;
-+
-+/*    lock_kernel(); *//* surely we do not want to lock the kernel for a whole network round trip which could take seconds */
-+
-+      if (direntry->d_inode) {
-+              if (cifs_revalidate(direntry)) {
-+                      /* unlock_kernel(); */
-+                      return 0;
-+              }
-+      } else {
-+              cFYI(1,
-+                   ("In cifs_d_revalidate with no inode but name = %s and dentry 0x%p",
-+                    direntry->d_name.name, direntry));
-+      }
-+
-+/*    unlock_kernel(); */
-+
-+      return isValid;
-+}
-+
-+/* 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;
-+}     */
-+
-+struct dentry_operations cifs_dentry_ops = {
-+      .d_revalidate = cifs_d_revalidate,
-+/* d_delete:       cifs_d_delete,       *//* not needed except for debugging */
-+      /* no need for d_hash, d_compare, d_release, d_iput ... yet. BB confirm this BB */
-+};
---- /dev/null
-+++ b/fs/cifs/file.c
-@@ -0,0 +1,2185 @@
-+/*
-+ *   fs/cifs/file.c
-+ *
-+ *   vfs operations that deal with files
-+ * 
-+ *   Copyright (C) International Business Machines  Corp., 2002,2003
-+ *   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/fcntl.h>
-+#include <linux/version.h>
-+#include <linux/pagemap.h>
-+#include <linux/smp_lock.h>
-+#include <linux/list.h>
-+#include <asm/div64.h>
-+#include <linux/mm.h>
-+#include <linux/types.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"
-+
-+int
-+cifs_open(struct inode *inode, struct file *file)
-+{
-+      int rc = -EACCES;
-+      int xid, oplock;
-+      struct cifs_sb_info *cifs_sb;
-+      struct cifsTconInfo *pTcon;
-+      struct cifsFileInfo *pCifsFile;
-+      struct cifsInodeInfo *pCifsInode;
-+      char *full_path = NULL;
-+      int desiredAccess = 0x20197;
-+      int disposition;
-+      __u16 netfid;
-+      FILE_ALL_INFO * buf = NULL;
-+      time_t temp;
-+
-+      xid = GetXid();
-+
-+      cifs_sb = CIFS_SB(inode->i_sb);
-+      pTcon = cifs_sb->tcon;
-+
-+      down(&inode->i_sb->s_vfs_rename_sem);
-+      full_path = build_path_from_dentry(file->f_dentry);
-+      up(&inode->i_sb->s_vfs_rename_sem);
-+      if(full_path == NULL) {
-+              FreeXid(xid);
-+              return -ENOMEM;
-+      }
-+
-+      cFYI(1, (" inode = 0x%p file flags are 0x%x for %s", inode, file->f_flags,full_path));
-+      if ((file->f_flags & O_ACCMODE) == O_RDONLY)
-+              desiredAccess = GENERIC_READ;
-+      else if ((file->f_flags & O_ACCMODE) == O_WRONLY)
-+              desiredAccess = GENERIC_WRITE;
-+      else if ((file->f_flags & O_ACCMODE) == O_RDWR) {
-+              /* GENERIC_ALL is too much permission to request */
-+              /* can cause unnecessary access denied on create */
-+              /* desiredAccess = GENERIC_ALL; */
-+              desiredAccess = GENERIC_READ | GENERIC_WRITE;
-+      }
-+
-+/*********************************************************************
-+ *  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
-+ *********************************************************************/
-+
-+      /* For 2.4 case, file was already checked for existence
-+              before create by vfs lookup and created in create
-+              entry point, we are now just opening the newly 
-+              created file with the right desiredAccess flags */
-+
-+      if((file->f_flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
-+              disposition = FILE_OPEN_IF; 
-+      else if((file->f_flags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
-+              disposition = FILE_OVERWRITE_IF;
-+      else if((file->f_flags & O_CREAT) == O_CREAT)
-+              disposition = FILE_OPEN_IF;
-+      else
-+              disposition = FILE_OPEN;
-+
-+      if (oplockEnabled)
-+              oplock = REQ_OPLOCK;
-+      else
-+              oplock = FALSE;
-+
-+      /* BB pass O_SYNC flag through on file attributes .. BB */
-+
-+      /* Also refresh inode by passing in file_info buf returned by SMBOpen 
-+         and calling get_inode_info with returned buf (at least 
-+         helps non-Unix server case */
-+
-+      /* BB we can not do this if this is the second open of a file 
-+      and the first handle has writebehind data, we might be 
-+      able to simply do a filemap_fdatawrite/filemap_fdatawait first */
-+      buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL);
-+      if(buf==0) {
-+              if (full_path)
-+                      kfree(full_path);
-+              FreeXid(xid);
-+              return -ENOMEM;
-+      }
-+      rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess,
-+                      CREATE_NOT_DIR, &netfid, &oplock, buf, cifs_sb->local_nls);
-+      if (rc) {
-+              cFYI(1, ("cifs_open returned 0x%x ", rc));
-+              cFYI(1, ("oplock: %d ", oplock));       
-+      } else {
-+              file->private_data =
-+                      kmalloc(sizeof (struct cifsFileInfo), GFP_KERNEL);
-+              if (file->private_data) {
-+                      memset(file->private_data, 0, sizeof(struct cifsFileInfo));
-+                      pCifsFile = (struct cifsFileInfo *) file->private_data;
-+                      pCifsFile->netfid = netfid;
-+                      pCifsFile->pid = current->pid;
-+                      init_MUTEX(&pCifsFile->fh_sem);
-+                      pCifsFile->pfile = file; /* needed for writepage */
-+                      pCifsFile->pInode = inode;
-+                      pCifsFile->invalidHandle = FALSE;
-+                      pCifsFile->closePend     = FALSE;
-+                      write_lock(&GlobalSMBSeslock);
-+                      spin_lock(&files_lock);
-+                      list_add(&pCifsFile->tlist,&pTcon->openFileList);
-+                      pCifsInode = CIFS_I(file->f_dentry->d_inode);
-+                      if(pCifsInode) {
-+                              /* want handles we can use to read with first */
-+                              /* in the list so we do not have to walk the */
-+                              /* list to search for one in prepare_write */
-+                              if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
-+                                      list_add_tail(&pCifsFile->flist,&pCifsInode->openFileList);
-+                              } else {
-+                                      list_add(&pCifsFile->flist,&pCifsInode->openFileList);
-+                              }
-+                              spin_unlock(&files_lock);
-+                              write_unlock(&GlobalSMBSeslock);
-+                              if(pCifsInode->clientCanCacheRead) {
-+                                      /* we have the inode open somewhere else
-+                                         no need to discard cache data */
-+                              } else {
-+                                      if(buf) {
-+                                      /* BB need same check in cifs_create too? */
-+
-+                                      /* if not oplocked, invalidate inode pages if mtime 
-+                                         or file size changed */
-+                                              temp = cifs_NTtimeToUnix(le64_to_cpu(buf->LastWriteTime));
-+                                              if((file->f_dentry->d_inode->i_mtime == temp) && 
-+                                                      (file->f_dentry->d_inode->i_size == (loff_t)le64_to_cpu(buf->EndOfFile))) {
-+                                                      cFYI(1,("inode unchanged on server"));
-+                                              } else {
-+                                                      if(file->f_dentry->d_inode->i_mapping) {
-+                                                      /* BB no need to lock inode until after invalidate*/
-+                                                      /* since namei code should already have it locked?*/
-+                                                              filemap_fdatasync(file->f_dentry->d_inode->i_mapping);
-+                                                      }
-+                                                      cFYI(1,("invalidating remote inode since open detected it changed"));
-+                                                      invalidate_inode_pages(file->f_dentry->d_inode);
-+                                              }
-+                                      }
-+                              }
-+                              if (pTcon->ses->capabilities & CAP_UNIX)
-+                                      rc = cifs_get_inode_info_unix(&file->f_dentry->d_inode,
-+                                              full_path, inode->i_sb,xid);
-+                              else
-+                                      rc = cifs_get_inode_info(&file->f_dentry->d_inode,
-+                                              full_path, buf, inode->i_sb,xid);
-+
-+                              if((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
-+                                      pCifsInode->clientCanCacheAll = TRUE;
-+                                      pCifsInode->clientCanCacheRead = TRUE;
-+                                      cFYI(1,("Exclusive Oplock granted on inode %p",file->f_dentry->d_inode));
-+                              } else if((oplock & 0xF) == OPLOCK_READ)
-+                                      pCifsInode->clientCanCacheRead = TRUE;
-+                      } else {
-+                              spin_unlock(&files_lock);
-+                              write_unlock(&GlobalSMBSeslock);
-+                      }
-+                      if(oplock & CIFS_CREATE_ACTION) {           
-+                              /* time to set mode which we can not set earlier due
-+                               to problems creating new read-only files */
-+                              if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)                
-+                                      CIFSSMBUnixSetPerms(xid, pTcon, full_path, inode->i_mode,
-+                                              (__u64)-1, 
-+                                              (__u64)-1,
-+                                              0 /* dev */,
-+                                              cifs_sb->local_nls);
-+                              else {/* BB implement via Windows security descriptors */
-+                      /* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/
-+                      /* in the meantime could set r/o dos attribute when perms are eg:
-+                                      mode & 0222 == 0 */
-+                              }
-+                      }
-+              }
-+      }
-+
-+      if (buf)
-+              kfree(buf);
-+      if (full_path)
-+              kfree(full_path);
-+      FreeXid(xid);
-+      return rc;
-+}
-+
-+/* Try to reaquire 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 inode *inode, struct file *file, int can_flush)
-+{
-+      int rc = -EACCES;
-+      int xid, oplock;
-+      struct cifs_sb_info *cifs_sb;
-+      struct cifsTconInfo *pTcon;
-+      struct cifsFileInfo *pCifsFile;
-+      struct cifsInodeInfo *pCifsInode;
-+      char *full_path = NULL;
-+      int desiredAccess = 0x20197;
-+      int disposition = FILE_OPEN;
-+      __u16 netfid;
-+
-+      if(inode == NULL)
-+              return -EBADF;
-+      if (file->private_data) {
-+              pCifsFile = (struct cifsFileInfo *) file->private_data;
-+      } else
-+              return -EBADF;
-+
-+      xid = GetXid();
-+      down(&pCifsFile->fh_sem);
-+      if(pCifsFile->invalidHandle == FALSE) {
-+              up(&pCifsFile->fh_sem);
-+              FreeXid(xid);
-+              return 0;
-+      }
-+
-+      if(file->f_dentry == NULL) {
-+              up(&pCifsFile->fh_sem);
-+              cFYI(1,("failed file reopen, no valid name if dentry freed"));
-+              FreeXid(xid);
-+              return -EBADF;
-+      }
-+      cifs_sb = CIFS_SB(inode->i_sb);
-+      pTcon = cifs_sb->tcon;
-+/* 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(file->f_dentry);
-+      if(full_path == NULL) {
-+              up(&pCifsFile->fh_sem);
-+              FreeXid(xid);
-+              return -ENOMEM;
-+      }
-+
-+      cFYI(1, (" inode = 0x%p file flags are 0x%x for %s", inode, file->f_flags,full_path));
-+      if ((file->f_flags & O_ACCMODE) == O_RDONLY)
-+              desiredAccess = GENERIC_READ;
-+      else if ((file->f_flags & O_ACCMODE) == O_WRONLY)
-+              desiredAccess = GENERIC_WRITE;
-+      else if ((file->f_flags & O_ACCMODE) == O_RDWR) {
-+              /* GENERIC_ALL is too much permission to request */
-+              /* can cause unnecessary access denied on create */
-+              /* desiredAccess = GENERIC_ALL; */
-+              desiredAccess = GENERIC_READ | GENERIC_WRITE;
-+      }
-+
-+      if (oplockEnabled)
-+              oplock = REQ_OPLOCK;
-+      else
-+              oplock = FALSE;
-+
-+      
-+      /* 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 */
-+
-+/*    buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL);
-+      if(buf==0) {
-+              up(&pCifsFile->fh_sem);
-+              if (full_path)
-+                      kfree(full_path);
-+              FreeXid(xid);
-+              return -ENOMEM;
-+      }*/
-+      rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess,
-+                              CREATE_NOT_DIR, &netfid, &oplock, NULL, cifs_sb->local_nls);
-+      if (rc) {
-+              up(&pCifsFile->fh_sem);
-+              cFYI(1, ("cifs_open returned 0x%x ", rc));
-+              cFYI(1, ("oplock: %d ", oplock));
-+      } else {
-+              pCifsFile->netfid = netfid;
-+              pCifsFile->invalidHandle = FALSE;
-+              up(&pCifsFile->fh_sem);
-+              pCifsInode = CIFS_I(inode);
-+              if(pCifsInode) {
-+                      if(can_flush) {
-+                              filemap_fdatasync(inode->i_mapping);
-+                              filemap_fdatawait(inode->i_mapping);
-+                      /* temporarily disable caching while we
-+                      go to server to get inode info */
-+                              pCifsInode->clientCanCacheAll = FALSE;
-+                              pCifsInode->clientCanCacheRead = FALSE;
-+                              if (pTcon->ses->capabilities & CAP_UNIX)
-+                                      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);
-+                      } /* 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 */
-+                      if((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
-+                              pCifsInode->clientCanCacheAll =  TRUE;
-+                              pCifsInode->clientCanCacheRead = TRUE;
-+                              cFYI(1,("Exclusive Oplock granted on inode %p",file->f_dentry->d_inode));
-+                      } else if((oplock & 0xF) == OPLOCK_READ) {
-+                              pCifsInode->clientCanCacheRead = TRUE;
-+                              pCifsInode->clientCanCacheAll =  FALSE;
-+                      } else {
-+                              pCifsInode->clientCanCacheRead = FALSE;
-+                              pCifsInode->clientCanCacheAll =  FALSE;
-+                      }
-+                      cifs_relock_file(pCifsFile);
-+              }
-+      }
-+
-+      if (full_path)
-+              kfree(full_path);
-+      FreeXid(xid);
-+      return rc;
-+}
-+
-+int
-+cifs_close(struct inode *inode, struct file *file)
-+{
-+      int rc = 0;
-+      int xid;
-+      struct cifs_sb_info *cifs_sb;
-+      struct cifsTconInfo *pTcon;
-+      struct cifsFileInfo *pSMBFile =
-+              (struct cifsFileInfo *) file->private_data;
-+
-+      xid = GetXid();
-+
-+      cifs_sb = CIFS_SB(inode->i_sb);
-+      pTcon = cifs_sb->tcon;
-+      if (pSMBFile) {
-+              pSMBFile->closePend    = TRUE;
-+              spin_lock(&files_lock);
-+              if(pTcon) {
-+                      /* no sense reconnecting to close a file that is
-+                              already closed */
-+                      if (pTcon->tidStatus != CifsNeedReconnect) {
-+                              spin_unlock(&files_lock);
-+                              rc = CIFSSMBClose(xid,pTcon,pSMBFile->netfid);
-+                              spin_lock(&files_lock);
-+                      }
-+              }
-+              list_del(&pSMBFile->flist);
-+              list_del(&pSMBFile->tlist);
-+              spin_unlock(&files_lock);
-+              if(pSMBFile->search_resume_name)
-+                      kfree(pSMBFile->search_resume_name);
-+              kfree(file->private_data);
-+              file->private_data = NULL;
-+      } else
-+              rc = -EBADF;
-+
-+      if(list_empty(&(CIFS_I(inode)->openFileList))) {
-+              cFYI(1,("closing last open instance for inode %p",inode));
-+              /* if the file is not open we do not know if we can cache
-+              info on this inode, much less write behind and read ahead */
-+              CIFS_I(inode)->clientCanCacheRead = FALSE;
-+              CIFS_I(inode)->clientCanCacheAll  = FALSE;
-+      }
-+      if((rc ==0) && CIFS_I(inode)->write_behind_rc)
-+              rc = CIFS_I(inode)->write_behind_rc;
-+      FreeXid(xid);
-+      return rc;
-+}
-+
-+int
-+cifs_closedir(struct inode *inode, struct file *file)
-+{
-+      int rc = 0;
-+      int xid;
-+      struct cifsFileInfo *pSMBFileStruct =
-+          (struct cifsFileInfo *) file->private_data;
-+
-+      cFYI(1, ("Closedir inode = 0x%p with ", inode));
-+
-+      xid = GetXid();
-+
-+      if (pSMBFileStruct) {
-+              cFYI(1, ("Freeing private data in close dir"));
-+              kfree(file->private_data);
-+              file->private_data = NULL;
-+      }
-+      FreeXid(xid);
-+      return rc;
-+}
-+
-+int
-+cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
-+{
-+      int rc, xid;
-+      __u32 lockType = LOCKING_ANDX_LARGE_FILES;
-+      __u32 numLock = 0;
-+      __u32 numUnlock = 0;
-+      __u64 length;
-+      int wait_flag = FALSE;
-+      struct cifs_sb_info *cifs_sb;
-+      struct cifsTconInfo *pTcon;
-+      length = 1 + pfLock->fl_end - pfLock->fl_start;
-+
-+      rc = -EACCES;
-+
-+      xid = GetXid();
-+
-+      cFYI(1,
-+           ("Lock parm: 0x%x flockflags: 0x%x flocktype: 0x%x start: %lld end: %lld",
-+            cmd, pfLock->fl_flags, pfLock->fl_type, pfLock->fl_start,
-+            pfLock->fl_end));
-+
-+      if (pfLock->fl_flags & FL_POSIX)
-+              cFYI(1, ("Posix "));
-+      if (pfLock->fl_flags & FL_FLOCK)
-+              cFYI(1, ("Flock "));
-+/*    if (pfLock->fl_flags & FL_SLEEP) {
-+              cFYI(1, ("Blocking lock "));
-+              wait_flag = TRUE;
-+      } */                          
-+      if (pfLock->fl_flags & FL_ACCESS)
-+              cFYI(1, ("Process suspended by mandatory locking - not implemented yet "));
-+      if (pfLock->fl_flags & FL_LEASE)
-+              cFYI(1, ("Lease on file - not implemented yet"));
-+      if (pfLock->fl_flags & (~(FL_POSIX | FL_FLOCK | FL_ACCESS | FL_LEASE)))
-+              cFYI(1, ("Unknown lock flags 0x%x",pfLock->fl_flags));
-+
-+      if (pfLock->fl_type == F_WRLCK) {
-+              cFYI(1, ("F_WRLCK "));
-+              numLock = 1;
-+      } else if (pfLock->fl_type == F_UNLCK) {
-+              cFYI(1, ("F_UNLCK "));
-+              numUnlock = 1;
-+      } else if (pfLock->fl_type == F_RDLCK) {
-+              cFYI(1, ("F_RDLCK "));
-+              lockType |= LOCKING_ANDX_SHARED_LOCK;
-+              numLock = 1;
-+      } else if (pfLock->fl_type == F_EXLCK) {
-+              cFYI(1, ("F_EXLCK "));
-+              numLock = 1;
-+      } else if (pfLock->fl_type == F_SHLCK) {
-+              cFYI(1, ("F_SHLCK "));
-+              lockType |= LOCKING_ANDX_SHARED_LOCK;
-+              numLock = 1;
-+      } else
-+              cFYI(1, ("Unknown type of lock "));
-+
-+      cifs_sb = CIFS_SB(file->f_dentry->d_sb);
-+      pTcon = cifs_sb->tcon;
-+
-+      if (file->private_data == NULL) {
-+              FreeXid(xid);
-+              return -EBADF;
-+      }
-+
-+      if (IS_GETLK(cmd)) {
-+              rc = CIFSSMBLock(xid, pTcon,
-+                               ((struct cifsFileInfo *) file->
-+                                private_data)->netfid,
-+                               length,
-+                               pfLock->fl_start, 0, 1, lockType,
-+                               0 /* wait flag */ );
-+              if (rc == 0) {
-+                      rc = CIFSSMBLock(xid, pTcon,
-+                                       ((struct cifsFileInfo *) file->
-+                                        private_data)->netfid,
-+                                       length,
-+                                       pfLock->fl_start, 1 /* numUnlock */ ,
-+                                       0 /* numLock */ , lockType,
-+                                       0 /* wait flag */ );
-+                      pfLock->fl_type = F_UNLCK;
-+                      if (rc != 0)
-+                              cERROR(1,
-+                                      ("Error unlocking previously locked range %d during test of lock ",
-+                                      rc));
-+                      rc = 0;
-+
-+              } else {
-+                      /* if rc == ERR_SHARING_VIOLATION ? */
-+                      rc = 0; /* do not change lock type to unlock since range in use */
-+              }
-+
-+              FreeXid(xid);
-+              return rc;
-+      }
-+
-+      rc = CIFSSMBLock(xid, pTcon,
-+                       ((struct cifsFileInfo *) file->private_data)->
-+                       netfid, length,
-+                       pfLock->fl_start, numUnlock, numLock, lockType,
-+                       wait_flag);
-+      FreeXid(xid);
-+      return rc;
-+}
-+
-+ssize_t
-+cifs_write(struct file * file, 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 cifsTconInfo *pTcon;
-+      int xid, long_op;
-+      struct cifsFileInfo * open_file;
-+
-+      if(file->f_dentry == NULL)
-+              return -EBADF;
-+
-+      cifs_sb = CIFS_SB(file->f_dentry->d_sb);
-+      if(cifs_sb == NULL) {
-+              return -EBADF;
-+      }
-+      pTcon = cifs_sb->tcon;
-+
-+      /*cFYI(1,
-+         (" write %d bytes to offset %lld of %s", write_size,
-+         *poffset, file->f_dentry->d_name.name)); */
-+
-+      if (file->private_data == NULL) {
-+              return -EBADF;
-+      } else {
-+              open_file = (struct cifsFileInfo *) file->private_data;
-+      }
-+      
-+      xid = GetXid();
-+      if(file->f_dentry->d_inode == NULL) {
-+              FreeXid(xid);
-+              return -EBADF;
-+      }
-+
-+      if (*poffset > file->f_dentry->d_inode->i_size)
-+              long_op = 2;  /* writes past end of file can take a long time */
-+      else
-+              long_op = 1;
-+
-+      for (total_written = 0; write_size > total_written;
-+           total_written += bytes_written) {
-+              rc = -EAGAIN;
-+              while(rc == -EAGAIN) {
-+                      if(file->private_data == NULL) {
-+                              /* file has been closed on us */
-+                              FreeXid(xid);
-+                      /* if we have gotten here we have written some data
-+                      and blocked, and the file has been freed on us
-+                      while we blocked so return what we managed to write */
-+                              return total_written;
-+                      } 
-+                      if(open_file->closePend) {
-+                              FreeXid(xid);
-+                              if(total_written)
-+                                      return total_written;
-+                              else
-+                                      return -EBADF;
-+                      }
-+                      if (open_file->invalidHandle) {
-+                              if((file->f_dentry == NULL) ||
-+                                 (file->f_dentry->d_inode == NULL)) {
-+                                      FreeXid(xid);
-+                                      return total_written;
-+                              }
-+                              /* 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(file->f_dentry->d_inode,
-+                                      file,FALSE);
-+                              if(rc != 0)
-+                                      break;
-+                      }
-+
-+                      rc = CIFSSMBWrite(xid, pTcon,
-+                                 open_file->netfid,
-+                                write_size - total_written, *poffset,
-+                                &bytes_written,
-+                                write_data + total_written, long_op);
-+              }
-+              if (rc || (bytes_written == 0)) {
-+                      if (total_written)
-+                              break;
-+                      else {
-+                              FreeXid(xid);
-+                              return rc;
-+                      }
-+              } else
-+                      *poffset += bytes_written;
-+              long_op = FALSE; /* subsequent writes fast - 15 seconds is plenty */
-+      }
-+
-+#ifdef CONFIG_CIFS_STATS
-+      if(total_written > 0) {
-+              atomic_inc(&pTcon->num_writes);
-+              spin_lock(&pTcon->stat_lock);
-+              pTcon->bytes_written += total_written;
-+              spin_unlock(&pTcon->stat_lock);
-+      }
-+#endif                
-+
-+      /* since the write may have blocked check these pointers again */
-+      if(file->f_dentry) {
-+              if(file->f_dentry->d_inode) {
-+                      file->f_dentry->d_inode->i_ctime = file->f_dentry->d_inode->i_mtime =
-+                              CURRENT_TIME;
-+                      if (total_written > 0) {
-+                              if (*poffset > file->f_dentry->d_inode->i_size)
-+                                      file->f_dentry->d_inode->i_size = *poffset;
-+                      }
-+                      mark_inode_dirty_sync(file->f_dentry->d_inode);
-+              }
-+      }
-+      FreeXid(xid);
-+      return total_written;
-+}
-+
-+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 cifs_sb_info *cifs_sb;
-+      struct cifsTconInfo *pTcon;
-+      struct inode *inode;
-+      struct cifsInodeInfo *cifsInode;
-+      struct cifsFileInfo *open_file = NULL;
-+      struct list_head *tmp;
-+      struct list_head *tmp1;
-+
-+      if (!mapping) {
-+              return -EFAULT;
-+      } else if(!mapping->host) {
-+              return -EFAULT;
-+      }
-+
-+      inode = page->mapping->host;
-+      cifs_sb = CIFS_SB(inode->i_sb);
-+      pTcon = cifs_sb->tcon;
-+
-+      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); 
-+              
-+
-+      cifsInode = CIFS_I(mapping->host);
-+      read_lock(&GlobalSMBSeslock); 
-+      /* BB we should start at the end */
-+      list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) {            
-+              open_file = list_entry(tmp,struct cifsFileInfo, flist);
-+              if(open_file->closePend)
-+                      continue;
-+              /* We check if file is open for writing first */
-+              if((open_file->pfile) && 
-+                 ((open_file->pfile->f_flags & O_RDWR) || 
-+                      (open_file->pfile->f_flags & O_WRONLY))) {
-+                      read_unlock(&GlobalSMBSeslock);
-+                      bytes_written = cifs_write(open_file->pfile, write_data,
-+                                      to-from, &offset);
-+                      read_lock(&GlobalSMBSeslock);
-+              /* Does mm or vfs already set times? */
-+                      inode->i_atime = inode->i_mtime = CURRENT_TIME;
-+                      if ((bytes_written > 0) && (offset)) {
-+                              rc = 0;
-+                      } else if(bytes_written < 0) {
-+                              if(rc == -EBADF) {
-+                              /* have seen a case in which
-+                              kernel seemed to have closed/freed a file
-+                              even with writes active so we might as well
-+                              see if there are other file structs to try
-+                              for the same inode before giving up */
-+                                      continue;
-+                              } else
-+                                      rc = bytes_written;
-+                      }
-+                      break;  /* now that we found a valid file handle
-+                              and tried to write to it we are done, no
-+                              sense continuing to loop looking for another */
-+              }
-+              if(tmp->next == NULL) {
-+                      cFYI(1,("File instance %p removed",tmp));
-+                      break;
-+              }
-+      }
-+      read_unlock(&GlobalSMBSeslock);
-+      if(open_file == NULL) {
-+              cFYI(1,("No writeable filehandles for inode"));
-+              rc = -EIO;
-+      }
-+
-+      kunmap(page);
-+      return rc;
-+}
-+
-+#if 0
-+static int
-+cifs_writepages(struct address_space *mapping, struct writeback_control *wbc)
-+{
-+      int rc = -EFAULT;
-+      int xid;
-+
-+      xid = GetXid();
-+/* call 16K write then Setpageuptodate */
-+      FreeXid(xid);
-+      return rc;
-+}
-+#endif
-+
-+static int
-+cifs_writepage(struct page* page)
-+{
-+      int rc = -EFAULT;
-+      int xid;
-+
-+      xid = GetXid();
-+/* BB add check for wbc flags */
-+      page_cache_get(page);
-+        if (!Page_Uptodate(page)) {
-+              cFYI(1,("ppw - page not up to date"));
-+      }
-+      
-+      rc = cifs_partialpagewrite(page,0,PAGE_CACHE_SIZE);
-+      SetPageUptodate(page); /* BB add check for error and Clearuptodate? */
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20))
-+      unlock_page(page);
-+#else
-+      UnlockPage(page);
-+#endif
-+      page_cache_release(page);       
-+      FreeXid(xid);
-+      return rc;
-+}
-+
-+static int
-+cifs_commit_write(struct file *file, struct page *page, unsigned offset,
-+                unsigned to)
-+{
-+      int xid;
-+      int rc = 0;
-+      struct inode *inode = page->mapping->host;
-+      loff_t position = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
-+      char * page_data;
-+
-+      xid = GetXid();
-+      cFYI(1,("commit write for page %p up to position %lld for %d",page,position,to));
-+      if (position > inode->i_size){
-+              inode->i_size = position;
-+              /*if (file->private_data == NULL) {
-+                      rc = -EBADF;
-+              } else {
-+                      open_file = (struct cifsFileInfo *)file->private_data;
-+                      cifs_sb = CIFS_SB(inode->i_sb);
-+                      rc = -EAGAIN;
-+                      while(rc == -EAGAIN) {
-+                              if((open_file->invalidHandle) && 
-+                                (!open_file->closePend)) {
-+                                      rc = cifs_reopen_file(file->f_dentry->d_inode,file);
-+                                      if(rc != 0)
-+                                              break;
-+                              }
-+                              if(!open_file->closePend) {
-+                                      rc = CIFSSMBSetFileSize(xid, cifs_sb->tcon, 
-+                                              position, open_file->netfid,
-+                                              open_file->pid,FALSE);
-+                              } else {
-+                                      rc = -EBADF;
-+                                      break;
-+                              }
-+                      }
-+                      cFYI(1,(" SetEOF (commit write) rc = %d",rc));
-+              }*/
-+      }
-+      if (!Page_Uptodate(page)) {
-+              position =  ((loff_t)page->index << PAGE_CACHE_SHIFT) + offset;
-+              /* can not rely on (or let) writepage write this data */
-+              if(to < offset) {
-+                      cFYI(1,("Illegal offsets, can not copy from %d to %d",
-+                              offset,to));
-+                      FreeXid(xid);
-+                      return rc;
-+              }
-+              /* 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(file, page_data+offset,to-offset,
-+                                        &position);
-+              if(rc > 0)
-+                      rc = 0;
-+              /* else if rc < 0 should we set writebehind rc? */
-+              kunmap(page);
-+      } else {        
-+              set_page_dirty(page);
-+      }
-+
-+      FreeXid(xid);
-+      return rc;
-+}
-+
-+int
-+cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
-+{
-+      int xid;
-+      int rc = 0;
-+      struct inode * inode = file->f_dentry->d_inode;
-+
-+      xid = GetXid();
-+
-+      cFYI(1, ("Sync file - name: %s datasync: 0x%x ", 
-+              dentry->d_name.name, datasync));
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,17))     
-+      rc = filemap_fdatasync(inode->i_mapping);
-+#else
-+      filemap_fdatasync(inode->i_mapping);
-+#endif
-+      if(rc == 0)
-+              CIFS_I(inode)->write_behind_rc = 0;
-+      FreeXid(xid);
-+      return rc;
-+}
-+
-+static int
-+cifs_sync_page(struct page *page)
-+{
-+      struct address_space *mapping;
-+      struct inode *inode;
-+      unsigned long index = page->index;
-+      unsigned int rpages = 0;
-+      int rc = 0;
-+
-+      cFYI(1,("sync page %p",page));
-+      mapping = page->mapping;
-+      if (!mapping)
-+              return 0;
-+      inode = mapping->host;
-+      if (!inode)
-+              return 0;
-+
-+/*    fill in rpages then 
-+    result = cifs_pagein_inode(inode, index, rpages); *//* BB finish */
-+
-+      cFYI(1, ("rpages is %d for sync page of Index %ld ", rpages, index));
-+
-+      if (rc < 0)
-+              return rc;
-+      return 0;
-+}
-+
-+/*
-+ * As file closes, flush all cached write data for this inode checking
-+ * for write behind errors.
-+ *
-+ */
-+int cifs_flush(struct file *file)
-+{
-+      struct inode * inode = file->f_dentry->d_inode;
-+      int rc = 0;
-+
-+      /* Rather than do the steps manually: */
-+      /* lock the inode for writing */
-+      /* loop through pages looking for write behind data (dirty pages) */
-+      /* coalesce into contiguous 16K (or smaller) chunks to write to server */
-+      /* send to server (prefer in parallel) */
-+      /* deal with writebehind errors */
-+      /* unlock inode for writing */
-+      /* filemapfdatawrite appears easier for the time being */
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,17))
-+      rc = filemap_fdatasync(inode->i_mapping);
-+#else
-+      filemap_fdatasync(inode->i_mapping);
-+#endif
-+      if(rc == 0) /* reset wb rc if we were able to write out dirty pages */
-+              CIFS_I(inode)->write_behind_rc = 0;
-+              
-+      cFYI(1,("Flush inode %p file %p rc %d",inode,file,rc));
-+
-+      return rc;
-+}
-+
-+
-+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;
-+      struct cifs_sb_info *cifs_sb;
-+      struct cifsTconInfo *pTcon;
-+      int xid;
-+      char * current_offset;
-+      struct cifsFileInfo * open_file;
-+
-+      xid = GetXid();
-+      cifs_sb = CIFS_SB(file->f_dentry->d_sb);
-+      pTcon = cifs_sb->tcon;
-+
-+      if (file->private_data == NULL) {
-+              FreeXid(xid);
-+              return -EBADF;
-+      }
-+      open_file = (struct cifsFileInfo *)file->private_data;
-+
-+      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) {
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,15))
-+              current_read_size = min_t(const int,read_size - total_read,cifs_sb->rsize);
-+#else
-+                current_read_size = min(read_size - total_read,cifs_sb->rsize);
-+#endif
-+              rc = -EAGAIN;
-+              while(rc == -EAGAIN) {
-+                      if ((open_file->invalidHandle) && (!open_file->closePend)) {
-+                              rc = cifs_reopen_file(file->f_dentry->d_inode,
-+                                      file,TRUE);
-+                              if(rc != 0)
-+                                      break;
-+                      }
-+
-+                      rc = CIFSSMBRead(xid, pTcon,
-+                               open_file->netfid,
-+                               current_read_size, *poffset,
-+                               &bytes_read, &current_offset);
-+              }
-+              if (rc || (bytes_read == 0)) {
-+                      if (total_read) {
-+                              break;
-+                      } else {
-+                              FreeXid(xid);
-+                              return rc;
-+                      }
-+              } else {
-+#ifdef CONFIG_CIFS_STATS
-+                      atomic_inc(&pTcon->num_reads);
-+                      spin_lock(&pTcon->stat_lock);
-+                      pTcon->bytes_read += total_read;
-+                      spin_unlock(&pTcon->stat_lock);
-+#endif
-+                      *poffset += bytes_read;
-+              }
-+      }
-+      FreeXid(xid);
-+      return total_read;
-+}
-+
-+int cifs_file_mmap(struct file * file, struct vm_area_struct * vma)
-+{
-+      struct dentry * dentry = file->f_dentry;
-+      int     rc, xid;
-+
-+      xid = GetXid();
-+      rc = cifs_revalidate(dentry);
-+      if (rc) {
-+              cFYI(1,("Validation prior to mmap failed, error=%d", rc));
-+              FreeXid(xid);
-+              return rc;
-+      }
-+      rc = generic_file_mmap(file, vma);
-+      FreeXid(xid);
-+      return rc;
-+}
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-+static void cifs_copy_cache_pages(struct address_space *mapping, 
-+              struct list_head *pages, int bytes_read, 
-+              char *data,struct pagevec * plru_pvec)
-+{
-+      struct page *page;
-+      char * target;
-+
-+      while (bytes_read > 0) {
-+              if(list_empty(pages))
-+                      break;
-+
-+              page = list_entry(pages->prev, struct page, lru);
-+              list_del(&page->lru);
-+
-+              if (add_to_page_cache(page, mapping, page->index, GFP_KERNEL)) {
-+                      page_cache_release(page);
-+                      cFYI(1,("Add page cache failed"));
-+                      continue;
-+              }
-+
-+              target = kmap_atomic(page,KM_USER0);
-+
-+              if(PAGE_CACHE_SIZE > bytes_read) {
-+                      memcpy(target,data,bytes_read);
-+                      /* zero the tail end of this partial page */
-+                      memset(target+bytes_read,0,PAGE_CACHE_SIZE-bytes_read);
-+                      bytes_read = 0;
-+              } else {
-+                      memcpy(target,data,PAGE_CACHE_SIZE);
-+                      bytes_read -= PAGE_CACHE_SIZE;
-+              }
-+              kunmap_atomic(target,KM_USER0);
-+
-+              flush_dcache_page(page);
-+              SetPageUptodate(page);
-+              unlock_page(page);
-+              if (!pagevec_add(plru_pvec, page))
-+                      __pagevec_lru_add(plru_pvec);
-+              data += PAGE_CACHE_SIZE;
-+      }
-+      return;
-+}
-+
-+
-+static int
-+cifs_readpages(struct file *file, struct address_space *mapping,
-+              struct list_head *page_list, unsigned num_pages)
-+{
-+      int rc = -EACCES;
-+      int xid;
-+      loff_t offset;
-+      struct page * page;
-+      struct cifs_sb_info *cifs_sb;
-+      struct cifsTconInfo *pTcon;
-+      int bytes_read = 0;
-+      unsigned int read_size,i;
-+      char * smb_read_data = NULL;
-+      struct smb_com_read_rsp * pSMBr;
-+      struct pagevec lru_pvec;
-+      struct cifsFileInfo * open_file;
-+
-+      xid = GetXid();
-+      if (file->private_data == NULL) {
-+              FreeXid(xid);
-+              return -EBADF;
-+      }
-+      open_file = (struct cifsFileInfo *)file->private_data;
-+      cifs_sb = CIFS_SB(file->f_dentry->d_sb);
-+      pTcon = cifs_sb->tcon;
-+
-+      pagevec_init(&lru_pvec, 0);
-+
-+      for(i = 0;i<num_pages;) {
-+              unsigned contig_pages;
-+              struct page * tmp_page;
-+              unsigned long expected_index;
-+
-+              if(list_empty(page_list)) {
-+                      break;
-+              }
-+              page = list_entry(page_list->prev, struct page, lru);
-+              offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
-+
-+              /* count adjacent pages that we will read into */
-+              contig_pages = 0;
-+              expected_index = list_entry(page_list->prev,struct page,lru)->index;
-+              list_for_each_entry_reverse(tmp_page,page_list,lru) {
-+                      if(tmp_page->index == expected_index) {
-+                              contig_pages++;
-+                              expected_index++;
-+                      } else {
-+                              break; 
-+                      }
-+              }
-+              if(contig_pages + i >  num_pages) {
-+                      contig_pages = num_pages - i;
-+              }
-+
-+              /* for reads over a certain size could initiate async read ahead */
-+
-+              read_size = contig_pages * PAGE_CACHE_SIZE;
-+              /* Read size needs to be in multiples of one page */
-+              read_size = min_t(const unsigned int,read_size,cifs_sb->rsize & PAGE_CACHE_MASK);
-+
-+              rc = -EAGAIN;
-+              while(rc == -EAGAIN) {
-+                      if ((open_file->invalidHandle) && (!open_file->closePend)) {
-+                              rc = cifs_reopen_file(file->f_dentry->d_inode,
-+                                      file, TRUE);
-+                              if(rc != 0)
-+                                      break;
-+                      }
-+
-+                      rc = CIFSSMBRead(xid, pTcon,
-+                              open_file->netfid,
-+                              read_size, offset,
-+                              &bytes_read, &smb_read_data);
-+                      /* BB need to check return code here */
-+                      if(rc== -EAGAIN) {
-+                              if(smb_read_data) {
-+                                      cifs_buf_release(smb_read_data);
-+                                      smb_read_data = NULL;
-+                              }
-+                      }
-+              }
-+              if ((rc < 0) || (smb_read_data == NULL)) {
-+                      cFYI(1,("Read error in readpages: %d",rc));
-+                      /* clean up remaing pages off list */
-+                      while (!list_empty(page_list) && (i < num_pages)) {
-+                              page = list_entry(page_list->prev, struct page, lru);
-+                              list_del(&page->lru);
-+                              page_cache_release(page);
-+                      }
-+                      break;
-+              } else if (bytes_read > 0) {
-+                      pSMBr = (struct smb_com_read_rsp *)smb_read_data;
-+                      cifs_copy_cache_pages(mapping, page_list, bytes_read,
-+                              smb_read_data + 4 /* RFC1001 hdr */ +
-+                              le16_to_cpu(pSMBr->DataOffset), &lru_pvec);
-+
-+                      i +=  bytes_read >> PAGE_CACHE_SHIFT;
-+#ifdef CONFIG_CIFS_STATS
-+                      atomic_inc(&pTcon->num_reads);
-+                      spin_lock(&pTcon->stat_lock);
-+                      pTcon->bytes_read += bytes_read;
-+                      spin_unlock(&pTcon->stat_lock);
-+#endif
-+                      if((int)(bytes_read & PAGE_CACHE_MASK) != bytes_read) {
-+                              cFYI(1,("Partial page %d of %d read to cache",i++,num_pages));
-+
-+                              i++; /* account for partial page */
-+
-+                              /* server copy of file can have smaller size than client */
-+                              /* BB do we need to verify this common case ? this case is ok - 
-+                              if we are at server EOF we will hit it on next read */
-+
-+                      /* while(!list_empty(page_list) && (i < num_pages)) {
-+                                      page = list_entry(page_list->prev,struct page, list);
-+                                      list_del(&page->list);
-+                                      page_cache_release(page);
-+                              }
-+                              break; */
-+                      }
-+              } else {
-+                      cFYI(1,("No bytes read (%d) at offset %lld . Cleaning remaining pages from readahead list",bytes_read,offset)); 
-+                      /* BB turn off caching and do new lookup on file size at server? */
-+                      while (!list_empty(page_list) && (i < num_pages)) {
-+                              page = list_entry(page_list->prev, struct page, lru);
-+                              list_del(&page->lru);
-+                              page_cache_release(page); /* BB removeme - replace with zero of page? */
-+                      }
-+                      break;
-+              }
-+              if(smb_read_data) {
-+                      cifs_buf_release(smb_read_data);
-+                      smb_read_data = NULL;
-+              }
-+              bytes_read = 0;
-+      }
-+
-+      pagevec_lru_add(&lru_pvec);
-+
-+/* need to free smb_read_data buf before exit */
-+      if(smb_read_data) {
-+              cifs_buf_release(smb_read_data);
-+              smb_read_data = NULL;
-+      } 
-+
-+      FreeXid(xid);
-+      return rc;
-+}
-+#endif
-+
-+static int cifs_readpage_worker(struct file *file, struct page *page, loff_t * poffset)
-+{
-+      char * read_data;
-+      int rc;
-+
-+      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_dentry->d_inode->i_atime = CURRENT_TIME;
-+                                                                                                                           
-+      if(PAGE_CACHE_SIZE > rc) {
-+              memset(read_data+rc, 0, PAGE_CACHE_SIZE - rc);
-+      }
-+      flush_dcache_page(page);
-+      SetPageUptodate(page);
-+      rc = 0;
-+                                                                                                                           
-+io_error:
-+        kunmap(page);
-+      page_cache_release(page);
-+      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) {
-+              FreeXid(xid);
-+              return -EBADF;
-+      }
-+
-+      cFYI(1,("readpage %p at offset %d 0x%x\n",page,(int)offset,(int)offset));
-+
-+      rc = cifs_readpage_worker(file,page,&offset);
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20))
-+      unlock_page(page);
-+#else
-+      UnlockPage(page);
-+#endif
-+
-+      FreeXid(xid);
-+      return rc;
-+}
-+
-+/* 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 */
-+
-+int is_size_safe_to_change(struct cifsInodeInfo * cifsInode)
-+{
-+      struct list_head *tmp;
-+      struct list_head *tmp1;
-+      struct cifsFileInfo *open_file = NULL;
-+      int rc = TRUE;
-+
-+      if(cifsInode == NULL)
-+              return rc;
-+
-+      read_lock(&GlobalSMBSeslock);
-+      list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) {
-+              open_file = list_entry(tmp,struct cifsFileInfo, flist);
-+              if(open_file == NULL)
-+                      break;
-+              if(open_file->closePend)
-+                      continue;
-+      /* We check if file is open for writing,
-+      BB we could supplement this with a check to see if file size
-+      changes have been flushed to server - ie inode metadata dirty */
-+              if((open_file->pfile) &&
-+                 ((open_file->pfile->f_flags & O_RDWR) ||
-+                  (open_file->pfile->f_flags & O_WRONLY))) {
-+                      rc = FALSE;
-+                      break;
-+              }
-+              if(tmp->next == NULL) {
-+                      cFYI(1,("File instance %p removed",tmp));
-+                      break;
-+              }
-+      }
-+      read_unlock(&GlobalSMBSeslock);
-+      return rc;
-+}
-+
-+
-+void
-+fill_in_inode(struct inode *tmp_inode,
-+            FILE_DIRECTORY_INFO * pfindData, int *pobject_type)
-+{
-+      struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode);
-+      struct cifs_sb_info *cifs_sb = CIFS_SB(tmp_inode->i_sb);
-+
-+      pfindData->ExtFileAttributes =
-+          le32_to_cpu(pfindData->ExtFileAttributes);
-+      pfindData->AllocationSize = le64_to_cpu(pfindData->AllocationSize);
-+      pfindData->EndOfFile = le64_to_cpu(pfindData->EndOfFile);
-+      cifsInfo->cifsAttrs = pfindData->ExtFileAttributes;
-+      cifsInfo->time = jiffies;
-+
-+      /* Linux can not store file creation time unfortunately so ignore it */
-+      tmp_inode->i_atime =
-+          cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime));
-+      tmp_inode->i_mtime =
-+          cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
-+      tmp_inode->i_ctime =
-+          cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
-+      /* treat dos attribute of read-only as read-only mode bit e.g. 555? */
-+      /* 2767 perms - indicate mandatory locking */
-+              /* BB fill in uid and gid here? with help from winbind? 
-+                      or retrieve from NTFS stream extended attribute */
-+      if(atomic_read(&cifsInfo->inUse) == 0) {
-+              tmp_inode->i_uid = cifs_sb->mnt_uid;
-+              tmp_inode->i_gid = cifs_sb->mnt_gid;
-+              /* set default mode. will override for dirs below */
-+              tmp_inode->i_mode = cifs_sb->mnt_file_mode;
-+      }
-+
-+      cFYI(0,
-+           ("CIFS FFIRST: Attributes came in as 0x%x",
-+            pfindData->ExtFileAttributes));
-+      if (pfindData->ExtFileAttributes & ATTR_REPARSE) {
-+              *pobject_type = DT_LNK;
-+              /* BB can this and S_IFREG or S_IFDIR be set as in Windows? */
-+              tmp_inode->i_mode |= S_IFLNK;
-+      } else if (pfindData->ExtFileAttributes & ATTR_DIRECTORY) {
-+              *pobject_type = DT_DIR;
-+              /* override default perms since we do not lock dirs */
-+              if(atomic_read(&cifsInfo->inUse) == 0) {
-+                      tmp_inode->i_mode = cifs_sb->mnt_dir_mode;
-+              }
-+              tmp_inode->i_mode |= S_IFDIR;
-+      } else {
-+              *pobject_type = DT_REG;
-+              tmp_inode->i_mode |= S_IFREG;
-+              if(pfindData->ExtFileAttributes & ATTR_READONLY)
-+                      tmp_inode->i_mode &= ~(S_IWUGO);
-+
-+      }/* could add code here - to validate if device or weird share type? */
-+
-+      /* can not fill in nlink here as in qpathinfo version and Unx search */
-+      if(atomic_read(&cifsInfo->inUse) == 0) {
-+              atomic_set(&cifsInfo->inUse,1);
-+      }
-+      if(is_size_safe_to_change(cifsInfo)) {
-+              /* can not safely change the file size here if the
-+              client is writing to it due to potential races */
-+              tmp_inode->i_size = pfindData->EndOfFile;
-+
-+      /* 512 bytes (2**9) is the fake blocksize that must be used */
-+      /* for this calculation, even though the reported blocksize is larger */
-+              tmp_inode->i_blocks = (512 - 1 + pfindData->AllocationSize) >> 9;
-+      }
-+
-+      if (pfindData->AllocationSize < pfindData->EndOfFile)
-+              cFYI(1, ("Possible sparse file: allocation size less than end of file "));
-+      cFYI(1,
-+           ("File Size %ld and blocks %ld and blocksize %ld",
-+            (unsigned long) tmp_inode->i_size, tmp_inode->i_blocks,
-+            tmp_inode->i_blksize));
-+      if (S_ISREG(tmp_inode->i_mode)) {
-+              cFYI(1, (" File inode "));
-+              tmp_inode->i_op = &cifs_file_inode_ops;
-+              tmp_inode->i_fop = &cifs_file_ops;
-+              tmp_inode->i_data.a_ops = &cifs_addr_ops;
-+      } else if (S_ISDIR(tmp_inode->i_mode)) {
-+              cFYI(1, (" Directory inode"));
-+              tmp_inode->i_op = &cifs_dir_inode_ops;
-+              tmp_inode->i_fop = &cifs_dir_ops;
-+      } else if (S_ISLNK(tmp_inode->i_mode)) {
-+              cFYI(1, (" Symbolic Link inode "));
-+              tmp_inode->i_op = &cifs_symlink_inode_ops;
-+      } else {
-+              cFYI(1, (" Init special inode "));
-+              init_special_inode(tmp_inode, tmp_inode->i_mode,
-+                                 kdev_t_to_nr(tmp_inode->i_rdev));
-+      }
-+}
-+
-+void
-+unix_fill_in_inode(struct inode *tmp_inode,
-+                 FILE_UNIX_INFO * pfindData, int *pobject_type)
-+{
-+      struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode);
-+      cifsInfo->time = jiffies;
-+      atomic_inc(&cifsInfo->inUse);
-+
-+      tmp_inode->i_atime =
-+          cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime));
-+      tmp_inode->i_mtime =
-+          cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastModificationTime));
-+      tmp_inode->i_ctime =
-+          cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastStatusChange));
-+
-+      tmp_inode->i_mode = le64_to_cpu(pfindData->Permissions);
-+      pfindData->Type = le32_to_cpu(pfindData->Type);
-+      if (pfindData->Type == UNIX_FILE) {
-+              *pobject_type = DT_REG;
-+              tmp_inode->i_mode |= S_IFREG;
-+      } else if (pfindData->Type == UNIX_SYMLINK) {
-+              *pobject_type = DT_LNK;
-+              tmp_inode->i_mode |= S_IFLNK;
-+      } else if (pfindData->Type == UNIX_DIR) {
-+              *pobject_type = DT_DIR;
-+              tmp_inode->i_mode |= S_IFDIR;
-+      } else if (pfindData->Type == UNIX_CHARDEV) {
-+              *pobject_type = DT_CHR;
-+              tmp_inode->i_mode |= S_IFCHR;
-+              tmp_inode->i_rdev = MKDEV(le64_to_cpu(pfindData->DevMajor),
-+                              le64_to_cpu(pfindData->DevMinor) & MINORMASK);
-+      } else if (pfindData->Type == UNIX_BLOCKDEV) {
-+              *pobject_type = DT_BLK;
-+              tmp_inode->i_mode |= S_IFBLK;
-+              tmp_inode->i_rdev = MKDEV(le64_to_cpu(pfindData->DevMajor),
-+                              le64_to_cpu(pfindData->DevMinor) & MINORMASK);
-+      } else if (pfindData->Type == UNIX_FIFO) {
-+              *pobject_type = DT_FIFO;
-+              tmp_inode->i_mode |= S_IFIFO;
-+      } else if (pfindData->Type == UNIX_SOCKET) {
-+              *pobject_type = DT_SOCK;
-+              tmp_inode->i_mode |= S_IFSOCK;
-+      }
-+
-+      tmp_inode->i_uid = le64_to_cpu(pfindData->Uid);
-+      tmp_inode->i_gid = le64_to_cpu(pfindData->Gid);
-+      tmp_inode->i_nlink = le64_to_cpu(pfindData->Nlinks);
-+
-+      pfindData->NumOfBytes = le64_to_cpu(pfindData->NumOfBytes);
-+      if(is_size_safe_to_change(cifsInfo)) {
-+              /* can not safely change the file size here if the
-+              client is writing to it due to potential races */
-+              pfindData->EndOfFile = le64_to_cpu(pfindData->EndOfFile);
-+              tmp_inode->i_size = pfindData->EndOfFile;
-+
-+      /* 512 bytes (2**9) is the fake blocksize that must be used */
-+      /* for this calculation, not the real blocksize */
-+              tmp_inode->i_blocks = (512 - 1 + pfindData->NumOfBytes) >> 9;
-+      }
-+
-+      if (S_ISREG(tmp_inode->i_mode)) {
-+              cFYI(1, ("File inode"));
-+              tmp_inode->i_op = &cifs_file_inode_ops;
-+              tmp_inode->i_fop = &cifs_file_ops;
-+              tmp_inode->i_data.a_ops = &cifs_addr_ops;
-+      } else if (S_ISDIR(tmp_inode->i_mode)) {
-+              cFYI(1, ("Directory inode"));
-+              tmp_inode->i_op = &cifs_dir_inode_ops;
-+              tmp_inode->i_fop = &cifs_dir_ops;
-+      } else if (S_ISLNK(tmp_inode->i_mode)) {
-+              cFYI(1, ("Symbolic Link inode"));
-+              tmp_inode->i_op = &cifs_symlink_inode_ops;
-+/* tmp_inode->i_fop = *//* do not need to set to anything */
-+      } else {
-+              cFYI(1, ("Special inode")); 
-+              init_special_inode(tmp_inode, tmp_inode->i_mode,
-+                                 kdev_t_to_nr(tmp_inode->i_rdev));
-+      }
-+}
-+
-+static void
-+construct_dentry(struct qstr *qstring, struct file *file,
-+               struct inode **ptmp_inode, struct dentry **pnew_dentry)
-+{
-+      struct dentry *tmp_dentry;
-+      struct cifs_sb_info *cifs_sb;
-+      struct cifsTconInfo *pTcon;
-+      struct cifsInodeInfo *pCifsI;
-+
-+      cFYI(1, ("For %s ", qstring->name));
-+      cifs_sb = CIFS_SB(file->f_dentry->d_sb);
-+      pTcon = cifs_sb->tcon;
-+
-+      qstring->hash = full_name_hash(qstring->name, qstring->len);
-+      tmp_dentry = d_lookup(file->f_dentry, qstring);
-+      if (tmp_dentry) {
-+              cFYI(0, (" existing dentry with inode 0x%p", tmp_dentry->d_inode));
-+              *ptmp_inode = tmp_dentry->d_inode;
-+              /* BB overwrite the old name? i.e. tmp_dentry->d_name and tmp_dentry->d_name.len ?? */
-+              if(*ptmp_inode == NULL) {
-+                      *ptmp_inode = new_inode(file->f_dentry->d_sb);
-+                      if(*ptmp_inode == NULL)
-+                              return;
-+                      d_instantiate(tmp_dentry, *ptmp_inode);
-+                      insert_inode_hash(*ptmp_inode);
-+                      pCifsI = CIFS_I(*ptmp_inode);
-+                      INIT_LIST_HEAD(&pCifsI->openFileList);
-+                      /* can not enable caching for this inode
-+                      until a file instance is open and we
-+                      can check the oplock flag on the open
-+                      response */
-+                      (*ptmp_inode)->i_blksize = CIFS_MAX_MSGSIZE;
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,15))
-+                      (*ptmp_inode)->i_blkbits = 14;  /* 2**14 = CIFS_MAX_MSGSIZE */
-+#endif
-+                      pCifsI->clientCanCacheRead = FALSE;
-+                      pCifsI->clientCanCacheAll = FALSE;
-+                      pCifsI->time = 0;
-+                      /* do not need to set cifs Attrs since
-+                      they are about to be overwritten
-+                      in fill_in_inode */
-+                      atomic_set(&pCifsI->inUse, 0);
-+              }
-+      } else {
-+              tmp_dentry = d_alloc(file->f_dentry, qstring);
-+              if(tmp_dentry == NULL) {
-+                      cERROR(1,("Failed allocating dentry"));
-+                      return;
-+              }
-+
-+              if(ptmp_inode) {                        
-+                      *ptmp_inode = new_inode(file->f_dentry->d_sb);
-+                      if(*ptmp_inode == NULL)
-+                              return;
-+                      pCifsI = CIFS_I(*ptmp_inode);
-+                      insert_inode_hash(*ptmp_inode);
-+                      INIT_LIST_HEAD(&pCifsI->openFileList);
-+                      /* can not enable caching for this inode 
-+                      until a file instance is open and we
-+                      can check the oplock flag on the open
-+                      response */
-+                      (*ptmp_inode)->i_blksize = CIFS_MAX_MSGSIZE;
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,15))
-+                      (*ptmp_inode)->i_blkbits = 14;  /* 2**14 = CIFS_MAX_MSGSIZE */
-+#endif
-+                      pCifsI->clientCanCacheRead = FALSE;
-+                      pCifsI->clientCanCacheAll = FALSE;
-+                      pCifsI->time = 0;
-+                      /* do not need to set cifs Attrs since
-+                              they are about to be overwritten 
-+                              in fill_in_inode */
-+                      atomic_set(&pCifsI->inUse, 0);
-+              }
-+              tmp_dentry->d_op = &cifs_dentry_ops;
-+              d_instantiate(tmp_dentry, *ptmp_inode);
-+              d_rehash(tmp_dentry);
-+      }
-+
-+      tmp_dentry->d_time = jiffies;
-+      *pnew_dentry = tmp_dentry;
-+}
-+
-+static void reset_resume_key(struct file * dir_file, 
-+                              unsigned char * filename, 
-+                              unsigned int len,int Unicode,struct nls_table * nls_tab) {
-+      struct cifsFileInfo *cifsFile;
-+
-+      cifsFile = (struct cifsFileInfo *)dir_file->private_data;
-+      if(cifsFile == NULL)
-+              return;
-+      if(cifsFile->search_resume_name) {
-+              kfree(cifsFile->search_resume_name);
-+      }
-+
-+      if(Unicode) 
-+              len *= 2;
-+      cifsFile->resume_name_length = len;
-+
-+      cifsFile->search_resume_name = 
-+              kmalloc(cifsFile->resume_name_length, GFP_KERNEL);
-+
-+      if(cifsFile->search_resume_name == NULL) {
-+              cERROR(1,("failed new resume key allocate, length %d",
-+                                cifsFile->resume_name_length));
-+              return;
-+      }
-+      if(Unicode)
-+              cifs_strtoUCS((wchar_t *) cifsFile->search_resume_name,
-+                      filename, len, nls_tab);
-+      else
-+              memcpy(cifsFile->search_resume_name, filename, 
-+                 cifsFile->resume_name_length);
-+      cFYI(1,("Reset resume key to: %s with len %d",filename,len));
-+      return;
-+}
-+
-+
-+
-+static int
-+cifs_filldir(struct qstr *pqstring, FILE_DIRECTORY_INFO * pfindData,
-+           struct file *file, filldir_t filldir, void *direntry)
-+{
-+      struct inode *tmp_inode;
-+      struct dentry *tmp_dentry;
-+      int object_type,rc;
-+
-+      pqstring->name = pfindData->FileName;
-+      pqstring->len = pfindData->FileNameLength;
-+
-+      construct_dentry(pqstring, file, &tmp_inode, &tmp_dentry);
-+      if((tmp_inode == NULL) || (tmp_dentry == NULL)) {
-+              return -ENOMEM;
-+      }
-+      fill_in_inode(tmp_inode, pfindData, &object_type);
-+      rc = filldir(direntry, pfindData->FileName, pqstring->len, file->f_pos,
-+              tmp_inode->i_ino, object_type);
-+      if(rc) {
-+              /* due to readdir error we need to recalculate resume 
-+              key so next readdir will restart on right entry */
-+              cFYI(1,("Error %d on filldir of %s",rc ,pfindData->FileName));
-+      }
-+      dput(tmp_dentry);
-+      return rc;
-+}
-+
-+static int
-+cifs_filldir_unix(struct qstr *pqstring,
-+                FILE_UNIX_INFO * pUnixFindData, struct file *file,
-+                filldir_t filldir, void *direntry)
-+{
-+      struct inode *tmp_inode;
-+      struct dentry *tmp_dentry;
-+      int object_type, rc;
-+
-+      pqstring->name = pUnixFindData->FileName;
-+      pqstring->len = strnlen(pUnixFindData->FileName, MAX_PATHCONF);
-+
-+      construct_dentry(pqstring, file, &tmp_inode, &tmp_dentry);
-+        if((tmp_inode == NULL) || (tmp_dentry == NULL)) {
-+                return -ENOMEM;
-+        }
-+
-+      unix_fill_in_inode(tmp_inode, pUnixFindData, &object_type);
-+      rc = filldir(direntry, pUnixFindData->FileName, pqstring->len,
-+              file->f_pos, tmp_inode->i_ino, object_type);
-+      if(rc) {
-+              /* due to readdir error we need to recalculate resume 
-+                      key so next readdir will restart on right entry */
-+              cFYI(1,("Error %d on filldir of %s",rc ,pUnixFindData->FileName));
-+      }
-+      dput(tmp_dentry);
-+      return rc;
-+}
-+
-+int
-+cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
-+{
-+      int rc = 0;
-+      int xid;
-+      int Unicode = FALSE;
-+      int UnixSearch = FALSE;
-+      unsigned int bufsize, i;
-+      __u16 searchHandle;
-+      struct cifs_sb_info *cifs_sb;
-+      struct cifsTconInfo *pTcon;
-+      struct cifsFileInfo *cifsFile = NULL;
-+      char *full_path = NULL;
-+      char *data;
-+      struct qstr qstring;
-+      T2_FFIRST_RSP_PARMS findParms;
-+      T2_FNEXT_RSP_PARMS findNextParms;
-+      FILE_DIRECTORY_INFO *pfindData;
-+      FILE_DIRECTORY_INFO *lastFindData;
-+      FILE_UNIX_INFO *pfindDataUnix;
-+
-+      xid = GetXid();
-+
-+      cifs_sb = CIFS_SB(file->f_dentry->d_sb);
-+      pTcon = cifs_sb->tcon;
-+      bufsize = pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE;
-+      if(bufsize > CIFS_MAX_MSGSIZE) {
-+              FreeXid(xid);
-+              return -EIO;
-+      }
-+      data = kmalloc(bufsize, GFP_KERNEL);
-+      pfindData = (FILE_DIRECTORY_INFO *) data;
-+
-+      if(file->f_dentry == NULL) {
-+              FreeXid(xid);
-+              return -EIO;
-+      }
-+      down(&file->f_dentry->d_sb->s_vfs_rename_sem);
-+      full_path = build_wildcard_path_from_dentry(file->f_dentry);
-+      up(&file->f_dentry->d_sb->s_vfs_rename_sem);
-+
-+
-+      cFYI(1, ("Full path: %s start at: %lld ", full_path, file->f_pos));
-+
-+      switch ((int) file->f_pos) {
-+      case 0:
-+              if (filldir(direntry, ".", 1, file->f_pos,
-+                   file->f_dentry->d_inode->i_ino, DT_DIR) < 0) {
-+                      cERROR(1, ("Filldir for current dir failed "));
-+                      break;
-+              }
-+              file->f_pos++;
-+              /* fallthrough */
-+      case 1:
-+              if (filldir(direntry, "..", 2, file->f_pos,
-+                   file->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) {
-+                      cERROR(1, ("Filldir for parent dir failed "));
-+                      break;
-+              }
-+              file->f_pos++;
-+              /* fallthrough */
-+      case 2:
-+              if (file->private_data != NULL) {
-+                      cifsFile =
-+                              (struct cifsFileInfo *) file->private_data;
-+                      if (cifsFile->endOfSearch) {
-+                              if(cifsFile->emptyDir) {
-+                                      cFYI(1, ("End of search, empty dir"));
-+                                      rc = 0;
-+                                      break;
-+                              }
-+                      } else {
-+                              cifsFile->invalidHandle = TRUE;
-+                              CIFSFindClose(xid, pTcon, cifsFile->netfid);
-+                      }
-+                      if(cifsFile->search_resume_name) {
-+                              kfree(cifsFile->search_resume_name);
-+                              cifsFile->search_resume_name = NULL;
-+                      }
-+              }
-+              rc = CIFSFindFirst(xid, pTcon, full_path, pfindData,
-+                              &findParms, cifs_sb->local_nls,
-+                              &Unicode, &UnixSearch);
-+              cFYI(1, ("Count: %d  End: %d ", findParms.SearchCount,
-+                      findParms.EndofSearch));
-+ 
-+              if (rc == 0) {
-+                      searchHandle = findParms.SearchHandle;
-+                      if(file->private_data == NULL)
-+                              file->private_data =
-+                                      kmalloc(sizeof(struct cifsFileInfo),GFP_KERNEL);
-+                      if (file->private_data) {
-+                              memset(file->private_data, 0,
-+                                     sizeof (struct cifsFileInfo));
-+                              cifsFile =
-+                                  (struct cifsFileInfo *) file->private_data;
-+                              cifsFile->netfid = searchHandle;
-+                              cifsFile->invalidHandle = FALSE;
-+                              init_MUTEX(&cifsFile->fh_sem);
-+                      } else {
-+                              rc = -ENOMEM;
-+                              break;
-+                      }
-+
-+                      renew_parental_timestamps(file->f_dentry);
-+                      lastFindData = 
-+                              (FILE_DIRECTORY_INFO *) ((char *) pfindData + 
-+                                      findParms.LastNameOffset);
-+                      if((char *)lastFindData > (char *)pfindData + bufsize) {
-+                              cFYI(1,("last search entry past end of packet"));
-+                              rc = -EIO;
-+                              break;
-+                      }
-+                      /* Offset of resume key same for levels 257 and 514 */
-+                      cifsFile->resume_key = lastFindData->FileIndex;
-+                      if(UnixSearch == FALSE) {
-+                              cifsFile->resume_name_length = 
-+                                      le32_to_cpu(lastFindData->FileNameLength);
-+                              if(cifsFile->resume_name_length > bufsize - 64) {
-+                                      cFYI(1,("Illegal resume file name length %d",
-+                                              cifsFile->resume_name_length));
-+                                      rc = -ENOMEM;
-+                                      break;
-+                              }
-+                              cifsFile->search_resume_name = 
-+                                      kmalloc(cifsFile->resume_name_length, GFP_KERNEL);
-+                              cFYI(1,("Last file: %s with name %d bytes long",
-+                                      lastFindData->FileName,
-+                                      cifsFile->resume_name_length));
-+                              memcpy(cifsFile->search_resume_name,
-+                                      lastFindData->FileName, 
-+                                      cifsFile->resume_name_length);
-+                      } else {
-+                              pfindDataUnix = (FILE_UNIX_INFO *)lastFindData;
-+                              if (Unicode == TRUE) {
-+                                      for(i=0;(pfindDataUnix->FileName[i] 
-+                                                  | pfindDataUnix->FileName[i+1]);
-+                                              i+=2) {
-+                                              if(i > bufsize-64)
-+                                                      break;
-+                                      }
-+                                      cifsFile->resume_name_length = i + 2;
-+                              } else {
-+                                      cifsFile->resume_name_length = 
-+                                              strnlen(pfindDataUnix->FileName,
-+                                                      bufsize-63);
-+                              }
-+                              if(cifsFile->resume_name_length > bufsize - 64) {
-+                                      cFYI(1,("Illegal resume file name length %d",
-+                                              cifsFile->resume_name_length));
-+                                      rc = -ENOMEM;
-+                                      break;
-+                              }
-+                              cifsFile->search_resume_name = 
-+                                      kmalloc(cifsFile->resume_name_length, GFP_KERNEL);
-+                              cFYI(1,("Last file: %s with name %d bytes long",
-+                                      pfindDataUnix->FileName,
-+                                      cifsFile->resume_name_length));
-+                              memcpy(cifsFile->search_resume_name,
-+                                      pfindDataUnix->FileName, 
-+                                      cifsFile->resume_name_length);
-+                      }
-+                      for (i = 2; i < (unsigned int)findParms.SearchCount + 2; i++) {
-+                              if (UnixSearch == FALSE) {
-+                                      pfindData->FileNameLength =
-+                                        le32_to_cpu(pfindData->FileNameLength);
-+                                      if (Unicode == TRUE)
-+                                              pfindData->FileNameLength =
-+                                                  cifs_strfromUCS_le
-+                                                  (pfindData->FileName,
-+                                                   (wchar_t *)
-+                                                   pfindData->FileName,
-+                                                   (pfindData->
-+                                                    FileNameLength) / 2,
-+                                                   cifs_sb->local_nls);
-+                                      qstring.len = pfindData->FileNameLength;
-+                                      if (((qstring.len != 1)
-+                                           || (pfindData->FileName[0] != '.'))
-+                                          && ((qstring.len != 2)
-+                                              || (pfindData->
-+                                                  FileName[0] != '.')
-+                                              || (pfindData->
-+                                                  FileName[1] != '.'))) {
-+                                              if(cifs_filldir(&qstring,
-+                                                           pfindData,
-+                                                           file, filldir,
-+                                                           direntry)) {
-+                                                      /* do not end search if
-+                                                              kernel not ready to take
-+                                                              remaining entries yet */
-+                                                      reset_resume_key(file, pfindData->FileName,qstring.len,
-+                                                              Unicode, cifs_sb->local_nls);
-+                                                      findParms.EndofSearch = 0;
-+                                                      break;
-+                                              }
-+                                              file->f_pos++;
-+                                      }
-+                              } else {        /* UnixSearch */
-+                                      pfindDataUnix =
-+                                          (FILE_UNIX_INFO *) pfindData;
-+                                      if (Unicode == TRUE)
-+                                              qstring.len =
-+                                                      cifs_strfromUCS_le
-+                                                      (pfindDataUnix->FileName,
-+                                                      (wchar_t *)
-+                                                      pfindDataUnix->FileName,
-+                                                      MAX_PATHCONF,
-+                                                      cifs_sb->local_nls);
-+                                      else
-+                                              qstring.len =
-+                                                      strnlen(pfindDataUnix->
-+                                                        FileName,
-+                                                        MAX_PATHCONF);
-+                                      if (((qstring.len != 1)
-+                                           || (pfindDataUnix->
-+                                               FileName[0] != '.'))
-+                                          && ((qstring.len != 2)
-+                                              || (pfindDataUnix->
-+                                                  FileName[0] != '.')
-+                                              || (pfindDataUnix->
-+                                                  FileName[1] != '.'))) {
-+                                              if(cifs_filldir_unix(&qstring,
-+                                                                pfindDataUnix,
-+                                                                file,
-+                                                                filldir,
-+                                                                direntry)) {
-+                                                      /* do not end search if
-+                                                              kernel not ready to take
-+                                                              remaining entries yet */
-+                                                      findParms.EndofSearch = 0;
-+                                                      reset_resume_key(file, pfindDataUnix->FileName,
-+                                                              qstring.len,Unicode,cifs_sb->local_nls);
-+                                                      break;
-+                                              }
-+                                              file->f_pos++;
-+                                      }
-+                              }
-+                              /* works also for Unix ff struct since first field of both */
-+                              pfindData = 
-+                                      (FILE_DIRECTORY_INFO *) ((char *) pfindData
-+                                               + le32_to_cpu(pfindData->NextEntryOffset));
-+                              /* BB also should check to make sure that pointer is not beyond the end of the SMB */
-+                              /* if(pfindData > lastFindData) rc = -EIO; break; */
-+                      }       /* end for loop */
-+                      if ((findParms.EndofSearch != 0) && cifsFile) {
-+                              cifsFile->endOfSearch = TRUE;
-+                              if(findParms.SearchCount == 2)
-+                                      cifsFile->emptyDir = TRUE;
-+                      }
-+              } else {
-+                      if (cifsFile)
-+                              cifsFile->endOfSearch = TRUE;
-+                      /* unless parent directory gone do not return error */
-+                      rc = 0;
-+              }
-+              break;
-+      default:
-+              if (file->private_data == NULL) {
-+                      rc = -EBADF;
-+                      cFYI(1,
-+                           ("Readdir on closed srch, pos = %lld",
-+                            file->f_pos));
-+              } else {
-+                      cifsFile = (struct cifsFileInfo *) file->private_data;
-+                      if (cifsFile->endOfSearch) {
-+                              rc = 0;
-+                              cFYI(1, ("End of search "));
-+                              break;
-+                      }
-+                      searchHandle = cifsFile->netfid;
-+                      rc = CIFSFindNext(xid, pTcon, pfindData,
-+                              &findNextParms, searchHandle, 
-+                              cifsFile->search_resume_name,
-+                              cifsFile->resume_name_length,
-+                              cifsFile->resume_key,
-+                              &Unicode, &UnixSearch);
-+                      cFYI(1,("Count: %d  End: %d ",
-+                            findNextParms.SearchCount,
-+                            findNextParms.EndofSearch));
-+                      if ((rc == 0) && (findNextParms.SearchCount != 0)) {
-+                      /* BB save off resume key, key name and name length  */
-+                              lastFindData = 
-+                                      (FILE_DIRECTORY_INFO *) ((char *) pfindData 
-+                                              + findNextParms.LastNameOffset);
-+                              if((char *)lastFindData > (char *)pfindData + bufsize) {
-+                                      cFYI(1,("last search entry past end of packet"));
-+                                      rc = -EIO;
-+                                      break;
-+                              }
-+                              /* Offset of resume key same for levels 257 and 514 */
-+                              cifsFile->resume_key = lastFindData->FileIndex;
-+
-+                              if(UnixSearch == FALSE) {
-+                                      cifsFile->resume_name_length = 
-+                                              le32_to_cpu(lastFindData->FileNameLength);
-+                                      if(cifsFile->resume_name_length > bufsize - 64) {
-+                                              cFYI(1,("Illegal resume file name length %d",
-+                                                      cifsFile->resume_name_length));
-+                                              rc = -ENOMEM;
-+                                              break;
-+                                      }
-+                                      /* Free the memory allocated by previous findfirst 
-+                                      or findnext call - we can not reuse the memory since
-+                                      the resume name may not be same string length */
-+                                      if(cifsFile->search_resume_name)
-+                                              kfree(cifsFile->search_resume_name);
-+                                      cifsFile->search_resume_name = 
-+                                              kmalloc(cifsFile->resume_name_length, GFP_KERNEL);
-+                                      cFYI(1,("Last file: %s with name %d bytes long",
-+                                              lastFindData->FileName,
-+                                              cifsFile->resume_name_length));
-+                                      memcpy(cifsFile->search_resume_name,
-+                                              lastFindData->FileName, 
-+                                              cifsFile->resume_name_length);
-+                              } else {
-+                                      pfindDataUnix = (FILE_UNIX_INFO *)lastFindData;
-+                                      if (Unicode == TRUE) {
-+                                              for(i=0;(pfindDataUnix->FileName[i] 
-+                                                              | pfindDataUnix->FileName[i+1]);
-+                                                      i+=2) {
-+                                                      if(i > bufsize-64)
-+                                                              break;
-+                                              }
-+                                              cifsFile->resume_name_length = i + 2;
-+                                      } else {
-+                                              cifsFile->resume_name_length = 
-+                                                      strnlen(pfindDataUnix->
-+                                                       FileName,
-+                                                       MAX_PATHCONF);
-+                                      }
-+                                      if(cifsFile->resume_name_length > bufsize - 64) {
-+                                              cFYI(1,("Illegal resume file name length %d",
-+                                                              cifsFile->resume_name_length));
-+                                              rc = -ENOMEM;
-+                                              break;
-+                                      }
-+                                      /* Free the memory allocated by previous findfirst 
-+                                      or findnext call - we can not reuse the memory since
-+                                      the resume name may not be same string length */
-+                                      if(cifsFile->search_resume_name)
-+                                              kfree(cifsFile->search_resume_name);
-+                                      cifsFile->search_resume_name = 
-+                                              kmalloc(cifsFile->resume_name_length, GFP_KERNEL);
-+                                      cFYI(1,("fnext last file: %s with name %d bytes long",
-+                                              pfindDataUnix->FileName,
-+                                              cifsFile->resume_name_length));
-+                                      memcpy(cifsFile->search_resume_name,
-+                                              pfindDataUnix->FileName, 
-+                                              cifsFile->resume_name_length);
-+                              }
-+
-+                              for (i = 0; i < findNextParms.SearchCount; i++) {
-+                                      pfindData->FileNameLength =
-+                                          le32_to_cpu(pfindData->
-+                                                      FileNameLength);
-+                                      if (UnixSearch == FALSE) {
-+                                              if (Unicode == TRUE)
-+                                                      pfindData->FileNameLength =
-+                                                        cifs_strfromUCS_le
-+                                                        (pfindData->FileName,
-+                                                        (wchar_t *)
-+                                                        pfindData->FileName,
-+                                                        (pfindData->FileNameLength)/ 2,
-+                                                        cifs_sb->local_nls);
-+                                              qstring.len = 
-+                                                      pfindData->FileNameLength;
-+                                              if (((qstring.len != 1)
-+                                                  || (pfindData->FileName[0] != '.'))
-+                                                  && ((qstring.len != 2)
-+                                                      || (pfindData->FileName[0] != '.')
-+                                                      || (pfindData->FileName[1] !=
-+                                                          '.'))) {
-+                                                      if(cifs_filldir
-+                                                          (&qstring,
-+                                                           pfindData,
-+                                                           file, filldir,
-+                                                           direntry)) {
-+                                                      /* do not end search if
-+                                                              kernel not ready to take
-+                                                              remaining entries yet */
-+                                                              findNextParms.EndofSearch = 0;
-+                                                              reset_resume_key(file, pfindData->FileName,qstring.len,
-+                                                                      Unicode,cifs_sb->local_nls);
-+                                                              break;
-+                                                      }
-+                                                      file->f_pos++;
-+                                              }
-+                                      } else {        /* UnixSearch */
-+                                              pfindDataUnix =
-+                                                  (FILE_UNIX_INFO *)
-+                                                  pfindData;
-+                                              if (Unicode == TRUE)
-+                                                      qstring.len =
-+                                                        cifs_strfromUCS_le
-+                                                        (pfindDataUnix->FileName,
-+                                                        (wchar_t *)
-+                                                        pfindDataUnix->FileName,
-+                                                        MAX_PATHCONF,
-+                                                        cifs_sb->local_nls);
-+                                              else
-+                                                      qstring.len =
-+                                                        strnlen
-+                                                        (pfindDataUnix->
-+                                                        FileName,
-+                                                        MAX_PATHCONF);
-+                                              if (((qstring.len != 1)
-+                                                   || (pfindDataUnix->
-+                                                       FileName[0] != '.'))
-+                                                  && ((qstring.len != 2)
-+                                                      || (pfindDataUnix->
-+                                                          FileName[0] != '.')
-+                                                      || (pfindDataUnix->
-+                                                          FileName[1] !=
-+                                                          '.'))) {
-+                                                      if(cifs_filldir_unix
-+                                                          (&qstring,
-+                                                           pfindDataUnix,
-+                                                           file, filldir,
-+                                                           direntry)) {
-+                                                              /* do not end search if
-+                                                              kernel not ready to take
-+                                                              remaining entries yet */
-+                                                              findNextParms.EndofSearch = 0;
-+                                                              reset_resume_key(file, pfindDataUnix->FileName,qstring.len,
-+                                                                      Unicode,cifs_sb->local_nls);
-+                                                              break;
-+                                                      }
-+                                                      file->f_pos++;
-+                                              }
-+                                      }
-+                                      pfindData = (FILE_DIRECTORY_INFO *) ((char *) pfindData + le32_to_cpu(pfindData->NextEntryOffset));     /* works also for Unix find struct since this is the first field of both */
-+                                      /* BB also should check to make sure that pointer is not beyond the end of the SMB */
-+                              } /* end for loop */
-+                              if (findNextParms.EndofSearch != 0) {
-+                                      cifsFile->endOfSearch = TRUE;
-+                              }
-+                      } else {
-+                              cifsFile->endOfSearch = TRUE;
-+                              rc = 0; /* unless parent directory disappeared - do not return error here (eg Access Denied or no more files) */
-+                      }
-+              }
-+      } /* end switch */
-+      if (data)
-+              kfree(data);
-+      if (full_path)
-+              kfree(full_path);
-+      FreeXid(xid);
-+
-+      return rc;
-+}
-+int cifs_prepare_write(struct file *file, struct page *page,
-+                      unsigned from, unsigned to)
-+{
-+      int rc = 0;
-+        loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
-+      cFYI(1,("prepare write for page %p from %d to %d",page,from,to));
-+      if (!Page_Uptodate(page)) {
-+      /*      if (to - from != PAGE_CACHE_SIZE) {
-+                      void *kaddr = kmap_atomic(page, KM_USER0);
-+                      memset(kaddr, 0, from);
-+                      memset(kaddr + to, 0, PAGE_CACHE_SIZE - to);
-+                      flush_dcache_page(page);
-+                      kunmap_atomic(kaddr, KM_USER0);
-+              } */
-+              /* If we are writing a full page it will be up to date,
-+              no need to read from the server */
-+              if((to==PAGE_CACHE_SIZE) && (from == 0))
-+                      SetPageUptodate(page);
-+
-+              /* might as well read a page, it is fast enough */
-+              if((file->f_flags & O_ACCMODE) != O_WRONLY) {
-+                      rc = cifs_readpage_worker(file,page,&offset);
-+              } else {
-+              /* should we try using another
-+              file handle if there is one - how would we lock it
-+              to prevent close of that handle racing with this read? */
-+              /* In any case this will be written out by commit_write */
-+              }
-+      }
-+
-+      /* BB should we pass any errors back? e.g. if we do not have read access to the file */
-+      return 0;
-+}
-+
-+
-+struct address_space_operations cifs_addr_ops = {
-+      .readpage = cifs_readpage,
-+/*    .readpages = cifs_readpages, */
-+      .writepage = cifs_writepage,
-+      .prepare_write = cifs_prepare_write, 
-+      .commit_write = cifs_commit_write,
-+      .sync_page = cifs_sync_page,
-+      /*.direct_IO = */
-+};
---- /dev/null
-+++ b/fs/cifs/inode.c
-@@ -0,0 +1,1079 @@
-+/*
-+ *   fs/cifs/inode.c
-+ *
-+ *   Copyright (C) International Business Machines  Corp., 2002,2003
-+ *   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/pagemap.h>
-+#include <linux/version.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"
-+
-+extern int is_size_safe_to_change(struct cifsInodeInfo *);
-+
-+struct inode * get_cifs_inode(struct super_block * sb)
-+{
-+      struct inode * newinode;
-+      newinode = new_inode(sb);
-+      cFYI(1,("got new inode %p",newinode));
-+      if(newinode) {    
-+              struct cifsInodeInfo * cifsInfo = CIFS_I(newinode);
-+              cifsInfo->clientCanCacheRead = FALSE;
-+              cifsInfo->clientCanCacheAll = FALSE;
-+              INIT_LIST_HEAD(&cifsInfo->openFileList);
-+              cifsInfo->cifsAttrs = 0x20;   /* default */
-+              newinode->i_blksize = CIFS_MAX_MSGSIZE;
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,15))
-+              newinode->i_blkbits = 14;  /* 2**14 = CIFS_MAX_MSGSIZE */
-+#endif
-+              atomic_set(&cifsInfo->inUse, 0);
-+              cifsInfo->time = 0;
-+              insert_inode_hash(newinode);
-+      }
-+      return newinode;
-+
-+}
-+
-+int
-+cifs_get_inode_info_unix(struct inode **pinode,
-+                       const unsigned char *search_path,
-+                       struct super_block *sb,int xid)
-+{
-+      int rc = 0;
-+      FILE_UNIX_BASIC_INFO findData;
-+      struct cifsTconInfo *pTcon;
-+      struct inode *inode;
-+      struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
-+      char *tmp_path;
-+
-+      pTcon = cifs_sb->tcon;
-+      cFYI(1, (" Getting info on %s ", search_path));
-+      /* we could have done a find first instead but this returns more info */
-+      rc = CIFSSMBUnixQPathInfo(xid, pTcon, search_path, &findData,
-+                                cifs_sb->local_nls);
-+      /* dump_mem("\nUnixQPathInfo return data", &findData, sizeof(findData)); */
-+      if (rc) {
-+              if (rc == -EREMOTE) {
-+                      tmp_path =
-+                          kmalloc(strnlen
-+                                  (pTcon->treeName,
-+                                   MAX_TREE_SIZE + 1) +
-+                                  strnlen(search_path, MAX_PATHCONF) + 1,
-+                                  GFP_KERNEL);
-+                      if (tmp_path == NULL) {
-+                              return -ENOMEM;
-+                      }
-+        /* have to skip first of the double backslash of UNC name */
-+                      strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE);      
-+                      strncat(tmp_path, search_path, MAX_PATHCONF);
-+                      rc = connect_to_dfs_path(xid, pTcon->ses,
-+                                               /* treename + */ tmp_path,
-+                                               cifs_sb->local_nls);
-+                      kfree(tmp_path);
-+
-+                      /* BB fix up inode etc. */
-+              } else if (rc) {
-+                      return rc;
-+              }
-+
-+      } else {
-+              struct cifsInodeInfo *cifsInfo;
-+
-+              /* get new inode */
-+              if (*pinode == NULL) {
-+                      *pinode = get_cifs_inode(sb);
-+              }
-+              if(*pinode == NULL) {
-+                      return -ENOMEM;
-+              }
-+                      
-+              inode = *pinode;
-+              cifsInfo = CIFS_I(inode);
-+
-+              cFYI(1, (" Old time %ld ", cifsInfo->time));
-+              cifsInfo->time = jiffies;
-+              cFYI(1, (" New time %ld ", cifsInfo->time));
-+              atomic_set(&cifsInfo->inUse,1); /* ok to set on every refresh of inode */
-+
-+              inode->i_atime =
-+                  cifs_NTtimeToUnix(le64_to_cpu(findData.LastAccessTime));
-+              inode->i_mtime =
-+                  cifs_NTtimeToUnix(le64_to_cpu
-+                              (findData.LastModificationTime));
-+              inode->i_ctime =
-+                  cifs_NTtimeToUnix(le64_to_cpu(findData.LastStatusChange));
-+              inode->i_mode = le64_to_cpu(findData.Permissions);
-+              findData.Type = le32_to_cpu(findData.Type);
-+              if (findData.Type == UNIX_FILE) {
-+                      inode->i_mode |= S_IFREG;
-+              } else if (findData.Type == UNIX_SYMLINK) {
-+                      inode->i_mode |= S_IFLNK;
-+              } else if (findData.Type == UNIX_DIR) {
-+                      inode->i_mode |= S_IFDIR;
-+              } else if (findData.Type == UNIX_CHARDEV) {
-+                      inode->i_mode |= S_IFCHR;
-+                      inode->i_rdev = MKDEV(le64_to_cpu(findData.DevMajor),
-+                              le64_to_cpu(findData.DevMinor) & MINORMASK);
-+              } else if (findData.Type == UNIX_BLOCKDEV) {
-+                      inode->i_mode |= S_IFBLK;
-+                      inode->i_rdev = MKDEV(le64_to_cpu(findData.DevMajor),
-+                              le64_to_cpu(findData.DevMinor) & MINORMASK);
-+              } else if (findData.Type == UNIX_FIFO) {
-+                      inode->i_mode |= S_IFIFO;
-+              } else if (findData.Type == UNIX_SOCKET) {
-+                      inode->i_mode |= S_IFSOCK;
-+              }
-+              inode->i_uid = le64_to_cpu(findData.Uid);
-+              inode->i_gid = le64_to_cpu(findData.Gid);
-+              inode->i_nlink = le64_to_cpu(findData.Nlinks);
-+              findData.NumOfBytes = le64_to_cpu(findData.NumOfBytes);
-+              findData.EndOfFile = le64_to_cpu(findData.EndOfFile);
-+
-+              if(is_size_safe_to_change(cifsInfo)) {
-+              /* can not safely change the file size here if the
-+                 client is writing to it due to potential races */
-+                      inode->i_size = findData.EndOfFile;
-+/* blksize needs to be multiple of two. So safer to default to blksize
-+      and blkbits set in superblock so 2**blkbits and blksize will match */
-+/*            inode->i_blksize =
-+                  (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/
-+
-+              /* This seems incredibly stupid but it turns out that
-+              i_blocks is not related to (i_size / i_blksize), instead a
-+              size of 512 is required to be used for calculating num blocks */
-+               
-+
-+/*            inode->i_blocks = 
-+                      (inode->i_blksize - 1 + findData.NumOfBytes) >> inode->i_blkbits;*/
-+
-+              /* 512 bytes (2**9) is the fake blocksize that must be used */
-+              /* for this calculation */
-+                      inode->i_blocks = (512 - 1 + findData.NumOfBytes) >> 9;
-+              }
-+
-+              if (findData.NumOfBytes < findData.EndOfFile)
-+                      cFYI(1, ("Server inconsistency Error: it says allocation size less than end of file "));
-+              cFYI(1,
-+                   ("Size %ld and blocks %ld ",
-+                    (unsigned long) inode->i_size, inode->i_blocks));
-+              if (S_ISREG(inode->i_mode)) {
-+                      cFYI(1, (" File inode "));
-+                      inode->i_op = &cifs_file_inode_ops;
-+                      inode->i_fop = &cifs_file_ops;
-+                      inode->i_data.a_ops = &cifs_addr_ops;
-+              } else if (S_ISDIR(inode->i_mode)) {
-+                      cFYI(1, (" Directory inode"));
-+                      inode->i_op = &cifs_dir_inode_ops;
-+                      inode->i_fop = &cifs_dir_ops;
-+              } else if (S_ISLNK(inode->i_mode)) {
-+                      cFYI(1, (" Symbolic Link inode "));
-+                      inode->i_op = &cifs_symlink_inode_ops;
-+/* tmp_inode->i_fop = *//* do not need to set to anything */
-+              } else {
-+                      cFYI(1, (" Init special inode "));
-+                      init_special_inode(inode, inode->i_mode,
-+                                         kdev_t_to_nr(inode->i_rdev));
-+              }
-+      }
-+      return rc;
-+}
-+
-+int
-+cifs_get_inode_info(struct inode **pinode, const unsigned char *search_path, 
-+              FILE_ALL_INFO * pfindData, struct super_block *sb, int xid)
-+{
-+      int rc = 0;
-+      struct cifsTconInfo *pTcon;
-+      struct inode *inode;
-+      struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
-+      char *tmp_path;
-+      char *buf = NULL;
-+
-+      pTcon = cifs_sb->tcon;
-+      cFYI(1,("Getting info on %s ", search_path));
-+
-+      if((pfindData == NULL) && (*pinode != NULL)) {
-+              if(CIFS_I(*pinode)->clientCanCacheRead) {
-+                      cFYI(1,("No need to revalidate inode sizes on cached file "));
-+                      return rc;
-+              }
-+      }
-+
-+      /* if file info not passed in then get it from server */
-+      if(pfindData == NULL) {
-+              buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL);
-+              pfindData = (FILE_ALL_INFO *)buf;
-+      /* could do find first instead but this returns more info */
-+              rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData,
-+                            cifs_sb->local_nls);
-+      }
-+      /* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */
-+      if (rc) {
-+              if (rc == -EREMOTE) {
-+                      tmp_path =
-+                          kmalloc(strnlen
-+                                  (pTcon->treeName,
-+                                   MAX_TREE_SIZE + 1) +
-+                                  strnlen(search_path, MAX_PATHCONF) + 1,
-+                                  GFP_KERNEL);
-+                      if (tmp_path == NULL) {
-+                              if(buf)
-+                                      kfree(buf);
-+                              return -ENOMEM;
-+                      }
-+
-+                      strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE);
-+                      strncat(tmp_path, search_path, MAX_PATHCONF);
-+                      rc = connect_to_dfs_path(xid, pTcon->ses,
-+                                               /* treename + */ tmp_path,
-+                                               cifs_sb->local_nls);
-+                      kfree(tmp_path);
-+                      /* BB fix up inode etc. */
-+              } else if (rc) {
-+                      if(buf)
-+                              kfree(buf);
-+                      return rc;
-+              }
-+      } else {
-+              struct cifsInodeInfo *cifsInfo;
-+
-+              /* get new inode */
-+              if (*pinode == NULL) {
-+                      *pinode = get_cifs_inode(sb);
-+              }
-+              if(*pinode == NULL)
-+                      return -ENOMEM;
-+              inode = *pinode;
-+              cifsInfo = CIFS_I(inode);
-+              pfindData->Attributes = le32_to_cpu(pfindData->Attributes);
-+              cifsInfo->cifsAttrs = pfindData->Attributes;
-+              cFYI(1, (" Old time %ld ", cifsInfo->time));
-+              cifsInfo->time = jiffies;
-+              cFYI(1, (" New time %ld ", cifsInfo->time));
-+
-+/* blksize needs to be multiple of two. So safer to default to blksize
-+        and blkbits set in superblock so 2**blkbits and blksize will match */
-+/*            inode->i_blksize =
-+                  (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/
-+
-+              /* Linux can not store file creation time unfortunately so we ignore it */
-+              inode->i_atime =
-+                  cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime));
-+              inode->i_mtime =
-+                  cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
-+              inode->i_ctime =
-+                  cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
-+              cFYI(0,
-+                   (" Attributes came in as 0x%x ", pfindData->Attributes));
-+
-+              /* set default mode. will override for dirs below */
-+              if(atomic_read(&cifsInfo->inUse) == 0)
-+                      /* new inode, can safely set these fields */
-+                      inode->i_mode = cifs_sb->mnt_file_mode;
-+
-+              if (pfindData->Attributes & ATTR_REPARSE) {
-+      /* Can IFLNK be set as it basically is on windows with IFREG or IFDIR? */
-+                      inode->i_mode |= S_IFLNK;
-+              } else if (pfindData->Attributes & ATTR_DIRECTORY) {
-+      /* override default perms since we do not do byte range locking on dirs */
-+                      inode->i_mode = cifs_sb->mnt_dir_mode;
-+                      inode->i_mode |= S_IFDIR;
-+              } else {
-+                      inode->i_mode |= S_IFREG;
-+                      /* treat the dos attribute of read-only as read-only mode e.g. 555 */
-+                      if(cifsInfo->cifsAttrs & ATTR_READONLY)
-+                              inode->i_mode &= ~(S_IWUGO);
-+   /* BB add code here - validate if device or weird share or device type? */
-+              }
-+              if(is_size_safe_to_change(cifsInfo)) {
-+              /* can not safely change the file size here if the
-+              client is writing to it due to potential races */
-+                      inode->i_size = le64_to_cpu(pfindData->EndOfFile);
-+
-+              /* 512 bytes (2**9) is the fake blocksize that must be used */
-+              /* for this calculation */
-+                      inode->i_blocks = (512 - 1 + pfindData->AllocationSize)
-+                               >> 9;
-+              }
-+                pfindData->AllocationSize = le64_to_cpu(pfindData->AllocationSize);
-+
-+              cFYI(1,
-+                   (" Size %ld and blocks %ld ",
-+                    (unsigned long) inode->i_size, inode->i_blocks));
-+              inode->i_nlink = le32_to_cpu(pfindData->NumberOfLinks);
-+
-+              /* BB fill in uid and gid here? with help from winbind? 
-+                      or retrieve from NTFS stream extended attribute */
-+              if(atomic_read(&cifsInfo->inUse) == 0) {
-+                      inode->i_uid = cifs_sb->mnt_uid;
-+                      inode->i_gid = cifs_sb->mnt_gid;
-+                      /* set so we do not keep refreshing these fields with
-+                      bad data after user has changed them in memory */
-+                      atomic_set(&cifsInfo->inUse,1);
-+              }
-+              
-+              if (S_ISREG(inode->i_mode)) {
-+                      cFYI(1, (" File inode "));
-+                      inode->i_op = &cifs_file_inode_ops;
-+                      inode->i_fop = &cifs_file_ops;
-+                      inode->i_data.a_ops = &cifs_addr_ops;
-+              } else if (S_ISDIR(inode->i_mode)) {
-+                      cFYI(1, (" Directory inode "));
-+                      inode->i_op = &cifs_dir_inode_ops;
-+                      inode->i_fop = &cifs_dir_ops;
-+              } else if (S_ISLNK(inode->i_mode)) {
-+                      cFYI(1, (" Symbolic Link inode "));
-+                      inode->i_op = &cifs_symlink_inode_ops;
-+              } else {
-+                      init_special_inode(inode, inode->i_mode,
-+                                         kdev_t_to_nr(inode->i_rdev));
-+              }
-+      }
-+      if(buf)
-+          kfree(buf);
-+      return rc;
-+}
-+
-+void
-+cifs_read_inode(struct inode *inode)
-+{                             /* gets root inode */
-+      int xid;
-+      struct cifs_sb_info *cifs_sb;
-+      struct cifsInodeInfo *cifs_inode;
-+      
-+      cifs_sb = CIFS_SB(inode->i_sb);
-+      xid = GetXid();
-+      
-+      cifs_inode = CIFS_I(inode);
-+      cifs_inode->cifsAttrs = ATTR_DIRECTORY; 
-+      atomic_set(&cifs_inode->inUse, 0);
-+      cifs_inode->time = 0;
-+      inode->i_blksize = CIFS_MAX_MSGSIZE;
-+      inode->i_blkbits = 14;  /* 2**14 = CIFS_MAX_MSGSIZE */
-+
-+      INIT_LIST_HEAD(&cifs_inode->openFileList);
-+
-+      if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)
-+              cifs_get_inode_info_unix(&inode, "", inode->i_sb,xid);
-+      else
-+              cifs_get_inode_info(&inode, "", NULL, inode->i_sb,xid);
-+      /* can not call macro FreeXid here since in a void func */
-+      _FreeXid(xid);
-+}
-+
-+int
-+cifs_unlink(struct inode *inode, struct dentry *direntry)
-+{
-+      int rc = 0;
-+      int xid;
-+      struct cifs_sb_info *cifs_sb;
-+      struct cifsTconInfo *pTcon;
-+      char *full_path = NULL;
-+      struct cifsInodeInfo *cifsInode;
-+      FILE_BASIC_INFO * pinfo_buf;
-+
-+      cFYI(1, (" cifs_unlink, inode = 0x%p with ", inode));
-+
-+      xid = GetXid();
-+
-+      cifs_sb = CIFS_SB(inode->i_sb);
-+      pTcon = cifs_sb->tcon;
-+
-+/* Unlink can be called from rename so we can not grab
-+      the sem here since we deadlock otherwise */
-+/*    down(&direntry->d_sb->s_vfs_rename_sem);*/
-+      full_path = build_path_from_dentry(direntry);
-+/*    up(&direntry->d_sb->s_vfs_rename_sem);*/
-+      if(full_path == NULL) {
-+              FreeXid(xid);
-+              return -ENOMEM;
-+      }
-+      rc = CIFSSMBDelFile(xid, pTcon, full_path, cifs_sb->local_nls);
-+
-+      if (!rc) {
-+              direntry->d_inode->i_nlink--;
-+      } else if (rc == -ENOENT) {
-+              d_drop(direntry);
-+      } else if (rc == -ETXTBSY) {
-+              int oplock = FALSE;
-+              __u16 netfid;
-+
-+              rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, DELETE, 
-+                              CREATE_NOT_DIR | CREATE_DELETE_ON_CLOSE,
-+                              &netfid, &oplock, NULL, cifs_sb->local_nls);
-+              if(rc==0) {
-+                      CIFSSMBRenameOpenFile(xid,pTcon,netfid,
-+                              NULL, cifs_sb->local_nls);
-+                      CIFSSMBClose(xid, pTcon, netfid);
-+                      direntry->d_inode->i_nlink--;
-+              }
-+      } else if (rc == -EACCES) {
-+              /* try only if r/o attribute set in local lookup data? */
-+              pinfo_buf = (FILE_BASIC_INFO *)kmalloc(sizeof(FILE_BASIC_INFO),GFP_KERNEL);
-+              if(pinfo_buf) {
-+                      memset(pinfo_buf,0,sizeof(FILE_BASIC_INFO));        
-+              /* ATTRS set to normal clears r/o bit */
-+                      pinfo_buf->Attributes = cpu_to_le32(ATTR_NORMAL);
-+                      rc = CIFSSMBSetTimes(xid, pTcon, full_path, pinfo_buf,
-+                              cifs_sb->local_nls);
-+                      kfree(pinfo_buf);
-+              }
-+              if(rc==0) {
-+                      rc = CIFSSMBDelFile(xid, pTcon, full_path, cifs_sb->local_nls);
-+                      if (!rc) {
-+                              direntry->d_inode->i_nlink--;
-+                      } else if (rc == -ETXTBSY) {
-+                              int oplock = FALSE;
-+                              __u16 netfid;
-+
-+                              rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, DELETE,
-+                                              CREATE_NOT_DIR | CREATE_DELETE_ON_CLOSE,
-+                                              &netfid, &oplock, NULL, cifs_sb->local_nls);
-+                              if(rc==0) {
-+                                      CIFSSMBRenameOpenFile(xid,pTcon,netfid,NULL,cifs_sb->local_nls);
-+                                      CIFSSMBClose(xid, pTcon, netfid);
-+                                      direntry->d_inode->i_nlink--;
-+                              }
-+                      /* BB if rc = -ETXTBUSY goto the rename logic BB */
-+                      }
-+              }
-+      }
-+      cifsInode = CIFS_I(direntry->d_inode);
-+      cifsInode->time = 0;    /* will force revalidate to get info when needed */
-+      direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime =
-+          CURRENT_TIME;
-+      cifsInode = CIFS_I(inode);
-+      cifsInode->time = 0;    /* force revalidate of dir as well */
-+
-+      if (full_path)
-+              kfree(full_path);
-+      FreeXid(xid);
-+      return rc;
-+}
-+
-+int
-+cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
-+{
-+      int rc = 0;
-+      int xid;
-+      struct cifs_sb_info *cifs_sb;
-+      struct cifsTconInfo *pTcon;
-+      char *full_path = NULL;
-+      struct inode *newinode = NULL;
-+
-+      cFYI(1, ("In cifs_mkdir, mode = 0x%x inode = 0x%p ", mode, inode));
-+
-+      xid = GetXid();
-+
-+      cifs_sb = CIFS_SB(inode->i_sb);
-+      pTcon = cifs_sb->tcon;
-+
-+      down(&inode->i_sb->s_vfs_rename_sem);
-+      full_path = build_path_from_dentry(direntry);
-+      up(&inode->i_sb->s_vfs_rename_sem);
-+      if(full_path == NULL) {
-+              FreeXid(xid);
-+              return -ENOMEM;
-+      }
-+      /* BB add setting the equivalent of mode via CreateX w/ACLs */
-+      rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls);
-+      if (rc) {
-+              cFYI(1, ("cifs_mkdir returned 0x%x ", rc));
-+              d_drop(direntry);
-+      } else {
-+              inode->i_nlink++;
-+              if (pTcon->ses->capabilities & CAP_UNIX)
-+                      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);
-+
-+              direntry->d_op = &cifs_dentry_ops;
-+              d_instantiate(direntry, newinode);
-+              if(direntry->d_inode)
-+                      direntry->d_inode->i_nlink = 2;
-+              if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)                
-+                      CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode,
-+                              (__u64)-1,  
-+                              (__u64)-1,
-+                              0 /* dev_t */,
-+                              cifs_sb->local_nls);
-+              else { /* BB to be implemented via Windows secrty descriptors*/
-+              /* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/
-+              }
-+      }
-+      if (full_path)
-+              kfree(full_path);
-+      FreeXid(xid);
-+
-+      return rc;
-+}
-+
-+int
-+cifs_rmdir(struct inode *inode, struct dentry *direntry)
-+{
-+      int rc = 0;
-+      int xid;
-+      struct cifs_sb_info *cifs_sb;
-+      struct cifsTconInfo *pTcon;
-+      char *full_path = NULL;
-+      struct cifsInodeInfo *cifsInode;
-+
-+      cFYI(1, (" cifs_rmdir, inode = 0x%p with ", inode));
-+
-+      xid = GetXid();
-+
-+      cifs_sb = CIFS_SB(inode->i_sb);
-+      pTcon = cifs_sb->tcon;
-+
-+      down(&inode->i_sb->s_vfs_rename_sem);
-+      full_path = build_path_from_dentry(direntry);
-+      up(&inode->i_sb->s_vfs_rename_sem);
-+      if(full_path == NULL) {
-+              FreeXid(xid);
-+              return -ENOMEM;
-+      }
-+
-+      rc = CIFSSMBRmDir(xid, pTcon, full_path, cifs_sb->local_nls);
-+
-+      if (!rc) {
-+              inode->i_nlink--;
-+              direntry->d_inode->i_size = 0;
-+              direntry->d_inode->i_nlink = 0;
-+      }
-+
-+      cifsInode = CIFS_I(direntry->d_inode);
-+      cifsInode->time = 0;    /* force revalidate to go get info when needed */
-+      direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime =
-+          CURRENT_TIME;
-+
-+      if (full_path)
-+              kfree(full_path);
-+      FreeXid(xid);
-+      return rc;
-+}
-+
-+int
-+cifs_rename(struct inode *source_inode, struct dentry *source_direntry,
-+          struct inode *target_inode, struct dentry *target_direntry)
-+{
-+      char *fromName;
-+      char *toName;
-+      struct cifs_sb_info *cifs_sb_source;
-+      struct cifs_sb_info *cifs_sb_target;
-+      struct cifsTconInfo *pTcon;
-+      int xid;
-+      int rc = 0;
-+
-+      xid = GetXid();
-+
-+      cifs_sb_target = CIFS_SB(target_inode->i_sb);
-+      cifs_sb_source = CIFS_SB(source_inode->i_sb);
-+      pTcon = cifs_sb_source->tcon;
-+
-+      if (pTcon != cifs_sb_target->tcon) {
-+              FreeXid(xid);    
-+              return -EXDEV;  /* BB actually could be allowed if same server, but
-+                     different share. Might eventually add support for this */
-+      }
-+
-+      /* 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_direntry);
-+      toName = build_path_from_dentry(target_direntry);
-+      if((fromName == NULL) || (toName == NULL)) {
-+              rc = -ENOMEM;
-+              goto cifs_rename_exit;
-+      }
-+
-+      rc = CIFSSMBRename(xid, pTcon, fromName, toName,
-+                         cifs_sb_source->local_nls);
-+      if(rc == -EEXIST) {
-+              /* check if they are the same file 
-+              because rename of hardlinked files is a noop */
-+              FILE_UNIX_BASIC_INFO * info_buf_source;
-+              FILE_UNIX_BASIC_INFO * info_buf_target;
-+
-+              info_buf_source = 
-+                      kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO),GFP_KERNEL);
-+              if(info_buf_source != NULL) {
-+                      info_buf_target = info_buf_source+1;
-+                      rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName, 
-+                              info_buf_source, cifs_sb_source->local_nls);
-+                      if(rc == 0) {
-+                              rc = CIFSSMBUnixQPathInfo(xid,pTcon,toName,
-+                                              info_buf_target,
-+                                              cifs_sb_target->local_nls);
-+                      }
-+                      if((rc == 0) && 
-+                              (info_buf_source->UniqueId == 
-+                               info_buf_target->UniqueId)) {
-+                      /* do not rename since the files are hardlinked 
-+                         which is a noop */
-+                      } else {
-+                      /* we either can not tell the files are hardlinked
-+                      (as with Windows servers) or files are not hardlinked 
-+                      so delete the target manually before renaming to
-+                      follow POSIX rather than Windows semantics */
-+                              cifs_unlink(target_inode, target_direntry);
-+                              rc = CIFSSMBRename(xid, pTcon, fromName, toName,
-+                                      cifs_sb_source->local_nls);
-+                      }
-+                      kfree(info_buf_source);
-+              } /* if we can not get memory just leave rc as EEXIST */
-+      }
-+
-+      if((rc == -EIO)||(rc == -EEXIST)) {
-+              int oplock = FALSE;
-+              __u16 netfid;
-+
-+              rc = CIFSSMBOpen(xid, pTcon, fromName, FILE_OPEN, GENERIC_READ,
-+                                      CREATE_NOT_DIR,
-+                                      &netfid, &oplock, NULL, cifs_sb_source->local_nls);
-+              if(rc==0) {
-+                      CIFSSMBRenameOpenFile(xid,pTcon,netfid,
-+                                      toName, cifs_sb_source->local_nls);
-+                      CIFSSMBClose(xid, pTcon, netfid);
-+              }
-+      }
-+
-+cifs_rename_exit:
-+      if (fromName)
-+              kfree(fromName);
-+      if (toName)
-+              kfree(toName);
-+
-+      FreeXid(xid);
-+      return rc;
-+}
-+
-+int
-+cifs_revalidate(struct dentry *direntry)
-+{
-+      int xid;
-+      int rc = 0;
-+      char *full_path;
-+      struct cifs_sb_info *cifs_sb;
-+      struct cifsInodeInfo *cifsInode;
-+      loff_t local_size;
-+      time_t local_mtime;
-+      int invalidate_inode = FALSE;
-+
-+      if(direntry->d_inode == NULL)
-+              return -ENOENT;
-+
-+      cifsInode = CIFS_I(direntry->d_inode);
-+
-+      if(cifsInode == NULL)
-+              return -ENOENT;
-+
-+      /* no sense revalidating inode info on file that no one can write */
-+      if(CIFS_I(direntry->d_inode)->clientCanCacheRead)
-+              return rc;
-+
-+      xid = GetXid();
-+
-+      cifs_sb = CIFS_SB(direntry->d_sb);
-+
-+      /* can not safely grab the rename sem here if
-+      rename calls revalidate since that would deadlock */
-+      full_path = build_path_from_dentry(direntry);
-+      if(full_path == NULL) {
-+              FreeXid(xid);
-+              return -ENOMEM;
-+      }
-+      cFYI(1,
-+           ("Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld jiffies %ld",
-+            full_path, direntry->d_inode,
-+            direntry->d_inode->i_count.counter, direntry,
-+            direntry->d_time, jiffies));
-+
-+      if (cifsInode->time == 0){
-+              /* was set to zero previously to force revalidate */
-+      } else if (time_before(jiffies, cifsInode->time + HZ) && lookupCacheEnabled) {
-+          if((S_ISREG(direntry->d_inode->i_mode) == 0) || 
-+                      (direntry->d_inode->i_nlink == 1)) {  
-+                      if (full_path)
-+                              kfree(full_path);
-+                      FreeXid(xid);
-+                      return rc;
-+              } else {
-+                      cFYI(1,("Have to revalidate file due to hardlinks"));
-+              }            
-+      }
-+      
-+      /* save mtime and size */
-+      local_mtime = direntry->d_inode->i_mtime;
-+      local_size  = direntry->d_inode->i_size;
-+
-+      if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) {
-+              rc = cifs_get_inode_info_unix(&direntry->d_inode, full_path,
-+                                       direntry->d_sb,xid);
-+              if(rc) {
-+                      cFYI(1,("error on getting revalidate info %d",rc));
-+/*                    if(rc != -ENOENT)
-+                              rc = 0; */ /* BB should we cache info on certain errors? */
-+              }
-+      } else {
-+              rc = cifs_get_inode_info(&direntry->d_inode, full_path, NULL,
-+                                  direntry->d_sb,xid);
-+              if(rc) {
-+                      cFYI(1,("error on getting revalidate info %d",rc));
-+/*                    if(rc != -ENOENT)
-+                              rc = 0; */  /* BB should we cache info on certain errors? */
-+              }
-+      }
-+      /* should we remap certain errors, access denied?, to zero */
-+
-+      /* if not oplocked, we invalidate inode pages if mtime 
-+         or file size had changed on server */
-+
-+      if((local_mtime == direntry->d_inode->i_mtime) && 
-+              (local_size == direntry->d_inode->i_size)) {
-+              cFYI(1,("cifs_revalidate - inode unchanged"));
-+      } else {
-+              /* file may have changed on server */
-+              if(cifsInode->clientCanCacheRead) {
-+                      /* no need to invalidate inode pages since we were
-+                         the only ones who could have modified the file and
-+                         the server copy is staler than ours */
-+              } else {
-+                      invalidate_inode = TRUE;
-+              }
-+      }
-+
-+      /* can not grab this sem since kernel filesys locking
-+              documentation indicates i_sem may be taken by the kernel 
-+              on lookup and rename which could deadlock if we grab
-+              the i_sem here as well */
-+/*    down(&direntry->d_inode->i_sem);*/
-+      /* need to write out dirty pages here  */
-+      if(direntry->d_inode->i_mapping) {
-+              /* do we need to lock inode until after invalidate completes below? */
-+              filemap_fdatasync(direntry->d_inode->i_mapping);
-+      }
-+      if(invalidate_inode) {
-+              filemap_fdatawait(direntry->d_inode->i_mapping);
-+              /* may eventually have to do this for open files too */
-+              if(list_empty(&(cifsInode->openFileList))) {
-+                      /* Has changed on server - flush read ahead pages */
-+                      cFYI(1,("Invalidating read ahead data on closed file"));
-+                      invalidate_inode_pages(direntry->d_inode);
-+              }
-+      }
-+/*    up(&direntry->d_inode->i_sem);*/
-+      
-+      if (full_path)
-+              kfree(full_path);
-+      FreeXid(xid);
-+
-+      return rc;
-+}
-+
-+/* int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
-+{
-+      int err = cifs_revalidate(dentry);
-+      if (!err)
-+              generic_fillattr(dentry->d_inode, stat);
-+      return err;
-+} */
-+
-+void
-+cifs_truncate_file(struct inode *inode)
-+{                             /* BB remove - may not need this function after all BB */
-+      int xid;
-+      int rc = -EIO;
-+      int found = FALSE;
-+      struct cifsFileInfo *open_file = NULL;
-+      struct cifs_sb_info *cifs_sb;
-+      struct cifsTconInfo *pTcon;
-+      struct cifsInodeInfo *cifsInode;
-+      struct dentry *dirent;
-+      struct list_head * tmp;
-+      char *full_path = NULL;   
-+
-+      xid = GetXid();
-+
-+      cifs_sb = CIFS_SB(inode->i_sb);
-+      pTcon = cifs_sb->tcon;
-+
-+      /* 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 */
-+      read_lock(&GlobalSMBSeslock); 
-+      cifsInode = CIFS_I(inode);
-+      list_for_each(tmp, &cifsInode->openFileList) {            
-+              open_file = list_entry(tmp,struct cifsFileInfo, flist);
-+              /* We check if file is open for writing first */
-+              if((open_file->pfile) && (!open_file->invalidHandle) &&
-+                 ((open_file->pfile->f_flags & O_RDWR) || 
-+                      (open_file->pfile->f_flags & O_WRONLY))) {
-+                      read_unlock(&GlobalSMBSeslock);
-+                      found = TRUE;
-+                      rc = CIFSSMBSetFileSize(xid, pTcon, inode->i_size,
-+                         open_file->netfid,open_file->pid,FALSE);
-+                      if(rc == 0) {
-+                              FreeXid(xid);
-+                              return;
-+                      } 
-+                      /* Do not need reopen and retry on EAGAIN since we will
-+                              retry by pathname below */
-+                      if(rc == -EAGAIN)
-+                              rc = -EHOSTDOWN;
-+
-+                      break;  /* now that we found one valid file handle no
-+                              sense continuing to loop trying others */
-+              }
-+      }
-+      if(found == FALSE)
-+              read_unlock(&GlobalSMBSeslock);
-+
-+      if (list_empty(&inode->i_dentry)) {
-+              cERROR(1,
-+                     ("Can not get pathname from empty dentry in inode 0x%p ",
-+                      inode));
-+              FreeXid(xid);
-+              return;
-+      }
-+
-+      dirent = list_entry(inode->i_dentry.next, struct dentry, d_alias);
-+      if (dirent) {
-+              full_path = build_path_from_dentry(dirent);
-+              rc = CIFSSMBSetEOF(xid, pTcon, full_path, inode->i_size,FALSE,
-+                                 cifs_sb->local_nls);
-+              cFYI(1,(" SetEOF (truncate) rc = %d",rc));
-+              if (!rc)
-+                      CIFSSMBSetEOF(xid,pTcon,full_path,inode->i_size,TRUE,cifs_sb->local_nls);
-+           /* allocation size setting seems optional so ignore return code */
-+      }
-+      if (full_path)
-+              kfree(full_path);
-+      FreeXid(xid);
-+      return;
-+}
-+
-+static int cifs_truncate_page(struct address_space *mapping, loff_t from)
-+{
-+      unsigned long index = from >> PAGE_CACHE_SHIFT;
-+      unsigned offset = from & (PAGE_CACHE_SIZE-1);
-+      struct page *page;
-+      char *kaddr;
-+      int rc = 0;
-+
-+      page = grab_cache_page(mapping, index);
-+      if (!page)
-+              return -ENOMEM;
-+
-+      kaddr = kmap_atomic(page, KM_USER0);
-+      memset(kaddr + offset, 0, PAGE_CACHE_SIZE - offset);
-+      flush_dcache_page(page);
-+      kunmap_atomic(kaddr, KM_USER0);
-+      unlock_page(page);
-+      page_cache_release(page);
-+      return rc;
-+}
-+
-+int
-+cifs_setattr(struct dentry *direntry, struct iattr *attrs)
-+{
-+      int xid;
-+      struct cifs_sb_info *cifs_sb;
-+      struct cifsTconInfo *pTcon;
-+      char *full_path = NULL;
-+      int rc = -EACCES;
-+      int found = FALSE;
-+      struct cifsFileInfo *open_file = NULL;
-+      FILE_BASIC_INFO time_buf;
-+      int set_time = FALSE;
-+      __u64 mode = 0xFFFFFFFFFFFFFFFFULL;
-+      __u64 uid = 0xFFFFFFFFFFFFFFFFULL;
-+      __u64 gid = 0xFFFFFFFFFFFFFFFFULL;
-+      struct cifsInodeInfo *cifsInode;
-+      struct list_head * tmp;
-+
-+      xid = GetXid();
-+
-+      cFYI(1,
-+           (" In cifs_setattr, name = %s attrs->iavalid 0x%x ",
-+            direntry->d_name.name, attrs->ia_valid));
-+      cifs_sb = CIFS_SB(direntry->d_inode->i_sb);
-+      pTcon = cifs_sb->tcon;
-+
-+      down(&direntry->d_sb->s_vfs_rename_sem);
-+      full_path = build_path_from_dentry(direntry);
-+      up(&direntry->d_sb->s_vfs_rename_sem);
-+      if(full_path == NULL) {
-+              FreeXid(xid);
-+              return -ENOMEM;
-+      }
-+      cifsInode = CIFS_I(direntry->d_inode);
-+
-+      /* BB check if we need to refresh inode from server now ? BB */
-+
-+      /* need to flush data before changing file size on server */
-+      filemap_fdatasync(direntry->d_inode->i_mapping);
-+
-+      if (attrs->ia_valid & ATTR_SIZE) {
-+              read_lock(&GlobalSMBSeslock); 
-+              /* 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 */
-+              list_for_each(tmp, &cifsInode->openFileList) {            
-+                      open_file = list_entry(tmp,struct cifsFileInfo, flist);
-+                      /* We check if file is open for writing first */
-+                      if((open_file->pfile) &&
-+                              ((open_file->pfile->f_flags & O_RDWR) || 
-+                               (open_file->pfile->f_flags & O_WRONLY))) {
-+                              if(open_file->invalidHandle == FALSE) {
-+                                      /* we found a valid, writeable network file 
-+                                      handle to use to try to set the file size */
-+                                      __u16 nfid = open_file->netfid;
-+                                      __u32 npid = open_file->pid;
-+                                      read_unlock(&GlobalSMBSeslock);
-+                                      found = TRUE;
-+                                      rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size,
-+                                         nfid,npid,FALSE);
-+                                      cFYI(1,("SetFileSize by handle (setattrs) rc = %d",rc));
-+                              /* Do not need reopen and retry on EAGAIN since we will
-+                                      retry by pathname below */
-+
-+                                      break;  /* now that we found one valid file handle no
-+                                              sense continuing to loop trying others */
-+                              }
-+                      }
-+              }
-+              if(found == FALSE) {
-+                      read_unlock(&GlobalSMBSeslock);
-+              }
-+
-+
-+              if(rc != 0) {
-+                      /* 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);
-+                      cFYI(1,(" SetEOF by path (setattrs) rc = %d",rc));
-+              }
-+        
-+      /*  Server is ok setting allocation size implicitly - no need to call: */
-+      /*CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size, TRUE, cifs_sb->local_nls);*/
-+
-+              if (rc == 0) {
-+                      rc = vmtruncate(direntry->d_inode, attrs->ia_size);
-+                      cifs_truncate_page(direntry->d_inode->i_mapping, direntry->d_inode->i_size);
-+              }
-+      }
-+      if (attrs->ia_valid & ATTR_UID) {
-+              cFYI(1, (" CIFS - UID changed to %d", attrs->ia_uid));
-+              uid = attrs->ia_uid;
-+              /*        entry->uid = cpu_to_le16(attr->ia_uid); */
-+      }
-+      if (attrs->ia_valid & ATTR_GID) {
-+              cFYI(1, (" CIFS - GID changed to %d", attrs->ia_gid));
-+              gid = attrs->ia_gid;
-+              /*      entry->gid = cpu_to_le16(attr->ia_gid); */
-+      }
-+
-+      time_buf.Attributes = 0;
-+      if (attrs->ia_valid & ATTR_MODE) {
-+              cFYI(1, (" CIFS - Mode changed to 0x%x", attrs->ia_mode));
-+              mode = attrs->ia_mode;
-+              /* entry->mode = cpu_to_le16(attr->ia_mode); */
-+      }
-+
-+      if ((cifs_sb->tcon->ses->capabilities & CAP_UNIX)
-+          && (attrs->ia_valid & (ATTR_MODE | ATTR_GID | ATTR_UID)))
-+              rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, uid, gid,
-+                              0 /* dev_t */, cifs_sb->local_nls);
-+      else if (attrs->ia_valid & ATTR_MODE) {
-+              if((mode & S_IWUGO) == 0) /* not writeable */ {
-+                      if((cifsInode->cifsAttrs & ATTR_READONLY) == 0)
-+                              time_buf.Attributes = 
-+                                      cpu_to_le32(cifsInode->cifsAttrs | ATTR_READONLY);
-+              } else if((mode & S_IWUGO) == S_IWUGO) {
-+                      if(cifsInode->cifsAttrs & ATTR_READONLY)
-+                              time_buf.Attributes = 
-+                                      cpu_to_le32(cifsInode->cifsAttrs & (~ATTR_READONLY));
-+              }
-+              /* BB to be implemented - via Windows security descriptors or streams */
-+              /* CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,uid,gid,cifs_sb->local_nls);*/
-+      }
-+
-+      if (attrs->ia_valid & ATTR_ATIME) {
-+              set_time = TRUE;
-+              time_buf.LastAccessTime =
-+                  cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_atime));
-+      } else
-+              time_buf.LastAccessTime = 0;
-+
-+      if (attrs->ia_valid & ATTR_MTIME) {
-+              set_time = TRUE;
-+              time_buf.LastWriteTime =
-+                  cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime));
-+      } else
-+              time_buf.LastWriteTime = 0;
-+
-+      if (attrs->ia_valid & ATTR_CTIME) {
-+              set_time = TRUE;
-+              time_buf.ChangeTime =
-+                  cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime));
-+      } else
-+              time_buf.ChangeTime = 0;
-+
-+      if (set_time | time_buf.Attributes) {
-+              /* BB what if setting one attribute fails  
-+                      (such as size) but time setting works */
-+              time_buf.CreationTime = 0;      /* do not change */
-+              /* In the future we should experiment - try setting timestamps
-+                       via Handle (SetFileInfo) instead of by path */
-+              rc = CIFSSMBSetTimes(xid, pTcon, full_path, &time_buf,
-+                              cifs_sb->local_nls);
-+      }
-+
-+      /* do not  need local check to inode_check_ok since the server does that */
-+      if (!rc)
-+              rc = inode_setattr(direntry->d_inode, attrs);
-+      if (full_path)
-+              kfree(full_path);
-+      FreeXid(xid);
-+      return rc;
-+}
-+
-+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 */
-+}
---- /dev/null
-+++ b/fs/cifs/link.c
-@@ -0,0 +1,328 @@
-+/*
-+ *   fs/cifs/link.c
-+ *
-+ *   Copyright (C) International Business Machines  Corp., 2002,2003
-+ *   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 "cifsfs.h"
-+#include "cifspdu.h"
-+#include "cifsglob.h"
-+#include "cifsproto.h"
-+#include "cifs_debug.h"
-+#include "cifs_fs_sb.h"
-+
-+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_target;
-+      struct cifsTconInfo *pTcon;
-+      struct cifsInodeInfo *cifsInode;
-+
-+      xid = GetXid();
-+
-+      cifs_sb_target = CIFS_SB(inode->i_sb);
-+      pTcon = cifs_sb_target->tcon;
-+
-+/* No need to check for cross device links since server will do that
-+   BB note DFS case in future though (when we may have to check) */
-+
-+      down(&inode->i_sb->s_vfs_rename_sem);
-+      fromName = build_path_from_dentry(old_file);
-+      toName = build_path_from_dentry(direntry);
-+      up(&inode->i_sb->s_vfs_rename_sem);
-+      if((fromName == NULL) || (toName == NULL)) {
-+              rc = -ENOMEM;
-+              goto cifs_hl_exit;
-+      }
-+
-+      if (cifs_sb_target->tcon->ses->capabilities & CAP_UNIX)
-+              rc = CIFSUnixCreateHardLink(xid, pTcon, fromName, toName,
-+                                          cifs_sb_target->local_nls);
-+      else {
-+              rc = CIFSCreateHardLink(xid, pTcon, fromName, toName,
-+                                      cifs_sb_target->local_nls);
-+              if(rc == -EIO)
-+                      rc = -EOPNOTSUPP;  
-+      }
-+
-+/* if (!rc)     */
-+      {
-+              /*   renew_parental_timestamps(old_file);
-+                 inode->i_nlink++;
-+                 mark_inode_dirty(inode);
-+                 d_instantiate(direntry, inode); */
-+              /* BB add call to either mark inode dirty or refresh its data and timestamp to current time */
-+      }
-+      d_drop(direntry);       /* force new lookup from server */
-+      cifsInode = CIFS_I(old_file->d_inode);
-+      cifsInode->time = 0;    /* will force revalidate to go get info when needed */
-+
-+cifs_hl_exit:
-+      if (fromName)
-+              kfree(fromName);
-+      if (toName)
-+              kfree(toName);
-+      FreeXid(xid);
-+      return rc;
-+}
-+
-+int
-+cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
-+{
-+      struct inode *inode = direntry->d_inode;
-+      int rc = -EACCES;
-+      int xid;
-+      char *full_path = NULL;
-+      char * target_path;
-+      struct cifs_sb_info *cifs_sb;
-+      struct cifsTconInfo *pTcon;
-+
-+      xid = GetXid();
-+
-+      down(&direntry->d_sb->s_vfs_rename_sem);
-+      full_path = build_path_from_dentry(direntry);
-+      up(&direntry->d_sb->s_vfs_rename_sem);
-+
-+      if(full_path == NULL) {
-+              FreeXid(xid);
-+              return -ENOMEM;
-+      }
-+      cFYI(1, ("Full path: %s inode = 0x%p", full_path, inode));
-+      cifs_sb = CIFS_SB(inode->i_sb);
-+      pTcon = cifs_sb->tcon;
-+      target_path = kmalloc(PATH_MAX, GFP_KERNEL);
-+      if(target_path == NULL) {
-+              if (full_path)
-+                      kfree(full_path);
-+              FreeXid(xid);
-+              return -ENOMEM;
-+      }
-+      /* can not call the following line due to EFAULT in vfs_readlink which is presumably expecting a user space buffer */
-+      /* length = cifs_readlink(direntry,target_path, sizeof(target_path) - 1);    */
-+
-+/* BB add read reparse point symlink code and Unix extensions symlink code here BB */
-+      if (pTcon->ses->capabilities & CAP_UNIX)
-+              rc = CIFSSMBUnixQuerySymLink(xid, pTcon, full_path,
-+                                           target_path,
-+                                           PATH_MAX-1,
-+                                           cifs_sb->local_nls);
-+      else {
-+              /* rc = CIFSSMBQueryReparseLinkInfo */
-+              /* BB Add code to Query ReparsePoint info */
-+      }
-+      /* BB Anything else to do to handle recursive links? */
-+      /* BB Should we be using page symlink ops here? */
-+
-+      if (rc == 0) {
-+
-+/* BB Add special case check for Samba DFS symlinks */
-+
-+              target_path[PATH_MAX-1] = 0;
-+              rc = vfs_follow_link(nd, target_path);
-+      }
-+      /* else EACCESS */
-+
-+      if (target_path)
-+              kfree(target_path);
-+      if (full_path)
-+              kfree(full_path);
-+      FreeXid(xid);
-+      return rc;
-+}
-+
-+int
-+cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
-+{
-+      int rc = -EOPNOTSUPP;
-+      int xid;
-+      struct cifs_sb_info *cifs_sb;
-+      struct cifsTconInfo *pTcon;
-+      char *full_path = NULL;
-+      struct inode *newinode = NULL;
-+
-+      xid = GetXid();
-+
-+      cifs_sb = CIFS_SB(inode->i_sb);
-+      pTcon = cifs_sb->tcon;
-+
-+      down(&inode->i_sb->s_vfs_rename_sem);
-+      full_path = build_path_from_dentry(direntry);
-+      up(&inode->i_sb->s_vfs_rename_sem);
-+
-+      if(full_path == NULL) {
-+              FreeXid(xid);
-+              return -ENOMEM;
-+      }
-+
-+      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->tcon->ses->capabilities & CAP_UNIX)
-+              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->ses->capabilities & CAP_UNIX)
-+                      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);
-+
-+              if (rc != 0) {
-+                      cFYI(1,
-+                           ("Create symlink worked but get_inode_info failed with rc = %d ",
-+                            rc));
-+              } else {
-+                      direntry->d_op = &cifs_dentry_ops;
-+                      d_instantiate(direntry, newinode);
-+              }
-+      }
-+
-+      if (full_path)
-+              kfree(full_path);
-+      FreeXid(xid);
-+      return rc;
-+}
-+
-+int
-+cifs_readlink(struct dentry *direntry, char *pBuffer, int buflen)
-+{
-+      struct inode *inode = direntry->d_inode;
-+      int rc = -EACCES;
-+      int xid;
-+      int oplock = FALSE;
-+      struct cifs_sb_info *cifs_sb;
-+      struct cifsTconInfo *pTcon;
-+      char *full_path = NULL;
-+      char *tmp_path =  NULL;
-+      char * tmpbuffer;
-+      unsigned char * referrals = NULL;
-+      int num_referrals = 0;
-+      int len;
-+      __u16 fid;
-+
-+      xid = GetXid();
-+      cifs_sb = CIFS_SB(inode->i_sb);
-+      pTcon = cifs_sb->tcon;
-+
-+/* BB would it be safe against deadlock to grab this sem 
-+      even though rename itself grabs the sem and calls lookup? */
-+/*       down(&inode->i_sb->s_vfs_rename_sem);*/
-+      full_path = build_path_from_dentry(direntry);
-+/*       up(&inode->i_sb->s_vfs_rename_sem);*/
-+
-+      if(full_path == NULL) {
-+              FreeXid(xid);
-+              return -ENOMEM;
-+      }
-+
-+      cFYI(1,
-+           ("Full path: %s inode = 0x%p pBuffer = 0x%p buflen = %d",
-+            full_path, inode, pBuffer, buflen));
-+      if(buflen > PATH_MAX)
-+              len = PATH_MAX;
-+      else
-+              len = buflen;
-+      tmpbuffer = kmalloc(len,GFP_KERNEL);   
-+      if(tmpbuffer == NULL) {
-+              if (full_path)
-+                      kfree(full_path);
-+              FreeXid(xid);
-+              return -ENOMEM;
-+      }
-+
-+/* BB add read reparse point symlink code and Unix extensions symlink code here BB */
-+      if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)
-+              rc = CIFSSMBUnixQuerySymLink(xid, pTcon, full_path,
-+                              tmpbuffer,
-+                              len - 1,
-+                              cifs_sb->local_nls);
-+      else {
-+              rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, GENERIC_READ,
-+                              OPEN_REPARSE_POINT,&fid, &oplock, NULL, cifs_sb->local_nls);
-+              if(!rc) {
-+                      rc = CIFSSMBQueryReparseLinkInfo(xid, pTcon, full_path,
-+                              tmpbuffer,
-+                              len - 1, 
-+                              fid,
-+                              cifs_sb->local_nls);
-+                      if(CIFSSMBClose(xid, pTcon, fid)) {
-+                              cFYI(1,("Error closing junction point (open for ioctl)"));
-+                      }
-+                      if(rc == -EIO) {
-+                              /* Query if DFS Junction */
-+                              tmp_path =
-+                                      kmalloc(MAX_TREE_SIZE + MAX_PATHCONF + 1,
-+                                              GFP_KERNEL);
-+                              if (tmp_path) {
-+                                      strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE);
-+                                      strncat(tmp_path, full_path, MAX_PATHCONF);
-+                                      rc = get_dfs_path(xid, pTcon->ses, tmp_path,
-+                                              cifs_sb->local_nls, &num_referrals, &referrals);
-+                                      cFYI(1,("Get DFS for %s rc = %d ",tmp_path, rc));
-+                                      if((num_referrals == 0) && (rc == 0))
-+                                              rc = -EACCES;
-+                                      else {
-+                                              cFYI(1,("num referral: %d",num_referrals));
-+                                              if(referrals) {
-+                                                      cFYI(1,("referral string: %s ",referrals));
-+                                                      strncpy(tmpbuffer, referrals, len-1);                            
-+                                              }
-+                                      }
-+                                      if(referrals)
-+                                              kfree(referrals);
-+                                      kfree(tmp_path);
-+                                      if(referrals) {
-+                                              kfree(referrals);
-+                                      }
-+                              }
-+                              /* BB add code like else decode referrals then memcpy to
-+                                tmpbuffer and free referrals string array BB */
-+                      }
-+              }
-+      }
-+      /* BB Anything else to do to handle recursive links? */
-+      /* BB Should we be using page ops here? */
-+
-+      /* BB null terminate returned string in pBuffer? BB */
-+      if (rc == 0) {
-+              rc = vfs_readlink(direntry, pBuffer, len, tmpbuffer);
-+              cFYI(1,
-+                   ("vfs_readlink called from cifs_readlink returned %d",
-+                    rc));
-+      }
-+
-+      if (tmpbuffer) {
-+              kfree(tmpbuffer);
-+      }
-+      if (full_path) {
-+              kfree(full_path);
-+      }
-+      FreeXid(xid);
-+      return rc;
-+}
---- /dev/null
-+++ b/fs/cifs/Makefile
-@@ -0,0 +1,10 @@
-+#
-+# Makefile for Linux CIFS VFS client 
-+#
-+O_TARGET := cifs.o
-+
-+obj-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o cifsencrypt.o
-+
-+obj-m := $(O_TARGET)
-+
-+include $(TOPDIR)/Rules.make
---- /dev/null
-+++ b/fs/cifs/md4.c
-@@ -0,0 +1,203 @@
-+/* 
-+   Unix SMB/Netbios implementation.
-+   Version 1.9.
-+   a implementation of MD4 designed for use in the SMB authentication protocol
-+   Copyright (C) Andrew Tridgell 1997-1998.
-+   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/fs.h>
-+/* NOTE: This code makes no attempt to be fast! */
-+
-+static __u32
-+F(__u32 X, __u32 Y, __u32 Z)
-+{
-+      return (X & Y) | ((~X) & Z);
-+}
-+
-+static __u32
-+G(__u32 X, __u32 Y, __u32 Z)
-+{
-+      return (X & Y) | (X & Z) | (Y & Z);
-+}
-+
-+static __u32
-+H(__u32 X, __u32 Y, __u32 Z)
-+{
-+      return X ^ Y ^ Z;
-+}
-+
-+static __u32
-+lshift(__u32 x, int s)
-+{
-+      x &= 0xFFFFFFFF;
-+      return ((x << s) & 0xFFFFFFFF) | (x >> (32 - s));
-+}
-+
-+#define ROUND1(a,b,c,d,k,s) (*a) = lshift((*a) + F(*b,*c,*d) + X[k], s)
-+#define ROUND2(a,b,c,d,k,s) (*a) = lshift((*a) + G(*b,*c,*d) + X[k] + (__u32)0x5A827999,s)
-+#define ROUND3(a,b,c,d,k,s) (*a) = lshift((*a) + H(*b,*c,*d) + X[k] + (__u32)0x6ED9EBA1,s)
-+
-+/* this applies md4 to 64 byte chunks */
-+static void
-+mdfour64(__u32 * M, __u32 * A, __u32 *B, __u32 * C, __u32 *D)
-+{
-+      int j;
-+      __u32 AA, BB, CC, DD;
-+      __u32 X[16];
-+
-+
-+      for (j = 0; j < 16; j++)
-+              X[j] = M[j];
-+
-+      AA = *A;
-+      BB = *B;
-+      CC = *C;
-+      DD = *D;
-+
-+      ROUND1(A, B, C, D, 0, 3);
-+      ROUND1(D, A, B, C, 1, 7);
-+      ROUND1(C, D, A, B, 2, 11);
-+      ROUND1(B, C, D, A, 3, 19);
-+      ROUND1(A, B, C, D, 4, 3);
-+      ROUND1(D, A, B, C, 5, 7);
-+      ROUND1(C, D, A, B, 6, 11);
-+      ROUND1(B, C, D, A, 7, 19);
-+      ROUND1(A, B, C, D, 8, 3);
-+      ROUND1(D, A, B, C, 9, 7);
-+      ROUND1(C, D, A, B, 10, 11);
-+      ROUND1(B, C, D, A, 11, 19);
-+      ROUND1(A, B, C, D, 12, 3);
-+      ROUND1(D, A, B, C, 13, 7);
-+      ROUND1(C, D, A, B, 14, 11);
-+      ROUND1(B, C, D, A, 15, 19);
-+
-+      ROUND2(A, B, C, D, 0, 3);
-+      ROUND2(D, A, B, C, 4, 5);
-+      ROUND2(C, D, A, B, 8, 9);
-+      ROUND2(B, C, D, A, 12, 13);
-+      ROUND2(A, B, C, D, 1, 3);
-+      ROUND2(D, A, B, C, 5, 5);
-+      ROUND2(C, D, A, B, 9, 9);
-+      ROUND2(B, C, D, A, 13, 13);
-+      ROUND2(A, B, C, D, 2, 3);
-+      ROUND2(D, A, B, C, 6, 5);
-+      ROUND2(C, D, A, B, 10, 9);
-+      ROUND2(B, C, D, A, 14, 13);
-+      ROUND2(A, B, C, D, 3, 3);
-+      ROUND2(D, A, B, C, 7, 5);
-+      ROUND2(C, D, A, B, 11, 9);
-+      ROUND2(B, C, D, A, 15, 13);
-+
-+      ROUND3(A, B, C, D, 0, 3);
-+      ROUND3(D, A, B, C, 8, 9);
-+      ROUND3(C, D, A, B, 4, 11);
-+      ROUND3(B, C, D, A, 12, 15);
-+      ROUND3(A, B, C, D, 2, 3);
-+      ROUND3(D, A, B, C, 10, 9);
-+      ROUND3(C, D, A, B, 6, 11);
-+      ROUND3(B, C, D, A, 14, 15);
-+      ROUND3(A, B, C, D, 1, 3);
-+      ROUND3(D, A, B, C, 9, 9);
-+      ROUND3(C, D, A, B, 5, 11);
-+      ROUND3(B, C, D, A, 13, 15);
-+      ROUND3(A, B, C, D, 3, 3);
-+      ROUND3(D, A, B, C, 11, 9);
-+      ROUND3(C, D, A, B, 7, 11);
-+      ROUND3(B, C, D, A, 15, 15);
-+
-+      *A += AA;
-+      *B += BB;
-+      *C += CC;
-+      *D += DD;
-+
-+      *A &= 0xFFFFFFFF;
-+      *B &= 0xFFFFFFFF;
-+      *C &= 0xFFFFFFFF;
-+      *D &= 0xFFFFFFFF;
-+
-+      for (j = 0; j < 16; j++)
-+              X[j] = 0;
-+}
-+
-+static void
-+copy64(__u32 * M, unsigned char *in)
-+{
-+      int i;
-+
-+      for (i = 0; i < 16; i++)
-+              M[i] = (in[i * 4 + 3] << 24) | (in[i * 4 + 2] << 16) |
-+                  (in[i * 4 + 1] << 8) | (in[i * 4 + 0] << 0);
-+}
-+
-+static void
-+copy4(unsigned char *out, __u32 x)
-+{
-+      out[0] = x & 0xFF;
-+      out[1] = (x >> 8) & 0xFF;
-+      out[2] = (x >> 16) & 0xFF;
-+      out[3] = (x >> 24) & 0xFF;
-+}
-+
-+/* produce a md4 message digest from data of length n bytes */
-+void
-+mdfour(unsigned char *out, unsigned char *in, int n)
-+{
-+      unsigned char buf[128];
-+      __u32 M[16];
-+      __u32 b = n * 8;
-+      int i;
-+      __u32 A = 0x67452301;
-+      __u32 B = 0xefcdab89;
-+      __u32 C = 0x98badcfe;
-+      __u32 D = 0x10325476;
-+
-+      while (n > 64) {
-+              copy64(M, in);
-+              mdfour64(M,&A,&B, &C, &D);
-+              in += 64;
-+              n -= 64;
-+      }
-+
-+      for (i = 0; i < 128; i++)
-+              buf[i] = 0;
-+      memcpy(buf, in, n);
-+      buf[n] = 0x80;
-+
-+      if (n <= 55) {
-+              copy4(buf + 56, b);
-+              copy64(M, buf);
-+              mdfour64(M, &A, &B, &C, &D);
-+      } else {
-+              copy4(buf + 120, b);
-+              copy64(M, buf);
-+              mdfour64(M, &A, &B, &C, &D);
-+              copy64(M, buf + 64);
-+              mdfour64(M, &A, &B, &C, &D);
-+      }
-+
-+      for (i = 0; i < 128; i++)
-+              buf[i] = 0;
-+      copy64(M, buf);
-+
-+      copy4(out, A);
-+      copy4(out + 4, B);
-+      copy4(out + 8, C);
-+      copy4(out + 12, D);
-+
-+      A = B = C = D = 0;
-+}
---- /dev/null
-+++ b/fs/cifs/md5.c
-@@ -0,0 +1,363 @@
-+/*
-+ * This code implements the MD5 message-digest algorithm.
-+ * The algorithm is due to Ron Rivest.  This code was
-+ * written by Colin Plumb in 1993, no copyright is claimed.
-+ * This code is in the public domain; do with it what you wish.
-+ *
-+ * Equivalent code is available from RSA Data Security, Inc.
-+ * This code has been tested against that, and is equivalent,
-+ * except that you don't need to include two pages of legalese
-+ * with every copy.
-+ *
-+ * To compute the message digest of a chunk of bytes, declare an
-+ * MD5Context structure, pass it to MD5Init, call MD5Update as
-+ * needed on buffers full of bytes, and then call MD5Final, which
-+ * will fill a supplied 16-byte array with the digest.
-+ */
-+
-+/* This code slightly modified to fit into Samba by 
-+   abartlet@samba.org Jun 2001 
-+   and to fit the cifs vfs by 
-+   Steve French sfrench@us.ibm.com */
-+
-+#include <linux/string.h>
-+#include "md5.h"
-+
-+static void MD5Transform(__u32 buf[4], __u32 const in[16]);
-+
-+/*
-+ * Note: this code is harmless on little-endian machines.
-+ */
-+static void
-+byteReverse(unsigned char *buf, unsigned longs)
-+{
-+      __u32 t;
-+      do {
-+              t = (__u32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
-+                  ((unsigned) buf[1] << 8 | buf[0]);
-+              *(__u32 *) buf = t;
-+              buf += 4;
-+      } while (--longs);
-+}
-+
-+/*
-+ * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
-+ * initialization constants.
-+ */
-+void
-+MD5Init(struct MD5Context *ctx)
-+{
-+      ctx->buf[0] = 0x67452301;
-+      ctx->buf[1] = 0xefcdab89;
-+      ctx->buf[2] = 0x98badcfe;
-+      ctx->buf[3] = 0x10325476;
-+
-+      ctx->bits[0] = 0;
-+      ctx->bits[1] = 0;
-+}
-+
-+/*
-+ * Update context to reflect the concatenation of another buffer full
-+ * of bytes.
-+ */
-+void
-+MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
-+{
-+      register __u32 t;
-+
-+      /* Update bitcount */
-+
-+      t = ctx->bits[0];
-+      if ((ctx->bits[0] = t + ((__u32) len << 3)) < t)
-+              ctx->bits[1]++; /* Carry from low to high */
-+      ctx->bits[1] += len >> 29;
-+
-+      t = (t >> 3) & 0x3f;    /* Bytes already in shsInfo->data */
-+
-+      /* Handle any leading odd-sized chunks */
-+
-+      if (t) {
-+              unsigned char *p = (unsigned char *) ctx->in + t;
-+
-+              t = 64 - t;
-+              if (len < t) {
-+                      memmove(p, buf, len);
-+                      return;
-+              }
-+              memmove(p, buf, t);
-+              byteReverse(ctx->in, 16);
-+              MD5Transform(ctx->buf, (__u32 *) ctx->in);
-+              buf += t;
-+              len -= t;
-+      }
-+      /* Process data in 64-byte chunks */
-+
-+      while (len >= 64) {
-+              memmove(ctx->in, buf, 64);
-+              byteReverse(ctx->in, 16);
-+              MD5Transform(ctx->buf, (__u32 *) ctx->in);
-+              buf += 64;
-+              len -= 64;
-+      }
-+
-+      /* Handle any remaining bytes of data. */
-+
-+      memmove(ctx->in, buf, len);
-+}
-+
-+/*
-+ * Final wrapup - pad to 64-byte boundary with the bit pattern 
-+ * 1 0* (64-bit count of bits processed, MSB-first)
-+ */
-+void
-+MD5Final(unsigned char digest[16], struct MD5Context *ctx)
-+{
-+      unsigned int count;
-+      unsigned char *p;
-+
-+      /* Compute number of bytes mod 64 */
-+      count = (ctx->bits[0] >> 3) & 0x3F;
-+
-+      /* Set the first char of padding to 0x80.  This is safe since there is
-+         always at least one byte free */
-+      p = ctx->in + count;
-+      *p++ = 0x80;
-+
-+      /* Bytes of padding needed to make 64 bytes */
-+      count = 64 - 1 - count;
-+
-+      /* Pad out to 56 mod 64 */
-+      if (count < 8) {
-+              /* Two lots of padding:  Pad the first block to 64 bytes */
-+              memset(p, 0, count);
-+              byteReverse(ctx->in, 16);
-+              MD5Transform(ctx->buf, (__u32 *) ctx->in);
-+
-+              /* Now fill the next block with 56 bytes */
-+              memset(ctx->in, 0, 56);
-+      } else {
-+              /* Pad block to 56 bytes */
-+              memset(p, 0, count - 8);
-+      }
-+      byteReverse(ctx->in, 14);
-+
-+      /* Append length in bits and transform */
-+      ((__u32 *) ctx->in)[14] = ctx->bits[0];
-+      ((__u32 *) ctx->in)[15] = ctx->bits[1];
-+
-+      MD5Transform(ctx->buf, (__u32 *) ctx->in);
-+      byteReverse((unsigned char *) ctx->buf, 4);
-+      memmove(digest, ctx->buf, 16);
-+      memset(ctx, 0, sizeof(*ctx));   /* In case it's sensitive */
-+}
-+
-+/* The four core functions - F1 is optimized somewhat */
-+
-+/* #define F1(x, y, z) (x & y | ~x & z) */
-+#define F1(x, y, z) (z ^ (x & (y ^ z)))
-+#define F2(x, y, z) F1(z, x, y)
-+#define F3(x, y, z) (x ^ y ^ z)
-+#define F4(x, y, z) (y ^ (x | ~z))
-+
-+/* This is the central step in the MD5 algorithm. */
-+#define MD5STEP(f, w, x, y, z, data, s) \
-+      ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
-+
-+/*
-+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
-+ * reflect the addition of 16 longwords of new data.  MD5Update blocks
-+ * the data and converts bytes into longwords for this routine.
-+ */
-+static void
-+MD5Transform(__u32 buf[4], __u32 const in[16])
-+{
-+      register __u32 a, b, c, d;
-+
-+      a = buf[0];
-+      b = buf[1];
-+      c = buf[2];
-+      d = buf[3];
-+
-+      MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
-+      MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
-+      MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
-+      MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
-+      MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
-+      MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
-+      MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
-+      MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
-+      MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
-+      MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
-+      MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
-+      MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
-+      MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
-+      MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
-+      MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
-+      MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
-+
-+      MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
-+      MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
-+      MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
-+      MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
-+      MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
-+      MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
-+      MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
-+      MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
-+      MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
-+      MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
-+      MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
-+      MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
-+      MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
-+      MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
-+      MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
-+      MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
-+
-+      MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
-+      MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
-+      MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
-+      MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
-+      MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
-+      MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
-+      MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
-+      MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
-+      MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
-+      MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
-+      MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
-+      MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
-+      MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
-+      MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
-+      MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
-+      MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
-+
-+      MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
-+      MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
-+      MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
-+      MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
-+      MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
-+      MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
-+      MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
-+      MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
-+      MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
-+      MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
-+      MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
-+      MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
-+      MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
-+      MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
-+      MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
-+      MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
-+
-+      buf[0] += a;
-+      buf[1] += b;
-+      buf[2] += c;
-+      buf[3] += d;
-+}
-+
-+/***********************************************************************
-+ the rfc 2104 version of hmac_md5 initialisation.
-+***********************************************************************/
-+void
-+hmac_md5_init_rfc2104(unsigned char *key, int key_len,
-+                    struct HMACMD5Context *ctx)
-+{
-+      int i;
-+
-+      /* if key is longer than 64 bytes reset it to key=MD5(key) */
-+      if (key_len > 64) {
-+              unsigned char tk[16];
-+              struct MD5Context tctx;
-+
-+              MD5Init(&tctx);
-+              MD5Update(&tctx, key, key_len);
-+              MD5Final(tk, &tctx);
-+
-+              key = tk;
-+              key_len = 16;
-+      }
-+
-+      /* start out by storing key in pads */
-+      memset(ctx->k_ipad, 0, sizeof (ctx->k_ipad));
-+      memset(ctx->k_opad, 0, sizeof (ctx->k_opad));
-+      memcpy(ctx->k_ipad, key, key_len);
-+      memcpy(ctx->k_opad, key, key_len);
-+
-+      /* XOR key with ipad and opad values */
-+      for (i = 0; i < 64; i++) {
-+              ctx->k_ipad[i] ^= 0x36;
-+              ctx->k_opad[i] ^= 0x5c;
-+      }
-+
-+      MD5Init(&ctx->ctx);
-+      MD5Update(&ctx->ctx, ctx->k_ipad, 64);
-+}
-+
-+/***********************************************************************
-+ the microsoft version of hmac_md5 initialisation.
-+***********************************************************************/
-+void
-+hmac_md5_init_limK_to_64(const unsigned char *key, int key_len,
-+                       struct HMACMD5Context *ctx)
-+{
-+      int i;
-+
-+      /* if key is longer than 64 bytes truncate it */
-+      if (key_len > 64) {
-+              key_len = 64;
-+      }
-+
-+      /* start out by storing key in pads */
-+      memset(ctx->k_ipad, 0, sizeof (ctx->k_ipad));
-+      memset(ctx->k_opad, 0, sizeof (ctx->k_opad));
-+      memcpy(ctx->k_ipad, key, key_len);
-+      memcpy(ctx->k_opad, key, key_len);
-+
-+      /* XOR key with ipad and opad values */
-+      for (i = 0; i < 64; i++) {
-+              ctx->k_ipad[i] ^= 0x36;
-+              ctx->k_opad[i] ^= 0x5c;
-+      }
-+
-+      MD5Init(&ctx->ctx);
-+      MD5Update(&ctx->ctx, ctx->k_ipad, 64);
-+}
-+
-+/***********************************************************************
-+ update hmac_md5 "inner" buffer
-+***********************************************************************/
-+void
-+hmac_md5_update(const unsigned char *text, int text_len,
-+              struct HMACMD5Context *ctx)
-+{
-+      MD5Update(&ctx->ctx, text, text_len);   /* then text of datagram */
-+}
-+
-+/***********************************************************************
-+ finish off hmac_md5 "inner" buffer and generate outer one.
-+***********************************************************************/
-+void
-+hmac_md5_final(unsigned char *digest, struct HMACMD5Context *ctx)
-+{
-+      struct MD5Context ctx_o;
-+
-+      MD5Final(digest, &ctx->ctx);
-+
-+      MD5Init(&ctx_o);
-+      MD5Update(&ctx_o, ctx->k_opad, 64);
-+      MD5Update(&ctx_o, digest, 16);
-+      MD5Final(digest, &ctx_o);
-+}
-+
-+/***********************************************************
-+ single function to calculate an HMAC MD5 digest from data.
-+ use the microsoft hmacmd5 init method because the key is 16 bytes.
-+************************************************************/
-+void
-+hmac_md5(unsigned char key[16], unsigned char *data, int data_len,
-+       unsigned char *digest)
-+{
-+      struct HMACMD5Context ctx;
-+      hmac_md5_init_limK_to_64(key, 16, &ctx);
-+      if (data_len != 0) {
-+              hmac_md5_update(data, data_len, &ctx);
-+      }
-+      hmac_md5_final(digest, &ctx);
-+}
---- /dev/null
-+++ b/fs/cifs/md5.h
-@@ -0,0 +1,38 @@
-+#ifndef MD5_H
-+#define MD5_H
-+#ifndef HEADER_MD5_H
-+/* Try to avoid clashes with OpenSSL */
-+#define HEADER_MD5_H
-+#endif
-+
-+struct MD5Context {
-+      __u32 buf[4];
-+      __u32 bits[2];
-+      unsigned char in[64];
-+};
-+#endif                                /* !MD5_H */
-+
-+#ifndef _HMAC_MD5_H
-+struct HMACMD5Context {
-+      struct MD5Context ctx;
-+      unsigned char k_ipad[65];
-+      unsigned char k_opad[65];
-+};
-+#endif                                /* _HMAC_MD5_H */
-+
-+void MD5Init(struct MD5Context *context);
-+void MD5Update(struct MD5Context *context, unsigned char const *buf,
-+                      unsigned len);
-+void MD5Final(unsigned char digest[16], struct MD5Context *context);
-+
-+/* The following definitions come from lib/hmacmd5.c  */
-+
-+void hmac_md5_init_rfc2104(unsigned char *key, int key_len,
-+                      struct HMACMD5Context *ctx);
-+void hmac_md5_init_limK_to_64(const unsigned char *key, int key_len,
-+                      struct HMACMD5Context *ctx);
-+void hmac_md5_update(const unsigned char *text, int text_len,
-+                      struct HMACMD5Context *ctx);
-+void hmac_md5_final(unsigned char *digest, struct HMACMD5Context *ctx);
-+void hmac_md5(unsigned char key[16], unsigned char *data, int data_len,
-+                      unsigned char *digest);
---- /dev/null
-+++ b/fs/cifs/misc.c
-@@ -0,0 +1,463 @@
-+/*
-+ *   fs/cifs/misc.c
-+ *
-+ *   Copyright (C) International Business Machines  Corp., 2002,2003
-+ *   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 "cifspdu.h"
-+#include "cifsglob.h"
-+#include "cifsproto.h"
-+#include "cifs_debug.h"
-+#include "smberr.h"
-+#include "nterr.h"
-+
-+extern kmem_cache_t *cifs_req_cachep;
-+extern struct task_struct * oplockThread;
-+
-+__u16 GlobalMid;              /* multiplex id - rotating counter */
-+
-+/* The xid serves as a useful identifier for each incoming vfs request, 
-+   in a similar way to the mid which is useful to track each sent smb, 
-+   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++;
-+      if (GlobalTotalActiveXid > GlobalMaxActiveXid)
-+              GlobalMaxActiveXid = GlobalTotalActiveXid;      /* keep high water mark for number of simultaneous vfs ops in our filesystem */
-+      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 cifsSesInfo *
-+sesInfoAlloc(void)
-+{
-+      struct cifsSesInfo *ret_buf;
-+
-+      ret_buf =
-+          (struct cifsSesInfo *) kmalloc(sizeof (struct cifsSesInfo),
-+                                         GFP_KERNEL);
-+      if (ret_buf) {
-+              memset(ret_buf, 0, sizeof (struct cifsSesInfo));
-+              write_lock(&GlobalSMBSeslock);
-+              atomic_inc(&sesInfoAllocCount);
-+              ret_buf->status = CifsNew;
-+              list_add(&ret_buf->cifsSessionList, &GlobalSMBSessionList);
-+              init_MUTEX(&ret_buf->sesSem);
-+              write_unlock(&GlobalSMBSeslock);
-+      }
-+      return ret_buf;
-+}
-+
-+void
-+sesInfoFree(struct cifsSesInfo *buf_to_free)
-+{
-+      if (buf_to_free == NULL) {
-+              cFYI(1, ("Null buffer passed to sesInfoFree"));
-+              return;
-+      }
-+
-+      write_lock(&GlobalSMBSeslock);
-+      atomic_dec(&sesInfoAllocCount);
-+      list_del(&buf_to_free->cifsSessionList);
-+      write_unlock(&GlobalSMBSeslock);
-+      if (buf_to_free->serverOS)
-+              kfree(buf_to_free->serverOS);
-+      if (buf_to_free->serverDomain)
-+              kfree(buf_to_free->serverDomain);
-+      if (buf_to_free->serverNOS)
-+              kfree(buf_to_free->serverNOS);
-+      if (buf_to_free->password)
-+              kfree(buf_to_free->password);
-+      kfree(buf_to_free);
-+}
-+
-+struct cifsTconInfo *
-+tconInfoAlloc(void)
-+{
-+      struct cifsTconInfo *ret_buf;
-+      ret_buf =
-+          (struct cifsTconInfo *) kmalloc(sizeof (struct cifsTconInfo),
-+                                          GFP_KERNEL);
-+      if (ret_buf) {
-+              memset(ret_buf, 0, sizeof (struct cifsTconInfo));
-+              write_lock(&GlobalSMBSeslock);
-+              atomic_inc(&tconInfoAllocCount);
-+              list_add(&ret_buf->cifsConnectionList,
-+                       &GlobalTreeConnectionList);
-+              ret_buf->tidStatus = CifsNew;
-+              INIT_LIST_HEAD(&ret_buf->openFileList);
-+              init_MUTEX(&ret_buf->tconSem);
-+#ifdef CONFIG_CIFS_STATS
-+              ret_buf->stat_lock = SPIN_LOCK_UNLOCKED;
-+#endif
-+              write_unlock(&GlobalSMBSeslock);
-+      }
-+      return ret_buf;
-+}
-+
-+void
-+tconInfoFree(struct cifsTconInfo *buf_to_free)
-+{
-+      if (buf_to_free == NULL) {
-+              cFYI(1, ("Null buffer passed to tconInfoFree"));
-+              return;
-+      }
-+      write_lock(&GlobalSMBSeslock);
-+      atomic_dec(&tconInfoAllocCount);
-+      list_del(&buf_to_free->cifsConnectionList);
-+      write_unlock(&GlobalSMBSeslock);
-+      if (buf_to_free->nativeFileSystem)
-+              kfree(buf_to_free->nativeFileSystem);
-+      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 =
-+          (struct smb_hdr *) kmem_cache_alloc(cifs_req_cachep, SLAB_KERNEL);
-+
-+      /* clear the first few header bytes */
-+      if (ret_buf) {
-+              memset(ret_buf, 0, sizeof (struct smb_hdr));
-+              atomic_inc(&bufAllocCount);
-+      }
-+
-+      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;
-+      }
-+      kmem_cache_free(cifs_req_cachep, buf_to_free);
-+
-+      atomic_dec(&bufAllocCount);
-+      return;
-+}
-+
-+void
-+header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
-+              const struct cifsTconInfo *treeCon, int word_count
-+              /* length of fixed section (word count) in two byte units  */
-+    )
-+{
-+      int i;
-+      __u32 tmp;
-+      struct list_head* temp_item;
-+      struct cifsSesInfo * ses;
-+      char *temp = (char *) buffer;
-+
-+      for (i = 0; i < MAX_CIFS_HDR_SIZE; i++) {
-+              temp[i] = 0;    /* BB is this needed ?? */
-+      }
-+
-+      buffer->smb_buf_length =
-+          (2 * word_count) + sizeof (struct smb_hdr) -
-+          4 /*  RFC 1001 length field does not count */  +
-+          2 /* for bcc field itself */ ;
-+      /* Note that this is the only network field that has to be converted to big endian and it is done just before we send it */
-+
-+      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;
-+      tmp = cpu_to_le32(current->pid);
-+      buffer->Pid = tmp & 0xFFFF;
-+      tmp >>= 16;
-+      buffer->PidHigh = tmp & 0xFFFF;
-+      spin_lock(&GlobalMid_Lock);
-+      GlobalMid++;
-+      buffer->Mid = GlobalMid;
-+      spin_unlock(&GlobalMid_Lock);
-+      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;
-+                      }
-+
-+                      buffer->Uid = treeCon->ses->Suid;       /* always in LE format */
-+                      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->uid != treeCon->ses->linux_uid) {
-+                                      cFYI(1,("Multiuser mode and UID did not match tcon uid "));
-+                                      read_lock(&GlobalSMBSeslock);
-+                                      list_for_each(temp_item, &GlobalSMBSessionList) {
-+                                              ses = list_entry(temp_item, struct cifsSesInfo, cifsSessionList);
-+                                              if(ses->linux_uid == current->uid) {
-+                                                      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 smb sess with this server does not exist"));  
-+                                                      }
-+                                              }
-+                                      }
-+                                      read_unlock(&GlobalSMBSeslock);
-+                              }
-+                      }
-+              }
-+              if (treeCon->Flags & SMB_SHARE_IS_IN_DFS)
-+                      buffer->Flags2 |= SMBFLG2_DFS;
-+              if(treeCon->ses->server)
-+                      if(treeCon->ses->server->secMode & 
-+                        (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;
-+}
-+
-+int
-+checkSMBhdr(struct smb_hdr *smb, __u16 mid)
-+{
-+      /* Make sure that this really is an SMB, that it is a response, 
-+         and that the message ids match */
-+      if ((*(unsigned int *) smb->Protocol == cpu_to_le32(0x424d53ff)) && 
-+              (mid == smb->Mid)) {    
-+              if(smb->Flags & SMBFLG_RESPONSE)
-+                      return 0;                    
-+              else {        
-+              /* only one valid case where server sends us request */
-+                      if(smb->Command == SMB_COM_LOCKING_ANDX)
-+                              return 0;
-+                      else
-+                              cERROR(1, ("Rcvd Request not response "));         
-+              }
-+      } else { /* bad signature or mid */
-+              if (*(unsigned int *) smb->Protocol != cpu_to_le32(0x424d53ff))
-+                      cERROR(1,
-+                             ("Bad protocol string signature header %x ",
-+                              *(unsigned int *) smb->Protocol));
-+              if (mid != smb->Mid)
-+                      cERROR(1, ("Mids do not match"));
-+      }
-+      cERROR(1, ("bad smb detected. The Mid=%d", smb->Mid));
-+      return 1;
-+}
-+
-+int
-+checkSMB(struct smb_hdr *smb, __u16 mid, int length)
-+{
-+      cFYI(0,
-+           ("Entering checkSMB with Length: %x, smb_buf_length: %x ",
-+            length, ntohl(smb->smb_buf_length)));
-+      if (((unsigned int)length < 2 + sizeof (struct smb_hdr))
-+          || (ntohl(smb->smb_buf_length) >
-+              CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE - 4)) {
-+              if ((unsigned int)length < 2 + sizeof (struct smb_hdr)) {
-+                      cERROR(1, ("Length less than 2 + sizeof smb_hdr "));
-+                      if (((unsigned int)length >= sizeof (struct smb_hdr) - 1)
-+                          && (smb->Status.CifsError != 0))
-+                              return 0;       /* some error cases do not return wct and bcc */
-+
-+              }
-+              if (ntohl(smb->smb_buf_length) >
-+                  CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE - 4)
-+                      cERROR(1,
-+                             ("smb_buf_length greater than CIFS_MAX_MSGSIZE ... "));
-+              cERROR(1,
-+                     ("bad smb detected. Illegal length. The mid=%d",
-+                      smb->Mid));
-+              return 1;
-+      }
-+
-+      if (checkSMBhdr(smb, mid))
-+              return 1;
-+
-+      if ((4 + ntohl(smb->smb_buf_length) != smbCalcSize(smb))
-+          || (4 + ntohl(smb->smb_buf_length) != (unsigned int)length)) {
-+              return 0;
-+      } else {
-+              cERROR(1, ("smbCalcSize %x ", smbCalcSize(smb)));
-+              cERROR(1,
-+                     ("bad smb size detected. The Mid=%d", smb->Mid));
-+              return 1;
-+      }
-+}
-+int
-+is_valid_oplock_break(struct smb_hdr *buf)
-+{    
-+      struct smb_com_lock_req * pSMB = (struct smb_com_lock_req *)buf;
-+      struct list_head *tmp;
-+      struct list_head *tmp1;
-+      struct cifsTconInfo *tcon;
-+      struct cifsFileInfo *netfile;
-+
-+      /* could add check for smb response flag 0x80 */
-+      cFYI(1,("Checking for oplock break"));    
-+      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 */
-+      read_lock(&GlobalSMBSeslock);
-+      list_for_each(tmp, &GlobalTreeConnectionList) {
-+              tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
-+              if (tcon->tid == buf->Tid) {
-+#ifdef CONFIG_CIFS_STATS
-+                      atomic_inc(&tcon->num_oplock_brks);
-+#endif
-+                      list_for_each(tmp1,&tcon->openFileList){
-+                              netfile = list_entry(tmp1,struct cifsFileInfo,tlist);
-+                              if(pSMB->Fid == netfile->netfid) {
-+                                      struct cifsInodeInfo *pCifsInode;
-+                                      read_unlock(&GlobalSMBSeslock);
-+                                      cFYI(1,("Matching file id, processing oplock break"));
-+                                      pCifsInode = 
-+                                              CIFS_I(netfile->pInode);
-+                                      pCifsInode->clientCanCacheAll = FALSE;
-+                                      if(pSMB->OplockLevel == 0)
-+                                              pCifsInode->clientCanCacheRead = FALSE;
-+                                      pCifsInode->oplockPending = TRUE;
-+                                      AllocOplockQEntry(netfile->pInode, netfile->netfid, tcon);
-+                                      cFYI(1,("about to wake up oplock thd"));
-+                                      wake_up_process(oplockThread);               
-+                                      return TRUE;
-+                              }
-+                      }
-+                      read_unlock(&GlobalSMBSeslock);
-+                      cFYI(1,("No matching file for oplock break on connection"));
-+                      return TRUE;
-+              }
-+      }
-+      read_unlock(&GlobalSMBSeslock);
-+      cFYI(1,("Can not process oplock break for non-existent connection"));
-+      return TRUE;
-+}
-+
-+void
-+dump_smb(struct smb_hdr *smb_buf, int smb_buf_length)
-+{
-+      int i, j;
-+      char debug_line[17];
-+      unsigned char *buffer;
-+
-+      if (traceSMB == 0)
-+              return;
-+
-+      buffer = (unsigned char *) smb_buf;
-+      for (i = 0, j = 0; i < smb_buf_length; i++, j++) {
-+              if (i % 8 == 0) {       /* we 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) {       /* we have 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;
-+}
---- /dev/null
-+++ b/fs/cifs/netmisc.c
-@@ -0,0 +1,905 @@
-+/*
-+ *   fs/cifs/netmisc.c
-+ *
-+ *   Copyright (c) International Business Machines  Corp., 2002
-+ *   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 "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;
-+};
-+
-+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},
-+      {ERRbadshare, -ETXTBSY},
-+      {ERRlock, -EACCES},
-+      {ERRunsup, -EINVAL},
-+      {ERRnosuchshare,-ENXIO},
-+      {ERRfilexists, -EEXIST},
-+      {ERRinvparm, -EINVAL},
-+      {ERRdiskfull, -ENOSPC},
-+      {ERRinvname, -ENOENT},
-+      {ERRdirnotempty, -ENOTEMPTY},
-+      {ERRnotlocked, -ENOLCK},
-+      {ERRalreadyexists, -EEXIST},
-+      {ERRmoredata, -EOVERFLOW},
-+      {ErrQuota, -EDQUOT},
-+      {ErrNotALink, -ENOLINK},
-+      {ERRnetlogonNotStarted,-ENOPROTOOPT},
-+      {0, 0}
-+};
-+
-+const struct smb_to_posix_error mapping_table_ERRSRV[] = {
-+      {ERRerror, -EIO},
-+      {ERRbadpw, -EPERM},
-+      {ERRbadtype, -EREMOTE},
-+      {ERRaccess, -EACCES},
-+      {ERRinvtid, -ENXIO},
-+      {ERRinvnetname, -ENODEV},
-+      {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},
-+      {ERRaccountexpired, -EACCES},
-+      {ERRbadclient, -EACCES},
-+      {ERRbadLogonTime, -EACCES},
-+      {ERRpasswordExpired, -EACCES},
-+      {ERRnosupport, -EINVAL},
-+      {0, 0}
-+};
-+
-+const struct smb_to_posix_error mapping_table_ERRHRD[] = {
-+      {0, 0}
-+};
-+
-+/* Convert string containing dotted ip address to binary form */
-+/* returns 0 if invalid address */
-+
-+/* BB add address family, change rc to status flag and return union or for ipv6 */
-+/*  will need parent to call something like inet_pton to convert ipv6 address  BB */
-+int
-+cifs_inet_pton(int address_family, char *cp,void *dst)
-+{
-+      struct in_addr address;
-+      int value;
-+      int digit;
-+      int i;
-+      char temp;
-+      char bytes[4];
-+      char *end = bytes;
-+      static const int addr_class_max[4] =
-+          { 0xffffffff, 0xffffff, 0xffff, 0xff };
-+
-+      if(address_family != AF_INET)
-+              return -EAFNOSUPPORT;
-+
-+      for (i = 0; i < 4; i++) {
-+              bytes[i] = 0;
-+      }
-+
-+      temp = *cp;
-+
-+      while (TRUE) {
-+              if (!isdigit(temp))
-+                      return 0;
-+
-+              value = 0;
-+              digit = 0;
-+              for (;;) {
-+                      if (isascii(temp) && isdigit(temp)) {
-+                              value = (value * 10) + temp - '0';
-+                              temp = *++cp;
-+                              digit = 1;
-+                      } else
-+                              break;
-+              }
-+
-+              if (temp == '.') {
-+                      if ((end > bytes + 2) || (value > 255))
-+                              return 0;
-+                      *end++ = value;
-+                      temp = *++cp;
-+              } else if (temp == ':') {
-+                      cFYI(1,("IPv6 addresses not supported for CIFS mounts yet"));
-+                      return -1;
-+              } else
-+                      break;
-+      }
-+
-+      /* check for last characters */
-+      if (temp != '\0' && (!isascii(temp) || !isspace(temp)))
-+              if (temp != '\\') {
-+                      if (temp != '/')
-+                              return 0;
-+                      else
-+                              (*cp = '\\');   /* switch the slash the expected way */
-+              }
-+      if (value > addr_class_max[end - bytes])
-+              return 0;
-+
-+      address.s_addr = *((int *) bytes) | htonl(value);
-+      *((int *)dst) = address.s_addr;
-+      return 1; /* success */
-+}
-+
-+/*****************************************************************************
-+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, 87, 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}, {
-+      ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_INVALID}, {   /* mapping changed since shell does lookup on * and expects file not found */
-+      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, 282, 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}, {
-+      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, 2241, NT_STATUS_INVALID_LOGON_HOURS}, {
-+      ERRSRV, 2240, NT_STATUS_INVALID_WORKSTATION}, {
-+      ERRSRV, 2242, NT_STATUS_PASSWORD_EXPIRED}, {
-+      ERRSRV, 2239, 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, 2239, 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, 2242, 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}, {
-+      ERRHRD, ERRgeneral, 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},};
-+
-+/*****************************************************************************
-+ 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(struct smb_hdr *smb)
-+{
-+      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 errors and then to POSIX errors */
-+              smb->Status.CifsError = le32_to_cpu(smb->Status.CifsError);
-+              if(cifsFYI)
-+                      cifs_print_status(smb->Status.CifsError);
-+              ntstatus_to_dos(smb->Status.CifsError, &smberrclass,
-+                              &smberrcode);
-+      } else {
-+              smberrclass = smb->Status.DosError.ErrorClass;
-+              smb->Status.DosError.Error =
-+                  le16_to_cpu(smb->Status.DosError.Error);
-+              smberrcode = smb->Status.DosError.Error;
-+      }
-+
-+      /* old style errors */
-+
-+      /* DOS class smb error codes - map DOS */
-+      if (smberrclass == ERRDOS) {    /* one 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 the next error mapping one to see if it will 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 the next error mapping one to see if it will match */
-+              }
-+      }
-+      /* else ERRHRD class errors or junk  - return EIO */
-+
-+      cFYI(1, (" !!Mapping smb error code %d to POSIX err %d !!", smberrcode,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) +
-+              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).
-+     */
-+time_t
-+cifs_NTtimeToUnix(__u64 ntutc)
-+{
-+      /* BB what about the timezone? BB */
-+
-+      /* Subtract the NTFS time offset, then convert to 1s intervals. */
-+      u64 t;
-+
-+      t = ntutc - NTFS_TIME_OFFSET;
-+      do_div(t, 10000000);
-+      return (time_t)t;
-+}
-+
-+/* Convert the Unix UTC into NT UTC. */
-+__u64
-+cifs_UnixTimeToNT(time_t t)
-+{
-+      __u64 dce_time;
-+   /* Convert to 100ns intervals and then add the NTFS time offset. */
-+      dce_time = (__u64) t * 10000000;
-+      dce_time += NTFS_TIME_OFFSET;
-+      return dce_time;
-+}
---- /dev/null
-+++ b/fs/cifs/nterr.c
-@@ -0,0 +1,687 @@
-+/* 
-+ *  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}
-+};
---- /dev/null
-+++ b/fs/cifs/nterr.h
-@@ -0,0 +1,556 @@
-+/* 
-+   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_BUFFER_OVERFLOW            0x80000005
-+#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_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 */
---- /dev/null
-+++ b/fs/cifs/ntlmssp.h
-@@ -0,0 +1,101 @@
-+/*
-+ *   fs/cifs/ntlmssp.h
-+ *
-+ *   Copyright (c) International Business Machines  Corp., 2002
-+ *   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 
-+ */
-+
-+#pragma pack(1)
-+
-+#define NTLMSSP_SIGNATURE "NTLMSSP"
-+/* Message Types */
-+#define NtLmNegotiate     1
-+#define NtLmChallenge     2
-+#define NtLmAuthenticate  3
-+#define UnknownMessage    8
-+
-+/* Negotiate Flags */
-+#define NTLMSSP_NEGOTIATE_UNICODE       0x01  // Text strings are in unicode
-+#define NTLMSSP_NEGOTIATE_OEM           0x02  // Text strings are in OEM
-+#define NTLMSSP_REQUEST_TARGET          0x04  // Server return its auth realm
-+#define NTLMSSP_NEGOTIATE_SIGN        0x0010  // Request signature capability
-+#define NTLMSSP_NEGOTIATE_SEAL        0x0020  // Request confidentiality
-+#define NTLMSSP_NEGOTIATE_DGRAM       0x0040
-+#define NTLMSSP_NEGOTIATE_LM_KEY      0x0080  // Use LM session key for sign/seal
-+#define NTLMSSP_NEGOTIATE_NTLM        0x0200  // NTLM authentication
-+#define NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED 0x1000
-+#define NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED 0x2000
-+#define NTLMSSP_NEGOTIATE_LOCAL_CALL  0x4000  // client/server on same machine
-+#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x8000  // Sign for all security levels
-+#define NTLMSSP_TARGET_TYPE_DOMAIN   0x10000
-+#define NTLMSSP_TARGET_TYPE_SERVER   0x20000
-+#define NTLMSSP_TARGET_TYPE_SHARE    0x40000
-+#define NTLMSSP_NEGOTIATE_NTLMV2     0x80000
-+#define NTLMSSP_REQUEST_INIT_RESP   0x100000
-+#define NTLMSSP_REQUEST_ACCEPT_RESP 0x200000
-+#define NTLMSSP_REQUEST_NOT_NT_KEY  0x400000
-+#define NTLMSSP_NEGOTIATE_TARGET_INFO 0x800000
-+#define NTLMSSP_NEGOTIATE_128     0x20000000
-+#define NTLMSSP_NEGOTIATE_KEY_XCH 0x40000000
-+#define NTLMSSP_NEGOTIATE_56      0x80000000
-+
-+/* 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 {
-+      __u16 Length;
-+      __u16 MaximumLength;
-+      __u32 Buffer;           /* offset to buffer */
-+} SECURITY_BUFFER;
-+
-+typedef struct _NEGOTIATE_MESSAGE {
-+      __u8 Signature[sizeof (NTLMSSP_SIGNATURE)];
-+      __u32 MessageType;     /* 1 */
-+      __u32 NegotiateFlags;
-+      SECURITY_BUFFER DomainName;     /* RFC 1001 style and ASCII */
-+      SECURITY_BUFFER WorkstationName;        /* RFC 1001 and ASCII */
-+      char DomainString[0];
-+      /* followed by WorkstationString */
-+} NEGOTIATE_MESSAGE, *PNEGOTIATE_MESSAGE;
-+
-+typedef struct _CHALLENGE_MESSAGE {
-+      __u8 Signature[sizeof (NTLMSSP_SIGNATURE)];
-+      __u32 MessageType;   /* 2 */
-+      SECURITY_BUFFER TargetName;
-+      __u32 NegotiateFlags;
-+      __u8 Challenge[CIFS_CRYPTO_KEY_SIZE];
-+      __u8 Reserved[8];
-+      SECURITY_BUFFER TargetInfoArray;
-+} CHALLENGE_MESSAGE, *PCHALLENGE_MESSAGE;
-+
-+typedef struct _AUTHENTICATE_MESSAGE {
-+      __u8 Signature[sizeof (NTLMSSP_SIGNATURE)];
-+      __u32 MessageType;  /* 3 */
-+      SECURITY_BUFFER LmChallengeResponse;
-+      SECURITY_BUFFER NtChallengeResponse;
-+      SECURITY_BUFFER DomainName;
-+      SECURITY_BUFFER UserName;
-+      SECURITY_BUFFER WorkstationName;
-+      SECURITY_BUFFER SessionKey;
-+      __u32 NegotiateFlags;
-+      char UserString[0];
-+} AUTHENTICATE_MESSAGE, *PAUTHENTICATE_MESSAGE;
-+
-+#pragma pack()                        /* resume default structure packing */
---- /dev/null
-+++ b/fs/cifs/README
-@@ -0,0 +1,356 @@
-+The CIFS VFS support for Linux supports many advanced network filesystem 
-+features such as heirarchical 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.  
-+
-+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.5:
-+1) Download the kernel (e.g. from http://www.kernel.org or from bitkeeper
-+at bk://linux.bkbits.net/linux-2.5) 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
-+
-+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 
-+
-+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 ea support is required for supporting Linux xattrs. 
-+Some administrators also change the "map archive" and the "create mask" 
-+parameters from their default values.  Creating special devices (mknod) 
-+remotely may require specifying a mkdev function to Samba if you are not using 
-+Samba 3.0.5 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.5, most symlinks to
-+files with absolute paths (ie beginning with slash) such as:
-+       ln -s /mnt/foo bar
-+would be forbidden. Samba 3.0.5 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).
-+
-+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 the NTLM SMB dialect (which is the most recent, supported 
-+by Samba and Windows NT version 4, 2000 and XP and many other SMB/CIFS servers) 
-+Servers must support either "pure-TCP" (port 445 TCP/IP CIFS connections) or RFC 
-+1001/1002 support for "Netbios-Over-TCP/IP." Neither of these is likely to be a 
-+problem as most servers support this.  IPv6 support is planned for the future.  
-+
-+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 it is 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
-+  uid         If CIFS Unix extensions are not supported by the server
-+              this overrides the default uid for inodes. 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.  For servers which do not support
-+              the Unix extensions, the default uid (and gid) returned on
-+              lookup of existing files is 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.  For the uid (gid) of newly
-+              created files and directories, ie files created since 
-+              the last mount of the server share, the expected uid 
-+              (gid) is cached as as long as the inode remains in 
-+              memory on the client.   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
-+  gid         If CIFS Unix extensions are not supported by the server
-+              this overrides the default gid for inodes.
-+  file_mode     If CIFS Unix extensions are not supported by the server
-+              this overrides the default mode for file inodes.
-+  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
-+  wsize               default write size
-+  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.
-+  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.
-+
-+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 recent 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.
-+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)
-+cifsFYI                       If set to one, additional debug information is
-+                      logged to the system error log. (default 0)
-+ExtendedSecurity      If set to one, SPNEGO session establishment
-+                      is allowed which enables more advanced 
-+                      secure CIFS session establishment (default 0)
-+NTLMV2Enabled         If set to one, more secure password hashes
-+                      are used when the server supports them and
-+                      when kerberos is not negotiated (default 0)
-+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 1 > /proc/fs/cifs/cifsFYI
-+      
-+and for more extensive tracing including the start of smb requests and responses
-+
-+      echo 1 > /proc/fs/cifs/traceSMB
-+
-+Three other experimental features are under development and to test 
-+require enabling an ifdef (e.g. by  adding "#define CIFS_FCNTL" in cifsglob.h)
-+
-+      CONFIG_CIFS_QUOTA
-+
-+      CONFIG_CIFS_XATTR
-+
-+      CONFIG_CIFS_FCNTL  (fcntl needed for support of directory change 
-+                          notification and perhaps later for file leases)
-+
-+Per share (per client mount) statistics are available in /proc/fs/cifs/DebugData
-+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.  Note: NTLMv2 enablement 
-+will not work since they its implementation is not quite complete yet.
-+Do not alter these configuration values unless you are doing specific testing.  
-+Enabling extended security works to Windows 2000 Workstations and XP but not to 
-+Windows 2000 server or Samba since it does not usually send "raw NTLMSSP" 
-+(instead it sends NTLMSSP encapsulated in SPNEGO/GSSAPI, which support is not 
-+complete in the CIFS VFS yet).  
---- /dev/null
-+++ b/fs/cifs/rfc1002pdu.h
-@@ -0,0 +1,79 @@
-+/*
-+ *   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 
-+ */
-+
-+#pragma pack(1)
-+
-+/* NB: unlike smb/cifs packets, the RFC1002 structures are big endian */
-+
-+      /* RFC 1002 session packet types */
-+#define RFC1002_SESSION_MESASAGE 0x00
-+#define RFC1002_SESSION_REQUEST  0x81
-+#define RFC1002_POSITIVE_SESSION_RESPONSE 0x82
-+#define RFC1002_NEGATIVE_SESSION_RESPONSE 0x83
-+#define RFC1002_RETARGET_SESSION_RESPONSE 0x83
-+#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 */
-+              } session_req;
-+              struct {
-+                      __u32 retarget_ip_addr;
-+                      __u16 port;
-+              } 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 */
-+      } trailer;
-+};
-+
-+/* 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      "
-+
-+#pragma pack()                /* resume default structure packing */
-+                                                             
---- /dev/null
-+++ b/fs/cifs/smbdes.c
-@@ -0,0 +1,408 @@
-+/* 
-+   Unix SMB/Netbios implementation.
-+   Version 1.9.
-+
-+   a partial implementation of DES designed for use in the 
-+   SMB authentication protocol
-+
-+   Copyright (C) Andrew Tridgell 1998
-+   Modified by Steve French (sfrench@us.ibm.com) 2002,2004
-+   
-+   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.
-+*/
-+
-+/* NOTES: 
-+
-+   This code makes no attempt to be fast! In fact, it is a very
-+   slow implementation 
-+
-+   This code is NOT a complete DES implementation. It implements only
-+   the minimum necessary for SMB authentication, as used by all SMB
-+   products (including every copy of Microsoft Windows95 ever sold)
-+
-+   In particular, it can only do a unchained forward DES pass. This
-+   means it is not possible to use this code for encryption/decryption
-+   of data, instead it is only useful as a "hash" algorithm.
-+
-+   There is no entry point into this code that allows normal DES operation.
-+
-+   I believe this means that this code does not come under ITAR
-+   regulations but this is NOT a legal opinion. If you are concerned
-+   about the applicability of ITAR regulations to this code then you
-+   should confirm it for yourself (and maybe let me know if you come
-+   up with a different answer to the one above)
-+*/
-+#include <linux/slab.h>
-+#define uchar unsigned char
-+
-+static uchar perm1[56] = { 57, 49, 41, 33, 25, 17, 9,
-+      1, 58, 50, 42, 34, 26, 18,
-+      10, 2, 59, 51, 43, 35, 27,
-+      19, 11, 3, 60, 52, 44, 36,
-+      63, 55, 47, 39, 31, 23, 15,
-+      7, 62, 54, 46, 38, 30, 22,
-+      14, 6, 61, 53, 45, 37, 29,
-+      21, 13, 5, 28, 20, 12, 4
-+};
-+
-+static uchar perm2[48] = { 14, 17, 11, 24, 1, 5,
-+      3, 28, 15, 6, 21, 10,
-+      23, 19, 12, 4, 26, 8,
-+      16, 7, 27, 20, 13, 2,
-+      41, 52, 31, 37, 47, 55,
-+      30, 40, 51, 45, 33, 48,
-+      44, 49, 39, 56, 34, 53,
-+      46, 42, 50, 36, 29, 32
-+};
-+
-+static uchar perm3[64] = { 58, 50, 42, 34, 26, 18, 10, 2,
-+      60, 52, 44, 36, 28, 20, 12, 4,
-+      62, 54, 46, 38, 30, 22, 14, 6,
-+      64, 56, 48, 40, 32, 24, 16, 8,
-+      57, 49, 41, 33, 25, 17, 9, 1,
-+      59, 51, 43, 35, 27, 19, 11, 3,
-+      61, 53, 45, 37, 29, 21, 13, 5,
-+      63, 55, 47, 39, 31, 23, 15, 7
-+};
-+
-+static uchar perm4[48] = { 32, 1, 2, 3, 4, 5,
-+      4, 5, 6, 7, 8, 9,
-+      8, 9, 10, 11, 12, 13,
-+      12, 13, 14, 15, 16, 17,
-+      16, 17, 18, 19, 20, 21,
-+      20, 21, 22, 23, 24, 25,
-+      24, 25, 26, 27, 28, 29,
-+      28, 29, 30, 31, 32, 1
-+};
-+
-+static uchar perm5[32] = { 16, 7, 20, 21,
-+      29, 12, 28, 17,
-+      1, 15, 23, 26,
-+      5, 18, 31, 10,
-+      2, 8, 24, 14,
-+      32, 27, 3, 9,
-+      19, 13, 30, 6,
-+      22, 11, 4, 25
-+};
-+
-+static uchar perm6[64] = { 40, 8, 48, 16, 56, 24, 64, 32,
-+      39, 7, 47, 15, 55, 23, 63, 31,
-+      38, 6, 46, 14, 54, 22, 62, 30,
-+      37, 5, 45, 13, 53, 21, 61, 29,
-+      36, 4, 44, 12, 52, 20, 60, 28,
-+      35, 3, 43, 11, 51, 19, 59, 27,
-+      34, 2, 42, 10, 50, 18, 58, 26,
-+      33, 1, 41, 9, 49, 17, 57, 25
-+};
-+
-+static uchar sc[16] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
-+
-+static uchar sbox[8][4][16] = {
-+      {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
-+       {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
-+       {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
-+       {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}},
-+
-+      {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
-+       {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
-+       {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
-+       {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}},
-+
-+      {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
-+       {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
-+       {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
-+       {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}},
-+
-+      {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
-+       {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
-+       {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
-+       {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}},
-+
-+      {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
-+       {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
-+       {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
-+       {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}},
-+
-+      {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
-+       {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
-+       {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
-+       {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}},
-+
-+      {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
-+       {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
-+       {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
-+       {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}},
-+
-+      {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
-+       {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
-+       {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
-+       {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}
-+};
-+
-+static void
-+permute(char *out, char *in, uchar * p, int n)
-+{
-+      int i;
-+      for (i = 0; i < n; i++)
-+              out[i] = in[p[i] - 1];
-+}
-+
-+static void
-+lshift(char *d, int count, int n)
-+{
-+      char out[64];
-+      int i;
-+      for (i = 0; i < n; i++)
-+              out[i] = d[(i + count) % n];
-+      for (i = 0; i < n; i++)
-+              d[i] = out[i];
-+}
-+
-+static void
-+concat(char *out, char *in1, char *in2, int l1, int l2)
-+{
-+      while (l1--)
-+              *out++ = *in1++;
-+      while (l2--)
-+              *out++ = *in2++;
-+}
-+
-+static void
-+xor(char *out, char *in1, char *in2, int n)
-+{
-+      int i;
-+      for (i = 0; i < n; i++)
-+              out[i] = in1[i] ^ in2[i];
-+}
-+
-+static void
-+dohash(char *out, char *in, char *key, int forw)
-+{
-+      int i, j, k;
-+      char *pk1;
-+      char c[28];
-+      char d[28];
-+      char *cd;
-+      char ki[16][48];
-+      char *pd1;
-+      char l[32], r[32];
-+      char *rl;
-+
-+      /* Have to reduce stack usage */
-+      pk1 = kmalloc(56+56+64+64,GFP_KERNEL);
-+      if(pk1 == NULL)
-+              return;
-+
-+      cd = pk1 + 56;
-+      pd1= cd  + 56;
-+      rl = pd1 + 64;
-+
-+      permute(pk1, key, perm1, 56);
-+
-+      for (i = 0; i < 28; i++)
-+              c[i] = pk1[i];
-+      for (i = 0; i < 28; i++)
-+              d[i] = pk1[i + 28];
-+
-+      for (i = 0; i < 16; i++) {
-+              lshift(c, sc[i], 28);
-+              lshift(d, sc[i], 28);
-+
-+              concat(cd, c, d, 28, 28);
-+              permute(ki[i], cd, perm2, 48);
-+      }
-+
-+      permute(pd1, in, perm3, 64);
-+
-+      for (j = 0; j < 32; j++) {
-+              l[j] = pd1[j];
-+              r[j] = pd1[j + 32];
-+      }
-+
-+      for (i = 0; i < 16; i++) {
-+              char *er;  /* er[48]  */
-+              char *erk; /* erk[48] */
-+              char b[8][6];
-+              char *cb;  /* cb[32]  */
-+              char *pcb; /* pcb[32] */
-+              char *r2;  /* r2[32]  */
-+
-+              er = kmalloc(48+48+32+32+32, GFP_KERNEL);
-+              if(er == NULL) {
-+                      kfree(pk1);
-+                      return;
-+              }
-+              erk = er+48;
-+              cb  = erk+48;
-+              pcb = cb+32;
-+              r2  = pcb+32;
-+
-+              permute(er, r, perm4, 48);
-+
-+              xor(erk, er, ki[forw ? i : 15 - i], 48);
-+
-+              for (j = 0; j < 8; j++)
-+                      for (k = 0; k < 6; k++)
-+                              b[j][k] = erk[j * 6 + k];
-+
-+              for (j = 0; j < 8; j++) {
-+                      int m, n;
-+                      m = (b[j][0] << 1) | b[j][5];
-+
-+                      n = (b[j][1] << 3) | (b[j][2] << 2) | (b[j][3] <<
-+                                                             1) | b[j][4];
-+
-+                      for (k = 0; k < 4; k++)
-+                              b[j][k] =
-+                                  (sbox[j][m][n] & (1 << (3 - k))) ? 1 : 0;
-+              }
-+
-+              for (j = 0; j < 8; j++)
-+                      for (k = 0; k < 4; k++)
-+                              cb[j * 4 + k] = b[j][k];
-+              permute(pcb, cb, perm5, 32);
-+
-+              xor(r2, l, pcb, 32);
-+
-+              for (j = 0; j < 32; j++)
-+                      l[j] = r[j];
-+
-+              for (j = 0; j < 32; j++)
-+                      r[j] = r2[j];
-+
-+              kfree(er);
-+      }
-+
-+      concat(rl, r, l, 32, 32);
-+
-+      permute(out, rl, perm6, 64);
-+      kfree(pk1);
-+}
-+
-+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 void
-+smbhash(unsigned char *out, unsigned char *in, unsigned char *key, int forw)
-+{
-+      int i;
-+      char *outb; /* outb[64] */
-+      char *inb;  /* inb[64]  */
-+      char *keyb; /* keyb[64] */
-+      unsigned char key2[8];
-+
-+      outb = kmalloc(64 * 3,GFP_KERNEL);
-+      if(outb == NULL)
-+              return;
-+
-+      inb  = outb + 64;
-+      keyb = inb +  64;
-+
-+      str_to_key(key, key2);
-+
-+      for (i = 0; i < 64; i++) {
-+              inb[i] = (in[i / 8] & (1 << (7 - (i % 8)))) ? 1 : 0;
-+              keyb[i] = (key2[i / 8] & (1 << (7 - (i % 8)))) ? 1 : 0;
-+              outb[i] = 0;
-+      }
-+
-+      dohash(outb, inb, keyb, forw);
-+
-+      for (i = 0; i < 8; i++) {
-+              out[i] = 0;
-+      }
-+
-+      for (i = 0; i < 64; i++) {
-+              if (outb[i])
-+                      out[i / 8] |= (1 << (7 - (i % 8)));
-+      }
-+      kfree(outb);
-+}
-+
-+void
-+E_P16(unsigned char *p14, unsigned char *p16)
-+{
-+      unsigned char sp8[8] =
-+          { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
-+      smbhash(p16, sp8, p14, 1);
-+      smbhash(p16 + 8, sp8, p14 + 7, 1);
-+}
-+
-+void
-+E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24)
-+{
-+      smbhash(p24, c8, p21, 1);
-+      smbhash(p24 + 8, c8, p21 + 7, 1);
-+      smbhash(p24 + 16, c8, p21 + 14, 1);
-+}
-+
-+void
-+D_P16(unsigned char *p14, unsigned char *in, unsigned char *out)
-+{
-+      smbhash(out, in, p14, 0);
-+      smbhash(out + 8, in + 8, p14 + 7, 0);
-+}
-+
-+void
-+E_old_pw_hash(unsigned char *p14, unsigned char *in, unsigned char *out)
-+{
-+      smbhash(out, in, p14, 1);
-+      smbhash(out + 8, in + 8, p14 + 7, 1);
-+}
-+
-+void
-+cred_hash1(unsigned char *out, unsigned char *in, unsigned char *key)
-+{
-+      unsigned char buf[8];
-+
-+      smbhash(buf, in, key, 1);
-+      smbhash(out, buf, key + 9, 1);
-+}
-+
-+void
-+cred_hash2(unsigned char *out, unsigned char *in, unsigned char *key)
-+{
-+      unsigned char buf[8];
-+      static unsigned char key2[8];
-+
-+      smbhash(buf, in, key, 1);
-+      key2[0] = key[7];
-+      smbhash(out, buf, key2, 1);
-+}
-+
-+void
-+cred_hash3(unsigned char *out, unsigned char *in, unsigned char *key, int forw)
-+{
-+      static unsigned char key2[8];
-+
-+      smbhash(out, in, key, forw);
-+      key2[0] = key[7];
-+      smbhash(out + 8, in + 8, key2, forw);
-+}
---- /dev/null
-+++ b/fs/cifs/smbencrypt.c
-@@ -0,0 +1,295 @@
-+/* 
-+   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/fs.h>
-+#include <linux/string.h>
-+#include <linux/kernel.h>
-+#include <linux/random.h>
-+#include "cifs_unicode.h"
-+#include "cifspdu.h"
-+#include "md5.h"
-+#include "cifs_debug.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)))
-+
-+/*The following definitions come from  lib/md4.c  */
-+
-+void mdfour(unsigned char *out, unsigned char *in, int n);
-+
-+/*The following definitions come from  libsmb/smbdes.c  */
-+
-+void E_P16(unsigned char *p14, unsigned char *p16);
-+void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24);
-+void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out);
-+void E_old_pw_hash(unsigned char *p14, unsigned char *in, unsigned char *out);
-+void cred_hash1(unsigned char *out, unsigned char *in, unsigned char *key);
-+void cred_hash2(unsigned char *out, unsigned char *in, unsigned char *key);
-+void cred_hash3(unsigned char *out, unsigned char *in, unsigned char *key,
-+              int forw);
-+
-+/*The following definitions come from  libsmb/smbencrypt.c  */
-+
-+void SMBencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24);
-+void E_md4hash(const unsigned char *passwd, unsigned char *p16);
-+void nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]);
-+void SMBOWFencrypt(unsigned char passwd[16], unsigned char *c8,
-+                 unsigned char p24[24]);
-+void NTLMSSPOWFencrypt(unsigned char passwd[8],
-+                     unsigned char *ntlmchalresp, unsigned char p24[24]);
-+void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24);
-+int decode_pw_buffer(char in_buffer[516], char *new_pwrd,
-+                   int new_pwrd_size, __u32 * new_pw_len);
-+
-+/*
-+   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 */
-+void
-+SMBencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24)
-+{
-+      unsigned char p14[15], p21[21];
-+
-+      memset(p21, '\0', 21);
-+      memset(p14, '\0', 14);
-+      strncpy((char *) p14, (char *) passwd, 14);
-+
-+/*    strupper((char *)p14); *//* BB at least uppercase the easy range */
-+      E_P16(p14, p21);
-+
-+      SMBOWFencrypt(p21, c8, p24);
-+      
-+      memset(p14,0,15);
-+      memset(p21,0,21);
-+}
-+
-+/* Routines for Windows NT MD4 Hash functions. */
-+static int
-+_my_wcslen(__u16 * str)
-+{
-+      int len = 0;
-+      while (*str++ != 0)
-+              len++;
-+      return len;
-+}
-+
-+/*
-+ * Convert a string into an NT UNICODE string.
-+ * Note that regardless of processor type 
-+ * this must be in intel (little-endian)
-+ * format.
-+ */
-+
-+static int
-+_my_mbstowcs(__u16 * dst, const unsigned char *src, int len)
-+{                             /* not a very good conversion routine - change/fix */
-+      int i;
-+      __u16 val;
-+
-+      for (i = 0; i < len; i++) {
-+              val = *src;
-+              SSVAL(dst, 0, val);
-+              dst++;
-+              src++;
-+              if (val == 0)
-+                      break;
-+      }
-+      return i;
-+}
-+
-+/* 
-+ * Creates the MD4 Hash of the users password in NT UNICODE.
-+ */
-+
-+void
-+E_md4hash(const unsigned char *passwd, unsigned char *p16)
-+{
-+      int len;
-+      __u16 wpwd[129];
-+
-+      /* Password cannot be longer than 128 characters */
-+      if(passwd) {
-+              len = strlen((char *) passwd);
-+              if (len > 128) {
-+                      len = 128;
-+              }
-+              /* Password must be converted to NT unicode */
-+              _my_mbstowcs(wpwd, passwd, len);
-+      } else
-+              len = 0;
-+
-+      wpwd[len] = 0;  /* Ensure string is null terminated */
-+      /* Calculate length in bytes */
-+      len = _my_wcslen(wpwd) * sizeof (__u16);
-+
-+      mdfour(p16, (unsigned char *) wpwd, len);
-+      memset(wpwd,0,129 * 2);
-+}
-+
-+/* Does both the NT and LM owfs of a user's password */
-+void
-+nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16])
-+{
-+      char passwd[514];
-+
-+      memset(passwd, '\0', 514);
-+      if (strlen(pwd) < 513)
-+              strcpy(passwd, pwd);
-+      else
-+              memcpy(passwd, pwd, 512);
-+      /* Calculate the MD4 hash (NT compatible) of the password */
-+      memset(nt_p16, '\0', 16);
-+      E_md4hash(passwd, nt_p16);
-+
-+      /* Mangle the passwords into Lanman format */
-+      passwd[14] = '\0';
-+/*    strupper(passwd); */
-+
-+      /* Calculate the SMB (lanman) hash functions of the password */
-+
-+      memset(p16, '\0', 16);
-+      E_P16((unsigned char *) passwd, (unsigned char *) p16);
-+
-+      /* clear out local copy of user's password (just being paranoid). */
-+      memset(passwd, '\0', sizeof (passwd));
-+}
-+
-+/* Does the NTLMv2 owfs of a user's password */
-+void
-+ntv2_owf_gen(const unsigned char owf[16], const char *user_n,
-+              const char *domain_n, unsigned char kr_buf[16],
-+              const struct nls_table *nls_codepage)
-+{
-+      wchar_t * user_u;
-+      wchar_t * dom_u;
-+      int user_l, domain_l;
-+      struct HMACMD5Context ctx;
-+
-+      /* might as well do one alloc to hold both (user_u and dom_u) */
-+      user_u = kmalloc(2048 * sizeof(wchar_t),GFP_KERNEL); 
-+      if(user_u == NULL)
-+              return;
-+      dom_u = user_u + 1024;
-+    
-+      /* push_ucs2(NULL, user_u, user_n, (user_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER);
-+         push_ucs2(NULL, dom_u, domain_n, (domain_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); */
-+
-+      /* BB user and domain may need to be uppercased */
-+      user_l = cifs_strtoUCS(user_u, user_n, 511, nls_codepage);
-+      domain_l = cifs_strtoUCS(dom_u, domain_n, 511, nls_codepage);
-+
-+      user_l++;               /* trailing null */
-+      domain_l++;
-+
-+      hmac_md5_init_limK_to_64(owf, 16, &ctx);
-+      hmac_md5_update((const unsigned char *) user_u, user_l * 2, &ctx);
-+      hmac_md5_update((const unsigned char *) dom_u, domain_l * 2, &ctx);
-+      hmac_md5_final(kr_buf, &ctx);
-+
-+      kfree(user_u);
-+}
-+
-+/* Does the des encryption from the NT or LM MD4 hash. */
-+void
-+SMBOWFencrypt(unsigned char passwd[16], unsigned char *c8,
-+            unsigned char p24[24])
-+{
-+      unsigned char p21[21];
-+
-+      memset(p21, '\0', 21);
-+
-+      memcpy(p21, passwd, 16);
-+      E_P24(p21, c8, p24);
-+}
-+
-+/* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */
-+void
-+NTLMSSPOWFencrypt(unsigned char passwd[8],
-+                unsigned char *ntlmchalresp, unsigned char p24[24])
-+{
-+      unsigned char p21[21];
-+
-+      memset(p21, '\0', 21);
-+      memcpy(p21, passwd, 8);
-+      memset(p21 + 8, 0xbd, 8);
-+
-+      E_P24(p21, ntlmchalresp, p24);
-+}
-+
-+/* Does the NT MD4 hash then des encryption. */
-+
-+void
-+SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24)
-+{
-+      unsigned char p21[21];
-+
-+      memset(p21, '\0', 21);
-+
-+      E_md4hash(passwd, p21);
-+      SMBOWFencrypt(p21, c8, p24);
-+}
-+
-+/* Does the md5 encryption from the NT hash for NTLMv2. */
-+void
-+SMBOWFencrypt_ntv2(const unsigned char kr[16],
-+                   const struct data_blob * srv_chal,
-+                   const struct data_blob * cli_chal, unsigned char resp_buf[16])
-+{
-+        struct HMACMD5Context ctx;
-+
-+        hmac_md5_init_limK_to_64(kr, 16, &ctx);
-+        hmac_md5_update(srv_chal->data, srv_chal->length, &ctx);
-+        hmac_md5_update(cli_chal->data, cli_chal->length, &ctx);
-+        hmac_md5_final(resp_buf, &ctx);
-+}
-+
-+void
-+SMBsesskeygen_ntv2(const unsigned char kr[16],
-+                 const unsigned char *nt_resp, __u8 sess_key[16])
-+{
-+      struct HMACMD5Context ctx;
-+
-+      hmac_md5_init_limK_to_64(kr, 16, &ctx);
-+      hmac_md5_update(nt_resp, 16, &ctx);
-+      hmac_md5_final((unsigned char *) sess_key, &ctx);
-+}
-+
-+void
-+SMBsesskeygen_ntv1(const unsigned char kr[16],
-+                 const unsigned char *nt_resp, __u8 sess_key[16])
-+{
-+      mdfour((unsigned char *) sess_key, (unsigned char *) kr, 16);
-+}
---- /dev/null
-+++ b/fs/cifs/smberr.c
-@@ -0,0 +1,240 @@
-+/* 
-+   Unix SMB/Netbios implementation.
-+   Version 1.9.
-+   Copyright (C) Andrew Tridgell 1998
-+   Copyright (C) Steve French (sfrench@us.ibm.com) 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-+*/
-+include "smberr.h"
-+#define NO_SYSLOG
-+/* error code stuff - put together by Merik Karman
-+   merik@blackadder.dsh.oz.au */
-+    typedef const struct {
-+      char *name;
-+      int code;
-+      char *message;
-+      int posix_code;
-+} err_code_struct;
-+
-+/* Dos Error Messages */
-+err_code_struct dos_msgs[] = {
-+      {"ERRbadfunc", ERRbadfunc, "Invalid function.", -EINVAL},
-+      {"ERRbadfile", ERRbadfile, "File not found.", -ENOENT},
-+      {"ERRbadpath", ERRbadpath, "Directory invalid.", -ENOENT},
-+      {"ERRnofids", ERRnofids, "No file descriptors available", -EMFILE},
-+      {"ERRnoaccess", ERRnoaccess, "Access denied.", -EACCES},
-+      {"ERRbadfid", ERRbadfid, "Invalid file handle.", -EBADF},
-+      {"ERRbadmcb", 7, "Memory control blocks destroyed.", -EIO},
-+      {"ERRnomem", ERRnomem,
-+       "Insufficient server memory to perform the requested function.",
-+       -ENOMEM},
-+      {"ERRbadmem", ERRbadmem, "Invalid memory block address.", -EFAULT},
-+      {"ERRbadenv", ERRbadenv, "Invalid environment.", -EFAULT},
-+      {"ERRbadformat", 11, "Invalid format.", -EINVAL},
-+      {"ERRbadaccess", ERRbadaccess, "Invalid open mode." - EACCES},
-+      {"ERRbaddata", ERRbaddata, "Invalid data.", -EIO},
-+      {"ERR", ERRres, "reserved.", -EIO},
-+      {"ERRbaddrive", ERRbaddrive, "Invalid drive specified.", -ENXIO},
-+      {"ERRremcd", ERRremcd,
-+       "A Delete Directory request attempted  to  remove  the  server's  current directory.",
-+       -EIO},
-+      {"ERRdiffdevice", ERRdiffdevice, "Not same device.", -EXDEV},
-+      {"ERRnofiles", ERRnofiles, "A File Search command can find no more files matching the specified criteria.", -ENOENT},   /* Note: must map to zero manually in some places such as readdir */
-+      {"ERRbadshare", ERRbadshare,
-+       "The sharing mode specified for an Open conflicts with existing  FIDs  on the file.",
-+       -EXTBSY},
-+      {"ERRlock", ERRlock,
-+       "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.",
-+       -EACCES},
-+      {"ERRunsup", ERRunsup, "The operation is unsupported", -EINVAL},
-+      {"ERRnosuchshare", ERRnosuchshare,
-+       "You specified an invalid share name", -ENXIO},
-+      {"ERRfilexists", ERRfilexists,
-+       "The file named in a Create Directory, Make  New  File  or  Link  request already exists.",
-+       -EEXIST},
-+      {"ERRinvalidname", ERRinvalidname, "Invalid name", -ENOENT},
-+      {"ERRdiskfull", ERRdiskfull, "Disk full", -ENOSPC}
-+
-+      {"ERRmoredata", ERRmoredata,
-+       "There is more data to be returned.",},
-+      {"ERRinvgroup", 2455, "Invalid workgroup (try the -W option)"},
-+      {NULL, -1, NULL, -EIO}
-+};
-+
-+/* Server Error Messages */
-+err_code_struct server_msgs[] = {
-+      {"ERRerror", 1, "Non-specific error code."},
-+      {"ERRbadpw", 2,
-+       "Bad password - name/password pair in a Tree Connect or Session Setup are invalid."},
-+      {"ERRbadtype", 3, "reserved."},
-+      {"ERRaccess", 4,
-+       "The requester does not have  the  necessary  access  rights  within  the specified  context for the requested function. The context is defined by the TID or the UID."},
-+      {"ERRinvnid", 5,
-+       "The tree ID (TID) specified in a command was invalid."},
-+      {"ERRinvnetname", 6, "Invalid network name in tree connect."},
-+      {"ERRinvdevice", 7,
-+       "Invalid device - printer request made to non-printer connection or  non-printer request made to printer connection."},
-+      {"ERRqfull", 49,
-+       "Print queue full (files) -- returned by open print file."},
-+      {"ERRqtoobig", 50, "Print queue full -- no space."},
-+      {"ERRqeof", 51, "EOF on print queue dump."},
-+      {"ERRinvpfid", 52, "Invalid print file FID."},
-+      {"ERRsmbcmd", 64,
-+       "The server did not recognize the command received."},
-+      {"ERRsrverror", 65,
-+       "The server encountered an internal error, e.g., system file unavailable."},
-+      {"ERRfilespecs", 67,
-+       "The file handle (FID) and pathname parameters contained an invalid  combination of values."},
-+      {"ERRreserved", 68, "reserved."},
-+      {"ERRbadpermits", 69,
-+       "The access permissions specified for a file or directory are not a valid combination.  The server cannot set the requested attribute."},
-+      {"ERRreserved", 70, "reserved."},
-+      {"ERRsetattrmode", 71,
-+       "The attribute mode in the Set File Attribute request is invalid."},
-+      {"ERRpaused", 81, "Server is paused."},
-+      {"ERRmsgoff", 82, "Not receiving messages."},
-+      {"ERRnoroom", 83, "No room to buffer message."},
-+      {"ERRrmuns", 87, "Too many remote user names."},
-+      {"ERRtimeout", 88, "Operation timed out."},
-+      {"ERRnoresource", 89,
-+       "No resources currently available for request."},
-+      {"ERRtoomanyuids", 90, "Too many UIDs active on this session."},
-+      {"ERRbaduid", 91,
-+       "The UID is not known as a valid ID on this session."},
-+      {"ERRusempx", 250, "Temp unable to support Raw, use MPX mode."},
-+      {"ERRusestd", 251,
-+       "Temp unable to support Raw, use standard read/write."},
-+      {"ERRcontmpx", 252, "Continue in MPX mode."},
-+      {"ERRreserved", 253, "reserved."},
-+      {"ERRreserved", 254, "reserved."},
-+      {"ERRnosupport", 0xFFFF, "Function not supported."},
-+      {NULL, -1, NULL}
-+};
-+
-+/* Hard Error Messages */
-+err_code_struct hard_msgs[] = {
-+      {"ERRnowrite", 19,
-+       "Attempt to write on write-protected diskette."},
-+      {"ERRbadunit", 20, "Unknown unit."},
-+      {"ERRnotready", 21, "Drive not ready."},
-+      {"ERRbadcmd", 22, "Unknown command."},
-+      {"ERRdata", 23, "Data error (CRC)."},
-+      {"ERRbadreq", 24, "Bad request structure length."},
-+      {"ERRseek", 25, "Seek error."},
-+      {"ERRbadmedia", 26, "Unknown media type."},
-+      {"ERRbadsector", 27, "Sector not found."},
-+      {"ERRnopaper", 28, "Printer out of paper."},
-+      {"ERRwrite", 29, "Write fault."},
-+      {"ERRread", 30, "Read fault."},
-+      {"ERRgeneral", 31, "General failure."},
-+      {"ERRbadshare", 32, "An open conflicts with an existing open."},
-+      {"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."},
-+      {"ERRwrongdisk", 34, "The wrong disk was found in a drive."},
-+      {"ERRFCBUnavail", 35, "No FCBs are available to process request."},
-+      {"ERRsharebufexc", 36, "A sharing buffer has been exceeded."},
-+      {NULL, -1, NULL}
-+};
-+
-+
-+const struct {
-+      int code;
-+      char *class;
-+      err_code_struct *err_msgs;
-+} err_classes[] = {
-+      {
-+      0, "SUCCESS", NULL}, {
-+      0x01, "ERRDOS", dos_msgs}, {
-+      0x02, "ERRSRV", server_msgs}, {
-+      0x03, "ERRHRD", hard_msgs}, {
-+      0x04, "ERRXOS", NULL}, {
-+      0xE1, "ERRRMX1", NULL}, {
-+      0xE2, "ERRRMX2", NULL}, {
-+      0xE3, "ERRRMX3", NULL}, {
-+      0xFF, "ERRCMD", NULL}, {
-+-1, NULL, NULL}};
-+
-+
-+/****************************************************************************
-+return a SMB error string from a SMB buffer
-+****************************************************************************/
-+char *smb_dos_errstr(char *inbuf)
-+{
-+      static pstring ret;
-+      int class = CVAL(inbuf, smb_rcls);
-+      int num = SVAL(inbuf, smb_err);
-+      int i, j;
-+
-+      for (i = 0; err_classes[i].class; i++)
-+              if (err_classes[i].code == class) {
-+                      if (err_classes[i].err_msgs) {
-+                              err_code_struct *err =
-+                                  err_classes[i].err_msgs;
-+                              for (j = 0; err[j].name; j++)
-+                                      if (num == err[j].code) {
-+                                              if (DEBUGLEVEL > 0)
-+                                                      slprintf(ret,
-+                                                               sizeof
-+                                                               (ret) - 1,
-+                                                               "%s - %s (%s)",
-+                                                               err_classes
-+                                                               [i].class,
-+                                                               err[j].
-+                                                               name,
-+                                                               err[j].
-+                                                               message);
-+                                              else
-+                                                      slprintf(ret,
-+                                                               sizeof
-+                                                               (ret) - 1,
-+                                                               "%s - %s",
-+                                                               err_classes
-+                                                               [i].class,
-+                                                               err[j].
-+                                                               name);
-+                                              return ret;
-+                                      }
-+                      }
-+
-+                      slprintf(ret, sizeof(ret) - 1, "%s - %d",
-+                               err_classes[i].class, num);
-+                      return ret;
-+              }
-+
-+      slprintf(ret, sizeof(ret) - 1, "Error: Unknown error (%d,%d)",
-+               class, num);
-+      return (ret);
-+}
-+
-+
-+/*****************************************************************************
-+ returns an WERROR error message.
-+ *****************************************************************************/
-+char *werror_str(WERROR status)
-+{
-+      static fstring msg;
-+      slprintf(msg, sizeof(msg), "WIN32 code 0x%08x", W_ERROR_V(status));
-+      return msg;
-+}
-+
-+
-+/*****************************************************************************
-+map a unix errno to a win32 error
-+ *****************************************************************************/
-+WERROR map_werror_from_unix(int error)
-+{
-+      NTSTATUS status = map_nt_error_from_unix(error);
-+      return ntstatus_to_werror(status);
-+}
---- /dev/null
-+++ b/fs/cifs/smberr.h
-@@ -0,0 +1,113 @@
-+/*
-+ *   fs/cifs/smberr.h
-+ *
-+ *   Copyright (c) International Business Machines  Corp., 2002
-+ *   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 0             /* 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 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 ERRdirnotempty 145
-+#define ERRnotlocked   158
-+#define ERRalreadyexists 183
-+#define ERRbadpipe 230
-+#define ERRpipebusy 231
-+#define ERRpipeclosing 232
-+#define ERRnotconnected 233
-+#define ERRmoredata    234
-+#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. */
-+
-+/* 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 ERRaccountexpired 2239
-+#define ERRbadclient      2240
-+#define ERRbadLogonTime   2241
-+#define ERRpasswordExpired 2242
-+#define ERRnetlogonNotStarted 2455
-+#define ERRnosupport       0xFFFF
---- /dev/null
-+++ b/fs/cifs/TODO
-@@ -0,0 +1,106 @@
-+version 1.16 May 27, 2004
-+
-+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 for chmod/chgrp/chown so
-+these can be supported for Windows servers
-+
-+b) Better pam/winbind integration
-+
-+c) multi-user mounts - multiplexed sessionsetups over single vc
-+(ie tcp session) - prettying up needed
-+
-+d) Kerberos/SPNEGO session setup support - (started)
-+
-+e) NTLMv2 authentication (mostly implemented)
-+
-+f) MD5-HMAC signing SMB PDUs when SPNEGO style SessionSetup 
-+used (Kerberos or NTLMSSP). Signing alreadyimplemented for NTLM
-+and raw NTLMSSP already. This is important when enabling
-+extended security and mounting to Windows 2003 Servers
-+
-+f) Directory entry caching relies on a 1 second timer, rather than 
-+using FindNotify or equivalent.  - (started)
-+
-+g) A few byte range testcases fail due to POSIX vs. Windows/CIFS
-+style byte range lock differences
-+
-+h) quota support
-+
-+i) support for the Linux 2.5 kernel new feature get_xattr and set_xattr
-+which will allow us to expose dos attributes as well as real
-+ACLs. This support has been started in the current code, but is
-+ifdeffed out.
-+
-+k) finish writepages support (multi-page write behind for improved
-+performance) and syncpage
-+
-+l) hook lower into the sockets api (as NFS/SunRPC does) to avoid the
-+extra copy in/out of the socket buffers in some cases.
-+
-+m) finish support for IPv6.  This is mostly complete but
-+needs a simple inet_pton like function to convert ipv6
-+addresses in string representation.
-+
-+o) 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).
-+
-+p) Improve performance of readpages by sending more than one read
-+at a time when 8 pages or more are requested.  Evaluate whether
-+reads larger than 16K would be helpful.
-+
-+q) For support of Windows9x/98 we need to retry failed mounts
-+to *SMBSERVER (default server name) with the uppercase hostname
-+in the RFC1001 session_init request.
-+
-+r) Add Extended Attributed support (for storing UID/GID info
-+to Windows servers)
-+
-+s) Finish fcntl D_NOTIFY support so kde and gnome file list windows
-+will autorefresh
-+
-+t) Add GUI tool to configure /proc/fs/cifs settings and for display of
-+the CIFS statistics
-+
-+KNOWN BUGS (updated May 27, 2004)
-+====================================
-+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 but Samba has a bug currently handling
-+symlink text beginning with slash
-+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) debug connectathon lock test case 10 which fails against
-+Samba (may be unmappable due to POSIX to Windows lock model
-+differences but worth investigating).  Also debug Samba to 
-+see why lock test case 7 takes longer to complete to Samba
-+than to Windows.
-+
-+Misc testing to do
-+==================
-+1) check out max path names and max path name components against various server
-+types. Try nested symlinks. 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.
-+
-+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 the recently added NT4 support against various
-+NT4 service pack levels.
-+
---- /dev/null
-+++ b/fs/cifs/transport.c
-@@ -0,0 +1,434 @@
-+/*
-+ *   fs/cifs/transport.c
-+ *
-+ *   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.
-+ *
-+ *   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/wait.h>
-+#include <linux/net.h>
-+#include <linux/version.h>
-+#include <asm/uaccess.h>
-+#include <asm/processor.h>
-+#include "cifspdu.h"
-+#include "cifsglob.h"
-+#include "cifsproto.h"
-+#include "cifs_debug.h"
-+
-+extern kmem_cache_t *cifs_mid_cachep;
-+extern kmem_cache_t *cifs_oplock_cachep;
-+
-+struct mid_q_entry *
-+AllocMidQEntry(struct smb_hdr *smb_buffer, struct cifsSesInfo *ses)
-+{
-+      struct mid_q_entry *temp;
-+
-+      if (ses == NULL) {
-+              cERROR(1, ("Null session passed in to AllocMidQEntry "));
-+              return NULL;
-+      }
-+      if (ses->server == NULL) {
-+              cERROR(1, ("Null TCP session in AllocMidQEntry"));
-+              return NULL;
-+      }
-+      
-+      temp = (struct mid_q_entry *) kmem_cache_alloc(cifs_mid_cachep,
-+                                                     SLAB_KERNEL);
-+      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 = smb_buffer->Command;
-+              cFYI(1, ("For smb_command %d", temp->command));
-+              do_gettimeofday(&temp->when_sent);
-+              temp->ses = ses;
-+              temp->tsk = current;
-+      }
-+
-+      spin_lock(&GlobalMid_Lock);
-+      list_add_tail(&temp->qhead, &ses->server->pending_mid_q);
-+      atomic_inc(&midCount);
-+      temp->midState = MID_REQUEST_ALLOCATED;
-+      spin_unlock(&GlobalMid_Lock);
-+      return temp;
-+}
-+
-+void
-+DeleteMidQEntry(struct mid_q_entry *midEntry)
-+{
-+      spin_lock(&GlobalMid_Lock);
-+      midEntry->midState = MID_FREE;
-+      list_del(&midEntry->qhead);
-+      atomic_dec(&midCount);
-+      spin_unlock(&GlobalMid_Lock);
-+      cifs_buf_release(midEntry->resp_buf);
-+      kmem_cache_free(cifs_mid_cachep, midEntry);
-+}
-+
-+struct oplock_q_entry *
-+AllocOplockQEntry(struct inode * pinode, __u16 fid, struct cifsTconInfo * tcon)
-+{
-+      struct oplock_q_entry *temp;
-+      if ((pinode== NULL) || (tcon == NULL)) {
-+              cERROR(1, ("Null parms passed to AllocOplockQEntry"));
-+              return NULL;
-+      }
-+      temp = (struct oplock_q_entry *) kmem_cache_alloc(cifs_oplock_cachep,
-+                                                     SLAB_KERNEL);
-+      if (temp == NULL)
-+              return temp;
-+      else {
-+              temp->pinode = pinode;
-+              temp->tcon = tcon;
-+              temp->netfid = fid;
-+              spin_lock(&GlobalMid_Lock);
-+              list_add_tail(&temp->qhead, &GlobalOplock_Q);
-+              spin_unlock(&GlobalMid_Lock);
-+      }
-+      return temp;
-+
-+}
-+
-+void DeleteOplockQEntry(struct oplock_q_entry * oplockEntry)
-+{
-+      spin_lock(&GlobalMid_Lock); 
-+    /* should we check if list empty first? */
-+      list_del(&oplockEntry->qhead);
-+      spin_unlock(&GlobalMid_Lock);
-+      kmem_cache_free(cifs_oplock_cachep, oplockEntry);
-+}
-+
-+int
-+smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer,
-+       unsigned int smb_buf_length, struct sockaddr *sin)
-+{
-+      int rc = 0;
-+      int i = 0;
-+      struct msghdr smb_msg;
-+      struct iovec iov;
-+      mm_segment_t temp_fs;
-+
-+      if(ssocket == NULL)
-+              return -ENOTSOCK; /* BB eventually add reconnect code here */
-+      iov.iov_base = smb_buffer;
-+      iov.iov_len = smb_buf_length + 4;
-+
-+      smb_msg.msg_name = sin;
-+      smb_msg.msg_namelen = sizeof (struct sockaddr);
-+      smb_msg.msg_iov = &iov;
-+      smb_msg.msg_iovlen = 1;
-+      smb_msg.msg_control = NULL;
-+      smb_msg.msg_controllen = 0;
-+      smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; /* BB add more flags?*/
-+
-+      /* smb header is converted in header_assemble. bcc and rest of SMB word
-+         area, and byte area if necessary, is converted to littleendian in 
-+         cifssmb.c and RFC1001 len is converted to bigendian in smb_send 
-+         Flags2 is converted in SendReceive */
-+
-+      smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length);
-+      cFYI(1, ("Sending smb of length %d ", smb_buf_length));
-+      dump_smb(smb_buffer, smb_buf_length + 4);
-+
-+      temp_fs = get_fs();     /* we must turn off socket api parm checking */
-+      set_fs(get_ds());
-+      while(iov.iov_len > 0) {
-+              rc = sock_sendmsg(ssocket, &smb_msg, smb_buf_length + 4);
-+              if ((rc == -ENOSPC) || (rc == -EAGAIN)) {
-+                      i++;
-+                      if(i > 60) {
-+                              cERROR(1,
-+                                 ("sends on sock %p stuck for 30 seconds",
-+                                  ssocket));
-+                              rc = -EAGAIN;
-+                              break;
-+                      }
-+                      set_current_state(TASK_INTERRUPTIBLE);
-+                      schedule_timeout(HZ/2);
-+                      continue;
-+              }
-+              if (rc < 0) 
-+                      break;
-+              iov.iov_base += rc;
-+              iov.iov_len -= rc;
-+      }
-+      set_fs(temp_fs);
-+
-+      if (rc < 0) {
-+              cERROR(1,("Error %d sending data on socket to server.", rc));
-+      } else {
-+              rc = 0;
-+      }
-+
-+      return rc;
-+}
-+
-+int
-+SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
-+          struct smb_hdr *in_buf, struct smb_hdr *out_buf,
-+          int *pbytes_returned, const int long_op)
-+{
-+      int rc = 0;
-+      unsigned int receive_len;
-+      long timeout;
-+      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;
-+      }
-+
-+      /* 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(long_op == -1) {
-+              /* oplock breaks must not be held up */
-+              atomic_inc(&ses->server->inFlight);
-+      } else {
-+              spin_lock(&GlobalMid_Lock); 
-+              while(1) {        
-+                      if(atomic_read(&ses->server->inFlight) >= CIFS_MAX_REQ){
-+                              spin_unlock(&GlobalMid_Lock);
-+                              wait_event(ses->server->request_q,
-+                                      atomic_read(&ses->server->inFlight)
-+                                       < CIFS_MAX_REQ);
-+                              spin_lock(&GlobalMid_Lock);
-+                      } else {
-+                              if(ses->server->tcpStatus == CifsExiting) {
-+                                      spin_unlock(&GlobalMid_Lock);
-+                                      return -ENOENT;
-+                              }
-+
-+                      /* can not count locking commands against total since
-+                         they are allowed to block on server */
-+                                      
-+                              if(long_op < 3) {
-+                              /* update # of requests on the wire to server */
-+                                      atomic_inc(&ses->server->inFlight);
-+                              }
-+                              spin_unlock(&GlobalMid_Lock);
-+                              break;
-+                      }
-+              }
-+      }
-+      /* 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 */
-+
-+      down(&ses->server->tcpSem); 
-+
-+      if (ses->server->tcpStatus == CifsExiting) {
-+              rc = -ENOENT;
-+              goto out_unlock;
-+      } else if (ses->server->tcpStatus == CifsNeedReconnect) {
-+              cFYI(1,("tcp session dead - return to caller to retry"));
-+              rc = -EAGAIN;
-+              goto out_unlock;
-+      } else 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)) {
-+                      rc = -EAGAIN;
-+                      goto out_unlock;
-+              } /* else ok - we are setting up session */
-+      }
-+      midQ = AllocMidQEntry(in_buf, ses);
-+      if (midQ == NULL) {
-+              up(&ses->server->tcpSem);
-+              /* If not lock req, update # of requests on wire to server */
-+              if(long_op < 3) {
-+                      atomic_dec(&ses->server->inFlight); 
-+                      wake_up(&ses->server->request_q);
-+              }
-+              return -ENOMEM;
-+      }
-+
-+      if (in_buf->smb_buf_length > CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE - 4) {
-+              up(&ses->server->tcpSem);
-+              cERROR(1,
-+                     ("Illegal length, greater than maximum frame, %d ",
-+                      in_buf->smb_buf_length));
-+              DeleteMidQEntry(midQ);
-+              /* If not lock req, update # of requests on wire to server */
-+              if(long_op < 3) {
-+                      atomic_dec(&ses->server->inFlight); 
-+                      wake_up(&ses->server->request_q);
-+              }
-+              return -EIO;
-+      }
-+
-+      if (in_buf->smb_buf_length > 12)
-+              in_buf->Flags2 = cpu_to_le16(in_buf->Flags2);
-+      
-+      rc = cifs_sign_smb(in_buf, ses, &midQ->sequence_number);
-+
-+      midQ->midState = MID_REQUEST_SUBMITTED;
-+      rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
-+                    (struct sockaddr *) &(ses->server->addr.sockAddr));
-+      if(rc < 0) {
-+              DeleteMidQEntry(midQ);
-+              up(&ses->server->tcpSem);
-+              /* If not lock req, update # of requests on wire to server */
-+              if(long_op < 3) {
-+                      atomic_dec(&ses->server->inFlight); 
-+                      wake_up(&ses->server->request_q);
-+              }
-+              return rc;
-+      } else
-+              up(&ses->server->tcpSem);
-+      if (long_op == -1)
-+              goto cifs_no_response_exit;
-+      else if (long_op == 2) /* writes past end of file can take looooong time */
-+              timeout = 300 * HZ;
-+      else if (long_op == 1)
-+              timeout = 45 * HZ; /* should be greater than 
-+                      servers oplock break timeout (about 43 seconds) */
-+      else if (long_op > 2) {
-+              timeout = MAX_SCHEDULE_TIMEOUT;
-+      } else
-+              timeout = 15 * HZ;
-+      /* wait for 15 seconds or until woken up due to response arriving or 
-+         due to last connection to this server being unmounted */
-+      if (signal_pending(current)) {
-+              /* if signal pending do not hold up user for full smb timeout
-+              but we still give response a change to complete */
-+              if(midQ->midState & MID_REQUEST_SUBMITTED) {
-+                      set_current_state(TASK_UNINTERRUPTIBLE);
-+                      timeout = sleep_on_timeout(&ses->server->response_q,2 * HZ);
-+              }
-+      } else { /* using normal timeout */
-+              /* timeout = wait_event_interruptible_timeout(ses->server->response_q,
-+                      (midQ->midState & MID_RESPONSE_RECEIVED) || 
-+                      ((ses->server->tcpStatus != CifsGood) &&
-+                       (ses->server->tcpStatus != CifsNew)),
-+                      timeout); */ 
-+              /* Can not allow user interrupts- wreaks havoc with performance */
-+              if(midQ->midState & MID_REQUEST_SUBMITTED) {
-+                      set_current_state(TASK_UNINTERRUPTIBLE);
-+                      timeout = sleep_on_timeout(&ses->server->response_q,timeout);
-+              }
-+      }
-+    
-+      spin_lock(&GlobalMid_Lock);
-+      if (midQ->resp_buf) {
-+              spin_unlock(&GlobalMid_Lock);
-+              receive_len = be32_to_cpu(midQ->resp_buf->smb_buf_length);
-+      } else {
-+              cERROR(1,("No response buffer"));
-+              if(midQ->midState == MID_REQUEST_SUBMITTED) {
-+                      if(ses->server->tcpStatus == CifsExiting)
-+                              rc = -EHOSTDOWN;
-+                      else {
-+                              ses->server->tcpStatus = CifsNeedReconnect;
-+                              midQ->midState = MID_RETRY_NEEDED;
-+                      }
-+              }
-+
-+              if (rc != -EHOSTDOWN) {
-+                      if(midQ->midState == MID_RETRY_NEEDED) {
-+                              rc = -EAGAIN;
-+                              cFYI(1,("marking request for retry"));
-+                      } else {
-+                              rc = -EIO;
-+                      }
-+              }
-+              spin_unlock(&GlobalMid_Lock);
-+              DeleteMidQEntry(midQ);
-+              /* If not lock req, update # of requests on wire to server */
-+              if(long_op < 3) {
-+                      atomic_dec(&ses->server->inFlight); 
-+                      wake_up(&ses->server->request_q);
-+              }
-+              return rc;
-+      }
-+  
-+      if (receive_len > CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE) {
-+              cERROR(1,
-+                     ("Frame too large received.  Length: %d  Xid: %d",
-+                      receive_len, xid));
-+              rc = -EIO;
-+      } else {                /* rcvd frame is ok */
-+
-+              if (midQ->resp_buf && out_buf
-+                  && (midQ->midState == MID_RESPONSE_RECEIVED)) {
-+                      memcpy(out_buf, midQ->resp_buf,
-+                             receive_len +
-+                             4 /* include 4 byte RFC1001 header */ );
-+
-+                      dump_smb(out_buf, 92);
-+                      /* convert the length into a more usable form */
-+                      out_buf->smb_buf_length =
-+                          be32_to_cpu(out_buf->smb_buf_length);
-+                      if((out_buf->smb_buf_length > 24) &&
-+                         (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))) {
-+                              rc = cifs_verify_signature(out_buf, ses->mac_signing_key,midQ->sequence_number); /* BB fix BB */
-+                              if(rc)
-+                                      cFYI(1,("Unexpected signature received from server"));
-+                      }
-+
-+                      if (out_buf->smb_buf_length > 12)
-+                              out_buf->Flags2 = le16_to_cpu(out_buf->Flags2);
-+                      if (out_buf->smb_buf_length > 28)
-+                              out_buf->Pid = le16_to_cpu(out_buf->Pid);
-+                      if (out_buf->smb_buf_length > 28)
-+                              out_buf->PidHigh =
-+                                  le16_to_cpu(out_buf->PidHigh);
-+
-+                      *pbytes_returned = out_buf->smb_buf_length;
-+
-+                      /* BB special case reconnect tid and reconnect uid here? */
-+                      rc = map_smb_to_linux_error(out_buf);
-+
-+                      /* convert ByteCount if necessary */
-+                      if (receive_len >=
-+                          sizeof (struct smb_hdr) -
-+                          4 /* do not count RFC1001 header */  +
-+                          (2 * out_buf->WordCount) + 2 /* bcc */ )
-+                              BCC(out_buf) = le16_to_cpu(BCC(out_buf));
-+              } else {
-+                      rc = -EIO;
-+                      cFYI(1,("Bad MID state? "));
-+              }
-+      }
-+cifs_no_response_exit:
-+      DeleteMidQEntry(midQ);
-+
-+      if(long_op < 3) {
-+              atomic_dec(&ses->server->inFlight); 
-+              wake_up(&ses->server->request_q);
-+      }
-+
-+      return rc;
-+
-+out_unlock:
-+      up(&ses->server->tcpSem);
-+      /* If not lock req, update # of requests on wire to server */
-+      if(long_op < 3) {
-+              atomic_dec(&ses->server->inFlight); 
-+              wake_up(&ses->server->request_q);
-+      }
-+
-+      return rc;
-+}
---- a/fs/Config.in
-+++ b/fs/Config.in
-@@ -153,6 +153,10 @@ if [ "$CONFIG_NET" = "y" ]; then
-      define_bool CONFIG_LOCKD_V4 y
-    fi
-+   dep_tristate 'CIFS support (advanced network filesystem for Samba, Window and other CIFS compliant servers)' CONFIG_CIFS $CONFIG_INET
-+   dep_mbool '  CIFS statistics' CONFIG_CIFS_STATS $CONFIG_CIFS
-+   dep_mbool '  CIFS POSIX Protocol Extensions' CONFIG_CIFS_POSIX $CONFIG_CIFS
-+
-    dep_tristate 'SMB file system support (to mount Windows shares etc.)' CONFIG_SMB_FS $CONFIG_INET
-    if [ "$CONFIG_SMB_FS" != "n" ]; then
-       bool '  Use a default NLS' CONFIG_SMB_NLS_DEFAULT
---- a/fs/Makefile
-+++ b/fs/Makefile
-@@ -37,6 +37,7 @@ subdir-$(CONFIG_MSDOS_FS)    += msdos
- subdir-$(CONFIG_VFAT_FS)      += vfat
- subdir-$(CONFIG_BFS_FS)               += bfs
- subdir-$(CONFIG_ISO9660_FS)   += isofs
-+subdir-$(CONFIG_CIFS)         += cifs
- subdir-$(CONFIG_DEVFS_FS)     += devfs
- subdir-$(CONFIG_HFSPLUS_FS)   += hfsplus # Before hfs to find wrapped HFS+
- subdir-$(CONFIG_HFS_FS)               += hfs
---- a/fs/nls/Config.in
-+++ b/fs/nls/Config.in
-@@ -11,6 +11,7 @@ fi
- # msdos and Joliet want NLS
- if [ "$CONFIG_JOLIET" = "y" -o "$CONFIG_FAT_FS" != "n" \
-+      -o "$CONFIG_CIFS" != "n" \
-       -o "$CONFIG_NTFS_FS" != "n" -o "$CONFIG_NCPFS_NLS" = "y" \
-       -o "$CONFIG_SMB_NLS" = "y" -o "$CONFIG_JFS_FS" != "n" \
-       -o "$CONFIG_BEFS_FS" != "n" -o "$CONFIG_HFSPLUS_FS" != "n" ]; then