From e7d32311b6f421ea2ee146351ba030880eff5403 Mon Sep 17 00:00:00 2001
From: geos_one <geos_one@6952d904-891a-0410-993b-d76249ca496b>
Date: Fri, 26 Jan 2007 22:34:44 +0000
Subject: [PATCH] Update to novfs 2.0.0

---
 .../net-fs/novell-novfs/ChangeLog             |    11 +-
 .../net-fs/novell-novfs/Manifest              |    39 +-
 .../files/digest-novell-novfs-2.0.0_p2        |     3 +
 .../files/novell-novfs-1.2.0_to_2.0.0.patch   | 32748 ++++++++++++++++
 .../files/novell-novfs-2.0.0-config_h.patch   |    12 +
 ...l-novfs-2.0.0-dont_use_tasklist_lock.patch |    21 +
 ...novell-novfs-2.0.0-generic_file_read.patch |    22 +
 .../files/novell-novfs-2.0.0-i_blksize.patch  |    67 +
 .../novell-novfs-2.0.0-u.generic_ip.patch     |   609 +
 .../novell-novfs/novell-novfs-2.0.0_p2.ebuild |    59 +
 10 files changed, 33586 insertions(+), 5 deletions(-)
 create mode 100644 trunk/novell4gentoo/net-fs/novell-novfs/files/digest-novell-novfs-2.0.0_p2
 create mode 100644 trunk/novell4gentoo/net-fs/novell-novfs/files/novell-novfs-1.2.0_to_2.0.0.patch
 create mode 100644 trunk/novell4gentoo/net-fs/novell-novfs/files/novell-novfs-2.0.0-config_h.patch
 create mode 100644 trunk/novell4gentoo/net-fs/novell-novfs/files/novell-novfs-2.0.0-dont_use_tasklist_lock.patch
 create mode 100644 trunk/novell4gentoo/net-fs/novell-novfs/files/novell-novfs-2.0.0-generic_file_read.patch
 create mode 100644 trunk/novell4gentoo/net-fs/novell-novfs/files/novell-novfs-2.0.0-i_blksize.patch
 create mode 100644 trunk/novell4gentoo/net-fs/novell-novfs/files/novell-novfs-2.0.0-u.generic_ip.patch
 create mode 100644 trunk/novell4gentoo/net-fs/novell-novfs/novell-novfs-2.0.0_p2.ebuild

diff --git a/trunk/novell4gentoo/net-fs/novell-novfs/ChangeLog b/trunk/novell4gentoo/net-fs/novell-novfs/ChangeLog
index d514663d..b02d9350 100644
--- a/trunk/novell4gentoo/net-fs/novell-novfs/ChangeLog
+++ b/trunk/novell4gentoo/net-fs/novell-novfs/ChangeLog
@@ -1,7 +1,16 @@
 # ChangeLog for net-fs/novell-novfs
-# Copyright 1999-2006 Gentoo Foundation; Distributed under the GPL v2
+# Copyright 1999-2007 Gentoo Foundation; Distributed under the GPL v2
 # $Header: $
 
+  26 Jan 2007; Mario Fetka <mario-fetka@gmx.at> 
+  +files/novell-novfs-1.2.0_to_2.0.0.patch,
+  +novell-novfs-2.0.0_p2.ebuild, +files/novell-novfs-2.0.0-config_h.patch,
+  +files/novell-novfs-2.0.0-dont_use_tasklist_lock.patch,
+  +files/novell-novfs-2.0.0-generic_file_read.patch,
+  +files/novell-novfs-2.0.0-i_blksize.patch,
+  +files/novell-novfs-2.0.0-u.generic_ip.patch:
+  Update to novfs 2.0.0
+
   18 Oct 2006; Mario Fetka <mario-fetka@gmx.at>
   -novell-novfs-1.2.0_p17-r1.ebuild, +novell-novfs-1.2.0_p17-r2.ebuild,
   -files/novell-novfs-1.2.0-2.6.17.patch,
diff --git a/trunk/novell4gentoo/net-fs/novell-novfs/Manifest b/trunk/novell4gentoo/net-fs/novell-novfs/Manifest
index 67534a1f..edf81bd6 100644
--- a/trunk/novell4gentoo/net-fs/novell-novfs/Manifest
+++ b/trunk/novell4gentoo/net-fs/novell-novfs/Manifest
@@ -18,15 +18,43 @@ AUX novell-novfs-1.2.0-license.patch 18620 RMD160 0685ae1d2fe1b88872f83aac50dd54
 MD5 9e1367517129a2381c4b29ba27f32052 files/novell-novfs-1.2.0-license.patch 18620
 RMD160 0685ae1d2fe1b88872f83aac50dd545a90ec0bc3 files/novell-novfs-1.2.0-license.patch 18620
 SHA256 e6e2c5c13b3f4fb6225532d53c1de264d6d3994fe86277b6ab15b4910c140c35 files/novell-novfs-1.2.0-license.patch 18620
+AUX novell-novfs-1.2.0_to_2.0.0.patch 934748 RMD160 83cf2e11354171acc045b3571e08654e082833fc SHA1 f6982ddf4f018baaeafbc5f19457b5ed52817643 SHA256 5a53ea406ac75848301a2d4d2e6f64a2610e1be5901de7638cdac18fb1db4667
+MD5 e835b754e6295e6c912284f19a53fa1e files/novell-novfs-1.2.0_to_2.0.0.patch 934748
+RMD160 83cf2e11354171acc045b3571e08654e082833fc files/novell-novfs-1.2.0_to_2.0.0.patch 934748
+SHA256 5a53ea406ac75848301a2d4d2e6f64a2610e1be5901de7638cdac18fb1db4667 files/novell-novfs-1.2.0_to_2.0.0.patch 934748
+AUX novell-novfs-2.0.0-config_h.patch 387 RMD160 c029426c8cfe7d6f8c63aefa3f94c801c8f397d8 SHA1 b43868344bc1d0d93ed12b325278a85fe49da767 SHA256 6ef79f82f4fbc2e15e0e914767166a9e7424426bc6a2a8a6597f6cc33738e17c
+MD5 ce1ba8bd6c62ed620571dfd89e97eb9c files/novell-novfs-2.0.0-config_h.patch 387
+RMD160 c029426c8cfe7d6f8c63aefa3f94c801c8f397d8 files/novell-novfs-2.0.0-config_h.patch 387
+SHA256 6ef79f82f4fbc2e15e0e914767166a9e7424426bc6a2a8a6597f6cc33738e17c files/novell-novfs-2.0.0-config_h.patch 387
+AUX novell-novfs-2.0.0-dont_use_tasklist_lock.patch 697 RMD160 a431437c46ba7ae8dd2105f785533d07c632e353 SHA1 c35467e9646d196e6a13f8edf19a266a9f42c512 SHA256 57e09616338ef0d6c8084b31eb5faf4acdcf8a2789a95462dde11e4bc7832818
+MD5 d37acca52d7eed5a32fc59ce0c03027f files/novell-novfs-2.0.0-dont_use_tasklist_lock.patch 697
+RMD160 a431437c46ba7ae8dd2105f785533d07c632e353 files/novell-novfs-2.0.0-dont_use_tasklist_lock.patch 697
+SHA256 57e09616338ef0d6c8084b31eb5faf4acdcf8a2789a95462dde11e4bc7832818 files/novell-novfs-2.0.0-dont_use_tasklist_lock.patch 697
+AUX novell-novfs-2.0.0-generic_file_read.patch 749 RMD160 5e57f0392dfa973fc94100c032463292347b883c SHA1 b2f985d366c1031fbc3d664d8933fabb61e2fe0a SHA256 9783dc6082597175af79073ec32e550210907cc7b0f1130d43cf65c9fed6d419
+MD5 ad0967dafd28c60736f5bacd80431300 files/novell-novfs-2.0.0-generic_file_read.patch 749
+RMD160 5e57f0392dfa973fc94100c032463292347b883c files/novell-novfs-2.0.0-generic_file_read.patch 749
+SHA256 9783dc6082597175af79073ec32e550210907cc7b0f1130d43cf65c9fed6d419 files/novell-novfs-2.0.0-generic_file_read.patch 749
+AUX novell-novfs-2.0.0-i_blksize.patch 2920 RMD160 8ae931e01954ee69288ece87bf67bafb81172ae3 SHA1 728aa3f689fbfe64966b78d54e85a2dd9df0ba58 SHA256 5fa30bf88f252e07481f03b2e875cfaff639d017f8f20c356930e973bf6e3740
+MD5 763e227d6b1ba5218633a2bc5d08402b files/novell-novfs-2.0.0-i_blksize.patch 2920
+RMD160 8ae931e01954ee69288ece87bf67bafb81172ae3 files/novell-novfs-2.0.0-i_blksize.patch 2920
+SHA256 5fa30bf88f252e07481f03b2e875cfaff639d017f8f20c356930e973bf6e3740 files/novell-novfs-2.0.0-i_blksize.patch 2920
+AUX novell-novfs-2.0.0-u.generic_ip.patch 24168 RMD160 37046de7e80c853327f2865f45f05458970feea9 SHA1 01b9aada0bdcd411e9b152c65b6fcdc591b3dd9b SHA256 950b959d82a21902ac0579bbb8721fc22a0813bd4ed5e0bf1ee835b1ad8dfbca
+MD5 95fe1b20b61bda4152c6140ef7b07241 files/novell-novfs-2.0.0-u.generic_ip.patch 24168
+RMD160 37046de7e80c853327f2865f45f05458970feea9 files/novell-novfs-2.0.0-u.generic_ip.patch 24168
+SHA256 950b959d82a21902ac0579bbb8721fc22a0813bd4ed5e0bf1ee835b1ad8dfbca files/novell-novfs-2.0.0-u.generic_ip.patch 24168
 DIST novell-client-1.2-SLE10.tar.gz 13963983 RMD160 98a0aa1ecd9c4f36c158fa2cce77f51927d2f693 SHA1 14278f74c8226afabc0c602bdc31d4e20acff6b9 SHA256 ddf55b7a757a4f4e104c4aefb04639f4022d43c31171d0a914d1b765d6e78241
 EBUILD novell-novfs-1.2.0_p17-r2.ebuild 1489 RMD160 ceb5173d5207ef5de76a81299baaaf16c3db9ce4 SHA1 2d7a71e11c7fd9477e3546e2c0383a46e4fcdb08 SHA256 662bf378500afaa0d561f6779ef9a67c7d68a4b8215bef128b402dd976478592
 MD5 656ac481e9df037933ac960dbff7055e novell-novfs-1.2.0_p17-r2.ebuild 1489
 RMD160 ceb5173d5207ef5de76a81299baaaf16c3db9ce4 novell-novfs-1.2.0_p17-r2.ebuild 1489
 SHA256 662bf378500afaa0d561f6779ef9a67c7d68a4b8215bef128b402dd976478592 novell-novfs-1.2.0_p17-r2.ebuild 1489
-MISC ChangeLog 999 RMD160 4f77e534464f968a067785085aa17753f6a3fe7d SHA1 2b49e4067542fcffe97f3955b16573fb1fa130ce SHA256 c7a9bc989c2665e5700c4112d4cc7f0e40d9464c28ee43f9f844bed0b291130d
-MD5 a7b5d13e1012cc93be895e2c8d459532 ChangeLog 999
-RMD160 4f77e534464f968a067785085aa17753f6a3fe7d ChangeLog 999
-SHA256 c7a9bc989c2665e5700c4112d4cc7f0e40d9464c28ee43f9f844bed0b291130d ChangeLog 999
+EBUILD novell-novfs-2.0.0_p2.ebuild 1555 RMD160 22b10dc232d47fb23783ac59fd39576f5e06b63b SHA1 a61b70010717297cd8e5ea15906cad4ad85edb7b SHA256 46721a52d5d4ad0b8a0bb048aee3e2f5689730209a4aa2f229507ea3be45ee1c
+MD5 c26f538973a4b4dc22a95fb3b0a0b716 novell-novfs-2.0.0_p2.ebuild 1555
+RMD160 22b10dc232d47fb23783ac59fd39576f5e06b63b novell-novfs-2.0.0_p2.ebuild 1555
+SHA256 46721a52d5d4ad0b8a0bb048aee3e2f5689730209a4aa2f229507ea3be45ee1c novell-novfs-2.0.0_p2.ebuild 1555
+MISC ChangeLog 1342 RMD160 23786f799a6d783fc533b8c9542b541d787f7aab SHA1 e64ca10d54f8cb5f91ef7861431c9b9a1bba0378 SHA256 3ed62003b6977d444e0d98f194575432423402e88f18437064b053b7280a8855
+MD5 d668e2d81331acb7233358f640394cc1 ChangeLog 1342
+RMD160 23786f799a6d783fc533b8c9542b541d787f7aab ChangeLog 1342
+SHA256 3ed62003b6977d444e0d98f194575432423402e88f18437064b053b7280a8855 ChangeLog 1342
 MISC metadata.xml 170 RMD160 645927a396fdc21cdeb089fe42c5397332420ea6 SHA1 ac7f48a14fec325926f9ce1be8fbf1f311b4f2e4 SHA256 d797a2ec6f9dc516c9f9c1a758ee87ad3e8c43101b5dc76c2f872d5bd4639b42
 MD5 1e678929a9fec6632e227bdf2262e9a1 metadata.xml 170
 RMD160 645927a396fdc21cdeb089fe42c5397332420ea6 metadata.xml 170
@@ -34,3 +62,6 @@ SHA256 d797a2ec6f9dc516c9f9c1a758ee87ad3e8c43101b5dc76c2f872d5bd4639b42 metadata
 MD5 dcdc80c8269e53d3a5ecd72aa4034a06 files/digest-novell-novfs-1.2.0_p17-r2 277
 RMD160 4767389e6f47ba8fb5b8907a954b9f80ce106b78 files/digest-novell-novfs-1.2.0_p17-r2 277
 SHA256 aa21d5b182ad571f4bedf0694cc608f211146d09e0af2bdd1addd6415a2bf0b8 files/digest-novell-novfs-1.2.0_p17-r2 277
+MD5 dcdc80c8269e53d3a5ecd72aa4034a06 files/digest-novell-novfs-2.0.0_p2 277
+RMD160 4767389e6f47ba8fb5b8907a954b9f80ce106b78 files/digest-novell-novfs-2.0.0_p2 277
+SHA256 aa21d5b182ad571f4bedf0694cc608f211146d09e0af2bdd1addd6415a2bf0b8 files/digest-novell-novfs-2.0.0_p2 277
diff --git a/trunk/novell4gentoo/net-fs/novell-novfs/files/digest-novell-novfs-2.0.0_p2 b/trunk/novell4gentoo/net-fs/novell-novfs/files/digest-novell-novfs-2.0.0_p2
new file mode 100644
index 00000000..9702858d
--- /dev/null
+++ b/trunk/novell4gentoo/net-fs/novell-novfs/files/digest-novell-novfs-2.0.0_p2
@@ -0,0 +1,3 @@
+MD5 2aab6c7358a733d1d8d9a4e893500a36 novell-client-1.2-SLE10.tar.gz 13963983
+RMD160 98a0aa1ecd9c4f36c158fa2cce77f51927d2f693 novell-client-1.2-SLE10.tar.gz 13963983
+SHA256 ddf55b7a757a4f4e104c4aefb04639f4022d43c31171d0a914d1b765d6e78241 novell-client-1.2-SLE10.tar.gz 13963983
diff --git a/trunk/novell4gentoo/net-fs/novell-novfs/files/novell-novfs-1.2.0_to_2.0.0.patch b/trunk/novell4gentoo/net-fs/novell-novfs/files/novell-novfs-1.2.0_to_2.0.0.patch
new file mode 100644
index 00000000..4321b415
--- /dev/null
+++ b/trunk/novell4gentoo/net-fs/novell-novfs/files/novell-novfs-1.2.0_to_2.0.0.patch
@@ -0,0 +1,32748 @@
+diff -uNr src.old/LICENSE src/LICENSE
+--- src.old/LICENSE	1970-01-01 01:00:00.000000000 +0100
++++ src/LICENSE	2006-10-16 15:08:22.000000000 +0200
+@@ -0,0 +1,343 @@
++"Use of the novfs source code is governed by the terms of the GPL:"
++
++		    GNU GENERAL PUBLIC LICENSE
++		       Version 2, June 1991
++
++ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
++                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ Everyone is permitted to copy and distribute verbatim copies
++ of this license document, but changing it is not allowed.
++
++			    Preamble
++
++  The licenses for most software are designed to take away your
++freedom to share and change it.  By contrast, the GNU General Public
++License is intended to guarantee your freedom to share and change free
++software--to make sure the software is free for all its users.  This
++General Public License applies to most of the Free Software
++Foundation's software and to any other program whose authors commit to
++using it.  (Some other Free Software Foundation software is covered by
++the GNU Library General Public License instead.)  You can apply it to
++your programs, too.
++
++  When we speak of free software, we are referring to freedom, not
++price.  Our General Public Licenses are designed to make sure that you
++have the freedom to distribute copies of free software (and charge for
++this service if you wish), that you receive source code or can get it
++if you want it, that you can change the software or use pieces of it
++in new free programs; and that you know you can do these things.
++
++  To protect your rights, we need to make restrictions that forbid
++anyone to deny you these rights or to ask you to surrender the rights.
++These restrictions translate to certain responsibilities for you if you
++distribute copies of the software, or if you modify it.
++
++  For example, if you distribute copies of such a program, whether
++gratis or for a fee, you must give the recipients all the rights that
++you have.  You must make sure that they, too, receive or can get the
++source code.  And you must show them these terms so they know their
++rights.
++
++  We protect your rights with two steps: (1) copyright the software, and
++(2) offer you this license which gives you legal permission to copy,
++distribute and/or modify the software.
++
++  Also, for each author's protection and ours, we want to make certain
++that everyone understands that there is no warranty for this free
++software.  If the software is modified by someone else and passed on, we
++want its recipients to know that what they have is not the original, so
++that any problems introduced by others will not reflect on the original
++authors' reputations.
++
++  Finally, any free program is threatened constantly by software
++patents.  We wish to avoid the danger that redistributors of a free
++program will individually obtain patent licenses, in effect making the
++program proprietary.  To prevent this, we have made it clear that any
++patent must be licensed for everyone's free use or not licensed at all.
++
++  The precise terms and conditions for copying, distribution and
++modification follow.
++
++		    GNU GENERAL PUBLIC LICENSE
++   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
++
++  0. This License applies to any program or other work which contains
++a notice placed by the copyright holder saying it may be distributed
++under the terms of this General Public License.  The "Program", below,
++refers to any such program or work, and a "work based on the Program"
++means either the Program or any derivative work under copyright law:
++that is to say, a work containing the Program or a portion of it,
++either verbatim or with modifications and/or translated into another
++language.  (Hereinafter, translation is included without limitation in
++the term "modification".)  Each licensee is addressed as "you".
++
++Activities other than copying, distribution and modification are not
++covered by this License; they are outside its scope.  The act of
++running the Program is not restricted, and the output from the Program
++is covered only if its contents constitute a work based on the
++Program (independent of having been made by running the Program).
++Whether that is true depends on what the Program does.
++
++  1. You may copy and distribute verbatim copies of the Program's
++source code as you receive it, in any medium, provided that you
++conspicuously and appropriately publish on each copy an appropriate
++copyright notice and disclaimer of warranty; keep intact all the
++notices that refer to this License and to the absence of any warranty;
++and give any other recipients of the Program a copy of this License
++along with the Program.
++
++You may charge a fee for the physical act of transferring a copy, and
++you may at your option offer warranty protection in exchange for a fee.
++
++  2. You may modify your copy or copies of the Program or any portion
++of it, thus forming a work based on the Program, and copy and
++distribute such modifications or work under the terms of Section 1
++above, provided that you also meet all of these conditions:
++
++    a) You must cause the modified files to carry prominent notices
++    stating that you changed the files and the date of any change.
++
++    b) You must cause any work that you distribute or publish, that in
++    whole or in part contains or is derived from the Program or any
++    part thereof, to be licensed as a whole at no charge to all third
++    parties under the terms of this License.
++
++    c) If the modified program normally reads commands interactively
++    when run, you must cause it, when started running for such
++    interactive use in the most ordinary way, to print or display an
++    announcement including an appropriate copyright notice and a
++    notice that there is no warranty (or else, saying that you provide
++    a warranty) and that users may redistribute the program under
++    these conditions, and telling the user how to view a copy of this
++    License.  (Exception: if the Program itself is interactive but
++    does not normally print such an announcement, your work based on
++    the Program is not required to print an announcement.)
++
++These requirements apply to the modified work as a whole.  If
++identifiable sections of that work are not derived from the Program,
++and can be reasonably considered independent and separate works in
++themselves, then this License, and its terms, do not apply to those
++sections when you distribute them as separate works.  But when you
++distribute the same sections as part of a whole which is a work based
++on the Program, the distribution of the whole must be on the terms of
++this License, whose permissions for other licensees extend to the
++entire whole, and thus to each and every part regardless of who wrote it.
++
++Thus, it is not the intent of this section to claim rights or contest
++your rights to work written entirely by you; rather, the intent is to
++exercise the right to control the distribution of derivative or
++collective works based on the Program.
++
++In addition, mere aggregation of another work not based on the Program
++with the Program (or with a work based on the Program) on a volume of
++a storage or distribution medium does not bring the other work under
++the scope of this License.
++
++  3. You may copy and distribute the Program (or a work based on it,
++under Section 2) in object code or executable form under the terms of
++Sections 1 and 2 above provided that you also do one of the following:
++
++    a) Accompany it with the complete corresponding machine-readable
++    source code, which must be distributed under the terms of Sections
++    1 and 2 above on a medium customarily used for software interchange; or,
++
++    b) Accompany it with a written offer, valid for at least three
++    years, to give any third party, for a charge no more than your
++    cost of physically performing source distribution, a complete
++    machine-readable copy of the corresponding source code, to be
++    distributed under the terms of Sections 1 and 2 above on a medium
++    customarily used for software interchange; or,
++
++    c) Accompany it with the information you received as to the offer
++    to distribute corresponding source code.  (This alternative is
++    allowed only for noncommercial distribution and only if you
++    received the program in object code or executable form with such
++    an offer, in accord with Subsection b above.)
++
++The source code for a work means the preferred form of the work for
++making modifications to it.  For an executable work, complete source
++code means all the source code for all modules it contains, plus any
++associated interface definition files, plus the scripts used to
++control compilation and installation of the executable.  However, as a
++special exception, the source code distributed need not include
++anything that is normally distributed (in either source or binary
++form) with the major components (compiler, kernel, and so on) of the
++operating system on which the executable runs, unless that component
++itself accompanies the executable.
++
++If distribution of executable or object code is made by offering
++access to copy from a designated place, then offering equivalent
++access to copy the source code from the same place counts as
++distribution of the source code, even though third parties are not
++compelled to copy the source along with the object code.
++
++  4. You may not copy, modify, sublicense, or distribute the Program
++except as expressly provided under this License.  Any attempt
++otherwise to copy, modify, sublicense or distribute the Program is
++void, and will automatically terminate your rights under this License.
++However, parties who have received copies, or rights, from you under
++this License will not have their licenses terminated so long as such
++parties remain in full compliance.
++
++  5. You are not required to accept this License, since you have not
++signed it.  However, nothing else grants you permission to modify or
++distribute the Program or its derivative works.  These actions are
++prohibited by law if you do not accept this License.  Therefore, by
++modifying or distributing the Program (or any work based on the
++Program), you indicate your acceptance of this License to do so, and
++all its terms and conditions for copying, distributing or modifying
++the Program or works based on it.
++
++  6. Each time you redistribute the Program (or any work based on the
++Program), the recipient automatically receives a license from the
++original licensor to copy, distribute or modify the Program subject to
++these terms and conditions.  You may not impose any further
++restrictions on the recipients' exercise of the rights granted herein.
++You are not responsible for enforcing compliance by third parties to
++this License.
++
++  7. If, as a consequence of a court judgment or allegation of patent
++infringement or for any other reason (not limited to patent issues),
++conditions are imposed on you (whether by court order, agreement or
++otherwise) that contradict the conditions of this License, they do not
++excuse you from the conditions of this License.  If you cannot
++distribute so as to satisfy simultaneously your obligations under this
++License and any other pertinent obligations, then as a consequence you
++may not distribute the Program at all.  For example, if a patent
++license would not permit royalty-free redistribution of the Program by
++all those who receive copies directly or indirectly through you, then
++the only way you could satisfy both it and this License would be to
++refrain entirely from distribution of the Program.
++
++If any portion of this section is held invalid or unenforceable under
++any particular circumstance, the balance of the section is intended to
++apply and the section as a whole is intended to apply in other
++circumstances.
++
++It is not the purpose of this section to induce you to infringe any
++patents or other property right claims or to contest validity of any
++such claims; this section has the sole purpose of protecting the
++integrity of the free software distribution system, which is
++implemented by public license practices.  Many people have made
++generous contributions to the wide range of software distributed
++through that system in reliance on consistent application of that
++system; it is up to the author/donor to decide if he or she is willing
++to distribute software through any other system and a licensee cannot
++impose that choice.
++
++This section is intended to make thoroughly clear what is believed to
++be a consequence of the rest of this License.
++
++  8. If the distribution and/or use of the Program is restricted in
++certain countries either by patents or by copyrighted interfaces, the
++original copyright holder who places the Program under this License
++may add an explicit geographical distribution limitation excluding
++those countries, so that distribution is permitted only in or among
++countries not thus excluded.  In such case, this License incorporates
++the limitation as if written in the body of this License.
++
++  9. The Free Software Foundation may publish revised and/or new versions
++of the General Public License from time to time.  Such new versions will
++be similar in spirit to the present version, but may differ in detail to
++address new problems or concerns.
++
++Each version is given a distinguishing version number.  If the Program
++specifies a version number of this License which applies to it and "any
++later version", you have the option of following the terms and conditions
++either of that version or of any later version published by the Free
++Software Foundation.  If the Program does not specify a version number of
++this License, you may choose any version ever published by the Free Software
++Foundation.
++
++  10. If you wish to incorporate parts of the Program into other free
++programs whose distribution conditions are different, write to the author
++to ask for permission.  For software which is copyrighted by the Free
++Software Foundation, write to the Free Software Foundation; we sometimes
++make exceptions for this.  Our decision will be guided by the two goals
++of preserving the free status of all derivatives of our free software and
++of promoting the sharing and reuse of software generally.
++
++			    NO WARRANTY
++
++  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
++FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
++OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
++PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
++OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
++TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
++PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
++REPAIR OR CORRECTION.
++
++  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
++WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
++REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
++INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
++OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
++TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
++YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
++PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
++POSSIBILITY OF SUCH DAMAGES.
++
++		     END OF TERMS AND CONDITIONS
++
++	    How to Apply These Terms to Your New Programs
++
++  If you develop a new program, and you want it to be of the greatest
++possible use to the public, the best way to achieve this is to make it
++free software which everyone can redistribute and change under these terms.
++
++  To do so, attach the following notices to the program.  It is safest
++to attach them to the start of each source file to most effectively
++convey the exclusion of warranty; and each file should have at least
++the "copyright" line and a pointer to where the full notice is found.
++
++    <one line to give the program's name and a brief idea of what it does.>
++    Copyright (C) <year>  <name of author>
++
++    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
++
++
++Also add information on how to contact you by electronic and paper mail.
++
++If the program is interactive, make it output a short notice like this
++when it starts in an interactive mode:
++
++    Gnomovision version 69, Copyright (C) year name of author
++    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
++    This is free software, and you are welcome to redistribute it
++    under certain conditions; type `show c' for details.
++
++The hypothetical commands `show w' and `show c' should show the appropriate
++parts of the General Public License.  Of course, the commands you use may
++be called something other than `show w' and `show c'; they could even be
++mouse-clicks or menu items--whatever suits your program.
++
++You should also get your employer (if you work as a programmer) or your
++school, if any, to sign a "copyright disclaimer" for the program, if
++necessary.  Here is a sample; alter the names:
++
++  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
++  `Gnomovision' (which makes passes at compilers) written by James Hacker.
++
++  <signature of Ty Coon>, 1 April 1989
++  Ty Coon, President of Vice
++
++This General Public License does not permit incorporating your program into
++proprietary programs.  If your program is a subroutine library, you may
++consider it more useful to permit linking proprietary applications with the
++library.  If this is what you want to do, use the GNU Library General
++Public License instead of this License.
++
+diff -uNr src.old/include/commands.h src/include/commands.h
+--- src.old/include/commands.h	2006-07-11 21:24:18.000000000 +0200
++++ src/include/commands.h	2006-10-16 15:08:23.000000000 +0200
+@@ -73,6 +73,7 @@
+ #define VFS_COMMAND_SET_MOUNT_PATH              31
+ #define VFS_COMMAND_GET_USER_SPACE              32
+ #define VFS_COMMAND_DBG                         33
++#define VFS_COMMAND_GET_CACHE_FLAG              34
+ 
+ 
+ #define  NWD_ACCESS_QUERY                        0x00000001
+@@ -1167,6 +1168,21 @@
+ 
+ } NwdCVerifyKey, *PNwdCVerifyKey;
+ 
++typedef struct _GET_CACHE_FLAG
++{
++   COMMAND_REQUEST_HEADER 	Command;
++   int                     pathLen;
++   unsigned char           path[0];
++    
++} GET_CACHE_FLAG_REQUEST, *PGET_CACHE_FLAG_REQUEST;
++
++typedef struct _GET_CACHE_FLAG_REPLY
++{
++	COMMAND_REPLY_HEADER 	Reply;
++   int                     CacheFlag;
++
++} GET_CACHE_FLAG_REPLY, *PGET_CACHE_FLAG_REPLY;
++
+ 
+ #pragma pack(pop)
+ 
+diff -uNr src.old/novfs/Makefile src/novfs/Makefile
+--- src.old/novfs/Makefile	2006-07-11 21:24:18.000000000 +0200
++++ src/novfs/Makefile	1970-01-01 01:00:00.000000000 +0100
+@@ -1,52 +0,0 @@
+-##*++======================================================================
+-## Program Name:     Novell NCP Redirector for Linux
+-## File Name:        Makefile
+-## Version:          v1.01
+-## Author:           James Turner
+-##
+-## Abstract:         This is used to generate the novfs module
+-## Notes:
+-## Revision History: 
+-##	6/10/2005 - Added lines for SuSE
+-##
+-## Copyright (C) 2005 Novell, Inc.
+-##
+-## 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.
+-##=====================================================================--*/ 
+-
+-#
+-# Makefile for the Novell NetWare Client for Linux filesystem.
+-#
+-NOVFS_VFS_MAJOR = 1
+-NOVFS_VFS_MINOR = 2
+-NOVFS_VFS_SUB = 0
+-NOVFS_VFS_RELEASE = 17
+-
+-# Remove # from the following line for debug version
+-EXTRA_CFLAGS += -finstrument-functions
+-EXTRA_CFLAGS += -g
+-EXTRA_CFLAGS += -I.
+-EXTRA_CFLAGS += -I$(obj)/../include
+-#EXTRA_CFLAGS += -I$(obj)/../../include
+-EXTRA_CFLAGS += -DNOVFS_VFS_MAJOR=$(NOVFS_VFS_MAJOR)
+-EXTRA_CFLAGS += -DNOVFS_VFS_MINOR=$(NOVFS_VFS_MINOR)
+-EXTRA_CFLAGS += -DNOVFS_VFS_SUB=$(NOVFS_VFS_SUB)
+-EXTRA_CFLAGS += -DNOVFS_VFS_PATCH=$(NOVFS_VFS_PATCH)
+-EXTRA_CFLAGS += -DNOVFS_VFS_RELEASE=$(NOVFS_VFS_RELEASE)
+-
+-
+-obj-m := novfs.o
+-
+-novfs-y := inode.o proc.o profile.o daemon.o file.o scope.o nwcapi.o
+diff -uNr src.old/novfs/blank.c src/novfs/blank.c
+--- src.old/novfs/blank.c	2006-07-11 21:24:18.000000000 +0200
++++ src/novfs/blank.c	1970-01-01 01:00:00.000000000 +0100
+@@ -1,61 +0,0 @@
+-/*++========================================================================
+- * Program Name:     Novell NCP Redirector for Linux
+- * File Name:        .c
+- * Version:          v1.00
+- * Author:           James Turner
+- *
+- * Abstract:         This module
+- *
+- * Notes:
+- * Revision History: 
+- *
+- *
+- * Copyright (C) 2005 Novell, Inc.
+- *
+- * 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 files specific to Linux ]==================================*/
+-
+-/*===[ Include files specific to this module ]============================*/
+-
+-/*===[ External data ]====================================================*/
+-
+-/*===[ External prototypes ]==============================================*/
+-
+-/*===[ Manifest constants ]===============================================*/
+-
+-/*===[ Type definitions ]=================================================*/
+-
+-/*===[ Function prototypes ]==============================================*/
+-
+-/*===[ Global variables ]=================================================*/
+-
+-/*===[ Code ]=============================================================*/
+-
+-/*++======================================================================*/
+-Function
+-/*
+- * Arguments:
+- * 
+- * Returns:
+- * 
+- * Abstract:
+- * 
+- * Notes:
+- * 
+- * Environment:
+- * 
+- *========================================================================*/
+diff -uNr src.old/novfs/daemon.c src/novfs/daemon.c
+--- src.old/novfs/daemon.c	2006-07-11 21:24:18.000000000 +0200
++++ src/novfs/daemon.c	1970-01-01 01:00:00.000000000 +0100
+@@ -1,2877 +0,0 @@
+-/*++========================================================================
+- * Program Name:     Novell NCP Redirector for Linux
+- * File Name:        daemon.c
+- * Version:          v1.00
+- * Author:           James Turner
+- *
+- * Abstract:         This module contains all the functions necessary
+- *                   for sending commands to our daemon module.
+- * Notes:
+- * Revision History: 
+- *
+- *
+- * Copyright (C) 2005 Novell, Inc.
+- *
+- * 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 files specific to Linux ]==================================*/
+-#include <linux/module.h>
+-#include <linux/fs.h>
+-#include <linux/slab.h>
+-#include <linux/list.h>
+-#include <linux/timer.h>
+-#include <linux/poll.h>
+-#include <linux/pagemap.h>
+-#include <linux/smp_lock.h>
+-#include <asm/semaphore.h>
+-#include <asm/uaccess.h>
+-#include <linux/time.h>
+-
+-
+-/*===[ Include files specific to this module ]============================*/
+-#include "vfs.h"
+-#include "nwcapi.h"
+-#include "commands.h"
+-#include "nwerror.h"
+-
+-/*===[ External data ]====================================================*/
+-extern char *Novfs_CurrentMount;
+-extern char DbgDaemonLogOn;
+-
+-
+-/*===[ External prototypes ]==============================================*/
+-extern int DbgPrint( char *Fmt, ... );
+-extern void mydump(int size, void *dumpptr);
+-
+-extern char *Scope_Get_UserName( void *Scope );
+-extern void *Scope_Lookup( void );
+-extern session_t Scope_Get_SessionId( void *Scope );
+-extern void Scope_Cleanup( void );
+-
+-extern int Novfs_Read_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, int User, session_t SessionId);
+-extern int Novfs_Write_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId);
+-extern int Novfs_Close_Stream( u_long ConnHandle, u_char *Handle, session_t SessionId );
+-
+-extern int Novfs_Add_to_Root(char *);
+-
+-/*
+- * nwcapi.c functions
+- */
+-extern int NwAuthConnWithId(PXPLAT pdata, session_t Session);
+-extern int NwConnClose(PXPLAT pdata, u_long *Handle, session_t Session);
+-extern int NwGetConnInfo(PXPLAT pdata, session_t Session);
+-extern int NwSetConnInfo(PXPLAT pdata, session_t Session);
+-extern int NwGetDaemonVersion(PXPLAT pdata, session_t Session);
+-extern int NwGetIdentityInfo(PXPLAT pdata, session_t Session);
+-extern int NwLicenseConn(PXPLAT pdata, session_t Session);
+-extern int NwLoginIdentity(PXPLAT pdata, session_t Session);
+-extern int NwLogoutIdentity(PXPLAT pdata, session_t Session);
+-extern int NwOpenConnByAddr(PXPLAT pdata, u_long *Handle, session_t Session);
+-extern int NwOpenConnByName(PXPLAT pdata, u_long *Handle, session_t Session);
+-extern int NwOpenConnByRef(PXPLAT pdata, u_long *Handle, session_t Session);
+-extern int NwQueryFeature(PXPLAT pdata, session_t Session);
+-extern int NwRawSend(PXPLAT pdata, session_t Session);
+-extern int NwScanConnInfo(PXPLAT pdata, session_t Session);
+-extern int NwSysConnClose(PXPLAT pdata, u_long *Handle, session_t Session);
+-extern int NwUnAuthenticate(PXPLAT pdata, session_t Session);
+-extern int NwUnlicenseConn(PXPLAT pdata, session_t Session);
+-extern int NwcChangeAuthKey(PXPLAT pdata, session_t Session);
+-extern int NwcEnumIdentities(PXPLAT pdata, session_t Session);
+-extern int NwcGetDefaultNameCtx(PXPLAT pdata, session_t Session);
+-extern int NwcGetPreferredDSTree(PXPLAT pdata, session_t Session);
+-extern int NwcGetTreeMonitoredConn(PXPLAT pdata, session_t Session);
+-extern int NwcSetDefaultNameCtx(PXPLAT pdata, session_t Session);
+-extern int NwcSetPreferredDSTree(PXPLAT pdata, session_t Session);
+-extern int NwcSetPrimaryConn(PXPLAT pdata, session_t Session);
+-extern int NwcGetPrimaryConn(PXPLAT pdata, session_t Session);
+-extern int NwcSetMapDrive(PXPLAT pdata, session_t Session);
+-extern int NwcUnMapDrive(PXPLAT pdata, session_t Session);
+-extern int NwcEnumerateDrives(PXPLAT pdata, session_t Session);
+-extern int NwcGetBroadcastMessage(PXPLAT pdata, session_t Session);
+-extern int NwdSetKeyValue(PXPLAT pdata, session_t Session);
+-extern int NwdVerifyKeyValue(PXPLAT pdata, session_t Session);
+-
+-/*===[ Manifest constants ]===============================================*/
+-#define QUEUE_SENDING 0
+-#define QUEUE_WAITING 1
+-#define QUEUE_TIMEOUT 2
+-#define QUEUE_ACKED   3
+-#define QUEUE_DONE    4
+-
+-#define TIMEOUT_VALUE 10
+-
+-#define DH_TYPE_UNDEFINED    0
+-#define DH_TYPE_STREAM       1
+-#define DH_TYPE_CONNECTION   2
+-
+-/*===[ Type definitions ]=================================================*/
+-typedef struct _DAEMON_QUEUE
+-{
+-   struct list_head list;       /* Must be first entry */
+-   spinlock_t       lock;       /* Used to control access to list */
+-   struct semaphore semaphore;  /* Used to signal when data is available */
+-} daemon_queue_t;
+-
+-typedef struct _DAEMON_COMMAND
+-{
+-   struct list_head  list;      /* Must be first entry */
+-   atomic_t          reference;
+-   u_long            status;
+-   u_long            flags;
+-   struct semaphore  semaphore;
+-   u_long            sequence;
+-   struct timer_list timer;
+-   void              *request;
+-   u_long            reqlen;
+-   void              *data;
+-   int               datalen;
+-   void              *reply;
+-   u_long            replen;
+-}  daemon_command_t;
+-
+-
+-typedef struct _DAEMON_HANDLE_
+-{
+-   struct list_head  list;
+-   rwlock_t          lock;
+-   session_t         session;
+-} daemon_handle_t;
+-
+-typedef struct _DAEMON_RESOURCE_
+-{
+-   struct list_head  list;
+-   int               type;
+-   u_long            connection;
+-   u_char            handle[6];
+-   mode_t            mode; 
+-   loff_t            size;
+-} daemon_resource_t;
+-
+-typedef struct _DRIVE_MAP_
+-{
+-   struct list_head  list; /* Must be first item */
+-   session_t session;
+-   u_long hash;
+-   int namelen;
+-   char name[1];
+-} drive_map_t;
+-
+-/*===[ Function prototypes ]==============================================*/
+-int     Daemon_Added_Resource(daemon_handle_t *DHandle, int Type, u_long CHandle, u_char *FHandle, u_long Mode, u_long Size);
+-int     Daemon_Close_Control(struct inode *Inode, struct file *File);
+-int     Daemon_CreateSessionId( uint64_t *SessionId );
+-int     Daemon_DestroySessionId( uint64_t SessionId );
+-void    Daemon_Dumpque( void );
+-int     Daemon_Get_UserSpace( uint64_t SessionId,  uint64_t *TotalSize, uint64_t *TotalFree, uint64_t *TotalDirectoryEnties, uint64_t *FreeDirectoryEnties);
+-int     Daemon_Library_close(struct inode *inode, struct file *file);
+-int     Daemon_Library_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u_long arg);
+-int     Daemon_Library_open(struct inode *inode, struct file *file);
+-ssize_t Daemon_Library_read(struct file *file, char *buf, size_t len, loff_t *off);
+-ssize_t Daemon_Library_write(struct file *file, const char *buf, size_t len, loff_t *off);
+-loff_t  Daemon_Library_llseek(struct file *file, loff_t offset, int origin);
+-int     Daemon_Login(PLOGIN Login, session_t Session);
+-int     Daemon_Logout(PLOGOUT Logout, session_t Session);
+-int     Daemon_Open_Control(struct inode *Inode, struct file *File);
+-uint    Daemon_Poll(struct file *file, struct poll_table_struct *poll_table);
+-ssize_t Daemon_Receive_Reply(struct file * file, char * buf, size_t nbytes, loff_t *ppos);
+-int     Daemon_Remove_Resource(daemon_handle_t *DHandle, int Type, u_long CHandle, u_long FHandle);
+-
+-ssize_t Daemon_Send_Command(struct file *file, char *buf, size_t len, loff_t *off);
+-int     Daemon_SetMountPoint( char *Path );
+-void    Daemon_Timer(u_long data);
+-int     Daemon_getpwuid( uid_t uid, int unamelen, char *uname );
+-int     Daemon_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u_long arg);
+-void    Init_Daemon_Queue( void );
+-int     Queue_Daemon_Command(void *request, u_long reqlen, void *data, int dlen, void **reply, u_long *replen, int interruptible);
+-void    Queue_get(daemon_command_t *que);
+-void    Queue_put(daemon_command_t *que);
+-void    Uninit_Daemon_Queue( void );
+-int     do_login(NclString *Server, NclString *Username, NclString *Password, u_long *lgnId, session_t Session);
+-int     do_logout( struct qstr *Server, session_t Session );
+-daemon_command_t *find_queue(u_long sequence);
+-daemon_command_t *get_next_queue(int Set_Queue_Waiting);
+-int NwdConvertNetwareHandle(PXPLAT pdata, daemon_handle_t *DHandle);
+-int NwdConvertLocalHandle(PXPLAT pdata, daemon_handle_t *DHandle);
+-int NwdGetMountPath(PXPLAT pdata);
+-int NwdSetMapDrive(PXPLAT pdata, session_t Session);
+-int NwdUnMapDrive(PXPLAT pdata, session_t Session);
+-void RemoveDriveMaps( void );
+-int local_unlink(const char *pathname);
+-
+-/*===[ Global variables ]=================================================*/
+-daemon_queue_t Daemon_Queue;
+-
+-static DECLARE_WAIT_QUEUE_HEAD(Read_waitqueue);
+-
+-u_long Sequence = 0;
+-atomic_t Daemon_Open_Count=ATOMIC_INIT(0);
+-
+-u_long Daemon_Command_Timeout = TIMEOUT_VALUE;
+-
+-DECLARE_MUTEX ( DriveMapLock );
+-LIST_HEAD( DriveMapList );
+-
+-int MaxIoSize=PAGE_SIZE;
+-
+-/*===[ Code ]=============================================================*/
+-
+-/*++======================================================================*/
+-void Init_Daemon_Queue()
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   INIT_LIST_HEAD(&Daemon_Queue.list);
+-   spin_lock_init(&Daemon_Queue.lock);
+-   init_MUTEX_LOCKED(&Daemon_Queue.semaphore);
+-}
+-
+-/*++======================================================================*/
+-void Uninit_Daemon_Queue( void )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   /* Does nothing for now but we maybe should clear the queue. */
+-}
+-
+-/*++======================================================================*/
+-void 
+-NO_TRACE
+-Daemon_Timer(u_long data)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   daemon_command_t *que = (daemon_command_t *)data;
+-
+-   if ( QUEUE_ACKED != que->status )
+-   {
+-      que->status = QUEUE_TIMEOUT;
+-   }
+-   up(&que->semaphore);
+-}
+-
+-/*++======================================================================*/
+-int Queue_Daemon_Command(
+-   void *request,
+-   u_long reqlen, 
+-   void *data, 
+-   int dlen,
+-   void **reply, 
+-   u_long *replen,
+-   int interruptible)
+-/*
+- *
+- *  Arguments:     void *request - pointer to the request that is to be sent.  Needs to be kernel memory.
+- *                 int reqlen - length of the request.
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   daemon_command_t *que;
+-   int retCode = 0;
+-   struct timespec ts1, ts2;
+-
+-   ts1 = current_kernel_time();
+-
+-   DbgPrint( "Queue_Daemon_Command: 0x%x %d\n", request, reqlen);
+-
+-   if (atomic_read(&Daemon_Open_Count))
+-   {
+-
+-      que = (daemon_command_t *)Novfs_Malloc(sizeof(*que), GFP_KERNEL);
+-
+-      DbgPrint( "Queue_Daemon_Command: que=0x%x\n", que);
+-      if (que)
+-      {
+-         atomic_set( &que->reference, 0 );
+-         que->status = QUEUE_SENDING;
+-         que->flags  = 0;
+-
+-         init_MUTEX_LOCKED(&que->semaphore);
+-
+-         DbgPrint( "Queue_Daemon_Command: semaphore inited que=0x%x\n", que);
+-         
+-         que->sequence = InterlockedIncrement(&Sequence);
+-
+-         DbgPrint( "Queue_Daemon_Command: sequence=0x%x\n", que->sequence);
+-
+-         ((PCOMMAND_REQUEST_HEADER)request)->SequenceNumber = que->sequence;
+-
+-         /*
+-          * Setup and start que timer
+-          */
+-         init_timer(&que->timer);
+-         que->timer.expires = jiffies + (HZ * Daemon_Command_Timeout);
+-         que->timer.data = (u_long)que;
+-         que->timer.function = Daemon_Timer;
+-         add_timer(&que->timer);
+-
+-         DbgPrint( "Queue_Daemon_Command: timer started que=0x%x\n", que);
+-
+-         /*
+-          * Setup request
+-          */
+-         que->request = request;
+-         que->reqlen  = reqlen;
+-         que->data    = data;
+-         que->datalen = dlen;
+-         que->reply   = NULL;
+-         que->replen  = 0;
+-
+-         DbgPrint( "Queue_Daemon_Command: setting up que=0x%x\n", que);
+-
+-         /*
+-          * Added entry to queue.
+-          */
+-         DbgPrint( "Queue_Daemon_Command: Daemon_Queue locked\n");
+-
+-         /*
+-          * Check to see if interruptible and set flags.
+-          */
+-         if (interruptible) 
+-         {
+-            que->flags |= INTERRUPTIBLE;
+-         }
+-
+-         spin_lock(&Daemon_Queue.lock);
+-         Queue_get( que );
+-         list_add_tail(&que->list, &Daemon_Queue.list);
+-         spin_unlock(&Daemon_Queue.lock);
+-
+-         DbgPrint( "Queue_Daemon_Command: 0x%x added to Daemon_Queue\n", que);
+-         /*
+-          * Signal that there is data to be read
+-          */
+-         up(&Daemon_Queue.semaphore);
+-
+-         /*
+-          * Give a change to the other processes.
+-          */
+-         yield();
+-
+-         DbgPrint( "Queue_Daemon_Command: calling down 0x%x\n", CURRENT_TIME);
+-   
+-         /*
+-          * Block waiting for reply or timeout
+-          */
+-         down(&que->semaphore);
+-
+-         DbgPrint( "Queue_Daemon_Command: after down 0x%x\n", CURRENT_TIME);
+-
+-         if ( QUEUE_ACKED == que->status )
+-         {
+-            que->status = QUEUE_WAITING;
+-            mod_timer(&que->timer, jiffies + (HZ * 2 * Daemon_Command_Timeout));
+-            DbgPrint( "Queue_Daemon_Command: mod_timer 0x%x\n", CURRENT_TIME);
+-            if (interruptible) 
+-            {
+-               retCode = down_interruptible(&que->semaphore);
+-            }
+-            else
+-            {
+-               down(&que->semaphore);
+-            }
+-            DbgPrint( "Queue_Daemon_Command: after down2 0x%x\n", CURRENT_TIME);
+-         }
+-
+-         DbgPrint( "Queue_Daemon_Command: after down 0x%d 0x%x\n", retCode, CURRENT_TIME);
+-         /*
+-          * Delete timer
+-          */
+-         del_timer(&que->timer);
+-
+-         /*
+-          * Check for timeout
+-          */
+-         if ((QUEUE_TIMEOUT == que->status) && (NULL == que->reply) )
+-         {
+-            DbgPrint( "Queue_Daemon_Command: Timeout\n");
+-            retCode = -ETIME;
+-         }
+-         *reply  = que->reply;
+-         *replen = que->replen;
+-
+-         /*
+-          * Remove item from queue
+-          */
+-         Queue_put( que );
+-
+-      }
+-      else /* Error case with no memory */
+-      {
+-         retCode = -ENOMEM;
+-         *reply = NULL;
+-         *replen = 0;
+-      }
+-   }
+-   else
+-   {
+-      retCode = -EIO;
+-      *reply = NULL;
+-      *replen = 0;
+-
+-   }
+-   ts2 = current_kernel_time();
+-   if (ts2.tv_nsec < ts1.tv_nsec)
+-   {
+-      ts2.tv_sec--;
+-      ts2.tv_nsec += NSEC_PER_SEC;
+-   }
+-   ts2.tv_sec = ts2.tv_sec-ts1.tv_sec;
+-   ts2.tv_nsec = ts2.tv_nsec-ts1.tv_nsec;
+-
+-   DbgPrint( "Queue_Daemon_Command: %ld:%lu retCode=%d \n", ts2.tv_sec, ts2.tv_nsec, retCode);
+-   return(retCode);
+-}
+-
+-/*++======================================================================*/
+-void Queue_get(daemon_command_t *Que)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   DbgPrint("Queue_get: que=0x%p %d\n", Que, atomic_read(&Que->reference));
+-   atomic_inc( &Que->reference );
+-}
+-
+-/*++======================================================================*/
+-void Queue_put(daemon_command_t *Que)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   spin_lock(&Daemon_Queue.lock);
+-
+-   DbgPrint("Queue_put: que=0x%p %d\n", Que, atomic_read(&Que->reference));
+-   if ( atomic_dec_and_test( &Que->reference ))
+-   {
+-      /*
+-       * Remove item from queue
+-       */
+-      list_del(&Que->list);
+-
+-      spin_unlock(&Daemon_Queue.lock);
+-
+-      /*
+-       * Free item memory
+-       */
+-      Novfs_Free(Que);
+-   }
+-   else
+-   {
+-      spin_unlock(&Daemon_Queue.lock);
+-   }
+-}
+-
+-/*++======================================================================*/
+-daemon_command_t *get_next_queue(int Set_Queue_Waiting)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   daemon_command_t *que;
+-   
+-   spin_lock(&Daemon_Queue.lock);
+-   que = (daemon_command_t *)Daemon_Queue.list.next;
+-
+-   DbgPrint( "get_next_queue: que=0x%x\n", que);
+-
+-   while (que && (que != (daemon_command_t *)&Daemon_Queue.list.next) && ( que->status != QUEUE_SENDING ) )
+-   {
+-      que = (daemon_command_t *)que->list.next;
+-      DbgPrint( "get_next_queue: que1=0x%x\n", que);
+-   }
+-
+-   if ((NULL == que) || (que == (daemon_command_t *)&Daemon_Queue.list) || (que->status != QUEUE_SENDING))
+-   {
+-      que = NULL;
+-   }
+-   else if (Set_Queue_Waiting)
+-   {
+-      que->status = QUEUE_WAITING;
+-   }
+-
+-   if (que)
+-   {
+-      atomic_inc( &que->reference );
+-   }
+-
+-   spin_unlock(&Daemon_Queue.lock);
+-
+-   DbgPrint( "get_next_queue: return=0x%x\n", que);
+-   return(que);
+-}
+-
+-/*++======================================================================*/
+-daemon_command_t *find_queue(u_long sequence)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   daemon_command_t *que;
+-   
+-   DbgPrint( "find_queue: 0x%x\n", sequence);
+-
+-   spin_lock(&Daemon_Queue.lock);
+-   que = (daemon_command_t *)Daemon_Queue.list.next;
+-   
+-   DbgPrint( "find_queue: que=0x%x\n", que);
+-
+-   while (que && (que != (daemon_command_t *)&Daemon_Queue.list.next) && (que->sequence != sequence))
+-   {
+-      DbgPrint( "find_queue: que1=0x%x\n", que);
+-      que = (daemon_command_t *)que->list.next;
+-   }
+-
+-   if ((NULL == que) || (que == (daemon_command_t *)&Daemon_Queue.list.next) || (que->sequence != sequence))
+-   {
+-      que = NULL;
+-   }
+-
+-   if (que)
+-   {
+-      atomic_inc( &que->reference );
+-   }
+-
+-   spin_unlock(&Daemon_Queue.lock);
+-
+-   DbgPrint( "find_queue: return 0x%x\n", que);
+-   return(que);
+-}
+-/*++======================================================================*/
+-int Daemon_Open_Control(struct inode *Inode, struct file *File)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   DbgPrint("Daemon_Open_Control: pid=%d Count=%d\n", current->pid, atomic_read(&Daemon_Open_Count));
+-   atomic_inc(&Daemon_Open_Count);
+-
+-   return(0);
+-}
+-
+-/*++======================================================================*/
+-int Daemon_Close_Control(struct inode *Inode, struct file *File)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   daemon_command_t *que;
+-
+-   DbgPrint("Daemon_Close_Control: pid=%d Count=%d\n", current->pid, atomic_read(&Daemon_Open_Count));
+-
+-   if (atomic_dec_and_test(&Daemon_Open_Count))
+-   {
+-      /*
+-       * Signal any pending que itmes.
+-       */
+-
+-      spin_lock(&Daemon_Queue.lock);
+-      que = (daemon_command_t *)Daemon_Queue.list.next;
+-
+-      DbgPrint( "Daemon_Close_Control: que=0x%x\n", que);
+-
+-      while (que && (que != (daemon_command_t *)&Daemon_Queue.list.next) && (que->status != QUEUE_DONE))
+-      {
+-         que->status = QUEUE_TIMEOUT;
+-         up(&que->semaphore);
+-
+-         que = (daemon_command_t *)que->list.next;
+-         DbgPrint( "Daemon_Close_Control: que1=0x%x\n", que);
+-      }
+-      spin_unlock(&Daemon_Queue.lock);
+-
+-      RemoveDriveMaps();
+-
+-      Scope_Cleanup();
+-   }
+-
+-   return(0);
+-}
+-
+-/*++======================================================================*/
+-ssize_t 
+-Daemon_Send_Command(struct file *file, char *buf, size_t len, loff_t *off)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   daemon_command_t *que;
+-   size_t retValue = 0;
+-   int Finished=0;
+-   PDATA_LIST dlist;
+-   int i, dcnt, bcnt, ccnt, error;
+-   char *vadr;
+-   u_long cpylen;
+-
+-   DbgPrint( "Daemon_Send_Command: %u %lld\n", len, *off);
+-   if (len > MaxIoSize)
+-   {
+-      MaxIoSize = len;
+-   }
+-
+-   while ( !Finished )
+-   {
+-      que = get_next_queue(1);
+-      DbgPrint( "Daemon_Send_Command: 0x%x\n", que);
+-      if (que)
+-      {
+-         retValue = que->reqlen;
+-         if (retValue > len)
+-         {
+-            retValue = len;
+-         }
+-         if (retValue > 0x80)
+-            mydump(0x80, que->request);
+-         else
+-            mydump(retValue, que->request);
+-
+-         cpylen = copy_to_user(buf, que->request, retValue);
+-         if (que->datalen && (retValue < len))
+-         {
+-            buf += retValue;
+-            dlist = que->data;
+-            dcnt  = que->datalen;
+-            for (i=0; i<dcnt; i++, dlist++)
+-            {
+-               if ( DLREAD == dlist->rwflag )
+-               {
+-                  bcnt = dlist->len;
+-                  DbgPrint("Daemon_Send_Command%d: page=0x%x offset=0x%x len=%d\n", i, dlist->page, dlist->offset, dlist->len);
+-                  if ((bcnt + retValue) <= len)
+-                  {
+-                     void *km_adr=NULL;
+-
+-                     if (dlist->page)
+-                     {
+-                        //vadr = kmap(dlist->page);
+-                        km_adr = kmap_atomic(dlist->page, KM_USER1);
+-                        vadr = km_adr;
+-                        vadr += (u_int)dlist->offset;
+-                     }
+-                     else
+-                     {
+-                        vadr = dlist->offset;
+-                     }
+-
+-                     ccnt = copy_to_user(buf, vadr, bcnt);
+-
+-                     if ( km_adr )
+-                     {
+-                        //kunmap(dlist->page);
+-                        kunmap_atomic(km_adr, KM_USER1);
+-                     }
+-
+-                     DbgPrint("Daemon_Send_Command: Copy %d from 0x%x to 0x%x.\n", bcnt, vadr, buf);
+-                     if (bcnt > 0x80)
+-                        mydump(0x80, vadr);
+-                     else
+-                        mydump(bcnt, vadr);
+-
+-                     retValue += bcnt;
+-                     buf += bcnt;
+-                  }
+-                  else
+-                  {
+-                     break;
+-                  }
+-               }
+-            }
+-         }
+-         Queue_put( que );
+-         break;
+-      }
+-
+-      if (O_NONBLOCK & file->f_flags)
+-      {
+-         retValue = -EAGAIN;
+-         break;
+-      }
+-      else
+-      {
+-         if ((error = down_interruptible(&Daemon_Queue.semaphore)))
+-         {
+-            DbgPrint( "Daemon_Send_Command: after down_interruptible error...%d\n", error);
+-            retValue = -EINTR;
+-            break;
+-         }
+-         DbgPrint( "Daemon_Send_Command: after down_interruptible\n");
+-      }
+-   }
+-
+-   *off = *off;
+-
+-   DbgPrint( "Daemon_Send_Command: return 0x%x\n", retValue);
+-
+-   return(retValue);
+-}
+-
+-/*++======================================================================*/
+-ssize_t
+-Daemon_Receive_Reply(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   daemon_command_t *que;
+-   size_t retValue = 0;
+-   void *reply;
+-   u_long sequence, cpylen;
+-
+-   PDATA_LIST dlist;
+-   char *vadr;
+-   int i;
+-
+-   DbgPrint( "Daemon_Receive_Reply: buf=0x%x nbytes=%d ppos=%llx\n", buf, nbytes, *ppos);
+-
+-   /*
+-    * Get sequence number from reply buffer
+-    */
+-
+-   cpylen = copy_from_user(&sequence, buf, sizeof(sequence));
+-
+-   /*
+-    * Find item based on sequence number
+-    */
+-   que = find_queue(sequence);
+-
+-   DbgPrint( "Daemon_Receive_Reply: 0x%x 0x%x %d\n", sequence, que, nbytes);
+-   if (que)
+-   {
+-      do
+-      {
+-         retValue = nbytes;
+-         /*
+-          * Ack packet from novfsd.  Remove timer and
+-          * return
+-          */
+-         if (nbytes == sizeof(sequence))
+-         {
+-            que->status = QUEUE_ACKED;
+-            break;
+-         }
+-
+-         /*
+-          * Set status that packet is done.
+-          */
+-         que->status = QUEUE_DONE;
+-
+-         if ( NULL != (dlist = que->data) )
+-         {
+-            int thiscopy, left=nbytes;
+-            retValue = 0;
+-
+-
+-            DbgPrint( "Daemon_Receive_Reply: dlist=0x%x count=%d\n", dlist, que->datalen);
+-            for (i=0; i < que->datalen; i++, dlist++)
+-            {
+-               DbgPrint( "Daemon_Receive_Reply:\n" \
+-                         "   dlist[%d].page:   0x%x\n" \
+-                         "   dlist[%d].offset: 0x%x\n" \
+-                         "   dlist[%d].len:    0x%x\n" \
+-                         "   dlist[%d].rwflag: 0x%x\n",
+-                  i, dlist->page,
+-                  i, dlist->offset,
+-                  i, dlist->len,
+-                  i, dlist->rwflag);
+-
+-               if (DLWRITE == dlist->rwflag)
+-               {
+-                  void *km_adr=NULL;
+-
+-                  if (dlist->page)
+-                  {
+-                     //vadr = kmap(dlist->page);
+-                     km_adr = kmap_atomic(dlist->page, KM_USER1);
+-                     vadr = km_adr;
+-                     vadr += (u_int)dlist->offset;
+-                  }
+-                  else
+-                  {
+-                     vadr = dlist->offset;
+-                  }
+-                  
+-                  thiscopy = dlist->len;
+-                  if (thiscopy > left)
+-                  {
+-                     thiscopy = left;
+-                     dlist->len = left;
+-                  }
+-                  cpylen = copy_from_user(vadr, buf, thiscopy);
+-
+-                  if ( km_adr )
+-                  {
+-                     //kunmap(dlist->page);
+-                     kunmap_atomic(km_adr, KM_USER1);
+-                  }
+-
+-                  left -= thiscopy;
+-                  retValue += thiscopy;
+-                  buf += thiscopy;
+-               }
+-            }
+-         }
+-         else
+-         {
+-            reply = Novfs_Malloc(nbytes, GFP_KERNEL);
+-            DbgPrint( "Daemon_Receive_Reply: reply=0x%x\n", reply);
+-            if (reply)
+-            {
+-               retValue = nbytes;
+-               que->reply = reply;
+-               que->replen = nbytes;
+-
+-               retValue -= copy_from_user(reply, buf, retValue);
+-               if (retValue > 0x80)
+-                  mydump(0x80, reply);
+-               else
+-                  mydump(retValue, reply);
+-
+-
+-            }
+-            else
+-            {
+-               retValue = -ENOMEM;
+-            }
+-         }
+-      } while (0);
+-      up(&que->semaphore);
+-      Queue_put( que );
+-   } 
+-
+-   DbgPrint( "Daemon_Receive_Reply: return 0x%x\n", retValue);
+-
+-   return(retValue);
+-}
+-
+-/*++======================================================================*/
+-int do_login(NclString *Server, NclString *Username, NclString *Password, u_long *lgnId, session_t Session)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PLOGIN_USER_REQUEST cmd;
+-   PLOGIN_USER_REPLY   reply;
+-   u_long replylen=0;
+-   int retCode, cmdlen, datalen;
+-   u_char *data;
+-
+-   datalen = Server->len+Username->len+Password->len;
+-   cmdlen = sizeof(*cmd) + datalen;
+-   cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-   if (cmd)
+-   {
+-      data = (u_char *)cmd + sizeof(*cmd);
+-      cmd->Command.CommandType    = VFS_COMMAND_LOGIN_USER;
+-      cmd->Command.SequenceNumber = 0;
+-      cmd->Command.SessionId      = Session;
+-
+-      cmd->srvNameType    = Server->type;
+-      cmd->serverLength   = Server->len;
+-      cmd->serverOffset   = (u_long)(data-(u_char *)cmd);
+-      memcpy(data, Server->buffer, Server->len);
+-      data += Server->len;
+-
+-      cmd->usrNameType    = Username->type;
+-      cmd->userNameLength = Username->len;
+-      cmd->userNameOffset = (u_long)(data-(u_char *)cmd);
+-      memcpy(data, Username->buffer, Username->len);
+-      data += Username->len;
+-
+-      cmd->pwdNameType    = Password->type;
+-      cmd->passwordLength = Password->len;
+-      cmd->passwordOffset = (u_long)(data-(u_char *)cmd);
+-      memcpy(data, Password->buffer, Password->len);
+-      data += Password->len;
+-
+-      retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+-      if (reply)
+-      {
+-         if (reply->Reply.ErrorCode)
+-         {
+-            retCode = reply->Reply.ErrorCode;
+-         }
+-         else
+-         {
+-            retCode = 0;
+-            if (lgnId)
+-            {
+-               *lgnId = reply->loginIdentity;
+-            }
+-         }
+-         Novfs_Free(reply);
+-      }
+-      memset(cmd, 0, cmdlen);
+-      Novfs_Free(cmd);
+-   }
+-   else
+-   {
+-      retCode = -ENOMEM;
+-   }
+-   return( retCode );
+-
+-}
+-
+-/*++======================================================================*/
+-int do_logout( struct qstr *Server, session_t Session )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PLOGOUT_REQUEST cmd;
+-   PLOGOUT_REPLY   reply;
+-   u_long replylen=0;
+-   int retCode, cmdlen;
+-
+-   cmdlen = (int)(&((PLOGOUT_REQUEST)0)->Name) + Server->len;
+-   cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-   if (cmd)
+-   {
+-      cmd->Command.CommandType    = VFS_COMMAND_LOGOUT_USER;
+-      cmd->Command.SequenceNumber = 0;
+-      cmd->Command.SessionId      = Session;
+-
+-      cmd->Length   = Server->len;
+-      memcpy(cmd->Name, Server->name, Server->len);
+-
+-      retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+-      if (reply)
+-      {
+-         if (reply->Reply.ErrorCode)
+-         {
+-            retCode = -EIO;
+-         }
+-         Novfs_Free(reply);
+-      }
+-      Novfs_Free(cmd);
+-   }
+-   else
+-   {
+-      retCode = -ENOMEM;
+-   }
+-   return( retCode );
+-
+-}
+-
+-/*++======================================================================*/
+-int Daemon_getpwuid( uid_t uid, int unamelen, char *uname )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   GETPWUID_REQUEST cmd;
+-   PGETPWUID_REPLY  reply;
+-   u_long replylen=0;
+-   int retCode;
+-
+-   cmd.Command.CommandType    = VFS_COMMAND_GETPWUD;
+-   cmd.Command.SequenceNumber = 0;
+-   cmd.Command.SessionId      = 0;
+-   cmd.uid = uid;
+-
+-   retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+-   if (reply)
+-   {
+-      if (reply->Reply.ErrorCode)
+-      {
+-         retCode = -EIO;
+-      }
+-      else
+-      {
+-         retCode = 0;
+-         memset(uname, 0, unamelen);
+-         replylen = replylen - (int)(&((PGETPWUID_REPLY)0)->UserName);
+-         if (replylen)
+-         {
+-            if (replylen > unamelen)
+-            {
+-               retCode = -EINVAL;
+-               replylen = unamelen-1;
+-            }
+-            memcpy(uname, reply->UserName, replylen);
+-         }
+-      }
+-      Novfs_Free(reply);
+-   }
+-   return( retCode );
+-
+-}
+-
+-/*++======================================================================*/
+-int Daemon_getversion( char *Buf, int Length )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   GET_VERSION_REQUEST cmd;
+-   PGET_VERSION_REPLY  reply;
+-   u_long replylen=0;
+-   int retVal=0;
+-
+-   cmd.Command.CommandType    = VFS_COMMAND_GET_VERSION;
+-   cmd.Command.SequenceNumber = 0;
+-   cmd.Command.SessionId      = 0;
+-
+-   Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+-   if (reply)
+-   {
+-      if (reply->Reply.ErrorCode)
+-      {
+-         retVal = -EIO;
+-      }
+-      else
+-      {
+-         retVal = replylen - (int)(&((PGET_VERSION_REPLY)0)->Version);
+-         if (retVal < Length)
+-         {
+-            memcpy(Buf, reply->Version, retVal);
+-            Buf[retVal] = '\0';
+-         }
+-      }
+-      Novfs_Free(reply);
+-   }
+-   return( retVal );
+-
+-}
+-
+-/*++======================================================================*/
+-int Daemon_Login(PLOGIN Login, session_t Session)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   int retCode = -ENOMEM;
+-   LOGIN lLogin;
+-   NclString   server;
+-   NclString   username;
+-   NclString   password;
+-
+-   if ( !copy_from_user(&lLogin, Login, sizeof(lLogin)))
+-   {
+-      if ( (server.buffer = Novfs_Malloc(lLogin.Server.Length, GFP_KERNEL)) )
+-      {
+-         server.len = lLogin.Server.Length;
+-         server.type = NWC_STRING_TYPE_ASCII;
+-         if ( !copy_from_user((void *)server.buffer, lLogin.Server.Data, server.len) )
+-         {
+-            if ( (username.buffer = Novfs_Malloc(lLogin.UserName.Length, GFP_KERNEL)) )
+-            {
+-               username.len = lLogin.UserName.Length;
+-               username.type = NWC_STRING_TYPE_ASCII;
+-               if ( !copy_from_user((void *)username.buffer, lLogin.UserName.Data, username.len) )
+-               {
+-                  if ( (password.buffer = Novfs_Malloc(lLogin.Password.Length, GFP_KERNEL)) )
+-                  {
+-                     password.len = lLogin.Password.Length;
+-                     password.type = NWC_STRING_TYPE_ASCII;
+-                     if ( !copy_from_user((void *)password.buffer, lLogin.Password.Data, password.len) )
+-                     {
+-                        retCode = do_login(&server, &username, &password, NULL, Session);
+-                        if ( !retCode )
+-                        {
+-                           char *username;
+-                           username = Scope_Get_UserName( NULL );
+-                           if (username)
+-                           {
+-                              Novfs_Add_to_Root( username );
+-                           }
+-                        }
+-                     }
+-                     memset(password.buffer, 0, password.len);
+-                     Novfs_Free(password.buffer);
+-                  }
+-               }
+-               memset(username.buffer, 0, username.len);
+-               Novfs_Free(username.buffer);
+-            }
+-         }
+-         Novfs_Free(server.buffer);
+-      }
+-   }
+-
+-   return( retCode );
+-}
+-
+-/*++======================================================================*/
+-int Daemon_Logout(PLOGOUT Logout, session_t Session)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   LOGOUT lLogout;
+-   struct qstr server;
+-   int retCode=0;
+-
+-   if ( !copy_from_user(&lLogout, Logout, sizeof(lLogout)))
+-   {
+-      if ( (server.name = Novfs_Malloc(lLogout.Server.Length, GFP_KERNEL)) )
+-      {
+-         server.len = lLogout.Server.Length;
+-         if ( !copy_from_user((void *)server.name, lLogout.Server.Data, server.len) )
+-         {
+-            retCode = do_logout( &server, Session );
+-         }
+-         Novfs_Free(server.name);
+-      }
+-   }
+-   return( retCode );
+-}
+-
+-/*++======================================================================*/
+-int Daemon_CreateSessionId( uint64_t *SessionId )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   CREATE_CONTEXT_REQUEST cmd;
+-   PCREATE_CONTEXT_REPLY  reply;
+-   u_long replylen=0;
+-   int retCode=0;
+-
+-   DbgPrint("Daemon_CreateSessionId: %d\n", current->pid);
+-
+-   cmd.Command.CommandType = VFS_COMMAND_CREATE_CONTEXT;
+-   cmd.Command.SequenceNumber = 0;
+-   cmd.Command.SessionId = 0;
+-
+-   retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+-   if ( reply )
+-   {
+-      if ( !reply->Reply.ErrorCode  && replylen > sizeof(COMMAND_REPLY_HEADER))
+-      {
+-         *SessionId = reply->SessionId;
+-         retCode = 0;
+-      }
+-      else
+-      {
+-         *SessionId = 0;
+-         retCode = -EIO;
+-      }
+-      Novfs_Free(reply);
+-   }
+-   DbgPrint("Daemon_CreateSessionId: SessionId=0x%llx\n", *SessionId);
+-   return(retCode);
+-}
+-
+-/*++======================================================================*/
+-int Daemon_DestroySessionId( uint64_t SessionId )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   DESTROY_CONTEXT_REQUEST cmd;
+-   PDESTROY_CONTEXT_REPLY  reply;
+-   u_long replylen=0;
+-   int retCode=0;
+-
+-   DbgPrint("Daemon_DestroySessionId: 0x%llx\n", SessionId);
+-
+-   cmd.Command.CommandType = VFS_COMMAND_DESTROY_CONTEXT;
+-   cmd.Command.SequenceNumber = 0;
+-   cmd.Command.SessionId = SessionId;
+-
+-   retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+-   if ( reply )
+-   {
+-      if ( !reply->Reply.ErrorCode )
+-      {
+-         drive_map_t *dm;
+-         struct list_head *list;
+-
+-         retCode = 0;
+-
+-         /*
+-          * When destroying the session check to see if there are any
+-          * mapped drives.  If there are then remove them.
+-          */
+-         down( &DriveMapLock );
+-         list_for_each( list, &DriveMapList )
+-         {
+-            dm = list_entry( list, drive_map_t, list );
+-            if ( SessionId == dm->session)
+-            {
+-                local_unlink( dm->name );
+-                list = list->prev;
+-                list_del( &dm->list );
+-                Novfs_Free( dm );
+-            }
+-
+-         }
+-         up( &DriveMapLock );
+-
+-      }
+-      else
+-      {
+-         retCode = -EIO;
+-      }
+-      Novfs_Free(reply);
+-   }
+-   return(retCode);
+-}
+-
+-/*++======================================================================*/
+-int Daemon_Get_UserSpace( uint64_t SessionId, uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   GET_USER_SPACE_REQUEST cmd;
+-   PGET_USER_SPACE_REPLY  reply;
+-   u_long replylen=0;
+-   int retCode=0;
+-
+-   DbgPrint("Daemon_Get_UserSpace: 0x%llx\n", SessionId);
+-
+-   cmd.Command.CommandType = VFS_COMMAND_GET_USER_SPACE;
+-   cmd.Command.SequenceNumber = 0;
+-   cmd.Command.SessionId = SessionId;
+-
+-   retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+-   if ( reply )
+-   {
+-      if ( !reply->Reply.ErrorCode )
+-      {
+-
+-         DbgPrint("TotalSpace:  %llu\n", reply->TotalSpace);
+-         DbgPrint("FreeSpace:   %llu\n", reply->FreeSpace);
+-         DbgPrint("TotalEnties: %llu\n", reply->TotalEnties);
+-         DbgPrint("FreeEnties:  %llu\n", reply->FreeEnties);
+-
+-         if (TotalSize)   *TotalSize   = reply->TotalSpace;
+-         if (Free)        *Free        = reply->FreeSpace;
+-         if (TotalEnties) *TotalEnties = reply->TotalEnties;
+-         if (FreeEnties)  *FreeEnties  = reply->FreeEnties;
+-         retCode = 0;
+-      }
+-      else
+-      {
+-         retCode = -EIO;
+-      }
+-      Novfs_Free(reply);
+-   }
+-   return(retCode);
+-}
+-
+-/*++======================================================================*/
+-int Daemon_SetMountPoint ( char *Path )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PSET_MOUNT_PATH_REQUEST cmd;
+-   PSET_MOUNT_PATH_REPLY  reply;
+-   u_long replylen, cmdlen;
+-   int retCode = -ENOMEM;
+-
+-   DbgPrint("Daemon_SetMountPoint: %s\n", Path);
+-   
+-   replylen = strlen(Path);
+-
+-   cmdlen = sizeof(SET_MOUNT_PATH_REQUEST) + replylen;
+-
+-   cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-   if ( cmd )
+-   {
+-      cmd->Command.CommandType = VFS_COMMAND_SET_MOUNT_PATH;
+-      cmd->Command.SequenceNumber = 0;
+-      cmd->Command.SessionId = 0;
+-      cmd->PathLength = replylen;
+-
+-      strcpy(cmd->Path, Path);
+-
+-      replylen = 0;
+-
+-      retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+-      if ( reply )
+-      {
+-         if ( !reply->Reply.ErrorCode )
+-         {
+-            retCode = 0;
+-         }
+-         else
+-         {
+-            retCode = -EIO;
+-         }
+-         Novfs_Free(reply);
+-      }
+-      Novfs_Free(cmd);
+-   }
+-   return(retCode);
+-}
+-
+-/*++======================================================================*/
+-int Daemon_SendDebugCmd ( char *Command )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   DEBUG_REQUEST cmd;
+-   PDEBUG_REPLY  reply;
+-   DEBUG_REPLY   lreply;
+-   u_long replylen, cmdlen;
+-   DATA_LIST dlist[2];
+-
+-   int retCode = -ENOMEM;
+-
+-   DbgPrint("Daemon_SendDebugCmd: %s\n", Command);
+-   
+-   dlist[0].page   = NULL;
+-   dlist[0].offset = (char *)Command;
+-   dlist[0].len    = strlen(Command);
+-   dlist[0].rwflag = DLREAD;
+-
+-   dlist[1].page   = NULL;
+-   dlist[1].offset = (char *)&lreply;
+-   dlist[1].len    = sizeof(lreply);
+-   dlist[1].rwflag = DLWRITE;
+-
+-   cmdlen = (int)(&((PDEBUG_REQUEST)0)->dbgcmd);
+-
+-   cmd.Command.CommandType = VFS_COMMAND_DBG;
+-   cmd.Command.SequenceNumber = 0;
+-   cmd.Command.SessionId = 0;
+-   cmd.cmdlen = strlen(Command);
+-
+-   replylen = 0;
+-
+-   retCode = Queue_Daemon_Command(&cmd, cmdlen, dlist, 2, (void *)&reply, &replylen, INTERRUPTIBLE);
+-   if ( reply )
+-   {
+-      Novfs_Free(reply);
+-   }
+-   if (0 == retCode)
+-   {
+-      retCode = lreply.Reply.ErrorCode;
+-   }
+-
+-   return(retCode);
+-}
+-
+-/*++======================================================================*/
+-int 
+-NO_TRACE
+-Daemon_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u_long arg)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   int retCode = -ENOSYS;
+-   u_long cpylen;
+-
+-
+-   switch (cmd)
+-   {
+-      case IOC_LOGIN:
+-      {
+-         retCode = Daemon_Login((PLOGIN)arg, Scope_Get_SessionId( NULL ));
+-         break;
+-      }
+-
+-      case IOC_LOGOUT:
+-      {
+-         retCode = Daemon_Logout((PLOGOUT)arg, Scope_Get_SessionId( NULL ));
+-         break;
+-      }
+-      case IOC_DEBUGPRINT:
+-      {
+-         struct Ioctl_Debug {
+-            int length;
+-            char *data;
+-         } io;
+-         char *buf;
+-         io.length = 0;
+-         cpylen = copy_from_user(&io, (char *)arg, sizeof(io));
+-         if (io.length)
+-         {
+-            buf = Novfs_Malloc(io.length+1, GFP_KERNEL);
+-            if (buf)
+-            {
+-               buf[0] = 0;
+-               cpylen = copy_from_user(buf, io.data, io.length);
+-               buf[io.length] = '\0';
+-               if( DbgDaemonLogOn )
+-                  printk("%s", buf);
+-               else
+-                  DbgPrint("%s", buf);
+-               Novfs_Free(buf);
+-               retCode = 0;
+-            }
+-         }
+-         break;
+-      }
+-
+-      case IOC_XPLAT:
+-      {
+-         XPLAT   data;
+-
+-         cpylen = copy_from_user(&data, (void *)arg, sizeof(data));
+-         retCode = ((data.xfunction & 0x0000FFFF) | 0xCC000000);
+-
+-         switch(data.xfunction)
+-         {
+-            case NWC_GET_MOUNT_PATH:
+-               DbgPrint("[Daemon_ioctl] Call NwdGetMountPath\n");
+-               retCode = NwdGetMountPath( &data );
+-               break;
+-         }
+-
+-         DbgPrint("[NOVFS XPLAT] status Code = %X\n", retCode);
+-         break;
+-      }
+-
+-   }
+-   return (retCode);
+-}
+-
+-/*++======================================================================*/
+-int Daemon_Added_Resource(daemon_handle_t *DHandle, int Type, u_long CHandle, u_char *FHandle, u_long Mode, u_long Size)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   daemon_resource_t *resource;
+-   int retVal = NWE_OUT_OF_HEAP_SPACE;
+-
+-   if (FHandle)
+-      DbgPrint("Daemon_Added_Resource: DHandle=0x%p Type=%d CHandle=0x%x FHandle=0x%x Mode=0x%x Size=%d\n", DHandle, Type, CHandle, *(u_long *)&FHandle[2], Mode, Size);
+-   else
+-      DbgPrint("Daemon_Added_Resource: DHandle=0x%p Type=%d CHandle=0x%x\n", DHandle, Type, CHandle);
+-
+-   resource = Novfs_Malloc(sizeof(daemon_resource_t), GFP_KERNEL);
+-   if (resource)
+-   {
+-      resource->type = Type;
+-      resource->connection = CHandle;
+-      if (FHandle)
+-      {
+-         memcpy( resource->handle, FHandle, sizeof(resource->handle) );
+-      }
+-      else
+-      {
+-         memset( resource->handle, 0, sizeof(resource->handle) );
+-      }
+-      resource->mode = Mode; 
+-      resource->size = Size;
+-      write_lock( &DHandle->lock );
+-      list_add( &resource->list, &DHandle->list );
+-      write_unlock( &DHandle->lock );
+-      DbgPrint("Daemon_Added_Resource: Adding resource=0x%p\n", resource);
+-      retVal = 0;
+-   }
+-
+-   return(retVal);
+-}
+-
+-/*++======================================================================*/
+-int Daemon_Remove_Resource(daemon_handle_t *DHandle, int Type, u_long CHandle, u_long FHandle)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   daemon_resource_t *resource;
+-   struct list_head *l;
+-   int retVal = -ENOMEM;
+-
+-   DbgPrint("Daemon_Remove_Resource: DHandle=0x%p Type=%d CHandle=0x%x FHandle=0x%x\n", DHandle, Type, CHandle, FHandle);
+-
+-   write_lock( &DHandle->lock );
+-      
+-   list_for_each( l, &DHandle->list )
+-   {
+-      resource = list_entry( l, daemon_resource_t, list );
+-      
+-      if ( (Type == resource->type) &&
+-           (resource->connection == CHandle) )
+-      {
+-         DbgPrint("Daemon_Remove_Resource: Found resource=0x%p\n", resource);
+-         l = l->prev;
+-         list_del( &resource->list );
+-         Novfs_Free( resource );
+-         break;
+-      }
+-   }
+-
+-   write_unlock( &DHandle->lock );
+-
+-   return(retVal);
+-}
+-
+-/*++======================================================================*/
+-int Daemon_Library_open(struct inode *inode, struct file *file)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   int retVal = -ENOMEM;
+-   daemon_handle_t *dh;
+-
+-   DbgPrint("Daemon_Library_open: inode=0x%p file=0x%p\n", inode, file);
+-
+-   if ((dh = Novfs_Malloc(sizeof(daemon_handle_t), GFP_KERNEL)))
+-   {
+-      file->private_data = dh;
+-      INIT_LIST_HEAD( &dh->list);
+-      rwlock_init( &dh->lock );
+-      dh->session = Scope_Get_SessionId( NULL );
+-      retVal = 0;
+-   }
+-   return(retVal); 
+-}
+-
+-/*++======================================================================*/
+-int Daemon_Library_close(struct inode *inode, struct file *file)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   daemon_handle_t *dh;
+-   daemon_resource_t *resource;
+-   struct list_head *l;
+-
+-   char commanddata[sizeof(XPLAT_CALL_REQUEST)+sizeof(NwdCCloseConn)];
+-   PXPLAT_CALL_REQUEST  cmd;
+-   PXPLAT_CALL_REPLY		reply;
+-   PNwdCCloseConn			nwdClose;
+-   u_long			cmdlen, replylen;
+-
+-   DbgPrint("Daemon_Library_close: inode=0x%p file=0x%p\n", inode, file);
+-   if (file->private_data)
+-   {
+-      dh = (daemon_handle_t *)file->private_data;
+-
+-      list_for_each( l, &dh->list )
+-      {
+-         resource = list_entry( l, daemon_resource_t, list );
+-         
+-         if (DH_TYPE_STREAM == resource->type)
+-         {
+-            Novfs_Close_Stream( resource->connection, resource->handle, dh->session );
+-         }
+-         else if (DH_TYPE_CONNECTION == resource->type)
+-         {
+-	         cmd = (PXPLAT_CALL_REQUEST)commanddata;
+-	         cmdlen = offsetof(XPLAT_CALL_REQUEST, data) + sizeof(NwdCCloseConn);
+-		      cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-		      cmd->Command.SequenceNumber = 0;
+-		      cmd->Command.SessionId      = dh->session;
+-		      cmd->NwcCommand = NWC_CLOSE_CONN;
+-
+-		      cmd->dataLen = sizeof(NwdCCloseConn);
+-		      nwdClose = (PNwdCCloseConn)cmd->data;
+-		      nwdClose->ConnHandle = resource->connection;
+-
+-		      Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, 0);
+-		      if (reply)
+-		      {
+-			      Novfs_Free(reply);
+-		      }
+-         }
+-         l = l->prev;
+-         list_del( &resource->list );
+-         Novfs_Free( resource );
+-      }
+-      Novfs_Free(dh);
+-      file->private_data = NULL;
+-	}
+-
+-   return(0);
+-}
+-
+-/*++======================================================================*/
+-ssize_t Daemon_Library_read(struct file *file, char *buf, size_t len, loff_t *off)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   daemon_handle_t *dh;
+-   daemon_resource_t *resource;
+-
+-   size_t thisread, totalread=0;
+-   loff_t offset = *off;
+-
+-   DbgPrint("Daemon_Library_read: file=0x%p len=%d off=%lld\n",  file, len, *off);
+-
+-   if (file->private_data)
+-   {
+-      dh = file->private_data;
+-      read_lock( &dh->lock );
+-      if (&dh->list != dh->list.next)
+-      {
+-         resource = list_entry( dh->list.next, daemon_resource_t, list );
+-         
+-         if (DH_TYPE_STREAM == resource->type)
+-         {
+-            while( len > 0 && (offset < resource->size) )
+-            {
+-               thisread = len;
+-               if (Novfs_Read_Stream(resource->connection, 
+-                                     resource->handle, 
+-                                     buf, &thisread, 
+-                                     &offset, 1, 
+-                                     dh->session) || !thisread)
+-               {
+-                  break;
+-               }
+-               len -= thisread;
+-               buf += thisread;
+-               offset += thisread;
+-               totalread += thisread;
+-            }
+-         }
+-      }
+-      read_unlock( &dh->lock );
+-   }
+-   *off = offset;
+-   DbgPrint("Daemon_Library_read return = 0x%x\n", totalread);
+-   return(totalread);
+-}
+-
+-/*++======================================================================*/
+-ssize_t Daemon_Library_write(struct file *file, const char *buf, size_t len, loff_t *off)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   daemon_handle_t *dh;
+-   daemon_resource_t *resource;
+-
+-   size_t thiswrite, totalwrite=-EINVAL;
+-   loff_t offset = *off;
+-   int status;
+-
+-   DbgPrint("Daemon_Library_write: file=0x%p len=%d off=%lld\n",  file, len, *off);
+-
+-   if (file->private_data)
+-   {
+-      dh = file->private_data;
+-      write_lock( &dh->lock );
+-      if (&dh->list != dh->list.next)
+-      {
+-         resource = list_entry( dh->list.next, daemon_resource_t, list );
+-         
+-         if ( (DH_TYPE_STREAM == resource->type) && (len >= 0) )
+-         {
+-            totalwrite = 0;
+-            do
+-            {
+-               thiswrite = len;
+-               status = Novfs_Write_Stream(resource->connection, 
+-                                           resource->handle, 
+-                                           (PVOID)buf, 
+-                                           &thiswrite, 
+-                                           &offset, 
+-                                           dh->session);
+-               if ( status || !thiswrite )
+-               {
+-                  /*
+-                   * If len is zero then the file will have just been 
+-                   * truncated to offset.  Update size.
+-                   */
+-                  if ( !status && !len )
+-                  {
+-                     resource->size = offset;
+-                  }
+-                  totalwrite = status;
+-                  break;
+-               }
+-               len -= thiswrite;
+-               buf += thiswrite;
+-               offset += thiswrite;
+-               totalwrite += thiswrite;
+-               if (offset > resource->size)
+-               {
+-                  resource->size = offset;
+-               }
+-            } while(len > 0);
+-         }
+-      }
+-      write_unlock( &dh->lock );
+-   }
+-   *off = offset;
+-   DbgPrint("Daemon_Library_write return = 0x%x\n", totalwrite);
+-
+-   return(totalwrite);
+-}
+-
+-/*++======================================================================*/
+-loff_t Daemon_Library_llseek(struct file *file, loff_t offset, int origin)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   daemon_handle_t *dh;
+-   daemon_resource_t *resource;
+-
+-	loff_t retVal = -EINVAL;
+-
+-   DbgPrint("Daemon_Library_llseek: file=0x%p offset=%lld origin=%d\n", file, offset, origin);
+-
+-   if (file->private_data)
+-   {
+-      dh = file->private_data;
+-      read_lock( &dh->lock );
+-      if (&dh->list != dh->list.next)
+-      {
+-         resource = list_entry( dh->list.next, daemon_resource_t, list );
+-         
+-         if (DH_TYPE_STREAM == resource->type)
+-         {
+-	         switch (origin) {
+-		         case 2:
+-			         offset += resource->size;
+-			         break;
+-		         case 1:
+-			         offset += file->f_pos;
+-	         }
+-	         if (offset >= 0) {
+-		         if (offset != file->f_pos) {
+-			         file->f_pos = offset;
+-			         file->f_version = 0;
+-		         }
+-		         retVal = offset;
+-	         }
+-         }
+-      }
+-      read_unlock( &dh->lock );
+-   }
+-
+-   DbgPrint("Daemon_Library_llseek: ret %lld\n", retVal);
+-
+-	return retVal;
+-}
+-
+-/*++======================================================================*/
+-int 
+-NO_TRACE
+-Daemon_Library_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u_long arg)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   int retCode = -ENOSYS;
+-   daemon_handle_t *dh;
+-   u_long handle=0, cpylen;
+-
+-
+-   dh = file->private_data;
+-
+-   DbgPrint("Daemon_Library_ioctl: file=0x%p 0x%x 0x%x dh=0x%p\n", file, cmd, arg, dh);
+-
+-   if (dh)
+-   {
+-
+-      switch (cmd)
+-      {
+-         case IOC_LOGIN:
+-         {
+-            retCode = Daemon_Login((PLOGIN)arg, dh->session);
+-            break;
+-         }
+-
+-         case IOC_LOGOUT:
+-         {
+-            retCode = Daemon_Logout((PLOGOUT)arg, dh->session);
+-            break;
+-         }
+-
+-         case IOC_DEBUGPRINT:
+-         {
+-            struct Ioctl_Debug {
+-               int length;
+-               char *data;
+-            } io;
+-            char *buf;
+-            io.length = 0;
+-            cpylen = copy_from_user(&io, (char *)arg, sizeof(io));
+-            if (io.length)
+-            {
+-               buf = Novfs_Malloc(io.length+1, GFP_KERNEL);
+-               if (buf)
+-               {
+-                  buf[0] = 0;
+-                  cpylen = copy_from_user(buf, io.data, io.length);
+-                  buf[io.length] = '\0';
+-                  DbgPrint("%s", buf);
+-                  Novfs_Free(buf);
+-                  retCode = 0;
+-               }
+-            }
+-            break;
+-         }
+-
+-         case IOC_XPLAT:
+-         {
+-            XPLAT   data;
+-
+-            cpylen = copy_from_user(&data, (void *)arg, sizeof(data));
+-            retCode = ((data.xfunction & 0x0000FFFF) | 0xCC000000);
+-
+-            switch(data.xfunction)
+-            {
+-               case NWC_OPEN_CONN_BY_NAME:
+-                  DbgPrint("[VFS XPLAT] Call NwOpenConnByName\n");
+-                  retCode = NwOpenConnByName(&data, &handle, dh->session);
+-                  if ( !retCode )
+-                  {
+-                     Daemon_Added_Resource(dh, DH_TYPE_CONNECTION, handle, 0, 0, 0);
+-                  }
+-                  break;
+-
+-               case NWC_OPEN_CONN_BY_ADDRESS:
+-                  DbgPrint("[VFS XPLAT] Call NwOpenConnByAddress\n");
+-                  retCode = NwOpenConnByAddr(&data, &handle, dh->session);
+-                  if ( !retCode )
+-                  {
+-                     Daemon_Added_Resource(dh, DH_TYPE_CONNECTION, handle, 0, 0, 0);
+-                  }
+-                  break;
+-
+-               case NWC_OPEN_CONN_BY_REFERENCE:
+-
+-                  DbgPrint("[VFS XPLAT] Call NwOpenConnByReference\n");
+-                  retCode = NwOpenConnByRef(&data, &handle, dh->session);
+-                  if ( !retCode )
+-                  {
+-                     Daemon_Added_Resource(dh, DH_TYPE_CONNECTION, handle, 0, 0, 0);
+-                  }
+-                  break;
+-
+-               case NWC_SYS_CLOSE_CONN:
+-                  DbgPrint("[VFS XPLAT] Call NwSysCloseConn\n");
+-                  retCode = NwSysConnClose(&data, &handle, dh->session);
+-                  Daemon_Remove_Resource(dh, DH_TYPE_CONNECTION, handle, 0);
+-                  break;
+-
+-               case NWC_CLOSE_CONN:
+-                  DbgPrint("[VFS XPLAT] Call NwCloseConn\n");
+-                  retCode = NwConnClose(&data, &handle, dh->session);
+-                  Daemon_Remove_Resource(dh, DH_TYPE_CONNECTION, handle, 0);
+-                  break;
+-
+-               case NWC_LOGIN_IDENTITY:
+-                  DbgPrint("[VFS XPLAT] Call NwLoginIdentity\n");
+-                  retCode = NwLoginIdentity(&data, dh->session);
+-                  break;
+-
+-               case NWC_RAW_NCP_REQUEST:
+-                  DbgPrint("[VFS XPLAT] Send Raw NCP Request\n");
+-                  retCode = NwRawSend(&data, dh->session);
+-                  break;
+-
+-               case NWC_AUTHENTICATE_CONN_WITH_ID:
+-                  DbgPrint("[VFS XPLAT] Authenticate Conn With ID\n");
+-                  retCode = NwAuthConnWithId(&data, dh->session);
+-                  break;
+-
+-			      case NWC_UNAUTHENTICATE_CONN:
+-				      DbgPrint("[VFS XPLAT] UnAuthenticate Conn With ID\n");
+-				      retCode = NwUnAuthenticate(&data, dh->session);
+-   			      break;
+-
+-               case NWC_LICENSE_CONN:
+-                  DbgPrint("Call NwLicenseConn\n");
+-                  retCode = NwLicenseConn(&data, dh->session);
+-                  break;
+-
+-               case NWC_LOGOUT_IDENTITY:
+-                  DbgPrint("[VFS XPLAT] Call NwLogoutIdentity\n");
+-                  retCode = NwLogoutIdentity(&data, dh->session);
+-                  break;
+-
+-               case NWC_UNLICENSE_CONN:
+-                  DbgPrint("[VFS XPLAT] Call NwUnlicense\n");
+-                  retCode = NwUnlicenseConn(&data, dh->session);
+-                  break;
+-
+-               case NWC_GET_CONN_INFO:
+-                  DbgPrint("[VFS XPLAT] Call NwGetConnInfo\n");
+-                  retCode = NwGetConnInfo(&data, dh->session);
+-                  break;
+-
+-               case NWC_SET_CONN_INFO:
+-                  DbgPrint("[VFS XPLAT] Call NwGetConnInfo\n");
+-                  retCode = NwSetConnInfo(&data, dh->session);
+-                  break;
+-
+-               case NWC_SCAN_CONN_INFO:
+-                  DbgPrint("[VFS XPLAT] Call NwScanConnInfo\n");
+-                  retCode = NwScanConnInfo(&data, dh->session);
+-                  break;
+-
+-
+-               case NWC_GET_IDENTITY_INFO:
+-                  DbgPrint("[VFS XPLAT] Call NwGetIdentityInfo\n");
+-                  retCode = NwGetIdentityInfo(&data, dh->session);				
+-                  break;
+-
+-               case NWC_GET_REQUESTER_VERSION:
+-                  DbgPrint("[VFS XPLAT] Call NwGetDaemonVersion\n");
+-                  retCode = NwGetDaemonVersion(&data, dh->session);				
+-                  break;
+-
+-               case NWC_GET_PREFERRED_DS_TREE:
+-                  DbgPrint("[VFS XPLAT] Call NwcGetPreferredDsTree\n");
+-                  retCode = NwcGetPreferredDSTree(&data, dh->session);
+-                  break;
+-
+-               case NWC_SET_PREFERRED_DS_TREE:
+-                  DbgPrint("[VFS XPLAT] Call NwcSetPreferredDsTree\n");
+-                  retCode = NwcSetPreferredDSTree(&data, dh->session);
+-                  break;
+-
+-               case NWC_GET_DEFAULT_NAME_CONTEXT:
+-                  DbgPrint("[VFS XPLAT] Call NwcGetDefaultNameContext\n");
+-                  retCode = NwcGetDefaultNameCtx(&data, dh->session);
+-                  break;
+-
+-               case NWC_SET_DEFAULT_NAME_CONTEXT:
+-                  DbgPrint("[VFS XPLAT] Call NwcSetDefaultNameContext\n");
+-                  retCode = NwcSetDefaultNameCtx(&data, dh->session);
+-                  break;
+-
+-               case NWC_QUERY_FEATURE:
+-                  DbgPrint("[VFS XPLAT] Call NwQueryFeature\n");
+-                  retCode = NwQueryFeature(&data, dh->session);
+-                  break;
+-
+-
+-               case NWC_GET_TREE_MONITORED_CONN_REF:
+-                  DbgPrint("[VFS XPLAT] Call NwcGetTreeMonitoredConn\n");
+-                  retCode = NwcGetTreeMonitoredConn(&data, dh->session);
+-                  break;
+-
+-               case NWC_ENUMERATE_IDENTITIES:
+-                  DbgPrint("[VFS XPLAT] Call NwcEnumerateIdentities\n");
+-                  retCode = NwcEnumIdentities(&data, dh->session);
+-                  break;
+-
+-               case NWC_CHANGE_KEY:
+-                  DbgPrint("[VFS XPLAT] Call NwcChangeAuthKey\n");
+-                  retCode = NwcChangeAuthKey(&data, dh->session);
+-                  break;
+-
+-               case NWC_CONVERT_LOCAL_HANDLE:
+-                  DbgPrint("[VFS XPLAT] Call NwdConvertLocalHandle\n");
+-                  retCode = NwdConvertLocalHandle(&data, dh);
+-                  break;
+-                  
+-               case NWC_CONVERT_NETWARE_HANDLE:
+-                  DbgPrint("[VFS XPLAT] Call NwdConvertNetwareHandle\n");
+-                  retCode = NwdConvertNetwareHandle(&data, dh);
+-                  break;
+-
+-               case NWC_SET_PRIMARY_CONN:
+-                  DbgPrint("[VFS XPLAT] Call NwcSetPrimaryConn\n");
+-                  retCode = NwcSetPrimaryConn(&data, dh->session);
+-                  break;
+-
+-               case NWC_GET_PRIMARY_CONN:
+-                  DbgPrint("[VFS XPLAT] Call NwcGetPrimaryConn\n");
+-                  retCode = NwcGetPrimaryConn(&data, dh->session);
+-                  break;
+-
+-               case NWC_MAP_DRIVE:
+-                  DbgPrint("[VFS XPLAT] Call NwcMapDrive\n");
+-                  retCode = NwdSetMapDrive(&data, dh->session);
+-                  break;
+-
+-               case NWC_UNMAP_DRIVE:
+-                  DbgPrint("[VFS XPLAT] Call NwcUnMapDrive\n");
+-                  retCode = NwdUnMapDrive(&data, dh->session);
+-                  break;
+-
+-               case NWC_ENUMERATE_DRIVES:
+-                  DbgPrint("[VFS XPLAT] Call NwcEnumerateDrives\n");
+-                  retCode = NwcEnumerateDrives(&data, dh->session);
+-                  break;
+-
+-               case NWC_GET_MOUNT_PATH:
+-                  DbgPrint("[VFS XPLAT] Call NwdGetMountPath\n");
+-                  retCode = NwdGetMountPath( &data );
+-                  break;
+-
+-               case NWC_GET_BROADCAST_MESSAGE:
+-                  DbgPrint("[VSF XPLAT Call NwdGetBroadcastMessage\n");
+-                  retCode = NwcGetBroadcastMessage(&data, dh->session);
+-                  break;
+-
+-               case NWC_SET_KEY:
+-                  DbgPrint("[VSF XPLAT Call NwdSetKey\n");
+-                  retCode = NwdSetKeyValue(&data, dh->session);
+-                  break;
+-
+-               case NWC_VERIFY_KEY:
+-                  DbgPrint("[VSF XPLAT Call NwdVerifyKey\n");
+-                  retCode = NwdVerifyKeyValue(&data, dh->session);
+-                  break;
+-
+-               case NWC_RAW_NCP_REQUEST_ALL:
+-               case NWC_NDS_RESOLVE_NAME_TO_ID:
+-               case NWC_FRAGMENT_REQUEST:
+-               case NWC_GET_CONFIGURED_NSPS:
+-               default:
+-               break;
+-
+-            }
+-
+-            DbgPrint("[NOVFS XPLAT] status Code = %X\n", retCode);
+-            break;
+-         }
+-      }
+-   }
+-
+-   return( retCode );
+-}
+-
+-/*++======================================================================*/
+-unsigned int Daemon_Poll(struct file *file, struct poll_table_struct *poll_table)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   daemon_command_t *que;
+-   unsigned int mask = POLLOUT | POLLWRNORM;
+-   
+-   que = get_next_queue(0);
+-   if (que)
+-   {
+-      mask |= (POLLIN | POLLRDNORM);
+-   }
+-   else
+-   {
+-
+-   }
+-   return(mask);
+-}
+-
+-
+-void Daemon_Dumpque( void )
+-{
+-#ifdef	CONFIG_KDB
+-   daemon_command_t *que;
+-
+-   que = (daemon_command_t *)Daemon_Queue.list.next;
+-
+-   while (que && (que != (daemon_command_t *)&Daemon_Queue.list.next))
+-   {
+-      kdb_printf("DaemonQue:\n" \
+-                 "   Que:       0x%p\n" \
+-                 "   status:    0x%lx\n" \
+-                 "   flags:     0x%lx\n" \
+-                 "   semaphore: 0x%x\n" \
+-                 "   sequence:  0x%lx\n" \
+-                 "   timer:     0x%lx\n" \
+-                 "   request:   0x%p\n" \
+-                 "   reqlen:    %ld\n" \
+-                 "   data:      0x%p\n" \
+-                 "   datalen:   %d\n" \
+-                 "   reply:     0x%p\n" \
+-                 "   replen:    %ld\n",
+-         que,
+-         que->status,
+-         que->flags,
+-         atomic_read(&que->semaphore.count),
+-         que->sequence,
+-         que->timer.expires,
+-         que->request,
+-         que->reqlen,
+-         que->data,
+-         que->datalen,
+-         que->reply,
+-         que->replen);
+-      que = (daemon_command_t *)que->list.next;
+-   }
+-#endif
+-}
+-
+-/*++======================================================================*/
+-int NwdConvertNetwareHandle(PXPLAT pdata, daemon_handle_t *DHandle)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   int retVal;
+-   NwcConvertNetWareHandle nh;
+-   u_long cpylen;
+-
+-   DbgPrint("NwdConvertNetwareHandle: DHandle=0x%p\n", DHandle);
+-
+-	cpylen = copy_from_user(&nh, pdata->reqData, sizeof(NwcConvertNetWareHandle));
+-
+-   retVal = Daemon_Added_Resource(DHandle, DH_TYPE_STREAM, nh.ConnHandle, nh.NetWareHandle, nh.uAccessMode, nh.uFileSize);
+-
+-   return(retVal);
+-}
+-
+-/*++======================================================================*/
+-int NwdConvertLocalHandle(PXPLAT pdata, daemon_handle_t *DHandle)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   int retVal = NWE_REQUESTER_FAILURE;
+-   daemon_resource_t *resource;
+-   NwcConvertLocalHandle lh;
+-   struct list_head *l;
+-   u_long cpylen;
+-
+-   DbgPrint("NwdConvertLocalHandle: DHandle=0x%p\n", DHandle);
+-
+-   read_lock( &DHandle->lock );
+-      
+-   list_for_each( l, &DHandle->list )
+-   {
+-      resource = list_entry( l, daemon_resource_t, list );
+-      
+-      if ( DH_TYPE_STREAM == resource->type )
+-      {
+-         lh.uConnReference = resource->connection;
+-
+-         memcpy(lh.NwFileHandle, resource->handle, sizeof(resource->handle));
+-         if (pdata->repLen >= sizeof(NwcConvertLocalHandle))
+-         {
+-            cpylen = copy_to_user(pdata->repData, &lh, sizeof(NwcConvertLocalHandle));
+-            retVal = 0;
+-         }
+-         else
+-         {
+-            retVal = NWE_BUFFER_OVERFLOW;
+-         }
+-            break;
+-      }
+-   }
+-
+-   read_unlock( &DHandle->lock );
+-
+-   return(retVal);
+-}
+-
+-/*++======================================================================*/
+-int NwdGetMountPath(PXPLAT pdata)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   int retVal = NWE_REQUESTER_FAILURE;
+-   int len;
+-   u_long cpylen;
+-   NwcGetMountPath mp;
+-
+-   cpylen = copy_from_user(&mp, pdata->reqData, pdata->reqLen);
+-
+-   if ( Novfs_CurrentMount )
+-   {
+-
+-      len = strlen(Novfs_CurrentMount)+1;
+-      if ( (len > mp.MountPathLen) && mp.pMountPath)
+-      {
+-         retVal = NWE_BUFFER_OVERFLOW;
+-      }
+-      else
+-      {
+-         if (mp.pMountPath)
+-         {
+-            cpylen = copy_to_user(mp.pMountPath, Novfs_CurrentMount, len);
+-         }
+-         retVal = 0;
+-      }
+-
+-      mp.MountPathLen = len;
+-
+-      if (pdata->repData && (pdata->repLen >= sizeof(mp)) )
+-      {
+-         cpylen = copy_to_user(pdata->repData, &mp, sizeof(mp));
+-      }
+-   }
+-
+-   return(retVal);
+-}
+-
+-/*++======================================================================*/
+-int NwdSetMapDrive(PXPLAT pdata, session_t Session)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   int retVal;
+-   u_long cpylen;
+-
+-   retVal = NwcSetMapDrive(pdata, Session);
+-   if ( !retVal )
+-   {
+-      NwcMapDriveEx symInfo;
+-      char *path;
+-      drive_map_t *drivemap, *dm;
+-      struct list_head *list;
+-
+-      cpylen = copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo));
+-      drivemap = Novfs_Malloc( sizeof(drive_map_t)+symInfo.linkOffsetLength, GFP_KERNEL );
+-      if (drivemap)
+-      {
+-         path = (char *)pdata->reqData;
+-         path += symInfo.linkOffset;
+-         cpylen = copy_from_user(drivemap->name, path, symInfo.linkOffsetLength);
+-
+-         drivemap->session = Session;
+-         drivemap->hash = full_name_hash(drivemap->name, symInfo.linkOffsetLength-1);
+-         drivemap->namelen = symInfo.linkOffsetLength-1;
+-         DbgPrint( "NwdSetMapDrive: hash=0x%x path=%s\n", drivemap->hash, drivemap->name);
+-
+-         dm = (drive_map_t *)&DriveMapList.next;
+-
+-         down( &DriveMapLock );
+-
+-         list_for_each( list, &DriveMapList )
+-         {
+-            dm = list_entry( list, drive_map_t, list );
+-            DbgPrint( "NwdSetMapDrive: dm=0x%p\n" \
+-                      "   hash:    0x%x\n" \
+-                      "   namelen: %d\n" \
+-                      "   name:    %s\n",
+-               dm, dm->hash, dm->namelen, dm->name);
+-                     
+-            if (drivemap->hash == dm->hash)
+-            {
+-               if ( 0 == strcmp(dm->name, drivemap->name))
+-               {
+-                  dm = NULL;
+-                  break;
+-               }
+-            }
+-            else if (drivemap->hash < dm->hash)
+-            {
+-               break;
+-            }
+-         }
+-
+-         if (dm)
+-         {
+-            if ( (dm == (drive_map_t *)&DriveMapList) || 
+-                 (dm->hash < drivemap->hash) )
+-            {
+-               list_add( &drivemap->list, &dm->list);
+-            }
+-            else
+-            {
+-               list_add_tail( &drivemap->list, &dm->list);
+-            }
+-         }
+-         else
+-         {
+-            Novfs_Free( drivemap );
+-         }
+-         up( &DriveMapLock );
+-      }
+-   }
+-
+-   return(retVal);
+-}
+-
+-/*++======================================================================*/
+-int NwdUnMapDrive(PXPLAT pdata, session_t Session)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   int retVal = NWE_REQUESTER_FAILURE;
+-   u_long cpylen;
+-
+-   retVal = NwcUnMapDrive(pdata, Session);
+-   if ( !retVal )
+-   {
+-      NwcUnmapDriveEx symInfo;
+-      char *path;
+-      drive_map_t *dm;
+-      struct list_head *list;
+-      u_long hash;
+-
+-
+-      cpylen = copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo));
+-      path = Novfs_Malloc( symInfo.linkLen, GFP_KERNEL );
+-      if (path)
+-      {
+-         cpylen = copy_from_user(path, ((NwcUnmapDriveEx *)pdata->reqData)->linkData, symInfo.linkLen);
+-
+-         hash = full_name_hash(path, symInfo.linkLen-1);
+-         DbgPrint( "NwdUnMapDrive: hash=0x%x path=%s\n", hash, path);
+-
+-         dm = NULL;
+-
+-         down( &DriveMapLock );
+-
+-         list_for_each( list, &DriveMapList )
+-         {
+-            dm = list_entry( list, drive_map_t, list );
+-            DbgPrint( "NwdUnMapDrive: dm=0x%p %s\n" \
+-                      "   hash:    0x%x\n" \
+-                      "   namelen: %d\n",
+-               dm, dm->name, dm->hash, dm->namelen);
+-                     
+-            if (hash == dm->hash)
+-            {
+-               if ( 0 == strcmp(dm->name, path))
+-               {
+-                  break;
+-               }
+-            }
+-            else if (hash < dm->hash)
+-            {
+-               dm = NULL;
+-               break;
+-            }
+-         }
+-
+-         if (dm)
+-         {
+-            DbgPrint( "NwdUnMapDrive: Remove dm=0x%p %s\n" \
+-                      "   hash:    0x%x\n" \
+-                      "   namelen: %d\n",
+-               dm, dm->name, dm->hash, dm->namelen);
+-            list_del( &dm->list );
+-            Novfs_Free( dm );
+-         }
+-
+-         up( &DriveMapLock );
+-      }
+-   }
+-
+-   return(retVal);
+-}
+-
+-/*++======================================================================*/
+-void RemoveDriveMaps( void )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   drive_map_t *dm;
+-   struct list_head *list;
+-
+-   down( &DriveMapLock );
+-   list_for_each( list, &DriveMapList )
+-   {
+-      dm = list_entry( list, drive_map_t, list );
+-
+-      DbgPrint( "RemoveDriveMap: dm=0x%p\n" \
+-                "   hash:    0x%x\n" \
+-                "   namelen: %d\n" \
+-                "   name:    %s\n",
+-         dm, dm->hash, dm->namelen, dm->name);
+-      local_unlink( dm->name );
+-      list = list->prev;
+-      list_del( &dm->list );
+-      Novfs_Free( dm );
+-   }
+-   up( &DriveMapLock );
+-}
+-
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
+-/*++======================================================================*/
+-int local_unlink(const char *pathname)
+-{
+-	int error;
+-	struct dentry *dentry;
+-	struct nameidata nd;
+-	struct inode *inode = NULL;
+-
+-   DbgPrint("local_unlink: %s\n", pathname);
+-   error = path_lookup(pathname, LOOKUP_PARENT, &nd);
+-   DbgPrint("local_unlink: path_lookup %d\n", error);
+-   if ( !error )
+-   {
+-      error = -EISDIR;
+-      if (nd.last_type == LAST_NORM)
+-      {
+-         mutex_lock(&nd.dentry->d_inode->i_mutex);
+-         dentry = lookup_hash( &nd );
+-         DbgPrint("local_unlink: lookup_hash 0x%p\n", dentry);
+-
+-         error = PTR_ERR(dentry);
+-         if (!IS_ERR(dentry)) 
+-         {
+-            if (nd.last.name[nd.last.len])
+-            {
+-               error = !dentry->d_inode ? -ENOENT : S_ISDIR(dentry->d_inode->i_mode) ? -EISDIR : -ENOTDIR;
+-            }
+-            else
+-            {
+-               inode = dentry->d_inode;
+-               if (inode)
+-               {
+-                  atomic_inc(&inode->i_count);
+-               }
+-               error = vfs_unlink(nd.dentry->d_inode, dentry);
+-               DbgPrint("local_unlink: vfs_unlink %d\n", error);
+-            }
+-            dput(dentry);
+-         }
+-         mutex_unlock(&nd.dentry->d_inode->i_mutex);
+-
+-      }
+-   	path_release(&nd);
+-   }
+-
+-	if (inode)
+-   {
+-		iput(inode);	/* truncate the inode here */
+-   }
+-
+-   DbgPrint("local_unlink: error=%d\n", error);
+-	return error;
+-}
+-
+-#else
+-/*++======================================================================*/
+-int local_unlink(const char *pathname)
+-{
+-	int error;
+-	struct dentry *dentry;
+-	struct nameidata nd;
+-	struct inode *inode = NULL;
+-
+-   DbgPrint("local_unlink: %s\n", pathname);
+-   error = path_lookup(pathname, LOOKUP_PARENT, &nd);
+-   DbgPrint("local_unlink: path_lookup %d\n", error);
+-   if ( !error )
+-   {
+-      error = -EISDIR;
+-      if (nd.last_type == LAST_NORM)
+-      {
+-         down(&nd.dentry->d_inode->i_sem);
+-         dentry = lookup_hash(&nd.last, nd.dentry);
+-         DbgPrint("local_unlink: lookup_hash 0x%p\n", dentry);
+-
+-         error = PTR_ERR(dentry);
+-         if (!IS_ERR(dentry)) 
+-         {
+-            if (nd.last.name[nd.last.len])
+-            {
+-               error = !dentry->d_inode ? -ENOENT : S_ISDIR(dentry->d_inode->i_mode) ? -EISDIR : -ENOTDIR;
+-            }
+-            else
+-            {
+-               inode = dentry->d_inode;
+-               if (inode)
+-               {
+-                  atomic_inc(&inode->i_count);
+-               }
+-               error = vfs_unlink(nd.dentry->d_inode, dentry);
+-               DbgPrint("local_unlink: vfs_unlink %d\n", error);
+-            }
+-            dput(dentry);
+-         }
+-         up(&nd.dentry->d_inode->i_sem);
+-      }
+-   	path_release(&nd);
+-   }
+-
+-	if (inode)
+-   {
+-		iput(inode);	/* truncate the inode here */
+-   }
+-
+-   DbgPrint("local_unlink: error=%d\n", error);
+-	return error;
+-}
+-#endif
+diff -uNr src.old/novfs/file.c src/novfs/file.c
+--- src.old/novfs/file.c	2006-07-11 21:24:18.000000000 +0200
++++ src/novfs/file.c	1970-01-01 01:00:00.000000000 +0100
+@@ -1,2188 +0,0 @@
+-/*++========================================================================
+- * Program Name:     Novell NCP Redirector for Linux
+- * File Name:        file.c
+- * Version:          v1.00
+- * Author:           James Turner
+- *
+- * Abstract:         This module contains functions for accessing
+- *                   files through the daemon.
+- * Notes:
+- * Revision History: 
+- *
+- *
+- * Copyright (C) 2005 Novell, Inc.
+- *
+- * 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 files specific to Linux ]==================================*/
+-#include <linux/module.h>
+-#include <linux/fs.h>
+-#include <linux/dcache.h>
+-#include <linux/pagemap.h>
+-#include <linux/stat.h>
+-#include <linux/slab.h>
+-#include <asm/uaccess.h>
+-
+-/*===[ Include files specific to this module ]============================*/
+-#include "commands.h"
+-#include "nwerror.h"
+-#include "vfs.h"
+-
+-/*===[ External data ]====================================================*/
+-extern struct dentry_operations Novfs_dentry_operations;
+-
+-/*===[ External prototypes ]==============================================*/
+-extern int DbgPrint( char *Fmt, ... );
+-extern void mydump(int size, void *dumpptr);
+-extern int Queue_Daemon_Command(void *request, u_long reqlen, void *data, int dlen, void **reply, u_long *replen, int interruptible);
+-extern struct inode *Novfs_get_inode(struct super_block *sb, int mode, int dev, uid_t uid);
+-
+-extern void *Scope_Lookup( void );
+-
+-/*===[ Manifest constants ]===============================================*/
+-
+-/*===[ Type definitions ]=================================================*/
+-
+-/*===[ Function prototypes ]==============================================*/
+-
+-int Novfs_verify_file( struct qstr *Path, session_t SessionId );
+-int Novfs_get_alltrees(struct dentry *parent);
+-ssize_t Novfs_tree_read(struct file *file, char *buf, size_t len, loff_t *off);
+-
+-int Novfs_Get_Connected_Server_List( u_char **ServerList, session_t SessionId );
+-int Novfs_Get_Server_Volume_List( struct qstr *Server, u_char **VolumeList, session_t SessionId );
+-int Novfs_Find_Name_In_List( struct qstr *Name, u_char *List );
+-int Novfs_Verify_Server_Name( struct qstr *Server, session_t SessionId  );
+-int Novfs_Verify_Volume_Name( struct qstr *Server,  struct qstr *Volume, session_t SessionId  );
+-int Novfs_Get_File_Info( u_char *Path, PENTRY_INFO Info, session_t SessionId );
+-int Novfs_Get_Directory_List( u_char *Path, u_long *EnumHandle, PENTRY_INFO Info, session_t SessionId );
+-int Novfs_Get_Directory_ListEx( u_char *Path, u_long *EnumHandle, int *Count, PENTRY_INFO *Info, session_t SessionId );
+-int Novfs_Open_File( u_char *Path, int Flags, PENTRY_INFO Info, u_long *Handle, session_t SessionId );
+-int Novfs_Create( u_char *Path, int DirectoryFlag, session_t SessionId );
+-int Novfs_Close_File( u_long Handle, session_t SessionId );
+-int Novfs_Read_File( u_long Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, int User, session_t SessionId);
+-int Novfs_Write_File( u_long Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId);
+-int Novfs_Read_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, int User, session_t SessionId);
+-int Novfs_Write_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId);
+-int Novfs_Close_Stream( u_long ConnHandle, u_char *Handle, session_t SessionId );
+-int Novfs_Delete( u_char *Path, int DirectoryFlag, session_t SessionId );
+-int Novfs_Truncate_File( u_char *Path, int PathLen, session_t SessionId );
+-int Novfs_Rename_File( int DirectoryFlag, u_char *OldName, int OldLen, u_char *NewName, int NewLen, session_t SessionId );
+-int Novfs_Set_Attr( u_char *Path, struct iattr *Attr, session_t SessionId );
+-
+-/*===[ Global variables ]=================================================*/
+-static struct file_operations Novfs_tree_operations = {
+-	read:    Novfs_tree_read,
+-};
+-
+-/*
+- * StripTrailingDots was added because some apps will 
+- * try and create a file name with a trailing dot.  NetWare
+- * doesn't like this and will return an error.
+- */
+-u_char StripTrailingDots=1;
+-
+-/*===[ Code ]=============================================================*/
+-
+-/*++======================================================================*/
+-int Novfs_verify_file( struct qstr *Path, scope_t SessionId  )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PVERIFY_FILE_REPLY reply=NULL;
+-   u_long replylen=0;
+-   PVERIFY_FILE_REQUEST cmd;
+-   int cmdlen;
+-   int retCode=0;
+-
+-   cmdlen = (int)(&((PVERIFY_FILE_REQUEST)0)->path) + Path->len;
+-   cmd = (PVERIFY_FILE_REQUEST)Novfs_Malloc(cmdlen, GFP_KERNEL);
+-   if (cmd)
+-   {
+-      cmd->Command.CommandType = VFS_COMMAND_VERIFY_FILE;
+-      cmd->Command.SequenceNumber = 0;
+-      cmd->Command.SessionId = SessionId;
+-      cmd->pathLen = Path->len;
+-      memcpy(cmd->path, Path->name, Path->len);
+-
+-      retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+-      if ( reply )
+-      {
+-         DbgPrint("Novfs_verify_file: reply\n");
+-         mydump(replylen, reply);
+-         if (reply->Reply.ErrorCode)
+-         {
+-            retCode = -ENOENT;
+-         }
+-         else
+-         {
+-            retCode = 0;
+-         }
+-         Novfs_Free(reply);
+-      }
+-      Novfs_Free(cmd);
+-   }
+-   else
+-   {
+-      retCode = -ENOMEM;
+-   }
+-   return(retCode);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_get_alltrees(struct dentry *parent)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   u_char *p;
+-   PCOMMAND_REPLY_HEADER reply=NULL;
+-   u_long replylen=0;
+-   COMMAND_REQUEST_HEADER cmd;
+-   int retCode;
+-	struct dentry *entry;
+-	struct qstr name;
+-	struct inode *inode;
+-
+-   cmd.CommandType = 0;
+-   cmd.SequenceNumber = 0;
+-   cmd.SessionId = 0x1234;
+-
+-   DbgPrint( "Novfs_get_alltrees:\n");
+-
+-   retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+-   DbgPrint( "Novfs_get_alltrees: relpy=0x%x replylen=%d\n", reply, replylen);
+-   if (reply)
+-   {
+-      mydump(replylen, reply);
+-      if ( !reply->ErrorCode  && (replylen > sizeof(COMMAND_REPLY_HEADER)))
+-      {
+-         p = (char *)reply+8;
+-         while (*p)
+-         {
+-            DbgPrint( "Novfs_get_alltrees: %s\n",p);
+-            name.len  = strlen(p);
+-            name.name = p;
+-            name.hash = full_name_hash(name.name, name.len);
+-            entry = d_lookup(parent, &name);
+-            if ( NULL == entry )
+-            {
+-               DbgPrint( "Novfs_get_alltrees: adding %s\n",p);
+-               entry = d_alloc(parent, &name);
+-               if (entry)
+-               {
+-                  entry->d_op = &Novfs_dentry_operations;
+-                  inode = Novfs_get_inode(parent->d_sb, S_IFREG | 0400, 0, 0);
+-                  if (inode)
+-                  {
+-                     inode->i_fop = &Novfs_tree_operations;
+-                     d_add(entry, inode);
+-                  }
+-               }
+-            }
+-            p += (name.len+1);
+-         }
+-      }
+-      Novfs_Free(reply);
+-   }
+-   return(retCode);
+-}
+-
+-/*++======================================================================*/
+-ssize_t Novfs_tree_read(struct file *file, char *buf, size_t len, loff_t *off)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   if (file->f_pos != 0)
+-   {
+-      return(0);
+-   }
+-   if (copy_to_user(buf, "Tree\n", 5))
+-   {
+-      return(0);
+-   }
+-   return(5);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_Get_Connected_Server_List( u_char **ServerList, session_t SessionId )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   GET_CONNECTED_SERVER_LIST_REQUEST req;
+-   PGET_CONNECTED_SERVER_LIST_REPLY  reply=NULL;
+-   u_long replylen=0;
+-   int retCode=0;
+-
+-   *ServerList = NULL;
+-
+-   req.Command.CommandType = VFS_COMMAND_GET_CONNECTED_SERVER_LIST;
+-   req.Command.SessionId = SessionId;
+-
+-   retCode = Queue_Daemon_Command(&req, sizeof(req), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+-   if ( reply )
+-   {
+-      DbgPrint("Novfs_Get_Connected_Server_List: reply\n");
+-      replylen -= sizeof(COMMAND_REPLY_HEADER);
+-      if ( !reply->Reply.ErrorCode && replylen )
+-      {
+-         memcpy(reply, reply->List, replylen);
+-         *ServerList = (u_char *)reply;
+-         retCode = 0;
+-      }
+-      else
+-      {
+-         Novfs_Free(reply);
+-         retCode = -ENOENT;
+-      }
+-   }
+-   return(retCode);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_Get_Server_Volume_List( struct qstr *Server, u_char **VolumeList, scope_t SessionId )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PGET_SERVER_VOLUME_LIST_REQUEST req;
+-   PGET_SERVER_VOLUME_LIST_REPLY  reply=NULL;
+-   u_long replylen=0, reqlen;
+-   int retCode;
+-
+-   *VolumeList = NULL;
+-   reqlen = sizeof(GET_SERVER_VOLUME_LIST_REQUEST)+Server->len;
+-   req = Novfs_Malloc(reqlen, GFP_KERNEL);
+-   if (req)
+-   {
+-      req->Command.CommandType = VFS_COMMAND_GET_SERVER_VOLUME_LIST;
+-      req->Length = Server->len;
+-      memcpy(req->Name, Server->name, Server->len);
+-      req->Command.SessionId = SessionId;
+-
+-      retCode = Queue_Daemon_Command(req, reqlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+-      if ( reply )
+-      {
+-         DbgPrint("Novfs_Get_Server_Volume_List: reply\n");
+-         mydump(replylen, reply);
+-         replylen -= sizeof(COMMAND_REPLY_HEADER);
+-
+-         if ( !reply->Reply.ErrorCode && replylen )
+-         {
+-            memcpy(reply, reply->List, replylen);
+-            *VolumeList = (u_char *)reply;
+-            retCode = 0;
+-         }
+-         else
+-         {
+-            Novfs_Free(reply);
+-            retCode = -ENOENT;
+-         }
+-      }
+-      Novfs_Free(req);
+-   }
+-   else
+-   {
+-      retCode = -ENOMEM;
+-   }
+-   return(retCode);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_Find_Name_In_List( struct qstr *Name, u_char *List )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   int len;
+-   int retCode = 0;
+-
+-   while (*List)
+-   {
+-      len = strlen(List);
+-      if ((len == Name->len) && !strncmp(Name->name, List, len))
+-      {
+-         retCode = 1;
+-         break;
+-      }
+-      List += (len+1);
+-   }
+-   return( retCode );
+-}
+-
+-/*++======================================================================*/
+-int Novfs_Verify_Server_Name( struct qstr *Server, session_t SessionId )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   u_char *list;
+-   int retCode = 0;
+-
+-   DbgPrint("Novfs_Verify_Server_Name: %.*s\n", Server->len, Server->name);
+-
+-   list = NULL;
+-   Novfs_Get_Connected_Server_List( &list, SessionId );
+-
+-   if (list)
+-   {
+-      retCode = Novfs_Find_Name_In_List( Server, list );
+-      Novfs_Free(list);
+-   }
+-   DbgPrint("Novfs_Verify_Server_Name: %d\n", retCode);
+-   return(retCode);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_Verify_Volume_Name( struct qstr *Server,  struct qstr *Volume, session_t SessionId )
+-/*
+- *
+- *  Arguments:   Server - Server name.
+- *               Volume - Volume name to check for.
+- *
+- *  Returns:     zero - not found.
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   u_char *list;
+-   int retCode = 0;
+-   u_char *name;
+-   int namelen;
+-   struct qstr path;
+-
+-   list = NULL;
+-   namelen = Server->len+Volume->len+2;
+-   name = Novfs_Malloc(namelen, GFP_KERNEL);
+-
+-   if (name)
+-   {
+-      name[0] = '\\';
+-      memcpy(&name[1], Server->name, Server->len);
+-      name[1+Server->len] = '\\';
+-      memcpy(&name[2+Server->len], Volume->name, Volume->len);
+-      path.len = namelen;
+-      path.name = name;
+-
+-      if (Novfs_verify_file(&path, SessionId))
+-      {
+-         retCode = 0;
+-      }
+-      else
+-      {
+-         retCode = 1;
+-      }
+-
+-      Novfs_Free(name);
+-   }
+-   else
+-   {
+-
+-      Novfs_Get_Server_Volume_List( Server, &list, SessionId );
+-
+-      if (list)
+-      {
+-         retCode = Novfs_Find_Name_In_List( Volume, list );
+-         Novfs_Free(list);
+-      }
+-   }
+-   return(retCode);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_Get_File_Info( u_char *Path, PENTRY_INFO Info, session_t SessionId )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PVERIFY_FILE_REPLY reply=NULL;
+-   u_long replylen=0;
+-   PVERIFY_FILE_REQUEST cmd;
+-   int cmdlen;
+-   int retCode=-ENOENT;
+-   int pathlen;
+-
+-   DbgPrint("Novfs_Get_File_Info: Path = %s\n", Path);
+-
+-   Info->mode = S_IFDIR | 0700;
+-   Info->uid = current->uid;
+-   Info->gid = current->gid;
+-   Info->size = 0;
+-   Info->atime = Info->mtime = Info->ctime = CURRENT_TIME;
+-
+-   if (Path && *Path)
+-   {
+-      pathlen = strlen(Path);
+-      if (StripTrailingDots)
+-      {
+-         if ('.' == Path[pathlen-1]) pathlen--;
+-      }
+-      cmdlen = (int)(&((PVERIFY_FILE_REQUEST)0)->path) + pathlen;
+-      cmd = (PVERIFY_FILE_REQUEST)Novfs_Malloc(cmdlen, GFP_KERNEL);
+-      if (cmd)
+-      {
+-         cmd->Command.CommandType = VFS_COMMAND_VERIFY_FILE;
+-         cmd->Command.SequenceNumber = 0;
+-         cmd->Command.SessionId = SessionId;
+-         cmd->pathLen = pathlen;
+-         memcpy(cmd->path, Path, cmd->pathLen);
+-
+-         retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+-/*
+- *        retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, 0); 
+- */
+-         if (reply)
+-         {
+-            
+-            if ( reply->Reply.ErrorCode )
+-            {
+-               retCode = -ENOENT;
+-            }
+-            else
+-            {
+-               Info->type = 3;
+-               Info->mode = S_IRWXU;
+-
+-               if (reply->fileMode & NW_ATTRIBUTE_DIRECTORY)
+-               {
+-                  Info->mode |= S_IFDIR;
+-               }
+-               else
+-               {
+-                  Info->mode |= S_IFREG;
+-               }
+-
+-               if (reply->fileMode & NW_ATTRIBUTE_READ_ONLY)
+-               {
+-                  Info->mode &= ~(S_IWUSR);
+-               }
+-
+-               Info->uid   = current->euid;
+-               Info->gid   = current->egid;
+-               Info->size  = reply->fileSize;
+-               Info->atime.tv_sec  = reply->lastAccessTime;
+-               Info->atime.tv_nsec = 0;
+-               Info->mtime.tv_sec  = reply->modifyTime;
+-               Info->mtime.tv_nsec = 0;
+-               Info->ctime.tv_sec  = reply->createTime;
+-               Info->ctime.tv_nsec = 0;
+-               retCode = 0;
+-            }
+-
+-            Novfs_Free(reply);
+-         }
+-         Novfs_Free(cmd);
+-      }
+-   }
+-
+-   DbgPrint("Novfs_Get_File_Info: return 0x%x\n", retCode);
+-   return(retCode);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_Get_File_Info2( u_char *Path, PENTRY_INFO Info, session_t SessionId )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PVERIFY_FILE_REPLY reply=NULL;
+-   u_long replylen=0;
+-   PVERIFY_FILE_REQUEST cmd;
+-   int cmdlen;
+-   struct qstr server = {0}, volume = {0};
+-   u_char *p;
+-   int i;
+-   int retCode=-ENOENT;
+-   p = Path;
+-
+-   DbgPrint("Novfs_Get_File_Info: Path = %s\n", Path);
+-
+-   Info->mode = S_IFDIR | 0700;
+-   Info->uid = current->uid;
+-   Info->gid = current->gid;
+-   Info->size = 0;
+-   Info->atime = Info->mtime = Info->ctime = CURRENT_TIME;
+-
+-   if ('\\' == *p)
+-   {
+-      p++;
+-   }
+-   server.name = p;
+-
+-   for(i=0; *p && ('\\' != *p); i++, p++);
+-   server.len = i;
+-   if (*p)
+-   {
+-      if ('\\' == *p)
+-      {
+-         p++;
+-      }
+-      volume.name = p;
+-      for(i=0; *p && ('\\' != *p); i++, p++);
+-      if (i)
+-      {
+-         volume.len = i;
+-         if (*p)
+-         {
+-            if ('\\' == *p)
+-            {
+-               p++;
+-            }
+-            if (*p)
+-            {
+-               cmdlen = (int)(&((PVERIFY_FILE_REQUEST)0)->path) + strlen(Path);
+-               cmd = (PVERIFY_FILE_REQUEST)Novfs_Malloc(cmdlen, GFP_KERNEL);
+-               if (cmd)
+-               {
+-                  cmd->Command.CommandType = VFS_COMMAND_VERIFY_FILE;
+-                  cmd->Command.SequenceNumber = 0;
+-                  cmd->Command.SessionId = SessionId;
+-                  cmd->pathLen = strlen(Path);
+-                  memcpy(cmd->path, Path, cmd->pathLen);
+-
+-                  retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+-                  if (reply)
+-                  {
+-                     
+-                     if ( reply->Reply.ErrorCode )
+-                     {
+-                        retCode = -ENOENT;
+-                     }
+-                     else
+-                     {
+-                        Info->type = 3;
+-                        Info->mode = S_IRWXU;
+-
+-                        if (reply->fileMode & NW_ATTRIBUTE_DIRECTORY)
+-                        {
+-                           Info->mode |= S_IFDIR;
+-                        }
+-                        else
+-                        {
+-                           Info->mode |= S_IFREG;
+-                        }
+-
+-                        if (reply->fileMode & NW_ATTRIBUTE_READ_ONLY)
+-                        {
+-                           Info->mode &= ~(S_IWUSR);
+-                        }
+-
+-                        Info->uid   = current->euid;
+-                        Info->gid   = current->egid;
+-                        Info->size  = reply->fileSize;
+-                        Info->atime.tv_sec  = reply->lastAccessTime;
+-                        Info->atime.tv_nsec = 0;
+-                        Info->mtime.tv_sec  = reply->modifyTime;
+-                        Info->mtime.tv_nsec = 0;
+-                        Info->ctime.tv_sec  = reply->createTime;
+-                        Info->ctime.tv_nsec = 0;
+-                        retCode = 0;
+-                     }
+-
+-                     Novfs_Free(reply);
+-                  }
+-                  Novfs_Free(cmd);
+-               }
+-            }
+-         }
+-      }
+-      if (('\0' == *p) && volume.len)
+-      {
+-         if ( Novfs_Verify_Volume_Name( &server, &volume, SessionId ) )
+-         {
+-            retCode = 0;
+-            Info->type = 2;
+-         }
+-      }
+-   }
+-   if (server.len && !volume.len)
+-   {
+-      if ( Novfs_Verify_Server_Name( &server, SessionId ) )
+-      {
+-         retCode = 0;
+-         Info->type = 1;
+-      }
+-   }
+-   DbgPrint("Novfs_Get_File_Info: return 0x%x\n", retCode);
+-   return(retCode);
+-}
+-
+-/*++======================================================================*/
+-int begin_directory_enumerate( u_char *Path, int PathLen, u_long *EnumHandle, session_t SessionId)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PBEGIN_ENUMERATE_DIRECTORY_REQUEST cmd;
+-   PBEGIN_ENUMERATE_DIRECTORY_REPLY   reply=NULL;
+-   u_long replylen=0;
+-   int retCode, cmdlen;
+-
+-   *EnumHandle = 0;
+-
+-   cmdlen = (int)(&((PBEGIN_ENUMERATE_DIRECTORY_REQUEST)0)->path) + PathLen;
+-   cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-   if (cmd)
+-   {
+-      cmd->Command.CommandType    = VFS_COMMAND_START_ENUMERATE;
+-      cmd->Command.SequenceNumber = 0;
+-      cmd->Command.SessionId      = SessionId;
+-
+-      cmd->pathLen = PathLen;
+-      memcpy(cmd->path, Path, PathLen);
+-
+-      retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+-/*
+- *      retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, 0);
+- */
+-      if (reply)
+-      {
+-         if (reply->Reply.ErrorCode)
+-         {
+-            retCode = -EIO;
+-         }
+-         else
+-         {
+-            *EnumHandle = reply->enumerateHandle;
+-            retCode = 0;
+-         }
+-         Novfs_Free(reply);
+-      }
+-      Novfs_Free(cmd);
+-   }
+-   else
+-   {
+-      retCode = -ENOMEM;
+-   }
+-   return( retCode );
+-}
+-
+-/*++======================================================================*/
+-int end_directory_enumerate( u_long EnumHandle, session_t SessionId )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   END_ENUMERATE_DIRECTORY_REQUEST cmd;
+-   PEND_ENUMERATE_DIRECTORY_REPLY  reply=NULL;
+-   u_long replylen=0;
+-   int retCode;
+-
+-
+-   cmd.Command.CommandType    = VFS_COMMAND_END_ENUMERATE;
+-   cmd.Command.SequenceNumber = 0;
+-   cmd.Command.SessionId      = SessionId;
+-
+-   cmd.enumerateHandle = EnumHandle;
+-
+-   retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, 0);
+-   if (reply)
+-   {
+-      retCode = 0;
+-      if (reply->Reply.ErrorCode)
+-      {
+-         retCode = -EIO;
+-      }
+-      Novfs_Free(reply);
+-   }
+-
+-   return( retCode );
+-}
+-
+-/*++======================================================================*/
+-int directory_enumerate( u_long *EnumHandle, PENTRY_INFO Info, session_t SessionId )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   ENUMERATE_DIRECTORY_REQUEST cmd;
+-   PENUMERATE_DIRECTORY_REPLY  reply=NULL;
+-   u_long replylen=0;
+-   int retCode;
+-
+-
+-   cmd.Command.CommandType    = VFS_COMMAND_ENUMERATE_DIRECTORY;
+-   cmd.Command.SequenceNumber = 0;
+-   cmd.Command.SessionId      = SessionId;
+-
+-   cmd.enumerateHandle = *EnumHandle;
+-   cmd.pathLen = 0;
+-   cmd.path[0] = '\0';
+-
+-   retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+-
+-   if (reply)
+-   {
+-      /*
+-       * The VFS_COMMAND_ENUMERATE_DIRECTORY call can return an
+-       * error but there could still be valid data.
+-       */
+-      if ( !reply->Reply.ErrorCode || 
+-           ( (replylen > sizeof(COMMAND_REPLY_HEADER)) &&
+-             (reply->nameLen > 0)) )
+-      {
+-         Info->type = 3;
+-         Info->mode = S_IRWXU;
+-
+-         if (reply->mode & NW_ATTRIBUTE_DIRECTORY)
+-         {
+-            Info->mode |= S_IFDIR;
+-            Info->mode |= S_IXUSR;
+-         }
+-         else
+-         {
+-            Info->mode |= S_IFREG;
+-         }
+-
+-         if (reply->mode & NW_ATTRIBUTE_READ_ONLY)
+-         {
+-            Info->mode &= ~(S_IWUSR);
+-         }
+-
+-         if (reply->mode & NW_ATTRIBUTE_EXECUTE)
+-         {
+-            Info->mode |= S_IXUSR;
+-         }
+-
+-         Info->uid           = current->uid;
+-         Info->gid           = current->gid;
+-         Info->size          = reply->size;
+-         Info->atime.tv_sec  = reply->lastAccessTime;
+-         Info->atime.tv_nsec = 0;
+-         Info->mtime.tv_sec  = reply->modifyTime;
+-         Info->mtime.tv_nsec = 0;
+-         Info->ctime.tv_sec  = reply->createTime;
+-         Info->ctime.tv_nsec = 0;
+-         Info->namelength    = reply->nameLen;
+-         memcpy(Info->name, reply->name, reply->nameLen);
+-         retCode = 0;
+-         if (reply->Reply.ErrorCode)
+-         {
+-            retCode = -1; /* Eof of data */
+-         }
+-         *EnumHandle = reply->enumerateHandle;
+-      }
+-      else
+-      {
+-         retCode = -ENODATA;
+-      }
+-      Novfs_Free(reply);
+-   }
+-
+-   return( retCode );
+-}
+-
+-/*++======================================================================*/
+-int directory_enumerate_ex( u_long *EnumHandle, session_t SessionId,  int *Count, PENTRY_INFO *PInfo, int Interrupt)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   ENUMERATE_DIRECTORY_EX_REQUEST cmd;
+-   PENUMERATE_DIRECTORY_EX_REPLY  reply=NULL;
+-   u_long replylen=0;
+-   int retCode=0;
+-   PENTRY_INFO info;
+-   PENUMERATE_DIRECTORY_EX_DATA data;
+-   int isize;
+-
+-   if (PInfo)
+-   {
+-      *PInfo = NULL;
+-   }
+-   *Count = 0;
+-
+-   cmd.Command.CommandType    = VFS_COMMAND_ENUMERATE_DIRECTORY_EX;
+-   cmd.Command.SequenceNumber = 0;
+-   cmd.Command.SessionId      = SessionId;
+-
+-   cmd.enumerateHandle = *EnumHandle;
+-   cmd.pathLen = 0;
+-   cmd.path[0] = '\0';
+-
+-   retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, Interrupt);
+-
+-   if (reply)
+-   {
+-      retCode = 0;
+-      /*
+-       * The VFS_COMMAND_ENUMERATE_DIRECTORY call can return an
+-       * error but there could still be valid data.
+-       */
+-
+-      if ( !reply->Reply.ErrorCode || 
+-           ( (replylen > sizeof(COMMAND_REPLY_HEADER)) &&
+-             (reply->enumCount > 0)) )
+-      {
+-         DbgPrint("directory_enumerate_ex: isize=%d\n", replylen);
+-         data = (PENUMERATE_DIRECTORY_EX_DATA)((char *)reply + sizeof(ENUMERATE_DIRECTORY_EX_REPLY));
+-         isize =  replylen - 
+-                  sizeof(PENUMERATE_DIRECTORY_EX_REPLY) - 
+-                  reply->enumCount * (int)(&((PENUMERATE_DIRECTORY_EX_DATA)0)->name);
+-         isize +=  (reply->enumCount * (int)(&((PENTRY_INFO)0)->name));
+-
+-         if (PInfo)
+-         {
+-            *PInfo = info = Novfs_Malloc(isize, GFP_KERNEL);
+-            if ( *PInfo )
+-            {
+-               DbgPrint("directory_enumerate_ex1: data=0x%p info=0x%p\n", data, info);
+-               *Count = reply->enumCount;
+-               do
+-               {
+-                  DbgPrint("directory_enumerate_ex2: data=0x%p length=%d\n", data);
+-
+-                  info->type = 3;
+-                  info->mode = S_IRWXU;
+-
+-                  if (data->mode & NW_ATTRIBUTE_DIRECTORY)
+-                  {
+-                     info->mode |= S_IFDIR;
+-                     info->mode |= S_IXUSR;
+-                  }
+-                  else
+-                  {
+-                     info->mode |= S_IFREG;
+-                  }
+-
+-                  if (data->mode & NW_ATTRIBUTE_READ_ONLY)
+-                  {
+-                     info->mode &= ~(S_IWUSR);
+-                  }
+-
+-                  if (data->mode & NW_ATTRIBUTE_EXECUTE)
+-                  {
+-                     info->mode |= S_IXUSR;
+-                  }
+-
+-                  info->uid           = current->euid;
+-                  info->gid           = current->egid;
+-                  info->size          = data->size;
+-                  info->atime.tv_sec  = data->lastAccessTime;
+-                  info->atime.tv_nsec = 0;
+-                  info->mtime.tv_sec  = data->modifyTime;
+-                  info->mtime.tv_nsec = 0;
+-                  info->ctime.tv_sec  = data->createTime;
+-                  info->ctime.tv_nsec = 0;
+-                  info->namelength    = data->nameLen;
+-                  memcpy(info->name, data->name, data->nameLen);
+-                  data = (PENUMERATE_DIRECTORY_EX_DATA)&data->name[data->nameLen];
+-                  replylen = (int)((char *)&info->name[info->namelength] - (char *)info);
+-                  DbgPrint("directory_enumerate_ex3: info=0x%p\n", info);
+-                  mydump(replylen, info);
+-
+-                  info = (PENTRY_INFO)&info->name[info->namelength];
+-
+-               } while (--reply->enumCount);
+-            }
+-         }
+-
+-         if (reply->Reply.ErrorCode)
+-         {
+-            retCode = -1; /* Eof of data */
+-         }
+-         *EnumHandle = reply->enumerateHandle;
+-      }
+-      else
+-      {
+-         retCode = -ENODATA;
+-      }
+-      Novfs_Free(reply);
+-   }
+-
+-   return( retCode );
+-}
+-
+-/*++======================================================================*/
+-int Novfs_Get_Directory_List( u_char *Path, u_long *EnumHandle, PENTRY_INFO Info, session_t SessionId )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   int retCode = -ENOENT;
+-
+-   if ( -1 == *EnumHandle)
+-   {
+-      return( -ENODATA );
+-   }
+-
+-   if ( 0 == *EnumHandle )
+-   {
+-      retCode = begin_directory_enumerate(Path, strlen(Path), EnumHandle, SessionId);
+-   }
+-
+-   if ( *EnumHandle )
+-   {
+-      retCode = directory_enumerate( EnumHandle, Info, SessionId );
+-      if (retCode)
+-      {
+-         end_directory_enumerate( *EnumHandle, SessionId );
+-         if ( -1 == retCode )
+-         {
+-            retCode = 0;
+-            *EnumHandle = -1;
+-         }
+-      }
+-   }
+-   return(retCode);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_Get_Directory_ListEx( u_char *Path, u_long *EnumHandle, int *Count, PENTRY_INFO *Info, session_t SessionId )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   int retCode = -ENOENT;
+-
+-   if (Count)  *Count = 0;
+-   if (Info)   *Info = NULL;
+-
+-   if ( -1 == *EnumHandle)
+-   {
+-      return( -ENODATA );
+-   }
+-
+-   if ( 0 == *EnumHandle )
+-   {
+-      retCode = begin_directory_enumerate(Path, strlen(Path), EnumHandle, SessionId);
+-   }
+-
+-   if ( *EnumHandle )
+-   {
+-      retCode = directory_enumerate_ex( EnumHandle, SessionId, Count, Info, INTERRUPTIBLE );
+-      if (retCode)
+-      {
+-         end_directory_enumerate( *EnumHandle, SessionId );
+-         if ( -1 == retCode )
+-         {
+-            retCode = 0;
+-            *EnumHandle = -1;
+-         }
+-      }
+-   }
+-   return(retCode);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_Open_File( u_char *Path, int Flags, PENTRY_INFO Info, u_long *Handle, session_t SessionId )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   POPEN_FILE_REQUEST cmd;
+-   POPEN_FILE_REPLY   reply;
+-   u_long replylen=0;
+-   int retCode, cmdlen, pathlen;
+-
+-   pathlen = strlen(Path);
+-
+-   if (StripTrailingDots)
+-   {
+-      if ('.' == Path[pathlen-1]) pathlen--;
+-   }
+-
+-   cmdlen = (int)(&((POPEN_FILE_REQUEST)0)->path) + pathlen;
+-   cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-   if (cmd)
+-   {
+-      cmd->Command.CommandType    = VFS_COMMAND_OPEN_FILE;
+-      cmd->Command.SequenceNumber = 0;
+-      cmd->Command.SessionId      = SessionId;
+-
+-      cmd->access = 0;
+-
+-      if ( !(Flags & O_WRONLY) || (Flags & O_RDWR))
+-      {
+-         cmd->access |= NWD_ACCESS_READ;
+-      }
+-
+-      if ((Flags & O_WRONLY) || (Flags & O_RDWR))
+-      {
+-         cmd->access |= NWD_ACCESS_WRITE;
+-      }
+-
+-      switch (Flags & (O_CREAT | O_EXCL | O_TRUNC))
+-      {
+-         case O_CREAT:
+-            cmd->disp = NWD_DISP_OPEN_ALWAYS;
+-            break;
+-
+-         case O_CREAT | O_EXCL:
+-            cmd->disp = NWD_DISP_CREATE_NEW;
+-            break;
+-
+-         case O_TRUNC:
+-            cmd->disp = NWD_DISP_CREATE_ALWAYS;
+-            break;
+-
+-         case O_CREAT | O_TRUNC:
+-            cmd->disp = NWD_DISP_CREATE_ALWAYS;
+-            break;
+-
+-         case O_CREAT | O_EXCL | O_TRUNC:
+-            cmd->disp = NWD_DISP_CREATE_NEW;
+-            break;
+-
+-         default:
+-            cmd->disp = NWD_DISP_OPEN_EXISTING;
+-            break;
+-      }
+-
+-      cmd->mode = NWD_SHARE_READ | NWD_SHARE_WRITE | NWD_SHARE_DELETE;
+-
+-      cmd->pathLen = pathlen;
+-      memcpy(cmd->path, Path, pathlen);
+-
+-      retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+-
+-      if (reply)
+-      {
+-         if (reply->Reply.ErrorCode)
+-         {
+-            if( NWE_OBJECT_EXISTS == reply->Reply.ErrorCode)
+-            {
+-               retCode = -EEXIST;
+-            }
+-            else if( NWE_ACCESS_DENIED == reply->Reply.ErrorCode)
+-            {
+-               retCode = -EACCES;
+-            }
+-            else 
+-            {
+-               retCode = -ENOENT;
+-            }
+-         }
+-         else
+-         {
+-            *Handle = reply->handle;
+-            retCode = 0;
+-         }
+-         Novfs_Free(reply);
+-      }
+-      Novfs_Free(cmd);
+-   }
+-   else
+-   {
+-      retCode = -ENOMEM;
+-   }
+-   return( retCode );
+-}
+-
+-/*++======================================================================*/
+-int Novfs_Create( u_char *Path, int DirectoryFlag, session_t SessionId )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PCREATE_FILE_REQUEST cmd;
+-   PCREATE_FILE_REPLY   reply;
+-   u_long replylen=0;
+-   int retCode, cmdlen, pathlen;
+-
+-   pathlen = strlen(Path);
+-
+-   if (StripTrailingDots)
+-   {
+-      if ('.' == Path[pathlen-1]) pathlen--;
+-   }
+-
+-   cmdlen = (int)(&((PCREATE_FILE_REQUEST)0)->path) + pathlen;
+-   cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-   if (cmd)
+-   {
+-      cmd->Command.CommandType    = VFS_COMMAND_CREATE_FILE;
+-      if (DirectoryFlag)
+-      {
+-         cmd->Command.CommandType    = VFS_COMMAND_CREATE_DIRECOTRY;
+-      }
+-      cmd->Command.SequenceNumber = 0;
+-      cmd->Command.SessionId      = SessionId;
+-
+-      cmd->pathlength = pathlen;
+-      memcpy(cmd->path, Path, pathlen);
+-
+-      retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+-
+-      if (reply)
+-      {
+-         retCode = 0;
+-         if (reply->Reply.ErrorCode)
+-         {
+-            retCode = -EIO;
+-         }
+-         Novfs_Free(reply);
+-      }
+-      Novfs_Free(cmd);
+-   }
+-   else
+-   {
+-      retCode = -ENOMEM;
+-   }
+-   return( retCode );
+-}
+-
+-/*++======================================================================*/
+-int Novfs_Close_File( u_long Handle, session_t SessionId )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   CLOSE_FILE_REQUEST cmd;
+-   PCLOSE_FILE_REPLY  reply;
+-   u_long replylen=0;
+-   int retCode;
+-
+-   cmd.Command.CommandType    = VFS_COMMAND_CLOSE_FILE;
+-   cmd.Command.SequenceNumber = 0;
+-   cmd.Command.SessionId      = SessionId;
+-
+-   cmd.handle = Handle;
+-
+-   retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, 0);
+-   if (reply)
+-   {
+-      retCode = 0;
+-      if (reply->Reply.ErrorCode)
+-      {
+-         retCode = -EIO;
+-      }
+-      Novfs_Free(reply);
+-   }
+-   return( retCode );
+-}
+-
+-/*++======================================================================*/
+-int Novfs_Read_File( u_long Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, int User, session_t SessionId)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   READ_FILE_REQUEST cmd;
+-   PREAD_FILE_REPLY  reply=NULL;
+-   u_long replylen=0;
+-   int retCode = 0;
+-   size_t len;
+-
+-   len = *Bytes;
+-   *Bytes = 0;
+-
+-   if ( ((int)(&((PREAD_FILE_REPLY)0)->data) + len) > MAX_IO_SIZE)
+-   {
+-      len = MAX_IO_SIZE - (int)(&((PREAD_FILE_REPLY)0)->data);
+-      len = (len/PAGE_SIZE)*PAGE_SIZE;
+-   }
+-
+-   cmd.Command.CommandType    = VFS_COMMAND_READ_FILE;
+-   cmd.Command.SequenceNumber = 0;
+-   cmd.Command.SessionId      = SessionId;
+-
+-   cmd.handle = Handle;
+-   cmd.len    = len;
+-   cmd.offset = *Offset;
+-
+-   retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+-
+-   DbgPrint("Novfs_Read_File: Queue_Daemon_Command 0x%x replylen=%d\n", retCode, replylen);
+-
+-   if (!retCode)
+-   {
+-      if (reply->Reply.ErrorCode)
+-      {
+-         retCode = -EIO;
+-      }
+-      else
+-      {
+-         replylen -= (int)(&((PREAD_FILE_REPLY)0)->data);
+-         if (replylen > 0)
+-         {
+-            if (User)
+-            {
+-               replylen -= copy_to_user(Buffer, reply->data, replylen);
+-            }
+-            else
+-            {
+-               memcpy(Buffer, reply->data, replylen);
+-            }
+-
+-            *Bytes = replylen;
+-         }
+-      }
+-   }
+-
+-   if ( reply )
+-   {
+-      Novfs_Free(reply);
+-   }
+-   
+-   DbgPrint("Novfs_Read_File *Bytes=0x%x retCode=0x%x\n", *Bytes, retCode);
+-
+-   return( retCode );
+-}
+-
+-/*++======================================================================*/
+-int Novfs_Write_File( u_long Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   WRITE_FILE_REQUEST cmd;
+-   PWRITE_FILE_REPLY  reply=NULL;
+-   unsigned long replylen=0;
+-   int retCode=0, cmdlen;
+-   size_t len;
+-
+-   unsigned long boff;
+-   struct page **pages;
+-   DATA_LIST *dlist;
+-	int res=0, npage, i;
+-   WRITE_FILE_REPLY   lreply;
+-
+-
+-   len = *Bytes;
+-   cmdlen = (int)(&((PWRITE_FILE_REQUEST)0)->data);
+-
+-   *Bytes = 0;
+-
+-   memset(&lreply, 0, sizeof(lreply));
+-
+-   DbgPrint("Novfs_Write_File cmdlen=%ld len=%ld\n", cmdlen, len);
+-
+-   if ( (cmdlen+len) > MAX_IO_SIZE)
+-   {
+-      len = MAX_IO_SIZE-cmdlen;
+-      len = (len/PAGE_SIZE)*PAGE_SIZE;
+-   }
+-   cmd.Command.CommandType    = VFS_COMMAND_WRITE_FILE;
+-   cmd.Command.SequenceNumber = 0;
+-   cmd.Command.SessionId      = SessionId;
+-   cmd.handle = Handle;
+-   cmd.len    = len;
+-   cmd.offset = *Offset;
+-
+-   DbgPrint("Novfs_Write_File cmdlen=%ld len=%ld\n", cmdlen, len);
+-
+-   npage = (((unsigned long)Buffer & ~PAGE_MASK) + len + (PAGE_SIZE-1)) >> PAGE_SHIFT;
+-
+-   dlist = Novfs_Malloc(sizeof(DATA_LIST)*(npage+1), GFP_KERNEL);
+-   if (NULL == dlist)
+-   {
+-      return(-ENOMEM);
+-   }
+-
+-   pages = Novfs_Malloc(sizeof(struct page *)*npage, GFP_KERNEL);
+-
+-   if (NULL == pages)
+-   {
+-      Novfs_Free(dlist);
+-      return(-ENOMEM);
+-   }
+-
+-	down_read(&current->mm->mmap_sem);
+-
+-	res = get_user_pages(
+-		current,
+-		current->mm,
+-		(unsigned long)Buffer,
+-		npage,
+-		0, /* read type */
+-		0, /* don't force */
+-		pages,
+-		NULL);
+-
+-	up_read(&current->mm->mmap_sem);
+-
+-   DbgPrint("Novfs_Write_File res=%d\n", res);
+-
+-   if ( res > 0 )
+-   {
+-      boff = (unsigned long)Buffer & ~PAGE_MASK;
+-      
+-   	flush_dcache_page(pages[0]);
+-      dlist[0].page   = pages[0];
+-      dlist[0].offset = (char *)boff;
+-      dlist[0].len    = PAGE_SIZE - boff;
+-      dlist[0].rwflag = DLREAD;
+-
+-      if (dlist[0].len > len)
+-      {
+-         dlist[0].len = len;
+-      }
+-
+-      DbgPrint("Novfs_Write_File0: page=0x%x offset=0x%p len=%d\n", dlist[0].page, dlist[0].offset, dlist[0].len);
+-
+-      boff = dlist[0].len;
+-
+-      DbgPrint("Novfs_Write_File len=%d boff=%d\n", len, boff);
+-
+-      for (i=1; (i < res) && (boff < len); i++)
+-      {
+-   		flush_dcache_page(pages[i]);
+-
+-         dlist[i].page = pages[i];
+-         dlist[i].offset = NULL;
+-         dlist[i].len = len-boff;
+-         if (dlist[i].len > PAGE_SIZE)
+-         {
+-            dlist[i].len = PAGE_SIZE;
+-         }
+-         dlist[i].rwflag = DLREAD;
+-
+-         boff += dlist[i].len;
+-         DbgPrint("Novfs_Write_File%d: page=0x%x offset=0x%p len=%d\n", i, dlist[i].page, dlist[i].offset, dlist[i].len);
+-      }
+-
+-      dlist[i].page   = NULL;
+-      dlist[i].offset = &lreply;
+-      dlist[i].len    = sizeof(lreply);
+-      dlist[i].rwflag = DLWRITE;
+-      res++;
+-
+-      DbgPrint("Novfs_Write_File Buffer=0x%x boff=0x%x len=%d\n", Buffer, boff, len);
+-
+-      retCode = Queue_Daemon_Command(&cmd, cmdlen, dlist, res, (void *)&reply, &replylen, INTERRUPTIBLE);
+-
+-   }
+-   else
+-   {
+-      char *kdata;
+-
+-      res = 0;
+-      
+-      kdata = Novfs_Malloc(len, GFP_KERNEL);
+-      if (kdata)
+-      {
+-         len -= copy_from_user(kdata, Buffer, len);
+-         dlist[0].page   = NULL;
+-         dlist[0].offset = kdata;
+-         dlist[0].len    = len;
+-         dlist[0].rwflag = DLREAD;
+-
+-         dlist[1].page   = NULL;
+-         dlist[1].offset = &lreply;
+-         dlist[1].len    = sizeof(lreply);
+-         dlist[1].rwflag = DLWRITE;
+-
+-         retCode = Queue_Daemon_Command(&cmd, cmdlen, dlist, 2, (void *)&reply, &replylen, INTERRUPTIBLE);
+-
+-         Novfs_Free(kdata);
+-      }
+-   }
+-
+-   DbgPrint("Novfs_Write_File retCode=0x%x reply=0x%x\n", retCode, reply);
+-
+-   if ( !retCode )
+-   {
+-      switch (lreply.Reply.ErrorCode)
+-      {
+-         case 0:
+-            *Bytes = (size_t)lreply.bytesWritten;
+-            retCode = 0;
+-            break;
+-
+-         case NWE_INSUFFICIENT_SPACE:
+-            retCode = -ENOSPC;
+-            break;
+-
+-         case NWE_ACCESS_DENIED:
+-            retCode = -EACCES;
+-            break;
+-
+-         default:
+-            retCode = -EIO;
+-            break;
+-      }
+-   }
+-
+-   if ( res )
+-   {
+-      for (i=0; i<res; i++)
+-      {
+-         if (dlist[i].page)
+-         {
+-            page_cache_release(dlist[i].page);
+-         }
+-      }
+-   }
+-
+-   Novfs_Free(pages);
+-   Novfs_Free(dlist);
+-
+-   DbgPrint("Novfs_Write_File *Bytes=0x%x retCode=0x%x\n", *Bytes, retCode);
+-
+-   return( retCode );
+-}
+-
+-/*++======================================================================*/
+-int Novfs_Write_File2( u_long Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PWRITE_FILE_REQUEST cmd;
+-   PWRITE_FILE_REPLY   reply=NULL;
+-   u_long replylen=0;
+-   int retCode=0, cmdlen;
+-   size_t len;
+-
+-   len = *Bytes;
+-   cmdlen = len+(int)(&((PWRITE_FILE_REQUEST)0)->data);
+-   *Bytes = 0;
+-
+-   if (cmdlen > MAX_IO_SIZE)
+-   {
+-      cmdlen = MAX_IO_SIZE;
+-      len = cmdlen - (int)(&((PWRITE_FILE_REQUEST)0)->data);
+-   }
+-
+-   DbgPrint("Novfs_Write_File cmdlen=%d len=%d\n", cmdlen, len);
+-
+-   cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-
+-   if (cmd)
+-   {
+-      len -= copy_from_user(cmd->data, Buffer, len);
+-      DbgPrint("Novfs_Write_File len=%d\n", len);
+-      if (len)
+-      {
+-         cmd->Command.CommandType    = VFS_COMMAND_WRITE_FILE;
+-         cmd->Command.SequenceNumber = 0;
+-         cmd->Command.SessionId      = SessionId;
+-
+-         cmd->handle = Handle;
+-         cmd->len    = len;
+-         cmd->offset = *Offset;
+-
+-         retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+-         if (!retCode)
+-         {
+-            if (reply)
+-            {
+-               switch (reply->Reply.ErrorCode)
+-               {
+-                  case 0:
+-                     *Bytes = (size_t)reply->bytesWritten;
+-                     retCode = 0;
+-                     break;
+-
+-                  case NWE_INSUFFICIENT_SPACE:
+-                     retCode = -ENOSPC;
+-                     break;
+-
+-                  case NWE_ACCESS_DENIED:
+-                     retCode = -EACCES;
+-                     break;
+-
+-                  default:
+-                     retCode = -EIO;
+-                     break;
+-               }
+-            }
+-         }
+-         if ( reply )
+-         {
+-            Novfs_Free(reply);
+-         }
+-
+-      }
+-      Novfs_Free(cmd);
+-   }
+-   DbgPrint("Novfs_Write_File *Bytes=0x%x retCode=0x%x\n", *Bytes, retCode);
+-
+-   return( retCode );
+-}
+-
+-/*++======================================================================*/
+-int Novfs_Read_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, int User, session_t SessionId)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   READ_STREAM_REQUEST cmd;
+-   PREAD_STREAM_REPLY  reply=NULL;
+-   u_long replylen=0;
+-   int retCode = 0;
+-   size_t len;
+-
+-   len = *Bytes;
+-   *Bytes = 0;
+-
+-   if ( ((int)(&((PREAD_FILE_REPLY)0)->data) + len) > MAX_IO_SIZE)
+-   {
+-      len = MAX_IO_SIZE - (int)(&((PREAD_FILE_REPLY)0)->data);
+-      len = (len/PAGE_SIZE)*PAGE_SIZE;
+-   }
+-
+-   cmd.Command.CommandType    = VFS_COMMAND_READ_STREAM;
+-   cmd.Command.SequenceNumber = 0;
+-   cmd.Command.SessionId      = SessionId;
+-
+-   cmd.connection = ConnHandle;
+-   memcpy( cmd.handle, Handle, sizeof(cmd.handle));
+-   cmd.len    = len;
+-   cmd.offset = *Offset;
+-
+-   retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+-
+-   DbgPrint("Novfs_Read_Stream: Queue_Daemon_Command 0x%x replylen=%d\n", retCode, replylen);
+-
+-   if ( reply )
+-   {
+-      retCode = 0;
+-      if (reply->Reply.ErrorCode)
+-      {
+-         retCode = -EIO;
+-      }
+-      else
+-      {
+-         replylen -= (int)(&((PREAD_STREAM_REPLY)0)->data);
+-         if (replylen > 0)
+-         {
+-            if (User)
+-            {
+-               replylen -= copy_to_user(Buffer, reply->data, replylen);
+-            }
+-            else
+-            {
+-               memcpy(Buffer, reply->data, replylen);
+-            }
+-
+-            *Bytes = replylen;
+-         }
+-      }
+-      Novfs_Free(reply);
+-   }
+-
+-   DbgPrint("Novfs_Read_Stream *Bytes=0x%x retCode=0x%x\n", *Bytes, retCode);
+-
+-   return( retCode );
+-}
+-
+-/*++======================================================================*/
+-int Novfs_Write_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PWRITE_STREAM_REQUEST cmd;
+-   PWRITE_STREAM_REPLY   reply=NULL;
+-   u_long replylen=0;
+-   int retCode=0, cmdlen;
+-   size_t len;
+-
+-   len = *Bytes;
+-   cmdlen = len+(int)(&((PWRITE_STREAM_REQUEST)0)->data);
+-   *Bytes = 0;
+-
+-   if (cmdlen > MAX_IO_SIZE)
+-   {
+-      cmdlen = MAX_IO_SIZE;
+-      len = cmdlen - (int)(&((PWRITE_STREAM_REQUEST)0)->data);
+-   }
+-
+-   DbgPrint("Novfs_Write_Stream cmdlen=%d len=%d\n", cmdlen, len);
+-
+-   cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-
+-   if (cmd)
+-   {
+-      if (Buffer && len)
+-      {
+-         len -= copy_from_user(cmd->data, Buffer, len);
+-      }
+-
+-      DbgPrint("Novfs_Write_Stream len=%d\n", len);
+-
+-      cmd->Command.CommandType    = VFS_COMMAND_WRITE_STREAM;
+-      cmd->Command.SequenceNumber = 0;
+-      cmd->Command.SessionId      = SessionId;
+-
+-      cmd->connection = ConnHandle;
+-      memcpy(cmd->handle, Handle, sizeof(cmd->handle));
+-      cmd->len    = len;
+-      cmd->offset = *Offset;
+-
+-      retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+-      if (reply)
+-      {
+-         switch (reply->Reply.ErrorCode)
+-         {
+-            case 0:
+-               retCode = 0;
+-               break;
+-
+-            case NWE_INSUFFICIENT_SPACE:
+-               retCode = -ENOSPC;
+-               break;
+-
+-            case NWE_ACCESS_DENIED:
+-               retCode = -EACCES;
+-               break;
+-
+-            default:
+-               retCode = -EIO;
+-               break;
+-         }
+-         DbgPrint("Novfs_Write_Stream reply->bytesWritten=0x%lx\n", reply->bytesWritten);
+-         *Bytes = reply->bytesWritten;
+-         Novfs_Free(reply);
+-      }
+-      Novfs_Free(cmd);
+-   }
+-   DbgPrint("Novfs_Write_Stream *Bytes=0x%x retCode=0x%x\n", *Bytes, retCode);
+-
+-   return( retCode );
+-}
+-
+-/*++======================================================================*/
+-int Novfs_Close_Stream( u_long ConnHandle, u_char *Handle, session_t SessionId )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   CLOSE_STREAM_REQUEST cmd;
+-   PCLOSE_STREAM_REPLY  reply;
+-   u_long replylen=0;
+-   int retCode;
+-
+-   cmd.Command.CommandType    = VFS_COMMAND_CLOSE_STREAM;
+-   cmd.Command.SequenceNumber = 0;
+-   cmd.Command.SessionId      = SessionId;
+-
+-   cmd.connection = ConnHandle;
+-   memcpy(cmd.handle, Handle, sizeof(cmd.handle));
+-
+-   retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, 0);
+-   if (reply)
+-   {
+-      retCode = 0;
+-      if (reply->Reply.ErrorCode)
+-      {
+-         retCode = -EIO;
+-      }
+-      Novfs_Free(reply);
+-   }
+-   return( retCode );
+-}
+-
+-/*++======================================================================*/
+-int Novfs_Delete( u_char *Path, int DirectoryFlag, session_t SessionId )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PDELETE_FILE_REQUEST cmd;
+-   PDELETE_FILE_REPLY   reply;
+-   u_long replylen=0;
+-   int retCode, cmdlen, pathlen;
+-
+-   pathlen = strlen(Path);
+-   
+-   if (StripTrailingDots)
+-   {
+-      if ('.' == Path[pathlen-1]) pathlen--;
+-   }
+-
+-   cmdlen = (int)(&((PDELETE_FILE_REQUEST)0)->path) + pathlen;
+-   cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-   if (cmd)
+-   {
+-      cmd->Command.CommandType    = VFS_COMMAND_DELETE_FILE;
+-      cmd->Command.SequenceNumber = 0;
+-      cmd->Command.SessionId      = SessionId;
+-
+-      cmd->isDirectory = DirectoryFlag;
+-      cmd->pathlength = pathlen;
+-      memcpy(cmd->path, Path, pathlen);
+-
+-      retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+-      if (reply)
+-      {
+-         retCode = 0;
+-         if (reply->Reply.ErrorCode)
+-         {
+-            if ((reply->Reply.ErrorCode & 0xFFFF) == 0x0006) /* Access Denied Error */
+-            {
+-               retCode = -EACCES;
+-            }
+-            else
+-            {
+-               retCode = -EIO;
+-            }
+-         }
+-         Novfs_Free(reply);
+-      }
+-      Novfs_Free(cmd);
+-   }
+-   else
+-   {
+-      retCode = -ENOMEM;
+-   }
+-   return( retCode );
+-}
+-
+-/*++======================================================================*/
+-int Novfs_Truncate_File( u_char *Path, int PathLen, session_t SessionId )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PTRUNCATE_FILE_REQUEST cmd;
+-   PTRUNCATE_FILE_REPLY   reply;
+-   u_long replylen=0;
+-   int retCode, cmdlen;
+-
+-   if (StripTrailingDots)
+-   {
+-      if ('.' == Path[PathLen-1]) PathLen--;
+-   }
+-   cmdlen = (int)(&((PTRUNCATE_FILE_REQUEST)0)->path) + PathLen;
+-   cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-   if (cmd)
+-   {
+-      cmd->Command.CommandType    = VFS_COMMAND_TRUNCATE_FILE;
+-      cmd->Command.SequenceNumber = 0;
+-      cmd->Command.SessionId      = SessionId;
+-
+-      cmd->pathLen = PathLen;
+-      memcpy(cmd->path, Path, PathLen);
+-
+-      retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+-      if (reply)
+-      {
+-         if (reply->Reply.ErrorCode)
+-         {
+-            retCode = -EIO;
+-         }
+-         Novfs_Free(reply);
+-      }
+-      Novfs_Free(cmd);
+-   }
+-   else
+-   {
+-      retCode = -ENOMEM;
+-   }
+-   return( retCode );
+-}
+-
+-/*++======================================================================*/
+-int Novfs_Rename_File( int DirectoryFlag, u_char *OldName, int OldLen, u_char *NewName, int NewLen, session_t SessionId )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   RENAME_FILE_REQUEST cmd;
+-   PRENAME_FILE_REPLY  reply;
+-   u_long replylen=0;
+-   int retCode;
+-
+-   DbgPrint("Novfs_Rename_File:\n" \
+-            "   DirectoryFlag: %d\n" \
+-            "   OldName:       %.*s\n" \
+-            "   NewName:       %.*s\n" \
+-            "   SessionId:     0x%llx\n",
+-      DirectoryFlag, 
+-      OldLen, OldName,
+-      NewLen, NewName, 
+-      SessionId );
+-
+-   cmd.Command.CommandType    = VFS_COMMAND_RENAME_FILE;
+-   cmd.Command.SequenceNumber = 0;
+-   cmd.Command.SessionId      = SessionId;
+-
+-   cmd.directoryFlag = DirectoryFlag;
+-
+-   if (StripTrailingDots)
+-   {
+-      if ('.' == OldName[OldLen-1]) OldLen--;
+-      if ('.' == NewName[NewLen-1]) NewLen--;
+-   }
+-
+-   cmd.newnameLen = NewLen;
+-   memcpy(cmd.newname, NewName, NewLen);
+-
+-   cmd.oldnameLen = OldLen;
+-   memcpy(cmd.oldname, OldName, OldLen);
+-
+-   retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+-   if (reply)
+-   {
+-      retCode = 0;
+-      if (reply->Reply.ErrorCode)
+-      {
+-         retCode = -ENOENT;
+-      }
+-      Novfs_Free(reply);
+-   }
+-   return( retCode );
+-}
+-
+-/*++======================================================================*/
+-int Novfs_Set_Attr( u_char *Path, struct iattr *Attr, session_t SessionId )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PSET_FILE_INFO_REQUEST cmd;
+-   PSET_FILE_INFO_REPLY   reply;
+-   u_long replylen=0;
+-   int retCode, cmdlen, pathlen;
+-
+-   pathlen = strlen(Path);
+-
+-   if (StripTrailingDots)
+-   {
+-      if ('.' == Path[pathlen-1]) pathlen--;
+-   }
+-
+-   cmdlen = (int)(&((PSET_FILE_INFO_REQUEST)0)->path) + pathlen;
+-   cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-   if (cmd)
+-   {
+-      cmd->Command.CommandType    = VFS_COMMAND_SET_FILE_INFO;
+-      cmd->Command.SequenceNumber = 0;
+-      cmd->Command.SessionId      = SessionId;
+-      cmd->fileInfo.ia_valid      = Attr->ia_valid;
+-      cmd->fileInfo.ia_mode       = Attr->ia_mode;
+-      cmd->fileInfo.ia_uid        = Attr->ia_uid;
+-      cmd->fileInfo.ia_gid        = Attr->ia_uid;
+-      cmd->fileInfo.ia_size       = Attr->ia_size;
+-      cmd->fileInfo.ia_atime      = Attr->ia_atime.tv_sec;
+-      cmd->fileInfo.ia_mtime      = Attr->ia_mtime.tv_sec;;
+-      cmd->fileInfo.ia_ctime      = Attr->ia_ctime.tv_sec;;
+-/*
+-      cmd->fileInfo.ia_attr_flags = Attr->ia_attr_flags;
+-*/
+-      cmd->fileInfo.ia_attr_flags = 0;
+-
+-      cmd->pathlength = pathlen;
+-      memcpy(cmd->path, Path, pathlen);
+-
+-      retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+-      if (reply)
+-      {
+-         switch( reply->Reply.ErrorCode )
+-         {
+-            case 0:
+-               retCode = 0;
+-               break;
+-
+-            case NWE_PARAM_INVALID:
+-               retCode = -EINVAL;
+-               break;
+-
+-            default:
+-               retCode = -EIO;
+-               break;
+-         }
+-         Novfs_Free(reply);
+-      }
+-      Novfs_Free(cmd);
+-   }
+-   else
+-   {
+-      retCode = -ENOMEM;
+-   }
+-   return( retCode );
+-}
+diff -uNr src.old/novfs/inode.c src/novfs/inode.c
+--- src.old/novfs/inode.c	2006-07-11 21:24:18.000000000 +0200
++++ src/novfs/inode.c	1970-01-01 01:00:00.000000000 +0100
+@@ -1,4584 +0,0 @@
+-/*++========================================================================
+- * Program Name:     Novell NCP Redirector for Linux
+- * File Name:        inode.c
+- * Version:          v1.00
+- * Author:           James Turner
+- *
+- * Abstract:         This module contains functions used to control
+- *                   access to the Linux file system.
+- * Notes:
+- * Revision History: 
+- *
+- *
+- * Copyright (C) 2005 Novell, Inc.
+- *
+- * 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 files specific to Linux ]==================================*/
+-#include <linux/module.h>
+-#include <linux/config.h>
+-#include <linux/init.h>
+-#include <linux/fs.h>
+-#include <linux/dcache.h>
+-#include <linux/mount.h>
+-#include <linux/pagemap.h>
+-#include <linux/string.h>
+-#include <linux/smp_lock.h>
+-#include <linux/slab.h>
+-#include <linux/unistd.h>
+-#include <linux/backing-dev.h>
+-#include <asm/statfs.h>
+-#include <asm/uaccess.h>
+-#include <linux/ctype.h>
+-#include <linux/statfs.h>
+-
+-/*===[ Include files specific to this module ]============================*/
+-#include "vfs.h"
+-
+-/*===[ External data ]====================================================*/
+-
+-/*===[ External prototypes ]==============================================*/
+-extern int DbgPrint( char *Fmt, ... );
+-extern int LocalPrint( char *Fmt, ... );
+-
+-extern int Init_Procfs_Interface( void );
+-extern void Uninit_Procfs_Interface( void );
+-extern void mydump(int size, void *dumpptr);
+-
+-/*
+- * Daemon.c functions
+- */
+-extern void Init_Daemon_Queue( void );
+-extern void Uninit_Daemon_Queue( void );
+-extern int do_logout( struct qstr *Server );
+-extern int Daemon_SetMountPoint( char *Path );
+-
+-/*
+- * file.c functions
+- */
+-extern int Novfs_verify_file( struct qstr *Path, session_t SessionId );
+-extern int Novfs_get_alltrees(struct dentry *parent);
+-extern int Novfs_Get_Connected_Server_List( unsigned char **ServerList, session_t SessionId );
+-extern int Novfs_Get_Server_Volume_List( struct qstr *Server, unsigned char **VolumeList, session_t SessionId );
+-extern int Novfs_Verify_Server_Name( struct qstr *Server, session_t SessionId );
+-extern int Novfs_Verify_Volume_Name( struct qstr *Server,  struct qstr *Volume, session_t SessionId );
+-extern int Novfs_Get_File_Info( unsigned char *Path, PENTRY_INFO Info, session_t SessionId  );
+-extern int Novfs_Get_Directory_List( unsigned char *Path, unsigned long *EnumHandle, PENTRY_INFO Info, session_t SessionId );
+-extern int Novfs_Get_Directory_ListEx( unsigned char *Path, unsigned long *EnumHandle, int *Count, PENTRY_INFO *Info, session_t SessionId );
+-extern int Novfs_Open_File( unsigned char *Path, int Flags, PENTRY_INFO Info, unsigned long *Handle, session_t SessionId );
+-extern int Novfs_Create( unsigned char *Path, int DirectoryFlag, session_t SessionId );
+-extern int Novfs_Close_File( unsigned long Handle, session_t SessionId );
+-extern int Novfs_Read_File( unsigned long Handle, unsigned char *Buffer, size_t *Bytes, loff_t *Offset, int User, session_t SessionId);
+-extern int Novfs_Write_File( unsigned long Handle, unsigned char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId);
+-extern int Novfs_Delete( unsigned char *Path, int DirectoryFlag, session_t SessionId );
+-extern int Novfs_Truncate_File( unsigned char *Path, int PathLen, session_t SessionId );
+-extern int Novfs_Rename_File( int DirectoryFlag, unsigned char *OldName, int OldLen, unsigned char *NewName, int NewLen, session_t SessionId );
+-extern int Novfs_Set_Attr( unsigned char *Path, struct iattr *Attr, session_t SessionId );
+-
+-/*
+- * scope.c functions
+- */
+-extern void Scope_Init( void );
+-extern void Scope_Uninit( void );
+-extern void *Scope_Lookup( void );
+-extern unsigned long Scope_Get_Hash( void *);
+-extern uid_t Scope_Get_Uid( void *);
+-extern session_t Scope_Get_SessionId( void *Scope );
+-extern void *Scope_Get_ScopefromName( struct qstr *Name );
+-extern void *Scope_Get_ScopefromPath( struct dentry *Dentry );
+-extern char *Scope_Get_ScopeUsers( void );
+-extern int Scope_Set_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties );
+-extern int Scope_Get_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties );
+-extern char *Scope_dget_path( struct dentry *Dentry, char *Buf, unsigned int Buflen, int Flags);
+-
+-/*
+- * profile.c functions
+- */
+-extern int init_profile( void );
+-
+-/*===[ Manifest constants ]===============================================*/
+-#define FILE_UPDATE_TIMEOUT   2
+-
+-/*===[ Type definitions ]=================================================*/
+-
+-/*===[ Function prototypes ]==============================================*/
+-int Novfs_Remove_from_Root(char *RemoveName);
+-int Novfs_Add_to_Root(char *);
+-char  *Novfs_dget_path( struct dentry *d, char *path, unsigned int pathlen );
+-int verify_dentry(struct dentry *dentry, int Flags);
+-int invalidate_dentry(struct dentry *parent);
+-struct dentry *Novfs_d_lookup(struct dentry *Parent, struct qstr *Name);
+-int Novfs_d_add(struct dentry *p, struct dentry *d, struct inode *i, int add);
+-int Novfs_d_strcmp (struct qstr *s1, struct qstr *s2);
+-struct inode *Novfs_get_inode(struct super_block *sb, int mode, int dev, uid_t uid, ino_t ino, struct qstr *name);
+-unsigned long Novfs_internal_hash (struct qstr *name);
+-
+-struct super_block *Novfs_get_sb (struct file_system_type *Fstype, int Flags, const char *Dev_name, void *Data);
+-void Novfs_kill_sb(struct super_block *SB);
+-int Novfs_fill_super (struct super_block *SB, void *Data, int Silent);
+-
+-/*
+- * Declared dentry_operations
+- */
+-int Novfs_d_revalidate(struct dentry *, struct nameidata *);
+-int Novfs_d_hash (struct dentry *, struct qstr *);
+-int Novfs_d_compare (struct dentry *, struct qstr *, struct qstr *);
+-int Novfs_d_delete(struct dentry *dentry);
+-void Novfs_d_release(struct dentry *dentry);
+-void Novfs_d_iput(struct dentry *dentry, struct inode *inode);
+-
+-/*
+- * Declared directory operations
+- */
+-int Novfs_dir_open(struct inode *inode, struct file *file);
+-int Novfs_dir_release(struct inode *inode, struct file *file);
+-loff_t  Novfs_dir_lseek(struct file *file, loff_t offset, int origin);
+-int Novfs_dir_read(struct file *file, char *buf, size_t len, loff_t *off);
+-void addtodentry( struct dentry *Parent, unsigned char *List, int Level );
+-int Novfs_filldir(void *data, const char *name, int namelen, loff_t off, ino_t ino, unsigned ftype);
+-int Novfs_dir_readdir(struct file * filp, void * dirent, filldir_t filldir);
+-int Novfs_dir_fsync(struct file * file, struct dentry *dentry, int datasync);
+-
+-/*
+- * Declared address space operations
+- */
+-int Novfs_a_readpage(struct file *file, struct page *page);
+-
+-/*
+- * Declared file_operations
+- */
+-ssize_t Novfs_f_read(struct file *, char *, size_t, loff_t *);
+-ssize_t Novfs_f_write(struct file *, const char *, size_t, loff_t *);
+-int Novfs_f_readdir(struct file *, void *, filldir_t);
+-int Novfs_f_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
+-int Novfs_f_mmap(struct file * file, struct vm_area_struct * vma);
+-int Novfs_f_open(struct inode *, struct file *);
+-int Novfs_f_flush(struct file *);
+-int Novfs_f_release(struct inode *, struct file *);
+-int Novfs_f_fsync(struct file *, struct dentry *, int datasync);
+-int Novfs_f_lock(struct file *, int, struct file_lock *);
+-
+-/*
+- * Declared inode_operations
+- */
+-int Novfs_i_create(struct inode *,struct dentry *,int, struct nameidata *);
+-struct dentry * Novfs_i_lookup(struct inode *,struct dentry *, struct nameidata *);
+-int Novfs_i_mkdir(struct inode *,struct dentry *,int);
+-int Novfs_i_unlink(struct inode *dir, struct dentry *dentry);
+-int Novfs_i_rmdir(struct inode *,struct dentry *);
+-int Novfs_i_mknod(struct inode *,struct dentry *,int,dev_t);
+-int Novfs_i_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
+-int Novfs_i_permission(struct inode *inode, int mask);
+-int Novfs_i_setattr(struct dentry *, struct iattr *);
+-int Novfs_i_getattr(struct vfsmount *mnt, struct dentry *, struct kstat *);
+-int Novfs_i_revalidate(struct dentry *dentry);
+-
+-void update_inode(struct inode *Inode, PENTRY_INFO Info);
+-
+-/*
+- * Declared super_operations
+- */
+-void Novfs_read_inode(struct inode *inode);
+-void Novfs_write_inode(struct inode *inode);
+-int Novfs_notify_change(struct dentry *dentry, struct iattr *attr);
+-void Novfs_clear_inode(struct inode *inode);
+-int Novfs_show_options( struct seq_file *s, struct vfsmount *m );
+-int Novfs_statfs(struct super_block *sb, struct kstatfs *buf);
+-
+-/*
+- * Declared control interface functions
+- */
+-ssize_t
+-Novfs_Control_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos);
+-
+-ssize_t
+-Novfs_Control_write(struct file * file, const char * buf, size_t nbytes, loff_t *ppos);
+-
+-int Novfs_Control_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
+-
+-int __init init_novfs(void);
+-void __exit exit_novfs(void);
+-
+-int Novfs_lock_inode_cache( struct inode *i );
+-void Novfs_unlock_inode_cache( struct inode *i );
+-int Novfs_enumerate_inode_cache( struct inode *i, struct list_head **iteration, ino_t *ino, PENTRY_INFO info);
+-int Novfs_get_entry( struct inode *i, struct qstr *name, ino_t *ino, PENTRY_INFO info);
+-int Novfs_get_entry_time( struct inode *i, struct qstr *name, ino_t *ino, PENTRY_INFO info, u64 *EntryTime);
+-int Novfs_get_remove_entry( struct inode *i, ino_t *ino, PENTRY_INFO info);
+-void Novfs_invalidate_inode_cache( struct inode *i );
+-PDIR_CACHE Novfs_lookup_inode_cache( struct inode *i, struct qstr *name, ino_t ino );
+-int Novfs_lookup_validate( struct inode *i, struct qstr *name, ino_t ino );
+-int Novfs_add_inode_entry( struct inode *i, struct qstr *name, ino_t ino, PENTRY_INFO info);
+-int Novfs_update_entry( struct inode *i, struct qstr *name, ino_t ino, PENTRY_INFO info);
+-void Novfs_remove_inode_entry( struct inode *i, struct qstr *name, ino_t ino);
+-void Novfs_free_invalid_entries( struct inode *i );
+-void Novfs_free_inode_cache( struct inode *i );
+-
+-/*===[ Global variables ]=================================================*/
+-struct dentry_operations Novfs_dentry_operations = {
+-   .d_revalidate  = Novfs_d_revalidate,
+-   .d_hash        = Novfs_d_hash,
+-   .d_compare     = Novfs_d_compare,
+-   .d_delete      = Novfs_d_delete,
+-   .d_release     = Novfs_d_release,
+-   .d_iput        = Novfs_d_iput,
+-};
+-
+-struct file_operations Novfs_dir_operations = {
+-   .open    = Novfs_dir_open,
+-   .release = Novfs_dir_release,
+-   .llseek  = Novfs_dir_lseek,
+-   .read    = Novfs_dir_read,
+-   .readdir = Novfs_dir_readdir,
+-   .fsync   = Novfs_dir_fsync,
+-};
+-
+-static struct file_operations Novfs_file_operations = {
+-   .read    = Novfs_f_read,
+-   .write   = Novfs_f_write,
+-   .readdir = Novfs_f_readdir,
+-   .ioctl   = Novfs_f_ioctl,
+-   .mmap    = Novfs_f_mmap,
+-   .open    = Novfs_f_open,
+-   .release = Novfs_f_release,
+-   .fsync   = Novfs_f_fsync,
+-	.llseek  = generic_file_llseek,
+-};
+-
+-static struct address_space_operations Novfs_aops = {
+-   .readpage   = Novfs_a_readpage,
+-};
+-
+-static struct inode_operations Novfs_inode_operations = {
+-   .create     = Novfs_i_create,
+-   .lookup     = Novfs_i_lookup,
+-   .unlink     = Novfs_i_unlink,
+-   .mkdir      = Novfs_i_mkdir,
+-   .rmdir      = Novfs_i_rmdir,
+-   .mknod      = Novfs_i_mknod,
+-   .rename     = Novfs_i_rename,
+-   .setattr    = Novfs_i_setattr,
+-   .getattr    = Novfs_i_getattr,
+-};
+-
+-static struct inode_operations Novfs_file_inode_operations = {
+-   .setattr    = Novfs_i_setattr,
+-   .getattr    = Novfs_i_getattr,
+-};
+-
+-static struct super_operations Novfs_ops = {
+-   .read_inode    = Novfs_read_inode,
+-   .statfs        = Novfs_statfs,
+-   .clear_inode   = Novfs_clear_inode,
+-	.drop_inode	   = generic_delete_inode,
+-   .show_options  = Novfs_show_options,
+-
+-};
+-
+-/* Not currently used
+-static struct file_operations Novfs_Control_operations = {
+-   .read    = Novfs_Control_read,
+-   .write   = Novfs_Control_write,
+-   .ioctl   = Novfs_Control_ioctl,
+-};
+-*/
+-
+-ino_t Novfs_Inode_Number=1;
+-
+-static struct file_system_type Novfs_fs_type = {
+-   .name    = "novfs", 
+-   .get_sb  = Novfs_get_sb,
+-   .kill_sb = Novfs_kill_sb,
+-	.owner	= THIS_MODULE,
+-};
+-
+-struct dentry *Novfs_root=NULL;
+-
+-int Novfs_Version_Major=NOVFS_VFS_MAJOR;
+-int Novfs_Version_Minor=NOVFS_VFS_MINOR;
+-int Novfs_Version_Sub=NOVFS_VFS_SUB;
+-int Novfs_Version_Release=NOVFS_VFS_RELEASE;
+-
+-char *Novfs_CurrentMount=NULL;
+-
+-DECLARE_MUTEX(InodeList_lock);
+-
+-LIST_HEAD(InodeList);
+-
+-unsigned long InodeCount=0, DCCount=0;
+-unsigned long File_update_timeout=FILE_UPDATE_TIMEOUT;
+-/*===[ Code ]=============================================================*/
+-static __inline__ void PRINT_DENTRY(const char *s, struct dentry *d)
+-{
+-   DbgPrint("%s: 0x%x\n",    s, d);
+-   DbgPrint("   d_count:      0x%x\n", d->d_count);
+-   DbgPrint("   d_lock:       0x%x\n", d->d_lock);
+-   DbgPrint("   d_inode:      0x%x\n", d->d_inode);
+-   DbgPrint("   d_lru:        0x%x\n" \
+-            "      next:      0x%x\n" \
+-            "      prev:      0x%x\n", &d->d_lru, d->d_lru.next, d->d_lru.prev);
+-   DbgPrint("   d_child:      0x%x\n" \
+-            "      next:      0x%x\n" \
+-            "      prev:      0x%x\n", &d->D_CHILD, d->D_CHILD.next, d->D_CHILD.prev);
+-   DbgPrint("   d_subdirs:    0x%x\n" \
+-            "      next:      0x%x\n" \
+-            "      prev:      0x%x\n", &d->d_subdirs, d->d_subdirs.next, d->d_subdirs.prev);
+-   DbgPrint("   d_alias:      0x%x\n" \
+-            "      next:      0x%x\n" \
+-            "      prev:      0x%x\n", &d->d_alias, d->d_alias.next, d->d_alias.prev);
+-   DbgPrint("   d_time:       0x%x\n", d->d_time);
+-   DbgPrint("   d_op:         0x%x\n", d->d_op);
+-   DbgPrint("   d_sb:         0x%x\n", d->d_sb);
+-   DbgPrint("   d_flags:      0x%x\n", d->d_flags);
+-   DbgPrint("   d_mounted:    0x%x\n", d->d_mounted);
+-   DbgPrint("   d_fsdata:     0x%x\n", d->d_fsdata);
+-/*   DbgPrint("   d_cookie:     0x%x\n", d->d_cookie); */
+-   DbgPrint("   d_parent:     0x%x\n", d->d_parent);
+-   DbgPrint("   d_name:       0x%x %.*s\n", &d->d_name, d->d_name.len, d->d_name.name);
+-   DbgPrint("      name:      0x%x\n" \
+-            "      len:       %d\n"   \
+-            "      hash:      0x%x\n", d->d_name.name, d->d_name.len, d->d_name.hash);
+-   DbgPrint("   d_hash:       0x%x\n" \
+-            "      next:      0x%x\n" \
+-            "      pprev:     0x%x\n", d->d_hash, d->d_hash.next, d->d_hash.pprev);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_Remove_from_Root(char *RemoveName)
+-/*
+- *  Arguments:
+- * 
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   struct qstr name;
+-   struct dentry *dentry;
+-   struct inode *dir;
+-
+-   DbgPrint( "Novfs_Remove_from_Root: %s\n", RemoveName);
+-   name.len  = strlen(RemoveName);
+-   name.name = RemoveName;
+-   Novfs_d_hash(Novfs_root, &name);
+-
+-   dentry = d_lookup( Novfs_root, &name);
+-   if (dentry)
+-   {
+-      if (dentry->d_inode && dentry->d_inode->u.generic_ip)
+-      {
+-         ((PINODE_DATA)(dentry->d_inode->u.generic_ip))->Scope = NULL;
+-      }
+-      dput(dentry);
+-   }
+-
+-   
+-   dir = Novfs_root->d_inode;
+-
+-   Novfs_lock_inode_cache( dir );
+-   Novfs_remove_inode_entry( dir, &name, 0);
+-   Novfs_unlock_inode_cache( dir );
+-
+-   return(0);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_Add_to_Root(char *AddName)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   struct qstr name;
+-   struct inode *dir;
+-   ENTRY_INFO info;
+-   ino_t ino;
+-
+-   DbgPrint( "Novfs_Add_to_Root: %s\n", AddName);
+-   name.len  = strlen(AddName);
+-   name.name = AddName;
+-   Novfs_d_hash(Novfs_root, &name);
+-
+-   dir = Novfs_root->d_inode;
+-
+-   Novfs_lock_inode_cache( dir );
+-
+-   ino = 0;
+-
+-   if ( !Novfs_lookup_inode_cache(dir, &name, 0))
+-   {
+-      info.mode = S_IFDIR | 0700;
+-      info.size = 0;
+-      info.atime = info.ctime = info.mtime = CURRENT_TIME;
+-
+-      ino = (ino_t)InterlockedIncrement(&Novfs_Inode_Number);
+-      Novfs_add_inode_entry( dir, &name, ino, &info);
+-   }
+-
+-   Novfs_unlock_inode_cache( dir );
+-
+-   return(0);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_Add_to_Root2(char *AddName)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   struct dentry *entry;
+-   struct qstr name;
+-   struct inode *inode;
+-   void *scope;
+-
+-   DbgPrint( "Novfs_Add_to_Root: %s\n", AddName);
+-   name.len  = strlen(AddName);
+-   name.name = AddName;
+-
+-   Novfs_d_hash(Novfs_root, &name);
+-
+-   entry = Novfs_d_lookup(Novfs_root, &name);
+-   DbgPrint( "Novfs_Add_to_Root: Novfs_d_lookup 0x%x\n", entry);
+-   if ( NULL == entry )
+-   {
+-      scope = Scope_Lookup();
+-
+-      entry = d_alloc(Novfs_root, &name);
+-      DbgPrint( "Novfs_Add_to_Root: d_alloc 0x%x\n", entry );
+-      if (entry)
+-      {
+-         entry->d_op = &Novfs_dentry_operations;
+-         entry->d_time = jiffies+(File_update_timeout*HZ);
+-         /*
+-          * done in Novfs_d_add now... entry->d_fsdata = (void *)Novfs_internal_hash( &name );
+-          */
+-         inode = Novfs_get_inode(Novfs_root->d_sb, S_IFDIR | 0700, 0, Scope_Get_Uid(scope), 0, &name);
+-         DbgPrint( "Novfs_Add_to_Root: Inode=0x%x\n", inode);
+-         if (inode)
+-         {
+-            inode->i_atime = 
+-            inode->i_ctime = 
+-            inode->i_mtime = CURRENT_TIME;
+-            if ( !Novfs_d_add(Novfs_root, entry, inode, 1))
+-            {
+-               if (inode->u.generic_ip)
+-               {
+-                  ((PINODE_DATA)inode->u.generic_ip)->Flags = USER_INODE;
+-               }
+-               PRINT_DENTRY("After Novfs_d_add", entry);
+-            }
+-            else
+-            {
+-               dput(entry);
+-               iput(inode);
+-            }
+-         }
+-      }
+-   }
+-   else
+-   {
+-      dput(entry);
+-      PRINT_DENTRY("Novfs_Add_to_Root: After dput Dentry", entry);
+-   }
+-   return(0);
+-}
+-
+-/*++======================================================================*/
+-char  *Novfs_dget_path( struct dentry *Dentry, char *Buf, unsigned int Buflen)
+-/*
+- *  Arguments:   struct dentry *Dentry - starting entry
+- *               char *Buf - pointer to memory buffer
+- *               unsigned int Buflen - size of memory buffer
+- * 
+- *  Returns:     pointer to path.
+- * 
+- *  Abstract:    Walks the dentry chain building a path.
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   char *retval=&Buf[Buflen];
+-   struct dentry *p=Dentry;
+-
+-   *(--retval) = '\0';
+-   Buflen--;
+-
+-   if (!IS_ROOT(p) && !IS_ROOT(p->d_parent))
+-   {
+-      while (Buflen && !IS_ROOT(p) && !IS_ROOT(p->d_parent))
+-      {
+-         if (Buflen > p->d_name.len)
+-         {
+-            retval -= p->d_name.len;
+-            Buflen -= p->d_name.len;
+-            memcpy(retval, p->d_name.name, p->d_name.len);
+-            *(--retval) = '\\';
+-            Buflen--;
+-            p = p->d_parent;
+-         }
+-         else
+-         {
+-            retval = NULL;
+-            break;
+-         }
+-      }
+-   }
+-   else
+-   {
+-      *(--retval) = '\\';
+-   }
+-
+-
+-
+-if (retval) DbgPrint("Novfs_dget_path: %s\n", retval);
+-   return(retval);
+-}
+-
+-/*++======================================================================*/
+-int verify_dentry( struct dentry *dentry, int Flags )
+-/*
+- *  Arguments:   struct dentry *dentry - entry to verify
+- *
+- *  Returns:     zero - Inode cache has been updated.  If not in the cache
+- *                      then file doesn't exist.
+- *               !zero - Error
+- *
+- *  Abstract:    This routine will verify if the file that dentry is pointing
+- *               at exist and if it does it will put it in the inode cache of
+- *               the parent.
+- *
+- *  Notes:
+- *
+- *  Environment: 
+- *
+- *========================================================================*/
+-{
+-   int retVal = -ENOENT;
+-   struct inode *dir;
+-   PENTRY_INFO info=NULL;
+-   PINODE_DATA id;
+-   session_t session;
+-   char *path, *list=NULL, *cp;
+-   ino_t ino;
+-   struct qstr name;
+-   int iLock=0;
+-   struct dentry *parent=NULL;
+-   u64 ctime;
+-   struct inode *inode;
+-
+-   if ( IS_ROOT(dentry) )
+-   {
+-      DbgPrint("verify_dentry: Root entry\n");
+-      return( 0 );
+-   }
+-
+-   if ( dentry && dentry->d_parent && 
+-        (dir = dentry->d_parent->d_inode) && 
+-        (id = dir->u.generic_ip) )
+-   {
+-      parent = dget_parent(dentry);
+-
+-      info = Novfs_Malloc(sizeof(ENTRY_INFO)+PATH_LENGTH_BUFFER, GFP_KERNEL);
+-
+-      if (info)
+-      {
+-         if (Novfs_lock_inode_cache( dir ))
+-         {
+-            name.len = dentry->d_name.len;
+-            name.name = dentry->d_name.name;
+-            name.hash = Novfs_internal_hash( &name );
+-            if ( !Novfs_get_entry_time(dir, &name, &ino, info, &ctime))
+-            {
+-               inode = dentry->d_inode;
+-               if ( inode && 
+-                    ( (inode->i_size != info->size) ||
+-                      (inode->i_mtime.tv_sec != info->mtime.tv_sec) ))
+-               {
+-                  ((PINODE_DATA)inode->u.generic_ip)->Flags |= UPDATE_INODE;
+-               }
+-
+-               ctime = get_jiffies_64() - ctime;
+-               if ( Flags || ctime < (u64)(File_update_timeout*HZ) )
+-               {
+-                  retVal = 0;
+-                  Novfs_unlock_inode_cache(dir);
+-                  dput(parent);
+-                  Novfs_Free(info);
+-                  return(0);
+-               }
+-            }
+-            Novfs_unlock_inode_cache(dir);
+-         }
+-
+-         if ( IS_ROOT(dentry->d_parent) )
+-         {
+-            session = Scope_Get_SessionId(Scope_Get_ScopefromName(&dentry->d_name));
+-         }
+-         else
+-         {
+-            session = Scope_Get_SessionId( id->Scope );
+-         }
+-
+-         if ( !session )
+-         {
+-            id->Scope = Scope_Get_ScopefromPath(dentry);
+-            session = Scope_Get_SessionId( id->Scope );
+-         }
+-
+-         ino = 0;
+-         retVal = 0;
+-
+-         if ( IS_ROOT(dentry->d_parent) )
+-         {
+-            DbgPrint("verify_dentry: parent is Root directory\n");
+-            list = Scope_Get_ScopeUsers();
+-
+-            iLock = Novfs_lock_inode_cache( dir );
+-            Novfs_invalidate_inode_cache( dir );
+-
+-            if ( list )
+-            {
+-               cp = list;
+-               while (*cp)
+-               {
+-                  name.name = cp;
+-                  name.len  = strlen(cp);
+-                  name.hash = Novfs_internal_hash( &name );
+-                  cp += (name.len+1);
+-                  ino = 0;
+-                  if ( Novfs_get_entry( dir, &name, &ino, info ) )
+-                  {
+-                     info->mode = S_IFDIR | 0700;
+-                     info->size = 0;
+-                     info->atime = info->ctime = info->mtime = CURRENT_TIME;
+-                     ino = (ino_t)InterlockedIncrement(&Novfs_Inode_Number);
+-                     Novfs_add_inode_entry(dir, &name, ino, info);
+-                  }
+-               }
+-            }
+-            Novfs_free_invalid_entries( dir );
+-         }
+-         else
+-         {
+-            
+-            path = Novfs_dget_path(dentry, info->name, PATH_LENGTH_BUFFER);
+-            if (path)
+-            {
+-               if (dentry->d_name.len <= NW_MAX_PATH_LENGTH)
+-               {
+-                  name.hash = Novfs_internal_hash(&dentry->d_name);
+-                  name.len  = dentry->d_name.len;
+-                  name.name = dentry->d_name.name;
+-
+-
+-                  
+-                  retVal = Novfs_Get_File_Info( path, info, session );
+-                  if ( 0 == retVal)
+-                  {
+-                     dentry->d_time = jiffies+(File_update_timeout*HZ);
+-                     iLock = Novfs_lock_inode_cache( dir );
+-                     if ( Novfs_update_entry( dir, &name, 0, info ) )
+-                     {
+-                        if (dentry->d_inode)
+-                        {
+-                           ino = dentry->d_inode->i_ino;
+-                        }
+-                        else
+-                        {
+-                           ino = (ino_t)InterlockedIncrement(&Novfs_Inode_Number);
+-                        }
+-                        Novfs_add_inode_entry( dir, &name, ino, info);
+-                     }
+-                     if ( dentry->d_inode )
+-                     {
+-                        update_inode(dentry->d_inode, info);
+-                        id->Flags &= ~UPDATE_INODE;
+-
+-                        dentry->d_inode->i_flags &= ~S_DEAD;
+-                        if (dentry->d_inode->u.generic_ip)
+-                        {
+-                           ((PINODE_DATA)dentry->d_inode->u.generic_ip)->Scope = id->Scope;
+-                        }
+-                     }
+-                  }
+-                  else if (-EINTR != retVal)
+-                  {
+-                     retVal = 0;
+-                     iLock = Novfs_lock_inode_cache( dir );
+-                     Novfs_remove_inode_entry( dir, &name, 0 );
+-                     if ( dentry->d_inode  && !(dentry->d_inode->i_flags & S_DEAD) )
+-                     {
+-                        dentry->d_inode->i_flags |= S_DEAD;
+-                        dentry->d_inode->i_size  = 0;
+-                        dentry->d_inode->i_atime.tv_sec  =
+-                        dentry->d_inode->i_atime.tv_nsec =
+-                        dentry->d_inode->i_ctime.tv_sec  =
+-                        dentry->d_inode->i_ctime.tv_nsec =
+-                        dentry->d_inode->i_mtime.tv_sec  =
+-                        dentry->d_inode->i_mtime.tv_nsec = 0;
+-                        dentry->d_inode->i_blocks = 0;
+-                        d_delete(dentry);   /* Remove from cache */
+-                     }
+-                  }
+-               }
+-               else
+-               {
+-                  retVal = -ENAMETOOLONG;
+-               }
+-            }
+-         }
+-      }
+-      else
+-      {
+-         retVal = -ENOMEM;
+-      }
+-      if (iLock)
+-      {
+-         Novfs_unlock_inode_cache( dir );
+-      }
+-      dput(parent);
+-   }
+-
+-   if (list) Novfs_Free(list);
+-   if (info) Novfs_Free(info);
+-
+-   DbgPrint("verify_dentry: return=0x%x\n", retVal);
+-
+-   return(retVal);
+-}
+-
+-/*++======================================================================*/
+-struct dentry *Novfs_d_lookup(struct dentry *Parent, struct qstr *Name)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment: 
+- *
+- *========================================================================*/
+-{
+-   return( d_lookup( Parent, Name));
+-}
+-
+-/*++======================================================================*/
+-int Novfs_d_add(struct dentry *Parent, struct dentry *d, struct inode *i, int a)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment: 
+- *
+- *========================================================================*/
+-{
+-   void *scope;
+-   PINODE_DATA id=NULL;
+-
+-   char *path, *buf;
+-   
+-   buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+-   if (buf)
+-   {
+-      path = Novfs_dget_path(d, buf, PATH_LENGTH_BUFFER);
+-      if (path)
+-      {
+-         DbgPrint("Novfs_d_add: inode=0x%p ino=%d path %s\n", i, i->i_ino, path);
+-      }
+-      Novfs_Free(buf);
+-   }
+-
+-   if ( Parent && Parent->d_inode && Parent->d_inode->u.generic_ip)
+-   {
+-      id = (PINODE_DATA)Parent->d_inode->u.generic_ip;
+-   }
+-
+-   if (id && id->Scope)
+-   {
+-      scope = id->Scope;
+-   }
+-   else
+-   {
+-      scope = Scope_Get_ScopefromPath( d );
+-   }
+-
+-   ((PINODE_DATA)i->u.generic_ip)->Scope = scope;
+-
+-   d->d_time = jiffies+(File_update_timeout*HZ);
+-   if (a)
+-   {
+-      d_add(d, i);
+-   }
+-   else
+-   {
+-      d_instantiate(d, i);
+-   }
+-      
+-   return(0);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
+-/*
+- *  Arguments:   struct dentry *dentry - pointer to dentry to revalidate.
+- *               struct nameidata *nd - pointer to nameidata.
+- * 
+- *  Returns:     zero - dentry is not valid.
+- *               !zero - valid entry
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment: 
+- *
+- *========================================================================*/
+-{
+-   int retCode = 0;
+-   struct inode *dir;
+-   PINODE_DATA id;
+-   struct qstr name;
+-
+-   UNUSED_VARIABLE( nd );
+-
+-   DbgPrint("Novfs_d_revalidate: 0x%p %.*s\n" \
+-            "   d_count: %d\n" \
+-            "   d_inode: 0x%p\n",
+-      dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_count, dentry->d_inode);
+-
+-   if (IS_ROOT( dentry ))
+-   {
+-      retCode = 1;
+-   }
+-   else
+-   {
+-      if ( dentry->d_inode &&
+-           dentry->d_parent && 
+-           (dir = dentry->d_parent->d_inode) && 
+-           (id = dir->u.generic_ip) )
+-      {
+-         /*
+-          * Check timer to see if in valid time limit
+-          */
+-         if (jiffies > dentry->d_time)
+-         {
+-            /*
+-             * Revalidate entry
+-             */
+-            name.len = dentry->d_name.len;
+-            name.name = dentry->d_name.name;
+-            name.hash = Novfs_internal_hash(&dentry->d_name);
+-            dentry->d_time = 0;
+-
+-            if ( 0 == verify_dentry( dentry, 0 ))
+-            {
+-               if (Novfs_lock_inode_cache( dir ))
+-               {
+-                  if (Novfs_lookup_inode_cache( dir, &name, 0))
+-                  {
+-                     dentry->d_time = jiffies + (File_update_timeout*HZ);
+-                     retCode = 1;
+-                  }
+-                  Novfs_unlock_inode_cache( dir );
+-               }
+-            }
+-         }
+-         else
+-         {
+-            retCode = 1;
+-         }
+-      }
+-   }
+-
+-
+-   if ( ( 0 == retCode ) && dentry->d_inode )
+-   {
+-      /*
+-       * Entry has become invalid
+-       */
+-/*      dput(dentry);
+-*/
+-   }
+-
+-   DbgPrint("Novfs_d_revalidate: return 0x%x\n", retCode);
+-
+-   return(retCode);
+-}
+-
+-/*++======================================================================*/
+-unsigned long Novfs_internal_hash (struct qstr *name)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   unsigned long hash = 0;
+-   unsigned int len = name->len;
+-   unsigned char *c = (unsigned char *)name->name;
+-
+-   while(len--)
+-   {
+-      /*
+-       * Lower case values for the hash.
+-       */
+-      hash = partial_name_hash(tolower(*c++), hash);
+-   }
+-
+-   return(hash);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_d_hash (struct dentry *dentry, struct qstr *name)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   UNUSED_VARIABLE( dentry );
+-
+-   DbgPrint("Novfs_d_hash: %.*s\n", name->len, name->name);
+-
+-   name->hash = Novfs_internal_hash( name );
+-   
+-   return(0);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_d_strcmp (struct qstr *s1, struct qstr *s2)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   int retCode = 1;
+-   unsigned char *str1, *str2;
+-   unsigned int len;
+-
+-   DbgPrint("Novfs_d_strcmp: s1=%.*s s2=%.*s\n", s1->len, s1->name, s2->len, s2->name);
+-
+-   if (s1->len && (s1->len == s2->len) && (s1->hash == s2->hash) )
+-   {
+-      len = s1->len;
+-      str1 = (unsigned char *)s1->name;
+-      str2 = (unsigned char *)s2->name;
+-      for ( retCode = 0; len-- ; str1++, str2++ )
+-      {
+-         if (*str1 != *str2)
+-         {
+-            if (tolower(*str1) != tolower(*str2))
+-            {
+-               retCode = 1;
+-               break;
+-            }
+-         }
+-      }
+-   }
+-
+-   DbgPrint("Novfs_d_strcmp: retCode=0x%x\n", retCode);
+-   return(retCode);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_d_compare (struct dentry *parent, struct qstr *s1, struct qstr *s2)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   int retCode;
+-
+-   retCode = Novfs_d_strcmp(s1, s2);
+-
+-   DbgPrint("Novfs_d_compare: retCode=0x%x\n", retCode);
+-   return(retCode);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_d_delete(struct dentry *dentry)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   int retVal = 0;
+-
+-     DbgPrint("Novfs_d_delete: 0x%p %.*s\n" \
+-            "   d_count: %d\n" \
+-            "   d_inode: 0x%p\n",
+-      dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_count, dentry->d_inode);
+-
+-   if (dentry->d_inode && (dentry->d_inode->i_flags & S_DEAD))
+-   {
+-      retVal = 1;
+-   }
+-
+-   dentry->d_time = 0;
+-
+-   return( retVal );
+-}
+-
+-/*++======================================================================*/
+-void Novfs_d_release(struct dentry *dentry)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   DbgPrint("Novfs_d_release: 0x%x %.*s\n", dentry, dentry->d_name.len, dentry->d_name.name);
+-}
+-
+-/*++======================================================================*/
+-void Novfs_d_iput(struct dentry *dentry, struct inode *inode)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   DbgPrint("Novfs_d_iput: Inode=0x%x Ino=%d Dentry=0x%x Name=%.*s\n", 
+-      inode, inode->i_ino, dentry, dentry->d_name.len, dentry->d_name.name);
+-
+-   iput(inode);
+-
+-}
+-/*++======================================================================*/
+-int Novfs_dir_open(struct inode *dir, struct file *file)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   char *path, *buf;
+-   
+-
+-   DbgPrint("Novfs_dir_open: Inode 0x%x %d Name %.*s\n", dir, dir->i_ino, file->f_dentry->d_name.len, file->f_dentry->d_name.name);
+-
+-   buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+-   if (buf)
+-   {
+-      path = Novfs_dget_path(file->f_dentry, buf, PATH_LENGTH_BUFFER);
+-      if (path)
+-      {
+-         DbgPrint("Novfs_dir_open: path %s\n", path);
+-      }
+-      Novfs_Free(buf);
+-   }
+-   file->private_data = NULL;
+-   return(0);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_dir_release(struct inode *dir, struct file *file)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   struct inode *inode;
+-
+-   DbgPrint("Novfs_dir_release: Inode 0x%x %d Name %.*s\n", dir, dir->i_ino, file->f_dentry->d_name.len, file->f_dentry->d_name.name);
+-   if (file->private_data)
+-   {
+-      inode = file->private_data;
+-      Novfs_free_inode_cache( inode );
+-      Novfs_Free(file->private_data);
+-   }
+-
+-   return(0);
+-}
+-
+-/*++======================================================================*/
+-loff_t  Novfs_dir_lseek(struct file *file, loff_t offset, int origin)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   return(dcache_dir_lseek(file, offset, origin));
+-}
+-
+-/*++======================================================================*/
+-int Novfs_dir_read(struct file *file, char *buf, size_t len, loff_t *off)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-/*
+-   int rlen = 0;
+-
+-   DbgPrint("Novfs_dir_readdir: dentry path %.*s buf=0x%p len=%d off=%lld\n", file->f_dentry->d_name.len, file->f_dentry->d_name.name, buf, len, *off);
+-
+-   if (0 == *off)
+-   {
+-      rlen = 8;
+-      rlen -= copy_to_user(buf, "Testing\n", 8);
+-      *off += rlen;
+-   }
+-   return(rlen);
+-*/
+-   return(generic_read_dir(file, buf, len, off));
+-}
+-
+-/*++======================================================================*/
+-void process_list(struct file *File, char *List, int Type, PENTRY_INFO Info, session_t SessionId)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   unsigned char *path, *buf=NULL, *cp;
+-   struct inode *dir = File->f_dentry->d_inode;
+-   struct qstr name;
+-   ino_t ino=0;
+-
+-   buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+-   path = buf;
+-   if (buf)
+-   {
+-      path = Novfs_dget_path(File->f_dentry, buf, PATH_LENGTH_BUFFER);
+-      if (path)
+-      {
+-         strcpy(buf, path);
+-      }
+-      path = buf+strlen(buf);
+-      *path++ = '\\';
+-   }
+-
+-   if ( List )
+-   {
+-      cp = List;
+-      while (*cp)
+-      {
+-         name.name = cp;
+-         name.len  = strlen(cp);
+-         name.hash = Novfs_internal_hash( &name );
+-         cp += (name.len+1);
+-
+-         Info->mode = S_IFDIR | 0700;
+-         Info->size = 0;
+-         Info->atime = Info->ctime = Info->mtime = CURRENT_TIME;
+-
+-         if ( (USER_LIST != Type) && buf && ((int)(path-buf)+name.len < PATH_LENGTH_BUFFER) )
+-         {
+-            strcpy(path, name.name);
+-            Novfs_Get_File_Info(buf, Info, SessionId);
+-         }
+-
+-         if ( Novfs_update_entry( dir, &name, ino, Info ) )
+-         {
+-            Novfs_add_inode_entry(dir, &name, (ino_t)InterlockedIncrement(&Novfs_Inode_Number), Info);
+-         }
+-      }
+-   }
+-
+-   if (buf) Novfs_Free(buf);
+-
+-}
+-
+-/*++======================================================================*/
+-int Novfs_dir_readdir(struct file * file, void * dirent, filldir_t filldir)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   unsigned char *path, *buf=NULL;
+-   unsigned char *list=NULL;
+-   PENTRY_INFO info=NULL, pinfo, iinfo;
+-   int count;
+-
+-   int status = -ENOMEM;
+-   struct inode *inode;
+-   session_t sessionId;
+-   uid_t uid;
+-   struct qstr name;
+-   struct list_head *inter;
+-   ino_t ino;
+-   int iLock=0;
+-   int type = 0;
+-
+-   DbgPrint("Novfs_dir_readdir(%s): dentry path %.*s 0x%x\n", current->comm, file->f_dentry->d_name.len, file->f_dentry->d_name.name, file->f_dentry->d_fsdata);
+-
+-   inode = file->f_dentry->d_inode;
+-
+-   info = Novfs_Malloc(sizeof(ENTRY_INFO)+PATH_LENGTH_BUFFER, GFP_KERNEL);
+-   if (info)
+-   {
+-      if (file->f_pos)
+-      {
+-         if (file->private_data)
+-         {
+-            inode = file->private_data;
+-            while( !Novfs_get_remove_entry(inode, &ino, info) )
+-            {
+-               DbgPrint("Calling filedir-2 %llu with ino %d mode 0%o name %s\n", file->f_pos, ino, info->mode, info->name);
+-		         if ( filldir(dirent, info->name, info->namelength, file->f_pos, ino, info->mode >> 12) < 0 )
+-               {
+-                  /*
+-                   * put entry back on the list.
+-                   */
+-                  name.len  = info->namelength;
+-                  name.name = info->name;
+-                  name.hash = Novfs_internal_hash( &name );
+-                  Novfs_add_inode_entry(inode, &name, ino, info);
+-                  
+-                  break;
+-               }
+-		         file->f_pos++;
+-            }
+-         }
+-         Novfs_Free(info);
+-         return(0);
+-      }
+-
+-      if ( inode && inode->u.generic_ip )
+-      {
+-         sessionId = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
+-         if (0 == sessionId)
+-         {
+-            ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath(file->f_dentry);
+-            sessionId = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
+-         }
+-         uid = Scope_Get_Uid(((PINODE_DATA)inode->u.generic_ip)->Scope);
+-      }
+-      else
+-      {
+-         sessionId = 0;
+-         uid = current->euid;
+-      }
+-
+-      if ( IS_ROOT(file->f_dentry) ||  /* Root */
+-           IS_ROOT(file->f_dentry->d_parent) || /* User */
+-           IS_ROOT(file->f_dentry->d_parent->d_parent) ) /* Server */
+-      {
+-         if ( IS_ROOT(file->f_dentry) )
+-         {
+-            DbgPrint("Novfs_dir_readdir: Root directory\n");
+-            list = Scope_Get_ScopeUsers();
+-            type = USER_LIST;
+-         
+-         } else if ( IS_ROOT(file->f_dentry->d_parent) )
+-         {
+-            DbgPrint("Novfs_dir_readdir: Parent is Root directory\n");
+-            Novfs_Get_Connected_Server_List( &list, sessionId );
+-            type = SERVER_LIST;
+-         }
+-         else
+-         {
+-            DbgPrint("Novfs_dir_readdir: Parent-Parent is Root directory\n");
+-            Novfs_Get_Server_Volume_List(&file->f_dentry->d_name, &list, sessionId);
+-            type = VOLUME_LIST;
+-         }
+-
+-         iLock = Novfs_lock_inode_cache( inode );
+-         Novfs_invalidate_inode_cache( inode );
+-
+-         process_list(file, list, type, info, sessionId);
+-      }
+-      else
+-      {
+-         DbgPrint("Novfs_dir_readdir: Default directory\n");
+-         buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+-         if (buf)
+-         {
+-            path = Novfs_dget_path(file->f_dentry, buf, PATH_LENGTH_BUFFER);
+-            if (path)
+-            {
+-               unsigned long enumHandle=0;
+-
+-               iLock = Novfs_lock_inode_cache( inode );
+-               Novfs_invalidate_inode_cache(inode);
+-
+-               do
+-               {
+-                  /*
+-                   * Novfs_Get_Directory_List will return 0 when no error or -1 when
+-                   * the last entry is returned.  Otherwise it will return an error.
+-                   */
+-                  info->namelength = 0;
+-                  status = Novfs_Get_Directory_ListEx(path, &enumHandle, &count, &pinfo, sessionId);
+-                  DbgPrint("Novfs_dir_readdir: Novfs_Get_Directory_List return 0x%x count=%d pinfo=0x%p\n", status, count, pinfo);
+-                  iinfo = pinfo;
+-                  while ( (0 == status) && pinfo && count-- )
+-                  {
+-                     memcpy(info, pinfo, (int)((char *)&pinfo->name[pinfo->namelength]-(char *)pinfo));
+-                     pinfo = (PENTRY_INFO)&pinfo->name[pinfo->namelength];
+-                     name.len  = info->namelength;
+-                     name.name = info->name;
+-                     name.hash = Novfs_internal_hash(&name);
+-                     info->name[name.len] = '\0';
+-
+-                     DbgPrint("Novfs_dir_readdir: Got %s\n", name.name);
+-
+-                     if ( Novfs_update_entry( inode, &name, 0, info ))
+-                     {
+-                        Novfs_add_inode_entry(inode, &name, (ino_t)InterlockedIncrement(&Novfs_Inode_Number), info);
+-                     }
+-                  }
+-
+-                  if (iinfo)
+-                  {
+-                     Novfs_Free(iinfo);
+-                  }
+-         
+-               } while ( !status );
+-            }
+-         }
+-      }
+-
+-      if ( iLock )
+-      {
+-         Novfs_free_invalid_entries( inode );
+-      }
+-
+-	   switch ((int) file->f_pos) 
+-	   {
+-	      case 0:
+-            DbgPrint("Calling filedir %llu with ino %d name .\n", file->f_pos, inode->i_ino);
+-		      if (filldir(dirent, ".", 1, file->f_pos, inode->i_ino, DT_DIR) < 0) 
+-		      {
+-			      break;
+-		      }
+-		      file->f_pos++;
+-		      /* fallthrough */
+-	      case 1:
+-            DbgPrint("Calling filedir %llu with ino %d name ..\n", file->f_pos, parent_ino(file->f_dentry));
+-		      if (filldir(dirent, "..", 2, file->f_pos, parent_ino(file->f_dentry), DT_DIR) < 0) 
+-		      {
+-			      break;
+-		      }
+-		      file->f_pos++;
+-		      /* fallthrough */
+-
+-	      default:
+-            status = 0;
+-            inter = NULL;
+-
+-            if ( iLock )
+-            {
+-               while( !Novfs_enumerate_inode_cache(inode, &inter, &ino, info) )
+-               {
+-                  DbgPrint("Calling filedir %llu with ino %d mode 0%o name %s\n", file->f_pos, ino, info->mode, info->name);
+-		            if ( filldir(dirent, info->name, info->namelength, file->f_pos, ino, info->mode >> 12) < 0 )
+-                  {
+-                     /*
+-                      * Get the rest of the entries and put them in a fake
+-                      * inode cache.
+-                      */
+-                     file->private_data = (PDIR_CACHE)Novfs_Malloc(sizeof(struct inode) + sizeof(DIR_CACHE), GFP_KERNEL);
+-                     if (file->private_data)
+-                     {
+-                        struct inode *dinode = file->private_data;
+-                        PINODE_DATA id = (PINODE_DATA)((char *)file->private_data+sizeof(struct inode));
+-
+-                        dinode->u.generic_ip = id;
+-
+-                        id->Scope = ((PINODE_DATA)inode->u.generic_ip)->Scope;
+-                        id->Flags = 0;
+-                        INIT_LIST_HEAD( &id->DirCache );
+-                        init_MUTEX( &id->DirCacheLock );
+-
+-                        /*
+-                         * Copy rest of the files.
+-                         */
+-                        do
+-                        {
+-                           name.len  = info->namelength;
+-                           name.name = info->name;
+-                           name.hash = Novfs_internal_hash( &name );
+-                           Novfs_add_inode_entry(dinode, &name, ino, info);
+-                        } while( !Novfs_enumerate_inode_cache(inode, &inter, &ino, info) );
+-                     }
+-
+-			            break;
+-                  }
+-		            file->f_pos++;
+-               }
+-            }
+-
+-      }
+-
+-      if (iLock)
+-      {
+-         Novfs_unlock_inode_cache(inode);
+-      }
+-   }
+-
+-   if (info) Novfs_Free( info );
+-   if (buf)  Novfs_Free( buf );
+-   if (list) Novfs_Free( list );
+-
+-   return(status);
+-}
+-
+-
+-/*++======================================================================*/
+-int Novfs_dir_fsync(struct file * file, struct dentry *dentry, int datasync)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   return(simple_sync_file(file, dentry, datasync));
+-}
+-
+-/*++======================================================================*/
+-int do_open(struct file *file)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PENTRY_INFO info=NULL;
+-   int retCode = -ENOENT;
+-   session_t session;
+-   char *path;
+-   struct dentry *parent;
+-   struct inode *inode;
+-   PINODE_DATA id;
+-
+-   inode = file->f_dentry->d_inode;
+-
+-   if (inode && inode->u.generic_ip)
+-   {
+-      id = (PINODE_DATA)file->f_dentry->d_inode->u.generic_ip;
+-      session = Scope_Get_SessionId(id->Scope);
+-      if (0 == session)
+-      {
+-         id->Scope = Scope_Get_ScopefromPath( file->f_dentry );
+-         session = Scope_Get_SessionId(id->Scope);
+-      }
+-
+-      retCode = -ENOMEM;
+-      info = (PENTRY_INFO)Novfs_Malloc(sizeof(ENTRY_INFO) + PATH_LENGTH_BUFFER, GFP_KERNEL);
+-      if (info)
+-      {
+-         path = Novfs_dget_path(file->f_dentry, info->name, PATH_LENGTH_BUFFER);
+-         if (path)
+-         {
+-            DbgPrint("do_open: %s\n", path);
+-            
+-            retCode = Novfs_Open_File(
+-                        path, 
+-                        file->f_flags & ~O_EXCL, info, 
+-                        (unsigned long *)&file->private_data,
+-                        session);
+-            DbgPrint("do_open: 0x%x 0x%x\n", retCode, file->private_data);
+-            if ( !retCode )
+-            {
+-               if( !Novfs_Get_File_Info(path, info, session))
+-               {
+-                  update_inode(inode, info);
+-               }
+-
+-               parent = dget_parent(file->f_dentry);
+-
+-               if (parent && parent->d_inode)
+-               {
+-                  struct inode *dir = parent->d_inode;
+-                  Novfs_lock_inode_cache(dir);
+-                  if (Novfs_update_entry(dir, &file->f_dentry->d_name, 0, info))
+-                  {
+-                     Novfs_add_inode_entry(dir, &file->f_dentry->d_name, inode->i_ino, info);
+-                  }
+-
+-                  Novfs_unlock_inode_cache(dir);
+-               }
+-               dput(parent);
+-            }
+-         }
+-         Novfs_Free(info);
+-      }
+-   }
+-
+-   return(retCode);
+-}
+-
+-/*++======================================================================*/
+-ssize_t Novfs_f_read(struct file *file, char *buf, size_t len, loff_t *off)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   size_t thisread, totalread=0;
+-   loff_t offset = *off;
+-   struct inode *inode;
+-   session_t session;
+-   
+-   if (file->f_dentry && file->f_dentry->d_inode && file->f_dentry->d_inode->u.generic_ip)
+-   {
+-      DbgPrint("Novfs_f_read(0x%x 0x%p %d %lld %.*s)\n", (unsigned long)file->private_data, buf, len, offset, file->f_dentry->d_name.len, file->f_dentry->d_name.name);
+-
+-      if ( !file->private_data )
+-      {
+-         totalread = (size_t)do_open( file );
+-         if (totalread)
+-         {
+-            return(totalread);
+-         }
+-      }
+-
+-      inode = file->f_dentry->d_inode;
+-      
+-      session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
+-      if (0 == session)
+-      {
+-         ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( file->f_dentry );
+-         session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
+-      }
+-
+-      while(len > 0 && (offset < inode->i_size) )
+-      {
+-         thisread = len;
+-         if (Novfs_Read_File((unsigned long)file->private_data, buf, &thisread, &offset, 1, session) || !thisread)
+-         {
+-            break;
+-         }
+-         DbgPrint("Novfs_f_read thisread = 0x%x\n", thisread);
+-         len -= thisread;
+-         buf += thisread;
+-         offset += thisread;
+-         totalread += thisread;
+-      }
+-   }
+-   *off = offset;
+-   DbgPrint("Novfs_f_read return = 0x%x\n", totalread);
+-
+-   return(totalread);
+-}
+-
+-/*++======================================================================*/
+-ssize_t Novfs_f_write(struct file *file, const char *buf, size_t len, loff_t *off)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   size_t thiswrite, totalwrite=0;
+-   loff_t offset = *off;
+-   session_t session;
+-   struct inode *inode;
+-   int status;
+-
+-   if (file->f_dentry && file->f_dentry->d_inode && file->f_dentry->d_inode->u.generic_ip)
+-   {
+-      inode = file->f_dentry->d_inode;
+-
+-      if ( !file->private_data )
+-      {
+-         totalwrite = (size_t)do_open( file );
+-         if (totalwrite)
+-         {
+-            return(totalwrite);
+-         }
+-      }
+-
+-      DbgPrint("Novfs_f_write(0x%x %d %lld %.*s)\n", (unsigned long)file->private_data, len, offset, file->f_dentry->d_name.len, file->f_dentry->d_name.name);
+-
+-      if (file->f_flags & O_APPEND) {
+-         offset = inode->i_size;
+-         DbgPrint("Novfs_f_write appending to end %lld %.*s\n", offset, file->f_dentry->d_name.len, file->f_dentry->d_name.name);
+-      }
+-
+-
+-      session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
+-      if (0 == session)
+-      {
+-         ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( file->f_dentry );
+-         session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
+-      }
+-   
+-      while(len > 0)
+-      {
+-         thiswrite = len;
+-         if ((status = Novfs_Write_File(
+-               (unsigned long)file->private_data, 
+-               (unsigned char *)buf, 
+-               &thiswrite, 
+-               &offset, 
+-               session)) || !thiswrite)
+-         {
+-            totalwrite = status;
+-            break;
+-         }
+-         DbgPrint("Novfs_f_write thiswrite = 0x%x\n", thiswrite);
+-         len -= thiswrite;
+-         buf += thiswrite;
+-         offset += thiswrite;
+-         totalwrite += thiswrite;
+-         if (offset > inode->i_size)
+-         {
+-            inode->i_size = offset;
+-            inode->i_blocks = (offset + inode->i_blksize - 1) >> inode->i_blkbits;
+-         }
+-         inode->i_mtime = inode->i_atime = CURRENT_TIME;
+-         ((PINODE_DATA)inode->u.generic_ip)->Flags |= UPDATE_INODE;
+-
+-      }
+-   }
+-   *off = offset;
+-   DbgPrint("Novfs_f_write return = 0x%x\n", totalwrite);
+-
+-   return(totalwrite);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_f_readdir(struct file *file, void *data, filldir_t fill)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   UNUSED_VARIABLE(file);
+-   UNUSED_VARIABLE(data);
+-   UNUSED_VARIABLE(fill);
+-   return(-EISDIR);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_f_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   UNUSED_VARIABLE(inode);
+-   UNUSED_VARIABLE(file);
+-   UNUSED_VARIABLE(cmd);
+-   UNUSED_VARIABLE(arg);
+-   DbgPrint("Novfs_f_ioctl: file=0x%x cmd=0x%x arg=0x%x", file, cmd, arg);
+-
+-   return(-ENOSYS);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_f_mmap(struct file * file, struct vm_area_struct * vma)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   int retCode = -EINVAL;
+-
+-   DbgPrint("Novfs_f_mmap: file=0x%x", file);
+-
+-   retCode = generic_file_mmap(file, vma);
+-
+-   DbgPrint("Novfs_f_mmap: retCode=0x%x\n", retCode);
+-   return( retCode );
+-}
+-
+-/*++======================================================================*/
+-int Novfs_f_open2(struct inode *inode, struct file *file)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   int retCode;
+-
+-   DbgPrint("Novfs_f_open: inode=0x%p file=0x%p dentry=0x%p dentry->d_inode=0x%p\n", inode, file, file->f_dentry, file->f_dentry->d_inode);
+-   if (file->f_dentry)
+-   {
+-      DbgPrint("Novfs_f_open: %.*s f_flags=0%o f_mode=0%o i_mode=0%o\n", file->f_dentry->d_name.len, file->f_dentry->d_name.name, file->f_flags, file->f_mode, inode->i_mode);
+-   }
+-   retCode = do_open(file);
+-
+-   DbgPrint("Novfs_f_open: retCode=0x%x\n", retCode);
+-
+-   return( retCode );
+-}
+-
+-/*++======================================================================*/
+-int Novfs_f_open(struct inode *inode, struct file *file)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PENTRY_INFO info=NULL;
+-   int retCode = -ENOENT;
+-   session_t session;
+-   char *path;
+-   struct dentry *parent;
+-   PINODE_DATA id;
+-
+-   DbgPrint("Novfs_f_open: inode=0x%p file=0x%p dentry=0x%p dentry->d_inode=0x%p\n", inode, file, file->f_dentry, file->f_dentry->d_inode);
+-   if (file->f_dentry)
+-   {
+-      DbgPrint("Novfs_f_open: %.*s f_flags=0%o f_mode=0%o i_mode=0%o\n", file->f_dentry->d_name.len, file->f_dentry->d_name.name, file->f_flags, file->f_mode, inode->i_mode);
+-   }
+-
+-   if (inode && inode->u.generic_ip)
+-   {
+-      id = (PINODE_DATA)file->f_dentry->d_inode->u.generic_ip;
+-      session = Scope_Get_SessionId(id->Scope);
+-      if (0 == session)
+-      {
+-         id->Scope = Scope_Get_ScopefromPath( file->f_dentry );
+-         session = Scope_Get_SessionId(id->Scope);
+-      }
+-
+-      info = (PENTRY_INFO)Novfs_Malloc(sizeof(ENTRY_INFO) + PATH_LENGTH_BUFFER, GFP_KERNEL);
+-      if (info)
+-      {
+-         path = Novfs_dget_path(file->f_dentry, info->name, PATH_LENGTH_BUFFER);
+-         if (path)
+-         {
+-            DbgPrint("Novfs_f_open: %s\n", path);
+-
+-
+-            retCode = Novfs_Get_File_Info(path, info, session);
+-            if ( !retCode )
+-            {
+-               if ( (O_TRUNC & file->f_flags) && S_ISREG(info->mode) && info->size ) 
+-               {
+-                  if (!Novfs_Truncate_File(path, strlen(path), session))
+-                  {
+-                     info->size = 0;
+-                  }
+-               }
+-
+-               /*
+-                * Update inode info.
+-                */
+-               update_inode(inode, info);
+-
+-               file->private_data = NULL;
+-               
+-               parent = dget_parent(file->f_dentry);
+-
+-               if (parent && parent->d_inode)
+-               {
+-                  struct inode *dir = parent->d_inode;
+-                  Novfs_lock_inode_cache(dir);
+-                  if (Novfs_update_entry(dir, &file->f_dentry->d_name, 0, info))
+-                  {
+-                     Novfs_add_inode_entry(dir, &file->f_dentry->d_name, inode->i_ino, info);
+-                  }
+-
+-                  Novfs_unlock_inode_cache(dir);
+-               }
+-               dput(parent);
+-
+-               if ( S_ISDIR(info->mode) )
+-               {
+-                  retCode = -EISDIR;
+-               }
+-            }
+-            else
+-            {
+-               if ( O_CREAT & file->f_flags )
+-               {
+-                  retCode = do_open(file);
+-                  if (file->private_data)
+-                  {
+-                     Novfs_f_release(file->f_dentry->d_inode, file);
+-                     file->private_data = NULL;
+-                  }
+-               }
+-            }
+-         }
+-         Novfs_Free(info);
+-      }
+-   }
+-   DbgPrint("Novfs_f_open: retCode=0x%x\n", retCode);
+-   return( retCode );
+-}
+-
+-/*++======================================================================*/
+-int Novfs_f_flush(struct file *file)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   struct inode *inode;
+-
+-   UNUSED_VARIABLE(file);
+-   if (file->f_dentry)
+-   {
+-      inode = file->f_dentry->d_inode;
+-      DbgPrint("Novfs_f_flush: %.*s f_flags=0x%x f_mode=0%o i_mode=0%o\n", file->f_dentry->d_name.len, file->f_dentry->d_name.name, file->f_flags, file->f_mode, inode->i_mode);
+-   }
+-   return(0);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_f_release(struct inode *inode, struct file *file)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   int retCode = -EACCES;
+-   session_t session;
+-   PINODE_DATA id;
+-  
+-   DbgPrint("Novfs_f_release: path=%.*s handle=0x%x inode=0x%p\n", 
+-      file->f_dentry->d_name.len, 
+-      file->f_dentry->d_name.name, 
+-      (unsigned long)file->private_data, file->f_dentry->d_inode);
+-
+-   if ( file->f_dentry->d_inode && (id = file->f_dentry->d_inode->u.generic_ip))
+-   {
+-      if (file->private_data)
+-      {
+-         session = Scope_Get_SessionId(id->Scope);
+-         if (0 == session)
+-         {
+-            id->Scope = Scope_Get_ScopefromPath( file->f_dentry );
+-            session = Scope_Get_SessionId(id->Scope);
+-         }
+-
+-		   //invalidate_remote_inode(file->f_dentry->d_inode);
+-
+-         retCode = Novfs_Close_File((unsigned long)file->private_data, session);
+-         file->private_data = NULL;
+-      }
+-      else
+-      {
+-         retCode = 0;
+-      }
+-   }
+-   return(retCode);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_f_fsync(struct file *file, struct dentry *dentry, int datasync)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   UNUSED_VARIABLE(file);
+-   UNUSED_VARIABLE(dentry);
+-   UNUSED_VARIABLE(datasync);
+-   return(0);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_f_llseek(struct file *file, loff_t offset, int origin)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   DbgPrint("Novfs_f_llseek: File=0x%x Name=%.*s offset=%lld origin=%d\n", file, file->f_dentry->d_name.len, file->f_dentry->d_name.name, offset, origin);
+-   return(generic_file_llseek(file, offset, origin));
+-}
+-
+-/*++======================================================================*/
+-int Novfs_f_lock(struct file *file, int cmd, struct file_lock *lock)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   UNUSED_VARIABLE(file);
+-   UNUSED_VARIABLE(cmd);
+-   UNUSED_VARIABLE(lock);
+-   return(-ENOSYS);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_a_readpage(struct file *file, struct page *page)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   int retCode = 0;
+-   void *pbuf;
+-   struct inode *inode=NULL;
+-   struct dentry *dentry=NULL;
+-   loff_t offset;
+-   size_t len;
+-   session_t session=0;
+-
+-   DbgPrint("Novfs_a_readpage: File=0x%x Name=%.*s Page=0x%x", file, file->f_dentry->d_name.len, file->f_dentry->d_name.name, page);
+-
+-   dentry = file->f_dentry;
+-
+-   if (dentry)
+-   {
+-      DbgPrint(" Dentry=0x%x Name=%.*s", dentry, dentry->d_name.len, dentry->d_name.name);
+-      if (dentry->d_inode)
+-      {
+-         inode = dentry->d_inode;
+-      }
+-   }
+-
+-
+-
+-   if (inode)
+-   {
+-      DbgPrint(" Inode=0x%x Ino=%d", inode, inode->i_ino);
+-
+-      if (inode->u.generic_ip)
+-      {
+-         session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
+-         if (0 == session)
+-         {
+-            ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( file->f_dentry );
+-            session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
+-         }
+-      }
+-   }
+-
+-   DbgPrint("\n");
+-
+-   if ( !file->private_data )
+-   {
+-      retCode = (size_t)do_open( file );
+-   }
+-
+-   if (file->private_data && !PageUptodate(page)) 
+-   {
+-      pbuf = kmap(page);
+-
+-      offset = page->index << PAGE_CACHE_SHIFT;
+-      len = PAGE_CACHE_SIZE;
+-
+-      retCode = Novfs_Read_File((unsigned long)file->private_data, pbuf, &len, &offset, 0, session);
+-      if ( len && (len < PAGE_CACHE_SIZE) ) 
+-      {
+-         memset(&((char *)pbuf)[len], 0, PAGE_CACHE_SIZE-len);
+-      }
+-   
+-      kunmap(page);
+-      flush_dcache_page(page);
+-      SetPageUptodate(page);
+-   }
+-   unlock_page(page);
+-
+-   DbgPrint("Novfs_a_readpage: retCode=%d\n", retCode);
+-   return (retCode);
+-
+-}
+-
+-/*++======================================================================*/
+-int Novfs_i_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   char *path, *buf;
+-   ENTRY_INFO info;
+-   unsigned long handle;
+-   session_t session;
+-   int retCode = -EACCES;
+-
+-
+-   DbgPrint("Novfs_i_create: mode=0%o flags=0%o %.*s\n", mode, nd->NDOPENFLAGS, dentry->d_name.len, dentry->d_name.name);
+-
+-   if ( IS_ROOT(dentry) || /* Root */
+-        IS_ROOT(dentry->d_parent) || /* User */
+-        IS_ROOT(dentry->d_parent->d_parent) || /* Server */
+-        IS_ROOT(dentry->d_parent->d_parent->d_parent) ) /* Volume */
+-   {
+-      return(-EACCES);
+-   }
+-
+-   if (mode | S_IFREG)
+-   {
+-      if (dir->u.generic_ip)
+-      {
+-         session = Scope_Get_SessionId( ((PINODE_DATA)dir->u.generic_ip)->Scope);
+-         if (0 == session)
+-         {
+-            ((PINODE_DATA)dir->u.generic_ip)->Scope = Scope_Get_ScopefromPath( dentry );
+-            session = Scope_Get_SessionId(((PINODE_DATA)dir->u.generic_ip)->Scope);
+-         }
+-
+-         buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+-         if (buf)
+-         {
+-            path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER);
+-            if (path)
+-            {
+-               retCode = Novfs_Open_File(path, nd->NDOPENFLAGS|O_RDWR, &info, &handle, session);
+-               if ( !retCode && handle )
+-               {
+-                  Novfs_Close_File(handle, session);
+-                  if (!Novfs_i_mknod(dir, dentry, mode | S_IFREG, 0))
+-                  {
+-                     if (dentry->d_inode)
+-                     {
+-                        ((PINODE_DATA)dentry->d_inode->u.generic_ip)->Flags |= UPDATE_INODE;
+-                     }
+-                  }
+-               }
+-            }
+-            Novfs_Free(buf);
+-         }
+-      }
+-   }
+-   return( retCode );
+-}
+-
+-/*++======================================================================*/
+-void update_inode(struct inode *Inode, PENTRY_INFO Info)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   static char dbuf[128];
+-
+-   DbgPrint("update_inode: Inode=0x%x I_ino=%d\n", Inode, Inode->i_ino);
+-
+-   DbgPrint("update_inode: atime=%s\n", ctime_r(&Info->atime.tv_sec, dbuf));
+-   DbgPrint("update_inode: ctime=%s\n", ctime_r(&Info->ctime.tv_sec, dbuf));
+-   DbgPrint("update_inode: mtime=%s\n", ctime_r(&Info->mtime.tv_sec, dbuf));
+-   DbgPrint("update_inode: size=%lld\n", Info->size);
+-   DbgPrint("update_inode: mode=0%o\n", Info->mode);
+-
+-   Inode->i_mode  = Info->mode;
+-   Inode->i_size  = Info->size;
+-   Inode->i_atime = Info->atime;
+-   Inode->i_ctime = Info->ctime;
+-   Inode->i_mtime = Info->mtime;
+-   Inode->i_blocks = (u_long)(Info->size >> (loff_t)Inode->i_blkbits);
+-   Inode->i_bytes = Info->size & (Inode->i_blksize - 1);
+-
+-   DbgPrint("update_inode: i_blksize=%d\n", Inode->i_blksize);
+-   DbgPrint("update_inode: i_blkbits=%d\n", Inode->i_blkbits);
+-   DbgPrint("update_inode: i_blocks=%d\n", Inode->i_blocks);
+-   DbgPrint("update_inode: i_bytes=%d\n", Inode->i_bytes);
+-}
+-
+-/*++======================================================================*/
+-struct dentry * Novfs_i_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   struct dentry *retVal = ERR_PTR(-ENOENT);
+-   struct dentry *parent;
+-   PENTRY_INFO info=NULL;
+-   PINODE_DATA id;
+-   struct inode *inode=NULL;
+-   uid_t uid=current->euid;
+-   ino_t ino=0;
+-   struct qstr name;
+-
+-   DbgPrint("Novfs_i_lookup: dir 0x%x %d name %.*s hash %d inode 0x%0p\n", dir, dir->i_ino, dentry->d_name.len, dentry->d_name.name, dentry->d_name.hash, dentry->d_inode);
+-
+-   if (dir && (id = dir->u.generic_ip) )
+-   {
+-      retVal = 0;
+-      if ( IS_ROOT( dentry ))
+-      {
+-         DbgPrint("Novfs_i_lookup: Root entry=0x%x\n", Novfs_root);
+-         inode = Novfs_root->d_inode;
+-         return(0);
+-      }
+-      else
+-      {
+-         info = Novfs_Malloc(sizeof(ENTRY_INFO)+PATH_LENGTH_BUFFER, GFP_KERNEL);
+-         if (info)
+-         {
+-            if ( NULL == (retVal = ERR_PTR(verify_dentry( dentry, 1 ))))
+-            {
+-               name.name = dentry->d_name.name;
+-               name.len  = dentry->d_name.len;
+-               name.hash = Novfs_internal_hash(&name);
+-         
+-               if (Novfs_lock_inode_cache( dir ))
+-               {
+-                  if ( !Novfs_get_entry(dir, &name, &ino, info) )
+-                  {
+-                     inode = ilookup(dentry->d_sb, ino);
+-                     if ( inode )
+-                     {
+-                        update_inode(inode, info);
+-                     }
+-                  }
+-                  Novfs_unlock_inode_cache( dir );
+-               }
+-
+-               if ( !inode && ino )
+-               {
+-                  uid = Scope_Get_Uid( id->Scope );
+-                  if (Novfs_lock_inode_cache( dir ))
+-                  {
+-                     inode = Novfs_get_inode(dentry->d_sb, info->mode, 0, uid, ino, &name);
+-                     if ( inode )
+-                     {
+-                        if ( !Novfs_get_entry(dir, &dentry->d_name, &ino, info) )
+-                        {
+-                           update_inode(inode, info);
+-                        }
+-                     }
+-                     Novfs_unlock_inode_cache( dir );
+-                  }
+-               }
+-            }
+-         }
+-      }
+-   }
+-
+-   if ( !retVal )
+-   {
+-      dentry->d_op = &Novfs_dentry_operations;
+-      if (inode)
+-      {
+-         parent = dget_parent(dentry);
+-         Novfs_d_add(dentry->d_parent, dentry, inode, 1);
+-         dput(parent);
+-      }
+-      else
+-      {
+-         d_add( dentry, inode);
+-      }
+-   }
+-
+-   if (info) Novfs_Free(info);
+-
+-   DbgPrint("Novfs_i_lookup: inode=0x%x dentry->d_inode=0x%x return=0x%x\n", dir, dentry->d_inode, retVal);
+-
+-   return(retVal);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_i_unlink(struct inode *dir, struct dentry *dentry)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   int retCode = -ENOENT;
+-   struct inode *inode;
+-   session_t session;
+-   char *path, *buf;
+-   uint64_t t64;
+-
+-   DbgPrint("Novfs_i_unlink: dir=0x%x dir->i_ino=%d %.*s\n", dir, dir->i_ino, dentry->d_name.len, dentry->d_name.name);
+-   DbgPrint("Novfs_i_unlink: IS_ROOT(dentry)=%d\n", IS_ROOT(dentry));
+-   DbgPrint("Novfs_i_unlink: IS_ROOT(dentry->d_parent)=%d\n", IS_ROOT(dentry->d_parent));
+-   DbgPrint("Novfs_i_unlink: IS_ROOT(dentry->d_parent->d_parent)=%d\n", IS_ROOT(dentry->d_parent->d_parent));
+-   DbgPrint("Novfs_i_unlink: IS_ROOT(dentry->d_parent->d_parent->d_parent)=%d\n", IS_ROOT(dentry->d_parent->d_parent->d_parent) );
+-
+-   if ( IS_ROOT(dentry) || /* Root */
+-        IS_ROOT(dentry->d_parent) || /* User */
+-        (!IS_ROOT(dentry->d_parent->d_parent) && /* Server */
+-        IS_ROOT(dentry->d_parent->d_parent->d_parent)) ) /* Volume */
+-   {
+-      return(-EACCES);
+-   }
+-
+-   inode = dentry->d_inode;
+-   if ( inode )
+-   {
+-      DbgPrint("Novfs_i_unlink: dir=0x%x dir->i_ino=%d inode=0x%x ino=%d\n", dir, dir->i_ino, inode, inode->i_ino);
+-      if (inode->u.generic_ip)
+-      {
+-         session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
+-         if (0 == session)
+-         {
+-            ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( dentry );
+-            session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
+-         }
+-
+-         buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+-         if (buf)
+-         {
+-            path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER);
+-            if (path)
+-            {
+-               DbgPrint("Novfs_i_unlink: path %s mode 0%o\n", path, inode->i_mode);
+-               if (IS_ROOT(dentry->d_parent->d_parent))
+-               {
+-                  retCode = do_logout(&dentry->d_name);
+-               }
+-               else
+-               {
+-                  retCode = Novfs_Delete(path, S_ISDIR(inode->i_mode), session);
+-               }
+-               if ( !retCode || IS_DEADDIR(inode))
+-               {
+-                  Novfs_remove_inode_entry(dir, &dentry->d_name, 0);
+-                  dentry->d_time = 0;
+-                  t64 = 0;
+-                  Scope_Set_UserSpace(&t64, &t64, &t64, &t64);
+-                  retCode = 0;
+-               }
+-            }
+-            Novfs_Free(buf);
+-         }
+-      }
+-   }
+-
+-   DbgPrint("Novfs_i_unlink: retCode 0x%x\n", retCode);
+-   return (retCode);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_i_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   char *path, *buf;
+-   session_t session;
+-   int retCode=0;
+-   struct inode *inode;
+-   ENTRY_INFO info;
+-   uid_t uid;
+-
+-   DbgPrint("Novfs_i_mkdir: dir=0x%p ino=%d dentry=0x%p %.*s mode=0%o\n", dir, dir->i_ino, dentry, dentry->d_name.len, dentry->d_name.name, mode);
+-
+-   if ( IS_ROOT(dentry) || /* Root */
+-        IS_ROOT(dentry->d_parent) || /* User */
+-        IS_ROOT(dentry->d_parent->d_parent) || /* Server */
+-        IS_ROOT(dentry->d_parent->d_parent->d_parent) ) /* Volume */
+-   {
+-      return(-EACCES);
+-   }
+-
+-   mode |= S_IFDIR;
+-   mode &= (S_IFMT | S_IRWXU);
+-   if ( dir->u.generic_ip )
+-   {
+-      session = Scope_Get_SessionId( ((PINODE_DATA)dir->u.generic_ip)->Scope);
+-      if (0 == session)
+-      {
+-         ((PINODE_DATA)dir->u.generic_ip)->Scope = Scope_Get_ScopefromPath( dentry );
+-         session = Scope_Get_SessionId(((PINODE_DATA)dir->u.generic_ip)->Scope);
+-      }
+-
+-      uid = Scope_Get_Uid( ((PINODE_DATA)dir->u.generic_ip)->Scope);
+-      buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+-      if (buf)
+-      {
+-         path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER);
+-         if (path)
+-         {
+-            DbgPrint("Novfs_i_mkdir: path %s\n", path);
+-            retCode = Novfs_Create(path, S_ISDIR(mode), session);
+-            if ( !retCode )
+-            {
+-                  retCode = Novfs_Get_File_Info(path, &info, session );
+-                  if ( !retCode )
+-                  {
+-                     retCode = Novfs_i_mknod(dir, dentry, mode, 0);
+-                     inode = dentry->d_inode;
+-                     if (inode)
+-                     {
+-                        update_inode(inode, &info);
+-                        ((PINODE_DATA)inode->u.generic_ip)->Flags &= ~UPDATE_INODE;
+-
+-                        dentry->d_time = jiffies+(File_update_timeout*HZ);
+-
+-                        Novfs_lock_inode_cache(dir);
+-                        if (Novfs_update_entry( dir, &dentry->d_name, 0, &info ))
+-                        {
+-                           Novfs_add_inode_entry(dir, &dentry->d_name, inode->i_ino, &info);
+-                        }
+-                        Novfs_unlock_inode_cache(dir);
+-                     }
+-
+-                  }
+-               }
+-         }
+-         Novfs_Free(buf);
+-      }
+-   }
+-
+-   return( retCode );
+-}
+-
+-/*++======================================================================*/
+-int Novfs_i_rmdir(struct inode *inode, struct dentry *dentry)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   return(Novfs_i_unlink(inode, dentry));
+-}
+-
+-/*++======================================================================*/
+-int Novfs_i_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   struct inode *inode=NULL;
+-   int retCode = -EACCES;
+-   uid_t uid;
+-   struct dentry *parent;
+-
+-   if ( IS_ROOT(dentry) || /* Root */
+-        IS_ROOT(dentry->d_parent) || /* User */
+-        IS_ROOT(dentry->d_parent->d_parent) || /* Server */
+-        IS_ROOT(dentry->d_parent->d_parent->d_parent) ) /* Volume */
+-   {
+-      return(-EACCES);
+-   }
+-
+-   if ( ((PINODE_DATA)dir->u.generic_ip) )
+-   {
+-      uid = Scope_Get_Uid( ((PINODE_DATA)dir->u.generic_ip)->Scope);
+-      if (mode & (S_IFREG | S_IFDIR))
+-      {
+-         inode = Novfs_get_inode(dir->i_sb, mode, dev, uid, 0, &dentry->d_name);
+-      }
+-   }
+-
+-   if (inode) 
+-   {
+-      ENTRY_INFO info;
+-
+-      dentry->d_op = &Novfs_dentry_operations;
+-      parent = dget_parent(dentry);
+-      Novfs_d_add(parent, dentry, inode, 0);
+-      memset(&info, 0, sizeof(info));
+-      info.mode = inode->i_mode;
+-      Novfs_lock_inode_cache( dir );
+-      Novfs_add_inode_entry( dir, &dentry->d_name, inode->i_ino, &info);
+-      Novfs_unlock_inode_cache( dir );
+-
+-      dput(parent);
+-      
+-      retCode = 0;
+-   }
+-   DbgPrint("Novfs_i_mknod: return 0x%x\n", retCode);
+-   return retCode;
+-}
+-
+-/*++======================================================================*/
+-int Novfs_i_rename(struct inode *odir, struct dentry *od, struct inode *ndir, struct dentry *nd)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   int retCode = -ENOTEMPTY;
+-   char *newpath, *newbuf, *newcon;
+-   char *oldpath, *oldbuf, *oldcon;
+-   struct qstr newname, oldname;
+-   PENTRY_INFO info=NULL;
+-   int oldlen, newlen;
+-   session_t session;
+-   ino_t ino;
+-
+-
+-   if ( IS_ROOT(od) || /* Root */
+-        IS_ROOT(od->d_parent) || /* User */
+-        IS_ROOT(od->d_parent->d_parent) || /* Server */
+-        IS_ROOT(od->d_parent->d_parent->d_parent) ) /* Volume */
+-   {
+-      return(-EACCES);
+-   }
+-
+-   DbgPrint("Novfs_i_rename: odir=0x%p ino=%d ndir=0x%p ino=%d\n", odir, odir->i_ino, ndir, ndir->i_ino);
+-
+-   oldbuf = Novfs_Malloc(PATH_LENGTH_BUFFER*2, GFP_KERNEL);
+-   newbuf = oldbuf+PATH_LENGTH_BUFFER;
+-   if ( oldbuf && newbuf )
+-   {
+-      oldpath = Novfs_dget_path(od, oldbuf, PATH_LENGTH_BUFFER);
+-      newpath = Novfs_dget_path(nd, newbuf, PATH_LENGTH_BUFFER);
+-      if (oldpath && newpath)
+-      {
+-         oldlen = PATH_LENGTH_BUFFER-(int)(oldpath-oldbuf);
+-         newlen = PATH_LENGTH_BUFFER-(int)(newpath-newbuf);
+-
+-         DbgPrint("Novfs_i_rename: odir=0x%x od->inode=0x%x\n", odir, od->d_inode);
+-         DbgPrint("Novfs_i_rename: old path %s\n", oldpath);
+-         DbgPrint("Novfs_i_rename: new path %s\n", newpath);
+-
+-         /*
+-          * Check to see if two different servers or different volumes
+-          */
+-         newcon = strchr(newpath+1, '\\');
+-         oldcon = strchr(oldpath+1, '\\');
+-         DbgPrint("Novfs_i_rename: newcon=0x%x newpath=0x%x\n", newcon, newpath);
+-         DbgPrint("Novfs_i_rename: oldcon=0x%x oldpath=0x%x\n", oldcon, oldpath);
+-         retCode = -EXDEV;
+-         if ( newcon && oldcon && ((int)(newcon-newpath) == (int)(oldcon-oldpath)) )
+-         {
+-            newcon = strchr(newcon+1, '\\');
+-            oldcon = strchr(oldcon+1, '\\');
+-            DbgPrint("Novfs_i_rename2: newcon=0x%x newpath=0x%x\n", newcon, newpath);
+-            DbgPrint("Novfs_i_rename2: oldcon=0x%x oldpath=0x%x\n", oldcon, oldpath);
+-            if ( newcon && oldcon && ((int)(newcon-newpath) == (int)(oldcon-oldpath)) )
+-            {
+-               newname.name = newpath;
+-               newname.len = (int)(newcon-newpath);
+-               newname.hash = 0;
+-
+-               oldname.name = oldpath;
+-               oldname.len = (int)(oldcon-oldpath);
+-               oldname.hash = 0;
+-               if ( !Novfs_d_strcmp(&newname, &oldname))
+-               {
+-
+-                  if ( od->d_inode && od->d_inode->u.generic_ip )
+-                  {
+-
+-                     if (nd->d_inode && nd->d_inode->u.generic_ip)
+-                     {
+-                        session = Scope_Get_SessionId(((PINODE_DATA)ndir->u.generic_ip)->Scope);
+-                        if (0 == session)
+-                        {
+-                           ((PINODE_DATA)ndir->u.generic_ip)->Scope = Scope_Get_ScopefromPath( nd );
+-                           session = Scope_Get_SessionId(((PINODE_DATA)ndir->u.generic_ip)->Scope);
+-                        }
+-
+-                        retCode = Novfs_Delete(newpath, S_ISDIR(nd->d_inode->i_mode), session);
+-                     }
+-
+-
+-                     session = Scope_Get_SessionId(((PINODE_DATA)ndir->u.generic_ip)->Scope);
+-                     if (0 == session)
+-                     {
+-                        ((PINODE_DATA)ndir->u.generic_ip)->Scope = Scope_Get_ScopefromPath( nd );
+-                        session = Scope_Get_SessionId(((PINODE_DATA)ndir->u.generic_ip)->Scope);
+-                     }
+-                     retCode = Novfs_Rename_File(
+-                                 S_ISDIR(od->d_inode->i_mode),
+-                                 oldpath,
+-                                 oldlen-1,
+-                                 newpath,
+-                                 newlen-1, 
+-                                 session);
+-
+-                     if ( !retCode )
+-                     {
+-                        info = (PENTRY_INFO)oldbuf;
+-                        od->d_time = 0;
+-                        Novfs_remove_inode_entry(odir, &od->d_name, 0);
+-                        Novfs_Get_File_Info(newpath, info, session);
+-                        nd->d_time = jiffies+(File_update_timeout*HZ);
+-                        if (Novfs_update_entry(ndir, &nd->d_name, 0, info))
+-                        {
+-                           if (nd->d_inode && nd->d_inode->i_ino)
+-                           {
+-                              ino = nd->d_inode->i_ino;
+-                           }
+-                           else
+-                           {
+-                              ino = (ino_t)InterlockedIncrement(&Novfs_Inode_Number);
+-                           }
+-                           Novfs_add_inode_entry(ndir, &nd->d_name, ino, info);
+-                        }
+-                     }
+-                  }
+-               }
+-            }
+-         }
+-      }
+-   }
+-
+-   if (oldbuf) Novfs_Free(oldbuf);
+-
+-   return( retCode );
+-}
+-
+-/*++======================================================================*/
+-int Novfs_i_permission(struct inode *inode, int mask)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   int retCode=0;
+-
+-   return(retCode);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_i_setattr(struct dentry *dentry, struct iattr *attr)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   char *path, *buf;
+-   struct inode *inode=dentry->d_inode;
+-   char atime_buf[32];
+-   char mtime_buf[32];
+-   char ctime_buf[32];
+-   unsigned int ia_valid = attr->ia_valid;
+-   session_t session;
+-   int retVal = 0;
+-
+-   if ( IS_ROOT(dentry) || /* Root */
+-        IS_ROOT(dentry->d_parent) || /* User */
+-        IS_ROOT(dentry->d_parent->d_parent) || /* Server */
+-        IS_ROOT(dentry->d_parent->d_parent->d_parent) ) /* Volume */
+-   {
+-      return(-EACCES);
+-   }
+-
+-   if (inode && inode->u.generic_ip)
+-   {
+-      session = Scope_Get_SessionId( ((PINODE_DATA)inode->u.generic_ip)->Scope);
+-      if (0 == session)
+-      {
+-         ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( dentry );
+-         session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
+-      }
+-
+-      buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+-      if (buf)
+-      {
+-         path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER);
+-         if (path)
+-         {
+-            strcpy(atime_buf, "Unspecified");
+-            strcpy(mtime_buf, "Unspecified");
+-            strcpy(ctime_buf, "Unspecified");
+-            if (attr->ia_valid & ATTR_ATIME)
+-            {
+-               ctime_r(&attr->ia_atime.tv_sec, atime_buf);
+-            }
+-            if (attr->ia_valid & ATTR_MTIME)
+-            {
+-               ctime_r(&attr->ia_mtime.tv_sec, mtime_buf);
+-            }
+-            if (attr->ia_valid & ATTR_CTIME)
+-            {
+-               ctime_r(&attr->ia_ctime.tv_sec, ctime_buf);
+-            }
+-            DbgPrint("Novfs_i_setattr: %s\n" \
+-                     "   ia_valid:      0x%x\n" \
+-                     "   ia_mode:       0%o\n" \
+-                     "   ia_uid:        %d\n" \
+-                     "   ia_gid:        %d\n" \
+-                     "   ia_size:       %lld\n" \
+-                     "   ia_atime:      %s\n" \
+-                     "   ia_mtime:      %s\n" \
+-                     "   ia_ctime:      %s\n",
+-               path,
+-               attr->ia_valid,
+-               attr->ia_mode,
+-               attr->ia_uid,
+-               attr->ia_gid,
+-               attr->ia_size,
+-               atime_buf,
+-               mtime_buf,
+-               ctime_buf);
+-            
+-            if ( !(retVal = Novfs_Set_Attr(path, attr, session) ) )
+-            {
+-               ((PINODE_DATA)inode->u.generic_ip)->Flags |= UPDATE_INODE;
+-
+-               if (ia_valid & ATTR_SIZE)
+-               {
+-                  inode->i_size = attr->ia_size;
+-                  inode->i_blocks = (u_long)(inode->i_size >> (loff_t)inode->i_blkbits);
+-                  inode->i_bytes = inode->i_size & (inode->i_blksize - 1);
+-
+-               }
+-               if (ia_valid & ATTR_ATIME)
+-                  inode->i_atime = attr->ia_atime;
+-               if (ia_valid & ATTR_MTIME)
+-                  inode->i_mtime = attr->ia_mtime;
+-               if (ia_valid & ATTR_CTIME)
+-                  inode->i_ctime = attr->ia_ctime;
+-               if (ia_valid & ATTR_MODE) {
+-                  inode->i_mode = attr->ia_mode & (S_IFMT | S_IRWXU);
+-               }
+-            }
+-         }
+-      }
+-      Novfs_Free(buf);
+-   }
+-
+-   return(retVal);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_i_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *kstat)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   int retCode = 0;
+-   char atime_buf[32];
+-   char mtime_buf[32];
+-   char ctime_buf[32];
+-   struct inode *inode = dentry->d_inode;
+-
+-   ENTRY_INFO info;
+-   char *path, *buf;
+-   session_t session;
+-   PINODE_DATA id;
+-
+-   if ( !IS_ROOT(dentry) &&
+-        !IS_ROOT(dentry->d_parent) )
+-   {
+-      session = 0;
+-      id = dentry->d_inode->u.generic_ip;
+-
+-      if (id && (id->Flags & UPDATE_INODE) )
+-      {
+-         session = Scope_Get_SessionId( id->Scope );
+-
+-         if (0 == session)
+-         {
+-            id->Scope = Scope_Get_ScopefromPath( dentry );
+-            session = Scope_Get_SessionId(id->Scope);
+-         }
+-
+-         buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+-         if (buf)
+-         {
+-            path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER);
+-            if (path)
+-            {
+-               retCode = Novfs_Get_File_Info(path, &info, session );
+-               if ( !retCode )
+-               {
+-                  update_inode(inode, &info);
+-                  id->Flags &= ~UPDATE_INODE;
+-               }
+-            }
+-            Novfs_Free(buf);
+-         }
+-      }
+-   }
+-
+-   kstat->ino     = inode->i_ino;
+-   kstat->dev     = inode->i_sb->s_dev;
+-   kstat->mode    = inode->i_mode;
+-   kstat->nlink   = inode->i_nlink;
+-   kstat->uid     = inode->i_uid;
+-   kstat->gid     = inode->i_gid;
+-   kstat->rdev    = inode->i_rdev;
+-   kstat->size    = i_size_read(inode);
+-   kstat->atime   = inode->i_atime;
+-   kstat->mtime   = inode->i_mtime;
+-   kstat->ctime   = inode->i_ctime;
+-   kstat->blksize = inode->i_blksize;
+-   kstat->blocks  = inode->i_blocks;
+-   if (inode->i_bytes)
+-   {
+-   	kstat->blocks++;
+-   }
+-   ctime_r(&kstat->atime.tv_sec, atime_buf);
+-   ctime_r(&kstat->mtime.tv_sec, mtime_buf);
+-   ctime_r(&kstat->ctime.tv_sec, ctime_buf);
+-
+-
+-   DbgPrint("Novfs_i_getattr: 0x%x <%.*s>\n" \
+-            "   ino: %d\n" \
+-            "   dev: 0x%x\n" \
+-            "   mode: 0%o\n" \
+-            "   nlink: 0x%x\n" \
+-            "   uid: 0x%x\n" \
+-            "   gid: 0x%x\n" \
+-            "   rdev: 0x%x\n" \
+-            "   size: 0x%llx\n" \
+-            "   atime: %s\n" \
+-            "   mtime: %s\n" \
+-            "   ctime: %s\n" \
+-            "   blksize: 0x%x\n" \
+-            "   blocks: 0x%x\n",
+-      retCode, dentry->d_name.len, dentry->d_name.name,
+-      kstat->ino,
+-      kstat->dev,
+-      kstat->mode,
+-      kstat->nlink,
+-      kstat->uid,
+-      kstat->gid,
+-      kstat->rdev,
+-      kstat->size,
+-      atime_buf,
+-      mtime_buf,
+-      ctime_buf,
+-      kstat->blksize,
+-      kstat->blocks);
+-   return( retCode );
+-}
+-
+-
+-/*++======================================================================*/
+-int Novfs_i_revalidate(struct dentry *dentry)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-
+-   DbgPrint("Novfs_i_revalidate: name %.*s\n", dentry->d_name.len, dentry->d_name.name);
+-
+-   return(0);
+-}
+-
+-/*++======================================================================*/
+-void Novfs_read_inode(struct inode *inode)
+-/*
+- *  Arguments:
+- *
+- *  Returns:      nothing
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:  Superblock operation
+- *
+- *=======================================================================-*/
+-{
+-   DbgPrint( "Novfs_read_inode: 0x%x %d\n", inode, inode->i_ino);
+-}
+-
+-/*++======================================================================*/
+-void Novfs_write_inode(struct inode *inode)
+-/*
+- *  Arguments:
+- *
+- *  Returns:      nothing
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:  Superblock operation
+- *
+- *=======================================================================-*/
+-{
+-   DbgPrint( "Novfs_write_inode: Inode=0x%x Ino=%d\n", inode, inode->i_ino);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_notify_change(struct dentry *dentry, struct iattr *attr)
+-/*
+- *  Arguments:
+- *
+- *  Returns:      error code
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:  Superblock operation
+- *
+- *=======================================================================-*/
+-{
+-   struct inode *inode = dentry->d_inode;
+-
+-   DbgPrint( "Novfs_notify_change: Dentry=0x%x Name=%.*s Inode=0x%x Ino=%d ia_valid=0x%x\n", 
+-      dentry, dentry->d_name.len, dentry->d_name.name,inode, inode->i_ino, attr->ia_valid);
+-   return(0);
+-}
+-
+-/*++======================================================================*/
+-void Novfs_clear_inode(struct inode *inode)
+-/*
+- * Arguments:    sb - pointer to the super_block
+- *               buf - pointer to the statfs buffer
+- *
+- *  Returns:      0
+- * 
+- *  Abstract:     Called when statfs(2) system called.
+- * 
+- *  Notes:
+- * 
+- *  Environment:  Superblock operation
+- *
+- *========================================================================*/
+-{
+-   InodeCount--;
+-   
+-   if ( inode->u.generic_ip )
+-   {
+-      PINODE_DATA id=inode->u.generic_ip;
+-
+-      DbgPrint("Novfs_clear_inode: inode=0x%x ino=%d Scope=0x%p Name=%s\n", inode, inode->i_ino, id->Scope, id->Name);
+-
+-      Novfs_free_inode_cache(inode);
+-
+-      down( &InodeList_lock );
+-      list_del( &id->IList );
+-      up( &InodeList_lock );
+-
+-
+-      Novfs_Free(inode->u.generic_ip);
+-      inode->u.generic_ip = NULL;
+-
+-      remove_inode_hash( inode );
+-
+-   }
+-   else
+-   {
+-      DbgPrint("Novfs_clear_inode: inode=0x%x ino=%d\n", inode, inode->i_ino);
+-   }
+-}
+-
+-/*++======================================================================*/
+-int 
+-NO_TRACE
+-Novfs_show_options( struct seq_file *s, struct vfsmount *m )
+-/*
+- * Arguments:    
+- *
+- *  Returns:      0
+- * 
+- *  Abstract:     Called when /proc/mounts is read
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   char *buf, *path, *tmp;
+-
+-   buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+-   if (buf)
+-   {
+-      path = d_path(m->mnt_root, m, buf, PATH_LENGTH_BUFFER);
+-      if (path)
+-      {
+-         if ( !Novfs_CurrentMount || (Novfs_CurrentMount && strcmp(Novfs_CurrentMount, path)))
+-         {
+-            DbgPrint("Novfs_show_options: %.*s %.*s %s\n", m->mnt_root->d_name.len, m->mnt_root->d_name.name, 
+-               m->mnt_mountpoint->d_name.len, m->mnt_mountpoint->d_name.name, path);
+-            tmp = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER - (int)(path-buf), GFP_KERNEL);
+-            if (tmp)
+-            {
+-               strcpy(tmp, path);
+-               path = Novfs_CurrentMount;
+-               Novfs_CurrentMount = tmp;
+-               Daemon_SetMountPoint( Novfs_CurrentMount );
+-
+-               if (path)
+-               {
+-                  Novfs_Free(path);
+-               }
+-            }
+-         }
+-      }
+-      Novfs_Free( buf );
+-   }
+-   return(0);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_statfs(struct super_block *sb, struct kstatfs *buf)
+-/*
+- * Arguments:    sb - pointer to the super_block
+- *               buf - pointer to the statfs buffer
+- *
+- *  Returns:      0
+- * 
+- *  Abstract:     Called when statfs(2) system called.
+- * 
+- *  Notes:
+- * 
+- *  Environment:  Superblock operation
+- *
+- *========================================================================*/
+-{
+-   uint64_t td, fd, te, fe;
+- 
+-   UNUSED_VARIABLE(sb);
+-
+-   DbgPrint("Novfs_statfs:\n");
+-
+-   td = fd = te = fe = 0;
+-
+-   Scope_Get_UserSpace( &td, &fd, &te, &fe );
+-
+-   DbgPrint("td=%llu\n", td);
+-   DbgPrint("fd=%llu\n", fd);
+-   DbgPrint("te=%llu\n", te);
+-   DbgPrint("fe=%llu\n", fd);
+-
+-   buf->f_type = sb->s_magic;
+-   buf->f_bsize = sb->s_blocksize;
+-   buf->f_namelen = NW_MAX_PATH_LENGTH;
+-   buf->f_blocks = (sector_t)(td + (uint64_t)(sb->s_blocksize-1)) >> (uint64_t)sb->s_blocksize_bits;
+-   buf->f_bfree = (sector_t)fd >> (uint64_t)sb->s_blocksize_bits;
+-   buf->f_bavail = (sector_t)buf->f_bfree;
+-   buf->f_files = (sector_t)te;
+-   buf->f_ffree = (sector_t)fe;
+-   buf->f_frsize = sb->s_blocksize;
+-   if (te > 0xffffffff)
+-      buf->f_files = 0xffffffff;
+-
+-   if (fe > 0xffffffff)
+-      buf->f_ffree = 0xffffffff;
+-
+-
+-   DbgPrint("f_type:    0x%x\n", buf->f_type);
+-   DbgPrint("f_bsize:   %u\n", buf->f_bsize);
+-   DbgPrint("f_namelen: %d\n", buf->f_namelen);
+-   DbgPrint("f_blocks:  %llu\n", buf->f_blocks);
+-   DbgPrint("f_bfree:   %llu\n", buf->f_bfree);
+-   DbgPrint("f_bavail:  %llu\n", buf->f_bavail);
+-   DbgPrint("f_files:   %llu\n", buf->f_files);
+-   DbgPrint("f_ffree:   %llu\n", buf->f_ffree);
+-   DbgPrint("f_frsize:  %u\n", buf->f_frsize);
+-
+-   return 0;
+-}
+-
+-/*++======================================================================*/
+-struct inode *Novfs_get_inode(struct super_block *sb, int mode, int dev, uid_t Uid, ino_t ino, struct qstr *name)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *=======================================================================-*/
+-{
+-   struct inode * inode = new_inode(sb);
+-
+-   if (inode) 
+-   {
+-      InodeCount++;
+-      inode->i_mode = mode;
+-      inode->i_uid = Uid;
+-      inode->i_gid = 0;
+-      inode->i_blksize = sb->s_blocksize;
+-      inode->i_blkbits = sb->s_blocksize_bits;
+-      inode->i_size = 0;
+-      inode->i_blocks = 0;
+-      inode->i_rdev = 0;
+-      inode->i_ino = (ino) ? ino: (ino_t)InterlockedIncrement(&Novfs_Inode_Number);
+-      inode->i_mapping->a_ops = &Novfs_aops;
+-      inode->i_atime.tv_sec = 0;
+-      inode->i_atime.tv_nsec = 0;
+-      inode->i_mtime = inode->i_ctime = inode->i_atime;
+-
+-      DbgPrint("Novfs_get_inode: Inode=0x%p I_ino=%d len=%d\n", inode, inode->i_ino, name->len);
+-
+-      if (NULL != (inode->u.generic_ip = Novfs_Malloc(sizeof(INODE_DATA)+name->len, GFP_KERNEL)))
+-      {
+-         PINODE_DATA id;
+-         id = inode->u.generic_ip;
+-
+-         DbgPrint("Novfs_get_inode: u.generic_ip 0x%p\n", id);
+-
+-         id->Scope = NULL;
+-         id->Flags = 0;
+-         id->Inode = inode;
+-         INIT_LIST_HEAD( &id->DirCache );
+-         init_MUTEX( &id->DirCacheLock );
+-         down( &InodeList_lock );
+-
+-         list_add_tail(&id->IList, &InodeList);
+-         up( &InodeList_lock );
+-
+-         id->Name[0] = '\0';
+-
+-         memcpy(id->Name, name->name, name->len);
+-         id->Name[name->len] = '\0';
+-
+-         DbgPrint("Novfs_get_inode: name %s\n", id->Name);
+-      }
+-
+-		insert_inode_hash(inode);
+-
+-      switch (mode & S_IFMT) {
+-
+-      case S_IFREG:
+-         inode->i_op = &Novfs_file_inode_operations;
+-         inode->i_fop = &Novfs_file_operations;
+-         break;
+-
+-      case S_IFDIR:
+-         inode->i_op = &Novfs_inode_operations;
+-         inode->i_fop = &Novfs_dir_operations;
+-         inode->i_blksize = 0;
+-         inode->i_blkbits = 0;
+-         break;
+-
+-      default:
+-         init_special_inode(inode, mode, dev);
+-         break;
+-      }
+-
+-      DbgPrint("Novfs_get_inode: size=%lld\n", inode->i_size);
+-      DbgPrint("Novfs_get_inode: mode=0%o\n", inode->i_mode);
+-      DbgPrint("Novfs_get_inode: i_blksize=%d\n", inode->i_blksize);
+-      DbgPrint("Novfs_get_inode: i_blkbits=%d\n", inode->i_blkbits);
+-      DbgPrint("Novfs_get_inode: i_blocks=%d\n", inode->i_blocks);
+-      DbgPrint("Novfs_get_inode: i_bytes=%d\n", inode->i_bytes);
+-   }
+-
+-   DbgPrint("Novfs_get_inode: 0x%p %d\n", inode, inode->i_ino);
+-   return (inode);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_fill_super (struct super_block *SB, void *Data, int Silent)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   struct inode * inode;
+-   struct dentry *server, *tree;
+-   struct qstr name;
+-/*   PINODE_DATA id;
+-*/
+-   ENTRY_INFO info;
+-
+-   UNUSED_VARIABLE(Data);
+-   UNUSED_VARIABLE(Silent);
+-
+-   SB->s_blocksize = PAGE_CACHE_SIZE;
+-   SB->s_blocksize_bits = PAGE_CACHE_SHIFT;
+-   SB->s_maxbytes = 0xFFFFFFFFFFFFFFFFULL;	/* Max file size */
+-   SB->s_op = &Novfs_ops;
+-   SB->s_flags |= (MS_NODIRATIME | MS_NODEV | MS_POSIXACL);
+-   SB->s_magic = NOVFS_MAGIC;
+-
+-   
+-   name.len = 1;
+-   name.name = "/";
+-
+-   inode = Novfs_get_inode(SB, S_IFDIR | 0777, 0, 0, 0, &name);
+-   if (!inode)
+-   {
+-      return( -ENOMEM );
+-   }
+-   
+-   Novfs_root = d_alloc_root(inode);
+-
+-   if (!Novfs_root)
+-   {
+-      iput(inode);
+-      return( -ENOMEM );
+-   }
+-   Novfs_root->d_time = jiffies+(File_update_timeout*HZ);
+-
+-   inode->i_atime = 
+-   inode->i_ctime = 
+-   inode->i_mtime = CURRENT_TIME;
+-
+-
+-   SB->s_root = Novfs_root;
+-
+-   DbgPrint( "Novfs_fill_super: root 0x%x\n", Novfs_root);
+-
+-   if (Novfs_root)
+-   {
+-      Novfs_root->d_op = &Novfs_dentry_operations;
+-
+-      name.name = SERVER_DIRECTORY_NAME;
+-      name.len  = strlen(SERVER_DIRECTORY_NAME);
+-      name.hash = Novfs_internal_hash( &name );
+-
+-      inode = Novfs_get_inode(SB, S_IFDIR | 0777, 0, 0, 0, &name);
+-      if (inode)
+-      {
+-         info.mode = inode->i_mode;
+-         info.namelength = 0;
+-         inode->i_size  = info.size = 0;
+-         inode->i_uid   = info.uid  = 0;
+-         inode->i_gid   = info.gid  = 0;
+-         inode->i_atime = info.atime =
+-         inode->i_ctime = info.ctime =
+-         inode->i_mtime = info.mtime = CURRENT_TIME;
+-
+-         server = d_alloc(Novfs_root, &name);
+-         if (server)
+-         {
+-            server->d_op = &Novfs_dentry_operations;
+-            server->d_time = 0xffffffff;
+-            d_add(server, inode);
+-            DbgPrint( "Novfs_fill_super: d_add %s 0x%x\n", SERVER_DIRECTORY_NAME, server);
+-            Novfs_add_inode_entry(Novfs_root->d_inode, &name, inode->i_ino, &info);
+-         }
+-      }
+-
+-      name.name = TREE_DIRECTORY_NAME;
+-      name.len  = strlen(TREE_DIRECTORY_NAME);
+-      name.hash =  Novfs_internal_hash( &name );
+-
+-      inode = Novfs_get_inode(SB, S_IFDIR | 0777, 0, 0, 0, &name);
+-      if (inode)
+-      {
+-         info.mode = inode->i_mode;
+-         info.namelength = 0;
+-         inode->i_size  = info.size = 0;
+-         inode->i_uid   = info.uid  = 0;
+-         inode->i_gid   = info.gid  = 0;
+-         inode->i_atime = info.atime =
+-         inode->i_ctime = info.ctime =
+-         inode->i_mtime = info.mtime = CURRENT_TIME;
+-         tree = d_alloc(Novfs_root, &name);
+-         if (tree)
+-         {
+-            tree->d_op = &Novfs_dentry_operations;
+-            tree->d_time = 0xffffffff;
+-
+-            d_add(tree, inode);
+-            DbgPrint( "Novfs_fill_super: d_add %s 0x%x\n", TREE_DIRECTORY_NAME, tree);
+-            Novfs_add_inode_entry(Novfs_root->d_inode, &name, inode->i_ino, &info);
+-         }
+-      }
+-   }
+-
+-   return( 0 );
+-}
+-
+-/*++======================================================================*/
+-struct super_block *Novfs_get_sb(struct file_system_type *Fstype, int Flags, const char *Dev_name, void *Data)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   struct super_block *sb;
+-   UNUSED_VARIABLE(Dev_name);
+-
+-   sb = get_sb_nodev(Fstype, Flags, Data, Novfs_fill_super);
+-
+-   DbgPrint( "Novfs_get_sb: sb=0x%x Fstype=0x%x Dev_name=%s\n", sb, Fstype, Dev_name);
+-
+-   return (sb );
+-}
+-
+-/*++======================================================================*/
+-void Novfs_kill_sb(struct super_block *SB)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   kill_litter_super(SB);
+-}
+-
+-/*++======================================================================*/
+-ssize_t Novfs_Control_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   ssize_t   retval=0;
+-
+-   UNUSED_VARIABLE(file);
+-   UNUSED_VARIABLE(buf);
+-   UNUSED_VARIABLE(nbytes);
+-   UNUSED_VARIABLE(ppos);
+-
+-   DbgPrint( "Novfs_Control_read: kernel_locked 0x%x\n", kernel_locked());
+-
+-   return retval;
+-}
+-
+-/*++======================================================================*/
+-ssize_t Novfs_Control_write(struct file * file, const char * buf, size_t nbytes, loff_t *ppos)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   ssize_t   retval=0;
+-
+-   UNUSED_VARIABLE(file);
+-   UNUSED_VARIABLE(buf);
+-   UNUSED_VARIABLE(nbytes);
+-   UNUSED_VARIABLE(ppos);
+-
+-   DbgPrint( "Novfs_Control_write: kernel_locked 0x%x\n", kernel_locked());
+-   if (buf && nbytes)
+-   {
+-   }
+-   
+-   return(retval);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_Control_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   int retval=0;
+-
+-   UNUSED_VARIABLE(inode);
+-   UNUSED_VARIABLE(file);
+-   UNUSED_VARIABLE(cmd);
+-   UNUSED_VARIABLE(arg);
+-
+-   DbgPrint( "Novfs_Control_ioctl: kernel_locked 0x%x\n", kernel_locked());
+-
+-   return(retval);
+-}
+-
+-/*++======================================================================*/
+-int __init init_novfs (void)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   int retCode;
+-   
+-
+-   retCode = Init_Procfs_Interface();
+-
+-   init_profile();
+-
+-   if ( !retCode )
+-   {
+-      DbgPrint("init_novfs: %s %s %s\n", __DATE__, __TIME__, NOVFS_VERSION_STRING);
+-      Init_Daemon_Queue();
+-      Scope_Init();
+-      retCode = register_filesystem(&Novfs_fs_type);
+-      if ( retCode )
+-      {
+-         Uninit_Procfs_Interface();
+-         Uninit_Daemon_Queue();
+-         Scope_Uninit();
+-      }
+-   }
+-   return(retCode);
+-}
+-
+-/*++======================================================================*/
+-void __exit exit_novfs(void)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   printk( KERN_INFO "exit_novfs\n");
+-   Scope_Uninit();
+-   printk( KERN_INFO "exit_novfs after Scope_Uninit\n");
+-   Uninit_Daemon_Queue();
+-   printk( KERN_INFO "exit_novfs after Uninit_Daemon_Queue\n");
+-   Uninit_Procfs_Interface();
+-   printk( KERN_INFO "exit_novfs Uninit_Procfs_Interface\n");
+-   unregister_filesystem(&Novfs_fs_type);
+-   printk( KERN_INFO "exit_novfs: Exit\n");
+-   if (Novfs_CurrentMount)
+-   {
+-      Novfs_Free(Novfs_CurrentMount);
+-      Novfs_CurrentMount = NULL;
+-   }
+-}
+-
+-/*++======================================================================*/
+-int Novfs_lock_inode_cache( struct inode *i )
+-/*
+- *
+- *  Arguments:   struct inode *i - pointer to directory inode
+- *
+- *  Returns:     0 - locked
+- *              -1 - not locked
+- *
+- *  Abstract:    Locks the inode cache.
+- *
+- *  Notes:       
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PINODE_DATA id;
+-   int retVal = 0;
+-
+-   DbgPrint("Novfs_lock_inode_cache: 0x%p\n", i);
+-   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
+-   {
+-      down( &id->DirCacheLock );
+-      retVal = 1;
+-   }
+-   DbgPrint("Novfs_lock_inode_cache: return %d\n", retVal);
+-   return( retVal );
+-}
+-
+-/*++======================================================================*/
+-void Novfs_unlock_inode_cache( struct inode *i )
+-/*
+- *  Arguments:   struct inode *i - pointer to directory inode
+- *
+- *  Returns:     nothing
+- * 
+- *  Abstract:    Unlocks inode cache.
+- * 
+- *  Notes:       
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PINODE_DATA id;
+-
+-   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
+-   {
+-      up( &id->DirCacheLock );
+-   }
+-}
+-
+-/*++======================================================================*/
+-int Novfs_enumerate_inode_cache( struct inode *i, struct list_head **iteration, ino_t *ino, PENTRY_INFO info)
+-/*
+- *  Arguments:   struct inode *i - pointer to directory inode
+- *
+- *  Returns:     0 - item found
+- *              -1 - done
+- *
+- *  Abstract:    Unlocks inode cache.
+- *
+- *  Notes:       DirCacheLock should be held before calling this routine.
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PINODE_DATA id;
+-   PDIR_CACHE dc;
+-   struct list_head *l=NULL;
+-   int retVal = -1;
+-
+-
+-   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
+-   {
+-      if ( (NULL == iteration) || (NULL == *iteration) )
+-      {
+-         l = id->DirCache.next;
+-      }
+-      else
+-      {
+-         l = *iteration;
+-      }
+-
+-      if (l == &id->DirCache)
+-      {
+-         l = NULL;
+-      }
+-      else
+-      {
+-         dc = list_entry(l, DIR_CACHE, list);
+-
+-         *ino = dc->ino;
+-         info->type = 0;
+-         info->mode = dc->mode;
+-         info->size = dc->size;
+-         info->atime = dc->atime;
+-         info->mtime = dc->mtime;
+-         info->ctime = dc->ctime;
+-         info->namelength = dc->nameLen;
+-         memcpy(info->name, dc->name, dc->nameLen);
+-         info->name[dc->nameLen] = '\0';
+-         retVal = 0;
+-
+-         l = l->next;
+-      }
+-   }
+-   *iteration = l;
+-   return( retVal );
+-}
+-
+-/*++======================================================================*/
+-int Novfs_get_entry( struct inode *i, struct qstr *name, ino_t *ino, PENTRY_INFO info)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:       DirCacheLock should be held before calling this routine.
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PINODE_DATA id;
+-   PDIR_CACHE dc;
+-   int retVal = -1;
+-   char *n="<NULL>";
+-   int nl=6;
+-
+-   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
+-   {
+-      if (name && name->len)
+-      {
+-         n = (char *)name->name;
+-         nl = name->len;
+-      }
+-      DbgPrint("Novfs_get_entry:\n" \
+-               "   inode: 0x%p\n" \
+-               "   name:  %.*s\n" \
+-               "   ino:   %d\n",
+-         i, nl, n, *ino);
+-
+-      dc = Novfs_lookup_inode_cache(i, name, *ino);
+-      if (dc)
+-      {
+-         dc->flags |= ENTRY_VALID;
+-         retVal = 0;
+-         *ino = dc->ino;
+-         info->type = 0;
+-         info->mode = dc->mode;
+-         info->size = dc->size;
+-         info->atime = dc->atime;
+-         info->mtime = dc->mtime;
+-         info->ctime = dc->ctime;
+-         info->namelength = dc->nameLen;
+-         memcpy(info->name, dc->name, dc->nameLen);
+-         info->name[dc->nameLen] = '\0';
+-         retVal = 0;
+-      }
+-   }
+-   DbgPrint("Novfs_get_entry: return %d\n", retVal);
+-   return( retVal );
+-}
+-
+-/*++======================================================================*/
+-int Novfs_get_entry_time( struct inode *i, struct qstr *name, ino_t *ino, PENTRY_INFO info, u64 *EntryTime)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:       DirCacheLock should be held before calling this routine.
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PINODE_DATA id;
+-   PDIR_CACHE dc;
+-   int retVal = -1;
+-   char *n="<NULL>";
+-   int nl=6;
+-
+-   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
+-   {
+-      if (name && name->len)
+-      {
+-         n = (char *)name->name;
+-         nl = name->len;
+-      }
+-      DbgPrint("Novfs_get_entry:\n" \
+-               "   inode: 0x%p\n" \
+-               "   name:  %.*s\n" \
+-               "   ino:   %d\n",
+-         i, nl, n, *ino);
+-
+-      dc = Novfs_lookup_inode_cache(i, name, *ino);
+-      if (dc)
+-      {
+-         retVal = 0;
+-         *ino = dc->ino;
+-         info->type = 0;
+-         info->mode = dc->mode;
+-         info->size = dc->size;
+-         info->atime = dc->atime;
+-         info->mtime = dc->mtime;
+-         info->ctime = dc->ctime;
+-         info->namelength = dc->nameLen;
+-         memcpy(info->name, dc->name, dc->nameLen);
+-         info->name[dc->nameLen] = '\0';
+-         if (EntryTime)
+-         {
+-            *EntryTime = dc->jiffies;
+-         }
+-         retVal = 0;
+-      }
+-   }
+-   DbgPrint("Novfs_get_entry: return %d\n", retVal);
+-   return( retVal );
+-}
+-
+-/*++======================================================================*/
+-int Novfs_get_remove_entry( struct inode *i, ino_t *ino, PENTRY_INFO info)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:    This routine will return the first entry on the list 
+- *               and then remove it.
+- *
+- *  Notes:       DirCacheLock should be held before calling this routine.
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PINODE_DATA id;
+-   PDIR_CACHE dc;
+-   struct list_head *l=NULL;
+-   int retVal = -1;
+-
+-
+-   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
+-   {
+-      l = id->DirCache.next;
+-
+-      if (l != &id->DirCache)
+-      {
+-         dc = list_entry(l, DIR_CACHE, list);
+-
+-         *ino = dc->ino;
+-         info->type = 0;
+-         info->mode = dc->mode;
+-         info->size = dc->size;
+-         info->atime = dc->atime;
+-         info->mtime = dc->mtime;
+-         info->ctime = dc->ctime;
+-         info->namelength = dc->nameLen;
+-         memcpy(info->name, dc->name, dc->nameLen);
+-         info->name[dc->nameLen] = '\0';
+-         retVal = 0;
+-
+-         list_del( &dc->list );
+-         Novfs_Free( dc );
+-         DCCount--;
+-
+-      }
+-   }
+-   return( retVal );
+-}
+-
+-/*++======================================================================*/
+-void Novfs_invalidate_inode_cache( struct inode *i )
+-/*
+- *  Arguments:   struct inode *i - pointer to directory inode
+- *
+- *  Returns:     nothing
+- * 
+- *  Abstract:    Marks all entries in the directory cache as invalid.
+- * 
+- *  Notes:       DirCacheLock should be held before calling this routine.
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PINODE_DATA id;
+-   PDIR_CACHE dc;
+-   struct list_head *l;
+-
+-   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
+-   {
+-      list_for_each(l, &id->DirCache)
+-      {
+-         dc = list_entry(l, DIR_CACHE, list);
+-         dc->flags &= ~ENTRY_VALID;
+-      }
+-   }
+-}
+-
+-/*++======================================================================*/
+-PDIR_CACHE Novfs_lookup_inode_cache( struct inode *i, struct qstr *name, ino_t ino )
+-/*
+- *  Arguments:   struct inode *i - pointer to directory inode
+- *               struct qstr *name - pointer to name
+- *               ino_t - inode number
+- *
+- *  Returns:     DIR_CACHE entry if match
+- *               NULL - if there is no match.
+- *
+- *  Abstract:    Checks a inode directory to see if there are any enties
+- *               matching name or ino.  If name is specified then ino is 
+- *               not used.  ino is use if name is not specified.
+- *
+- *  Notes:       DirCacheLock should be held before calling this routine.
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PINODE_DATA id;
+-   PDIR_CACHE dc, retVal=NULL;
+-   struct list_head *l;
+-   char *n="<NULL>";
+-   int nl=6;
+-   int hash=0;
+-
+-   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
+-   {
+-      if (name && name->name)
+-      {
+-         nl = name->len;
+-         n = (char *)name->name;
+-         hash = name->hash;
+-      }
+-      DbgPrint("Novfs_lookup_inode_cache:\n" \
+-               "   inode: 0x%p\n" \
+-               "   name:  %.*s\n" \
+-               "   hash:  0x%x\n" \
+-               "   len:   %d\n" \
+-               "   ino:   %d\n",
+-         i, nl, n, hash, nl, ino);
+-
+-      list_for_each(l, &id->DirCache)
+-      {
+-         dc = list_entry(l, DIR_CACHE, list);
+-         if (name)
+-         {
+-            
+-/*         DbgPrint("Novfs_lookup_inode_cache: 0x%p\n" \
+-                  "   ino:   %d\n" \
+-                  "   hash:  0x%x\n" \
+-                  "   len:   %d\n" \
+-                  "   name:  %.*s\n",
+-            dc, dc->ino, dc->hash, dc->nameLen, dc->nameLen, dc->name);
+-*/
+-            if ( (name->hash == dc->hash) &&
+-                 (name->len == dc->nameLen) &&
+-                 (0 == memcmp(name->name, dc->name, name->len)) )
+-            {
+-               retVal = dc;
+-               break;
+-            }
+-         }
+-         else
+-         {
+-            if (ino == dc->ino)
+-            {
+-               retVal = dc;
+-               break;
+-            }
+-         }
+-      }
+-   }
+-
+-   DbgPrint("Novfs_lookup_inode_cache: return 0x%p\n", retVal);
+-   return( retVal );
+-}
+-
+-/*++======================================================================*/
+-int Novfs_lookup_validate( struct inode *i, struct qstr *name, ino_t ino )
+-/*
+- *  Arguments:   struct inode *i - pointer to directory inode
+- *               struct qstr *name - pointer to name
+- *               ino_t - inode number
+- *
+- *  Returns:     0 if found
+- *               !0 if not found
+- *
+- *  Abstract:    Checks a inode directory to see if there are any enties
+- *               matching name or ino.  If entry is found the valid bit
+- *               is set.
+- *
+- *  Notes:       DirCacheLock should be held before calling this routine.
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PINODE_DATA id;
+-   PDIR_CACHE dc;
+-   int retVal = -1;
+-   char *n="<NULL>";
+-   int nl=6;
+-
+-   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
+-   {
+-      if (name && name->len)
+-      {
+-         n = (char *)name->name;
+-         nl = name->len;
+-      }
+-      DbgPrint("Novfs_update_entry:\n" \
+-               "   inode: 0x%p\n" \
+-               "   name:  %.*s\n" \
+-               "   ino:   %d\n",
+-         i, nl, n, ino);
+-
+-      dc = Novfs_lookup_inode_cache( i, name, ino );
+-      if (dc)
+-      {
+-         dc->flags |= ENTRY_VALID;
+-         retVal = 0;
+-      }
+-   }
+-   return( retVal );
+-}
+-
+-/*++======================================================================*/
+-int Novfs_add_inode_entry( 
+-   struct inode    *i, 
+-   struct qstr     *name, 
+-   ino_t            ino, 
+-   PENTRY_INFO      info)
+-/*
+- *  Arguments:
+- *
+- *  Returns:     -ENOMEM - alloc error.
+- *                0 - success.
+- *
+- *  Abstract:    Added entry to directory cache.
+- *
+- *  Notes:       DirCacheLock should be held before calling this routine.
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PINODE_DATA id;
+-   PDIR_CACHE new;
+-   int retVal = -ENOMEM;
+-
+-   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
+-   {
+-      new = Novfs_Malloc(sizeof(DIR_CACHE)+name->len, GFP_KERNEL);
+-      if (new)
+-      {
+-         DCCount++;
+-         DbgPrint("Novfs_add_inode_entry:\n" \
+-                  "   inode: 0x%p\n" \
+-                  "   id:    0x%p\n" \
+-                  "   DC:    0x%p\n" \
+-                  "   new:   0x%p\n" \
+-                  "   name:  %.*s\n" \
+-                  "   ino:   %d\n"   \
+-                  "   size:  %lld\n" \
+-                  "   mode:  0x%x\n",
+-            i, id, &id->DirCache, new, name->len, name->name, ino, info->size, info->mode);
+-
+-         retVal = 0;
+-         new->flags   = ENTRY_VALID;
+-         new->jiffies = get_jiffies_64();
+-         new->size    = info->size;
+-         new->mode    = info->mode;
+-         new->atime   = info->atime;
+-         new->mtime   = info->mtime;
+-         new->ctime   = info->ctime;
+-         new->ino     = ino;
+-         new->hash    = name->hash;
+-         new->nameLen = name->len;
+-         memcpy(new->name, name->name, name->len);
+-         new->name[new->nameLen] = '\0';
+-         list_add(&new->list, &id->DirCache);
+-
+-/*         list_for_each(l, &id->DirCache)
+-         {
+-            dc = list_entry(l, DIR_CACHE, list);
+-            if ( dc->hash > new->hash )
+-            {
+-               break;
+-            }
+-         }
+-
+-         DbgPrint("Novfs_add_inode_entry: adding 0x%p to 0x%p\n", new, l);
+-         list_add(&new->list, l);
+-*/
+-      }
+-   }
+-   return( retVal );
+-}
+-
+-/*++======================================================================*/
+-int Novfs_update_entry( struct inode *i, struct qstr *name, ino_t ino, PENTRY_INFO info)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- * 
+- *  Abstract:
+- * 
+- *  Notes:       DirCacheLock should be held before calling this routine.
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PINODE_DATA id;
+-   PDIR_CACHE dc;
+-   int retVal = -1;
+-   char *n="<NULL>";
+-   int nl=6;
+-   char atime_buf[32];
+-   char mtime_buf[32];
+-   char ctime_buf[32];
+-
+-   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
+-   {
+-
+-      if (name && name->len)
+-      {
+-         n = (char *)name->name;
+-         nl = name->len;
+-      }
+-      ctime_r(&info->atime.tv_sec, atime_buf);
+-      ctime_r(&info->mtime.tv_sec, mtime_buf);
+-      ctime_r(&info->ctime.tv_sec, ctime_buf);
+-      DbgPrint("Novfs_update_entry:\n" \
+-               "   inode: 0x%p\n" \
+-               "   name:  %.*s\n" \
+-               "   ino:   %d\n" \
+-               "   size:  %lld\n" \
+-               "   atime: %s\n" \
+-               "   mtime: %s\n" \
+-               "   ctime: %s\n",
+-         i, nl, n, ino, info->size, atime_buf, mtime_buf, ctime_buf);
+-
+-
+-      dc = Novfs_lookup_inode_cache(i, name, ino);
+-      if (dc)
+-      {
+-         retVal = 0;
+-         dc->flags   = ENTRY_VALID;
+-         dc->jiffies = get_jiffies_64();
+-         dc->size    = info->size;
+-         dc->mode    = info->mode;
+-         dc->atime   = info->atime;
+-         dc->mtime   = info->mtime;
+-         dc->ctime   = info->ctime;
+-
+-         ctime_r(&dc->atime.tv_sec, atime_buf);
+-         ctime_r(&dc->mtime.tv_sec, mtime_buf);
+-         ctime_r(&dc->ctime.tv_sec, ctime_buf);
+-         DbgPrint("Novfs_update_entry entry: 0x%x\n" \
+-                  "   flags:   0x%x\n" \
+-                  "   jiffies: %lld\n" \
+-                  "   ino:     %d\n"   \
+-                  "   size:    %lld\n" \
+-                  "   mode:    0%o\n"  \
+-                  "   atime:   %s\n"   \
+-                  "   mtime:   %s\n"   \
+-                  "   ctime:   %s\n"   \
+-                  "   hash:    0x%x\n" \
+-                  "   nameLen: %d\n"   \
+-                  "   name:    %s\n",
+-            dc, dc->flags, dc->jiffies, dc->ino, dc->size, dc->mode,
+-            atime_buf, mtime_buf, ctime_buf, dc->hash, dc->nameLen, dc->name);
+-      }
+-   }
+-   DbgPrint("Novfs_update_entry: return %d\n", retVal);
+-   return( retVal );
+-}
+-
+-/*++======================================================================*/
+-void Novfs_remove_inode_entry( struct inode *i, struct qstr *name, ino_t ino)
+-/*
+- *  Arguments:
+- *
+- *  Returns:     nothing
+- *
+- *  Abstract:    Removes entry from directory cache.  You can specify a name
+- *               or an inode number.
+- *
+- *  Notes:       DirCacheLock should be held before calling this routine.
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PINODE_DATA id;
+-   PDIR_CACHE dc;
+-   char *n="<NULL>";
+-   int nl=6;
+-
+-   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
+-   {
+-      dc = Novfs_lookup_inode_cache( i, name, ino );
+-      if (dc)
+-      {
+-         if (name && name->name)
+-         {
+-            nl = name->len;
+-            n = (char *)name->name;
+-         }
+-         DbgPrint("Novfs_remove_inode_entry:\n" \
+-                  "   inode: 0x%p\n" \
+-                  "   id:    0x%p\n" \
+-                  "   DC:    0x%p\n" \
+-                  "   name:  %.*s\n" \
+-                  "   ino:   %d\n" \
+-                  "   entry: 0x%p\n" \
+-                  "      name: %.*s\n"\
+-                  "      ino:  %d\n" \
+-                  "      next: 0x%p\n" \
+-                  "      prev: 0x%p\n",
+-            i, id, &id->DirCache, nl, n, ino, dc, dc->nameLen, dc->name, dc->ino, dc->list.next, dc->list.prev);
+-         list_del( &dc->list );
+-         Novfs_Free( dc );
+-         DCCount--;
+-
+-      }
+-   }
+-}
+-
+-/*++======================================================================*/
+-void Novfs_free_invalid_entries( struct inode *i )
+-/*
+- *  Arguments:   struct inode *i - pointer to directory inode.
+- *
+- *  Returns:     nothing
+- * 
+- *  Abstract:    Frees all invalid entries in the directory cache.
+- * 
+- *  Notes:       DirCacheLock should be held before calling this routine.
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PINODE_DATA id;
+-   PDIR_CACHE dc;
+-   struct list_head *l;
+-
+-   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
+-   {
+-      list_for_each( l, &id->DirCache )
+-      {
+-         dc = list_entry( l, DIR_CACHE, list );
+-         if ( 0 == (dc->flags & ENTRY_VALID) )
+-         {
+-            DbgPrint("Novfs_free_invalid_entries:\n" \
+-                     "   inode: 0x%p\n" \
+-                     "   id:    0x%p\n" \
+-                     "   entry:    0x%p\n" \
+-                     "   name:  %.*s\n" \
+-                     "   ino:   %d\n",
+-               i, id, dc, dc->nameLen, dc->name, dc->ino);
+-            l = l->prev;
+-            list_del( &dc->list );
+-            Novfs_Free( dc );
+-            DCCount--;
+-         }
+-      }
+-   }
+-}
+-
+-/*++======================================================================*/
+-void Novfs_free_inode_cache( struct inode *i )
+-/*
+- *  Arguments:   struct inode *i - pointer to directory inode.
+- *
+- *  Returns:     nothing
+- * 
+- *  Abstract:    Frees all entries in the inode cache.
+- * 
+- *  Notes:       DirCacheLock should be held before calling this routine.
+- * 
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PINODE_DATA id;
+-   PDIR_CACHE dc;
+-   struct list_head *l;
+-
+-   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
+-   {
+-      list_for_each( l, &id->DirCache )
+-      {
+-         dc = list_entry( l, DIR_CACHE, list );
+-         l = l->prev;
+-         list_del( &dc->list );
+-         Novfs_Free( dc );
+-         DCCount--;
+-      }
+-   }
+-}
+-
+-/*++======================================================================*/
+-int
+-NO_TRACE
+-Novfs_dump_inode_cache(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+-/*
+- * Arguments:
+- * 
+- *  Returns:
+- *  
+- *  Abstract:
+- *  
+- *  Notes:
+- *  
+- *  Environment:
+- * 
+- *========================================================================*/
+-{
+-#ifdef	CONFIG_KDB
+-   struct inode *inode=NULL;
+-   PINODE_DATA id;
+-   PDIR_CACHE dc;
+-   struct list_head *l;
+-   char atime_buf[32];
+-   char mtime_buf[32];
+-   char ctime_buf[32];
+-
+-   if (Novfs_root)
+-   {
+-      inode = Novfs_root->d_inode;
+-   }
+-
+-   if (argc > 0)
+-   {
+-      inode = (void *)simple_strtoul(argv[1], NULL, 0);
+-   }
+-
+-   kdb_printf("Inode: 0x%p\n", inode);
+-   if (inode)
+-   {
+-      id = inode->u.generic_ip;
+-      kdb_printf("INODE_DATA: 0x%p\n", id);
+-
+-      if ( id && id->DirCache.next )
+-      {
+-         list_for_each(l, &id->DirCache)
+-         {
+-            dc = list_entry(l, DIR_CACHE, list);
+-            ctime_r(&dc->atime.tv_sec, atime_buf);
+-            ctime_r(&dc->mtime.tv_sec, mtime_buf);
+-            ctime_r(&dc->ctime.tv_sec, ctime_buf);
+-
+-            DbgPrint("Cache Entry: 0x%p\n" \
+-                     "   flags:   0x%x\n" \
+-                     "   jiffies: %llu\n" \
+-                     "   ino:     %u\n" \
+-                     "   size:    %llu\n" \
+-                     "   mode:    0%o\n" \
+-                     "   atime:   %s\n" \
+-                     "   mtime:   %s\n" \
+-                     "   ctime:   %s\n" \
+-                     "   hash:    0x%x\n" \
+-                     "   len:     %d\n" \
+-                     "   name:    %s\n",
+-               dc, dc->flags, dc->jiffies,
+-               dc->ino, dc->size, dc->mode,
+-               atime_buf, mtime_buf, ctime_buf,
+-               dc->hash, dc->nameLen, dc->name);
+-         }
+-      }
+-   }
+-#endif
+-   return(0);
+-}
+-
+-/*++======================================================================*/
+-void
+-NO_TRACE
+-Novfs_dump_inode( void *pf )
+-/*
+- * Arguments:
+- * 
+- *  Returns:
+- *  
+- *  Abstract:
+- *  
+- *  Notes:
+- *  
+- *  Environment:
+- * 
+- *========================================================================*/
+-{
+-   struct inode *inode;
+-   void (*pfunc)(char *Fmt, ...) = pf;
+-   PINODE_DATA id;
+-   PDIR_CACHE dc;
+-   struct list_head *il, *l;
+-   char atime_buf[32];
+-   char mtime_buf[32];
+-   char ctime_buf[32];
+-   unsigned long icnt=0, dccnt=0;
+-
+-   down( &InodeList_lock );
+-   list_for_each(il, &InodeList)
+-   {
+-      id  = list_entry(il, INODE_DATA, IList);
+-      inode = id->Inode;
+-      if (inode)
+-      {
+-         icnt++;
+-
+-         pfunc("Inode=0x%x I_ino=%d\n", inode, inode->i_ino);
+-
+-         pfunc("   atime=%s\n", ctime_r(&inode->i_atime.tv_sec, atime_buf));
+-         pfunc("   ctime=%s\n", ctime_r(&inode->i_mtime.tv_sec, atime_buf));
+-         pfunc("   mtime=%s\n", ctime_r(&inode->i_ctime.tv_sec, atime_buf));
+-         pfunc("   size=%lld\n", inode->i_size);
+-         pfunc("   mode=0%o\n", inode->i_mode);
+-      }
+-
+-      pfunc("   INODE_DATA: 0x%p Name=%s Scope=0x%p\n", id, id->Name, id->Scope);
+-
+-      if (id->DirCache.next )
+-      {
+-         list_for_each(l, &id->DirCache)
+-         {
+-            dccnt++;
+-            dc = list_entry(l, DIR_CACHE, list);
+-            ctime_r(&dc->atime.tv_sec, atime_buf);
+-            ctime_r(&dc->mtime.tv_sec, mtime_buf);
+-            ctime_r(&dc->ctime.tv_sec, ctime_buf);
+-
+-            pfunc("   Cache Entry: 0x%p\n" \
+-                       "      flags:   0x%x\n" \
+-                       "      jiffies: %llu\n" \
+-                       "      ino:     %u\n" \
+-                       "      size:    %llu\n" \
+-                       "      mode:    0%o\n" \
+-                       "      atime:   %s\n" \
+-                       "      mtime:   %s\n" \
+-                       "      ctime:   %s\n" \
+-                       "      hash:    0x%x\n" \
+-                       "      len:     %d\n" \
+-                       "      name:    %s\n",
+-               dc, dc->flags, dc->jiffies,
+-               dc->ino, dc->size, dc->mode,
+-               atime_buf, mtime_buf, ctime_buf,
+-               dc->hash, dc->nameLen, dc->name);
+-         }
+-      }
+-   }
+-   up( &InodeList_lock );
+-
+-   pfunc("Inodes: %d(%d) DirCache: %d(%d)\n", InodeCount, icnt, DCCount, dccnt );
+-   
+-}
+-
+-module_init(init_novfs)
+-module_exit(exit_novfs)
+-
+-MODULE_LICENSE("GPL");
+-MODULE_AUTHOR("Novell Inc.");
+-MODULE_DESCRIPTION("Novell NetWare Client for Linux");
+-MODULE_VERSION( NOVFS_VERSION_STRING );
+diff -uNr src.old/novfs/m src/novfs/m
+--- src.old/novfs/m	2006-07-11 21:24:18.000000000 +0200
++++ src/novfs/m	1970-01-01 01:00:00.000000000 +0100
+@@ -1,12 +0,0 @@
+-#!/bin/sh
+-
+-VERSION=`uname -r`
+-
+-make -C /usr/src/linux SUBDIRS=$PWD modules
+-
+-if [ -e novfs.ko ]
+-then
+-	mkdir -p -m 755 /lib/modules/$VERSION/kernel/fs/novfs
+-	echo "copying novfs.ko to /lib/modules/$VERSION/kernel/fs/novfs"
+-	cp novfs.ko /lib/modules/$VERSION/kernel/fs/novfs
+-fi
+diff -uNr src.old/novfs/mk_novfs src/novfs/mk_novfs
+--- src.old/novfs/mk_novfs	2006-07-11 21:24:18.000000000 +0200
++++ src/novfs/mk_novfs	1970-01-01 01:00:00.000000000 +0100
+@@ -1,113 +0,0 @@
+-#!/bin/sh
+-
+-RVAL=1
+-TO_BUILD=1
+-
+-BUILD_TYPE=modules
+-
+-if [ $1 ]
+-then
+-	if [ "$1" = "force" ]
+-	then
+-		FORCE=1
+-	else
+-		BUILD_TYPE=$1
+-		FORCE=0
+-	fi
+-else
+-	FORCE=0
+-fi
+-
+-
+-if [ -d /usr/src/linux-obj/i386 ]
+-then
+-    for i in $(ls /usr/src/linux-obj/i386) 
+-    do
+-		TO_BUILD=1
+-    	VERSION=`cat /usr/src/linux-obj/i386/$i/include/linux/version.h |grep UTS_RELEASE |awk '{printf("%s\n", substr($3, 2,length($3)-2))}'`
+-		NOVFS_PATH=/lib/modules/$VERSION/kernel/fs/novfs
+-
+-    	if [ -e /lib/modules/$VERSION/extra/novfs.ko ]
+-    	then
+-			NOVFS_PATH=/lib/modules/$VERSION/extra
+-		
+-    	else
+-	    	if [ -e /lib/modules/$VERSION/updates/novfs.ko ]
+-	    	then
+-				NOVFS_PATH=/lib/modules/$VERSION/updates
+-			
+-			fi
+-		fi
+-
+-		if [ -d /lib/modules/$VERSION ]
+-		then
+-
+-			if [ -e $NOVFS_PATH/novfs.ko ]
+-			then
+-				CUR_NOVFS_VERSION=`od --strings=8 $NOVFS_PATH/novfs.ko |grep version= |awk '{split($2,a,"="); if("version"==a[1]) printf("%s", a[2])}'`
+-				CUR_NOVFS_VFS_MAJOR=`echo $CUR_NOVFS_VERSION |awk '{split($0,a,"."); printf("%d", a[1])}'`
+-				CUR_NOVFS_VFS_MINOR=`echo $CUR_NOVFS_VERSION |awk '{split($0,a,"."); printf("%d", a[2])}'`
+-				CUR_NOVFS_VFS_SUB=`echo $CUR_NOVFS_VERSION |awk '{split($0,a,"."); printf("%d", a[3])}'`
+-				CUR_NOVFS_VFS_RELEASE=`echo $CUR_NOVFS_VERSION |awk '{split($0,a,"-"); printf("%d", a[2])}'`
+-
+-				NOVFS_VFS_MAJOR=`cat Makefile |grep 'NOVFS_VFS_MAJOR =' |awk '{printf("%d", $3)}'`
+-				NOVFS_VFS_MINOR=`cat Makefile |grep 'NOVFS_VFS_MINOR =' |awk '{printf("%d", $3)}'`
+-				NOVFS_VFS_SUB=`cat Makefile |grep 'NOVFS_VFS_SUB =' |awk '{printf("%d", $3)}'`
+-				NOVFS_VFS_RELEASE=`cat Makefile |grep 'NOVFS_VFS_RELEASE =' |awk '{printf("%d", $3)}'`
+-				NOVFS_VFS_VERSION="$NOVFS_VFS_MAJOR.$NOVFS_VFS_MINOR.$NOVFS_VFS_SUB-$NOVFS_VFS_RELEASE"
+-
+-				TO_BUILD=0
+-
+-				if [ $NOVFS_VFS_MAJOR -gt $CUR_NOVFS_VFS_MAJOR ]
+-				then
+-					TO_BUILD=1
+-				else 
+-					if [ $NOVFS_VFS_MAJOR -eq $CUR_NOVFS_VFS_MAJOR ]
+-					then
+-						if [ $NOVFS_VFS_MINOR -gt $CUR_NOVFS_VFS_MINOR ]
+-						then
+-							TO_BUILD=1
+-						else
+-							if [ $NOVFS_VFS_MINOR -eq $CUR_NOVFS_VFS_MINOR ]
+-							then
+-								if [ $NOVFS_VFS_SUB -gt $CUR_NOVFS_VFS_SUB ]
+-								then
+-									TO_BUILD=1
+-								else
+-									if [ $NOVFS_VFS_SUB -eq $CUR_NOVFS_VFS_SUB ]
+-									then
+-										if [ $NOVFS_VFS_RELEASE -gt $CUR_NOVFS_VFS_RELEASE ]
+-										then
+-											TO_BUILD=1
+-										fi
+-									fi
+-								fi
+-							fi
+-						fi
+-					fi
+-				fi
+-			fi
+-
+-			if [ $FORCE -eq 1 ]
+-			then
+-				TO_BUILD=1;
+-			fi
+-
+-			if [ $TO_BUILD -eq 1 ]
+-			then
+-	    		echo Building novfs.ko for $VERSION
+-	    		make -C /usr/src/linux-obj/i386/$i SUBDIRS=$PWD $BUILD_TYPE 
+-	    		RVAL=$?
+-	    		if [ -e novfs.ko ]
+-	    		then
+-	    			mkdir -p -m 755 $NOVFS_PATH
+-	    			echo "copying novfs.ko to $NOVFS_PATH"
+-	    			cp novfs.ko $NOVFS_PATH
+-	    			RVAL=$?
+-	    		fi
+-			fi
+-		fi
+-    done
+-fi
+-exit $RVAL
+-
+diff -uNr src.old/novfs/nwcapi.c src/novfs/nwcapi.c
+--- src.old/novfs/nwcapi.c	2006-07-11 21:24:18.000000000 +0200
++++ src/novfs/nwcapi.c	1970-01-01 01:00:00.000000000 +0100
+@@ -1,2410 +0,0 @@
+-/*++========================================================================
+- * Program Name:     Novell NCP Redirector for Linux
+- * File Name:        nwcapi.c
+- * Version:          v1.00
+- * Author:           James Turner/Richard Williams
+- *
+- * Abstract:         This module contains functions used to interface to
+- *                   the library interface of the daemon.
+- * Notes:
+- * Revision History: 
+- *
+- *
+- * Copyright (C) 2005 Novell, Inc.
+- *
+- * 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 files specific to Linux ]==================================*/
+-
+-/*===[ Include files specific to this module ]============================*/
+-#include <linux/module.h>
+-#include <linux/fs.h>
+-#include <linux/slab.h>
+-#include <linux/list.h>
+-#include <linux/timer.h>
+-#include <linux/poll.h>
+-#include <asm/semaphore.h>
+-#include <asm/uaccess.h>
+-
+-#include "nwcapi.h"
+-#include "nwerror.h"
+-#include "commands.h"
+-
+-#include "vfs.h"
+-
+-/*===[ External data ]====================================================*/
+-
+-/*===[ External prototypes ]==============================================*/
+-
+-extern int DbgPrint( char *Fmt, ... );
+-extern void mydump(int size, void *dumpptr);
+-
+-extern session_t Scope_Get_SessionId( void *Scope );
+-extern int Queue_Daemon_Command(void *request, u_long reqlen, void *data, int dlen, void **reply, u_long *replen, int interruptible);
+-
+-extern int do_login(NclString *Server, NclString *Username, NclString *Password, u_long *lgnId, session_t Session);
+-
+-void	GetUserData(NwcScanConnInfo *connInfo, PXPLAT_CALL_REQUEST cmd, PXPLAT_CALL_REPLY reply);
+-void	GetConnData(NwcGetConnInfo *connInfo, PXPLAT_CALL_REQUEST cmd, PXPLAT_CALL_REPLY reply);
+-
+-/*===[ Manifest constants ]===============================================*/
+-
+-/*===[ Type definitions ]=================================================*/
+-
+-/*===[ Function prototypes ]==============================================*/
+-
+-/*===[ Global variables ]=================================================*/
+-
+-/*===[ Code ]=============================================================*/
+-
+-/*++======================================================================*/
+-
+-/*++======================================================================*/
+-int NwOpenConnByName(PXPLAT pdata, u_long *Handle, session_t Session)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-PXPLAT_CALL_REQUEST		cmd;
+-PXPLAT_CALL_REPLY		reply;
+-PNwdCOpenConnByName	  	openConn, connReply;
+-NwcOpenConnByName 		ocbn;
+-u_long			retCode = 0, cmdlen, datalen, replylen, cpylen;
+-char					*data;
+-
+-	cpylen = copy_from_user(&ocbn, pdata->reqData, sizeof(ocbn));
+-	datalen = sizeof(*openConn) + strlen_user(ocbn.pName->pString) + strlen_user(ocbn.pServiceType);
+-	cmdlen = datalen + sizeof(*cmd);
+-	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-
+-	if (cmd)
+-	{
+-		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-		cmd->Command.SequenceNumber = 0;
+-		cmd->Command.SessionId      = Session;
+-		cmd->NwcCommand = NWC_OPEN_CONN_BY_NAME;
+-
+-		cmd->dataLen = datalen;
+-		openConn = (PNwdCOpenConnByName)cmd->data;					  
+-
+-		openConn->nameLen = strlen_user(ocbn.pName->pString);
+-		openConn->serviceLen = strlen_user(ocbn.pServiceType);
+-		openConn->uConnFlags = ocbn.uConnFlags;
+-		openConn->ConnHandle = ocbn.ConnHandle;
+-		data = (char *)openConn;
+-		data += sizeof(*openConn);
+-		openConn->oName = sizeof(*openConn);
+-
+-		openConn->oServiceType = openConn->oName + openConn->nameLen;
+-		cpylen = copy_from_user(data, ocbn.pName->pString, openConn->nameLen);
+-		data += openConn->nameLen;
+-		cpylen = copy_from_user(data, ocbn.pServiceType, openConn->serviceLen);
+-
+-		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+-		if (reply)
+-		{
+-			/*
+-			 * we got reply data from the daemon
+-          */
+-			connReply = (PNwdCOpenConnByName)reply->data;
+-			retCode = reply->Reply.ErrorCode;
+-			if (!retCode)
+-			{
+-				/*
+-				 * we got valid data.
+-             */
+-				connReply = (PNwdCOpenConnByName)reply->data;
+-                ocbn.RetConnHandle = connReply->newConnHandle;
+-                *Handle = connReply->newConnHandle;
+-				cpylen = copy_to_user(pdata->reqData, &ocbn, sizeof(ocbn));
+-				DbgPrint("New Conn Handle = %X\n", connReply->newConnHandle);
+-			}
+-			Novfs_Free(reply);
+-		}
+-
+-		Novfs_Free(cmd);
+-	}
+-
+-	return((int)retCode);
+-
+-}
+-
+-/*++======================================================================*/
+-int NwOpenConnByAddr(PXPLAT pdata, u_long *Handle, session_t Session)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-PXPLAT_CALL_REQUEST		cmd;
+-PXPLAT_CALL_REPLY		reply;
+-PNwdCOpenConnByAddr	  	openConn, connReply;
+-NwcOpenConnByAddr 		ocba;
+-NwcTranAddr            tranAddr;
+-u_long			retCode = 0, cmdlen, datalen, replylen, cpylen;
+-char                 addr[MAX_ADDRESS_LENGTH];
+-
+-	cpylen = copy_from_user(&ocba, pdata->reqData, sizeof(ocba));
+-	datalen = sizeof(*openConn);
+-	cmdlen = datalen + sizeof(*cmd);
+-	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-
+-	if (cmd)
+-	{
+-		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-		cmd->Command.SequenceNumber = 0;
+-		cmd->Command.SessionId      = Session;
+-		cmd->NwcCommand 			= NWC_OPEN_CONN_BY_ADDRESS;
+-		cmd->dataLen 				= datalen;
+-		openConn 					= (PNwdCOpenConnByAddr)cmd->data;
+-
+-		cpylen = copy_from_user(&tranAddr, ocba.pTranAddr, sizeof(tranAddr));
+-
+-	   DbgPrint("NwOpenConnByAddr: tranAddr\n");
+-      mydump(sizeof(tranAddr), &tranAddr);
+-
+-      openConn->TranAddr.uTransportType = tranAddr.uTransportType;
+-      openConn->TranAddr.uAddressLength = tranAddr.uAddressLength;
+-      memset(addr, 0xcc, sizeof(addr)-1);
+-
+-      cpylen = copy_from_user(addr, tranAddr.puAddress, tranAddr.uAddressLength);
+-
+-	   DbgPrint("NwOpenConnByAddr: addr\n");
+-      mydump(sizeof(addr), addr);
+-      
+-      openConn->TranAddr.oAddress = *(u_long *)(&addr[2]);
+-
+-		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+-		if (reply)
+-		{
+-			/*
+-			 * we got reply data from the daemon
+-          */
+-			connReply = (PNwdCOpenConnByAddr)reply->data;
+-			retCode = reply->Reply.ErrorCode;
+-			if (!retCode)
+-			{
+-				/*
+-				 * we got valid data.
+-             */
+-				connReply = (PNwdCOpenConnByAddr)reply->data;
+-				ocba.ConnHandle = connReply->ConnHandle;
+-            *Handle = connReply->ConnHandle;
+-				cpylen = copy_to_user(pdata->reqData, &ocba, sizeof(ocba));
+-				DbgPrint("New Conn Handle = %X\n", connReply->ConnHandle);
+-			}
+-			Novfs_Free(reply);
+-		}
+-
+-		Novfs_Free(cmd);
+-	}
+-
+-	return(retCode);
+-
+-}
+-
+-/*++======================================================================*/
+-int NwOpenConnByRef(PXPLAT pdata, u_long *Handle, session_t Session)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-PXPLAT_CALL_REQUEST		cmd;
+-PXPLAT_CALL_REPLY		reply;
+-PNwdCOpenConnByRef	  	openConn;
+-NwcOpenConnByReference 	ocbr;
+-u_long			retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+-
+-	
+-	cpylen = copy_from_user(&ocbr, pdata->reqData, sizeof(ocbr));
+-	datalen = sizeof(*openConn);
+-	cmdlen = datalen + sizeof(*cmd);
+-	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-	if (cmd)
+-	{
+-		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-		cmd->Command.SequenceNumber = 0;
+-		cmd->Command.SessionId      = Session;
+-		cmd->NwcCommand 			= NWC_OPEN_CONN_BY_REFERENCE;
+-		cmd->dataLen 				= datalen;
+-		openConn 					= (PNwdCOpenConnByRef)cmd->data;
+-
+-		memcpy(openConn, &ocbr, sizeof(ocbr));
+-		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+-		if (reply)
+-		{
+-			/*
+-			 * we got reply data from the daemon
+-          */
+-			openConn = (PNwdCOpenConnByRef)reply->data;
+-			retCode = reply->Reply.ErrorCode;
+-			if (!retCode)
+-			{
+-				/*
+-				 * we got valid data.
+-             */
+-				ocbr.ConnHandle = openConn->ConnHandle;
+-            *Handle = openConn->ConnHandle;
+-
+-				cpylen = copy_to_user(pdata->reqData, &ocbr, sizeof(ocbr));
+-				DbgPrint("New Conn Handle = %X\n", openConn->ConnHandle);
+-			}
+-			Novfs_Free(reply);
+-		}
+-
+-		Novfs_Free(cmd);
+-	}
+-	return(retCode);
+-
+-}
+-
+-/*++======================================================================*/
+-int NwRawSend(PXPLAT pdata, session_t Session)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-NwcRequest           xRequest;
+-PNwcFrag             frag, cFrag, reqFrag;
+-PXPLAT_CALL_REQUEST  cmd;
+-PXPLAT_CALL_REPLY    reply;
+-u_long               retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+-u_long               x, totalLen;
+-PNwdCNCPReq          ncpData;
+-PNwdCNCPRep          ncpReply;
+-u_char               *reqData;
+-unsigned long        actualReplyLength=0;
+-
+-	DbgPrint("[XPLAT] Process Raw NCP Send\n");
+-	cpylen = copy_from_user(&xRequest, pdata->reqData, sizeof(xRequest));
+-
+-	/*
+-	 * Figure out the length of the request
+-    */
+-	frag = Novfs_Malloc(xRequest.uNumReplyFrags * sizeof(NwcFrag), GFP_KERNEL);
+-
+-	DbgPrint("[XPLAT RawNCP] - Reply Frag Count 0x%X\n", xRequest.uNumReplyFrags);
+-
+-	if (!frag)
+-		return(retCode);		
+-
+-	cpylen = copy_from_user(frag, xRequest.pReplyFrags, xRequest.uNumReplyFrags * sizeof(NwcFrag));
+-	totalLen = 0;
+-
+-	cFrag = frag;
+-	for (x = 0; x < xRequest.uNumReplyFrags; x ++)
+-	{
+-		DbgPrint("[XPLAT - RawNCP] - Frag Len = %d\n", cFrag->uLength);
+-		totalLen += cFrag->uLength;
+-		cFrag++;
+-	}
+-
+-
+-	DbgPrint("[XPLAT - RawNCP] - totalLen = %d\n", totalLen);
+-	datalen = 0;
+-	reqFrag = Novfs_Malloc(xRequest.uNumRequestFrags * sizeof(NwcFrag), GFP_KERNEL);
+-	if (!reqFrag)
+-	{
+-		Novfs_Free(frag);
+-		return(retCode);
+-	}
+-
+-	cpylen = copy_from_user(reqFrag, xRequest.pRequestFrags, xRequest.uNumRequestFrags * sizeof(NwcFrag));
+-	cFrag = reqFrag;
+-	for (x = 0; x < xRequest.uNumRequestFrags; x ++)
+-	{
+-		datalen += cFrag->uLength;
+-		cFrag++;
+-	}
+-
+-	/*
+-	 * Allocate the cmd Request
+-    */
+-	cmdlen = datalen + sizeof(*cmd) + sizeof(*ncpData);
+-	DbgPrint("[XPLAT RawNCP] - Frag Count 0x%X\n", xRequest.uNumRequestFrags);
+-	DbgPrint("[XPLAT RawNCP] - Total Command Data Len = %x\n", cmdlen);	
+-
+-	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-	if (cmd)
+-	{
+-		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-		cmd->Command.SequenceNumber = 0;
+-		cmd->Command.SessionId      = Session;
+-		cmd->NwcCommand = NWC_RAW_NCP_REQUEST;
+-
+-		/*
+-		 * build the NCP Request
+-       */
+-		cmd->dataLen = cmdlen - sizeof(*cmd);
+-		ncpData = (PNwdCNCPReq)cmd->data;
+-		ncpData->replyLen = totalLen;
+-		ncpData->requestLen = datalen;
+-		ncpData->ConnHandle = xRequest.ConnHandle;
+-		ncpData->function = xRequest.uFunction;
+-
+-
+-		reqData = ncpData->data;
+-		cFrag = reqFrag;
+-
+-		for (x = 0; x < xRequest.uNumRequestFrags; x ++)
+-		{
+-			cpylen = copy_from_user(reqData, cFrag->pData, cFrag->uLength);
+-			reqData += cFrag->uLength;
+-			cFrag++;
+-		}
+-
+-		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+-		DbgPrint("RawNCP - reply = %x\n", reply);	
+-		DbgPrint("RawNCP - retCode = %x\n", retCode);	
+-
+-		if (reply)
+-		{
+-			/*
+-			 * we got reply data from the daemon
+-          */
+-			ncpReply = (PNwdCNCPRep)reply->data;
+-			retCode = reply->Reply.ErrorCode;
+-
+-			DbgPrint("RawNCP - Reply Frag Count 0x%X\n", xRequest.uNumReplyFrags);
+-
+-			/*
+-			 * We need to copy the reply frags to the packet.
+-          */
+-			reqData = ncpReply->data;
+-			cFrag = frag;
+-
+-			totalLen = ncpReply->replyLen;
+-			for (x = 0; x < xRequest.uNumReplyFrags; x ++)
+-			{
+-		
+-				DbgPrint("RawNCP - Copy Frag %d: 0x%X\n", x, cFrag->uLength);
+-
+-            datalen = min(cFrag->uLength, totalLen);
+-						
+-				cpylen = copy_to_user(cFrag->pData, reqData, datalen);
+-				totalLen -= datalen;
+-				reqData += datalen;
+-            actualReplyLength += datalen;
+-
+-				cFrag++;
+-			}
+-
+-			Novfs_Free(reply);
+-		}
+-      else
+-      {
+-         retCode = -EIO;
+-      }
+-		
+-		Novfs_Free(cmd);
+-	}
+-   xRequest.uActualReplyLength = actualReplyLength;
+-	cpylen = copy_to_user(pdata->reqData, &xRequest, sizeof(xRequest));
+-
+-	Novfs_Free(reqFrag);
+-	Novfs_Free(frag);
+-
+-	return(retCode);		
+-}
+-
+-/*++======================================================================*/
+-int NwConnClose(PXPLAT pdata, u_long *Handle, session_t Session)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-PXPLAT_CALL_REQUEST		cmd;
+-PXPLAT_CALL_REPLY		reply;
+-NwcCloseConn			cc;
+-PNwdCCloseConn			nwdClose;
+-u_long			retCode = 0, cmdlen, datalen, replylen, cpylen;
+-
+-	cpylen = copy_from_user(&cc, pdata->reqData, sizeof(cc));
+-
+-	datalen = sizeof(*nwdClose);
+-	cmdlen = datalen + sizeof(*cmd);
+-	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-	if (cmd)
+-	{
+-		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-		cmd->Command.SequenceNumber = 0;
+-		cmd->Command.SessionId      = Session;
+-		cmd->NwcCommand = NWC_CLOSE_CONN;
+-
+-		nwdClose = (PNwdCCloseConn)cmd->data;
+-		cmd->dataLen = sizeof(*nwdClose);
+-		nwdClose->ConnHandle = cc.ConnHandle;
+-      *Handle = cc.ConnHandle;
+-
+-		/*
+-		 * send the request
+-       */
+-		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, 0);
+-		if (reply)
+-		{
+-			retCode = reply->Reply.ErrorCode;
+-			Novfs_Free(reply);
+-		}
+-		Novfs_Free(cmd);
+-
+-	}
+-
+-	return(retCode);		
+-
+-}
+-
+-/*++======================================================================*/
+-int NwSysConnClose(PXPLAT pdata, u_long *Handle, session_t Session)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-PXPLAT_CALL_REQUEST		cmd;
+-PXPLAT_CALL_REPLY		reply;
+-NwcCloseConn			cc;
+-PNwdCCloseConn			nwdClose;
+-u_long			retCode = 0, cmdlen, datalen, replylen, cpylen;
+-
+-	cpylen = copy_from_user(&cc, pdata->reqData, sizeof(cc));
+-
+-	datalen = sizeof(*nwdClose);
+-	cmdlen = datalen + sizeof(*cmd);
+-	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-	if (cmd)
+-	{
+-		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-		cmd->Command.SequenceNumber = 0;
+-		cmd->Command.SessionId      = Session;
+-		cmd->NwcCommand = NWC_SYS_CLOSE_CONN;
+-
+-		nwdClose = (PNwdCCloseConn)cmd->data;
+-		cmd->dataLen = sizeof(*nwdClose);
+-		nwdClose->ConnHandle = cc.ConnHandle;
+-      *Handle = cc.ConnHandle;
+-
+-		/*
+-		 * send the request
+-       */
+-		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, 0);
+-		if (reply)
+-		{
+-			retCode = reply->Reply.ErrorCode;
+-			Novfs_Free(reply);
+-		}
+-		Novfs_Free(cmd);
+-
+-	}
+-
+-	return(retCode);		
+-
+-}
+-
+-/*++======================================================================*/
+-int	NwLoginIdentity(PXPLAT pdata, session_t Session)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-NwcLoginIdentity	lgn, *plgn;
+-int retCode = -ENOMEM;
+-NclString  server;
+-NclString  username;
+-NclString  password;
+-u_long cpylen;
+-NwcString nwcStr;
+-
+-	cpylen = copy_from_user(&lgn, pdata->reqData, sizeof(lgn));
+-
+-   DbgPrint("NwLoginIdentity:\n");
+-   mydump(sizeof(lgn), &lgn);
+-
+-
+-
+-   cpylen = copy_from_user(&nwcStr, lgn.pDomainName, sizeof(nwcStr));
+-   DbgPrint("NwLoginIdentity: DomainName\n");
+-   mydump(sizeof(nwcStr), &nwcStr);
+-
+-	if ( (server.buffer = Novfs_Malloc(nwcStr.DataLen, GFP_KERNEL)) )
+-	{
+-		server.type = nwcStr.DataType;
+-      server.len  = nwcStr.DataLen;
+-		if ( !copy_from_user((void *)server.buffer, nwcStr.pBuffer, server.len) )
+-		{
+-         DbgPrint("NwLoginIdentity: Server\n");
+-         mydump(server.len, server.buffer);
+-         
+-         cpylen = copy_from_user(&nwcStr, lgn.pObjectName, sizeof(nwcStr));
+-         DbgPrint("NwLoginIdentity: ObjectName\n");
+-         mydump(sizeof(nwcStr), &nwcStr);
+-
+-			if ( (username.buffer = Novfs_Malloc(nwcStr.DataLen, GFP_KERNEL)) )
+-			{
+-				username.type = nwcStr.DataType;
+-            username.len  = nwcStr.DataLen;
+-				if ( !copy_from_user((void *)username.buffer, nwcStr.pBuffer, username.len) )
+-				{
+-               DbgPrint("NwLoginIdentity: User\n");
+-               mydump(username.len, username.buffer);
+-               
+-               cpylen = copy_from_user(&nwcStr, lgn.pPassword, sizeof(nwcStr));
+-               DbgPrint("NwLoginIdentity: Password\n");
+-               mydump(sizeof(nwcStr), &nwcStr);
+-
+-					if ( (password.buffer = Novfs_Malloc(nwcStr.DataLen, GFP_KERNEL)) )
+-					{
+-						password.type = nwcStr.DataType;
+-						password.len  = nwcStr.DataLen;
+-						if ( !copy_from_user((void *)password.buffer, nwcStr.pBuffer, password.len) )
+-						{
+-							retCode = do_login(&server, &username, &password, (u_long *)&lgn.AuthenticationId, Session);
+-                            if (retCode)
+-                            {
+-                                lgn.AuthenticationId = 0;
+-                            }
+-
+-                            plgn = (NwcLoginIdentity *)pdata->reqData;
+-                            cpylen = copy_to_user(&plgn->AuthenticationId, &lgn.AuthenticationId, sizeof(plgn->AuthenticationId));
+-
+-						}
+-                  memset(password.buffer, 0, password.len);
+-						Novfs_Free(password.buffer);
+-					}
+-				}
+-            memset(username.buffer, 0, username.len);
+-				Novfs_Free(username.buffer);
+-			}
+-		}
+-		Novfs_Free(server.buffer);
+-	}
+-	return(retCode);
+-}
+-
+-/*++======================================================================*/
+-int	NwAuthConnWithId(PXPLAT pdata, session_t Session)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-NwcAuthenticateWithId 	pauth;
+-PNwdCAuthenticateWithId pDauth;
+-PXPLAT_CALL_REQUEST		cmd;
+-PXPLAT_CALL_REPLY		reply;
+-u_long			retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+-
+-	datalen = sizeof(*pDauth);
+-	cmdlen = datalen + sizeof(*cmd);
+-	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-
+-	if (cmd)
+-	{
+-		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-		cmd->Command.SequenceNumber = 0;
+-		cmd->Command.SessionId      = Session;
+-		cmd->NwcCommand = NWC_AUTHENTICATE_CONN_WITH_ID;
+-
+-
+-		cpylen = copy_from_user(&pauth, pdata->reqData, sizeof(pauth));
+-
+-		pDauth = (PNwdCAuthenticateWithId)cmd->data;
+-		cmd->dataLen = datalen;
+-		pDauth->AuthenticationId = pauth.AuthenticationId;
+-		pDauth->ConnHandle = pauth.ConnHandle;
+-
+-		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+-		if (reply)
+-		{
+-			retCode = reply->Reply.ErrorCode;
+-			Novfs_Free(reply);
+-		}
+-		Novfs_Free(cmd);
+-	}
+-	return(retCode);
+-}
+-
+-/*++======================================================================*/
+-int	NwLicenseConn(PXPLAT pdata, session_t Session)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-PXPLAT_CALL_REQUEST		cmd;
+-PXPLAT_CALL_REPLY		reply;
+-NwcLicenseConn			lisc;
+-PNwdCLicenseConn		pDLisc;
+-u_long			retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+-
+-	datalen = sizeof(*pDLisc);
+-	cmdlen = datalen + sizeof(*cmd);
+-	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-
+-	if (cmd)
+-	{
+-		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-		cmd->Command.SequenceNumber = 0;
+-		cmd->Command.SessionId      = Session;
+-		cmd->NwcCommand = NWC_LICENSE_CONN;
+-
+-
+-		cpylen = copy_from_user(&lisc, pdata->reqData, sizeof(lisc));
+-
+-		pDLisc = (PNwdCLicenseConn)cmd->data;
+-		cmd->dataLen = datalen;
+-		pDLisc->ConnHandle = lisc.ConnHandle;
+-
+-		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+-		if (reply)
+-		{
+-			retCode = reply->Reply.ErrorCode;
+-			Novfs_Free(reply);
+-		}
+-		Novfs_Free(cmd);
+-	}
+-	return(retCode);
+-}
+-
+-
+-/*++======================================================================*/
+-int	NwLogoutIdentity(PXPLAT pdata, session_t Session)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-PXPLAT_CALL_REQUEST		cmd;
+-PXPLAT_CALL_REPLY		reply;
+-NwcLogoutIdentity		logout;
+-PNwdCLogoutIdentity		pDLogout;
+-u_long			retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+-
+-	datalen = sizeof(*pDLogout);
+-	cmdlen = datalen + sizeof(*cmd);
+-	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-
+-	if (cmd)
+-	{
+-		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-		cmd->Command.SequenceNumber = 0;
+-		cmd->Command.SessionId      = Session;
+-		cmd->NwcCommand = NWC_LOGOUT_IDENTITY;
+-
+-		cpylen = copy_from_user(&logout, pdata->reqData, sizeof(logout));
+-
+-		pDLogout = (PNwdCLogoutIdentity)cmd->data;
+-		cmd->dataLen = datalen;
+-		pDLogout->AuthenticationId = logout.AuthenticationId;
+-
+-		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+-		if (reply)
+-		{
+-			retCode = reply->Reply.ErrorCode;
+-			Novfs_Free(reply);
+-		}
+-		Novfs_Free(cmd);
+-	}
+-	return(retCode);
+-}
+-
+-/*++======================================================================*/
+-int	NwUnlicenseConn(PXPLAT pdata, session_t Session)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-PXPLAT_CALL_REQUEST		cmd;
+-PXPLAT_CALL_REPLY		reply;
+-PNwdCUnlicenseConn		pUconn;
+-NwcUnlicenseConn 		ulc;
+-u_long			retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+-
+-	
+-	cpylen = copy_from_user(&ulc, pdata->reqData, sizeof(ulc));
+-	datalen = sizeof(*pUconn);
+-	cmdlen = datalen + sizeof(*cmd);
+-	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-	if (cmd)
+-	{
+-		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-		cmd->Command.SequenceNumber = 0;
+-		cmd->Command.SessionId      = Session;
+-		cmd->NwcCommand 			= NWC_UNLICENSE_CONN;
+-		cmd->dataLen 				= datalen;
+-		pUconn 						= (PNwdCUnlicenseConn)cmd->data;
+-
+-		pUconn->ConnHandle = ulc.ConnHandle;
+-		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+-		if (reply)
+-		{
+-			/*
+-			 * we got reply data from the daemon
+-          */
+-			retCode = reply->Reply.ErrorCode;
+-			Novfs_Free(reply);
+-		}
+-
+-		Novfs_Free(cmd);
+-	}
+-	return(retCode);
+-
+-}
+-
+-
+-/*++======================================================================*/
+-int	NwUnAuthenticate(PXPLAT pdata, session_t Session)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-PXPLAT_CALL_REQUEST		cmd;
+-PXPLAT_CALL_REPLY		reply;
+-NwcUnauthenticate		auth;
+-PNwdCUnauthenticate		pDAuth;
+-u_long			retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+-
+-	datalen = sizeof(*pDAuth);
+-	cmdlen = datalen + sizeof(*cmd);
+-	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-
+-	if (cmd)
+-	{
+-		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-		cmd->Command.SequenceNumber = 0;
+-		cmd->Command.SessionId      = Session;
+-		cmd->NwcCommand = NWC_UNAUTHENTICATE_CONN;
+-
+-		cpylen = copy_from_user(&auth, pdata->reqData, sizeof(auth));
+-
+-		pDAuth = (PNwdCUnauthenticate)cmd->data;
+-		cmd->dataLen = datalen;
+-		pDAuth->AuthenticationId = auth.AuthenticationId;
+-		pDAuth->ConnHandle = auth.ConnHandle;
+-
+-		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+-		if (reply)
+-		{
+-			retCode = reply->Reply.ErrorCode;
+-			Novfs_Free(reply);
+-		}
+-		Novfs_Free(cmd);
+-	}
+-	return(retCode);
+-
+-}
+-
+-
+-/*++======================================================================*/
+-int	NwGetConnInfo(PXPLAT pdata, session_t Session)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-PXPLAT_CALL_REQUEST		cmd;
+-PXPLAT_CALL_REPLY		reply;
+-NwcGetConnInfo			connInfo;
+-PNwdCGetConnInfo		pDConnInfo;
+-u_long			retCode = -ENOMEM, cmdlen, replylen, cpylen;
+-
+-	cmdlen = sizeof(*cmd) + sizeof(*pDConnInfo);
+-	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-	cpylen = copy_from_user(&connInfo, pdata->reqData, sizeof(NwcGetConnInfo));
+-
+-	if (cmd)
+-	{
+-		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-		cmd->Command.SequenceNumber = 0;
+-		cmd->Command.SessionId      = Session;
+-		cmd->NwcCommand = NWC_GET_CONN_INFO;
+-		
+-		pDConnInfo = (PNwdCGetConnInfo)cmd->data;
+-
+-		pDConnInfo->ConnHandle = connInfo.ConnHandle;
+-		pDConnInfo->uInfoLevel = connInfo.uInfoLevel;
+-		pDConnInfo->uInfoLength = connInfo.uInfoLength;
+-		cmd->dataLen = sizeof(*pDConnInfo);
+-
+-		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+-		if (reply)
+-		{
+-			retCode = reply->Reply.ErrorCode;
+-			GetConnData(&connInfo, cmd, reply);
+-
+-			Novfs_Free(reply);
+-		}
+-		Novfs_Free(cmd);
+-
+-	}
+-
+-	return(retCode);
+-
+-}
+-
+-
+-/*++======================================================================*/
+-int	NwSetConnInfo(PXPLAT pdata, session_t Session)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-PXPLAT_CALL_REQUEST		cmd;
+-PXPLAT_CALL_REPLY		reply;
+-NwcSetConnInfo			connInfo;
+-PNwdCSetConnInfo		pDConnInfo;
+-u_long			retCode = -ENOMEM, cmdlen, replylen, cpylen;
+-
+-	cmdlen = sizeof(*cmd) + sizeof(*pDConnInfo);
+-	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-	cpylen = copy_from_user(&connInfo, pdata->reqData, sizeof(NwcSetConnInfo));
+-
+-	if (cmd)
+-	{
+-		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-		cmd->Command.SequenceNumber = 0;
+-		cmd->Command.SessionId      = Session;
+-		cmd->NwcCommand = NWC_SET_CONN_INFO;
+-		
+-		pDConnInfo = (PNwdCSetConnInfo)cmd->data;
+-
+-		pDConnInfo->ConnHandle = connInfo.ConnHandle;
+-		pDConnInfo->uInfoLevel = connInfo.uInfoLevel;
+-		pDConnInfo->uInfoLength = connInfo.uInfoLength;
+-		cmd->dataLen = sizeof(*pDConnInfo);
+-
+-		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+-		if (reply)
+-		{
+-			retCode = reply->Reply.ErrorCode;
+-			Novfs_Free(reply);
+-		}
+-		Novfs_Free(cmd);
+-
+-	}
+-
+-	return(retCode);
+-
+-}
+-
+-/*++======================================================================*/
+-int	NwGetIdentityInfo(PXPLAT pdata, session_t Session)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-PXPLAT_CALL_REQUEST		cmd;
+-PXPLAT_CALL_REPLY		reply;
+-NwcGetIdentityInfo		qidInfo, *gId;
+-PNwdCGetIdentityInfo	idInfo;
+-NwcString				xferStr;
+-char					*str;
+-u_long			retCode = -ENOMEM, cmdlen, replylen, cpylen;
+-
+-	cmdlen = sizeof(*cmd) + sizeof(*idInfo);
+-	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-	cpylen = copy_from_user(&qidInfo, pdata->reqData, sizeof(qidInfo));
+-
+-	if (cmd)
+-	{
+-		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-		cmd->Command.SequenceNumber = 0;
+-		cmd->Command.SessionId      = Session;
+-		cmd->NwcCommand = NWC_GET_IDENTITY_INFO;
+-		
+-		idInfo = (PNwdCGetIdentityInfo)cmd->data;
+-
+-		idInfo->AuthenticationId = qidInfo.AuthenticationId;
+-		cmd->dataLen = sizeof(*idInfo);
+-
+-		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+-		if (reply)
+-		{
+-			retCode = reply->Reply.ErrorCode;
+-	
+-            if (!reply->Reply.ErrorCode)
+-            {
+-			    /*
+-			     * Save the return info to the user structure.
+-              */
+-			    gId = pdata->reqData;
+-			    idInfo = (PNwdCGetIdentityInfo)reply->data;
+-			    cpylen = copy_to_user(&gId->AuthenticationId, &idInfo->AuthenticationId, sizeof(idInfo->AuthenticationId));
+-			    cpylen = copy_to_user(&gId->AuthType, &idInfo->AuthType, sizeof(idInfo->AuthType));
+-			    cpylen = copy_to_user(&gId->IdentityFlags, &idInfo->IdentityFlags, sizeof(idInfo->IdentityFlags));
+-			    cpylen = copy_to_user(&gId->NameType, &idInfo->NameType, sizeof(idInfo->NameType));
+-			    cpylen = copy_to_user(&gId->ObjectType, &idInfo->ObjectType, sizeof(idInfo->ObjectType));
+-
+-			    cpylen = copy_from_user(&xferStr, gId->pDomainName, sizeof(NwcString));
+-			    str = (char *)((char *)reply->data + idInfo->pDomainNameOffset);
+-			    cpylen = copy_to_user(xferStr.pBuffer, str, idInfo->domainLen);
+-			    xferStr.DataType = NWC_STRING_TYPE_ASCII;
+-			    xferStr.DataLen = idInfo->domainLen;
+-			    cpylen = copy_to_user(gId->pDomainName, &xferStr, sizeof(NwcString));
+-
+-
+-			    cpylen = copy_from_user(&xferStr, gId->pObjectName, sizeof(NwcString));
+-			    str = (char *)((char *)reply->data + idInfo->pObjectNameOffset);
+-			    cpylen = copy_to_user(xferStr.pBuffer, str, idInfo->objectLen);
+-			    xferStr.DataLen = idInfo->objectLen - 1;
+-			    xferStr.DataType = NWC_STRING_TYPE_ASCII;
+-			    cpylen = copy_to_user(gId->pObjectName, &xferStr, sizeof(NwcString));
+-            }
+-
+-			Novfs_Free(reply);
+-		}
+-		Novfs_Free(cmd);
+-
+-	}
+-
+-	return(retCode);
+-}
+-
+-/*++======================================================================*/
+-int	NwScanConnInfo(PXPLAT pdata, session_t Session)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-PXPLAT_CALL_REQUEST		cmd;
+-PXPLAT_CALL_REPLY		reply;
+-NwcScanConnInfo			connInfo, *rInfo;
+-PNwdCScanConnInfo		pDConnInfo;
+-u_long			retCode = -ENOMEM, cmdlen, replylen, cpylen;
+-u_char 			*localData;
+-
+-	cpylen = copy_from_user(&connInfo, pdata->reqData, sizeof(NwcScanConnInfo));
+-
+-	cmdlen = sizeof(*cmd) + sizeof(*pDConnInfo) + connInfo.uScanInfoLen;
+-	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-
+-	if (cmd)
+-	{
+-		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-		cmd->Command.SequenceNumber = 0;
+-		cmd->Command.SessionId      = Session;
+-		cmd->NwcCommand = NWC_SCAN_CONN_INFO;
+-		
+-		pDConnInfo = (PNwdCScanConnInfo)cmd->data;
+-
+-		DbgPrint("NwScanConnInfo: Input Data\n");
+-		DbgPrint("connInfo.uScanIndex = 0x%X\n", connInfo.uScanIndex);
+-		DbgPrint("connInfo.uConnectionReference = 0x%X\n", connInfo.uConnectionReference);
+-		DbgPrint("connInfo.uScanInfoLevel = 0x%X\n", connInfo.uScanInfoLevel);
+-		DbgPrint("connInfo.uScanInfoLen = 0x%X\n", connInfo.uScanInfoLen);
+-		DbgPrint("connInfo.uReturnInfoLength = 0x%X\n", connInfo.uReturnInfoLength);
+-		DbgPrint("connInfo.uReturnInfoLevel = 0x%X\n", connInfo.uReturnInfoLevel);
+-		DbgPrint("connInfo.uScanFlags = 0x%X\n", connInfo.uScanFlags);
+-
+-
+-		pDConnInfo->uScanIndex = connInfo.uScanIndex;
+-		pDConnInfo->uConnectionReference = connInfo.uConnectionReference;
+-		pDConnInfo->uScanInfoLevel = connInfo.uScanInfoLevel;
+-		pDConnInfo->uScanInfoLen = connInfo.uScanInfoLen;
+-		pDConnInfo->uReturnInfoLength = connInfo.uReturnInfoLength;
+-		pDConnInfo->uReturnInfoLevel = connInfo.uReturnInfoLevel;
+-		pDConnInfo->uScanFlags = connInfo.uScanFlags;
+-
+-		if (pDConnInfo->uScanInfoLen)
+-		{
+-			localData = (u_char *)pDConnInfo;
+-			pDConnInfo->uScanConnInfoOffset = sizeof(*pDConnInfo);
+-			localData += pDConnInfo->uScanConnInfoOffset;
+-			cpylen = copy_from_user(localData, connInfo.pScanConnInfo, connInfo.uScanInfoLen);
+-		}
+-		else
+-		{
+-			pDConnInfo->uScanConnInfoOffset = 0;
+-		}
+-			
+-
+-		cmd->dataLen = sizeof(*pDConnInfo);
+-
+-		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+-		if (reply)
+-		{
+-			DbgPrint("NwScanConnInfo: Reply recieved\n");
+-			DbgPrint("   NextIndex = %x\n", connInfo.uScanIndex);
+-			DbgPrint("   ErrorCode = %x\n", reply->Reply.ErrorCode);
+-			DbgPrint("   data = %x\n", reply->data);
+-
+-			pDConnInfo = (PNwdCScanConnInfo)reply->data;
+-			retCode = (u_long)reply->Reply.ErrorCode;
+-			if (!retCode)
+-			{
+-				GetUserData(&connInfo, cmd, reply);
+-				rInfo = (NwcScanConnInfo *)pdata->repData;
+-				cpylen = copy_to_user(pdata->repData, &pDConnInfo->uScanIndex, sizeof(pDConnInfo->uScanIndex));
+-				cpylen = copy_to_user(&rInfo->uConnectionReference, &pDConnInfo->uConnectionReference, sizeof(pDConnInfo->uConnectionReference));
+-			}
+-			else
+-			{
+-			u_long x;
+-
+-				x = 0;
+-				rInfo = (NwcScanConnInfo *)pdata->reqData;
+-				cpylen = copy_to_user(&rInfo->uConnectionReference, &x, sizeof(rInfo->uConnectionReference));
+-			}
+-				
+-			Novfs_Free(reply);
+-		}
+-      else
+-      {
+-         retCode = -EIO;
+-      }
+-		Novfs_Free(cmd);
+-
+-	}
+-
+-	return(retCode);
+-}
+-
+-/*++======================================================================*/
+-void	GetUserData(NwcScanConnInfo *connInfo, PXPLAT_CALL_REQUEST cmd, PXPLAT_CALL_REPLY reply)
+-/*
+- *  Abstract:  Copies the user data out of the scan conn info call.
+- *
+- *========================================================================*/
+-
+-{
+-u_long			uLevel;
+-PNwdCScanConnInfo		pDConnInfo;
+-
+-u_char			*srcData = NULL;
+-u_long			dataLen = 0, cpylen;
+-
+-	
+-	pDConnInfo = (PNwdCScanConnInfo)reply->data;
+-	uLevel = pDConnInfo->uReturnInfoLevel;
+-	DbgPrint("[GetUserData] uLevel = %d, reply = 0x%X, reply->data = 0x%X\n", uLevel, reply, reply->data);
+-
+-	switch(uLevel)
+-	{
+-		case NWC_CONN_INFO_RETURN_ALL:
+-		case NWC_CONN_INFO_TRAN_ADDR:
+-		case NWC_CONN_INFO_NDS_STATE:
+-		case NWC_CONN_INFO_MAX_PACKET_SIZE:
+-		case NWC_CONN_INFO_LICENSE_STATE:
+-		case NWC_CONN_INFO_PUBLIC_STATE:
+-		case NWC_CONN_INFO_SERVICE_TYPE:
+-		case NWC_CONN_INFO_DISTANCE:
+-		case NWC_CONN_INFO_SERVER_VERSION:
+-		case NWC_CONN_INFO_AUTH_ID:
+-		case NWC_CONN_INFO_SUSPENDED:
+-		case NWC_CONN_INFO_WORKGROUP_ID:
+-		case NWC_CONN_INFO_SECURITY_STATE:
+-		case NWC_CONN_INFO_CONN_NUMBER:
+-		case NWC_CONN_INFO_USER_ID:
+-		case NWC_CONN_INFO_BCAST_STATE:
+-		case NWC_CONN_INFO_CONN_REF:
+-		case NWC_CONN_INFO_AUTH_STATE:
+-		case NWC_CONN_INFO_TREE_NAME:
+-		case NWC_CONN_INFO_SERVER_NAME:
+-		case NWC_CONN_INFO_VERSION:
+-			srcData = (u_char *)pDConnInfo;
+-			srcData += pDConnInfo->uReturnConnInfoOffset;
+-			dataLen = pDConnInfo->uReturnInfoLength;
+-			break;
+-
+-		case NWC_CONN_INFO_RETURN_NONE:
+-		case NWC_CONN_INFO_TREE_NAME_UNICODE:
+-		case NWC_CONN_INFO_SERVER_NAME_UNICODE:
+-		case NWC_CONN_INFO_LOCAL_TRAN_ADDR:
+-		case NWC_CONN_INFO_ALTERNATE_ADDR:
+-		case NWC_CONN_INFO_SERVER_GUID:
+-		default:
+-		break;
+-	}
+-
+-	if (srcData && dataLen)
+-	{
+-		DbgPrint("Copy Data in GetUserData 0x%X -> 0x%X :: 0x%X\n",
+-						srcData, connInfo->pReturnConnInfo, dataLen);			
+-		cpylen = copy_to_user(connInfo->pReturnConnInfo, srcData, dataLen);
+-	}
+-
+-	return;
+-}
+-
+-/*++======================================================================*/
+-void	GetConnData(NwcGetConnInfo *connInfo, PXPLAT_CALL_REQUEST cmd, PXPLAT_CALL_REPLY reply)
+-/*
+- *  Abstract:  Copies the user data out of the scan conn info call.
+- *
+- *========================================================================*/
+-
+-{
+-u_long			uLevel;
+-PNwdCGetConnInfo		pDConnInfo;
+-
+-u_char			*srcData = NULL;
+-u_long			dataLen = 0, cpylen;
+-
+-	
+-	pDConnInfo = (PNwdCGetConnInfo)cmd->data;
+-	uLevel = pDConnInfo->uInfoLevel;
+-
+-	switch(uLevel)
+-	{
+-		case NWC_CONN_INFO_RETURN_ALL:
+-			srcData = (u_char *)reply->data;
+-			dataLen = reply->dataLen;
+-		break;
+-
+-		case NWC_CONN_INFO_RETURN_NONE:
+-			dataLen = 0;
+-		break;
+-
+-		case NWC_CONN_INFO_TRAN_ADDR:
+-      {
+-         u_char *dstData = connInfo->pConnInfo;
+-         NwcTranAddr tranAddr;
+-
+-         srcData = (u_char *)reply->data;
+-
+-         cpylen = copy_from_user(&tranAddr, dstData, sizeof(tranAddr));
+-         tranAddr.uTransportType = ((PNwdTranAddr)srcData)->uTransportType;
+-         tranAddr.uAddressLength = ((PNwdTranAddr)srcData)->uAddressLength;
+-         cpylen = copy_to_user(dstData, &tranAddr, sizeof(tranAddr));
+-         cpylen = copy_to_user(tranAddr.puAddress, ((PNwdTranAddr)srcData)->Buffer, ((PNwdTranAddr)srcData)->uAddressLength);
+-         dataLen=0;
+-         break;
+-      }
+-		case NWC_CONN_INFO_NDS_STATE:
+-		case NWC_CONN_INFO_MAX_PACKET_SIZE:
+-		case NWC_CONN_INFO_LICENSE_STATE:
+-		case NWC_CONN_INFO_PUBLIC_STATE:
+-		case NWC_CONN_INFO_SERVICE_TYPE:
+-		case NWC_CONN_INFO_DISTANCE:
+-		case NWC_CONN_INFO_SERVER_VERSION:
+-		case NWC_CONN_INFO_AUTH_ID:
+-		case NWC_CONN_INFO_SUSPENDED:
+-		case NWC_CONN_INFO_WORKGROUP_ID:
+-		case NWC_CONN_INFO_SECURITY_STATE:
+-		case NWC_CONN_INFO_CONN_NUMBER:
+-		case NWC_CONN_INFO_USER_ID:
+-		case NWC_CONN_INFO_BCAST_STATE:
+-		case NWC_CONN_INFO_CONN_REF:
+-		case NWC_CONN_INFO_AUTH_STATE:
+-		case NWC_CONN_INFO_VERSION:
+-		case NWC_CONN_INFO_SERVER_NAME:
+-		case NWC_CONN_INFO_TREE_NAME:
+-			srcData = (u_char *)reply->data;
+-			dataLen = reply->dataLen;
+-		break;
+-
+-		case NWC_CONN_INFO_TREE_NAME_UNICODE:
+-		case NWC_CONN_INFO_SERVER_NAME_UNICODE:
+-		break;
+-
+-		case NWC_CONN_INFO_LOCAL_TRAN_ADDR:
+-		break;
+-
+-		case NWC_CONN_INFO_ALTERNATE_ADDR:
+-		break;
+-
+-		case NWC_CONN_INFO_SERVER_GUID:
+-		break;
+-
+-		default:
+-		break;
+-	}
+-
+-	if (srcData && dataLen)
+-	{
+-		cpylen = copy_to_user(connInfo->pConnInfo, srcData, connInfo->uInfoLength);
+-	}
+-
+-	return;
+-}
+-
+-/*++======================================================================*/
+-int	 NwGetDaemonVersion(PXPLAT pdata, session_t Session)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-
+-{
+-PXPLAT_CALL_REQUEST			cmd;
+-PXPLAT_CALL_REPLY			reply;
+-PNwdCGetRequesterVersion	pDVersion;
+-u_long				retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+-
+-	datalen = sizeof(*pDVersion);
+-	cmdlen = datalen + sizeof(*cmd);
+-	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-
+-	if (cmd)
+-	{
+-		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-		cmd->Command.SequenceNumber = 0;
+-		cmd->Command.SessionId      = Session;
+-		cmd->NwcCommand = NWC_GET_REQUESTER_VERSION;
+-		cmdlen = sizeof(*cmd);
+-		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+-		if (reply)
+-		{
+-			retCode = reply->Reply.ErrorCode;
+-			pDVersion = (PNwdCGetRequesterVersion)reply->data;
+-			cpylen = copy_to_user(pDVersion, pdata->reqData, sizeof(*pDVersion));
+-			Novfs_Free(reply);
+-		}
+-		Novfs_Free(cmd);
+-	}
+-	return(retCode);
+-
+-}
+-
+-
+-/*++======================================================================*/
+-int	 NwcGetPreferredDSTree(PXPLAT pdata, session_t Session)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-
+-{
+-PXPLAT_CALL_REQUEST			cmd;
+-PXPLAT_CALL_REPLY			reply;
+-PNwdCGetPreferredDsTree		pDGetTree;
+-NwcGetPreferredDsTree		xplatCall, *p;
+-u_long				retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+-u_char				*dPtr;
+-
+-	cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcGetPreferredDsTree));
+-	datalen = sizeof(*pDGetTree) + xplatCall.uTreeLength;
+-	cmdlen = datalen + sizeof(*cmd);
+-	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-
+-	if (cmd)
+-	{
+-		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-		cmd->Command.SequenceNumber = 0;
+-		cmd->Command.SessionId      = Session;
+-		cmd->NwcCommand = NWC_GET_PREFERRED_DS_TREE;
+-		cmdlen = sizeof(*cmd);
+-
+-		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+-		if (reply)
+-		{
+-			retCode = reply->Reply.ErrorCode;
+-			if (!retCode)
+-			{
+-				pDGetTree = (PNwdCGetPreferredDsTree)reply->data;
+-				dPtr = reply->data + pDGetTree->DsTreeNameOffset;
+-				p = (NwcGetPreferredDsTree *)pdata->reqData;
+-
+-				DbgPrint("NwcGetPreferredDSTree: Reply recieved\n");
+-				DbgPrint("   TreeLen = %x\n", pDGetTree->uTreeLength);
+-				DbgPrint("   TreeName = %s\n", dPtr);
+-
+-				cpylen = copy_to_user(p, &pDGetTree->uTreeLength, 4);
+-				cpylen = copy_to_user(xplatCall.pDsTreeName, dPtr, pDGetTree->uTreeLength);
+-			}
+-         Novfs_Free(reply);
+-		}
+-		Novfs_Free(cmd);
+-	}
+-	return(retCode);
+-
+-}
+-
+-/*++======================================================================*/
+-int	 NwcSetPreferredDSTree(PXPLAT pdata, session_t Session)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-
+-{
+-PXPLAT_CALL_REQUEST			cmd;
+-PXPLAT_CALL_REPLY			reply;
+-PNwdCSetPreferredDsTree		pDSetTree;
+-NwcSetPreferredDsTree		xplatCall;
+-u_long				retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+-u_char				*dPtr;
+-
+-	cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcSetPreferredDsTree));
+-	datalen = sizeof(*pDSetTree) + xplatCall.uTreeLength;
+-	cmdlen = datalen + sizeof(*cmd);
+-	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-
+-	if (cmd)
+-	{
+-		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-		cmd->Command.SequenceNumber = 0;
+-		cmd->Command.SessionId      = Session;
+-		cmd->NwcCommand = NWC_SET_PREFERRED_DS_TREE;
+-
+-		pDSetTree = (PNwdCSetPreferredDsTree)cmd->data;
+-		pDSetTree->DsTreeNameOffset = sizeof(*pDSetTree);
+-		pDSetTree->uTreeLength = xplatCall.uTreeLength;
+-
+-		dPtr = cmd->data + sizeof(*pDSetTree);
+-		cpylen = copy_from_user(dPtr, xplatCall.pDsTreeName, xplatCall.uTreeLength);
+-		
+-
+-		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+-		if (reply)
+-		{
+-         retCode = reply->Reply.ErrorCode;
+-         Novfs_Free(reply);
+-		}
+-		Novfs_Free(cmd);
+-	}
+-	return(retCode);
+-
+-}
+-
+-
+-/*++======================================================================*/
+-int	 NwcSetDefaultNameCtx(PXPLAT pdata, session_t Session)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-
+-{
+-PXPLAT_CALL_REQUEST			cmd;
+-PXPLAT_CALL_REPLY			reply;
+-NwcSetDefaultNameContext	xplatCall;
+-PNwdCSetDefaultNameContext	pDSet;
+-u_long				retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+-u_char				*dPtr;
+-
+-	cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcSetDefaultNameContext));
+-	datalen = sizeof(*pDSet) + xplatCall.uTreeLength + xplatCall.uNameLength;
+-	cmdlen = datalen + sizeof(*cmd);
+-	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-
+-	if (cmd)
+-	{
+-		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-		cmd->Command.SequenceNumber = 0;
+-		cmd->Command.SessionId      = Session;
+-		cmd->NwcCommand = NWC_SET_DEFAULT_NAME_CONTEXT;
+-      cmd->dataLen = sizeof(NwdCSetDefaultNameContext) + xplatCall.uTreeLength + xplatCall.uNameLength;
+-
+-		pDSet = (PNwdCSetDefaultNameContext)cmd->data;
+-      dPtr  = cmd->data;
+-
+-      pDSet->TreeOffset = sizeof(NwdCSetDefaultNameContext);
+-      pDSet->uTreeLength = xplatCall.uTreeLength;
+-      pDSet->NameContextOffset = pDSet->TreeOffset+xplatCall.uTreeLength;
+-      pDSet->uNameLength = xplatCall.uNameLength;
+-
+-      cpylen = copy_from_user(dPtr+pDSet->TreeOffset, xplatCall.pTreeName, xplatCall.uTreeLength);
+-		cpylen = copy_from_user(dPtr+pDSet->NameContextOffset, xplatCall.pNameContext, xplatCall.uNameLength);
+-
+-		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+-		if (reply)
+-		{
+-            retCode = reply->Reply.ErrorCode;
+-            Novfs_Free(reply);
+-		}
+-		Novfs_Free(cmd);
+-	}
+-	return(retCode);
+-
+-}
+-
+-/*++======================================================================*/
+-int	 NwcGetDefaultNameCtx(PXPLAT pdata, session_t Session)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-
+-{
+-PXPLAT_CALL_REQUEST			cmd;
+-PXPLAT_CALL_REPLY			reply;
+-NwcGetDefaultNameContext	xplatCall;
+-PNwdCGetDefaultNameContext pGet;
+-char *dPtr;
+-int retCode = -ENOMEM;
+-u_long cmdlen, replylen, cpylen;
+-
+-	cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcGetDefaultNameContext));
+-	cmdlen = sizeof(*cmd) + sizeof(NwdCGetDefaultNameContext) + xplatCall.uTreeLength;
+-	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-
+-	if (cmd)
+-	{
+-		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-		cmd->Command.SequenceNumber = 0;
+-		cmd->Command.SessionId      = Session;
+-		cmd->NwcCommand = NWC_GET_DEFAULT_NAME_CONTEXT;
+-      cmd->dataLen = sizeof(NwdCGetDefaultNameContext)+xplatCall.uTreeLength;
+-
+-      pGet = (PNwdCGetDefaultNameContext)cmd->data;
+-      dPtr = cmd->data;
+-
+-      pGet->TreeOffset = sizeof(NwdCGetDefaultNameContext);
+-      pGet->uTreeLength = xplatCall.uTreeLength;
+-
+-      cpylen = copy_from_user( dPtr + pGet->TreeOffset, xplatCall.pTreeName, xplatCall.uTreeLength);
+-      dPtr[pGet->TreeOffset+pGet->uTreeLength] = 0;
+-
+-		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+-		if (reply)
+-		{
+-         retCode = reply->Reply.ErrorCode;
+-         if (!retCode)
+-         {
+-            pGet = (PNwdCGetDefaultNameContext)reply->data;
+-
+-            DbgPrint("NwcGetDefaultNameCtx: retCode=0x%x uNameLength1=%d uNameLength2=%d\n", retCode, pGet->uNameLength, xplatCall.uNameLength);
+-            if (xplatCall.uNameLength < pGet->uNameLength)
+-            {
+-               pGet->uNameLength = xplatCall.uNameLength;
+-               retCode = NWE_BUFFER_OVERFLOW;
+-            }
+-            dPtr = (char *)pGet + pGet->NameContextOffset;
+-            cpylen = copy_to_user(xplatCall.pNameContext, dPtr, pGet->uNameLength);
+-         }
+-
+-         Novfs_Free(reply);
+-		}
+-		Novfs_Free(cmd);
+-	}
+-	return(retCode);
+-
+-}
+-
+-/*++======================================================================*/
+-int NwQueryFeature(PXPLAT pdata, session_t Session)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   NwcQueryFeature xpCall;
+-   int status = SUCCESS;
+-   u_long cpylen;
+-
+-   cpylen = copy_from_user(&xpCall, pdata->reqData, sizeof(NwcQueryFeature));
+-   switch (xpCall.Feature)   
+-   {
+-      case NWC_FEAT_NDS:
+-      case NWC_FEAT_NDS_MTREE:
+-      case NWC_FEAT_PRN_CAPTURE:
+-      case NWC_FEAT_NDS_RESOLVE:
+-
+-      status = NWE_REQUESTER_FAILURE;  
+-
+-   }
+-   return( status );
+-}
+-
+-/*++======================================================================*/
+-int	NwcGetTreeMonitoredConn(PXPLAT pdata, session_t Session)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-PXPLAT_CALL_REQUEST				cmd;
+-PXPLAT_CALL_REPLY				reply;
+-NwcGetTreeMonitoredConnRef		xplatCall, *p;
+-PNwdCGetTreeMonitoredConnRef	pDConnRef;
+-char							*dPtr;
+-u_long					status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+-
+-	cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcGetTreeMonitoredConnRef));
+-	datalen = sizeof(*pDConnRef) + xplatCall.pTreeName->DataLen;
+-	cmdlen = datalen + sizeof(*cmd);
+-	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-
+-	if (cmd)
+-	{
+-		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-		cmd->Command.SequenceNumber = 0;
+-		cmd->Command.SessionId      = Session;
+-		cmd->NwcCommand = NWC_GET_TREE_MONITORED_CONN_REF;
+-
+-		pDConnRef = (PNwdCGetTreeMonitoredConnRef)cmd->data;
+-		pDConnRef->TreeName.boffset = sizeof(*pDConnRef);
+-		pDConnRef->TreeName.len = xplatCall.pTreeName->DataLen;
+-		pDConnRef->TreeName.type = xplatCall.pTreeName->DataType;
+-
+-		dPtr = cmd->data + sizeof(*pDConnRef);
+-		cpylen = copy_from_user(dPtr, xplatCall.pTreeName->pBuffer, pDConnRef->TreeName.len);
+-		status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+-		if (reply)
+-		{
+-			pDConnRef = (PNwdCGetTreeMonitoredConnRef)reply->data;
+-			dPtr = reply->data + pDConnRef->TreeName.boffset;
+-			p = (NwcGetTreeMonitoredConnRef *)pdata->reqData;
+-			cpylen = copy_to_user(&p->uConnReference, &pDConnRef->uConnReference, 4);
+-
+-			status = reply->Reply.ErrorCode;
+-         Novfs_Free(reply);
+-		}
+-		Novfs_Free(cmd);
+-
+-	}
+-
+-	return(status);
+-}
+-
+-/*++======================================================================*/
+-int	NwcEnumIdentities(PXPLAT pdata, session_t Session)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-PXPLAT_CALL_REQUEST				cmd;
+-PXPLAT_CALL_REPLY				reply;
+-NwcEnumerateIdentities			xplatCall, *eId;
+-PNwdCEnumerateIdentities		pEnum;
+-NwcString						xferStr;
+-char							*str;
+-u_long					status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+-
+-	cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcEnumerateIdentities));
+-	datalen = sizeof(*pEnum);
+-	cmdlen = datalen + sizeof(*cmd);
+-	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-
+-	if (cmd)
+-	{
+-		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-		cmd->Command.SequenceNumber = 0;
+-		cmd->Command.SessionId      = Session;
+-		cmd->NwcCommand = NWC_ENUMERATE_IDENTITIES;
+-
+-		DbgPrint("NwcEnumIdentities: Send Request\n");
+-		DbgPrint("   iterator = %x\n", xplatCall.Iterator);
+-		DbgPrint("   cmdlen = %d\n", cmdlen);
+-
+-		pEnum = (PNwdCEnumerateIdentities)cmd->data;
+-		pEnum->Iterator = xplatCall.Iterator;
+-		status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+-		if (reply)
+-		{
+-			status = reply->Reply.ErrorCode;
+-			
+-			eId = pdata->repData;
+-			pEnum = (PNwdCEnumerateIdentities)reply->data;
+-			cpylen = copy_to_user(&eId->Iterator, &pEnum->Iterator, sizeof(pEnum->Iterator));
+-			DbgPrint("[XPLAT NWCAPI] Found AuthId 0x%X\n", pEnum->AuthenticationId);
+-			cpylen = copy_to_user(&eId->AuthenticationId, &pEnum->AuthenticationId, sizeof(pEnum->AuthenticationId));
+-			cpylen = copy_to_user(&eId->AuthType, &pEnum->AuthType, sizeof(pEnum->AuthType));
+-			cpylen = copy_to_user(&eId->IdentityFlags, &pEnum->IdentityFlags, sizeof(pEnum->IdentityFlags));
+-			cpylen = copy_to_user(&eId->NameType, &pEnum->NameType, sizeof(pEnum->NameType));
+-			cpylen = copy_to_user(&eId->ObjectType, &pEnum->ObjectType, sizeof(pEnum->ObjectType));
+-
+-			if (!status)
+-			{
+-				cpylen = copy_from_user(&xferStr, eId->pDomainName, sizeof(NwcString));
+-				str = (char *)((char *)reply->data + pEnum->domainNameOffset);
+-				DbgPrint("[XPLAT NWCAPI] Found Domain %s\n", str);
+-				cpylen = copy_to_user(xferStr.pBuffer, str, pEnum->domainNameLen);
+-				xferStr.DataType = NWC_STRING_TYPE_ASCII;
+-				xferStr.DataLen = pEnum->domainNameLen - 1;
+-				cpylen = copy_to_user(eId->pDomainName, &xferStr, sizeof(NwcString));
+-
+-
+-				cpylen = copy_from_user(&xferStr, eId->pObjectName, sizeof(NwcString));
+-				str = (char *)((char *)reply->data + pEnum->objectNameOffset);
+-				DbgPrint("[XPLAT NWCAPI] Found User %s\n", str);
+-				cpylen = copy_to_user(xferStr.pBuffer, str, pEnum->objectNameLen);
+-				xferStr.DataType = NWC_STRING_TYPE_ASCII;
+-				xferStr.DataLen = pEnum->objectNameLen - 1;
+-				cpylen = copy_to_user(eId->pObjectName, &xferStr, sizeof(NwcString));
+-			}
+-
+-		    Novfs_Free(reply);
+-
+-		}
+-		Novfs_Free(cmd);
+-
+-	}
+-	return(status);
+-}
+-
+-/*++======================================================================*/
+-int	NwcChangeAuthKey(PXPLAT pdata, session_t Session)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract: Change the password on the server
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-PXPLAT_CALL_REQUEST				cmd;
+-PXPLAT_CALL_REPLY				reply;
+-NwcChangeKey			        xplatCall;
+-PNwdCChangeKey		            pNewKey;
+-NwcString						xferStr;
+-char							*str;
+-u_long                          status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+-
+-	cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcChangeKey));
+-
+-    datalen = sizeof(NwdCChangeKey) + xplatCall.pDomainName->DataLen + xplatCall.pObjectName->DataLen
+-        + xplatCall.pNewPassword->DataLen + xplatCall.pVerifyPassword->DataLen;
+-
+-    cmdlen = sizeof(*cmd) + datalen;
+-    cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-
+-    if (cmd)
+-    {
+-        pNewKey = (PNwdCChangeKey)cmd->data;
+-        cmd->dataLen = datalen;
+-   		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-		cmd->Command.SequenceNumber = 0;
+-		cmd->Command.SessionId      = Session;
+-		cmd->NwcCommand = NWC_CHANGE_KEY;
+-
+-        pNewKey->NameType = xplatCall.NameType;
+-        pNewKey->ObjectType = xplatCall.ObjectType;
+-        pNewKey->AuthType = xplatCall.AuthType;
+-        str = (char *)pNewKey;
+-
+-        /*
+-         * Get the tree name
+-         */
+-        str += sizeof(*pNewKey);
+-        cpylen = copy_from_user(&xferStr, xplatCall.pDomainName, sizeof(NwcString));
+-        pNewKey->domainNameOffset = sizeof(*pNewKey);
+-        cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
+-        pNewKey->domainNameLen = xferStr.DataLen;
+-
+-        /*
+-         * Get the User Name
+-         */
+-        str += pNewKey->domainNameLen;
+-        cpylen = copy_from_user(&xferStr, xplatCall.pObjectName, sizeof(NwcString));
+-        pNewKey->objectNameOffset = pNewKey->domainNameOffset + pNewKey->domainNameLen;
+-        cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
+-        pNewKey->objectNameLen = xferStr.DataLen;
+-
+-        /*
+-         * Get the New Password
+-         */
+-        str += pNewKey->objectNameLen;
+-        cpylen = copy_from_user(&xferStr, xplatCall.pNewPassword, sizeof(NwcString));
+-        pNewKey->newPasswordOffset = pNewKey->objectNameOffset + pNewKey->objectNameLen;
+-        cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
+-        pNewKey->newPasswordLen = xferStr.DataLen;
+-
+-        /*
+-         * Get the Verify Password
+-         */
+-        str += pNewKey->newPasswordLen;
+-        cpylen = copy_from_user(&xferStr, xplatCall.pVerifyPassword, sizeof(NwcString));
+-        pNewKey->verifyPasswordOffset = pNewKey->newPasswordOffset + pNewKey->newPasswordLen;
+-        cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
+-        pNewKey->verifyPasswordLen = xferStr.DataLen;
+-
+-		status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+-        if (reply)
+-        {
+-            status = reply->Reply.ErrorCode;
+-            Novfs_Free(reply);
+-        }
+-        memset(cmd, 0, cmdlen);
+-
+-        Novfs_Free(cmd);
+-    }
+-
+-	return(status);
+-}
+-
+-/*++======================================================================*/
+-int	NwcSetPrimaryConn(PXPLAT pdata, session_t Session)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract: Set the primary connection Id
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-PXPLAT_CALL_REQUEST        cmd;
+-PXPLAT_CALL_REPLY          reply;
+-NwcSetPrimaryConnection    xplatCall;
+-PNwdCSetPrimaryConnection  pConn;
+-u_long                     status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+-
+-   cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcSetPrimaryConnection));
+-
+-   datalen = sizeof(NwdCSetPrimaryConnection);
+-   cmdlen = sizeof(*cmd) + datalen;
+-   cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-   if (cmd)
+-   {
+-      pConn = (PNwdCSetPrimaryConnection)cmd->data;
+-      cmd->dataLen = datalen;
+-      cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-      cmd->Command.SequenceNumber = 0;
+-      cmd->Command.SessionId      = Session;
+-      cmd->NwcCommand = NWC_SET_PRIMARY_CONN;
+-      pConn->ConnHandle = xplatCall.ConnHandle;
+-      status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+-
+-      if (reply)
+-      {
+-         status = reply->Reply.ErrorCode;
+-         Novfs_Free(reply);
+-      }
+-
+-      Novfs_Free(cmd);
+-   }
+-
+-   return(status);
+-}
+-
+-/*++======================================================================*/
+-int	NwcGetPrimaryConn(PXPLAT pdata, session_t Session)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract: Get the Primary connection 
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-XPLAT_CALL_REQUEST   cmd;
+-PXPLAT_CALL_REPLY    reply;
+-u_long               status = -ENOMEM, cmdlen, replylen, cpylen;
+-
+-
+-   cmdlen = (u_long)(&((PXPLAT_CALL_REQUEST)0)->data);
+-
+-   cmd.dataLen = 0;
+-   cmd.Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-   cmd.Command.SequenceNumber = 0;
+-   cmd.Command.SessionId      = Session;
+-   cmd.NwcCommand = NWC_GET_PRIMARY_CONN;
+-
+-   status = Queue_Daemon_Command((void *)&cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+-
+-   if (reply)
+-   {
+-      status = reply->Reply.ErrorCode;
+-      if (!status)
+-      {
+-         cpylen = copy_to_user(pdata->repData, reply->data, sizeof(u_long));
+-      }
+-
+-      Novfs_Free(reply);
+-   }
+-
+-   return(status);
+-}
+-
+-
+-/*++======================================================================*/
+-int	NwcSetMapDrive(PXPLAT pdata, session_t Session)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract: Get the Primary connection 
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-
+-PXPLAT_CALL_REQUEST     cmd;
+-PXPLAT_CALL_REPLY       reply;
+-u_long                  status = 0, datalen, cmdlen, replylen, cpylen;
+-NwcMapDriveEx           symInfo;
+-
+-    DbgPrint("Call to NwcSetMapDrive\n");
+-    cpylen = copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo));
+-    cmdlen = sizeof(*cmd);
+-    datalen = sizeof(symInfo) + symInfo.dirPathOffsetLength + symInfo.linkOffsetLength;
+-
+-    DbgPrint(" cmdlen = %d\n", cmdlen);
+-    DbgPrint(" dataLen = %d\n", datalen);
+-    DbgPrint(" symInfo.dirPathOffsetLength = %d\n", symInfo.dirPathOffsetLength);
+-    DbgPrint(" symInfo.linkOffsetLength = %d\n", symInfo.linkOffsetLength);
+-    DbgPrint(" pdata->datalen = %d\n", pdata->reqLen);
+-
+-    mydump(sizeof(symInfo), &symInfo);
+-
+-    cmdlen += datalen;
+-
+-
+-    cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-    if (cmd)
+-    {
+-        cmd->dataLen = datalen;
+-        cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-        cmd->Command.SequenceNumber = 0;
+-        cmd->Command.SessionId      = Session;
+-        cmd->NwcCommand = NWC_MAP_DRIVE;
+-
+-        cpylen = copy_from_user(cmd->data, pdata->reqData, datalen);
+-        status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+-
+-        if (reply)
+-        {
+-            status = reply->Reply.ErrorCode;
+-            Novfs_Free(reply);
+-        }
+-        Novfs_Free(cmd);
+-    }
+-    return(status);
+-
+-}
+-
+-/*++======================================================================*/
+-int	NwcUnMapDrive(PXPLAT pdata, session_t Session)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract: Get the Primary connection 
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-PXPLAT_CALL_REQUEST     cmd;
+-PXPLAT_CALL_REPLY       reply;
+-u_long             status = 0, datalen, cmdlen, replylen, cpylen;
+-NwcUnmapDriveEx    symInfo;
+-
+-    DbgPrint("Call to NwcUnMapDrive\n");
+-
+-    cpylen = copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo));
+-    cmdlen = sizeof(*cmd);
+-    datalen = sizeof(symInfo) + symInfo.linkLen;
+-
+-    cmdlen += datalen;
+-    cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-    if (cmd)
+-    {
+-        cmd->dataLen = datalen;
+-        cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-        cmd->Command.SequenceNumber = 0;
+-        cmd->Command.SessionId      = Session;
+-        cmd->NwcCommand = NWC_UNMAP_DRIVE;
+-
+-        cpylen = copy_from_user(cmd->data, pdata->reqData, datalen);
+-        status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+-
+-        if (reply)
+-        {
+-            status = reply->Reply.ErrorCode;
+-            Novfs_Free(reply);
+-        }
+-        Novfs_Free(cmd);
+-    }
+-
+-    return(status);
+-}
+-
+-
+-/*++======================================================================*/
+-int	NwcEnumerateDrives(PXPLAT pdata, session_t Session)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract: Get the Primary connection 
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-PXPLAT_CALL_REQUEST     cmd;
+-PXPLAT_CALL_REPLY       reply;
+-u_long                  status = 0, cmdlen, replylen, cpylen;
+-u_long                  offset;
+-char                    *cp;
+-
+-    DbgPrint("Call to NwcEnumerateDrives\n");
+-
+-    cmdlen = sizeof(*cmd);
+-    cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-    if (cmd)
+-    {
+-        cmd->dataLen = 0;
+-        cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-        cmd->Command.SequenceNumber = 0;
+-        cmd->Command.SessionId      = Session;
+-        cmd->NwcCommand = NWC_ENUMERATE_DRIVES;
+-        status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+-
+-        if (reply)
+-        {
+-            status = reply->Reply.ErrorCode;
+-            DbgPrint("Status Code = 0x%X\n", status);
+-            if (!status)
+-            {
+-                offset = sizeof(u_long);
+-                cp = reply->data;
+-                replylen = ((PNwcGetMappedDrives)pdata->repData)->MapBuffLen;
+-                cpylen = copy_to_user(pdata->repData, cp, offset);
+-                cp += offset;
+-                cpylen = copy_to_user(((PNwcGetMappedDrives)pdata->repData)->MapBuffer, cp, min(replylen - offset, reply->dataLen - offset));
+-            }
+-
+-            Novfs_Free(reply);
+-        }
+-        Novfs_Free(cmd);
+-    }
+-
+-    return(status);
+-}
+-
+-
+-/*++======================================================================*/
+-int	NwcGetBroadcastMessage(PXPLAT pdata, session_t Session)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract: Get the Primary connection 
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-PXPLAT_CALL_REQUEST             cmd;
+-PXPLAT_CALL_REPLY               reply;
+-u_long                          status = 0x8866, cmdlen, replylen, cpylen;
+-NwcGetBroadcastNotification     msg;
+-PNwdCGetBroadcastNotification   dmsg;
+-
+-    cmdlen = sizeof(*cmd) + sizeof(*dmsg);
+-    cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-    if (cmd)
+-    {
+-
+-        cpylen = copy_from_user(&msg, pdata->reqData, sizeof(msg));
+-        cmd->dataLen = sizeof(*dmsg);
+-        cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-        cmd->Command.SequenceNumber = 0;
+-        cmd->Command.SessionId      = Session;
+-
+-        cmd->NwcCommand = NWC_GET_BROADCAST_MESSAGE;
+-        dmsg = (PNwdCGetBroadcastNotification)cmd->data;
+-        dmsg->uConnReference = msg.uConnReference;
+-        
+-        status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+-
+-        if (reply)
+-        {
+-            status = reply->Reply.ErrorCode;
+-            DbgPrint("Status Code = 0x%X\n", status);
+-            if (!status)
+-            {
+-                /* we have a message so copy it to the user buffer */
+-                cpylen = copy_to_user(pdata->repData, reply->data, min(pdata->repLen, reply->dataLen));
+-            }
+-            else
+-            {
+-                msg.messageLen = 0;
+-                msg.message[0] = 0;
+-                cpylen = copy_to_user(pdata->repData, &msg, sizeof(msg));
+-            }
+-
+-            Novfs_Free(reply);
+-        }
+-        Novfs_Free(cmd);
+-    }
+-    return(status);
+-
+-}
+-
+-
+-int NwdSetKeyValue(PXPLAT pdata, session_t Session)
+-{
+-PXPLAT_CALL_REQUEST     cmd;
+-PXPLAT_CALL_REPLY	    reply;
+-NwcSetKey               xplatCall;
+-PNwdCSetKey             pNewKey;
+-NwcString               cstrObjectName, cstrPassword;
+-char                    *str;
+-u_long                  status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+-
+-   cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcSetKey));
+-   cpylen = copy_from_user(&cstrObjectName, xplatCall.pObjectName, sizeof(NwcString));
+-   cpylen = copy_from_user(&cstrPassword, xplatCall.pNewPassword, sizeof(NwcString));
+-
+-   datalen = sizeof(NwdCSetKey) + cstrObjectName.DataLen + cstrPassword.DataLen;
+-
+-   cmdlen = sizeof(*cmd) + datalen;
+-   cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-
+-   if (cmd)
+-   {
+-      pNewKey = (PNwdCSetKey)cmd->data;
+-      cmd->dataLen = datalen;
+-      cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-      cmd->Command.SequenceNumber = 0;
+-      cmd->Command.SessionId      = Session;
+-      cmd->NwcCommand = NWC_SET_KEY;
+-
+-      pNewKey->ObjectType = xplatCall.ObjectType;
+-      pNewKey->AuthenticationId = xplatCall.AuthenticationId;
+-      pNewKey->ConnHandle = xplatCall.ConnHandle;
+-      str = (char *)pNewKey;
+-
+-      /*
+-       * Get the User Name
+-       */
+-      str += sizeof(NwdCSetKey);
+-      cpylen = copy_from_user(str, cstrObjectName.pBuffer, cstrObjectName.DataLen);
+-
+-      str += 
+-      pNewKey->objectNameLen = cstrObjectName.DataLen;
+-      pNewKey->objectNameOffset = sizeof(NwdCSetKey);
+-
+-      /*
+-       * Get the Verify Password
+-       */
+-      cpylen = copy_from_user(str, cstrPassword.pBuffer, cstrPassword.DataLen);
+-
+-      pNewKey->newPasswordLen = cstrPassword.DataLen;
+-      pNewKey->newPasswordOffset = pNewKey->objectNameOffset+pNewKey->objectNameLen;
+-
+-      status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+-      if (reply)
+-      {
+-         status = reply->Reply.ErrorCode;
+-         Novfs_Free(reply);
+-      }
+-      memset(cmd, 0, cmdlen);
+-      Novfs_Free(cmd);
+-   }
+-
+-   return(status);
+-}
+- 
+-/*++======================================================================*/
+-int NwdVerifyKeyValue(PXPLAT pdata, session_t Session)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract: Change the password on the server
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-PXPLAT_CALL_REQUEST				cmd;
+-PXPLAT_CALL_REPLY				reply;
+-NwcVerifyKey			        xplatCall;
+-PNwdCVerifyKey		            pNewKey;
+-NwcString						xferStr;
+-char							*str;
+-u_long                          status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+-
+-	cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcVerifyKey));
+-
+-    datalen = sizeof(NwdCVerifyKey) + xplatCall.pDomainName->DataLen + xplatCall.pObjectName->DataLen
+-        + xplatCall.pVerifyPassword->DataLen;
+-
+-    cmdlen = sizeof(*cmd) + datalen;
+-    cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
+-
+-    if (cmd)
+-    {
+-        pNewKey = (PNwdCVerifyKey)cmd->data;
+-        cmd->dataLen = datalen;
+-   		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
+-		cmd->Command.SequenceNumber = 0;
+-		cmd->Command.SessionId      = Session;
+-		cmd->NwcCommand = NWC_VERIFY_KEY;
+-
+-        pNewKey->NameType = xplatCall.NameType;
+-        pNewKey->ObjectType = xplatCall.ObjectType;
+-        pNewKey->AuthType = xplatCall.AuthType;
+-        str = (char *)pNewKey;
+-
+-        /*
+-         * Get the tree name
+-         */
+-        str += sizeof(*pNewKey);
+-        cpylen = copy_from_user(&xferStr, xplatCall.pDomainName, sizeof(NwcString));
+-        pNewKey->domainNameOffset = sizeof(*pNewKey);
+-        cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
+-        pNewKey->domainNameLen = xferStr.DataLen;
+-
+-        /*
+-         * Get the User Name
+-         */
+-        str += pNewKey->domainNameLen;
+-        cpylen = copy_from_user(&xferStr, xplatCall.pObjectName, sizeof(NwcString));
+-        pNewKey->objectNameOffset = pNewKey->domainNameOffset + pNewKey->domainNameLen;
+-        cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
+-        pNewKey->objectNameLen = xferStr.DataLen;
+-
+-        /*
+-         * Get the Verify Password
+-         */
+-        str += pNewKey->objectNameLen;
+-        cpylen = copy_from_user(&xferStr, xplatCall.pVerifyPassword, sizeof(NwcString));
+-        pNewKey->verifyPasswordOffset = pNewKey->objectNameOffset + pNewKey->objectNameLen;
+-        cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
+-        pNewKey->verifyPasswordLen = xferStr.DataLen;
+-
+-		status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
+-        if (reply)
+-        {
+-            status = reply->Reply.ErrorCode;
+-            Novfs_Free(reply);
+-        }
+-        memset(cmd, 0, cmdlen);
+-        Novfs_Free(cmd);
+-    }
+-
+-	return(status);
+-}
+diff -uNr src.old/novfs/proc.c src/novfs/proc.c
+--- src.old/novfs/proc.c	2006-07-11 21:24:18.000000000 +0200
++++ src/novfs/proc.c	1970-01-01 01:00:00.000000000 +0100
+@@ -1,339 +0,0 @@
+-/*++========================================================================
+- * Program Name:     Novell NCP Redirector for Linux
+- * File Name:        proc.c
+- * Version:          v1.00
+- * Author:           James Turner
+- *
+- * Abstract:         This module contains functions that create the
+- *                   interface to the proc filesystem.
+- * Notes:
+- * Revision History: 
+- *
+- *
+- * Copyright (C) 2005 Novell, Inc.
+- *
+- * 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 files specific to Linux ]==================================*/
+-#include <linux/module.h>
+-#include <linux/kernel.h>
+-#include <linux/proc_fs.h>
+-#include <linux/smp_lock.h>
+-
+-/*===[ Include files specific to this module ]============================*/
+-#include "vfs.h"
+-
+-/*===[ External data ]====================================================*/
+-extern char *Novfs_CurrentMount;
+-
+-/*===[ External prototypes ]==============================================*/
+-extern int DbgPrint( char *Fmt, ... );
+-
+-extern ssize_t
+-Daemon_Receive_Reply(struct file *file, const char *buf, size_t nbytes, loff_t *ppos);
+-
+-extern ssize_t 
+-Daemon_Send_Command(struct file *file, char *buf, size_t len, loff_t *off);
+-
+-extern int Daemon_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
+-
+-extern int     Daemon_Library_close(struct inode *inode, struct file *file);
+-extern int     Daemon_Library_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
+-extern int     Daemon_Library_open(struct inode *inode, struct file *file);
+-extern ssize_t Daemon_Library_read(struct file *file, char *buf, size_t len, loff_t *off);
+-extern ssize_t Daemon_Library_write(struct file *file, const char *buf, size_t len, loff_t *off);
+-extern loff_t  Daemon_Library_llseek(struct file *file, loff_t offset, int origin);
+-
+-extern int Daemon_Open_Control(struct inode *Inode, struct file *File);
+-extern int Daemon_Close_Control(struct inode *Inode, struct file *File);
+-
+-extern int Daemon_getversion( char *Buf, int Length );
+-
+-/*===[ Manifest constants ]===============================================*/
+-
+-/*===[ Type definitions ]=================================================*/
+-
+-/*===[ Function prototypes ]==============================================*/
+-ssize_t
+-Novfs_User_proc_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos);
+-
+-ssize_t
+-Novfs_User_proc_write(struct file * file, char * buf, size_t nbytes, loff_t *ppos);
+-
+-int Novfs_User_proc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
+-
+-int Init_Procfs_Interface( void );
+-void Uninit_Procfs_Interface( void );
+-
+-/*===[ Global variables ]=================================================*/
+-struct proc_dir_entry *Novfs_Procfs_dir, *Novfs_Control, *Novfs_Library, *Novfs_Version;
+-static struct file_operations Daemon_proc_fops;
+-static struct file_operations Library_proc_fops;
+-
+-/*===[ Code ]=============================================================*/
+-
+-/*++======================================================================*/
+-int Novfs_Get_Version(char *page, char **start, off_t off, int count, int *eof, void *data)
+-/*
+- * Arguments:
+- * 
+- * Returns:
+- * 
+- * Abstract:
+- * 
+- * Notes:
+- * 
+- * Environment:
+- * 
+- *========================================================================*/
+-{
+-   char *buf, tbuf[48];
+-   int len=0, i;
+-
+-   if ( !off )   
+-   {
+-      buf = page+off;
+-      *start = buf;
+-      len = sprintf(buf, "Novfs Version=%s\n", NOVFS_VERSION_STRING);
+-      i = Daemon_getversion(tbuf, sizeof(tbuf));
+-      if ((i > 0) && i < (count-len))
+-      {
+-         len += sprintf(buf+len, "Novfsd Version=%s\n", tbuf);
+-      }
+-      
+-      if (Novfs_CurrentMount)
+-      {
+-         i = strlen(Novfs_CurrentMount);
+-         if ((i > 0) && i < (count-len))
+-         {
+-            len += sprintf(buf+len, "Novfs mount=%s\n", Novfs_CurrentMount);
+-         }
+-      }
+-      DbgPrint("Novfs_Get_Version:\n%s\n", buf);
+-   }
+-	*eof = 1;
+-   return(len);
+-}
+-
+-/*++======================================================================*/
+-ssize_t
+-Novfs_User_proc_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-	ssize_t	retval=0;
+-
+-   UNUSED_VARIABLE(file);
+-   UNUSED_VARIABLE(buf);
+-   UNUSED_VARIABLE(nbytes);
+-   UNUSED_VARIABLE(ppos);
+-
+-	DbgPrint( "Novfs_User_proc_read: kernel_locked 0x%x\n", kernel_locked());
+-
+-	return retval;
+-}
+-/*++======================================================================*/
+-ssize_t
+-Novfs_User_proc_write(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-	ssize_t	retval=0;
+-
+-   UNUSED_VARIABLE(file);
+-   UNUSED_VARIABLE(ppos);
+-	
+-	DbgPrint( "Novfs_User_proc_write: kernel_locked 0x%x\n", kernel_locked());
+-	if (buf && nbytes)
+-	{
+-	}
+-	
+-	return(retval);
+-}
+-
+-/*++======================================================================*/
+-int Novfs_User_proc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-	int retval=-ENOSYS;
+-
+-   UNUSED_VARIABLE(inode);
+-   UNUSED_VARIABLE(file);
+-   UNUSED_VARIABLE(cmd);
+-   UNUSED_VARIABLE(arg);
+-
+-	DbgPrint( "Novfs_User_proc_ioctl: kernel_locked 0x%x\n", kernel_locked());
+-
+-	return(retval);
+-}
+-
+-/*++======================================================================*/
+-int Init_Procfs_Interface( void )
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-	int retCode=0;
+-	
+-	Novfs_Procfs_dir = proc_mkdir(MODULE_NAME, NULL);
+-	if ( Novfs_Procfs_dir ) 
+-	{
+-		Novfs_Procfs_dir->owner = THIS_MODULE;
+-		
+-		Novfs_Control = create_proc_entry("Control", 0600, Novfs_Procfs_dir);
+-
+-		if ( Novfs_Control )
+-		{
+-			Novfs_Control->owner = THIS_MODULE;
+-			Novfs_Control->size  = 0;
+-			memcpy(&Daemon_proc_fops, Novfs_Control->proc_fops, sizeof(struct file_operations));
+-			
+-			/*
+-			 * Setup our functions
+-          */
+-			Daemon_proc_fops.owner   = THIS_MODULE;
+-			Daemon_proc_fops.open    = Daemon_Open_Control;
+-			Daemon_proc_fops.release = Daemon_Close_Control;
+-			Daemon_proc_fops.read    = Daemon_Send_Command;
+-			Daemon_proc_fops.write   = Daemon_Receive_Reply;
+-         Daemon_proc_fops.ioctl   = Daemon_ioctl;
+-			
+-			Novfs_Control->proc_fops = &Daemon_proc_fops;
+-		}
+-		else
+-		{
+-			remove_proc_entry(MODULE_NAME, NULL);
+-			return(-ENOENT);
+-		}
+-      
+-		Novfs_Library = create_proc_entry("Library", 0666, Novfs_Procfs_dir);
+-      if ( Novfs_Library )
+-      {
+-			Novfs_Library->owner = THIS_MODULE;
+-			Novfs_Library->size  = 0;
+-			
+-			/*
+-			 * Setup our file functions
+-          */
+-			memcpy(&Library_proc_fops, Novfs_Library->proc_fops, sizeof(struct file_operations));
+-			Library_proc_fops.owner   = THIS_MODULE;
+-         Library_proc_fops.open    = Daemon_Library_open;
+-			Library_proc_fops.release = Daemon_Library_close;
+-			Library_proc_fops.read    = Daemon_Library_read;
+-			Library_proc_fops.write   = Daemon_Library_write;
+-         Library_proc_fops.llseek  = Daemon_Library_llseek;
+-         Library_proc_fops.ioctl   = Daemon_Library_ioctl;
+-			Novfs_Library->proc_fops  = &Library_proc_fops;
+-      }
+-      else
+-      {
+-         remove_proc_entry("Control", Novfs_Procfs_dir);
+-         remove_proc_entry(MODULE_NAME, NULL);
+-			return(-ENOENT);
+-      }
+-
+-      Novfs_Version = create_proc_read_entry("Version", 0444, Novfs_Procfs_dir, Novfs_Get_Version, NULL);
+-      if ( Novfs_Version )
+-      {
+-			Novfs_Version->owner = THIS_MODULE;
+-			Novfs_Version->size  = 0;
+-      }
+-      else
+-      {
+-         remove_proc_entry("Library", Novfs_Procfs_dir);
+-         remove_proc_entry("Control", Novfs_Procfs_dir);
+-         remove_proc_entry(MODULE_NAME, NULL);
+-			retCode = -ENOENT;
+-      }
+-	}
+-	else
+-	{
+-		retCode = -ENOENT;
+-	}
+-	return(retCode);
+-}
+-
+-/*++======================================================================*/
+-void Uninit_Procfs_Interface( void )
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-
+-   DbgPrint("Uninit_Procfs_Interface remove_proc_entry(Version, NULL)\n");
+-   remove_proc_entry("Version", Novfs_Procfs_dir);
+-
+-   DbgPrint("Uninit_Procfs_Interface remove_proc_entry(Control, NULL)\n");
+-   remove_proc_entry("Control", Novfs_Procfs_dir);
+-
+-   DbgPrint("Uninit_Procfs_Interface remove_proc_entry(Library, NULL)\n");
+-   remove_proc_entry("Library", Novfs_Procfs_dir);
+-
+-   DbgPrint("Uninit_Procfs_Interface remove_proc_entry(%s, NULL)\n", MODULE_NAME);
+-   remove_proc_entry(MODULE_NAME, NULL);
+-
+-   DbgPrint("Uninit_Procfs_Interface done\n");
+-}
+diff -uNr src.old/novfs/profile.c src/novfs/profile.c
+--- src.old/novfs/profile.c	2006-07-11 21:24:18.000000000 +0200
++++ src/novfs/profile.c	1970-01-01 01:00:00.000000000 +0100
+@@ -1,1201 +0,0 @@
+-/*++========================================================================
+- * Program Name:     Novell NCP Redirector for Linux
+- * File Name:        profile.c
+- * Version:          v1.00
+- * Author:           James Turner
+- *
+- * Abstract:         This module contains a debugging code for
+- *                   the novfs VFS.
+- * Notes:
+- * Revision History: 
+- *
+- *
+- * Copyright (C) 2005 Novell, Inc.
+- *
+- * 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 files specific to Linux ]==================================*/
+-#include <linux/module.h>
+-#include <linux/kernel.h>
+-#include <linux/init.h>
+-#include <linux/proc_fs.h>
+-#include <linux/sched.h>
+-#include <asm/uaccess.h>
+-#include <linux/vmalloc.h>
+-#include <linux/time.h>
+-
+-#include <linux/profile.h>
+-#include <linux/notifier.h>
+-
+-/*===[ Include files specific to this module ]============================*/
+-#include "vfs.h"
+-
+-/*===[ External data ]====================================================*/
+-extern struct dentry *Novfs_root;
+-extern struct proc_dir_entry *Novfs_Procfs_dir;
+-extern unsigned long File_update_timeout;
+-
+-/*===[ External prototypes ]==============================================*/
+-extern void Scope_Dump_Tasklist( void );
+-extern void Scope_Dump_Scopetable( void );
+-extern void Daemon_Dumpque( void );
+-extern char  *Scope_dget_path( struct dentry *Dentry, char *Buf, unsigned int Buflen, int Flags);
+-extern int Novfs_dump_inode_cache(int argc, const char **argv, const char **envp, struct pt_regs *regs);
+-extern void Novfs_dump_inode( void *pf );
+-extern int Daemon_SendDebugCmd ( char *Command );
+-
+-
+-/*===[ Manifest constants ]===============================================*/
+-#define DBGBUFFERSIZE (1024*1024*32)
+-
+-/*===[ Type definitions ]=================================================*/
+-typedef void daemon_command_t;
+-
+-typedef struct _SYMBOL_TABLE {
+-	void *address;
+-	char *name;
+-} SYMBOL_TABLE, *PSYMBOL_TABLE;
+-
+-struct local_rtc_time {
+-	int tm_sec;
+-	int tm_min;
+-	int tm_hour;
+-	int tm_mday;
+-	int tm_mon;
+-	int tm_year;
+-	int tm_wday;
+-	int tm_yday;
+-	int tm_isdst;
+-};
+-
+-/*===[ Function prototypes ]==============================================*/
+-int profile_task_exit_callback(struct notifier_block *self, unsigned long val, void *data) __attribute__((__no_instrument_function__));
+-int init_profile( void );
+-
+-char *ctime_r(time_t *clock, char *buf);
+-int LocalPrint( char *Fmt, ... ) __attribute__((__no_instrument_function__));
+-int DbgPrint( char *Fmt, ... ) __attribute__((__no_instrument_function__));
+-
+-void __cyg_profile_func_enter (void *this_fn, void *call_site) __attribute__((__no_instrument_function__)) ;
+-void __cyg_profile_func_exit (void *this_fn, void *call_site) __attribute__((__no_instrument_function__));
+-void doline(unsigned char *b, unsigned char *p, unsigned char *l) __attribute__((__no_instrument_function__));
+-void mydump(int size, void *dumpptr) __attribute__((__no_instrument_function__));
+-void GregorianDay(struct local_rtc_time * tm) __attribute__((__no_instrument_function__));
+-void to_tm(int tim, struct local_rtc_time * tm) __attribute__((__no_instrument_function__));
+-char *ctime_r(time_t *clock, char *buf) __attribute__((__no_instrument_function__));
+-int profile_dump_tasklist(int argc, const char **argv, const char **envp, struct pt_regs *regs);
+-int profile_dump_scopetable(int argc, const char **argv, const char **envp, struct pt_regs *regs);
+-int profile_dump_daemonque(int argc, const char **argv, const char **envp, struct pt_regs *regs);
+-int profile_dump_DbgBuffer(int argc, const char **argv, const char **envp, struct pt_regs *regs);
+-int profile_dump_DentryTree(int argc, const char **argv, const char **envp, struct pt_regs *regs);
+-int profile_dump_inode(int argc, const char **argv, const char **envp, struct pt_regs *regs);
+-
+-void *Novfs_Malloc( size_t size, int flags ) __attribute__((__no_instrument_function__));
+-void Novfs_Free( const void *p ) __attribute__((__no_instrument_function__));
+-
+-int profile_dump_memorylist_dbg(int argc, const char **argv, const char **envp, struct pt_regs *regs)  __attribute__((__no_instrument_function__));
+-void profile_dump_memorylist( void *pf );
+-
+-static ssize_t User_proc_write_DbgBuffer(struct file * file, const char __user *buf, size_t nbytes, loff_t *ppos) __attribute__((__no_instrument_function__));
+-static ssize_t User_proc_read_DbgBuffer(struct file * file, char * buf, size_t nbytes, loff_t *ppos) __attribute__((__no_instrument_function__));
+-static int proc_read_DbgBuffer(char *page, char **start,
+-                            off_t off, int count, 
+-                            int *eof, void *data) __attribute__((__no_instrument_function__));
+-
+-void profile_dump_dt(struct dentry *parent, void *pf );
+-ssize_t profile_inode_read(struct file *file, char *buf, size_t len, loff_t *off);
+-ssize_t profile_dentry_read(struct file *file, char *buf, size_t len, loff_t *off);
+-ssize_t profile_memory_read(struct file *file, char *buf, size_t len, loff_t *off);
+-
+-/*===[ Global variables ]=================================================*/
+-char *DbgPrintBuffer=NULL;
+-char DbgPrintOn=0;
+-char DbgSyslogOn=0;
+-char DbgProfileOn=0;
+-char DbgDaemonLogOn=0;
+-unsigned long DbgPrintBufferOffset=0;
+-unsigned long DbgPrintBufferReadOffset=0;
+-unsigned long DbgPrintBufferSize = DBGBUFFERSIZE;
+-
+-int Indent = 0;
+-char IndentString[] = "                                       ";
+-
+-static struct file_operations Dbg_proc_file_operations;
+-static struct file_operations dentry_proc_file_ops;
+-static struct file_operations inode_proc_file_ops;
+-static struct file_operations memory_proc_file_ops;
+-
+-static struct proc_dir_entry *dbg_dir, *dbg_file;
+-static struct proc_dir_entry *dentry_file;
+-static struct proc_dir_entry *inode_file;
+-static struct proc_dir_entry *memory_file;
+-
+-static struct notifier_block taskexit_nb;
+-
+-
+-DECLARE_MUTEX(LocalPrint_lock);
+-spinlock_t Syslog_lock = SPIN_LOCK_UNLOCKED;
+-
+-#include "profile_funcs.h"
+-
+-
+-/*===[ Code ]=============================================================*/
+-int 
+-profile_task_exit_callback(struct notifier_block *self, unsigned long val, void *data)
+-{
+-   struct task_struct *task = (struct task_struct *)data;
+-
+-	DbgPrint("profile_task_exit_callback: task 0x%p %u exiting %s\n", task, task->pid, task->comm);
+-   return(0);
+-}
+-
+-int init_profile( void )
+-{
+-   int retCode = 0;
+-
+-	if ( DbgPrintBuffer )
+-	{
+-		if (Novfs_Procfs_dir)
+-      {
+-         dbg_dir = Novfs_Procfs_dir;
+-      }
+-      else
+-      {
+-			dbg_dir = proc_mkdir(MODULE_NAME, NULL);
+-      }
+-
+-		if( dbg_dir ) 
+-		{
+-			dbg_dir->owner = THIS_MODULE;
+-			dbg_file = create_proc_read_entry("Debug", 
+-												0600, 
+-												dbg_dir, 
+-												proc_read_DbgBuffer,
+-												NULL);
+-			if ( dbg_file )
+-			{
+-				dbg_file->owner = THIS_MODULE;
+-				dbg_file->size  = DBGBUFFERSIZE;
+-				memcpy(&Dbg_proc_file_operations, dbg_file->proc_fops, sizeof(struct file_operations));
+-				Dbg_proc_file_operations.read = User_proc_read_DbgBuffer;
+-				Dbg_proc_file_operations.write = User_proc_write_DbgBuffer;
+-				dbg_file->proc_fops = &Dbg_proc_file_operations;
+-			}
+-			else
+-			{
+-				remove_proc_entry(MODULE_NAME, NULL);
+-				vfree( DbgPrintBuffer );
+-				DbgPrintBuffer = NULL;
+-			}
+-
+-			inode_file = create_proc_entry("inode", 
+-												0600, 
+-												dbg_dir);
+-			if ( inode_file )
+-			{
+-				inode_file->owner = THIS_MODULE;
+-				inode_file->size  = 0;
+-				memcpy(&inode_proc_file_ops, inode_file->proc_fops, sizeof(struct file_operations));
+-		      inode_proc_file_ops.owner   = THIS_MODULE;
+-		      inode_proc_file_ops.read    = profile_inode_read;
+-				inode_file->proc_fops = &inode_proc_file_ops;
+-			}
+-
+-			dentry_file = create_proc_entry("dentry", 
+-												0600, 
+-												dbg_dir);
+-			if ( dentry_file )
+-			{
+-				dentry_file->owner = THIS_MODULE;
+-				dentry_file->size  = 0;
+-				memcpy(&dentry_proc_file_ops, dentry_file->proc_fops, sizeof(struct file_operations));
+-		      dentry_proc_file_ops.owner   = THIS_MODULE;
+-		      dentry_proc_file_ops.read    = profile_dentry_read;
+-				dentry_file->proc_fops = &dentry_proc_file_ops;
+-			}
+-
+-			memory_file = create_proc_entry("memory", 
+-												0600, 
+-												dbg_dir);
+-			if ( memory_file )
+-			{
+-				memory_file->owner = THIS_MODULE;
+-				memory_file->size  = 0;
+-				memcpy(&memory_proc_file_ops, memory_file->proc_fops, sizeof(struct file_operations));
+-		      memory_proc_file_ops.owner   = THIS_MODULE;
+-		      memory_proc_file_ops.read    = profile_memory_read;
+-				memory_file->proc_fops = &memory_proc_file_ops;
+-			}
+-
+-		}
+-		else
+-		{
+-			vfree( DbgPrintBuffer );
+-			DbgPrintBuffer = NULL;
+-		}
+-	}
+-   return( retCode );
+-}
+-
+-/*
+-void uninit_profile()
+-{
+-   if (dbg_file)    DbgPrint("Calling remove_proc_entry(Debug, NULL)\n"), remove_proc_entry( "Debug", dbg_dir );
+-   if (inode_file)  DbgPrint("Calling remove_proc_entry(inode, NULL)\n"), remove_proc_entry( "inode", dbg_dir );
+-   if (dentry_file) DbgPrint("Calling remove_proc_entry(dentry, NULL)\n"), remove_proc_entry( "dentry", dbg_dir );
+-   if (memory_file) DbgPrint("Calling remove_proc_entry(memory, NULL)\n"), remove_proc_entry( "memory", dbg_dir );
+-
+-   if (dbg_dir && (dbg_dir != Novfs_Procfs_dir))  
+-   {
+-      DbgPrint("Calling remove_proc_entry(%s, NULL)\n", MODULE_NAME);
+-	   remove_proc_entry( MODULE_NAME, NULL );
+-   }
+-}
+-*/
+-
+-static 
+-ssize_t
+-User_proc_write_DbgBuffer(struct file * file, const char __user *buf, size_t nbytes, loff_t *ppos)
+-{
+-	ssize_t	retval=nbytes;
+-   u_char *lbuf, *p;
+-   int i;
+-   u_long cpylen;
+-
+-
+-   UNUSED_VARIABLE( *ppos );
+-
+-   lbuf = Novfs_Malloc(nbytes+1, GFP_KERNEL);
+-   if (lbuf)
+-   {
+-      cpylen = copy_from_user(lbuf, buf, nbytes);
+-   
+-      lbuf[nbytes] = 0;
+-      DbgPrint("User_proc_write_DbgBuffer: %s\n", lbuf);
+-
+-      for (i=0; lbuf[i] && lbuf[i] != '\n'; i++) ;
+-
+-      if ( '\n' == lbuf[i] )
+-      {
+-         lbuf[i] = '\0';
+-      }
+-
+-      if ( !strcmp("on", lbuf))
+-      {
+-   	   DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
+-         DbgPrintOn = 1;
+-      }
+-      else if ( !strcmp("off", lbuf))
+-      {
+-         DbgPrintOn = 0;
+-      }
+-      else if ( !strcmp("reset", lbuf))
+-      {
+-   	   DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
+-      }
+-      else if ( NULL != (p = strchr(lbuf, ' ')))
+-      {
+-         *p++ = '\0';
+-         if ( !strcmp("syslog", lbuf))
+-         {
+-            
+-            if (!strcmp("on", p))
+-            {
+-               DbgSyslogOn = 1;
+-            }
+-            else if (!strcmp("off", p))
+-            {
+-               DbgSyslogOn = 0;
+-            }
+-         }
+-         else if ( !strcmp("profile", lbuf))
+-         {
+-            
+-            if (!strcmp("on", p))
+-            {
+-               DbgProfileOn = 1;
+-            }
+-            else if (!strcmp("off", p))
+-            {
+-               DbgProfileOn = 0;
+-            }
+-         }
+-         else if ( !strcmp("daemonlog", lbuf))
+-         {
+-            
+-            if (!strcmp("on", p))
+-            {
+-               DbgDaemonLogOn = 1;
+-            }
+-            else if (!strcmp("off", p))
+-            {
+-               DbgDaemonLogOn = 0;
+-            }
+-         }
+-         else if ( !strcmp("novfsd", lbuf))
+-         {
+-            Daemon_SendDebugCmd( p );
+-         }
+-         else if ( !strcmp("file_update_timeout", lbuf))
+-         {
+-            File_update_timeout = simple_strtoul(p, NULL, 0);
+-         }
+-      }
+-      Novfs_Free(lbuf);
+-   }
+-
+-	return (retval);
+-}
+-
+-static 
+-ssize_t
+-User_proc_read_DbgBuffer(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
+-
+-{
+-	ssize_t	retval=0;
+-	size_t	count;
+-
+-   UNUSED_VARIABLE( *ppos );
+-
+-	if (0 != (count = DbgPrintBufferOffset - DbgPrintBufferReadOffset))
+-   {
+-
+-	   if (count > nbytes)
+-	   {
+-			   count = nbytes;
+-	   }
+-
+-	   count -= copy_to_user(buf, &DbgPrintBuffer[DbgPrintBufferReadOffset], count);
+-
+-	   if (count == 0) 
+-	   {
+-		   if (retval == 0)
+-			   retval = -EFAULT;
+-	   }
+-	   else
+-	   {
+-		   DbgPrintBufferReadOffset += count;
+-		   if (DbgPrintBufferReadOffset >= DbgPrintBufferOffset)
+-		   {
+-			   DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
+-		   }
+-		   retval = count;
+-	   }
+-   }
+-
+-	return retval;
+-}
+-
+-static 
+-int 
+-proc_read_DbgBuffer(char *page, char **start,
+-                            off_t off, int count, 
+-                            int *eof, void *data)
+-{
+-	int len;
+-	static char bufd[512];
+-
+-   UNUSED_VARIABLE(start);
+-   UNUSED_VARIABLE(eof);
+-   UNUSED_VARIABLE(data);
+-
+-	sprintf(bufd, KERN_ALERT "proc_read_DbgBuffer: off=%ld count=%d DbgPrintBufferOffset=%lu DbgPrintBufferReadOffset=%lu\n", 
+-			off, count, DbgPrintBufferOffset, DbgPrintBufferReadOffset);
+-	printk(bufd);
+-
+-	len = DbgPrintBufferOffset - DbgPrintBufferReadOffset;
+-
+-	if ((int)(DbgPrintBufferOffset-DbgPrintBufferReadOffset) > count)
+-	{
+-		len = count;
+-	}
+-
+-	if (len)
+-	{
+-		memcpy(page, &DbgPrintBuffer[DbgPrintBufferReadOffset], len);
+-		DbgPrintBufferReadOffset += len;
+-	}
+-	
+-
+-	if (DbgPrintBufferReadOffset >= DbgPrintBufferOffset)
+-	{
+-		DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
+-	}
+-
+-	sprintf(bufd, KERN_ALERT "proc_read_DbgBuffer: return %d\n", len);
+-	printk(bufd);
+-
+-	return len;
+-}
+-
+-#define DBG_BUFFER_SIZE (2*1024)
+-
+-int 
+-LocalPrint( char *Fmt, ... )
+-{
+-	int len=0;
+-	va_list args;
+-
+-   if (DbgPrintBuffer)
+-   {
+-		va_start(args, Fmt);
+-   	len += vsnprintf(DbgPrintBuffer+DbgPrintBufferOffset, DbgPrintBufferSize-DbgPrintBufferOffset, Fmt, args);
+-      DbgPrintBufferOffset += len;
+-   }
+-
+-	return(len);
+-}
+-
+-
+-int 
+-DbgPrint( char *Fmt, ... )
+-{
+-	char *buf;
+-	int len=0;
+-	unsigned long offset;
+-	va_list args;
+-
+-   if ( (DbgPrintBuffer && DbgPrintOn) || DbgSyslogOn )
+-   {
+-      buf = kmalloc( DBG_BUFFER_SIZE, GFP_KERNEL );
+-
+-      if (buf)
+-      {
+-		   va_start(args, Fmt);
+-         len = sprintf(buf, "[%d] ", current->pid);
+-	
+-		   len += vsnprintf(buf+len, DBG_BUFFER_SIZE-len, Fmt, args);
+-		   if ( -1 == len )
+-		   {
+-			   len = DBG_BUFFER_SIZE-1;
+-			   buf[len] = '\0';
+-		   }
+-         /*
+-         len = sprintf(&DbgPrintBuffer[offset], "[%llu] ", ts);
+-         len += vsprintf(&DbgPrintBuffer[offset+len], Fmt, args);
+-         */
+-
+-		   if (len)
+-		   {
+-            if (DbgSyslogOn)
+-            {
+-               spin_lock( &Syslog_lock );
+-			      printk("<6>%s", buf);
+-               spin_unlock( &Syslog_lock );
+-            }
+-            
+-            if ( DbgPrintBuffer && DbgPrintOn )
+-            {
+-		         if ((DbgPrintBufferOffset+len) > DbgPrintBufferSize)
+-               {
+-                  offset = DbgPrintBufferOffset;
+-                  DbgPrintBufferOffset = 0;
+-                  memset(&DbgPrintBuffer[offset], 0, DbgPrintBufferSize-offset);
+-               }
+-
+-               mb();
+-
+-		         if ((DbgPrintBufferOffset+len) < DbgPrintBufferSize)
+-		         {
+-			         DbgPrintBufferOffset += len;		
+-			         offset = DbgPrintBufferOffset-len;
+-                  memcpy(&DbgPrintBuffer[offset], buf, len+1);
+-		         }
+-            }
+-		   }
+-         kfree(buf);
+-      }
+-   }
+-
+-	return(len);
+-}
+-
+-void
+-__cyg_profile_func_enter (void *this_fn, void *call_site)
+-{
+-	PSYMBOL_TABLE sym;
+-   struct timespec ts;
+-
+-	
+-	if ((void *)init_novfs == this_fn)
+-	{
+-		DbgPrintBuffer = vmalloc(DBGBUFFERSIZE);
+-      taskexit_nb.notifier_call = profile_task_exit_callback;
+-
+-#ifdef	CONFIG_KDB
+-      kdb_register("novfs_tl", profile_dump_tasklist, "", "Dumps task list", 0);
+-      kdb_register("novfs_st", profile_dump_scopetable, "", "Dumps the novfs scope table", 0);
+-      kdb_register("novfs_dque", profile_dump_daemonque, "", "Dumps the novfs daemon que", 0);
+-      kdb_register("novfs_db", profile_dump_DbgBuffer, "[-r] [-e size] [-i]", "Dumps the novfs DbgBuffer", 0);
+-      kdb_register("novfs_den", profile_dump_DentryTree, "[dentry]", "Dumps a Dentry tree", 0);
+-      kdb_register("novfs_ic", Novfs_dump_inode_cache, "[inode]", "Dumps a Inode Cache", 0);
+-      kdb_register("novfs_inode", profile_dump_inode, "", "Dump allocated Inodes", 0);
+-      kdb_register("novfs_mem", profile_dump_memorylist_dbg, "", "Dumps allocated memory", 0);
+-#endif
+-	}
+-   else if (exit_novfs == this_fn)
+-   {
+-		if (dbg_file)    DbgPrint("Calling remove_proc_entry(Debug, NULL)\n"), remove_proc_entry( "Debug", dbg_dir );
+-		if (inode_file)  DbgPrint("Calling remove_proc_entry(inode, NULL)\n"), remove_proc_entry( "inode", dbg_dir );
+-		if (dentry_file) DbgPrint("Calling remove_proc_entry(dentry, NULL)\n"), remove_proc_entry( "dentry", dbg_dir );
+-		if (memory_file) DbgPrint("Calling remove_proc_entry(memory, NULL)\n"), remove_proc_entry( "memory", dbg_dir );
+-
+-		if (dbg_dir && (dbg_dir != Novfs_Procfs_dir))  
+-		{
+-         printk( KERN_INFO "Calling remove_proc_entry(%s, NULL)\n", MODULE_NAME);
+-		   remove_proc_entry( MODULE_NAME, NULL );
+-      }
+-   }
+-
+-   if (DbgProfileOn)
+-   {
+-	   sym = SymbolTable;
+-	   while (sym->address)
+-	   {
+-		   if (this_fn == sym->address )
+-		   {
+-            ts = current_kernel_time();
+-			   DbgPrint("[%ld:lu]%sS %s (0x%p 0x%p)\n", ts.tv_sec, ts.tv_nsec, &IndentString[sizeof(IndentString)-Indent-1], sym->name, this_fn, call_site);
+-
+-	         Indent++;
+-	         if (Indent > (int)(sizeof(IndentString)-1))
+-		         Indent--;
+-		
+-			   break;
+-		   }
+-		   sym++;
+-	   }
+-   }
+-}
+-
+-void
+-__cyg_profile_func_exit (void *this_fn, void *call_site)
+-{
+-	PSYMBOL_TABLE sym;
+-   struct timespec ts;
+-
+-	if (exit_novfs == this_fn)
+-	{
+-		if (DbgPrintBuffer) vfree( DbgPrintBuffer );
+-		DbgPrintBuffer = NULL;
+-
+-#ifdef	CONFIG_KDB
+-      kdb_unregister("novfs_tl");
+-      kdb_unregister("novfs_st");
+-      kdb_unregister("novfs_dque");
+-      kdb_unregister("novfs_db");
+-      kdb_unregister("novfs_den");
+-      kdb_unregister("novfs_ic");
+-      kdb_unregister("novfs_inode");
+-      kdb_unregister("novfs_mem");
+-#endif
+-		return;
+-	}
+-
+-   if (DbgProfileOn)
+-   {
+-	   sym = SymbolTable;
+-	   while (sym->address)
+-	   {
+-		   if (this_fn == sym->address )
+-		   {
+-	         Indent--;
+-	         if (Indent < 0)
+-		         Indent = 0;
+-
+-            ts = current_kernel_time();
+-			   DbgPrint("[%ld:lu]%sR %s (0x%p)\n", ts.tv_sec, ts.tv_nsec, &IndentString[sizeof(IndentString)-Indent-1], sym->name, call_site);
+-			   break;
+-		   }
+-		   sym++;
+-	   }
+-   }
+-}
+-
+-void
+-doline(unsigned char *b, unsigned char *e, unsigned char *l)
+-{
+-	*b++ = ' ';
+-	while (l < e) {
+-		if ((*l < ' ') || (*l > '~')) 
+-		{
+-		   *b++ = '.';
+-         *b = '\0';
+-      }
+-		else 
+-		{
+-		   b += sprintf(b, "%c", *l);
+-      }
+-		l++;
+-	}
+-}
+-
+-void
+-mydump(int size, void *dumpptr)
+-{
+-	unsigned char *ptr = (unsigned char *)dumpptr;
+-	unsigned char *line=0, buf[80], *bptr=buf;
+-	int i;
+-
+-   if ( DbgPrintBuffer )
+-   {
+-      if (size)
+-      {
+-	      for (i=0; i < size; i++) 
+-	      {
+-		      if (0 == (i % 16)) 
+-		      {
+-			      if (line) 
+-			      {
+-				      doline(bptr, ptr, line);
+-				      DbgPrint("%s\n", buf);
+-                  bptr = buf;
+-			      }
+-			      bptr += sprintf(bptr, "0x%p: ", ptr);
+-			      line = ptr;
+-		      }
+-		      bptr += sprintf(bptr, "%02x ", *ptr++);
+-	      }
+-	      doline(bptr, ptr, line);
+-	      DbgPrint("%s\n", buf);
+-      }
+-   }
+-}
+-
+-#define FEBRUARY	2
+-#define	STARTOFTIME	1970
+-#define SECDAY		86400L
+-#define SECYR		(SECDAY * 365)
+-#define	leapyear(year)		((year) % 4 == 0)
+-#define	days_in_year(a) 	(leapyear(a) ? 366 : 365)
+-#define	days_in_month(a) 	(month_days[(a) - 1])
+-
+-static int month_days[12] = {
+-	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
+-};
+-
+-/*
+- * This only works for the Gregorian calendar - i.e. after 1752 (in the UK)
+- */
+-void 
+-GregorianDay(struct local_rtc_time * tm)
+-{
+-	int leapsToDate;
+-	int lastYear;
+-	int day;
+-	int MonthOffset[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
+-
+-	lastYear=tm->tm_year-1;
+-
+-	/*
+-	 * Number of leap corrections to apply up to end of last year
+-	 */
+-	leapsToDate = lastYear/4 - lastYear/100 + lastYear/400;
+-
+-	/*
+-	 * This year is a leap year if it is divisible by 4 except when it is
+-	 * divisible by 100 unless it is divisible by 400
+-	 *
+-	 * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 will be
+-	 */
+-	if((tm->tm_year%4==0) &&
+-	   ((tm->tm_year%100!=0) || (tm->tm_year%400==0)) &&
+-	   (tm->tm_mon>2))
+-	{
+-		/*
+-		 * We are past Feb. 29 in a leap year
+-		 */
+-		day=1;
+-	}
+-	else
+-	{
+-		day=0;
+-	}
+-
+-	day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] +
+-		   tm->tm_mday;
+-
+-	tm->tm_wday=day%7;
+-}
+-
+-void 
+-to_tm(int tim, struct local_rtc_time * tm)
+-{
+-	register int    i;
+-	register long   hms, day;
+-
+-	day = tim / SECDAY;
+-	hms = tim % SECDAY;
+-
+-	/* Hours, minutes, seconds are easy */
+-	tm->tm_hour = hms / 3600;
+-	tm->tm_min = (hms % 3600) / 60;
+-	tm->tm_sec = (hms % 3600) % 60;
+-
+-	/* Number of years in days */
+-	for (i = STARTOFTIME; day >= days_in_year(i); i++)
+-		day -= days_in_year(i);
+-	tm->tm_year = i;
+-
+-	/* Number of months in days left */
+-	if (leapyear(tm->tm_year))
+-		days_in_month(FEBRUARY) = 29;
+-	for (i = 1; day >= days_in_month(i); i++)
+-		day -= days_in_month(i);
+-	days_in_month(FEBRUARY) = 28;
+-	tm->tm_mon = i;
+-
+-	/* Days are what is left over (+1) from all that. */
+-	tm->tm_mday = day + 1;
+-
+-	/*
+-	 * Determine the day of week
+-	 */
+-	GregorianDay(tm);
+-}
+-
+-char *
+-ctime_r(time_t *clock, char *buf)
+-{
+-   struct local_rtc_time tm;
+-   static char *DAYOFWEEK[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
+-   static char *MONTHOFYEAR[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
+-
+-   to_tm(*clock, &tm);
+-
+-   sprintf(buf, "%s %s %d %d:%02d:%02d %d", DAYOFWEEK[tm.tm_wday], MONTHOFYEAR[tm.tm_mon-1], tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_year);
+-   return(buf);
+-}
+-
+-
+-#ifdef	CONFIG_KDB
+-
+-int
+-NO_TRACE
+-profile_dump_tasklist(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+-{
+-   Scope_Dump_Tasklist();
+-   return( 0 );
+-}
+-
+-int
+-NO_TRACE
+-profile_dump_scopetable(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+-{
+-   Scope_Dump_Scopetable();
+-   return( 0 );
+-}
+-
+-int
+-NO_TRACE
+-profile_dump_daemonque(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+-{
+-   Daemon_Dumpque();
+-   return( 0 );
+-}
+-
+-int
+-NO_TRACE
+-profile_dump_DbgBuffer(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+-{
+-   unsigned long offset = DbgPrintBufferReadOffset;
+-   if (argc > 0)
+-   {
+-      if (!strcmp("-r", argv[1]))
+-      {
+-         DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
+-      }
+-      else if (!strcmp("-e", argv[1]) && (argc > 1))
+-      {
+-         offset = simple_strtoul(argv[2], NULL, 0);
+-         if (offset && offset < DbgPrintBufferOffset)
+-         {
+-            offset = DbgPrintBufferOffset - offset;
+-         }
+-         else
+-         {
+-            offset = DbgPrintBufferOffset;
+-         }
+-      }
+-      else if (!strcmp("-i", argv[1]))
+-      {
+-         kdb_printf("DbgPrintBuffer       =0x%p\n", DbgPrintBuffer);
+-         kdb_printf("DbgPrintBufferOffset =0x%lx\n", DbgPrintBufferOffset);
+-         kdb_printf("DbgPrintBufferSize   =0x%lx\n", DbgPrintBufferSize);
+-         offset = DbgPrintBufferOffset;
+-         
+-      }
+-   }
+-	while (DbgPrintBufferOffset > offset)
+-   {
+-      kdb_printf("%c", DbgPrintBuffer[offset++]);
+-   }
+-   return( 0 );
+-}
+-
+-int
+-NO_TRACE
+-profile_dump_DentryTree(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+-{
+-   struct dentry *parent=Novfs_root;
+-
+-   if (argc > 0)
+-   {
+-      parent = (void *)simple_strtoul(argv[1], NULL, 0);
+-   }
+-
+-   if (parent)
+-   {
+-      profile_dump_dt(parent, kdb_printf );
+-   }
+-
+-   return(0);
+-}
+-
+-
+-int
+-NO_TRACE
+-profile_dump_inode(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+-{
+-   Novfs_dump_inode( kdb_printf );
+-   return( 0 );
+-}
+-
+-#endif	/* CONFIG_KDB */
+-
+-typedef struct memory_header
+-{
+-   struct list_head list;
+-   void *caller;
+-   size_t size;
+-} MEMORY_LIST, *PMEMORY_LIST;
+-
+-spinlock_t Malloc_Lock = SPIN_LOCK_UNLOCKED;
+-LIST_HEAD( Memory_List );
+-
+-void *Novfs_Malloc( size_t size, int flags )
+-{
+-   void *p=NULL;
+-   PMEMORY_LIST mh;
+-
+-   mh = kmalloc(size + sizeof(MEMORY_LIST), flags);
+-   if (mh)
+-   {
+-      mh->caller = __builtin_return_address(0);
+-      mh->size = size;
+-   	spin_lock(&Malloc_Lock);
+-      list_add(&mh->list, &Memory_List);
+-   	spin_unlock(&Malloc_Lock);
+-      p = (char *)mh+sizeof(MEMORY_LIST);
+-   	/*DbgPrint("Novfs_Malloc: 0x%p 0x%p %d\n", p, mh->caller, size);
+-      */
+-   }
+-   return(p);
+-}
+-
+-void Novfs_Free( const void *p )
+-{
+-   PMEMORY_LIST mh;
+-
+-   if (p)
+-   {
+-   	/*DbgPrint("Novfs_Free: 0x%p 0x%p\n", p, __builtin_return_address(0));
+-      */
+-      mh = (PMEMORY_LIST)((char *)p-sizeof(MEMORY_LIST));
+-
+-   	spin_lock(&Malloc_Lock);
+-      list_del(&mh->list);
+-   	spin_unlock(&Malloc_Lock);
+-      kfree(mh);
+-   }
+-}
+-
+-
+-int
+-NO_TRACE
+-profile_dump_memorylist_dbg(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+-{
+-#ifdef	CONFIG_KDB
+-   profile_dump_memorylist(kdb_printf);
+-#endif	/* CONFIG_KDB */
+-
+-   return( 0 );
+-}
+-
+-void
+-NO_TRACE
+-profile_dump_memorylist( void *pf )
+-{
+-   void (*pfunc)(char *Fmt, ...) = pf;
+-
+-   PMEMORY_LIST mh;
+-   struct list_head *l;
+-
+-   size_t total=0;
+-   int count=0;
+-
+-   spin_lock( &Malloc_Lock );
+-
+-   list_for_each( l, &Memory_List )
+-   {
+-      mh = list_entry(l, MEMORY_LIST, list);
+-      pfunc("0x%p 0x%p 0x%p %d\n", mh, (char *)mh+sizeof(MEMORY_LIST), mh->caller, mh->size);
+-      count++;
+-      total += mh->size;
+-   }
+-   spin_unlock( &Malloc_Lock );
+-
+-   pfunc("Blocks=%d Total=%d\n", count, total);
+-}
+-
+-void 
+-NO_TRACE
+-profile_dump_dt(struct dentry *parent, void *pf )
+-{
+-   void (*pfunc)(char *Fmt, ...) = pf;
+-   struct l {
+-      struct l *next;
+-      struct dentry *dentry;
+-   } *l, *n, *start;
+-   struct list_head *p;
+-   struct dentry *d;
+-   char *buf, *path, *sd;
+-   char inode_number[16];
+-
+-   buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+-
+-   if( NULL == buf )
+-   {
+-      return;
+-   }
+-
+-   if (parent)
+-   {
+-      pfunc("starting 0x%p %.*s\n", parent, parent->d_name.len, parent->d_name.name);
+-      if (parent->d_subdirs.next == &parent->d_subdirs)
+-      {
+-         pfunc("No children...\n");
+-      }
+-      else
+-      {
+-         start = Novfs_Malloc(sizeof(*start), GFP_KERNEL);
+-         if (start)
+-         {
+-            start->next = NULL;
+-            start->dentry = parent;
+-            l = start;
+-            while(l)
+-            {
+-               p = l->dentry->d_subdirs.next;
+-               while(p != &l->dentry->d_subdirs)
+-               {
+-                  d = list_entry(p, struct dentry, D_CHILD);
+-                  p = p->next;
+-
+-                  if (d->d_subdirs.next != &d->d_subdirs)
+-                  {
+-                     n = Novfs_Malloc(sizeof(*n), GFP_KERNEL);
+-                     if (n)
+-                     {
+-                        n->next = l->next;
+-                        l->next = n;
+-                        n->dentry = d;
+-                     }
+-                  }
+-                  else
+-                  {
+-                     path = Scope_dget_path(d, buf, PATH_LENGTH_BUFFER, 1);
+-                     if (path)
+-                     {
+-                        pfunc("1-0x%p %s\n" \
+-                              "   d_name:    %.*s\n" \
+-                              "   d_parent:  0x%p\n" \
+-                              "   d_count:   %d\n" \
+-                              "   d_flags:   0x%x\n" \
+-                              "   d_subdirs: 0x%p\n" \
+-                              "   d_inode:   0x%p\n",
+-                           d, path, d->d_name.len, d->d_name.name, d->d_parent,
+-                           atomic_read(&d->d_count), d->d_flags, d->d_subdirs.next, d->d_inode);
+-                     }
+-                  }
+-               }
+-               l = l->next;
+-            }
+-            l = start;
+-            while(l)
+-            {
+-               d=l->dentry;
+-               path = Scope_dget_path(d, buf, PATH_LENGTH_BUFFER, 1);
+-               if (path)
+-               {
+-                  sd = " (None)";
+-                  if (&d->d_subdirs != d->d_subdirs.next)
+-                  {
+-                     sd = "";
+-                  }
+-                  inode_number[0] = '\0';
+-                  if (d->d_inode)
+-                  {
+-                     sprintf(inode_number, " (%lu)", d->d_inode->i_ino);
+-                  }
+-                  pfunc("0x%p %s\n" \
+-                        "   d_parent:  0x%p\n" \
+-                        "   d_count:   %d\n" \
+-                        "   d_flags:   0x%x\n" \
+-                        "   d_subdirs: 0x%p%s\n" \
+-                        "   d_inode:   0x%p%s\n",
+-                     d, path, d->d_parent,
+-                     atomic_read(&d->d_count), d->d_flags, d->d_subdirs.next, sd, d->d_inode, inode_number);
+-               }
+-
+-               n = l;
+-               l = l->next;
+-               Novfs_Free(n);
+-            }
+-         }
+-      }
+-   }
+-
+-   Novfs_Free(buf);
+-
+-}
+-
+-/*int profile_inode_open(struct inode *inode, struct file *file)
+-{
+-
+-}
+-
+-int profile_inode_close(struct inode *inode, struct file *file)
+-{
+-}
+-*/
+-ssize_t profile_common_read( char *buf, size_t len, loff_t *off )
+-{
+-	ssize_t	retval=0;
+-	size_t	count;
+-   unsigned long offset = *off;
+-
+-	if (0 != (count = DbgPrintBufferOffset - offset))
+-   {
+-	   if (count > len)
+-	   {
+-			   count = len;
+-	   }
+-
+-	   count -= copy_to_user(buf, &DbgPrintBuffer[offset], count);
+-
+-	   if (count == 0) 
+-	   {
+-			retval = -EFAULT;
+-	   }
+-	   else
+-	   {
+-         *off += (loff_t)count;
+-		   retval = count;
+-	   }
+-   }
+-	return retval;
+-
+-}
+-
+-//ssize_t NO_TRACE profile_inode_read(struct file *file, char *buf, size_t len, loff_t *off)
+-ssize_t profile_inode_read(struct file *file, char *buf, size_t len, loff_t *off)
+-{
+-	ssize_t	retval=0;
+-   unsigned long offset = *off;
+-   static char save_DbgPrintOn;
+-
+-   if (offset == 0)
+-   {
+-      down(&LocalPrint_lock);
+-      save_DbgPrintOn = DbgPrintOn;
+-      DbgPrintOn = 0;
+-
+-   	DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
+-      Novfs_dump_inode( LocalPrint );
+-   }
+-
+-   retval = profile_common_read(buf, len, off);
+-
+-   if ( 0 == retval)
+-   {
+-      DbgPrintOn = save_DbgPrintOn;
+-   	DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
+-
+-      up(&LocalPrint_lock);
+-   }
+-
+-	return retval;
+-
+-}
+-
+-ssize_t NO_TRACE profile_dentry_read(struct file *file, char *buf, size_t len, loff_t *off)
+-{
+-	ssize_t	retval=0;
+-   unsigned long offset = *off;
+-   static char save_DbgPrintOn;
+-
+-   if (offset == 0)
+-   {
+-      down(&LocalPrint_lock);
+-      save_DbgPrintOn = DbgPrintOn;
+-      DbgPrintOn = 0;
+-   	DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
+-      profile_dump_dt(Novfs_root, LocalPrint);
+-   }
+-
+-   retval = profile_common_read(buf, len, off);
+-
+-   if ( 0 == retval)
+-   {
+-   	DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
+-      DbgPrintOn = save_DbgPrintOn;
+-
+-      up(&LocalPrint_lock);
+-   }
+-
+-	return retval;
+-
+-}
+-
+-ssize_t NO_TRACE profile_memory_read(struct file *file, char *buf, size_t len, loff_t *off)
+-{
+-	ssize_t	retval=0;
+-   unsigned long offset = *off;
+-   static char save_DbgPrintOn;
+-
+-   if (offset == 0)
+-   {
+-      down(&LocalPrint_lock);
+-      save_DbgPrintOn = DbgPrintOn;
+-      DbgPrintOn = 0;
+-   	DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
+-      profile_dump_memorylist( LocalPrint );
+-   }
+-
+-   retval = profile_common_read(buf, len, off);
+-
+-   if ( 0 == retval)
+-   {
+-   	DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
+-      DbgPrintOn = save_DbgPrintOn;
+-
+-      up(&LocalPrint_lock);
+-   }
+-
+-	return retval;
+-
+-}
+diff -uNr src.old/novfs/profile_funcs.h src/novfs/profile_funcs.h
+--- src.old/novfs/profile_funcs.h	2006-07-11 21:24:18.000000000 +0200
++++ src/novfs/profile_funcs.h	1970-01-01 01:00:00.000000000 +0100
+@@ -1,419 +0,0 @@
+-extern void Daemon_Added_Resource( void );
+-extern void Daemon_Close_Control( void );
+-extern void Daemon_CreateSessionId( void );
+-extern void Daemon_DestroySessionId( void );
+-extern void Daemon_Dumpque( void );
+-extern void Daemon_Get_UserSpace( void );
+-extern void Daemon_Library_close( void );
+-extern void Daemon_Library_ioctl( void );
+-extern void Daemon_Library_open( void );
+-extern void Daemon_Library_read( void );
+-extern void Daemon_Library_write( void );
+-extern void Daemon_Login( void );
+-extern void Daemon_Logout( void );
+-extern void Daemon_Open_Control( void );
+-extern void Daemon_Poll( void );
+-extern void Daemon_Receive_Reply( void );
+-extern void Daemon_Remove_Resource( void );
+-extern void Daemon_Send_Command( void );
+-extern void Daemon_SetMountPoint( void );
+-extern void Daemon_Timer( void );
+-extern void Daemon_getpwuid( void );
+-extern void Daemon_getversion( void );
+-extern void Daemon_ioctl( void );
+-extern void GetConnData( void );
+-extern void GetUserData( void );
+-extern void Init_Daemon_Queue( void );
+-extern void Init_Procfs_Interface( void );
+-extern void Novfs_Add_to_Root( void );
+-extern void Novfs_Add_to_Root2( void );
+-extern void Novfs_Close_File( void );
+-extern void Novfs_Close_Stream( void );
+-extern void Novfs_Control_ioctl( void );
+-extern void Novfs_Control_read( void );
+-extern void Novfs_Control_write( void );
+-extern void Novfs_Create( void );
+-extern void Novfs_Delete( void );
+-extern void Novfs_Find_Name_In_List( void );
+-extern void Novfs_Get_Connected_Server_List( void );
+-extern void Novfs_Get_Directory_List( void );
+-extern void Novfs_Get_Directory_ListEx( void );
+-extern void Novfs_Get_File_Info( void );
+-extern void Novfs_Get_File_Info2( void );
+-extern void Novfs_Get_Server_Volume_List( void );
+-extern void Novfs_Get_Version( void );
+-extern void Novfs_Open_File( void );
+-extern void Novfs_Read_File( void );
+-extern void Novfs_Read_Stream( void );
+-extern void Novfs_Remove_from_Root( void );
+-extern void Novfs_Rename_File( void );
+-extern void Novfs_Set_Attr( void );
+-extern void Novfs_Truncate_File( void );
+-extern void Novfs_User_proc_ioctl( void );
+-extern void Novfs_User_proc_read( void );
+-extern void Novfs_User_proc_write( void );
+-extern void Novfs_Verify_Server_Name( void );
+-extern void Novfs_Verify_Volume_Name( void );
+-extern void Novfs_Write_File( void );
+-extern void Novfs_Write_File2( void );
+-extern void Novfs_Write_Stream( void );
+-extern void Novfs_a_readpage( void );
+-extern void Novfs_add_inode_entry( void );
+-extern void Novfs_clear_inode( void );
+-extern void Novfs_d_add( void );
+-extern void Novfs_d_compare( void );
+-extern void Novfs_d_delete( void );
+-extern void Novfs_d_hash( void );
+-extern void Novfs_d_iput( void );
+-extern void Novfs_d_lookup( void );
+-extern void Novfs_d_release( void );
+-extern void Novfs_d_revalidate( void );
+-extern void Novfs_d_strcmp( void );
+-extern void Novfs_dget_path( void );
+-extern void Novfs_dir_fsync( void );
+-extern void Novfs_dir_lseek( void );
+-extern void Novfs_dir_open( void );
+-extern void Novfs_dir_read( void );
+-extern void Novfs_dir_readdir( void );
+-extern void Novfs_dir_release( void );
+-extern void Novfs_enumerate_inode_cache( void );
+-extern void Novfs_f_flush( void );
+-extern void Novfs_f_fsync( void );
+-extern void Novfs_f_ioctl( void );
+-extern void Novfs_f_llseek( void );
+-extern void Novfs_f_lock( void );
+-extern void Novfs_f_mmap( void );
+-extern void Novfs_f_open( void );
+-extern void Novfs_f_read( void );
+-extern void Novfs_f_readdir( void );
+-extern void Novfs_f_release( void );
+-extern void Novfs_f_write( void );
+-extern void Novfs_fill_super( void );
+-extern void Novfs_free_inode_cache( void );
+-extern void Novfs_free_invalid_entries( void );
+-extern void Novfs_get_alltrees( void );
+-extern void Novfs_get_entry( void );
+-extern void Novfs_get_entry_time( void );
+-extern void Novfs_get_inode( void );
+-extern void Novfs_get_remove_entry( void );
+-extern void Novfs_get_sb( void );
+-extern void Novfs_i_create( void );
+-extern void Novfs_i_getattr( void );
+-extern void Novfs_i_lookup( void );
+-extern void Novfs_i_mkdir( void );
+-extern void Novfs_i_mknod( void );
+-extern void Novfs_i_permission( void );
+-extern void Novfs_i_rename( void );
+-extern void Novfs_i_revalidate( void );
+-extern void Novfs_i_rmdir( void );
+-extern void Novfs_i_setattr( void );
+-extern void Novfs_i_unlink( void );
+-extern void Novfs_internal_hash( void );
+-extern void Novfs_invalidate_inode_cache( void );
+-extern void Novfs_kill_sb( void );
+-extern void Novfs_lock_inode_cache( void );
+-extern void Novfs_lookup_inode_cache( void );
+-extern void Novfs_lookup_validate( void );
+-extern void Novfs_notify_change( void );
+-extern void Novfs_read_inode( void );
+-extern void Novfs_remove_inode_entry( void );
+-extern void Novfs_show_options( void );
+-extern void Novfs_statfs( void );
+-extern void Novfs_tree_read( void );
+-extern void Novfs_unlock_inode_cache( void );
+-extern void Novfs_update_entry( void );
+-extern void Novfs_verify_file( void );
+-extern void Novfs_write_inode( void );
+-extern void NwAuthConnWithId( void );
+-extern void NwConnClose( void );
+-extern void NwGetConnInfo( void );
+-extern void NwGetDaemonVersion( void );
+-extern void NwGetIdentityInfo( void );
+-extern void NwLicenseConn( void );
+-extern void NwLoginIdentity( void );
+-extern void NwLogoutIdentity( void );
+-extern void NwOpenConnByAddr( void );
+-extern void NwOpenConnByName( void );
+-extern void NwOpenConnByRef( void );
+-extern void NwQueryFeature( void );
+-extern void NwRawSend( void );
+-extern void NwScanConnInfo( void );
+-extern void NwSetConnInfo( void );
+-extern void NwSysConnClose( void );
+-extern void NwUnAuthenticate( void );
+-extern void NwUnlicenseConn( void );
+-extern void NwcChangeAuthKey( void );
+-extern void NwcEnumIdentities( void );
+-extern void NwcEnumerateDrives( void );
+-extern void NwcGetBroadcastMessage( void );
+-extern void NwcGetDefaultNameCtx( void );
+-extern void NwcGetPreferredDSTree( void );
+-extern void NwcGetPrimaryConn( void );
+-extern void NwcGetTreeMonitoredConn( void );
+-extern void NwcSetDefaultNameCtx( void );
+-extern void NwcSetMapDrive( void );
+-extern void NwcSetPreferredDSTree( void );
+-extern void NwcSetPrimaryConn( void );
+-extern void NwcUnMapDrive( void );
+-extern void NwdConvertLocalHandle( void );
+-extern void NwdConvertNetwareHandle( void );
+-extern void NwdGetMountPath( void );
+-extern void NwdSetKeyValue( void );
+-extern void NwdSetMapDrive( void );
+-extern void NwdUnMapDrive( void );
+-extern void NwdVerifyKeyValue( void );
+-extern void Queue_Daemon_Command( void );
+-extern void Queue_get( void );
+-extern void Queue_put( void );
+-extern void RemoveDriveMaps( void );
+-extern void Scope_Cleanup( void );
+-extern void Scope_Cleanup_Thread( void );
+-extern void Scope_Dump_Scopetable( void );
+-extern void Scope_Dump_Tasklist( void );
+-extern void Scope_Find_Scope( void );
+-extern void Scope_Get_Hash( void );
+-extern void Scope_Get_ScopeUsers( void );
+-extern void Scope_Get_ScopefromName( void );
+-extern void Scope_Get_ScopefromPath( void );
+-extern void Scope_Get_SessionId( void );
+-extern void Scope_Get_Uid( void );
+-extern void Scope_Get_UserName( void );
+-extern void Scope_Get_UserSpace( void );
+-extern void Scope_Init( void );
+-extern void Scope_Lookup( void );
+-extern void Scope_Search4Scope( void );
+-extern void Scope_Set_UserSpace( void );
+-extern void Scope_Timer_Function( void );
+-extern void Scope_Uninit( void );
+-extern void Scope_Validate_Scope( void );
+-extern void Uninit_Daemon_Queue( void );
+-extern void Uninit_Procfs_Interface( void );
+-extern void add_to_list( void );
+-extern void begin_directory_enumerate( void );
+-extern void directory_enumerate( void );
+-extern void directory_enumerate_ex( void );
+-extern void do_login( void );
+-extern void do_logout( void );
+-extern void end_directory_enumerate( void );
+-extern void exit_novfs( void );
+-extern void find_queue( void );
+-extern void get_next_queue( void );
+-extern void init_novfs( void );
+-extern void local_unlink( void );
+-extern void process_list( void );
+-extern void update_inode( void );
+-extern void verify_dentry( void );
+-
+-SYMBOL_TABLE SymbolTable[] = {
+-   {Scope_Get_UserSpace, "Scope_Get_UserSpace"},
+-   {NwLoginIdentity, "NwLoginIdentity"},
+-   {Novfs_d_revalidate, "Novfs_d_revalidate"},
+-   {Daemon_SetMountPoint, "Daemon_SetMountPoint"},
+-   {Scope_Get_Hash, "Scope_Get_Hash"},
+-   {Queue_get, "Queue_get"},
+-   {Queue_Daemon_Command, "Queue_Daemon_Command"},
+-   {Novfs_dir_fsync, "Novfs_dir_fsync"},
+-   {Novfs_Read_File, "Novfs_Read_File"},
+-   {Daemon_Library_close, "Daemon_Library_close"},
+-   {NwRawSend, "NwRawSend"},
+-   {Novfs_get_inode, "Novfs_get_inode"},
+-   {Novfs_Remove_from_Root, "Novfs_Remove_from_Root"},
+-   {Novfs_Find_Name_In_List, "Novfs_Find_Name_In_List"},
+-   {Scope_Get_SessionId, "Scope_Get_SessionId"},
+-   {NwOpenConnByAddr, "NwOpenConnByAddr"},
+-   {Novfs_read_inode, "Novfs_read_inode"},
+-   {Novfs_Truncate_File, "Novfs_Truncate_File"},
+-   {Daemon_Login, "Daemon_Login"},
+-   {Scope_Get_ScopefromPath, "Scope_Get_ScopefromPath"},
+-   {NwcGetTreeMonitoredConn, "NwcGetTreeMonitoredConn"},
+-   {Novfs_write_inode, "Novfs_write_inode"},
+-   {Scope_Lookup, "Scope_Lookup"},
+-   {NwQueryFeature, "NwQueryFeature"},
+-   {Novfs_get_entry_time, "Novfs_get_entry_time"},
+-   {Novfs_Control_write, "Novfs_Control_write"},
+-   {Scope_Get_Uid, "Scope_Get_Uid"},
+-   {NwSysConnClose, "NwSysConnClose"},
+-   {NwConnClose, "NwConnClose"},
+-   {Novfs_get_entry, "Novfs_get_entry"},
+-   {Novfs_Rename_File, "Novfs_Rename_File"},
+-   {NwdConvertLocalHandle, "NwdConvertLocalHandle"},
+-   {Novfs_dir_lseek, "Novfs_dir_lseek"},
+-   {Scope_Get_ScopefromName, "Scope_Get_ScopefromName"},
+-   {NwcGetPrimaryConn, "NwcGetPrimaryConn"},
+-   {Novfs_d_strcmp, "Novfs_d_strcmp"},
+-   {Daemon_Library_ioctl, "Daemon_Library_ioctl"},
+-   {end_directory_enumerate, "end_directory_enumerate"},
+-   {directory_enumerate, "directory_enumerate"},
+-   {begin_directory_enumerate, "begin_directory_enumerate"},
+-   {NwdGetMountPath, "NwdGetMountPath"},
+-   {NwAuthConnWithId, "NwAuthConnWithId"},
+-   {Novfs_Set_Attr, "Novfs_Set_Attr"},
+-   {Daemon_getversion, "Daemon_getversion"},
+-   {Scope_Dump_Scopetable, "Scope_Dump_Scopetable"},
+-   {NwcSetMapDrive, "NwcSetMapDrive"},
+-   {Novfs_lookup_inode_cache, "Novfs_lookup_inode_cache"},
+-   {Novfs_i_mkdir, "Novfs_i_mkdir"},
+-   {Novfs_free_invalid_entries, "Novfs_free_invalid_entries"},
+-   {Novfs_dump_inode_cache, "Novfs_dump_inode_cache"},
+-   {Novfs_Write_Stream, "Novfs_Write_Stream"},
+-   {Novfs_Verify_Server_Name, "Novfs_Verify_Server_Name"},
+-   {GetConnData, "GetConnData"},
+-   {Uninit_Procfs_Interface, "Uninit_Procfs_Interface"},
+-   {Scope_Validate_Scope, "Scope_Validate_Scope"},
+-   {Scope_Timer_Function, "Scope_Timer_Function"},
+-   {Novfs_i_setattr, "Novfs_i_setattr"},
+-   {Novfs_i_mknod, "Novfs_i_mknod"},
+-   {Novfs_Verify_Volume_Name, "Novfs_Verify_Volume_Name"},
+-   {Novfs_Close_Stream, "Novfs_Close_Stream"},
+-   {Novfs_Add_to_Root, "Novfs_Add_to_Root"},
+-   {Init_Procfs_Interface, "Init_Procfs_Interface"},
+-   {Novfs_dump_inode, "Novfs_dump_inode"},
+-   {Novfs_Get_Directory_List, "Novfs_Get_Directory_List"},
+-   {Novfs_Get_Connected_Server_List, "Novfs_Get_Connected_Server_List"},
+-   {Daemon_Logout, "Daemon_Logout"},
+-   {do_logout, "do_logout"},
+-   {Scope_Search4Scope, "Scope_Search4Scope"},
+-   {NwdUnMapDrive, "NwdUnMapDrive"},
+-   {Novfs_Control_read, "Novfs_Control_read"},
+-   {Scope_Cleanup_Thread, "Scope_Cleanup_Thread"},
+-   {Novfs_invalidate_inode_cache, "Novfs_invalidate_inode_cache"},
+-   {Novfs_f_flush, "Novfs_f_flush"},
+-   {Novfs_enumerate_inode_cache, "Novfs_enumerate_inode_cache"},
+-   {Novfs_d_compare, "Novfs_d_compare"},
+-   {Daemon_Library_write, "Daemon_Library_write"},
+-   {GetUserData, "GetUserData"},
+-   {Daemon_Remove_Resource, "Daemon_Remove_Resource"},
+-   {Scope_Set_UserSpace, "Scope_Set_UserSpace"},
+-   {Novfs_get_alltrees, "Novfs_get_alltrees"},
+-   {Daemon_Get_UserSpace, "Daemon_Get_UserSpace"},
+-   {Uninit_Daemon_Queue, "Uninit_Daemon_Queue"},
+-   {NwcChangeAuthKey, "NwcChangeAuthKey"},
+-   {NwLicenseConn, "NwLicenseConn"},
+-   {Init_Daemon_Queue, "Init_Daemon_Queue"},
+-   {Novfs_tree_read, "Novfs_tree_read"},
+-   {Novfs_f_llseek, "Novfs_f_llseek"},
+-   {find_queue, "find_queue"},
+-   {Scope_Find_Scope, "Scope_Find_Scope"},
+-   {Novfs_lookup_validate, "Novfs_lookup_validate"},
+-   {Novfs_d_hash, "Novfs_d_hash"},
+-   {Novfs_a_readpage, "Novfs_a_readpage"},
+-   {Novfs_Create, "Novfs_Create"},
+-   {Novfs_Close_File, "Novfs_Close_File"},
+-   {Daemon_getpwuid, "Daemon_getpwuid"},
+-   {Daemon_CreateSessionId, "Daemon_CreateSessionId"},
+-   {Scope_dget_path, "Scope_dget_path"},
+-   {NwcSetDefaultNameCtx, "NwcSetDefaultNameCtx"},
+-   {NwcGetDefaultNameCtx, "NwcGetDefaultNameCtx"},
+-   {NwUnAuthenticate, "NwUnAuthenticate"},
+-   {Novfs_i_getattr, "Novfs_i_getattr"},
+-   {Novfs_get_remove_entry, "Novfs_get_remove_entry"},
+-   {Novfs_f_ioctl, "Novfs_f_ioctl"},
+-   {Scope_Get_ScopeUsers, "Scope_Get_ScopeUsers"},
+-   {Scope_Dump_Tasklist, "Scope_Dump_Tasklist"},
+-   {NwOpenConnByRef, "NwOpenConnByRef"},
+-   {Novfs_unlock_inode_cache, "Novfs_unlock_inode_cache"},
+-   {Novfs_lock_inode_cache, "Novfs_lock_inode_cache"},
+-   {Daemon_DestroySessionId, "Daemon_DestroySessionId"},
+-   {do_login, "do_login"},
+-   {Novfs_free_inode_cache, "Novfs_free_inode_cache"},
+-   {Novfs_Read_Stream, "Novfs_Read_Stream"},
+-   {Daemon_Library_read, "Daemon_Library_read"},
+-   {NwdSetMapDrive, "NwdSetMapDrive"},
+-   {Novfs_internal_hash, "Novfs_internal_hash"},
+-   {Daemon_Receive_Reply, "Daemon_Receive_Reply"},
+-   {Daemon_Library_open, "Daemon_Library_open"},
+-   {get_next_queue, "get_next_queue"},
+-   {exit_novfs, "exit_novfs"},
+-   {NwcGetBroadcastMessage, "NwcGetBroadcastMessage"},
+-   {Novfs_d_lookup, "Novfs_d_lookup"},
+-   {Novfs_clear_inode, "Novfs_clear_inode"},
+-   {Daemon_Open_Control, "Daemon_Open_Control"},
+-   {NwdConvertNetwareHandle, "NwdConvertNetwareHandle"},
+-   {NwcUnMapDrive, "NwcUnMapDrive"},
+-   {Novfs_notify_change, "Novfs_notify_change"},
+-   {Novfs_dir_release, "Novfs_dir_release"},
+-   {directory_enumerate_ex, "directory_enumerate_ex"},
+-   {RemoveDriveMaps, "RemoveDriveMaps"},
+-   {NwOpenConnByName, "NwOpenConnByName"},
+-   {Novfs_verify_file, "Novfs_verify_file"},
+-   {Novfs_statfs, "Novfs_statfs"},
+-   {Novfs_f_write, "Novfs_f_write"},
+-   {Novfs_Get_File_Info, "Novfs_Get_File_Info"},
+-   {Novfs_Delete, "Novfs_Delete"},
+-   {update_inode, "update_inode"},
+-   {NwcSetPreferredDSTree, "NwcSetPreferredDSTree"},
+-   {NwcGetPreferredDSTree, "NwcGetPreferredDSTree"},
+-   {Novfs_update_entry, "Novfs_update_entry"},
+-   {Novfs_kill_sb, "Novfs_kill_sb"},
+-   {Daemon_ioctl, "Daemon_ioctl"},
+-   {Scope_Get_UserName, "Scope_Get_UserName"},
+-   {NwcEnumerateDrives, "NwcEnumerateDrives"},
+-   {Novfs_i_revalidate, "Novfs_i_revalidate"},
+-   {Novfs_f_release, "Novfs_f_release"},
+-   {Novfs_f_read, "Novfs_f_read"},
+-   {Novfs_d_delete, "Novfs_d_delete"},
+-   {Novfs_Write_File, "Novfs_Write_File"},
+-   {Novfs_User_proc_ioctl, "Novfs_User_proc_ioctl"},
+-   {Novfs_Get_File_Info2, "Novfs_Get_File_Info2"},
+-   {NwdSetKeyValue, "NwdSetKeyValue"},
+-   {Novfs_remove_inode_entry, "Novfs_remove_inode_entry"},
+-   {Novfs_i_rename, "Novfs_i_rename"},
+-   {Novfs_f_open, "Novfs_f_open"},
+-   {Novfs_d_iput, "Novfs_d_iput"},
+-   {Novfs_Get_Directory_ListEx, "Novfs_Get_Directory_ListEx"},
+-   {Daemon_Timer, "Daemon_Timer"},
+-   {Daemon_Close_Control, "Daemon_Close_Control"},
+-   {verify_dentry, "verify_dentry"},
+-   {process_list, "process_list"},
+-   {local_unlink, "local_unlink"},
+-   {init_novfs, "init_novfs"},
+-   {NwUnlicenseConn, "NwUnlicenseConn"},
+-   {NwGetConnInfo, "NwGetConnInfo"},
+-   {Novfs_i_permission, "Novfs_i_permission"},
+-   {Novfs_dir_read, "Novfs_dir_read"},
+-   {NwcSetPrimaryConn, "NwcSetPrimaryConn"},
+-   {Novfs_f_lock, "Novfs_f_lock"},
+-   {Novfs_dir_readdir, "Novfs_dir_readdir"},
+-   {Novfs_dir_open, "Novfs_dir_open"},
+-   {Queue_put, "Queue_put"},
+-   {NwLogoutIdentity, "NwLogoutIdentity"},
+-   {NwGetIdentityInfo, "NwGetIdentityInfo"},
+-   {Novfs_i_rmdir, "Novfs_i_rmdir"},
+-   {Novfs_i_create, "Novfs_i_create"},
+-   {Novfs_f_mmap, "Novfs_f_mmap"},
+-   {Novfs_Write_File2, "Novfs_Write_File2"},
+-   {Novfs_User_proc_read, "Novfs_User_proc_read"},
+-   {Novfs_show_options, "Novfs_show_options"},
+-   {Novfs_add_inode_entry, "Novfs_add_inode_entry"},
+-   {Novfs_Open_File, "Novfs_Open_File"},
+-   {Novfs_Get_Version, "Novfs_Get_Version"},
+-   {Daemon_Poll, "Daemon_Poll"},
+-   {add_to_list, "add_to_list"},
+-   {Scope_Init, "Scope_Init"},
+-   {Scope_Cleanup, "Scope_Cleanup"},
+-   {NwSetConnInfo, "NwSetConnInfo"},
+-   {Novfs_i_unlink, "Novfs_i_unlink"},
+-   {Novfs_get_sb, "Novfs_get_sb"},
+-   {Novfs_f_readdir, "Novfs_f_readdir"},
+-   {Novfs_f_fsync, "Novfs_f_fsync"},
+-   {Novfs_d_release, "Novfs_d_release"},
+-   {Novfs_User_proc_write, "Novfs_User_proc_write"},
+-   {Daemon_Send_Command, "Daemon_Send_Command"},
+-   {Daemon_Dumpque, "Daemon_Dumpque"},
+-   {NwcEnumIdentities, "NwcEnumIdentities"},
+-   {NwGetDaemonVersion, "NwGetDaemonVersion"},
+-   {Novfs_i_lookup, "Novfs_i_lookup"},
+-   {Novfs_fill_super, "Novfs_fill_super"},
+-   {Novfs_Get_Server_Volume_List, "Novfs_Get_Server_Volume_List"},
+-   {Novfs_Add_to_Root2, "Novfs_Add_to_Root2"},
+-   {Daemon_SendDebugCmd, "Daemon_SendDebugCmd"},
+-   {Daemon_Added_Resource, "Daemon_Added_Resource"},
+-   {Scope_Uninit, "Scope_Uninit"},
+-   {NwdVerifyKeyValue, "NwdVerifyKeyValue"},
+-   {NwScanConnInfo, "NwScanConnInfo"},
+-   {Novfs_dget_path, "Novfs_dget_path"},
+-   {Novfs_d_add, "Novfs_d_add"},
+-   {Novfs_Control_ioctl, "Novfs_Control_ioctl"},
+-   // Terminate the table
+-   {NULL, NULL}
+-};
+diff -uNr src.old/novfs/scope.c src/novfs/scope.c
+--- src.old/novfs/scope.c	2006-07-11 21:24:18.000000000 +0200
++++ src/novfs/scope.c	1970-01-01 01:00:00.000000000 +0100
+@@ -1,1210 +0,0 @@
+-/*++========================================================================
+- * Program Name:     Novell NCP Redirector for Linux
+- * File Name:        scope.c
+- * Version:          v1.00
+- * Author:           James Turner
+- *
+- * Abstract:         This module contains functions used to scope
+- *                   users.
+- * Notes:
+- * Revision History: 
+- *
+- *
+- * Copyright (C) 2005 Novell, Inc.
+- *
+- * 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 files specific to Linux ]==================================*/
+-#include <linux/version.h>
+-#include <linux/module.h>
+-#include <linux/kthread.h>
+-#include <linux/fs.h>
+-#include <linux/file.h>
+-#include <linux/sched.h>
+-#include <linux/personality.h>
+-#include <linux/module.h>
+-#include <linux/slab.h>
+-#include <linux/synclink.h>
+-#include <linux/smp_lock.h>
+-#include <asm/semaphore.h>
+-#include <linux/security.h>
+-#include <linux/syscalls.h>
+-
+-/*===[ Include files specific to this module ]============================*/
+-#include "vfs.h"
+-#define LEADER signal->leader
+-
+-/*===[ External data ]====================================================*/
+-
+-/*===[ External prototypes ]==============================================*/
+-extern int DbgPrint( char *Fmt, ... );
+-extern int Daemon_CreateSessionId( uint64_t *SessionId );
+-extern int Daemon_DestroySessionId( uint64_t SessionId );
+-extern int Daemon_getpwuid( uid_t uid, int unamelen, char *uname );
+-extern int Daemon_Get_UserSpace( uint64_t SessionId,  uint64_t *TotalSize, uint64_t *TotalFree, uint64_t *TotalDirectoryEnties, uint64_t *FreeDirectoryEnties);
+-
+-extern int Novfs_Remove_from_Root(char *);
+-extern int Novfs_Add_to_Root(char *);
+-
+-/*===[ Manifest constants ]===============================================*/
+-#define CLEANUP_INTERVAL      10
+-#define MAX_USERNAME_LENGTH   32
+-
+-/*===[ Type definitions ]=================================================*/
+-typedef struct _SCOPE_LIST_
+-{
+-   struct list_head  ScopeList;
+-   scope_t           ScopeId;
+-   session_t         SessionId;
+-   pid_t             ScopePid;
+-   task_t           *ScopeTask;
+-   unsigned long     ScopeHash;
+-   uid_t             ScopeUid;
+-   uint64_t          ScopeUSize;
+-   uint64_t          ScopeUFree;
+-   uint64_t          ScopeUTEnties;
+-   uint64_t          ScopeUAEnties;
+-   int               ScopeUserNameLength;
+-   unsigned char     ScopeUserName[MAX_USERNAME_LENGTH];
+-} SCOPE_LIST, *PSCOPE_LIST;
+-
+-/*===[ Function prototypes ]==============================================*/
+-void Scope_Init( void );
+-void Scope_Uninit( void );
+-
+-PSCOPE_LIST Scope_Search4Scope( session_t Id, BOOLEAN Session, BOOLEAN Locked );
+-PSCOPE_LIST Scope_Find_Scope( BOOLEAN Create );
+-unsigned long Scope_Get_Hash( PSCOPE_LIST Scope );
+-uid_t Scope_Get_Uid( PSCOPE_LIST Scope );
+-int Scope_Validate_Scope( PSCOPE_LIST Scope );
+-char *Scope_Get_UserName( PSCOPE_LIST Scope );
+-session_t Scope_Get_SessionId( PSCOPE_LIST Scope );
+-PSCOPE_LIST Scope_Get_ScopefromName( struct qstr *Name );
+-int Scope_Set_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties );
+-int Scope_Get_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties );
+-
+-char *Scope_Get_ScopeUsers( void );
+-void *Scope_Lookup( void );
+-
+-void Scope_Timer_Function(unsigned long Context);
+-int Scope_Cleanup_Thread(void *Args);
+-void Scope_Cleanup( void );
+-char  *Scope_dget_path( struct dentry *Dentry, char *Buf, unsigned int Buflen, int Flags);
+-void Scope_Dump_Tasklist( void );
+-void Scope_Dump_Scopetable( void );
+-
+-/*===[ Global variables ]=================================================*/
+-struct list_head  Scope_List;
+-struct semaphore  Scope_Lock;
+-struct semaphore  Scope_Thread_Delay;
+-int               Scope_Thread_Terminate=0;
+-struct semaphore  Scope_Delay_Event;
+-struct timer_list Scope_Timer;
+-unsigned long     Scope_Hash_Val=1;
+-
+-/*===[ Code ]=============================================================*/
+-
+-/*++======================================================================*/
+-void Scope_Init( void )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   INIT_LIST_HEAD( &Scope_List );
+-   init_MUTEX( &Scope_Lock );
+-   init_MUTEX_LOCKED( &Scope_Thread_Delay );
+-
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7)
+-   kernel_thread( Scope_Cleanup_Thread, NULL, 0 );
+-#else
+-   kthread_run(Scope_Cleanup_Thread, NULL, "novfs_ST");
+-#endif
+-}
+-
+-/*++======================================================================*/
+-void Scope_Uninit( void )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   Scope_Thread_Terminate = 1;
+-
+-   up(&Scope_Thread_Delay);
+-
+-   mb();
+-   while( Scope_Thread_Terminate )
+-   {
+-      yield();
+-   }
+-   printk( KERN_INFO "Scope_Uninit: Exit\n");
+-   
+-}
+-
+-/*++======================================================================*/
+-PSCOPE_LIST Scope_Search4Scope( session_t Id, BOOLEAN Session, BOOLEAN Locked )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PSCOPE_LIST scope, rscope=NULL;
+-   struct list_head *sl;
+-   int  offset;
+-
+-   DbgPrint("Scope_Search4Scope: 0x%llx 0x%x 0x%x\n", Id, Session, Locked);
+-
+-   if ( Session )
+-   {
+-      offset = (int)(&((PSCOPE_LIST)0)->SessionId);
+-   }
+-   else
+-   {
+-      offset = (int)(&((PSCOPE_LIST)0)->ScopeId);
+-   }
+-
+-   if ( !Locked ) 
+-   {
+-      down( &Scope_Lock );
+-   }
+-
+-   sl = Scope_List.next;
+-   DbgPrint("Scope_Search4Scope: 0x%x\n", sl);
+-   while (sl != &Scope_List)
+-   {
+-      scope = list_entry(sl, SCOPE_LIST, ScopeList);
+-
+-      if ( Id == *(session_t *)((char *)scope+offset) )
+-      {
+-         rscope = scope;
+-         break;
+-      }
+-
+-      sl = sl->next;
+-   }
+-
+-   if ( !Locked )
+-   {
+-      up( &Scope_Lock );
+-   }
+-
+-   DbgPrint("Scope_Search4Scope: return 0x%x\n", rscope);
+-   return( rscope );
+-}
+-
+-/*++======================================================================*/
+-PSCOPE_LIST Scope_Find_Scope( BOOLEAN Create )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PSCOPE_LIST scope=NULL, pscope=NULL;
+-   task_t *task;
+-   scope_t scopeId;
+-   int addscope=0;
+-
+-   task = current;
+-
+-   DbgPrint("Scope_Find_Scope: %d %d %d %d\n", task->uid, task->euid, task->suid, task->fsuid);
+-
+-   scopeId = task->euid;
+-
+-   scope = Scope_Search4Scope( scopeId, FALSE, FALSE );
+-   
+-   if ( !scope && Create )
+-   {
+-      scope = Novfs_Malloc( sizeof(*pscope), GFP_KERNEL );
+-      if ( scope )
+-      {
+-         scope->ScopeId          = scopeId;
+-         scope->SessionId        = 0;
+-         scope->ScopePid         = task->pid;
+-         scope->ScopeTask        = task;
+-         scope->ScopeHash        = 0;
+-         scope->ScopeUid         = task->euid;
+-         scope->ScopeUserName[0] = '\0';
+-
+-         if ( !Daemon_CreateSessionId( &scope->SessionId ) )
+-         {
+-            DbgPrint("Scope_Find_Scope2: %d %d %d %d\n", task->uid, task->euid, task->suid, task->fsuid);
+-            memset(scope->ScopeUserName, 0, sizeof(scope->ScopeUserName));
+-            scope->ScopeUserNameLength = 0;
+-            Daemon_getpwuid(task->euid, sizeof(scope->ScopeUserName), scope->ScopeUserName);
+-            scope->ScopeUserNameLength = strlen(scope->ScopeUserName);
+-            addscope = 1;
+-         }
+-
+-         scope->ScopeHash = Scope_Hash_Val++;
+-         DbgPrint("Scope_Find_Scope: Adding 0x%x\n" \
+-                  "   ScopeId:             0x%llx\n" \
+-                  "   SessionId:           0x%llx\n" \
+-                  "   ScopePid:            %d\n" \
+-                  "   ScopeTask:           0x%x\n" \
+-                  "   ScopeHash:           %d\n" \
+-                  "   ScopeUid:            %d\n" \
+-                  "   ScopeUserNameLength: %d\n" \
+-                  "   ScopeUserName:       %s\n",
+-            scope, 
+-            scope->ScopeId, 
+-            scope->SessionId, 
+-            scope->ScopePid, 
+-            scope->ScopeTask, 
+-            scope->ScopeHash,
+-            scope->ScopeUid,
+-            scope->ScopeUserNameLength,
+-            scope->ScopeUserName);
+-
+-         if ( scope->SessionId )
+-         {
+-            down( &Scope_Lock );
+-            list_add(&scope->ScopeList, &Scope_List);
+-            up( &Scope_Lock );
+-         }
+-         else
+-         {
+-            Novfs_Free(scope);
+-            scope = NULL;
+-         }
+-      }
+-
+-      if (addscope)
+-      {
+-         Novfs_Add_to_Root( scope->ScopeUserName );
+-      }
+-   }
+-
+-   return(scope);
+-}
+-
+-/*++======================================================================*/
+-unsigned long Scope_Get_Hash( PSCOPE_LIST Scope )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   unsigned long hash=0;
+-   
+-   if ( NULL == Scope)
+-   {
+-      Scope = Scope_Find_Scope( TRUE );
+-   }
+-
+-   if ( Scope && Scope_Validate_Scope( Scope ))
+-   {
+-      hash = Scope->ScopeHash;
+-   }
+-   return( hash );
+-}
+-
+-/*++======================================================================*/
+-uid_t Scope_Get_Uid( PSCOPE_LIST Scope )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   uid_t uid=0;
+-   
+-   if ( NULL == Scope)
+-   {
+-      Scope = Scope_Find_Scope( TRUE );
+-   }
+-
+-   if ( Scope && Scope_Validate_Scope( Scope ))
+-   {
+-      uid = Scope->ScopeUid;
+-   }
+-   return( uid );
+-}
+-
+-/*++======================================================================*/
+-int Scope_Validate_Scope( PSCOPE_LIST Scope )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PSCOPE_LIST s;
+-   struct list_head *sl;
+-   int retVal = 0;
+-
+-   DbgPrint("Scope_Validate_Scope: 0x%x\n", Scope);
+-
+-   down( &Scope_Lock );
+-
+-   sl = Scope_List.next;
+-   while (sl != &Scope_List)
+-   {
+-      s = list_entry(sl, SCOPE_LIST, ScopeList);
+-
+-      if ( s == Scope )
+-      {
+-         retVal = 1;
+-         break;
+-      }
+-
+-      sl = sl->next;
+-   }
+-
+-   up( &Scope_Lock );
+-
+-   return( retVal );
+-}
+-
+-/*++======================================================================*/
+-char *Scope_Get_UserName( PSCOPE_LIST Scope )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   char *name=NULL;
+-   
+-   if ( !Scope )
+-   {
+-      Scope = Scope_Find_Scope( TRUE );
+-   }
+-
+-   if ( Scope && Scope_Validate_Scope( Scope ))
+-   {
+-      name = Scope->ScopeUserName;
+-   }
+-   return( name );
+-}
+-
+-/*++======================================================================*/
+-session_t Scope_Get_SessionId( PSCOPE_LIST Scope )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   session_t sessionId=0;
+-   
+-   DbgPrint("Scope_Get_SessionId: 0x%p\n", Scope);
+-   if ( !Scope )
+-   {
+-      Scope = Scope_Find_Scope( TRUE );
+-   }
+-
+-   if ( Scope && Scope_Validate_Scope( Scope ))
+-   {
+-      sessionId = Scope->SessionId;
+-   }
+-   DbgPrint("Scope_Get_SessionId: return 0x%llx\n", sessionId);
+-   return( sessionId );
+-}
+-
+-/*++======================================================================*/
+-PSCOPE_LIST Scope_Get_ScopefromName( struct qstr *Name )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PSCOPE_LIST scope, rscope=NULL;
+-   struct list_head *sl;
+-
+-   DbgPrint("Scope_Get_ScopefromName: %.*s\n", Name->len, Name->name);
+-
+-   down( &Scope_Lock );
+-
+-   sl = Scope_List.next;
+-   while (sl != &Scope_List)
+-   {
+-      scope = list_entry(sl, SCOPE_LIST, ScopeList);
+-
+-      if ( (Name->len == scope->ScopeUserNameLength) &&
+-           (0 == strncmp(scope->ScopeUserName, Name->name, Name->len)) )
+-      {
+-         rscope = scope;
+-         break;
+-      }
+-
+-      sl = sl->next;
+-   }
+-
+-   up( &Scope_Lock );
+-
+-   return( rscope );
+-}
+-
+-/*++======================================================================*/
+-int Scope_Set_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PSCOPE_LIST scope;
+-   int retVal=0;
+-
+-   scope = Scope_Find_Scope( TRUE );
+-
+-   if ( scope )
+-   {
+-      if (TotalSize)    scope->ScopeUSize = *TotalSize;
+-      if (Free)         scope->ScopeUFree = *Free;
+-      if (TotalEnties)  scope->ScopeUTEnties = *TotalEnties;
+-      if (FreeEnties)   scope->ScopeUAEnties = *FreeEnties;
+-   }
+-
+-
+-   return( retVal );
+-}
+-
+-/*++======================================================================*/
+-int Scope_Get_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PSCOPE_LIST scope;
+-   int retVal=0;
+-
+-   uint64_t td, fd, te, fe;
+-
+-   scope = Scope_Find_Scope( TRUE );
+-
+-   td = fd = te = fe = 0;
+-   if ( scope )
+-   {
+-
+-      retVal = Daemon_Get_UserSpace(scope->SessionId, &td, &fd, &te, &fe);
+-
+-      scope->ScopeUSize = td;
+-      scope->ScopeUFree = fd;
+-      scope->ScopeUTEnties = te;
+-      scope->ScopeUAEnties = fe;
+-   }
+-
+-   if (TotalSize) *TotalSize = td;
+-   if (Free) *Free = fd;
+-   if (TotalEnties) *TotalEnties = te;
+-   if (FreeEnties) *FreeEnties = fe;
+-
+-   return( retVal );
+-}
+-
+-/*++======================================================================*/
+-PSCOPE_LIST Scope_Get_ScopefromPath( struct dentry *Dentry )
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PSCOPE_LIST scope=NULL;
+-   char *buf, *path, *cp;
+-   struct qstr name;
+-
+-   buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+-   if (buf)
+-   {
+-      path = Scope_dget_path( Dentry, buf, PATH_LENGTH_BUFFER, 0 );
+-      if (path)
+-      {
+-         DbgPrint("Scope_Get_ScopefromPath: %s\n", path );
+-
+-         if (*path == '/') path++;
+-
+-         cp = path;
+-         if ( *cp )
+-         {
+-            while ( *cp && (*cp != '/') ) cp++;
+-
+-            *cp = '\0';
+-            name.hash = 0;
+-            name.len = (int)(cp-path);
+-            name.name = path;
+-            scope = Scope_Get_ScopefromName( &name );
+-         }
+-      }
+-      Novfs_Free(buf);
+-   }
+-
+-   return( scope );
+-}
+-
+-/*++======================================================================*/
+-char *add_to_list(char *Name, char *List, char *EndOfList)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   while (*Name && (List < EndOfList) )
+-   {
+-      *List++ = *Name++;
+-   }
+-
+-   if (List < EndOfList)
+-   {
+-      *List++ = '\0';
+-   }
+-   return(List);
+-}
+-
+-/*++======================================================================*/
+-char *Scope_Get_ScopeUsers()
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PSCOPE_LIST scope;
+-   struct list_head *sl;
+-   int asize=8*MAX_USERNAME_LENGTH;
+-   char *list, *cp, *ep;
+-   
+-   DbgPrint("Scope_Get_ScopeUsers\n");
+-
+-   do /* Copy list until done or out of memory */
+-   {
+-      list = Novfs_Malloc(asize, GFP_KERNEL);
+-
+-      DbgPrint("Scope_Get_ScopeUsers list=0x%p\n", list);
+-      if (list)
+-      {
+-         cp = list;
+-         ep = cp+asize;
+-
+-         /*
+-          * Add the tree and server entries
+-          */
+-         cp = add_to_list(TREE_DIRECTORY_NAME, cp, ep);
+-         cp = add_to_list(SERVER_DIRECTORY_NAME, cp, ep);
+-
+-         down( &Scope_Lock );
+-
+-         sl = Scope_List.next;
+-         while ( (sl != &Scope_List) && (cp < ep) )
+-         {
+-            scope = list_entry(sl, SCOPE_LIST, ScopeList);
+-
+-            DbgPrint("Scope_Get_ScopeUsers found 0x%p %s\n", scope, scope->ScopeUserName);
+-
+-            cp = add_to_list(scope->ScopeUserName, cp, ep);
+-            
+-            sl = sl->next;
+-         }
+-
+-         up( &Scope_Lock );
+-
+-         if (cp < ep)
+-         {
+-            *cp++ = '\0';
+-            asize = 0;
+-         }
+-         else  /* Allocation was to small, up size */
+-         {
+-            asize *= 4;
+-            Novfs_Free(list);
+-            list=NULL;
+-         }
+-      }
+-      else /* if allocation fails return an empty list */
+-      {
+-         break;
+-      }
+-   } while ( !list );  /* List was to small try again */
+-
+-   return( list );
+-}
+-
+-/*++======================================================================*/
+-void *Scope_Lookup()
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PSCOPE_LIST scope;
+-
+-   scope = Scope_Find_Scope( TRUE );
+-   return( scope );
+-}
+-
+-/*++======================================================================*/
+-void 
+-NO_TRACE
+-Scope_Timer_Function(unsigned long Context)
+-/*
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   up(&Scope_Thread_Delay);
+-}
+-
+-/*++======================================================================*/
+-int Scope_Cleanup_Thread(void *Args)
+-/*
+- *
+- *  Arguments:
+- *
+- *  Returns:
+- *
+- *  Abstract:
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PSCOPE_LIST scope, rscope;
+-   struct list_head *sl, cleanup;
+-   task_t *task;
+-
+-   DbgPrint( "Scope_Cleanup_Thread: %d\n", current->pid);
+-
+-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7)
+-   lock_kernel();
+-   snprintf(current->comm, 16, "novfs_ST");
+-   unlock_kernel();
+-   sys_close(0);
+-   sys_close(1);
+-   sys_close(2);
+-#endif
+-
+-	/*
+-	 * Setup and start que timer
+-    */
+-	init_timer( &Scope_Timer );
+-
+-   for ( ;; )
+-   {
+-      DbgPrint( "Scope_Cleanup_Thread: looping\n");
+-      if ( Scope_Thread_Terminate )
+-      {
+-         break;
+-      }
+-
+-      /*
+-       * Check scope list for any terminated processes
+-       */
+-      down( &Scope_Lock );
+-
+-      sl = Scope_List.next;
+-      INIT_LIST_HEAD( &cleanup );
+-
+-      while (sl != &Scope_List)
+-      {
+-         scope = list_entry(sl, SCOPE_LIST, ScopeList);
+-         sl = sl->next;
+-
+-         rscope = NULL;
+-         read_lock(&tasklist_lock);
+-         for_each_process(task)
+-         {
+-            if ( (task->uid == scope->ScopeUid) || (task->euid == scope->ScopeUid) )
+-            {
+-               rscope = scope;
+-               break;
+-            }
+-         }
+-         read_unlock(&tasklist_lock);
+-         if ( !rscope )
+-         {
+-            list_move( &scope->ScopeList, &cleanup );
+-            DbgPrint("Scope_Cleanup_Thread: Scope=0x%x\n", rscope);
+-         }
+-      }         
+-
+-      up(&Scope_Lock);
+-
+-      sl = cleanup.next;
+-      while ( sl != &cleanup )
+-      {
+-         scope = list_entry(sl, SCOPE_LIST, ScopeList);
+-         sl = sl->next;
+-
+-         DbgPrint("Scope_Cleanup_Thread: Removing 0x%x\n" \
+-                  "   ScopeId:       0x%llx\n" \
+-                  "   SessionId:     0x%llx\n" \
+-                  "   ScopePid:      %d\n" \
+-                  "   ScopeTask:     0x%x\n" \
+-                  "   ScopeHash:     %d\n" \
+-                  "   ScopeUid:      %d\n" \
+-                  "   ScopeUserName: %s\n",
+-            scope, 
+-            scope->ScopeId, 
+-            scope->SessionId, 
+-            scope->ScopePid, 
+-            scope->ScopeTask, 
+-            scope->ScopeHash,
+-            scope->ScopeUid,
+-            scope->ScopeUserName);
+-         if ( !Scope_Search4Scope(scope->SessionId, TRUE, FALSE) )
+-         {
+-            Novfs_Remove_from_Root( scope->ScopeUserName );
+-            Daemon_DestroySessionId( scope->SessionId );
+-         }
+-         Novfs_Free( scope );
+-      }
+-
+-      Scope_Timer.expires = jiffies + HZ*CLEANUP_INTERVAL;
+-      Scope_Timer.data = (unsigned long)0;
+-      Scope_Timer.function = Scope_Timer_Function;
+-      add_timer(&Scope_Timer);
+-      DbgPrint( "Scope_Cleanup_Thread: sleeping\n");
+-
+-      if (down_interruptible( &Scope_Thread_Delay ))
+-      {
+-         break;
+-      }
+-      del_timer(&Scope_Timer);
+-   }
+-   Scope_Thread_Terminate = 0;
+-
+-   printk( KERN_INFO "Scope_Cleanup_Thread: Exit\n");
+-   DbgPrint( "Scope_Cleanup_Thread: Exit\n");
+-   return(0);
+-}
+-
+-/*++======================================================================*/
+-void Scope_Cleanup( void )
+-/*
+- *
+- *  Arguments:   None
+- *
+- *  Returns:     Nothing
+- *
+- *  Abstract:    Removes all knows scopes.
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   PSCOPE_LIST scope;
+-   struct list_head *sl;
+-
+-   DbgPrint( "Scope_Cleanup:\n");
+-
+-   /*
+-    * Check scope list for any terminated processes
+-    */
+-   down( &Scope_Lock );
+-
+-   sl = Scope_List.next;
+-
+-   while (sl != &Scope_List)
+-   {
+-      scope = list_entry( sl, SCOPE_LIST, ScopeList );
+-      sl = sl->next;
+-
+-      list_del( &scope->ScopeList );
+-
+-      DbgPrint("Scope_Cleanup: Removing 0x%x\n" \
+-               "   ScopeId:       0x%llx\n" \
+-               "   SessionId:     0x%llx\n" \
+-               "   ScopePid:      %d\n" \
+-               "   ScopeTask:     0x%x\n" \
+-               "   ScopeHash:     %d\n" \
+-               "   ScopeUid:      %d\n" \
+-               "   ScopeUserName: %s\n",
+-         scope, 
+-         scope->ScopeId, 
+-         scope->SessionId, 
+-         scope->ScopePid, 
+-         scope->ScopeTask, 
+-         scope->ScopeHash,
+-         scope->ScopeUid,
+-         scope->ScopeUserName);
+-      if ( !Scope_Search4Scope( scope->SessionId, TRUE, TRUE ) )
+-      {
+-         Novfs_Remove_from_Root( scope->ScopeUserName );
+-         Daemon_DestroySessionId( scope->SessionId );
+-      }
+-      Novfs_Free( scope );
+-   }         
+-
+-   up(&Scope_Lock);
+-
+-}
+-
+-/*++======================================================================*/
+-char  *
+-NO_TRACE
+-Scope_dget_path( struct dentry *Dentry, char *Buf, unsigned int Buflen, int Flags)
+-/*
+- *  Arguments:   struct dentry *Dentry - starting entry
+- *               char *Buf - pointer to memory buffer
+- *               unsigned int Buflen - size of memory buffer
+- *
+- *  Returns:     pointer to path.
+- *
+- *  Abstract:    Walks the dentry chain building a path.
+- *
+- *  Notes:
+- *
+- *  Environment:
+- *
+- *========================================================================*/
+-{
+-   char *retval=&Buf[Buflen];
+-   struct dentry *p=Dentry;
+-   int len;
+-
+-   *(--retval) = '\0';
+-   Buflen--;
+-
+-/*
+-   if (!IS_ROOT(p))
+-   {
+-      while (Buflen && !IS_ROOT(p))
+-      {
+-         if (Buflen > p->d_name.len)
+-         {
+-            retval -= p->d_name.len;
+-            Buflen -= p->d_name.len;
+-            memcpy(retval, p->d_name.name, p->d_name.len);
+-            *(--retval) = '/';
+-            Buflen--;
+-            p = p->d_parent;
+-         }
+-         else
+-         {
+-            retval = NULL;
+-            break;
+-         }
+-      }
+-   }
+-   if (Flags)
+-   {
+-      len = strlen(p->d_sb->s_type->name);
+-      if (Buflen-len > 0)
+-      {
+-         retval -= len;
+-         Buflen -= len;
+-         memcpy(retval, p->d_sb->s_type->name, len);
+-         *(--retval) = '/';
+-         Buflen--;
+-      }
+-   }
+-   else
+-   {
+-      *(--retval) = '/';
+-      Buflen--;
+-   }
+-*/
+-   do
+-   {
+-      if (Buflen > p->d_name.len)
+-      {
+-         retval -= p->d_name.len;
+-         Buflen -= p->d_name.len;
+-         memcpy(retval, p->d_name.name, p->d_name.len);
+-         *(--retval) = '/';
+-         Buflen--;
+-         p = p->d_parent;
+-      }
+-      else
+-      {
+-         retval = NULL;
+-         break;
+-      }
+-   } while (!IS_ROOT(p));
+-
+-   if (IS_ROOT(Dentry))
+-   {
+-      retval++;
+-   }
+-   
+-   if (Flags)
+-   {
+-      len = strlen(p->d_sb->s_type->name);
+-      if (Buflen-len > 0)
+-      {
+-         retval -= len;
+-         Buflen -= len;
+-         memcpy(retval, p->d_sb->s_type->name, len);
+-         *(--retval) = '/';
+-         Buflen--;
+-      }
+-   }
+-
+-   return(retval);
+-}
+-
+-void Scope_Dump_Tasklist( void )
+-{
+-#ifdef	OLD_DEBUG_KERNEL
+-   task_t *task;
+-   struct files_struct *fs;
+-   int i, open_files=0;
+-   static char buf[1024];
+-   char *path;
+-
+-   
+-   for_each_process(task)
+-   {
+-      kdb_printf("Task List:\n" \
+-                 "   Task:           0x%p\n" \
+-                 "   pid:            %d\n" \
+-                 "   tgid:           %d\n" \
+-                 "   uid:            %d %d %d %d\n" \
+-                 "   gid:            %d\n" \
+-                 "   parent:         0x%p\n" \
+-                 "   comm:           %s\n" \
+-                 "   user:           0x%p\n" \
+-                 "   real_parent:    0x%p\n" \
+-                 "   parent_exec_id: 0x%x\n" \
+-                 "   self_exec_id:   0x%x\n" \
+-                 "   did_exec:       0x%x\n" \
+-                 "   signal:         0x%p\n" \
+-                 "   thread_info:    0x%p\n" \
+-                 "   security:       0x%p\n",
+-            task,
+-            task->pid,
+-            task->tgid,
+-            task->uid,task->euid,task->suid,task->fsuid,
+-            task->gid,
+-            task->parent,
+-            task->comm,
+-            task->user,
+-            task->real_parent,
+-            task->parent_exec_id,
+-            task->self_exec_id,
+-            task->did_exec,
+-            task->signal,
+-            task->thread_info,
+-            task->security);
+-      
+-      fs = task->files;
+-      kdb_printf("   File List:      0x%p\n", fs);
+-      if (fs)
+-      {
+-         open_files = fs->max_fds;
+-         kdb_printf("   Max fds:        %d\n", open_files);
+-         for (i = 0; i<open_files; i++) 
+-         {
+-            struct file *f = fs->fd[i];
+-            if (f && (f->f_dentry))
+-            {
+-               path = Scope_dget_path(f->f_dentry, buf, sizeof(buf), 1);
+-               if ( !path )
+-               {
+-                  path = buf;
+-                  memcpy(path, f->f_dentry->d_name.name, f->f_dentry->d_name.len);
+-                  path[f->f_dentry->d_name.len] = '\0';
+-               }
+-               kdb_printf("      file(%d): 0x%p\n" \
+-                          "         f_dentry: 0x%p\n" \
+-                          "            d_name:  %s\n" \
+-                          "            d_count: %d\n" \
+-                          "            d_inode: 0x%p\n",
+-                  i, f, f->f_dentry, path, 
+-                  atomic_read(&f->f_dentry->d_count), 
+-                  f->f_dentry->d_inode);
+-            }
+-         }
+-      }
+-   }
+-#endif
+-}
+-
+-void Scope_Dump_Scopetable( void )
+-{
+-#ifdef	CONFIG_KDB
+-   PSCOPE_LIST scope;
+-   struct list_head *sl;
+-
+-   sl = Scope_List.next;
+-   while (sl != &Scope_List)
+-   {
+-      scope = list_entry(sl, SCOPE_LIST, ScopeList);
+-      sl = sl->next;
+-      kdb_printf("Scope List:\n" \
+-                 "   Scope:         0x%p\n" \
+-                 "   ScopeId:       0x%llx\n" \
+-                 "   SessionId:     0x%llx\n" \
+-                 "   ScopePid:      %u\n" \
+-                 "   ScopeTask:     0x%p\n" \
+-                 "   ScopeHash:     0x%lx\n" \
+-                 "   ScopeUid:      %ld\n" \
+-                 "   ScopeUserName: %s\n",
+-         scope, 
+-         scope->ScopeId, 
+-         scope->SessionId, 
+-         scope->ScopePid, 
+-         scope->ScopeTask, 
+-         scope->ScopeHash,
+-         (long)scope->ScopeUid,
+-         scope->ScopeUserName);
+-
+-   }         
+-
+-#endif
+-}
+diff -uNr src.old/novfs/vfs.h src/novfs/vfs.h
+--- src.old/novfs/vfs.h	2006-07-11 21:24:18.000000000 +0200
++++ src/novfs/vfs.h	1970-01-01 01:00:00.000000000 +0100
+@@ -1,276 +0,0 @@
+-/*++========================================================================
+- * Program Name:     Novell NCP Redirector for Linux
+- * File Name:        vfs.h
+- * Version:          v1.00
+- * Author:           James Turner
+- *
+- * Abstract:         Include module for novfs.
+- * Notes:
+- * Revision History: 
+- *
+- *
+- * Copyright (C) 2005 Novell, Inc.
+- *
+- * 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.
+- *======================================================================--*/
+-#ifndef __STDC_VERSION__
+-#define __STDC_VERSION__ 0L
+-#endif
+-
+-/*===[ Include files specific to Linux ]==================================*/
+-#ifdef	CONFIG_KDB
+-#include <linux/kdb.h>
+-#include <linux/kdbprivate.h>
+-
+-#endif	/* CONFIG_KDB */
+-
+-#include <linux/version.h>
+-#include <linux/namei.h>
+-
+-/*===[ Include files specific to this module ]============================*/
+-
+-/*===[ External data ]====================================================*/
+-extern int Novfs_Version_Major;
+-extern int Novfs_Version_Minor;
+-extern int Novfs_Version_Sub;
+-extern int Novfs_Version_Release;
+-
+-/*===[ External prototypes ]==============================================*/
+-extern void *Novfs_Malloc( size_t, int );
+-extern void  Novfs_Free( const void * );
+-
+-
+-/*===[ Manifest constants ]===============================================*/
+-#define NOVFS_MAGIC	0x4e574653
+-#define MODULE_NAME "novfs"
+-
+-#define UNUSED_VARIABLE(a) (a) = (a)
+-
+-#define TREE_DIRECTORY_NAME   ".Trees"
+-#define SERVER_DIRECTORY_NAME ".Servers"
+-
+-#define PATH_LENGTH_BUFFER	PATH_MAX
+-#define NW_MAX_PATH_LENGTH 255
+-
+-#define IOC_LOGIN    0x4a540000
+-#define IOC_LOGOUT	0x4a540001
+-#define IOC_XPLAT    0x4a540002
+-#define IOC_SESSION  0x4a540003
+-#define IOC_DEBUGPRINT  0x4a540004
+-
+-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
+-#define D_CHILD d_u.d_child
+-#else
+-#define D_CHILD d_child
+-#endif
+-
+-/*
+- * NetWare file attributes
+- */
+-
+-#define  NW_ATTRIBUTE_NORMAL                    0x00
+-#define  NW_ATTRIBUTE_READ_ONLY                 0x01
+-#define  NW_ATTRIBUTE_HIDDEN                    0x02
+-#define  NW_ATTRIBUTE_SYSTEM                    0x04
+-#define  NW_ATTRIBUTE_EXECUTE_ONLY              0x08
+-#define  NW_ATTRIBUTE_DIRECTORY                 0x10
+-#define  NW_ATTRIBUTE_ARCHIVE                   0x20
+-#define  NW_ATTRIBUTE_EXECUTE                   0x40
+-#define  NW_ATTRIBUTE_SHAREABLE                 0x80
+-
+-/*
+- * Define READ/WRITE flag for DATA_LIST
+- */
+-#define DLREAD    0
+-#define DLWRITE   1
+-
+-/*
+- * Define list type
+- */
+-#define USER_LIST    1
+-#define SERVER_LIST  2
+-#define VOLUME_LIST  3
+-
+-/*
+- * Define flags used in for inodes
+- */
+-#define  USER_INODE     1
+-#define  UPDATE_INODE   2
+-
+-/*
+- * Define flags for directory cache flags
+- */
+-#define ENTRY_VALID  0x00000001
+-
+-#ifdef INTENT_MAGIC
+-#define NDOPENFLAGS intent.it_flags
+-#else
+-#define NDOPENFLAGS intent.open.flags
+-#endif
+-
+-/*
+- * daemon_command_t flags values
+- */
+-#define INTERRUPTIBLE   1
+-
+-#define NO_TRACE __attribute__((__no_instrument_function__))
+-
+-#ifndef NOVFS_VFS_MAJOR
+-#define NOVFS_VFS_MAJOR 0
+-#endif
+-
+-#ifndef NOVFS_VFS_MINOR
+-#define NOVFS_VFS_MINOR 0
+-#endif
+-
+-#ifndef NOVFS_VFS_SUB
+-#define NOVFS_VFS_SUB 0
+-#endif
+-
+-#ifndef NOVFS_VFS_RELEASE
+-#define NOVFS_VFS_RELEASE 0
+-#endif
+-
+-#define VALUE_TO_STR( value ) #value
+-#define DEFINE_TO_STR(value) VALUE_TO_STR(value)
+-
+-
+-#define NOVFS_VERSION_STRING \
+-         DEFINE_TO_STR(NOVFS_VFS_MAJOR)"." \
+-         DEFINE_TO_STR(NOVFS_VFS_MINOR)"." \
+-         DEFINE_TO_STR(NOVFS_VFS_SUB)"-" \
+-         DEFINE_TO_STR(NOVFS_VFS_RELEASE)
+-
+-/*===[ Type definitions ]=================================================*/
+-typedef struct _ENTRY_INFO
+-{
+-	int			    type;
+-	umode_t		    mode;
+-	uid_t		       uid;
+-	gid_t		       gid;
+-	loff_t		    size;
+-	struct timespec atime;
+-	struct timespec mtime;
+-	struct timespec ctime;
+-	int			    namelength;
+-	unsigned char   name[1];
+-} ENTRY_INFO, *PENTRY_INFO;
+-
+-typedef struct _STRING_
+-{
+-	int Length;
+-	unsigned char *Data;
+-} STRING, *PSTRING;
+-
+-typedef struct _LOGIN_
+-{
+-	STRING Server;
+-	STRING UserName;
+-	STRING Password;
+-} LOGIN, *PLOGIN;
+-
+-typedef struct _LOGOUT_
+-{
+-	STRING Server;
+-} LOGOUT, *PLOGOUT;
+-
+-typedef uint64_t scope_t;
+-typedef uint64_t session_t;
+-
+-typedef struct _DIR_CACHE_
+-{
+-   struct list_head list;
+-   int flags;
+-   u64 jiffies;
+-   ino_t ino;
+-	loff_t size;
+-   umode_t mode; 
+-	struct timespec atime;
+-	struct timespec mtime;
+-	struct timespec ctime;
+-   unsigned long hash;
+-   int nameLen;
+-   char name[1];
+-} DIR_CACHE, *PDIR_CACHE;
+-
+-typedef struct _INODE_DATA_
+-{
+-	void         *Scope;
+-	unsigned long Flags;
+-	struct list_head IList;
+-	struct inode *Inode;
+-	struct list_head DirCache;
+-	struct semaphore DirCacheLock;
+-	char Name[1]; /* Needs to be last entry */
+-} INODE_DATA, *PINODE_DATA;
+-
+-typedef struct _DATA_LIST_
+-{
+-   void *page;
+-   void *offset;
+-   int   len;
+-   int   rwflag;
+-} DATA_LIST, *PDATA_LIST;
+-
+-typedef struct	_XPLAT_
+-{
+-	int				xfunction;
+-	unsigned long	reqLen;
+-	void			*reqData;
+-	unsigned long	repLen;
+-	void			*repData;
+-
+-} XPLAT, *PXPLAT;
+-
+-
+-/*===[ Function prototypes ]==============================================*/
+-
+-extern int DbgPrint( char *Fmt, ... );
+-extern char *ctime_r(time_t *clock, char *buf);
+-
+-
+-/*++======================================================================*/
+-static inline unsigned long InterlockedIncrement( unsigned long *p )
+-/*
+- *
+- *  Arguments:   unsigned long *p - pointer to value. 
+- *
+- *  Returns:     unsigned long - value prior to increment.
+- *
+- *  Abstract:    The value of *p is incremented and the value of *p before
+- *               it was incremented is returned.  This is an atomic operation.
+- *
+- *  Notes:       
+- *
+- *  Environment: 
+- *
+- *========================================================================*/
+-{
+-	unsigned long x = 1;
+-
+-	mb();
+-
+-#if   defined(__i386) || defined(__i386__)
+-	__asm__ __volatile__(
+-        " lock xadd %0,(%2)"
+-		: "+r"(x), "=m"(p)
+-		: "r"(p), "m"(p)
+-		: "memory");
+-
+-#else
+-   x = *p++;
+-#endif
+-	return( x );
+-}
+diff -uNr src.old/src/Makefile src/src/Makefile
+--- src.old/src/Makefile	1970-01-01 01:00:00.000000000 +0100
++++ src/src/Makefile	2006-10-16 15:08:22.000000000 +0200
+@@ -0,0 +1,58 @@
++##*++======================================================================
++## Program Name:     Novell NCP Redirector for Linux
++## File Name:        Makefile
++## Version:          v1.01
++## Author:           James Turner
++##
++## Abstract:         This is used to generate the novfs module
++## Notes:
++## Revision History: 
++##	6/10/2005 - Added lines for SuSE
++##
++## Copyright (C) 2005 Novell, Inc.
++##
++## 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.
++##=====================================================================--*/ 
++
++#
++# Makefile for the Novell NetWare Client for Linux filesystem.
++#
++NOVFS_VFS_MAJOR = 2
++NOVFS_VFS_MINOR = 0
++NOVFS_VFS_SUB = 0
++NOVFS_VFS_RELEASE = 0
++
++# Remove # from the following line for debug version
++EXTRA_CFLAGS += -finstrument-functions
++EXTRA_CFLAGS += -g
++EXTRA_CFLAGS += -I.
++EXTRA_CFLAGS += -I$(obj)/../include
++EXTRA_CFLAGS += -I$(obj)/../../include
++EXTRA_CFLAGS += -DNOVFS_VFS_MAJOR=$(NOVFS_VFS_MAJOR)
++EXTRA_CFLAGS += -DNOVFS_VFS_MINOR=$(NOVFS_VFS_MINOR)
++EXTRA_CFLAGS += -DNOVFS_VFS_SUB=$(NOVFS_VFS_SUB)
++EXTRA_CFLAGS += -DNOVFS_VFS_PATCH=$(NOVFS_VFS_PATCH)
++EXTRA_CFLAGS += -DNOVFS_VFS_RELEASE=$(NOVFS_VFS_RELEASE)
++
++
++obj-m := novfs.o
++
++novfs-y := inode.o proc.o profile.o daemon.o file.o scope.o nwcapi.o
++
++all:
++	make -C /usr/src/linux SUBDIRS=`pwd` modules
++
++clean:
++	make -C /usr/src/linux SUBDIRS=`pwd` modules clean
+diff -uNr src.old/src/blank.c src/src/blank.c
+--- src.old/src/blank.c	1970-01-01 01:00:00.000000000 +0100
++++ src/src/blank.c	2006-10-16 15:08:22.000000000 +0200
+@@ -0,0 +1,61 @@
++/*++========================================================================
++ * Program Name:     Novell NCP Redirector for Linux
++ * File Name:        .c
++ * Version:          v1.00
++ * Author:           James Turner
++ *
++ * Abstract:         This module
++ *
++ * Notes:
++ * Revision History: 
++ *
++ *
++ * Copyright (C) 2005 Novell, Inc.
++ *
++ * 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 files specific to Linux ]==================================*/
++
++/*===[ Include files specific to this module ]============================*/
++
++/*===[ External data ]====================================================*/
++
++/*===[ External prototypes ]==============================================*/
++
++/*===[ Manifest constants ]===============================================*/
++
++/*===[ Type definitions ]=================================================*/
++
++/*===[ Function prototypes ]==============================================*/
++
++/*===[ Global variables ]=================================================*/
++
++/*===[ Code ]=============================================================*/
++
++/*++======================================================================*/
++Function
++/*
++ * Arguments:
++ * 
++ * Returns:
++ * 
++ * Abstract:
++ * 
++ * Notes:
++ * 
++ * Environment:
++ * 
++ *========================================================================*/
+diff -uNr src.old/src/daemon.c src/src/daemon.c
+--- src.old/src/daemon.c	1970-01-01 01:00:00.000000000 +0100
++++ src/src/daemon.c	2006-10-16 15:08:23.000000000 +0200
+@@ -0,0 +1,2863 @@
++/*++========================================================================
++ * Program Name:     Novell NCP Redirector for Linux
++ * File Name:        daemon.c
++ * Version:          v1.00
++ * Author:           James Turner
++ *
++ * Abstract:         This module contains all the functions necessary
++ *                   for sending commands to our daemon module.
++ * Notes:
++ * Revision History: 
++ *
++ *
++ * Copyright (C) 2005 Novell, Inc.
++ *
++ * 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 files specific to Linux ]==================================*/
++#include <linux/module.h>
++#include <linux/fs.h>
++#include <linux/slab.h>
++#include <linux/list.h>
++#include <linux/timer.h>
++#include <linux/poll.h>
++#include <linux/pagemap.h>
++#include <linux/smp_lock.h>
++#include <asm/semaphore.h>
++#include <asm/uaccess.h>
++#include <linux/time.h>
++
++
++/*===[ Include files specific to this module ]============================*/
++#include "vfs.h"
++#include "nwcapi.h"
++#include "commands.h"
++#include "nwerror.h"
++
++/*===[ External data ]====================================================*/
++extern char *Novfs_CurrentMount;
++
++/*===[ External prototypes ]==============================================*/
++extern int DbgPrint( char *Fmt, ... );
++extern void mydump(int size, void *dumpptr);
++
++extern char *Scope_Get_UserName( void *Scope );
++extern void *Scope_Lookup( void );
++extern session_t Scope_Get_SessionId( void *Scope );
++extern void Scope_Cleanup( void );
++
++extern int Novfs_Read_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, int User, session_t SessionId);
++extern int Novfs_Write_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId);
++extern int Novfs_Close_Stream( u_long ConnHandle, u_char *Handle, session_t SessionId );
++
++extern int Novfs_Add_to_Root(char *);
++
++/*
++ * profile.c functions
++ */
++extern uint64_t get_nanosecond_time( void );
++
++/*
++ * nwcapi.c functions
++ */
++extern int NwAuthConnWithId(PXPLAT pdata, session_t Session);
++extern int NwConnClose(PXPLAT pdata, u_long *Handle, session_t Session);
++extern int NwGetConnInfo(PXPLAT pdata, session_t Session);
++extern int NwSetConnInfo(PXPLAT pdata, session_t Session);
++extern int NwGetDaemonVersion(PXPLAT pdata, session_t Session);
++extern int NwGetIdentityInfo(PXPLAT pdata, session_t Session);
++extern int NwLicenseConn(PXPLAT pdata, session_t Session);
++extern int NwLoginIdentity(PXPLAT pdata, session_t Session);
++extern int NwLogoutIdentity(PXPLAT pdata, session_t Session);
++extern int NwOpenConnByAddr(PXPLAT pdata, u_long *Handle, session_t Session);
++extern int NwOpenConnByName(PXPLAT pdata, u_long *Handle, session_t Session);
++extern int NwOpenConnByRef(PXPLAT pdata, u_long *Handle, session_t Session);
++extern int NwQueryFeature(PXPLAT pdata, session_t Session);
++extern int NwRawSend(PXPLAT pdata, session_t Session);
++extern int NwScanConnInfo(PXPLAT pdata, session_t Session);
++extern int NwSysConnClose(PXPLAT pdata, u_long *Handle, session_t Session);
++extern int NwUnAuthenticate(PXPLAT pdata, session_t Session);
++extern int NwUnlicenseConn(PXPLAT pdata, session_t Session);
++extern int NwcChangeAuthKey(PXPLAT pdata, session_t Session);
++extern int NwcEnumIdentities(PXPLAT pdata, session_t Session);
++extern int NwcGetDefaultNameCtx(PXPLAT pdata, session_t Session);
++extern int NwcGetPreferredDSTree(PXPLAT pdata, session_t Session);
++extern int NwcGetTreeMonitoredConn(PXPLAT pdata, session_t Session);
++extern int NwcSetDefaultNameCtx(PXPLAT pdata, session_t Session);
++extern int NwcSetPreferredDSTree(PXPLAT pdata, session_t Session);
++extern int NwcSetPrimaryConn(PXPLAT pdata, session_t Session);
++extern int NwcGetPrimaryConn(PXPLAT pdata, session_t Session);
++extern int NwcSetMapDrive(PXPLAT pdata, session_t Session);
++extern int NwcUnMapDrive(PXPLAT pdata, session_t Session);
++extern int NwcEnumerateDrives(PXPLAT pdata, session_t Session);
++extern int NwcGetBroadcastMessage(PXPLAT pdata, session_t Session);
++extern int NwdSetKeyValue(PXPLAT pdata, session_t Session);
++extern int NwdVerifyKeyValue(PXPLAT pdata, session_t Session);
++
++/*===[ Manifest constants ]===============================================*/
++#define QUEUE_SENDING 0
++#define QUEUE_WAITING 1
++#define QUEUE_TIMEOUT 2
++#define QUEUE_ACKED   3
++#define QUEUE_DONE    4
++
++#define TIMEOUT_VALUE 10
++
++#define DH_TYPE_UNDEFINED    0
++#define DH_TYPE_STREAM       1
++#define DH_TYPE_CONNECTION   2
++
++/*===[ Type definitions ]=================================================*/
++typedef struct _DAEMON_QUEUE
++{
++   struct list_head list;       /* Must be first entry */
++   spinlock_t       lock;       /* Used to control access to list */
++   struct semaphore semaphore;  /* Used to signal when data is available */
++} daemon_queue_t;
++
++typedef struct _DAEMON_COMMAND
++{
++   struct list_head  list;      /* Must be first entry */
++   atomic_t          reference;
++   u_long            status;
++   u_long            flags;
++   struct semaphore  semaphore;
++   u_long            sequence;
++   struct timer_list timer;
++   void              *request;
++   u_long            reqlen;
++   void              *data;
++   int               datalen;
++   void              *reply;
++   u_long            replen;
++}  daemon_command_t;
++
++
++typedef struct _DAEMON_HANDLE_
++{
++   struct list_head  list;
++   rwlock_t          lock;
++   session_t         session;
++} daemon_handle_t;
++
++typedef struct _DAEMON_RESOURCE_
++{
++   struct list_head  list;
++   int               type;
++   u_long            connection;
++   u_char            handle[6];
++   mode_t            mode; 
++   loff_t            size;
++} daemon_resource_t;
++
++typedef struct _DRIVE_MAP_
++{
++   struct list_head  list; /* Must be first item */
++   session_t session;
++   u_long hash;
++   int namelen;
++   char name[1];
++} drive_map_t;
++
++/*===[ Function prototypes ]==============================================*/
++int     Daemon_Added_Resource(daemon_handle_t *DHandle, int Type, u_long CHandle, u_char *FHandle, u_long Mode, u_long Size);
++int     Daemon_Close_Control(struct inode *Inode, struct file *File);
++int     Daemon_CreateSessionId( uint64_t *SessionId );
++int     Daemon_DestroySessionId( uint64_t SessionId );
++void    Daemon_Dumpque( void );
++int     Daemon_Get_UserSpace( uint64_t SessionId,  uint64_t *TotalSize, uint64_t *TotalFree, uint64_t *TotalDirectoryEnties, uint64_t *FreeDirectoryEnties);
++int     Daemon_Library_close(struct inode *inode, struct file *file);
++int     Daemon_Library_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u_long arg);
++int     Daemon_Library_open(struct inode *inode, struct file *file);
++ssize_t Daemon_Library_read(struct file *file, char *buf, size_t len, loff_t *off);
++ssize_t Daemon_Library_write(struct file *file, const char *buf, size_t len, loff_t *off);
++loff_t  Daemon_Library_llseek(struct file *file, loff_t offset, int origin);
++int     Daemon_Login(PLOGIN Login, session_t Session);
++int     Daemon_Logout(PLOGOUT Logout, session_t Session);
++int     Daemon_Open_Control(struct inode *Inode, struct file *File);
++uint    Daemon_Poll(struct file *file, struct poll_table_struct *poll_table);
++ssize_t Daemon_Receive_Reply(struct file * file, char * buf, size_t nbytes, loff_t *ppos);
++int     Daemon_Remove_Resource(daemon_handle_t *DHandle, int Type, u_long CHandle, u_long FHandle);
++
++ssize_t Daemon_Send_Command(struct file *file, char *buf, size_t len, loff_t *off);
++int     Daemon_SetMountPoint( char *Path );
++void    Daemon_Timer(u_long data);
++int     Daemon_getpwuid( uid_t uid, int unamelen, char *uname );
++int     Daemon_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u_long arg);
++void    Init_Daemon_Queue( void );
++int     Queue_Daemon_Command(void *request, u_long reqlen, void *data, int dlen, void **reply, u_long *replen, int interruptible);
++void    Queue_get(daemon_command_t *que);
++void    Queue_put(daemon_command_t *que);
++void    Uninit_Daemon_Queue( void );
++int     do_login(NclString *Server, NclString *Username, NclString *Password, u_long *lgnId, session_t Session);
++int     do_logout( struct qstr *Server, session_t Session );
++daemon_command_t *find_queue(u_long sequence);
++daemon_command_t *get_next_queue(int Set_Queue_Waiting);
++int NwdConvertNetwareHandle(PXPLAT pdata, daemon_handle_t *DHandle);
++int NwdConvertLocalHandle(PXPLAT pdata, daemon_handle_t *DHandle);
++int NwdGetMountPath(PXPLAT pdata);
++int NwdSetMapDrive(PXPLAT pdata, session_t Session);
++int NwdUnMapDrive(PXPLAT pdata, session_t Session);
++void RemoveDriveMaps( void );
++int local_unlink(const char *pathname);
++
++/*===[ Global variables ]=================================================*/
++daemon_queue_t Daemon_Queue;
++
++static DECLARE_WAIT_QUEUE_HEAD(Read_waitqueue);
++
++u_long Sequence = 0;
++atomic_t Daemon_Open_Count=ATOMIC_INIT(0);
++
++u_long Daemon_Command_Timeout = TIMEOUT_VALUE;
++
++DECLARE_MUTEX ( DriveMapLock );
++LIST_HEAD( DriveMapList );
++
++int MaxIoSize=PAGE_SIZE;
++
++/*===[ Code ]=============================================================*/
++
++/*++======================================================================*/
++void Init_Daemon_Queue()
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   INIT_LIST_HEAD(&Daemon_Queue.list);
++   spin_lock_init(&Daemon_Queue.lock);
++   init_MUTEX_LOCKED(&Daemon_Queue.semaphore);
++}
++
++/*++======================================================================*/
++void Uninit_Daemon_Queue( void )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   /* Does nothing for now but we maybe should clear the queue. */
++}
++
++/*++======================================================================*/
++void 
++NO_TRACE
++Daemon_Timer(u_long data)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   daemon_command_t *que = (daemon_command_t *)data;
++
++   if ( QUEUE_ACKED != que->status )
++   {
++      que->status = QUEUE_TIMEOUT;
++   }
++   up(&que->semaphore);
++}
++
++/*++======================================================================*/
++int Queue_Daemon_Command(
++   void *request,
++   u_long reqlen, 
++   void *data, 
++   int dlen,
++   void **reply, 
++   u_long *replen,
++   int interruptible)
++/*
++ *
++ *  Arguments:     void *request - pointer to the request that is to be sent.  Needs to be kernel memory.
++ *                 int reqlen - length of the request.
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   daemon_command_t *que;
++   int retCode = 0;
++   uint64_t ts1, ts2;
++
++   ts1 = get_nanosecond_time();
++
++   DbgPrint( "Queue_Daemon_Command: 0x%x %d\n", request, reqlen);
++
++   if (atomic_read(&Daemon_Open_Count))
++   {
++
++      que = (daemon_command_t *)Novfs_Malloc(sizeof(*que), GFP_KERNEL);
++
++      DbgPrint( "Queue_Daemon_Command: que=0x%x\n", que);
++      if (que)
++      {
++         atomic_set( &que->reference, 0 );
++         que->status = QUEUE_SENDING;
++         que->flags  = 0;
++
++         init_MUTEX_LOCKED(&que->semaphore);
++
++         DbgPrint( "Queue_Daemon_Command: semaphore inited que=0x%x\n", que);
++         
++         que->sequence = InterlockedIncrement(&Sequence);
++
++         DbgPrint( "Queue_Daemon_Command: sequence=0x%x\n", que->sequence);
++
++         ((PCOMMAND_REQUEST_HEADER)request)->SequenceNumber = que->sequence;
++
++         /*
++          * Setup and start que timer
++          */
++         init_timer(&que->timer);
++         que->timer.expires = jiffies + (HZ * Daemon_Command_Timeout);
++         que->timer.data = (u_long)que;
++         que->timer.function = Daemon_Timer;
++         add_timer(&que->timer);
++
++         DbgPrint( "Queue_Daemon_Command: timer started que=0x%x\n", que);
++
++         /*
++          * Setup request
++          */
++         que->request = request;
++         que->reqlen  = reqlen;
++         que->data    = data;
++         que->datalen = dlen;
++         que->reply   = NULL;
++         que->replen  = 0;
++
++         DbgPrint( "Queue_Daemon_Command: setting up que=0x%x\n", que);
++
++         /*
++          * Added entry to queue.
++          */
++         DbgPrint( "Queue_Daemon_Command: Daemon_Queue locked\n");
++
++         /*
++          * Check to see if interruptible and set flags.
++          */
++         if (interruptible) 
++         {
++            que->flags |= INTERRUPTIBLE;
++         }
++
++         Queue_get( que );
++
++         spin_lock(&Daemon_Queue.lock);
++         list_add_tail(&que->list, &Daemon_Queue.list);
++         spin_unlock(&Daemon_Queue.lock);
++
++         DbgPrint( "Queue_Daemon_Command: 0x%x added to Daemon_Queue\n", que);
++         /*
++          * Signal that there is data to be read
++          */
++         up(&Daemon_Queue.semaphore);
++
++         /*
++          * Give a change to the other processes.
++          */
++         yield();
++
++         DbgPrint( "Queue_Daemon_Command: calling down 0x%x\n", CURRENT_TIME);
++   
++         /*
++          * Block waiting for reply or timeout
++          */
++         down(&que->semaphore);
++
++         DbgPrint( "Queue_Daemon_Command: after down 0x%x\n", CURRENT_TIME);
++
++         if ( QUEUE_ACKED == que->status )
++         {
++            que->status = QUEUE_WAITING;
++            mod_timer(&que->timer, jiffies + (HZ * 2 * Daemon_Command_Timeout));
++            DbgPrint( "Queue_Daemon_Command: mod_timer 0x%x\n", CURRENT_TIME);
++            if (interruptible) 
++            {
++               retCode = down_interruptible(&que->semaphore);
++            }
++            else
++            {
++               down(&que->semaphore);
++            }
++            DbgPrint( "Queue_Daemon_Command: after down2 0x%x\n", CURRENT_TIME);
++         }
++
++         DbgPrint( "Queue_Daemon_Command: after down 0x%d 0x%x\n", retCode, CURRENT_TIME);
++         /*
++          * Delete timer
++          */
++         del_timer(&que->timer);
++
++         /*
++          * Check for timeout
++          */
++         if ((QUEUE_TIMEOUT == que->status) && (NULL == que->reply) )
++         {
++            DbgPrint( "Queue_Daemon_Command: Timeout\n");
++            retCode = -ETIME;
++         }
++         *reply  = que->reply;
++         *replen = que->replen;
++
++         /*
++          * Remove item from queue
++          */
++         Queue_put( que );
++
++      }
++      else /* Error case with no memory */
++      {
++         retCode = -ENOMEM;
++         *reply = NULL;
++         *replen = 0;
++      }
++   }
++   else
++   {
++      retCode = -EIO;
++      *reply = NULL;
++      *replen = 0;
++
++   }
++   ts2 = get_nanosecond_time();
++   ts2 = ts2-ts1;
++
++   DbgPrint( "Queue_Daemon_Command: %llu retCode=%d \n", ts2, retCode);
++   return(retCode);
++}
++
++/*++======================================================================*/
++void Queue_get(daemon_command_t *Que)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   DbgPrint("Queue_get: que=0x%p %d\n", Que, atomic_read(&Que->reference));
++   atomic_inc( &Que->reference );
++}
++
++/*++======================================================================*/
++void Queue_put(daemon_command_t *Que)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++
++   DbgPrint("Queue_put: que=0x%p %d\n", Que, atomic_read(&Que->reference));
++   spin_lock(&Daemon_Queue.lock);
++
++   if ( atomic_dec_and_test( &Que->reference ))
++   {
++      /*
++       * Remove item from queue
++       */
++      list_del(&Que->list);
++      spin_unlock(&Daemon_Queue.lock);
++
++      /*
++       * Free item memory
++       */
++      Novfs_Free(Que);
++   }
++   else
++   {
++      spin_unlock(&Daemon_Queue.lock);
++   }
++}
++
++/*++======================================================================*/
++daemon_command_t *get_next_queue(int Set_Queue_Waiting)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   daemon_command_t *que;
++   
++   DbgPrint( "get_next_queue: que=0x%p\n", Daemon_Queue.list.next);
++
++   spin_lock(&Daemon_Queue.lock);
++   que = (daemon_command_t *)Daemon_Queue.list.next;
++
++   while (que && (que != (daemon_command_t *)&Daemon_Queue.list.next) && ( que->status != QUEUE_SENDING ) )
++   {
++      que = (daemon_command_t *)que->list.next;
++   }
++
++   if ((NULL == que) || (que == (daemon_command_t *)&Daemon_Queue.list) || (que->status != QUEUE_SENDING))
++   {
++      que = NULL;
++   }
++   else if (Set_Queue_Waiting)
++   {
++      que->status = QUEUE_WAITING;
++   }
++
++   if (que)
++   {
++      atomic_inc( &que->reference );
++   }
++
++   spin_unlock(&Daemon_Queue.lock);
++
++   DbgPrint( "get_next_queue: return=0x%x\n", que);
++   return(que);
++}
++
++/*++======================================================================*/
++daemon_command_t *find_queue(u_long sequence)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   daemon_command_t *que;
++   
++   DbgPrint( "find_queue: 0x%x\n", sequence);
++
++   spin_lock(&Daemon_Queue.lock);
++   que = (daemon_command_t *)Daemon_Queue.list.next;
++   
++
++   while (que && (que != (daemon_command_t *)&Daemon_Queue.list.next) && (que->sequence != sequence))
++   {
++      que = (daemon_command_t *)que->list.next;
++   }
++
++   if ((NULL == que) || (que == (daemon_command_t *)&Daemon_Queue.list.next) || (que->sequence != sequence))
++   {
++      que = NULL;
++   }
++
++   if (que)
++   {
++      atomic_inc( &que->reference );
++   }
++
++   spin_unlock(&Daemon_Queue.lock);
++
++   DbgPrint( "find_queue: return 0x%p\n", que);
++   return(que);
++}
++/*++======================================================================*/
++int Daemon_Open_Control(struct inode *Inode, struct file *File)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   DbgPrint("Daemon_Open_Control: pid=%d Count=%d\n", current->pid, atomic_read(&Daemon_Open_Count));
++   atomic_inc(&Daemon_Open_Count);
++
++   return(0);
++}
++
++/*++======================================================================*/
++int Daemon_Close_Control(struct inode *Inode, struct file *File)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   daemon_command_t *que;
++
++   DbgPrint("Daemon_Close_Control: pid=%d Count=%d\n", current->pid, atomic_read(&Daemon_Open_Count));
++
++   if (atomic_dec_and_test(&Daemon_Open_Count))
++   {
++      /*
++       * Signal any pending que itmes.
++       */
++
++      spin_lock(&Daemon_Queue.lock);
++      que = (daemon_command_t *)Daemon_Queue.list.next;
++
++      while (que && (que != (daemon_command_t *)&Daemon_Queue.list.next) && (que->status != QUEUE_DONE))
++      {
++         que->status = QUEUE_TIMEOUT;
++         up(&que->semaphore);
++
++         que = (daemon_command_t *)que->list.next;
++      }
++      spin_unlock(&Daemon_Queue.lock);
++
++      RemoveDriveMaps();
++
++      Scope_Cleanup();
++   }
++
++   return(0);
++}
++
++/*++======================================================================*/
++ssize_t 
++Daemon_Send_Command(struct file *file, char *buf, size_t len, loff_t *off)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   daemon_command_t *que;
++   size_t retValue = 0;
++   int Finished=0;
++   PDATA_LIST dlist;
++   int i, dcnt, bcnt, ccnt, error;
++   char *vadr;
++   u_long cpylen;
++
++   DbgPrint( "Daemon_Send_Command: %u %lld\n", len, *off);
++   if (len > MaxIoSize)
++   {
++      MaxIoSize = len;
++   }
++
++   while ( !Finished )
++   {
++      que = get_next_queue(1);
++      DbgPrint( "Daemon_Send_Command: 0x%x\n", que);
++      if (que)
++      {
++         retValue = que->reqlen;
++         if (retValue > len)
++         {
++            retValue = len;
++         }
++         if (retValue > 0x80)
++            mydump(0x80, que->request);
++         else
++            mydump(retValue, que->request);
++
++         cpylen = copy_to_user(buf, que->request, retValue);
++         if (que->datalen && (retValue < len))
++         {
++            buf += retValue;
++            dlist = que->data;
++            dcnt  = que->datalen;
++            for (i=0; i<dcnt; i++, dlist++)
++            {
++               if ( DLREAD == dlist->rwflag )
++               {
++                  bcnt = dlist->len;
++                  DbgPrint("Daemon_Send_Command%d: page=0x%x offset=0x%x len=%d\n", i, dlist->page, dlist->offset, dlist->len);
++                  if ((bcnt + retValue) <= len)
++                  {
++                     void *km_adr=NULL;
++
++                     if (dlist->page)
++                     {
++                        km_adr = kmap(dlist->page);
++                        vadr = km_adr;
++                        vadr += (u_int)dlist->offset;
++                     }
++                     else
++                     {
++                        vadr = dlist->offset;
++                     }
++
++                     ccnt = copy_to_user(buf, vadr, bcnt);
++
++                     if ( km_adr )
++                     {
++                        kunmap(dlist->page);
++                     }
++
++                     DbgPrint("Daemon_Send_Command: Copy %d from 0x%x to 0x%x.\n", bcnt, vadr, buf);
++                     if (bcnt > 0x80)
++                        mydump(0x80, vadr);
++                     else
++                        mydump(bcnt, vadr);
++
++                     retValue += bcnt;
++                     buf += bcnt;
++                  }
++                  else
++                  {
++                     break;
++                  }
++               }
++            }
++         }
++         Queue_put( que );
++         break;
++      }
++
++      if (O_NONBLOCK & file->f_flags)
++      {
++         retValue = -EAGAIN;
++         break;
++      }
++      else
++      {
++         if ((error = down_interruptible(&Daemon_Queue.semaphore)))
++         {
++            DbgPrint( "Daemon_Send_Command: after down_interruptible error...%d\n", error);
++            retValue = -EINTR;
++            break;
++         }
++         DbgPrint( "Daemon_Send_Command: after down_interruptible\n");
++      }
++   }
++
++   *off = *off;
++
++   DbgPrint( "Daemon_Send_Command: return 0x%x\n", retValue);
++
++   return(retValue);
++}
++
++/*++======================================================================*/
++ssize_t
++Daemon_Receive_Reply(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   daemon_command_t *que;
++   size_t retValue = 0;
++   void *reply;
++   u_long sequence, cpylen;
++
++   PDATA_LIST dlist;
++   char *vadr;
++   int i;
++
++   DbgPrint( "Daemon_Receive_Reply: buf=0x%x nbytes=%d ppos=%llx\n", buf, nbytes, *ppos);
++
++   /*
++    * Get sequence number from reply buffer
++    */
++
++   cpylen = copy_from_user(&sequence, buf, sizeof(sequence));
++
++   /*
++    * Find item based on sequence number
++    */
++   que = find_queue(sequence);
++
++   DbgPrint( "Daemon_Receive_Reply: 0x%x 0x%x %d\n", sequence, que, nbytes);
++   if (que)
++   {
++      do
++      {
++         retValue = nbytes;
++         /*
++          * Ack packet from novfsd.  Remove timer and
++          * return
++          */
++         if (nbytes == sizeof(sequence))
++         {
++            que->status = QUEUE_ACKED;
++            break;
++         }
++
++         /*
++          * Set status that packet is done.
++          */
++         que->status = QUEUE_DONE;
++
++         if ( NULL != (dlist = que->data) )
++         {
++            int thiscopy, left=nbytes;
++            retValue = 0;
++
++
++            DbgPrint( "Daemon_Receive_Reply: dlist=0x%x count=%d\n", dlist, que->datalen);
++            for (i=0; (i < que->datalen) && (retValue < nbytes); i++, dlist++)
++            {
++               DbgPrint( "Daemon_Receive_Reply:\n" \
++                         "   dlist[%d].page:   0x%x\n" \
++                         "   dlist[%d].offset: 0x%x\n" \
++                         "   dlist[%d].len:    0x%x\n" \
++                         "   dlist[%d].rwflag: 0x%x\n",
++                  i, dlist->page,
++                  i, dlist->offset,
++                  i, dlist->len,
++                  i, dlist->rwflag);
++
++               if (DLWRITE == dlist->rwflag)
++               {
++                  void *km_adr=NULL;
++
++                  if (dlist->page)
++                  {
++                     km_adr = kmap(dlist->page);
++                     vadr = km_adr;
++                     vadr += (u_int)dlist->offset;
++                  }
++                  else
++                  {
++                     vadr = dlist->offset;
++                  }
++                  
++                  thiscopy = dlist->len;
++                  if (thiscopy > left)
++                  {
++                     thiscopy = left;
++                     dlist->len = left;
++                  }
++                  cpylen = copy_from_user(vadr, buf, thiscopy);
++
++                  if ( km_adr )
++                  {
++                     kunmap(dlist->page);
++                  }
++
++                  left -= thiscopy;
++                  retValue += thiscopy;
++                  buf += thiscopy;
++               }
++            }
++            que->replen = retValue;
++         }
++         else
++         {
++            reply = Novfs_Malloc(nbytes, GFP_KERNEL);
++            DbgPrint( "Daemon_Receive_Reply: reply=0x%x\n", reply);
++            if (reply)
++            {
++               retValue = nbytes;
++               que->reply = reply;
++               que->replen = nbytes;
++
++               retValue -= copy_from_user(reply, buf, retValue);
++               if (retValue > 0x80)
++                  mydump(0x80, reply);
++               else
++                  mydump(retValue, reply);
++
++
++            }
++            else
++            {
++               retValue = -ENOMEM;
++            }
++         }
++      } while (0);
++      up(&que->semaphore);
++      Queue_put( que );
++   } 
++
++   DbgPrint( "Daemon_Receive_Reply: return 0x%x\n", retValue);
++
++   return(retValue);
++}
++
++/*++======================================================================*/
++int do_login(NclString *Server, NclString *Username, NclString *Password, u_long *lgnId, session_t Session)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PLOGIN_USER_REQUEST cmd;
++   PLOGIN_USER_REPLY   reply;
++   u_long replylen=0;
++   int retCode, cmdlen, datalen;
++   u_char *data;
++
++   datalen = Server->len+Username->len+Password->len;
++   cmdlen = sizeof(*cmd) + datalen;
++   cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++   if (cmd)
++   {
++      data = (u_char *)cmd + sizeof(*cmd);
++      cmd->Command.CommandType    = VFS_COMMAND_LOGIN_USER;
++      cmd->Command.SequenceNumber = 0;
++      cmd->Command.SessionId      = Session;
++
++      cmd->srvNameType    = Server->type;
++      cmd->serverLength   = Server->len;
++      cmd->serverOffset   = (u_long)(data-(u_char *)cmd);
++      memcpy(data, Server->buffer, Server->len);
++      data += Server->len;
++
++      cmd->usrNameType    = Username->type;
++      cmd->userNameLength = Username->len;
++      cmd->userNameOffset = (u_long)(data-(u_char *)cmd);
++      memcpy(data, Username->buffer, Username->len);
++      data += Username->len;
++
++      cmd->pwdNameType    = Password->type;
++      cmd->passwordLength = Password->len;
++      cmd->passwordOffset = (u_long)(data-(u_char *)cmd);
++      memcpy(data, Password->buffer, Password->len);
++      data += Password->len;
++
++      retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
++      if (reply)
++      {
++         if (reply->Reply.ErrorCode)
++         {
++            retCode = reply->Reply.ErrorCode;
++         }
++         else
++         {
++            retCode = 0;
++            if (lgnId)
++            {
++               *lgnId = reply->loginIdentity;
++            }
++         }
++         Novfs_Free(reply);
++      }
++      memset(cmd, 0, cmdlen);
++      Novfs_Free(cmd);
++   }
++   else
++   {
++      retCode = -ENOMEM;
++   }
++   return( retCode );
++
++}
++
++/*++======================================================================*/
++int do_logout( struct qstr *Server, session_t Session )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PLOGOUT_REQUEST cmd;
++   PLOGOUT_REPLY   reply;
++   u_long replylen=0;
++   int retCode, cmdlen;
++
++   cmdlen = (int)(&((PLOGOUT_REQUEST)0)->Name) + Server->len;
++   cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++   if (cmd)
++   {
++      cmd->Command.CommandType    = VFS_COMMAND_LOGOUT_USER;
++      cmd->Command.SequenceNumber = 0;
++      cmd->Command.SessionId      = Session;
++
++      cmd->Length   = Server->len;
++      memcpy(cmd->Name, Server->name, Server->len);
++
++      retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
++      if (reply)
++      {
++         if (reply->Reply.ErrorCode)
++         {
++            retCode = -EIO;
++         }
++         Novfs_Free(reply);
++      }
++      Novfs_Free(cmd);
++   }
++   else
++   {
++      retCode = -ENOMEM;
++   }
++   return( retCode );
++
++}
++
++/*++======================================================================*/
++int Daemon_getpwuid( uid_t uid, int unamelen, char *uname )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   GETPWUID_REQUEST cmd;
++   PGETPWUID_REPLY  reply;
++   u_long replylen=0;
++   int retCode;
++
++   cmd.Command.CommandType    = VFS_COMMAND_GETPWUD;
++   cmd.Command.SequenceNumber = 0;
++   cmd.Command.SessionId      = 0;
++   cmd.uid = uid;
++
++   retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
++   if (reply)
++   {
++      if (reply->Reply.ErrorCode)
++      {
++         retCode = -EIO;
++      }
++      else
++      {
++         retCode = 0;
++         memset(uname, 0, unamelen);
++         replylen = replylen - (int)(&((PGETPWUID_REPLY)0)->UserName);
++         if (replylen)
++         {
++            if (replylen > unamelen)
++            {
++               retCode = -EINVAL;
++               replylen = unamelen-1;
++            }
++            memcpy(uname, reply->UserName, replylen);
++         }
++      }
++      Novfs_Free(reply);
++   }
++   return( retCode );
++
++}
++
++/*++======================================================================*/
++int Daemon_getversion( char *Buf, int Length )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   GET_VERSION_REQUEST cmd;
++   PGET_VERSION_REPLY  reply;
++   u_long replylen=0;
++   int retVal=0;
++
++   cmd.Command.CommandType    = VFS_COMMAND_GET_VERSION;
++   cmd.Command.SequenceNumber = 0;
++   cmd.Command.SessionId      = 0;
++
++   Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
++   if (reply)
++   {
++      if (reply->Reply.ErrorCode)
++      {
++         retVal = -EIO;
++      }
++      else
++      {
++         retVal = replylen - (int)(&((PGET_VERSION_REPLY)0)->Version);
++         if (retVal < Length)
++         {
++            memcpy(Buf, reply->Version, retVal);
++            Buf[retVal] = '\0';
++         }
++      }
++      Novfs_Free(reply);
++   }
++   return( retVal );
++
++}
++
++/*++======================================================================*/
++int Daemon_Login(PLOGIN Login, session_t Session)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   int retCode = -ENOMEM;
++   LOGIN lLogin;
++   NclString   server;
++   NclString   username;
++   NclString   password;
++
++   if ( !copy_from_user(&lLogin, Login, sizeof(lLogin)))
++   {
++      if ( (server.buffer = Novfs_Malloc(lLogin.Server.Length, GFP_KERNEL)) )
++      {
++         server.len = lLogin.Server.Length;
++         server.type = NWC_STRING_TYPE_ASCII;
++         if ( !copy_from_user((void *)server.buffer, lLogin.Server.Data, server.len) )
++         {
++            if ( (username.buffer = Novfs_Malloc(lLogin.UserName.Length, GFP_KERNEL)) )
++            {
++               username.len = lLogin.UserName.Length;
++               username.type = NWC_STRING_TYPE_ASCII;
++               if ( !copy_from_user((void *)username.buffer, lLogin.UserName.Data, username.len) )
++               {
++                  if ( (password.buffer = Novfs_Malloc(lLogin.Password.Length, GFP_KERNEL)) )
++                  {
++                     password.len = lLogin.Password.Length;
++                     password.type = NWC_STRING_TYPE_ASCII;
++                     if ( !copy_from_user((void *)password.buffer, lLogin.Password.Data, password.len) )
++                     {
++                        retCode = do_login(&server, &username, &password, NULL, Session);
++                        if ( !retCode )
++                        {
++                           char *username;
++                           username = Scope_Get_UserName( NULL );
++                           if (username)
++                           {
++                              Novfs_Add_to_Root( username );
++                           }
++                        }
++                     }
++                     memset(password.buffer, 0, password.len);
++                     Novfs_Free(password.buffer);
++                  }
++               }
++               memset(username.buffer, 0, username.len);
++               Novfs_Free(username.buffer);
++            }
++         }
++         Novfs_Free(server.buffer);
++      }
++   }
++
++   return( retCode );
++}
++
++/*++======================================================================*/
++int Daemon_Logout(PLOGOUT Logout, session_t Session)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   LOGOUT lLogout;
++   struct qstr server;
++   int retCode=0;
++
++   if ( !copy_from_user(&lLogout, Logout, sizeof(lLogout)))
++   {
++      if ( (server.name = Novfs_Malloc(lLogout.Server.Length, GFP_KERNEL)) )
++      {
++         server.len = lLogout.Server.Length;
++         if ( !copy_from_user((void *)server.name, lLogout.Server.Data, server.len) )
++         {
++            retCode = do_logout( &server, Session );
++         }
++         Novfs_Free(server.name);
++      }
++   }
++   return( retCode );
++}
++
++/*++======================================================================*/
++int Daemon_CreateSessionId( uint64_t *SessionId )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   CREATE_CONTEXT_REQUEST cmd;
++   PCREATE_CONTEXT_REPLY  reply;
++   u_long replylen=0;
++   int retCode=0;
++
++   DbgPrint("Daemon_CreateSessionId: %d\n", current->pid);
++
++   cmd.Command.CommandType = VFS_COMMAND_CREATE_CONTEXT;
++   cmd.Command.SequenceNumber = 0;
++   cmd.Command.SessionId = 0;
++
++   retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
++   if ( reply )
++   {
++      if ( !reply->Reply.ErrorCode  && replylen > sizeof(COMMAND_REPLY_HEADER))
++      {
++         *SessionId = reply->SessionId;
++         retCode = 0;
++      }
++      else
++      {
++         *SessionId = 0;
++         retCode = -EIO;
++      }
++      Novfs_Free(reply);
++   }
++   DbgPrint("Daemon_CreateSessionId: SessionId=0x%llx\n", *SessionId);
++   return(retCode);
++}
++
++/*++======================================================================*/
++int Daemon_DestroySessionId( uint64_t SessionId )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   DESTROY_CONTEXT_REQUEST cmd;
++   PDESTROY_CONTEXT_REPLY  reply;
++   u_long replylen=0;
++   int retCode=0;
++
++   DbgPrint("Daemon_DestroySessionId: 0x%llx\n", SessionId);
++
++   cmd.Command.CommandType = VFS_COMMAND_DESTROY_CONTEXT;
++   cmd.Command.SequenceNumber = 0;
++   cmd.Command.SessionId = SessionId;
++
++   retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
++   if ( reply )
++   {
++      if ( !reply->Reply.ErrorCode )
++      {
++         drive_map_t *dm;
++         struct list_head *list;
++
++         retCode = 0;
++
++         /*
++          * When destroying the session check to see if there are any
++          * mapped drives.  If there are then remove them.
++          */
++         down( &DriveMapLock );
++         list_for_each( list, &DriveMapList )
++         {
++            dm = list_entry( list, drive_map_t, list );
++            if ( SessionId == dm->session)
++            {
++                local_unlink( dm->name );
++                list = list->prev;
++                list_del( &dm->list );
++                Novfs_Free( dm );
++            }
++
++         }
++         up( &DriveMapLock );
++
++      }
++      else
++      {
++         retCode = -EIO;
++      }
++      Novfs_Free(reply);
++   }
++   return(retCode);
++}
++
++/*++======================================================================*/
++int Daemon_Get_UserSpace( uint64_t SessionId, uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   GET_USER_SPACE_REQUEST cmd;
++   PGET_USER_SPACE_REPLY  reply;
++   u_long replylen=0;
++   int retCode=0;
++
++   DbgPrint("Daemon_Get_UserSpace: 0x%llx\n", SessionId);
++
++   cmd.Command.CommandType = VFS_COMMAND_GET_USER_SPACE;
++   cmd.Command.SequenceNumber = 0;
++   cmd.Command.SessionId = SessionId;
++
++   retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
++   if ( reply )
++   {
++      if ( !reply->Reply.ErrorCode )
++      {
++
++         DbgPrint("TotalSpace:  %llu\n", reply->TotalSpace);
++         DbgPrint("FreeSpace:   %llu\n", reply->FreeSpace);
++         DbgPrint("TotalEnties: %llu\n", reply->TotalEnties);
++         DbgPrint("FreeEnties:  %llu\n", reply->FreeEnties);
++
++         if (TotalSize)   *TotalSize   = reply->TotalSpace;
++         if (Free)        *Free        = reply->FreeSpace;
++         if (TotalEnties) *TotalEnties = reply->TotalEnties;
++         if (FreeEnties)  *FreeEnties  = reply->FreeEnties;
++         retCode = 0;
++      }
++      else
++      {
++         retCode = -EIO;
++      }
++      Novfs_Free(reply);
++   }
++   return(retCode);
++}
++
++/*++======================================================================*/
++int Daemon_SetMountPoint ( char *Path )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PSET_MOUNT_PATH_REQUEST cmd;
++   PSET_MOUNT_PATH_REPLY  reply;
++   u_long replylen, cmdlen;
++   int retCode = -ENOMEM;
++
++   DbgPrint("Daemon_SetMountPoint: %s\n", Path);
++   
++   replylen = strlen(Path);
++
++   cmdlen = sizeof(SET_MOUNT_PATH_REQUEST) + replylen;
++
++   cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++   if ( cmd )
++   {
++      cmd->Command.CommandType = VFS_COMMAND_SET_MOUNT_PATH;
++      cmd->Command.SequenceNumber = 0;
++      cmd->Command.SessionId = 0;
++      cmd->PathLength = replylen;
++
++      strcpy(cmd->Path, Path);
++
++      replylen = 0;
++
++      retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
++      if ( reply )
++      {
++         if ( !reply->Reply.ErrorCode )
++         {
++            retCode = 0;
++         }
++         else
++         {
++            retCode = -EIO;
++         }
++         Novfs_Free(reply);
++      }
++      Novfs_Free(cmd);
++   }
++   return(retCode);
++}
++
++/*++======================================================================*/
++int Daemon_SendDebugCmd ( char *Command )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   DEBUG_REQUEST cmd;
++   PDEBUG_REPLY  reply;
++   DEBUG_REPLY   lreply;
++   u_long replylen, cmdlen;
++   DATA_LIST dlist[2];
++
++   int retCode = -ENOMEM;
++
++   DbgPrint("Daemon_SendDebugCmd: %s\n", Command);
++   
++   dlist[0].page   = NULL;
++   dlist[0].offset = (char *)Command;
++   dlist[0].len    = strlen(Command);
++   dlist[0].rwflag = DLREAD;
++
++   dlist[1].page   = NULL;
++   dlist[1].offset = (char *)&lreply;
++   dlist[1].len    = sizeof(lreply);
++   dlist[1].rwflag = DLWRITE;
++
++   cmdlen = (int)(&((PDEBUG_REQUEST)0)->dbgcmd);
++
++   cmd.Command.CommandType = VFS_COMMAND_DBG;
++   cmd.Command.SequenceNumber = 0;
++   cmd.Command.SessionId = 0;
++   cmd.cmdlen = strlen(Command);
++
++   replylen = 0;
++
++   retCode = Queue_Daemon_Command(&cmd, cmdlen, dlist, 2, (void *)&reply, &replylen, INTERRUPTIBLE);
++   if ( reply )
++   {
++      Novfs_Free(reply);
++   }
++   if (0 == retCode)
++   {
++      retCode = lreply.Reply.ErrorCode;
++   }
++
++   return(retCode);
++}
++
++/*++======================================================================*/
++int 
++NO_TRACE
++Daemon_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u_long arg)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   int retCode = -ENOSYS;
++   u_long cpylen;
++
++
++   switch (cmd)
++   {
++      case IOC_LOGIN:
++      {
++         retCode = Daemon_Login((PLOGIN)arg, Scope_Get_SessionId( NULL ));
++         break;
++      }
++
++      case IOC_LOGOUT:
++      {
++         retCode = Daemon_Logout((PLOGOUT)arg, Scope_Get_SessionId( NULL ));
++         break;
++      }
++      case IOC_DEBUGPRINT:
++      {
++         struct Ioctl_Debug {
++            int length;
++            char *data;
++         } io;
++         char *buf;
++         io.length = 0;
++         cpylen = copy_from_user(&io, (char *)arg, sizeof(io));
++         if (io.length)
++         {
++            buf = Novfs_Malloc(io.length+1, GFP_KERNEL);
++            if (buf)
++            {
++               buf[0] = 0;
++               cpylen = copy_from_user(buf, io.data, io.length);
++               buf[io.length] = '\0';
++               DbgPrint("%s", buf);
++               Novfs_Free(buf);
++               retCode = 0;
++            }
++         }
++         break;
++      }
++
++      case IOC_XPLAT:
++      {
++         XPLAT   data;
++
++         cpylen = copy_from_user(&data, (void *)arg, sizeof(data));
++         retCode = ((data.xfunction & 0x0000FFFF) | 0xCC000000);
++
++         switch(data.xfunction)
++         {
++            case NWC_GET_MOUNT_PATH:
++               DbgPrint("[Daemon_ioctl] Call NwdGetMountPath\n");
++               retCode = NwdGetMountPath( &data );
++               break;
++         }
++
++         DbgPrint("[NOVFS XPLAT] status Code = %X\n", retCode);
++         break;
++      }
++
++   }
++   return (retCode);
++}
++
++/*++======================================================================*/
++int Daemon_Added_Resource(daemon_handle_t *DHandle, int Type, u_long CHandle, u_char *FHandle, u_long Mode, u_long Size)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   daemon_resource_t *resource;
++   int retVal = NWE_OUT_OF_HEAP_SPACE;
++
++   if (FHandle)
++      DbgPrint("Daemon_Added_Resource: DHandle=0x%p Type=%d CHandle=0x%x FHandle=0x%x Mode=0x%x Size=%d\n", DHandle, Type, CHandle, *(u_long *)&FHandle[2], Mode, Size);
++   else
++      DbgPrint("Daemon_Added_Resource: DHandle=0x%p Type=%d CHandle=0x%x\n", DHandle, Type, CHandle);
++
++   resource = Novfs_Malloc(sizeof(daemon_resource_t), GFP_KERNEL);
++   if (resource)
++   {
++      resource->type = Type;
++      resource->connection = CHandle;
++      if (FHandle)
++      {
++         memcpy( resource->handle, FHandle, sizeof(resource->handle) );
++      }
++      else
++      {
++         memset( resource->handle, 0, sizeof(resource->handle) );
++      }
++      resource->mode = Mode; 
++      resource->size = Size;
++      write_lock( &DHandle->lock );
++      list_add( &resource->list, &DHandle->list );
++      write_unlock( &DHandle->lock );
++      DbgPrint("Daemon_Added_Resource: Adding resource=0x%p\n", resource);
++      retVal = 0;
++   }
++
++   return(retVal);
++}
++
++/*++======================================================================*/
++int Daemon_Remove_Resource(daemon_handle_t *DHandle, int Type, u_long CHandle, u_long FHandle)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   daemon_resource_t *resource;
++   struct list_head *l;
++   int retVal = -ENOMEM;
++
++   DbgPrint("Daemon_Remove_Resource: DHandle=0x%p Type=%d CHandle=0x%x FHandle=0x%x\n", DHandle, Type, CHandle, FHandle);
++
++   write_lock( &DHandle->lock );
++      
++   list_for_each( l, &DHandle->list )
++   {
++      resource = list_entry( l, daemon_resource_t, list );
++      
++      if ( (Type == resource->type) &&
++           (resource->connection == CHandle) )
++      {
++         DbgPrint("Daemon_Remove_Resource: Found resource=0x%p\n", resource);
++         l = l->prev;
++         list_del( &resource->list );
++         Novfs_Free( resource );
++         break;
++      }
++   }
++
++   write_unlock( &DHandle->lock );
++
++   return(retVal);
++}
++
++/*++======================================================================*/
++int Daemon_Library_open(struct inode *inode, struct file *file)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   int retVal = -ENOMEM;
++   daemon_handle_t *dh;
++
++   DbgPrint("Daemon_Library_open: inode=0x%p file=0x%p\n", inode, file);
++
++   if ((dh = Novfs_Malloc(sizeof(daemon_handle_t), GFP_KERNEL)))
++   {
++      file->private_data = dh;
++      INIT_LIST_HEAD( &dh->list);
++      rwlock_init( &dh->lock );
++      dh->session = Scope_Get_SessionId( NULL );
++      retVal = 0;
++   }
++   return(retVal); 
++}
++
++/*++======================================================================*/
++int Daemon_Library_close(struct inode *inode, struct file *file)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   daemon_handle_t *dh;
++   daemon_resource_t *resource;
++   struct list_head *l;
++
++   char commanddata[sizeof(XPLAT_CALL_REQUEST)+sizeof(NwdCCloseConn)];
++   PXPLAT_CALL_REQUEST  cmd;
++   PXPLAT_CALL_REPLY		reply;
++   PNwdCCloseConn			nwdClose;
++   u_long			cmdlen, replylen;
++
++   DbgPrint("Daemon_Library_close: inode=0x%p file=0x%p\n", inode, file);
++   if (file->private_data)
++   {
++      dh = (daemon_handle_t *)file->private_data;
++
++      list_for_each( l, &dh->list )
++      {
++         resource = list_entry( l, daemon_resource_t, list );
++         
++         if (DH_TYPE_STREAM == resource->type)
++         {
++            Novfs_Close_Stream( resource->connection, resource->handle, dh->session );
++         }
++         else if (DH_TYPE_CONNECTION == resource->type)
++         {
++	         cmd = (PXPLAT_CALL_REQUEST)commanddata;
++	         cmdlen = offsetof(XPLAT_CALL_REQUEST, data) + sizeof(NwdCCloseConn);
++		      cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++		      cmd->Command.SequenceNumber = 0;
++		      cmd->Command.SessionId      = dh->session;
++		      cmd->NwcCommand = NWC_CLOSE_CONN;
++
++		      cmd->dataLen = sizeof(NwdCCloseConn);
++		      nwdClose = (PNwdCCloseConn)cmd->data;
++		      nwdClose->ConnHandle = resource->connection;
++
++		      Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, 0);
++		      if (reply)
++		      {
++			      Novfs_Free(reply);
++		      }
++         }
++         l = l->prev;
++         list_del( &resource->list );
++         Novfs_Free( resource );
++      }
++      Novfs_Free(dh);
++      file->private_data = NULL;
++	}
++
++   return(0);
++}
++
++/*++======================================================================*/
++ssize_t Daemon_Library_read(struct file *file, char *buf, size_t len, loff_t *off)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   daemon_handle_t *dh;
++   daemon_resource_t *resource;
++
++   size_t thisread, totalread=0;
++   loff_t offset = *off;
++
++   DbgPrint("Daemon_Library_read: file=0x%p len=%d off=%lld\n",  file, len, *off);
++
++   if (file->private_data)
++   {
++      dh = file->private_data;
++      read_lock( &dh->lock );
++      if (&dh->list != dh->list.next)
++      {
++         resource = list_entry( dh->list.next, daemon_resource_t, list );
++         
++         if (DH_TYPE_STREAM == resource->type)
++         {
++            while( len > 0 && (offset < resource->size) )
++            {
++               thisread = len;
++               if (Novfs_Read_Stream(resource->connection, 
++                                     resource->handle, 
++                                     buf, &thisread, 
++                                     &offset, 1, 
++                                     dh->session) || !thisread)
++               {
++                  break;
++               }
++               len -= thisread;
++               buf += thisread;
++               offset += thisread;
++               totalread += thisread;
++            }
++         }
++      }
++      read_unlock( &dh->lock );
++   }
++   *off = offset;
++   DbgPrint("Daemon_Library_read return = 0x%x\n", totalread);
++   return(totalread);
++}
++
++/*++======================================================================*/
++ssize_t Daemon_Library_write(struct file *file, const char *buf, size_t len, loff_t *off)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   daemon_handle_t *dh;
++   daemon_resource_t *resource;
++
++   size_t thiswrite, totalwrite=-EINVAL;
++   loff_t offset = *off;
++   int status;
++
++   DbgPrint("Daemon_Library_write: file=0x%p len=%d off=%lld\n",  file, len, *off);
++
++   if (file->private_data)
++   {
++      dh = file->private_data;
++      write_lock( &dh->lock );
++      if (&dh->list != dh->list.next)
++      {
++         resource = list_entry( dh->list.next, daemon_resource_t, list );
++         
++         if ( (DH_TYPE_STREAM == resource->type) && (len >= 0) )
++         {
++            totalwrite = 0;
++            do
++            {
++               thiswrite = len;
++               status = Novfs_Write_Stream(resource->connection, 
++                                           resource->handle, 
++                                           (PVOID)buf, 
++                                           &thiswrite, 
++                                           &offset, 
++                                           dh->session);
++               if ( status || !thiswrite )
++               {
++                  /*
++                   * If len is zero then the file will have just been 
++                   * truncated to offset.  Update size.
++                   */
++                  if ( !status && !len )
++                  {
++                     resource->size = offset;
++                  }
++                  totalwrite = status;
++                  break;
++               }
++               len -= thiswrite;
++               buf += thiswrite;
++               offset += thiswrite;
++               totalwrite += thiswrite;
++               if (offset > resource->size)
++               {
++                  resource->size = offset;
++               }
++            } while(len > 0);
++         }
++      }
++      write_unlock( &dh->lock );
++   }
++   *off = offset;
++   DbgPrint("Daemon_Library_write return = 0x%x\n", totalwrite);
++
++   return(totalwrite);
++}
++
++/*++======================================================================*/
++loff_t Daemon_Library_llseek(struct file *file, loff_t offset, int origin)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   daemon_handle_t *dh;
++   daemon_resource_t *resource;
++
++	loff_t retVal = -EINVAL;
++
++   DbgPrint("Daemon_Library_llseek: file=0x%p offset=%lld origin=%d\n", file, offset, origin);
++
++   if (file->private_data)
++   {
++      dh = file->private_data;
++      read_lock( &dh->lock );
++      if (&dh->list != dh->list.next)
++      {
++         resource = list_entry( dh->list.next, daemon_resource_t, list );
++         
++         if (DH_TYPE_STREAM == resource->type)
++         {
++	         switch (origin) {
++		         case 2:
++			         offset += resource->size;
++			         break;
++		         case 1:
++			         offset += file->f_pos;
++	         }
++	         if (offset >= 0) {
++		         if (offset != file->f_pos) {
++			         file->f_pos = offset;
++			         file->f_version = 0;
++		         }
++		         retVal = offset;
++	         }
++         }
++      }
++      read_unlock( &dh->lock );
++   }
++
++   DbgPrint("Daemon_Library_llseek: ret %lld\n", retVal);
++
++	return retVal;
++}
++
++/*++======================================================================*/
++int 
++NO_TRACE
++Daemon_Library_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u_long arg)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   int retCode = -ENOSYS;
++   daemon_handle_t *dh;
++   u_long handle=0, cpylen;
++
++
++   dh = file->private_data;
++
++   DbgPrint("Daemon_Library_ioctl: file=0x%p 0x%x 0x%x dh=0x%p\n", file, cmd, arg, dh);
++
++   if (dh)
++   {
++
++      switch (cmd)
++      {
++         case IOC_LOGIN:
++         {
++            retCode = Daemon_Login((PLOGIN)arg, dh->session);
++            break;
++         }
++
++         case IOC_LOGOUT:
++         {
++            retCode = Daemon_Logout((PLOGOUT)arg, dh->session);
++            break;
++         }
++
++         case IOC_DEBUGPRINT:
++         {
++            struct Ioctl_Debug {
++               int length;
++               char *data;
++            } io;
++            char *buf;
++            io.length = 0;
++            cpylen = copy_from_user(&io, (char *)arg, sizeof(io));
++            if (io.length)
++            {
++               buf = Novfs_Malloc(io.length+1, GFP_KERNEL);
++               if (buf)
++               {
++                  buf[0] = 0;
++                  cpylen = copy_from_user(buf, io.data, io.length);
++                  buf[io.length] = '\0';
++                  DbgPrint("%s", buf);
++                  Novfs_Free(buf);
++                  retCode = 0;
++               }
++            }
++            break;
++         }
++
++         case IOC_XPLAT:
++         {
++            XPLAT   data;
++
++            cpylen = copy_from_user(&data, (void *)arg, sizeof(data));
++            retCode = ((data.xfunction & 0x0000FFFF) | 0xCC000000);
++
++            switch(data.xfunction)
++            {
++               case NWC_OPEN_CONN_BY_NAME:
++                  DbgPrint("[VFS XPLAT] Call NwOpenConnByName\n");
++                  retCode = NwOpenConnByName(&data, &handle, dh->session);
++                  if ( !retCode )
++                  {
++                     Daemon_Added_Resource(dh, DH_TYPE_CONNECTION, handle, 0, 0, 0);
++                  }
++                  break;
++
++               case NWC_OPEN_CONN_BY_ADDRESS:
++                  DbgPrint("[VFS XPLAT] Call NwOpenConnByAddress\n");
++                  retCode = NwOpenConnByAddr(&data, &handle, dh->session);
++                  if ( !retCode )
++                  {
++                     Daemon_Added_Resource(dh, DH_TYPE_CONNECTION, handle, 0, 0, 0);
++                  }
++                  break;
++
++               case NWC_OPEN_CONN_BY_REFERENCE:
++
++                  DbgPrint("[VFS XPLAT] Call NwOpenConnByReference\n");
++                  retCode = NwOpenConnByRef(&data, &handle, dh->session);
++                  if ( !retCode )
++                  {
++                     Daemon_Added_Resource(dh, DH_TYPE_CONNECTION, handle, 0, 0, 0);
++                  }
++                  break;
++
++               case NWC_SYS_CLOSE_CONN:
++                  DbgPrint("[VFS XPLAT] Call NwSysCloseConn\n");
++                  retCode = NwSysConnClose(&data, &handle, dh->session);
++                  Daemon_Remove_Resource(dh, DH_TYPE_CONNECTION, handle, 0);
++                  break;
++
++               case NWC_CLOSE_CONN:
++                  DbgPrint("[VFS XPLAT] Call NwCloseConn\n");
++                  retCode = NwConnClose(&data, &handle, dh->session);
++                  Daemon_Remove_Resource(dh, DH_TYPE_CONNECTION, handle, 0);
++                  break;
++
++               case NWC_LOGIN_IDENTITY:
++                  DbgPrint("[VFS XPLAT] Call NwLoginIdentity\n");
++                  retCode = NwLoginIdentity(&data, dh->session);
++                  break;
++
++               case NWC_RAW_NCP_REQUEST:
++                  DbgPrint("[VFS XPLAT] Send Raw NCP Request\n");
++                  retCode = NwRawSend(&data, dh->session);
++                  break;
++
++               case NWC_AUTHENTICATE_CONN_WITH_ID:
++                  DbgPrint("[VFS XPLAT] Authenticate Conn With ID\n");
++                  retCode = NwAuthConnWithId(&data, dh->session);
++                  break;
++
++			      case NWC_UNAUTHENTICATE_CONN:
++				      DbgPrint("[VFS XPLAT] UnAuthenticate Conn With ID\n");
++				      retCode = NwUnAuthenticate(&data, dh->session);
++   			      break;
++
++               case NWC_LICENSE_CONN:
++                  DbgPrint("Call NwLicenseConn\n");
++                  retCode = NwLicenseConn(&data, dh->session);
++                  break;
++
++               case NWC_LOGOUT_IDENTITY:
++                  DbgPrint("[VFS XPLAT] Call NwLogoutIdentity\n");
++                  retCode = NwLogoutIdentity(&data, dh->session);
++                  break;
++
++               case NWC_UNLICENSE_CONN:
++                  DbgPrint("[VFS XPLAT] Call NwUnlicense\n");
++                  retCode = NwUnlicenseConn(&data, dh->session);
++                  break;
++
++               case NWC_GET_CONN_INFO:
++                  DbgPrint("[VFS XPLAT] Call NwGetConnInfo\n");
++                  retCode = NwGetConnInfo(&data, dh->session);
++                  break;
++
++               case NWC_SET_CONN_INFO:
++                  DbgPrint("[VFS XPLAT] Call NwGetConnInfo\n");
++                  retCode = NwSetConnInfo(&data, dh->session);
++                  break;
++
++               case NWC_SCAN_CONN_INFO:
++                  DbgPrint("[VFS XPLAT] Call NwScanConnInfo\n");
++                  retCode = NwScanConnInfo(&data, dh->session);
++                  break;
++
++
++               case NWC_GET_IDENTITY_INFO:
++                  DbgPrint("[VFS XPLAT] Call NwGetIdentityInfo\n");
++                  retCode = NwGetIdentityInfo(&data, dh->session);				
++                  break;
++
++               case NWC_GET_REQUESTER_VERSION:
++                  DbgPrint("[VFS XPLAT] Call NwGetDaemonVersion\n");
++                  retCode = NwGetDaemonVersion(&data, dh->session);				
++                  break;
++
++               case NWC_GET_PREFERRED_DS_TREE:
++                  DbgPrint("[VFS XPLAT] Call NwcGetPreferredDsTree\n");
++                  retCode = NwcGetPreferredDSTree(&data, dh->session);
++                  break;
++
++               case NWC_SET_PREFERRED_DS_TREE:
++                  DbgPrint("[VFS XPLAT] Call NwcSetPreferredDsTree\n");
++                  retCode = NwcSetPreferredDSTree(&data, dh->session);
++                  break;
++
++               case NWC_GET_DEFAULT_NAME_CONTEXT:
++                  DbgPrint("[VFS XPLAT] Call NwcGetDefaultNameContext\n");
++                  retCode = NwcGetDefaultNameCtx(&data, dh->session);
++                  break;
++
++               case NWC_SET_DEFAULT_NAME_CONTEXT:
++                  DbgPrint("[VFS XPLAT] Call NwcSetDefaultNameContext\n");
++                  retCode = NwcSetDefaultNameCtx(&data, dh->session);
++                  break;
++
++               case NWC_QUERY_FEATURE:
++                  DbgPrint("[VFS XPLAT] Call NwQueryFeature\n");
++                  retCode = NwQueryFeature(&data, dh->session);
++                  break;
++
++
++               case NWC_GET_TREE_MONITORED_CONN_REF:
++                  DbgPrint("[VFS XPLAT] Call NwcGetTreeMonitoredConn\n");
++                  retCode = NwcGetTreeMonitoredConn(&data, dh->session);
++                  break;
++
++               case NWC_ENUMERATE_IDENTITIES:
++                  DbgPrint("[VFS XPLAT] Call NwcEnumerateIdentities\n");
++                  retCode = NwcEnumIdentities(&data, dh->session);
++                  break;
++
++               case NWC_CHANGE_KEY:
++                  DbgPrint("[VFS XPLAT] Call NwcChangeAuthKey\n");
++                  retCode = NwcChangeAuthKey(&data, dh->session);
++                  break;
++
++               case NWC_CONVERT_LOCAL_HANDLE:
++                  DbgPrint("[VFS XPLAT] Call NwdConvertLocalHandle\n");
++                  retCode = NwdConvertLocalHandle(&data, dh);
++                  break;
++                  
++               case NWC_CONVERT_NETWARE_HANDLE:
++                  DbgPrint("[VFS XPLAT] Call NwdConvertNetwareHandle\n");
++                  retCode = NwdConvertNetwareHandle(&data, dh);
++                  break;
++
++               case NWC_SET_PRIMARY_CONN:
++                  DbgPrint("[VFS XPLAT] Call NwcSetPrimaryConn\n");
++                  retCode = NwcSetPrimaryConn(&data, dh->session);
++                  break;
++
++               case NWC_GET_PRIMARY_CONN:
++                  DbgPrint("[VFS XPLAT] Call NwcGetPrimaryConn\n");
++                  retCode = NwcGetPrimaryConn(&data, dh->session);
++                  break;
++
++               case NWC_MAP_DRIVE:
++                  DbgPrint("[VFS XPLAT] Call NwcMapDrive\n");
++                  retCode = NwdSetMapDrive(&data, dh->session);
++                  break;
++
++               case NWC_UNMAP_DRIVE:
++                  DbgPrint("[VFS XPLAT] Call NwcUnMapDrive\n");
++                  retCode = NwdUnMapDrive(&data, dh->session);
++                  break;
++
++               case NWC_ENUMERATE_DRIVES:
++                  DbgPrint("[VFS XPLAT] Call NwcEnumerateDrives\n");
++                  retCode = NwcEnumerateDrives(&data, dh->session);
++                  break;
++
++               case NWC_GET_MOUNT_PATH:
++                  DbgPrint("[VFS XPLAT] Call NwdGetMountPath\n");
++                  retCode = NwdGetMountPath( &data );
++                  break;
++
++               case NWC_GET_BROADCAST_MESSAGE:
++                  DbgPrint("[VSF XPLAT Call NwdGetBroadcastMessage\n");
++                  retCode = NwcGetBroadcastMessage(&data, dh->session);
++                  break;
++
++               case NWC_SET_KEY:
++                  DbgPrint("[VSF XPLAT Call NwdSetKey\n");
++                  retCode = NwdSetKeyValue(&data, dh->session);
++                  break;
++
++               case NWC_VERIFY_KEY:
++                  DbgPrint("[VSF XPLAT Call NwdVerifyKey\n");
++                  retCode = NwdVerifyKeyValue(&data, dh->session);
++                  break;
++
++               case NWC_RAW_NCP_REQUEST_ALL:
++               case NWC_NDS_RESOLVE_NAME_TO_ID:
++               case NWC_FRAGMENT_REQUEST:
++               case NWC_GET_CONFIGURED_NSPS:
++               default:
++               break;
++
++            }
++
++            DbgPrint("[NOVFS XPLAT] status Code = %X\n", retCode);
++            break;
++         }
++      }
++   }
++
++   return( retCode );
++}
++
++/*++======================================================================*/
++unsigned int Daemon_Poll(struct file *file, struct poll_table_struct *poll_table)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   daemon_command_t *que;
++   unsigned int mask = POLLOUT | POLLWRNORM;
++   
++   que = get_next_queue(0);
++   if (que)
++   {
++      mask |= (POLLIN | POLLRDNORM);
++   }
++   else
++   {
++
++   }
++   return(mask);
++}
++
++
++void Daemon_Dumpque( void )
++{
++#ifdef	CONFIG_KDB
++   daemon_command_t *que;
++
++   que = (daemon_command_t *)Daemon_Queue.list.next;
++
++   while (que && (que != (daemon_command_t *)&Daemon_Queue.list.next))
++   {
++      kdb_printf("DaemonQue:\n" \
++                 "   Que:       0x%p\n" \
++                 "   status:    0x%lx\n" \
++                 "   flags:     0x%lx\n" \
++                 "   semaphore: 0x%x\n" \
++                 "   sequence:  0x%lx\n" \
++                 "   timer:     0x%lx\n" \
++                 "   request:   0x%p\n" \
++                 "   reqlen:    %ld\n" \
++                 "   data:      0x%p\n" \
++                 "   datalen:   %d\n" \
++                 "   reply:     0x%p\n" \
++                 "   replen:    %ld\n",
++         que,
++         que->status,
++         que->flags,
++         atomic_read(&que->semaphore.count),
++         que->sequence,
++         que->timer.expires,
++         que->request,
++         que->reqlen,
++         que->data,
++         que->datalen,
++         que->reply,
++         que->replen);
++      que = (daemon_command_t *)que->list.next;
++   }
++#endif
++}
++
++/*++======================================================================*/
++int NwdConvertNetwareHandle(PXPLAT pdata, daemon_handle_t *DHandle)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   int retVal;
++   NwcConvertNetWareHandle nh;
++   u_long cpylen;
++
++   DbgPrint("NwdConvertNetwareHandle: DHandle=0x%p\n", DHandle);
++
++	cpylen = copy_from_user(&nh, pdata->reqData, sizeof(NwcConvertNetWareHandle));
++
++   retVal = Daemon_Added_Resource(DHandle, DH_TYPE_STREAM, nh.ConnHandle, nh.NetWareHandle, nh.uAccessMode, nh.uFileSize);
++
++   return(retVal);
++}
++
++/*++======================================================================*/
++int NwdConvertLocalHandle(PXPLAT pdata, daemon_handle_t *DHandle)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   int retVal = NWE_REQUESTER_FAILURE;
++   daemon_resource_t *resource;
++   NwcConvertLocalHandle lh;
++   struct list_head *l;
++   u_long cpylen;
++
++   DbgPrint("NwdConvertLocalHandle: DHandle=0x%p\n", DHandle);
++
++   read_lock( &DHandle->lock );
++      
++   list_for_each( l, &DHandle->list )
++   {
++      resource = list_entry( l, daemon_resource_t, list );
++      
++      if ( DH_TYPE_STREAM == resource->type )
++      {
++         lh.uConnReference = resource->connection;
++
++         memcpy(lh.NwFileHandle, resource->handle, sizeof(resource->handle));
++         if (pdata->repLen >= sizeof(NwcConvertLocalHandle))
++         {
++            cpylen = copy_to_user(pdata->repData, &lh, sizeof(NwcConvertLocalHandle));
++            retVal = 0;
++         }
++         else
++         {
++            retVal = NWE_BUFFER_OVERFLOW;
++         }
++            break;
++      }
++   }
++
++   read_unlock( &DHandle->lock );
++
++   return(retVal);
++}
++
++/*++======================================================================*/
++int NwdGetMountPath(PXPLAT pdata)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   int retVal = NWE_REQUESTER_FAILURE;
++   int len;
++   u_long cpylen;
++   NwcGetMountPath mp;
++
++   cpylen = copy_from_user(&mp, pdata->reqData, pdata->reqLen);
++
++   if ( Novfs_CurrentMount )
++   {
++
++      len = strlen(Novfs_CurrentMount)+1;
++      if ( (len > mp.MountPathLen) && mp.pMountPath)
++      {
++         retVal = NWE_BUFFER_OVERFLOW;
++      }
++      else
++      {
++         if (mp.pMountPath)
++         {
++            cpylen = copy_to_user(mp.pMountPath, Novfs_CurrentMount, len);
++         }
++         retVal = 0;
++      }
++
++      mp.MountPathLen = len;
++
++      if (pdata->repData && (pdata->repLen >= sizeof(mp)) )
++      {
++         cpylen = copy_to_user(pdata->repData, &mp, sizeof(mp));
++      }
++   }
++
++   return(retVal);
++}
++
++/*++======================================================================*/
++int NwdSetMapDrive(PXPLAT pdata, session_t Session)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   int retVal;
++   u_long cpylen;
++
++   retVal = NwcSetMapDrive(pdata, Session);
++   if ( !retVal )
++   {
++      NwcMapDriveEx symInfo;
++      char *path;
++      drive_map_t *drivemap, *dm;
++      struct list_head *list;
++
++      cpylen = copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo));
++      drivemap = Novfs_Malloc( sizeof(drive_map_t)+symInfo.linkOffsetLength, GFP_KERNEL );
++      if (drivemap)
++      {
++         path = (char *)pdata->reqData;
++         path += symInfo.linkOffset;
++         cpylen = copy_from_user(drivemap->name, path, symInfo.linkOffsetLength);
++
++         drivemap->session = Session;
++         drivemap->hash = full_name_hash(drivemap->name, symInfo.linkOffsetLength-1);
++         drivemap->namelen = symInfo.linkOffsetLength-1;
++         DbgPrint( "NwdSetMapDrive: hash=0x%x path=%s\n", drivemap->hash, drivemap->name);
++
++         dm = (drive_map_t *)&DriveMapList.next;
++
++         down( &DriveMapLock );
++
++         list_for_each( list, &DriveMapList )
++         {
++            dm = list_entry( list, drive_map_t, list );
++            DbgPrint( "NwdSetMapDrive: dm=0x%p\n" \
++                      "   hash:    0x%x\n" \
++                      "   namelen: %d\n" \
++                      "   name:    %s\n",
++               dm, dm->hash, dm->namelen, dm->name);
++                     
++            if (drivemap->hash == dm->hash)
++            {
++               if ( 0 == strcmp(dm->name, drivemap->name))
++               {
++                  dm = NULL;
++                  break;
++               }
++            }
++            else if (drivemap->hash < dm->hash)
++            {
++               break;
++            }
++         }
++
++         if (dm)
++         {
++            if ( (dm == (drive_map_t *)&DriveMapList) || 
++                 (dm->hash < drivemap->hash) )
++            {
++               list_add( &drivemap->list, &dm->list);
++            }
++            else
++            {
++               list_add_tail( &drivemap->list, &dm->list);
++            }
++         }
++         else
++         {
++            Novfs_Free( drivemap );
++         }
++         up( &DriveMapLock );
++      }
++   }
++
++   return(retVal);
++}
++
++/*++======================================================================*/
++int NwdUnMapDrive(PXPLAT pdata, session_t Session)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   int retVal = NWE_REQUESTER_FAILURE;
++   u_long cpylen;
++
++   retVal = NwcUnMapDrive(pdata, Session);
++   if ( !retVal )
++   {
++      NwcUnmapDriveEx symInfo;
++      char *path;
++      drive_map_t *dm;
++      struct list_head *list;
++      u_long hash;
++
++
++      cpylen = copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo));
++      path = Novfs_Malloc( symInfo.linkLen, GFP_KERNEL );
++      if (path)
++      {
++         cpylen = copy_from_user(path, ((NwcUnmapDriveEx *)pdata->reqData)->linkData, symInfo.linkLen);
++
++         hash = full_name_hash(path, symInfo.linkLen-1);
++         DbgPrint( "NwdUnMapDrive: hash=0x%x path=%s\n", hash, path);
++
++         dm = NULL;
++
++         down( &DriveMapLock );
++
++         list_for_each( list, &DriveMapList )
++         {
++            dm = list_entry( list, drive_map_t, list );
++            DbgPrint( "NwdUnMapDrive: dm=0x%p %s\n" \
++                      "   hash:    0x%x\n" \
++                      "   namelen: %d\n",
++               dm, dm->name, dm->hash, dm->namelen);
++                     
++            if (hash == dm->hash)
++            {
++               if ( 0 == strcmp(dm->name, path))
++               {
++                  break;
++               }
++            }
++            else if (hash < dm->hash)
++            {
++               dm = NULL;
++               break;
++            }
++         }
++
++         if (dm)
++         {
++            DbgPrint( "NwdUnMapDrive: Remove dm=0x%p %s\n" \
++                      "   hash:    0x%x\n" \
++                      "   namelen: %d\n",
++               dm, dm->name, dm->hash, dm->namelen);
++            list_del( &dm->list );
++            Novfs_Free( dm );
++         }
++
++         up( &DriveMapLock );
++      }
++   }
++
++   return(retVal);
++}
++
++/*++======================================================================*/
++void RemoveDriveMaps( void )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   drive_map_t *dm;
++   struct list_head *list;
++
++   down( &DriveMapLock );
++   list_for_each( list, &DriveMapList )
++   {
++      dm = list_entry( list, drive_map_t, list );
++
++      DbgPrint( "RemoveDriveMap: dm=0x%p\n" \
++                "   hash:    0x%x\n" \
++                "   namelen: %d\n" \
++                "   name:    %s\n",
++         dm, dm->hash, dm->namelen, dm->name);
++      local_unlink( dm->name );
++      list = list->prev;
++      list_del( &dm->list );
++      Novfs_Free( dm );
++   }
++   up( &DriveMapLock );
++}
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
++/*++======================================================================*/
++int local_unlink(const char *pathname)
++{
++	int error;
++	struct dentry *dentry;
++	struct nameidata nd;
++	struct inode *inode = NULL;
++
++   DbgPrint("local_unlink: %s\n", pathname);
++   error = path_lookup(pathname, LOOKUP_PARENT, &nd);
++   DbgPrint("local_unlink: path_lookup %d\n", error);
++   if ( !error )
++   {
++      error = -EISDIR;
++      if (nd.last_type == LAST_NORM)
++      {
++         mutex_lock(&nd.dentry->d_inode->i_mutex);
++         dentry = lookup_create( &nd, 1);
++         DbgPrint("local_unlink: lookup_hash 0x%p\n", dentry);
++
++         error = PTR_ERR(dentry);
++         if (!IS_ERR(dentry)) 
++         {
++            if (nd.last.name[nd.last.len])
++            {
++               error = !dentry->d_inode ? -ENOENT : S_ISDIR(dentry->d_inode->i_mode) ? -EISDIR : -ENOTDIR;
++            }
++            else
++            {
++               inode = dentry->d_inode;
++               if (inode)
++               {
++                  atomic_inc(&inode->i_count);
++               }
++               error = vfs_unlink(nd.dentry->d_inode, dentry);
++               DbgPrint("local_unlink: vfs_unlink %d\n", error);
++            }
++            dput(dentry);
++         }
++         mutex_unlock(&nd.dentry->d_inode->i_mutex);
++
++      }
++   	path_release(&nd);
++   }
++
++	if (inode)
++   {
++		iput(inode);	/* truncate the inode here */
++   }
++
++   DbgPrint("local_unlink: error=%d\n", error);
++	return error;
++}
++
++#else
++/*++======================================================================*/
++int local_unlink(const char *pathname)
++{
++	int error;
++	struct dentry *dentry;
++	struct nameidata nd;
++	struct inode *inode = NULL;
++
++   DbgPrint("local_unlink: %s\n", pathname);
++   error = path_lookup(pathname, LOOKUP_PARENT, &nd);
++   DbgPrint("local_unlink: path_lookup %d\n", error);
++   if ( !error )
++   {
++      error = -EISDIR;
++      if (nd.last_type == LAST_NORM)
++      {
++         down(&nd.dentry->d_inode->i_sem);
++         dentry = lookup_one_len(&nd.last, nd.dentry, sizeof(nd.last));
++         DbgPrint("local_unlink: lookup_hash 0x%p\n", dentry);
++
++         error = PTR_ERR(dentry);
++         if (!IS_ERR(dentry)) 
++         {
++            if (nd.last.name[nd.last.len])
++            {
++               error = !dentry->d_inode ? -ENOENT : S_ISDIR(dentry->d_inode->i_mode) ? -EISDIR : -ENOTDIR;
++            }
++            else
++            {
++               inode = dentry->d_inode;
++               if (inode)
++               {
++                  atomic_inc(&inode->i_count);
++               }
++               error = vfs_unlink(nd.dentry->d_inode, dentry);
++               DbgPrint("local_unlink: vfs_unlink %d\n", error);
++            }
++            dput(dentry);
++         }
++         up(&nd.dentry->d_inode->i_sem);
++      }
++   	path_release(&nd);
++   }
++
++	if (inode)
++   {
++		iput(inode);	/* truncate the inode here */
++   }
++
++   DbgPrint("local_unlink: error=%d\n", error);
++	return error;
++}
++#endif
+diff -uNr src.old/src/file.c src/src/file.c
+--- src.old/src/file.c	1970-01-01 01:00:00.000000000 +0100
++++ src/src/file.c	2006-10-16 15:08:22.000000000 +0200
+@@ -0,0 +1,2318 @@
++/*++========================================================================
++ * Program Name:     Novell NCP Redirector for Linux
++ * File Name:        file.c
++ * Version:          v1.00
++ * Author:           James Turner
++ *
++ * Abstract:         This module contains functions for accessing
++ *                   files through the daemon.
++ * Notes:
++ * Revision History: 
++ *
++ *
++ * Copyright (C) 2005 Novell, Inc.
++ *
++ * 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 files specific to Linux ]==================================*/
++#include <linux/module.h>
++#include <linux/fs.h>
++#include <linux/dcache.h>
++#include <linux/pagemap.h>
++#include <linux/stat.h>
++#include <linux/slab.h>
++#include <asm/uaccess.h>
++
++/*===[ Include files specific to this module ]============================*/
++#include "commands.h"
++#include "nwerror.h"
++#include "vfs.h"
++
++/*===[ External data ]====================================================*/
++extern struct dentry_operations Novfs_dentry_operations;
++extern int MaxIoSize;
++
++
++/*===[ External prototypes ]==============================================*/
++extern int DbgPrint( char *Fmt, ... );
++extern void mydump(int size, void *dumpptr);
++extern int Queue_Daemon_Command(void *request, u_long reqlen, void *data, int dlen, void **reply, u_long *replen, int interruptible);
++extern struct inode *Novfs_get_inode(struct super_block *sb, int mode, int dev, uid_t uid);
++
++extern void *Scope_Lookup( void );
++
++/*===[ Manifest constants ]===============================================*/
++
++/*===[ Type definitions ]=================================================*/
++
++/*===[ Function prototypes ]==============================================*/
++
++int Novfs_verify_file( struct qstr *Path, session_t SessionId );
++int Novfs_get_alltrees(struct dentry *parent);
++ssize_t Novfs_tree_read(struct file *file, char *buf, size_t len, loff_t *off);
++
++int Novfs_Get_Connected_Server_List( u_char **ServerList, session_t SessionId );
++int Novfs_Get_Server_Volume_List( struct qstr *Server, u_char **VolumeList, session_t SessionId );
++int Novfs_Find_Name_In_List( struct qstr *Name, u_char *List );
++int Novfs_Verify_Server_Name( struct qstr *Server, session_t SessionId  );
++int Novfs_Verify_Volume_Name( struct qstr *Server,  struct qstr *Volume, session_t SessionId  );
++int Novfs_Get_File_Info( u_char *Path, PENTRY_INFO Info, session_t SessionId );
++int Novfs_Get_Directory_List( u_char *Path, u_long *EnumHandle, PENTRY_INFO Info, session_t SessionId );
++int Novfs_Get_Directory_ListEx( u_char *Path, u_long *EnumHandle, int *Count, PENTRY_INFO *Info, session_t SessionId );
++int Novfs_Open_File( u_char *Path, int Flags, PENTRY_INFO Info, u_long *Handle, session_t SessionId );
++int Novfs_Create( u_char *Path, int DirectoryFlag, session_t SessionId );
++int Novfs_Close_File( u_long Handle, session_t SessionId );
++int Novfs_Read_File( u_long Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId);
++int Novfs_Read_Pages( u_long Handle, PDATA_LIST DList, int DList_Cnt, size_t *Bytes, loff_t *Offset, session_t SessionId);
++int Novfs_Write_File( u_long Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId);
++int Novfs_Write_Pages( u_long Handle, PDATA_LIST DList, int DList_Cnt, size_t Bytes, loff_t Offset, session_t SessionId);
++int Novfs_Read_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, int User, session_t SessionId);
++int Novfs_Write_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId);
++int Novfs_Close_Stream( u_long ConnHandle, u_char *Handle, session_t SessionId );
++int Novfs_Delete( u_char *Path, int DirectoryFlag, session_t SessionId );
++int Novfs_Truncate_File( u_char *Path, int PathLen, session_t SessionId );
++int Novfs_Rename_File( int DirectoryFlag, u_char *OldName, int OldLen, u_char *NewName, int NewLen, session_t SessionId );
++int Novfs_Set_Attr( u_char *Path, struct iattr *Attr, session_t SessionId );
++int Novfs_Get_File_Cache_Flag( u_char *Path, session_t SessionId );
++
++/*===[ Global variables ]=================================================*/
++static struct file_operations Novfs_tree_operations = {
++	read:    Novfs_tree_read,
++};
++
++/*
++ * StripTrailingDots was added because some apps will 
++ * try and create a file name with a trailing dot.  NetWare
++ * doesn't like this and will return an error.
++ */
++u_char StripTrailingDots=1;
++
++/*===[ Code ]=============================================================*/
++
++/*++======================================================================*/
++int Novfs_verify_file( struct qstr *Path, scope_t SessionId  )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PVERIFY_FILE_REPLY reply=NULL;
++   u_long replylen=0;
++   PVERIFY_FILE_REQUEST cmd;
++   int cmdlen;
++   int retCode=0;
++
++   cmdlen = (int)(&((PVERIFY_FILE_REQUEST)0)->path) + Path->len;
++   cmd = (PVERIFY_FILE_REQUEST)Novfs_Malloc(cmdlen, GFP_KERNEL);
++   if (cmd)
++   {
++      cmd->Command.CommandType = VFS_COMMAND_VERIFY_FILE;
++      cmd->Command.SequenceNumber = 0;
++      cmd->Command.SessionId = SessionId;
++      cmd->pathLen = Path->len;
++      memcpy(cmd->path, Path->name, Path->len);
++
++      retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
++      if ( reply )
++      {
++         DbgPrint("Novfs_verify_file: reply\n");
++         mydump(replylen, reply);
++         if (reply->Reply.ErrorCode)
++         {
++            retCode = -ENOENT;
++         }
++         else
++         {
++            retCode = 0;
++         }
++         Novfs_Free(reply);
++      }
++      Novfs_Free(cmd);
++   }
++   else
++   {
++      retCode = -ENOMEM;
++   }
++   return(retCode);
++}
++
++/*++======================================================================*/
++int Novfs_get_alltrees(struct dentry *parent)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   u_char *p;
++   PCOMMAND_REPLY_HEADER reply=NULL;
++   u_long replylen=0;
++   COMMAND_REQUEST_HEADER cmd;
++   int retCode;
++	struct dentry *entry;
++	struct qstr name;
++	struct inode *inode;
++
++   cmd.CommandType = 0;
++   cmd.SequenceNumber = 0;
++   cmd.SessionId = 0x1234;
++
++   DbgPrint( "Novfs_get_alltrees:\n");
++
++   retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
++   DbgPrint( "Novfs_get_alltrees: relpy=0x%x replylen=%d\n", reply, replylen);
++   if (reply)
++   {
++      mydump(replylen, reply);
++      if ( !reply->ErrorCode  && (replylen > sizeof(COMMAND_REPLY_HEADER)))
++      {
++         p = (char *)reply+8;
++         while (*p)
++         {
++            DbgPrint( "Novfs_get_alltrees: %s\n",p);
++            name.len  = strlen(p);
++            name.name = p;
++            name.hash = full_name_hash(name.name, name.len);
++            entry = d_lookup(parent, &name);
++            if ( NULL == entry )
++            {
++               DbgPrint( "Novfs_get_alltrees: adding %s\n",p);
++               entry = d_alloc(parent, &name);
++               if (entry)
++               {
++                  entry->d_op = &Novfs_dentry_operations;
++                  inode = Novfs_get_inode(parent->d_sb, S_IFREG | 0400, 0, 0);
++                  if (inode)
++                  {
++                     inode->i_fop = &Novfs_tree_operations;
++                     d_add(entry, inode);
++                  }
++               }
++            }
++            p += (name.len+1);
++         }
++      }
++      Novfs_Free(reply);
++   }
++   return(retCode);
++}
++
++/*++======================================================================*/
++ssize_t Novfs_tree_read(struct file *file, char *buf, size_t len, loff_t *off)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   if (file->f_pos != 0)
++   {
++      return(0);
++   }
++   if (copy_to_user(buf, "Tree\n", 5))
++   {
++      return(0);
++   }
++   return(5);
++}
++
++/*++======================================================================*/
++int Novfs_Get_Connected_Server_List( u_char **ServerList, session_t SessionId )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   GET_CONNECTED_SERVER_LIST_REQUEST req;
++   PGET_CONNECTED_SERVER_LIST_REPLY  reply=NULL;
++   u_long replylen=0;
++   int retCode=0;
++
++   *ServerList = NULL;
++
++   req.Command.CommandType = VFS_COMMAND_GET_CONNECTED_SERVER_LIST;
++   req.Command.SessionId = SessionId;
++
++   retCode = Queue_Daemon_Command(&req, sizeof(req), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
++   if ( reply )
++   {
++      DbgPrint("Novfs_Get_Connected_Server_List: reply\n");
++      replylen -= sizeof(COMMAND_REPLY_HEADER);
++      if ( !reply->Reply.ErrorCode && replylen )
++      {
++         memcpy(reply, reply->List, replylen);
++         *ServerList = (u_char *)reply;
++         retCode = 0;
++      }
++      else
++      {
++         Novfs_Free(reply);
++         retCode = -ENOENT;
++      }
++   }
++   return(retCode);
++}
++
++/*++======================================================================*/
++int Novfs_Get_Server_Volume_List( struct qstr *Server, u_char **VolumeList, scope_t SessionId )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PGET_SERVER_VOLUME_LIST_REQUEST req;
++   PGET_SERVER_VOLUME_LIST_REPLY  reply=NULL;
++   u_long replylen=0, reqlen;
++   int retCode;
++
++   *VolumeList = NULL;
++   reqlen = sizeof(GET_SERVER_VOLUME_LIST_REQUEST)+Server->len;
++   req = Novfs_Malloc(reqlen, GFP_KERNEL);
++   if (req)
++   {
++      req->Command.CommandType = VFS_COMMAND_GET_SERVER_VOLUME_LIST;
++      req->Length = Server->len;
++      memcpy(req->Name, Server->name, Server->len);
++      req->Command.SessionId = SessionId;
++
++      retCode = Queue_Daemon_Command(req, reqlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
++      if ( reply )
++      {
++         DbgPrint("Novfs_Get_Server_Volume_List: reply\n");
++         mydump(replylen, reply);
++         replylen -= sizeof(COMMAND_REPLY_HEADER);
++
++         if ( !reply->Reply.ErrorCode && replylen )
++         {
++            memcpy(reply, reply->List, replylen);
++            *VolumeList = (u_char *)reply;
++            retCode = 0;
++         }
++         else
++         {
++            Novfs_Free(reply);
++            retCode = -ENOENT;
++         }
++      }
++      Novfs_Free(req);
++   }
++   else
++   {
++      retCode = -ENOMEM;
++   }
++   return(retCode);
++}
++
++/*++======================================================================*/
++int Novfs_Find_Name_In_List( struct qstr *Name, u_char *List )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   int len;
++   int retCode = 0;
++
++   while (*List)
++   {
++      len = strlen(List);
++      if ((len == Name->len) && !strncmp(Name->name, List, len))
++      {
++         retCode = 1;
++         break;
++      }
++      List += (len+1);
++   }
++   return( retCode );
++}
++
++/*++======================================================================*/
++int Novfs_Verify_Server_Name( struct qstr *Server, session_t SessionId )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   u_char *list;
++   int retCode = 0;
++
++   DbgPrint("Novfs_Verify_Server_Name: %.*s\n", Server->len, Server->name);
++
++   list = NULL;
++   Novfs_Get_Connected_Server_List( &list, SessionId );
++
++   if (list)
++   {
++      retCode = Novfs_Find_Name_In_List( Server, list );
++      Novfs_Free(list);
++   }
++   DbgPrint("Novfs_Verify_Server_Name: %d\n", retCode);
++   return(retCode);
++}
++
++/*++======================================================================*/
++int Novfs_Verify_Volume_Name( struct qstr *Server,  struct qstr *Volume, session_t SessionId )
++/*
++ *
++ *  Arguments:   Server - Server name.
++ *               Volume - Volume name to check for.
++ *
++ *  Returns:     zero - not found.
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   u_char *list;
++   int retCode = 0;
++   u_char *name;
++   int namelen;
++   struct qstr path;
++
++   list = NULL;
++   namelen = Server->len+Volume->len+2;
++   name = Novfs_Malloc(namelen, GFP_KERNEL);
++
++   if (name)
++   {
++      name[0] = '\\';
++      memcpy(&name[1], Server->name, Server->len);
++      name[1+Server->len] = '\\';
++      memcpy(&name[2+Server->len], Volume->name, Volume->len);
++      path.len = namelen;
++      path.name = name;
++
++      if (Novfs_verify_file(&path, SessionId))
++      {
++         retCode = 0;
++      }
++      else
++      {
++         retCode = 1;
++      }
++
++      Novfs_Free(name);
++   }
++   else
++   {
++
++      Novfs_Get_Server_Volume_List( Server, &list, SessionId );
++
++      if (list)
++      {
++         retCode = Novfs_Find_Name_In_List( Volume, list );
++         Novfs_Free(list);
++      }
++   }
++   return(retCode);
++}
++
++/*++======================================================================*/
++int Novfs_Get_File_Info( u_char *Path, PENTRY_INFO Info, session_t SessionId )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PVERIFY_FILE_REPLY reply=NULL;
++   u_long replylen=0;
++   PVERIFY_FILE_REQUEST cmd;
++   int cmdlen;
++   int retCode=-ENOENT;
++   int pathlen;
++
++   DbgPrint("Novfs_Get_File_Info: Path = %s\n", Path);
++
++   Info->mode = S_IFDIR | 0700;
++   Info->uid = current->uid;
++   Info->gid = current->gid;
++   Info->size = 0;
++   Info->atime = Info->mtime = Info->ctime = CURRENT_TIME;
++
++   if (Path && *Path)
++   {
++      pathlen = strlen(Path);
++      if (StripTrailingDots)
++      {
++         if ('.' == Path[pathlen-1]) pathlen--;
++      }
++      cmdlen = (int)(&((PVERIFY_FILE_REQUEST)0)->path) + pathlen;
++      cmd = (PVERIFY_FILE_REQUEST)Novfs_Malloc(cmdlen, GFP_KERNEL);
++      if (cmd)
++      {
++         cmd->Command.CommandType = VFS_COMMAND_VERIFY_FILE;
++         cmd->Command.SequenceNumber = 0;
++         cmd->Command.SessionId = SessionId;
++         cmd->pathLen = pathlen;
++         memcpy(cmd->path, Path, cmd->pathLen);
++
++         retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
++
++         if (reply)
++         {
++            
++            if ( reply->Reply.ErrorCode )
++            {
++               retCode = -ENOENT;
++            }
++            else
++            {
++               Info->type = 3;
++               Info->mode = S_IRWXU;
++
++               if (reply->fileMode & NW_ATTRIBUTE_DIRECTORY)
++               {
++                  Info->mode |= S_IFDIR;
++               }
++               else
++               {
++                  Info->mode |= S_IFREG;
++               }
++
++               if (reply->fileMode & NW_ATTRIBUTE_READ_ONLY)
++               {
++                  Info->mode &= ~(S_IWUSR);
++               }
++
++               Info->uid   = current->euid;
++               Info->gid   = current->egid;
++               Info->size  = reply->fileSize;
++               Info->atime.tv_sec  = reply->lastAccessTime;
++               Info->atime.tv_nsec = 0;
++               Info->mtime.tv_sec  = reply->modifyTime;
++               Info->mtime.tv_nsec = 0;
++               Info->ctime.tv_sec  = reply->createTime;
++               Info->ctime.tv_nsec = 0;
++               DbgPrint("Novfs_Get_File_Info: replylen=%d sizeof(VERIFY_FILE_REPLY)=%d\n", replylen, sizeof(VERIFY_FILE_REPLY));
++               if (replylen > sizeof(VERIFY_FILE_REPLY))
++               {
++                  long *lp = &reply->fileMode;
++                  lp++;
++                  DbgPrint("Novfs_Get_File_Info: extra data 0x%x\n", *lp);
++                  Info->mtime.tv_nsec = *lp;
++               }
++               retCode = 0;
++            }
++
++            Novfs_Free(reply);
++         }
++         Novfs_Free(cmd);
++      }
++   }
++
++   DbgPrint("Novfs_Get_File_Info: return 0x%x\n", retCode);
++   return(retCode);
++}
++
++/*++======================================================================*/
++int Novfs_Get_File_Info2( u_char *Path, PENTRY_INFO Info, session_t SessionId )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PVERIFY_FILE_REPLY reply=NULL;
++   u_long replylen=0;
++   PVERIFY_FILE_REQUEST cmd;
++   int cmdlen;
++   struct qstr server = {0}, volume = {0};
++   u_char *p;
++   int i;
++   int retCode=-ENOENT;
++   p = Path;
++
++   DbgPrint("Novfs_Get_File_Info: Path = %s\n", Path);
++
++   Info->mode = S_IFDIR | 0700;
++   Info->uid = current->uid;
++   Info->gid = current->gid;
++   Info->size = 0;
++   Info->atime = Info->mtime = Info->ctime = CURRENT_TIME;
++
++   if ('\\' == *p)
++   {
++      p++;
++   }
++   server.name = p;
++
++   for(i=0; *p && ('\\' != *p); i++, p++);
++   server.len = i;
++   if (*p)
++   {
++      if ('\\' == *p)
++      {
++         p++;
++      }
++      volume.name = p;
++      for(i=0; *p && ('\\' != *p); i++, p++);
++      if (i)
++      {
++         volume.len = i;
++         if (*p)
++         {
++            if ('\\' == *p)
++            {
++               p++;
++            }
++            if (*p)
++            {
++               cmdlen = (int)(&((PVERIFY_FILE_REQUEST)0)->path) + strlen(Path);
++               cmd = (PVERIFY_FILE_REQUEST)Novfs_Malloc(cmdlen, GFP_KERNEL);
++               if (cmd)
++               {
++                  cmd->Command.CommandType = VFS_COMMAND_VERIFY_FILE;
++                  cmd->Command.SequenceNumber = 0;
++                  cmd->Command.SessionId = SessionId;
++                  cmd->pathLen = strlen(Path);
++                  memcpy(cmd->path, Path, cmd->pathLen);
++
++                  retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
++                  if (reply)
++                  {
++                     
++                     if ( reply->Reply.ErrorCode )
++                     {
++                        retCode = -ENOENT;
++                     }
++                     else
++                     {
++                        Info->type = 3;
++                        Info->mode = S_IRWXU;
++
++                        if (reply->fileMode & NW_ATTRIBUTE_DIRECTORY)
++                        {
++                           Info->mode |= S_IFDIR;
++                        }
++                        else
++                        {
++                           Info->mode |= S_IFREG;
++                        }
++
++                        if (reply->fileMode & NW_ATTRIBUTE_READ_ONLY)
++                        {
++                           Info->mode &= ~(S_IWUSR);
++                        }
++
++                        Info->uid   = current->euid;
++                        Info->gid   = current->egid;
++                        Info->size  = reply->fileSize;
++                        Info->atime.tv_sec  = reply->lastAccessTime;
++                        Info->atime.tv_nsec = 0;
++                        Info->mtime.tv_sec  = reply->modifyTime;
++                        Info->mtime.tv_nsec = 0;
++                        Info->ctime.tv_sec  = reply->createTime;
++                        Info->ctime.tv_nsec = 0;
++                        retCode = 0;
++                     }
++
++                     Novfs_Free(reply);
++                  }
++                  Novfs_Free(cmd);
++               }
++            }
++         }
++      }
++      if (('\0' == *p) && volume.len)
++      {
++         if ( Novfs_Verify_Volume_Name( &server, &volume, SessionId ) )
++         {
++            retCode = 0;
++            Info->type = 2;
++         }
++      }
++   }
++   if (server.len && !volume.len)
++   {
++      if ( Novfs_Verify_Server_Name( &server, SessionId ) )
++      {
++         retCode = 0;
++         Info->type = 1;
++      }
++   }
++   DbgPrint("Novfs_Get_File_Info: return 0x%x\n", retCode);
++   return(retCode);
++}
++
++/*++======================================================================*/
++int begin_directory_enumerate( u_char *Path, int PathLen, u_long *EnumHandle, session_t SessionId)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PBEGIN_ENUMERATE_DIRECTORY_REQUEST cmd;
++   PBEGIN_ENUMERATE_DIRECTORY_REPLY   reply=NULL;
++   u_long replylen=0;
++   int retCode, cmdlen;
++
++   *EnumHandle = 0;
++
++   cmdlen = (int)(&((PBEGIN_ENUMERATE_DIRECTORY_REQUEST)0)->path) + PathLen;
++   cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++   if (cmd)
++   {
++      cmd->Command.CommandType    = VFS_COMMAND_START_ENUMERATE;
++      cmd->Command.SequenceNumber = 0;
++      cmd->Command.SessionId      = SessionId;
++
++      cmd->pathLen = PathLen;
++      memcpy(cmd->path, Path, PathLen);
++
++      retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
++/*
++ *      retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, 0);
++ */
++      if (reply)
++      {
++         if (reply->Reply.ErrorCode)
++         {
++            retCode = -EIO;
++         }
++         else
++         {
++            *EnumHandle = reply->enumerateHandle;
++            retCode = 0;
++         }
++         Novfs_Free(reply);
++      }
++      Novfs_Free(cmd);
++   }
++   else
++   {
++      retCode = -ENOMEM;
++   }
++   return( retCode );
++}
++
++/*++======================================================================*/
++int end_directory_enumerate( u_long EnumHandle, session_t SessionId )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   END_ENUMERATE_DIRECTORY_REQUEST cmd;
++   PEND_ENUMERATE_DIRECTORY_REPLY  reply=NULL;
++   u_long replylen=0;
++   int retCode;
++
++
++   cmd.Command.CommandType    = VFS_COMMAND_END_ENUMERATE;
++   cmd.Command.SequenceNumber = 0;
++   cmd.Command.SessionId      = SessionId;
++
++   cmd.enumerateHandle = EnumHandle;
++
++   retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, 0);
++   if (reply)
++   {
++      retCode = 0;
++      if (reply->Reply.ErrorCode)
++      {
++         retCode = -EIO;
++      }
++      Novfs_Free(reply);
++   }
++
++   return( retCode );
++}
++
++/*++======================================================================*/
++int directory_enumerate( u_long *EnumHandle, PENTRY_INFO Info, session_t SessionId )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   ENUMERATE_DIRECTORY_REQUEST cmd;
++   PENUMERATE_DIRECTORY_REPLY  reply=NULL;
++   u_long replylen=0;
++   int retCode;
++
++
++   cmd.Command.CommandType    = VFS_COMMAND_ENUMERATE_DIRECTORY;
++   cmd.Command.SequenceNumber = 0;
++   cmd.Command.SessionId      = SessionId;
++
++   cmd.enumerateHandle = *EnumHandle;
++   cmd.pathLen = 0;
++   cmd.path[0] = '\0';
++
++   retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
++
++   if (reply)
++   {
++      /*
++       * The VFS_COMMAND_ENUMERATE_DIRECTORY call can return an
++       * error but there could still be valid data.
++       */
++      if ( !reply->Reply.ErrorCode || 
++           ( (replylen > sizeof(COMMAND_REPLY_HEADER)) &&
++             (reply->nameLen > 0)) )
++      {
++         Info->type = 3;
++         Info->mode = S_IRWXU;
++
++         if (reply->mode & NW_ATTRIBUTE_DIRECTORY)
++         {
++            Info->mode |= S_IFDIR;
++            Info->mode |= S_IXUSR;
++         }
++         else
++         {
++            Info->mode |= S_IFREG;
++         }
++
++         if (reply->mode & NW_ATTRIBUTE_READ_ONLY)
++         {
++            Info->mode &= ~(S_IWUSR);
++         }
++
++         if (reply->mode & NW_ATTRIBUTE_EXECUTE)
++         {
++            Info->mode |= S_IXUSR;
++         }
++
++         Info->uid           = current->uid;
++         Info->gid           = current->gid;
++         Info->size          = reply->size;
++         Info->atime.tv_sec  = reply->lastAccessTime;
++         Info->atime.tv_nsec = 0;
++         Info->mtime.tv_sec  = reply->modifyTime;
++         Info->mtime.tv_nsec = 0;
++         Info->ctime.tv_sec  = reply->createTime;
++         Info->ctime.tv_nsec = 0;
++         Info->namelength    = reply->nameLen;
++         memcpy(Info->name, reply->name, reply->nameLen);
++         retCode = 0;
++         if (reply->Reply.ErrorCode)
++         {
++            retCode = -1; /* Eof of data */
++         }
++         *EnumHandle = reply->enumerateHandle;
++      }
++      else
++      {
++         retCode = -ENODATA;
++      }
++      Novfs_Free(reply);
++   }
++
++   return( retCode );
++}
++
++/*++======================================================================*/
++int directory_enumerate_ex( u_long *EnumHandle, session_t SessionId,  int *Count, PENTRY_INFO *PInfo, int Interrupt)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   ENUMERATE_DIRECTORY_EX_REQUEST cmd;
++   PENUMERATE_DIRECTORY_EX_REPLY  reply=NULL;
++   u_long replylen=0;
++   int retCode=0;
++   PENTRY_INFO info;
++   PENUMERATE_DIRECTORY_EX_DATA data;
++   int isize;
++
++   if (PInfo)
++   {
++      *PInfo = NULL;
++   }
++   *Count = 0;
++
++   cmd.Command.CommandType    = VFS_COMMAND_ENUMERATE_DIRECTORY_EX;
++   cmd.Command.SequenceNumber = 0;
++   cmd.Command.SessionId      = SessionId;
++
++   cmd.enumerateHandle = *EnumHandle;
++   cmd.pathLen = 0;
++   cmd.path[0] = '\0';
++
++   retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, Interrupt);
++
++   if (reply)
++   {
++      retCode = 0;
++      /*
++       * The VFS_COMMAND_ENUMERATE_DIRECTORY call can return an
++       * error but there could still be valid data.
++       */
++
++      if ( !reply->Reply.ErrorCode || 
++           ( (replylen > sizeof(COMMAND_REPLY_HEADER)) &&
++             (reply->enumCount > 0)) )
++      {
++         DbgPrint("directory_enumerate_ex: isize=%d\n", replylen);
++         data = (PENUMERATE_DIRECTORY_EX_DATA)((char *)reply + sizeof(ENUMERATE_DIRECTORY_EX_REPLY));
++         isize =  replylen - 
++                  sizeof(PENUMERATE_DIRECTORY_EX_REPLY) - 
++                  reply->enumCount * (int)(&((PENUMERATE_DIRECTORY_EX_DATA)0)->name);
++         isize +=  (reply->enumCount * (int)(&((PENTRY_INFO)0)->name));
++
++         if (PInfo)
++         {
++            *PInfo = info = Novfs_Malloc(isize, GFP_KERNEL);
++            if ( *PInfo )
++            {
++               DbgPrint("directory_enumerate_ex1: data=0x%p info=0x%p\n", data, info);
++               *Count = reply->enumCount;
++               do
++               {
++                  DbgPrint("directory_enumerate_ex2: data=0x%p length=%d\n", data);
++
++                  info->type = 3;
++                  info->mode = S_IRWXU;
++
++                  if (data->mode & NW_ATTRIBUTE_DIRECTORY)
++                  {
++                     info->mode |= S_IFDIR;
++                     info->mode |= S_IXUSR;
++                  }
++                  else
++                  {
++                     info->mode |= S_IFREG;
++                  }
++
++                  if (data->mode & NW_ATTRIBUTE_READ_ONLY)
++                  {
++                     info->mode &= ~(S_IWUSR);
++                  }
++
++                  if (data->mode & NW_ATTRIBUTE_EXECUTE)
++                  {
++                     info->mode |= S_IXUSR;
++                  }
++
++                  info->uid           = current->euid;
++                  info->gid           = current->egid;
++                  info->size          = data->size;
++                  info->atime.tv_sec  = data->lastAccessTime;
++                  info->atime.tv_nsec = 0;
++                  info->mtime.tv_sec  = data->modifyTime;
++                  info->mtime.tv_nsec = 0;
++                  info->ctime.tv_sec  = data->createTime;
++                  info->ctime.tv_nsec = 0;
++                  info->namelength    = data->nameLen;
++                  memcpy(info->name, data->name, data->nameLen);
++                  data = (PENUMERATE_DIRECTORY_EX_DATA)&data->name[data->nameLen];
++                  replylen = (int)((char *)&info->name[info->namelength] - (char *)info);
++                  DbgPrint("directory_enumerate_ex3: info=0x%p\n", info);
++                  mydump(replylen, info);
++
++                  info = (PENTRY_INFO)&info->name[info->namelength];
++
++               } while (--reply->enumCount);
++            }
++         }
++
++         if (reply->Reply.ErrorCode)
++         {
++            retCode = -1; /* Eof of data */
++         }
++         *EnumHandle = reply->enumerateHandle;
++      }
++      else
++      {
++         retCode = -ENODATA;
++      }
++      Novfs_Free(reply);
++   }
++
++   return( retCode );
++}
++
++/*++======================================================================*/
++int Novfs_Get_Directory_List( u_char *Path, u_long *EnumHandle, PENTRY_INFO Info, session_t SessionId )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   int retCode = -ENOENT;
++
++   if ( -1 == *EnumHandle)
++   {
++      return( -ENODATA );
++   }
++
++   if ( 0 == *EnumHandle )
++   {
++      retCode = begin_directory_enumerate(Path, strlen(Path), EnumHandle, SessionId);
++   }
++
++   if ( *EnumHandle )
++   {
++      retCode = directory_enumerate( EnumHandle, Info, SessionId );
++      if (retCode)
++      {
++         end_directory_enumerate( *EnumHandle, SessionId );
++         if ( -1 == retCode )
++         {
++            retCode = 0;
++            *EnumHandle = -1;
++         }
++      }
++   }
++   return(retCode);
++}
++
++/*++======================================================================*/
++int Novfs_Get_Directory_ListEx( u_char *Path, u_long *EnumHandle, int *Count, PENTRY_INFO *Info, session_t SessionId )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   int retCode = -ENOENT;
++
++   if (Count)  *Count = 0;
++   if (Info)   *Info = NULL;
++
++   if ( -1 == *EnumHandle)
++   {
++      return( -ENODATA );
++   }
++
++   if ( 0 == *EnumHandle )
++   {
++      retCode = begin_directory_enumerate(Path, strlen(Path), EnumHandle, SessionId);
++   }
++
++   if ( *EnumHandle )
++   {
++      retCode = directory_enumerate_ex( EnumHandle, SessionId, Count, Info, INTERRUPTIBLE );
++      if (retCode)
++      {
++         end_directory_enumerate( *EnumHandle, SessionId );
++         if ( -1 == retCode )
++         {
++            retCode = 0;
++            *EnumHandle = -1;
++         }
++      }
++   }
++   return(retCode);
++}
++
++/*++======================================================================*/
++int Novfs_Open_File( u_char *Path, int Flags, PENTRY_INFO Info, u_long *Handle, session_t SessionId )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   POPEN_FILE_REQUEST cmd;
++   POPEN_FILE_REPLY   reply;
++   u_long replylen=0;
++   int retCode, cmdlen, pathlen;
++
++   pathlen = strlen(Path);
++
++   if (StripTrailingDots)
++   {
++      if ('.' == Path[pathlen-1]) pathlen--;
++   }
++
++   *Handle = 0;
++
++   cmdlen = (int)(&((POPEN_FILE_REQUEST)0)->path) + pathlen;
++   cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++   if (cmd)
++   {
++      cmd->Command.CommandType    = VFS_COMMAND_OPEN_FILE;
++      cmd->Command.SequenceNumber = 0;
++      cmd->Command.SessionId      = SessionId;
++
++      cmd->access = 0;
++
++      if ( !(Flags & O_WRONLY) || (Flags & O_RDWR))
++      {
++         cmd->access |= NWD_ACCESS_READ;
++      }
++
++      if ((Flags & O_WRONLY) || (Flags & O_RDWR))
++      {
++         cmd->access |= NWD_ACCESS_WRITE;
++      }
++
++      switch (Flags & (O_CREAT | O_EXCL | O_TRUNC))
++      {
++         case O_CREAT:
++            cmd->disp = NWD_DISP_OPEN_ALWAYS;
++            break;
++
++         case O_CREAT | O_EXCL:
++            cmd->disp = NWD_DISP_CREATE_NEW;
++            break;
++
++         case O_TRUNC:
++            cmd->disp = NWD_DISP_CREATE_ALWAYS;
++            break;
++
++         case O_CREAT | O_TRUNC:
++            cmd->disp = NWD_DISP_CREATE_ALWAYS;
++            break;
++
++         case O_CREAT | O_EXCL | O_TRUNC:
++            cmd->disp = NWD_DISP_CREATE_NEW;
++            break;
++
++         default:
++            cmd->disp = NWD_DISP_OPEN_EXISTING;
++            break;
++      }
++
++      cmd->mode = NWD_SHARE_READ | NWD_SHARE_WRITE | NWD_SHARE_DELETE;
++
++      cmd->pathLen = pathlen;
++      memcpy(cmd->path, Path, pathlen);
++
++      retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
++
++      if (reply)
++      {
++         if (reply->Reply.ErrorCode)
++         {
++            if( NWE_OBJECT_EXISTS == reply->Reply.ErrorCode)
++            {
++               retCode = -EEXIST;
++            }
++            else if( NWE_ACCESS_DENIED == reply->Reply.ErrorCode)
++            {
++               retCode = -EACCES;
++            }
++            else 
++            {
++               retCode = -ENOENT;
++            }
++         }
++         else
++         {
++            *Handle = reply->handle;
++            retCode = 0;
++         }
++         Novfs_Free(reply);
++      }
++      Novfs_Free(cmd);
++   }
++   else
++   {
++      retCode = -ENOMEM;
++   }
++   return( retCode );
++}
++
++/*++======================================================================*/
++int Novfs_Create( u_char *Path, int DirectoryFlag, session_t SessionId )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PCREATE_FILE_REQUEST cmd;
++   PCREATE_FILE_REPLY   reply;
++   u_long replylen=0;
++   int retCode, cmdlen, pathlen;
++
++   pathlen = strlen(Path);
++
++   if (StripTrailingDots)
++   {
++      if ('.' == Path[pathlen-1]) pathlen--;
++   }
++
++   cmdlen = (int)(&((PCREATE_FILE_REQUEST)0)->path) + pathlen;
++   cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++   if (cmd)
++   {
++      cmd->Command.CommandType    = VFS_COMMAND_CREATE_FILE;
++      if (DirectoryFlag)
++      {
++         cmd->Command.CommandType    = VFS_COMMAND_CREATE_DIRECOTRY;
++      }
++      cmd->Command.SequenceNumber = 0;
++      cmd->Command.SessionId      = SessionId;
++
++      cmd->pathlength = pathlen;
++      memcpy(cmd->path, Path, pathlen);
++
++      retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
++
++      if (reply)
++      {
++         retCode = 0;
++         if (reply->Reply.ErrorCode)
++         {
++            retCode = -EIO;
++         }
++         Novfs_Free(reply);
++      }
++      Novfs_Free(cmd);
++   }
++   else
++   {
++      retCode = -ENOMEM;
++   }
++   return( retCode );
++}
++
++/*++======================================================================*/
++int Novfs_Close_File( u_long Handle, session_t SessionId )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   CLOSE_FILE_REQUEST cmd;
++   PCLOSE_FILE_REPLY  reply;
++   u_long replylen=0;
++   int retCode;
++
++   cmd.Command.CommandType    = VFS_COMMAND_CLOSE_FILE;
++   cmd.Command.SequenceNumber = 0;
++   cmd.Command.SessionId      = SessionId;
++
++   cmd.handle = Handle;
++
++   retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, 0);
++   if (reply)
++   {
++      retCode = 0;
++      if (reply->Reply.ErrorCode)
++      {
++         retCode = -EIO;
++      }
++      Novfs_Free(reply);
++   }
++   return( retCode );
++}
++/*++======================================================================*/
++int Novfs_Read_File( u_long Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   READ_FILE_REQUEST cmd;
++   PREAD_FILE_REPLY  reply=NULL;
++   u_long replylen=0;
++   int retCode = 0;
++   size_t len;
++
++   len = *Bytes;
++   *Bytes = 0;
++
++   if ( ((int)(&((PREAD_FILE_REPLY)0)->data) + len) > MaxIoSize)
++   {
++      len = MaxIoSize - (int)(&((PREAD_FILE_REPLY)0)->data);
++      len = (len/PAGE_SIZE)*PAGE_SIZE;
++   }
++
++   cmd.Command.CommandType    = VFS_COMMAND_READ_FILE;
++   cmd.Command.SequenceNumber = 0;
++   cmd.Command.SessionId      = SessionId;
++
++   cmd.handle = Handle;
++   cmd.len    = len;
++   cmd.offset = *Offset;
++
++   retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
++
++   DbgPrint("Novfs_Read_File: Queue_Daemon_Command 0x%x replylen=%d\n", retCode, replylen);
++
++   if (!retCode)
++   {
++      if (reply->Reply.ErrorCode)
++      {
++         retCode = -EIO;
++      }
++      else
++      {
++         replylen -= (int)(&((PREAD_FILE_REPLY)0)->data);
++         if (replylen > 0)
++         {
++            replylen -= copy_to_user(Buffer, reply->data, replylen);
++            *Bytes = replylen;
++         }
++      }
++   }
++
++   if ( reply )
++   {
++      Novfs_Free(reply);
++   }
++   
++   DbgPrint("Novfs_Read_File *Bytes=0x%x retCode=0x%x\n", *Bytes, retCode);
++
++   return( retCode );
++}
++
++/*++======================================================================*/
++int Novfs_Read_Pages( u_long Handle, PDATA_LIST DList, int DList_Cnt, size_t *Bytes, loff_t *Offset, session_t SessionId)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   READ_FILE_REQUEST cmd;
++   PREAD_FILE_REPLY  reply=NULL;
++   READ_FILE_REPLY   lreply;
++   u_long replylen=0;
++   int retCode = 0;
++   size_t len;
++
++   len = *Bytes;
++   *Bytes = 0;
++
++   DbgPrint("Novfs_Read_File_Pages: Handle=0x%x Dlst=0x%p Dlcnt=%d Bytes=%d Offset=%lld SessionId=0x%llx\n", 
++      Handle, DList, DList_Cnt, len, *Offset, SessionId);
++
++   cmd.Command.CommandType    = VFS_COMMAND_READ_FILE;
++   cmd.Command.SequenceNumber = 0;
++   cmd.Command.SessionId      = SessionId;
++
++   cmd.handle = Handle;
++   cmd.len    = len;
++   cmd.offset = *Offset;
++
++   /*
++    * Dlst first entry is reserved for reply header.
++    */
++   DList[0].page   = NULL;
++   DList[0].offset = &lreply;
++   DList[0].len    = (int)(&((PREAD_FILE_REPLY)0)->data);
++   DList[0].rwflag = DLWRITE;
++
++   retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), DList, DList_Cnt, (void *)&reply, &replylen, INTERRUPTIBLE);
++
++   DbgPrint("Novfs_Read_File_Pages: Queue_Daemon_Command 0x%x\n", retCode);
++
++   if (!retCode)
++   {
++      if (reply)
++      {
++         memcpy(&lreply, reply, sizeof(lreply));
++      }
++
++      if (lreply.Reply.ErrorCode)
++      {
++         retCode = -EIO;
++      }
++      *Bytes = replylen - (int)(&((PREAD_FILE_REPLY)0)->data);
++   }
++
++   if ( reply )
++   {
++      Novfs_Free(reply);
++   }
++   
++   DbgPrint("Novfs_Read_File: retCode=0x%x\n", retCode);
++
++   return( retCode );
++}
++
++/*++======================================================================*/
++int Novfs_Write_File( u_long Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   WRITE_FILE_REQUEST cmd;
++   PWRITE_FILE_REPLY  reply=NULL;
++   unsigned long replylen=0;
++   int retCode=0, cmdlen;
++   size_t len;
++
++   unsigned long boff;
++   struct page **pages;
++   DATA_LIST *dlist;
++	int res=0, npage, i;
++   WRITE_FILE_REPLY   lreply;
++
++
++   len = *Bytes;
++   cmdlen = (int)(&((PWRITE_FILE_REQUEST)0)->data);
++
++   *Bytes = 0;
++
++   memset(&lreply, 0, sizeof(lreply));
++
++   DbgPrint("Novfs_Write_File cmdlen=%ld len=%ld\n", cmdlen, len);
++
++   if ( (cmdlen+len) > MaxIoSize)
++   {
++      len = MaxIoSize-cmdlen;
++      len = (len/PAGE_SIZE)*PAGE_SIZE;
++   }
++   cmd.Command.CommandType    = VFS_COMMAND_WRITE_FILE;
++   cmd.Command.SequenceNumber = 0;
++   cmd.Command.SessionId      = SessionId;
++   cmd.handle = Handle;
++   cmd.len    = len;
++   cmd.offset = *Offset;
++
++   DbgPrint("Novfs_Write_File cmdlen=%ld len=%ld\n", cmdlen, len);
++
++   npage = (((unsigned long)Buffer & ~PAGE_MASK) + len + (PAGE_SIZE-1)) >> PAGE_SHIFT;
++
++   dlist = Novfs_Malloc(sizeof(DATA_LIST)*(npage+1), GFP_KERNEL);
++   if (NULL == dlist)
++   {
++      return(-ENOMEM);
++   }
++
++   pages = Novfs_Malloc(sizeof(struct page *)*npage, GFP_KERNEL);
++
++   if (NULL == pages)
++   {
++      Novfs_Free(dlist);
++      return(-ENOMEM);
++   }
++
++	down_read(&current->mm->mmap_sem);
++
++	res = get_user_pages(
++		current,
++		current->mm,
++		(unsigned long)Buffer,
++		npage,
++		0, /* read type */
++		0, /* don't force */
++		pages,
++		NULL);
++
++	up_read(&current->mm->mmap_sem);
++
++   DbgPrint("Novfs_Write_File res=%d\n", res);
++
++   if ( res > 0 )
++   {
++      boff = (unsigned long)Buffer & ~PAGE_MASK;
++      
++   	flush_dcache_page(pages[0]);
++      dlist[0].page   = pages[0];
++      dlist[0].offset = (char *)boff;
++      dlist[0].len    = PAGE_SIZE - boff;
++      dlist[0].rwflag = DLREAD;
++
++      if (dlist[0].len > len)
++      {
++         dlist[0].len = len;
++      }
++
++      DbgPrint("Novfs_Write_File0: page=0x%x offset=0x%p len=%d\n", dlist[0].page, dlist[0].offset, dlist[0].len);
++
++      boff = dlist[0].len;
++
++      DbgPrint("Novfs_Write_File len=%d boff=%d\n", len, boff);
++
++      for (i=1; (i < res) && (boff < len); i++)
++      {
++   		flush_dcache_page(pages[i]);
++
++         dlist[i].page = pages[i];
++         dlist[i].offset = NULL;
++         dlist[i].len = len-boff;
++         if (dlist[i].len > PAGE_SIZE)
++         {
++            dlist[i].len = PAGE_SIZE;
++         }
++         dlist[i].rwflag = DLREAD;
++
++         boff += dlist[i].len;
++         DbgPrint("Novfs_Write_File%d: page=0x%x offset=0x%p len=%d\n", i, dlist[i].page, dlist[i].offset, dlist[i].len);
++      }
++
++      dlist[i].page   = NULL;
++      dlist[i].offset = &lreply;
++      dlist[i].len    = sizeof(lreply);
++      dlist[i].rwflag = DLWRITE;
++      res++;
++
++      DbgPrint("Novfs_Write_File Buffer=0x%x boff=0x%x len=%d\n", Buffer, boff, len);
++
++      retCode = Queue_Daemon_Command(&cmd, cmdlen, dlist, res, (void *)&reply, &replylen, INTERRUPTIBLE);
++
++   }
++   else
++   {
++      char *kdata;
++
++      res = 0;
++      
++      kdata = Novfs_Malloc(len, GFP_KERNEL);
++      if (kdata)
++      {
++         len -= copy_from_user(kdata, Buffer, len);
++         dlist[0].page   = NULL;
++         dlist[0].offset = kdata;
++         dlist[0].len    = len;
++         dlist[0].rwflag = DLREAD;
++
++         dlist[1].page   = NULL;
++         dlist[1].offset = &lreply;
++         dlist[1].len    = sizeof(lreply);
++         dlist[1].rwflag = DLWRITE;
++
++         retCode = Queue_Daemon_Command(&cmd, cmdlen, dlist, 2, (void *)&reply, &replylen, INTERRUPTIBLE);
++
++         Novfs_Free(kdata);
++      }
++   }
++
++   DbgPrint("Novfs_Write_File retCode=0x%x reply=0x%x\n", retCode, reply);
++
++   if ( !retCode )
++   {
++      switch (lreply.Reply.ErrorCode)
++      {
++         case 0:
++            *Bytes = (size_t)lreply.bytesWritten;
++            retCode = 0;
++            break;
++
++         case NWE_INSUFFICIENT_SPACE:
++            retCode = -ENOSPC;
++            break;
++
++         case NWE_ACCESS_DENIED:
++            retCode = -EACCES;
++            break;
++
++         default:
++            retCode = -EIO;
++            break;
++      }
++   }
++
++   if ( res )
++   {
++      for (i=0; i<res; i++)
++      {
++         if (dlist[i].page)
++         {
++            page_cache_release(dlist[i].page);
++         }
++      }
++   }
++
++   Novfs_Free(pages);
++   Novfs_Free(dlist);
++
++   DbgPrint("Novfs_Write_File *Bytes=0x%x retCode=0x%x\n", *Bytes, retCode);
++
++   return( retCode );
++}
++
++/*++======================================================================*/
++int Novfs_Write_Pages( u_long Handle, PDATA_LIST DList, int DList_Cnt, size_t Bytes, loff_t Offset, session_t SessionId)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   WRITE_FILE_REQUEST cmd;
++   WRITE_FILE_REPLY   lreply;
++   PWRITE_FILE_REPLY  reply=NULL;
++   u_long replylen=0;
++   int retCode=0, cmdlen;
++   size_t len;
++
++   DbgPrint("Novfs_Write_Pages: Handle=0x%x Dlst=0x%p Dlcnt=%d Bytes=%d Offset=%lld SessionId=0x%llx\n", 
++      Handle, DList, DList_Cnt, Bytes, Offset, SessionId);
++
++   DList[0].page   = NULL;
++   DList[0].offset = &lreply;
++   DList[0].len    = sizeof(lreply);
++   DList[0].rwflag = DLWRITE; 
++
++   len = Bytes;
++   cmdlen = (int)(&((PWRITE_FILE_REQUEST)0)->data);
++
++   if (len)
++   {
++      cmd.Command.CommandType    = VFS_COMMAND_WRITE_FILE;
++      cmd.Command.SequenceNumber = 0;
++      cmd.Command.SessionId      = SessionId;
++
++      cmd.handle = Handle;
++      cmd.len    = len;
++      cmd.offset = Offset;
++
++      retCode = Queue_Daemon_Command(&cmd, cmdlen, DList, DList_Cnt, (void *)&reply, &replylen, INTERRUPTIBLE);
++      if (!retCode)
++      {
++         if (reply)
++         {
++            memcpy(&lreply, reply, sizeof(lreply));
++         }
++         switch (lreply.Reply.ErrorCode)
++         {
++            case 0:
++               retCode = 0;
++               break;
++
++            case NWE_INSUFFICIENT_SPACE:
++               retCode = -ENOSPC;
++               break;
++
++            case NWE_ACCESS_DENIED:
++               retCode = -EACCES;
++               break;
++
++            default:
++               retCode = -EIO;
++               break;
++         }
++      }
++      if ( reply )
++      {
++         Novfs_Free(reply);
++      }
++   }
++   DbgPrint("Novfs_Write_Pages retCode=0x%x\n", retCode);
++
++   return( retCode );
++}
++
++/*++======================================================================*/
++int Novfs_Read_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, int User, session_t SessionId)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   READ_STREAM_REQUEST cmd;
++   PREAD_STREAM_REPLY  reply=NULL;
++   u_long replylen=0;
++   int retCode = 0;
++   size_t len;
++
++   len = *Bytes;
++   *Bytes = 0;
++
++   if ( ((int)(&((PREAD_FILE_REPLY)0)->data) + len) > MaxIoSize)
++   {
++      len = MaxIoSize - (int)(&((PREAD_FILE_REPLY)0)->data);
++      len = (len/PAGE_SIZE)*PAGE_SIZE;
++   }
++
++   cmd.Command.CommandType    = VFS_COMMAND_READ_STREAM;
++   cmd.Command.SequenceNumber = 0;
++   cmd.Command.SessionId      = SessionId;
++
++   cmd.connection = ConnHandle;
++   memcpy( cmd.handle, Handle, sizeof(cmd.handle));
++   cmd.len    = len;
++   cmd.offset = *Offset;
++
++   retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
++
++   DbgPrint("Novfs_Read_Stream: Queue_Daemon_Command 0x%x replylen=%d\n", retCode, replylen);
++
++   if ( reply )
++   {
++      retCode = 0;
++      if (reply->Reply.ErrorCode)
++      {
++         retCode = -EIO;
++      }
++      else
++      {
++         replylen -= (int)(&((PREAD_STREAM_REPLY)0)->data);
++         if (replylen > 0)
++         {
++            if (User)
++            {
++               replylen -= copy_to_user(Buffer, reply->data, replylen);
++            }
++            else
++            {
++               memcpy(Buffer, reply->data, replylen);
++            }
++
++            *Bytes = replylen;
++         }
++      }
++      Novfs_Free(reply);
++   }
++
++   DbgPrint("Novfs_Read_Stream *Bytes=0x%x retCode=0x%x\n", *Bytes, retCode);
++
++   return( retCode );
++}
++
++/*++======================================================================*/
++int Novfs_Write_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PWRITE_STREAM_REQUEST cmd;
++   PWRITE_STREAM_REPLY   reply=NULL;
++   u_long replylen=0;
++   int retCode=0, cmdlen;
++   size_t len;
++
++   len = *Bytes;
++   cmdlen = len+(int)(&((PWRITE_STREAM_REQUEST)0)->data);
++   *Bytes = 0;
++
++   if (cmdlen > MaxIoSize)
++   {
++      cmdlen = MaxIoSize;
++      len = cmdlen - (int)(&((PWRITE_STREAM_REQUEST)0)->data);
++   }
++
++   DbgPrint("Novfs_Write_Stream cmdlen=%d len=%d\n", cmdlen, len);
++
++   cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++
++   if (cmd)
++   {
++      if (Buffer && len)
++      {
++         len -= copy_from_user(cmd->data, Buffer, len);
++      }
++
++      DbgPrint("Novfs_Write_Stream len=%d\n", len);
++
++      cmd->Command.CommandType    = VFS_COMMAND_WRITE_STREAM;
++      cmd->Command.SequenceNumber = 0;
++      cmd->Command.SessionId      = SessionId;
++
++      cmd->connection = ConnHandle;
++      memcpy(cmd->handle, Handle, sizeof(cmd->handle));
++      cmd->len    = len;
++      cmd->offset = *Offset;
++
++      retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
++      if (reply)
++      {
++         switch (reply->Reply.ErrorCode)
++         {
++            case 0:
++               retCode = 0;
++               break;
++
++            case NWE_INSUFFICIENT_SPACE:
++               retCode = -ENOSPC;
++               break;
++
++            case NWE_ACCESS_DENIED:
++               retCode = -EACCES;
++               break;
++
++            default:
++               retCode = -EIO;
++               break;
++         }
++         DbgPrint("Novfs_Write_Stream reply->bytesWritten=0x%lx\n", reply->bytesWritten);
++         *Bytes = reply->bytesWritten;
++         Novfs_Free(reply);
++      }
++      Novfs_Free(cmd);
++   }
++   DbgPrint("Novfs_Write_Stream *Bytes=0x%x retCode=0x%x\n", *Bytes, retCode);
++
++   return( retCode );
++}
++
++/*++======================================================================*/
++int Novfs_Close_Stream( u_long ConnHandle, u_char *Handle, session_t SessionId )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   CLOSE_STREAM_REQUEST cmd;
++   PCLOSE_STREAM_REPLY  reply;
++   u_long replylen=0;
++   int retCode;
++
++   cmd.Command.CommandType    = VFS_COMMAND_CLOSE_STREAM;
++   cmd.Command.SequenceNumber = 0;
++   cmd.Command.SessionId      = SessionId;
++
++   cmd.connection = ConnHandle;
++   memcpy(cmd.handle, Handle, sizeof(cmd.handle));
++
++   retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, 0);
++   if (reply)
++   {
++      retCode = 0;
++      if (reply->Reply.ErrorCode)
++      {
++         retCode = -EIO;
++      }
++      Novfs_Free(reply);
++   }
++   return( retCode );
++}
++
++/*++======================================================================*/
++int Novfs_Delete( u_char *Path, int DirectoryFlag, session_t SessionId )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PDELETE_FILE_REQUEST cmd;
++   PDELETE_FILE_REPLY   reply;
++   u_long replylen=0;
++   int retCode, cmdlen, pathlen;
++
++   pathlen = strlen(Path);
++   
++   if (StripTrailingDots)
++   {
++      if ('.' == Path[pathlen-1]) pathlen--;
++   }
++
++   cmdlen = (int)(&((PDELETE_FILE_REQUEST)0)->path) + pathlen;
++   cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++   if (cmd)
++   {
++      cmd->Command.CommandType    = VFS_COMMAND_DELETE_FILE;
++      cmd->Command.SequenceNumber = 0;
++      cmd->Command.SessionId      = SessionId;
++
++      cmd->isDirectory = DirectoryFlag;
++      cmd->pathlength = pathlen;
++      memcpy(cmd->path, Path, pathlen);
++
++      retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
++      if (reply)
++      {
++         retCode = 0;
++         if (reply->Reply.ErrorCode)
++         {
++            if ((reply->Reply.ErrorCode & 0xFFFF) == 0x0006) /* Access Denied Error */
++            {
++               retCode = -EACCES;
++            }
++            else
++            {
++               retCode = -EIO;
++            }
++         }
++         Novfs_Free(reply);
++      }
++      Novfs_Free(cmd);
++   }
++   else
++   {
++      retCode = -ENOMEM;
++   }
++   return( retCode );
++}
++
++/*++======================================================================*/
++int Novfs_Truncate_File( u_char *Path, int PathLen, session_t SessionId )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PTRUNCATE_FILE_REQUEST cmd;
++   PTRUNCATE_FILE_REPLY   reply;
++   u_long replylen=0;
++   int retCode, cmdlen;
++
++   if (StripTrailingDots)
++   {
++      if ('.' == Path[PathLen-1]) PathLen--;
++   }
++   cmdlen = (int)(&((PTRUNCATE_FILE_REQUEST)0)->path) + PathLen;
++   cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++   if (cmd)
++   {
++      cmd->Command.CommandType    = VFS_COMMAND_TRUNCATE_FILE;
++      cmd->Command.SequenceNumber = 0;
++      cmd->Command.SessionId      = SessionId;
++
++      cmd->pathLen = PathLen;
++      memcpy(cmd->path, Path, PathLen);
++
++      retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
++      if (reply)
++      {
++         if (reply->Reply.ErrorCode)
++         {
++            retCode = -EIO;
++         }
++         Novfs_Free(reply);
++      }
++      Novfs_Free(cmd);
++   }
++   else
++   {
++      retCode = -ENOMEM;
++   }
++   return( retCode );
++}
++
++/*++======================================================================*/
++int Novfs_Rename_File( int DirectoryFlag, u_char *OldName, int OldLen, u_char *NewName, int NewLen, session_t SessionId )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   RENAME_FILE_REQUEST cmd;
++   PRENAME_FILE_REPLY  reply;
++   u_long replylen=0;
++   int retCode;
++
++   DbgPrint("Novfs_Rename_File:\n" \
++            "   DirectoryFlag: %d\n" \
++            "   OldName:       %.*s\n" \
++            "   NewName:       %.*s\n" \
++            "   SessionId:     0x%llx\n",
++      DirectoryFlag, 
++      OldLen, OldName,
++      NewLen, NewName, 
++      SessionId );
++
++   cmd.Command.CommandType    = VFS_COMMAND_RENAME_FILE;
++   cmd.Command.SequenceNumber = 0;
++   cmd.Command.SessionId      = SessionId;
++
++   cmd.directoryFlag = DirectoryFlag;
++
++   if (StripTrailingDots)
++   {
++      if ('.' == OldName[OldLen-1]) OldLen--;
++      if ('.' == NewName[NewLen-1]) NewLen--;
++   }
++
++   cmd.newnameLen = NewLen;
++   memcpy(cmd.newname, NewName, NewLen);
++
++   cmd.oldnameLen = OldLen;
++   memcpy(cmd.oldname, OldName, OldLen);
++
++   retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
++   if (reply)
++   {
++      retCode = 0;
++      if (reply->Reply.ErrorCode)
++      {
++         retCode = -ENOENT;
++      }
++      Novfs_Free(reply);
++   }
++   return( retCode );
++}
++
++/*++======================================================================*/
++int Novfs_Set_Attr( u_char *Path, struct iattr *Attr, session_t SessionId )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PSET_FILE_INFO_REQUEST cmd;
++   PSET_FILE_INFO_REPLY   reply;
++   u_long replylen=0;
++   int retCode, cmdlen, pathlen;
++
++   pathlen = strlen(Path);
++
++   if (StripTrailingDots)
++   {
++      if ('.' == Path[pathlen-1]) pathlen--;
++   }
++
++   cmdlen = (int)(&((PSET_FILE_INFO_REQUEST)0)->path) + pathlen;
++   cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++   if (cmd)
++   {
++      cmd->Command.CommandType    = VFS_COMMAND_SET_FILE_INFO;
++      cmd->Command.SequenceNumber = 0;
++      cmd->Command.SessionId      = SessionId;
++      cmd->fileInfo.ia_valid      = Attr->ia_valid;
++      cmd->fileInfo.ia_mode       = Attr->ia_mode;
++      cmd->fileInfo.ia_uid        = Attr->ia_uid;
++      cmd->fileInfo.ia_gid        = Attr->ia_uid;
++      cmd->fileInfo.ia_size       = Attr->ia_size;
++      cmd->fileInfo.ia_atime      = Attr->ia_atime.tv_sec;
++      cmd->fileInfo.ia_mtime      = Attr->ia_mtime.tv_sec;;
++      cmd->fileInfo.ia_ctime      = Attr->ia_ctime.tv_sec;;
++/*
++      cmd->fileInfo.ia_attr_flags = Attr->ia_attr_flags;
++*/
++      cmd->fileInfo.ia_attr_flags = 0;
++
++      cmd->pathlength = pathlen;
++      memcpy(cmd->path, Path, pathlen);
++
++      retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
++      if (reply)
++      {
++         switch( reply->Reply.ErrorCode )
++         {
++            case 0:
++               retCode = 0;
++               break;
++
++            case NWE_PARAM_INVALID:
++               retCode = -EINVAL;
++               break;
++
++            default:
++               retCode = -EIO;
++               break;
++         }
++         Novfs_Free(reply);
++      }
++      Novfs_Free(cmd);
++   }
++   else
++   {
++      retCode = -ENOMEM;
++   }
++   return( retCode );
++}
++
++/*++======================================================================*/
++int Novfs_Get_File_Cache_Flag( u_char *Path, session_t SessionId )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PGET_CACHE_FLAG_REQUEST cmd;
++   PGET_CACHE_FLAG_REPLY   reply=NULL;
++   u_long replylen=0;
++   int cmdlen;
++   int retCode = 0;
++   int pathlen;
++
++   DbgPrint("Novfs_Get_File_Cache_Flag: Path = %s\n", Path);
++
++   if (Path && *Path)
++   {
++      pathlen = strlen(Path);
++      if (StripTrailingDots)
++      {
++         if ('.' == Path[pathlen-1]) pathlen--;
++      }
++      cmdlen = (int)(&((PGET_CACHE_FLAG_REQUEST)0)->path) + pathlen;
++      cmd = (PGET_CACHE_FLAG_REQUEST)Novfs_Malloc(cmdlen, GFP_KERNEL);
++      if (cmd)
++      {
++         cmd->Command.CommandType = VFS_COMMAND_GET_CACHE_FLAG;
++         cmd->Command.SequenceNumber = 0;
++         cmd->Command.SessionId = SessionId;
++         cmd->pathLen = pathlen;
++         memcpy(cmd->path, Path, cmd->pathLen);
++
++         Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
++
++         if (reply)
++         {
++            
++            if ( !reply->Reply.ErrorCode )
++            {
++               retCode = reply->CacheFlag;
++            }
++
++            Novfs_Free(reply);
++         }
++         Novfs_Free(cmd);
++      }
++   }
++
++   DbgPrint("Novfs_Get_File_Cache_Flag: return %d\n", retCode);
++   return(retCode);
++}
+diff -uNr src.old/src/inode.c src/src/inode.c
+--- src.old/src/inode.c	1970-01-01 01:00:00.000000000 +0100
++++ src/src/inode.c	2006-10-16 15:08:22.000000000 +0200
+@@ -0,0 +1,5236 @@
++/*++========================================================================
++ * Program Name:     Novell NCP Redirector for Linux
++ * File Name:        inode.c
++ * Version:          v1.00
++ * Author:           James Turner
++ *
++ * Abstract:         This module contains functions used to control
++ *                   access to the Linux file system.
++ * Notes:
++ * Revision History: 
++ *
++ *
++ * Copyright (C) 2005 Novell, Inc.
++ *
++ * 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 files specific to Linux ]==================================*/
++#include <linux/module.h>
++#include <linux/config.h>
++#include <linux/init.h>
++#include <linux/fs.h>
++#include <linux/dcache.h>
++#include <linux/mount.h>
++#include <linux/pagemap.h>
++#include <linux/string.h>
++#include <linux/smp_lock.h>
++#include <linux/slab.h>
++#include <linux/unistd.h>
++#include <linux/backing-dev.h>
++#include <asm/statfs.h>
++#include <asm/uaccess.h>
++#include <linux/ctype.h>
++#include <linux/statfs.h>
++#include <linux/pagevec.h>
++#include <linux/writeback.h>
++#include <linux/backing-dev.h>
++
++/*===[ Include files specific to this module ]============================*/
++#include "vfs.h"
++
++/*===[ External data ]====================================================*/
++extern int MaxIoSize;
++
++/*===[ External prototypes ]==============================================*/
++extern int DbgPrint( char *Fmt, ... );
++extern int LocalPrint( char *Fmt, ... );
++
++extern int Init_Procfs_Interface( void );
++extern void Uninit_Procfs_Interface( void );
++extern void mydump(int size, void *dumpptr);
++
++/*
++ * Daemon.c functions
++ */
++extern void Init_Daemon_Queue( void );
++extern void Uninit_Daemon_Queue( void );
++extern int do_logout( struct qstr *Server );
++extern int Daemon_SetMountPoint( char *Path );
++
++/*
++ * file.c functions
++ */
++extern int Novfs_verify_file( struct qstr *Path, session_t SessionId );
++extern int Novfs_get_alltrees(struct dentry *parent);
++extern int Novfs_Get_Connected_Server_List( unsigned char **ServerList, session_t SessionId );
++extern int Novfs_Get_Server_Volume_List( struct qstr *Server, unsigned char **VolumeList, session_t SessionId );
++extern int Novfs_Verify_Server_Name( struct qstr *Server, session_t SessionId );
++extern int Novfs_Verify_Volume_Name( struct qstr *Server,  struct qstr *Volume, session_t SessionId );
++extern int Novfs_Get_File_Info( unsigned char *Path, PENTRY_INFO Info, session_t SessionId  );
++extern int Novfs_Get_Directory_List( unsigned char *Path, unsigned long *EnumHandle, PENTRY_INFO Info, session_t SessionId );
++extern int Novfs_Get_Directory_ListEx( unsigned char *Path, unsigned long *EnumHandle, int *Count, PENTRY_INFO *Info, session_t SessionId );
++extern int Novfs_Open_File( unsigned char *Path, int Flags, PENTRY_INFO Info, unsigned long *Handle, session_t SessionId );
++extern int Novfs_Create( unsigned char *Path, int DirectoryFlag, session_t SessionId );
++extern int Novfs_Close_File( unsigned long Handle, session_t SessionId );
++extern int Novfs_Read_File( unsigned long Handle, unsigned char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId);
++extern int Novfs_Read_Pages( u_long Handle, PDATA_LIST DList, int DList_Cnt, size_t *Bytes, loff_t *Offset, session_t SessionId);
++extern int Novfs_Write_File( unsigned long Handle, unsigned char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId);
++extern int Novfs_Write_Pages( unsigned long Handle, PDATA_LIST DList, int DList_Cnt, size_t Bytes, loff_t Offset, session_t SessionId);
++extern int Novfs_Delete( unsigned char *Path, int DirectoryFlag, session_t SessionId );
++extern int Novfs_Truncate_File( unsigned char *Path, int PathLen, session_t SessionId );
++extern int Novfs_Rename_File( int DirectoryFlag, unsigned char *OldName, int OldLen, unsigned char *NewName, int NewLen, session_t SessionId );
++extern int Novfs_Set_Attr( unsigned char *Path, struct iattr *Attr, session_t SessionId );
++extern int Novfs_Get_File_Cache_Flag( u_char *Path, session_t SessionId );
++
++/*
++ * scope.c functions
++ */
++extern void Scope_Init( void );
++extern void Scope_Uninit( void );
++extern void *Scope_Lookup( void );
++extern unsigned long Scope_Get_Hash( void *);
++extern uid_t Scope_Get_Uid( void *);
++extern session_t Scope_Get_SessionId( void *Scope );
++extern void *Scope_Get_ScopefromName( struct qstr *Name );
++extern void *Scope_Get_ScopefromPath( struct dentry *Dentry );
++extern char *Scope_Get_ScopeUsers( void );
++extern int Scope_Set_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties );
++extern int Scope_Get_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties );
++extern char *Scope_dget_path( struct dentry *Dentry, char *Buf, unsigned int Buflen, int Flags);
++
++/*
++ * profile.c functions
++ */
++extern int init_profile( void );
++extern void uninit_profile( void );
++
++/*===[ Manifest constants ]===============================================*/
++#define FILE_UPDATE_TIMEOUT   2
++
++/*===[ Type definitions ]=================================================*/
++
++/*===[ Function prototypes ]==============================================*/
++int Novfs_Remove_from_Root(char *RemoveName);
++int Novfs_Add_to_Root(char *);
++char  *Novfs_dget_path( struct dentry *d, char *path, unsigned int pathlen );
++int verify_dentry(struct dentry *dentry, int Flags);
++int invalidate_dentry(struct dentry *parent);
++struct dentry *Novfs_d_lookup(struct dentry *Parent, struct qstr *Name);
++int Novfs_d_add(struct dentry *p, struct dentry *d, struct inode *i, int add);
++int Novfs_d_strcmp (struct qstr *s1, struct qstr *s2);
++struct inode *Novfs_get_inode(struct super_block *sb, int mode, int dev, uid_t uid, ino_t ino, struct qstr *name);
++unsigned long Novfs_internal_hash (struct qstr *name);
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
++    int Novfs_get_sb(struct file_system_type *Fstype, int Flags, const char *Dev_name, void *Data, struct vfsmount *Mnt);
++#else
++    struct super_block * Novfs_get_sb(struct file_system_type *Fstype, int Flags, const char *Dev_name, void *Data);
++#endif
++
++void Novfs_kill_sb(struct super_block *SB);
++int Novfs_fill_super (struct super_block *SB, void *Data, int Silent);
++
++/*
++ * Declared dentry_operations
++ */
++int Novfs_d_revalidate(struct dentry *, struct nameidata *);
++int Novfs_d_hash (struct dentry *, struct qstr *);
++int Novfs_d_compare (struct dentry *, struct qstr *, struct qstr *);
++int Novfs_d_delete(struct dentry *dentry);
++void Novfs_d_release(struct dentry *dentry);
++void Novfs_d_iput(struct dentry *dentry, struct inode *inode);
++
++/*
++ * Declared directory operations
++ */
++int Novfs_dir_open(struct inode *inode, struct file *file);
++int Novfs_dir_release(struct inode *inode, struct file *file);
++loff_t  Novfs_dir_lseek(struct file *file, loff_t offset, int origin);
++int Novfs_dir_read(struct file *file, char *buf, size_t len, loff_t *off);
++void addtodentry( struct dentry *Parent, unsigned char *List, int Level );
++int Novfs_filldir(void *data, const char *name, int namelen, loff_t off, ino_t ino, unsigned ftype);
++int Novfs_dir_readdir(struct file * filp, void * dirent, filldir_t filldir);
++int Novfs_dir_fsync(struct file * file, struct dentry *dentry, int datasync);
++
++/*
++ * Declared address space operations
++ */
++int Novfs_a_writepage(struct page* page, struct writeback_control *wbc);
++int Novfs_a_writepages(struct address_space *mapping, struct writeback_control *wbc);
++int Novfs_a_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to);
++int Novfs_a_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to);
++int Novfs_a_readpage(struct file *file, struct page *page);
++int Novfs_a_readpages(struct file *file, struct address_space *mapping, struct list_head *page_lst, unsigned nr_pages);
++ssize_t Novfs_a_direct_IO(int rw, struct kiocb *kiocb, 
++                          const struct iovec *iov,
++                          loff_t offset, 
++                          unsigned long nr_segs);
++
++/*
++ * Declared file_operations
++ */
++ssize_t Novfs_f_read(struct file *, char *, size_t, loff_t *);
++ssize_t Novfs_f_write(struct file *, const char *, size_t, loff_t *);
++int Novfs_f_readdir(struct file *, void *, filldir_t);
++int Novfs_f_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
++int Novfs_f_mmap(struct file * file, struct vm_area_struct * vma);
++int Novfs_f_open(struct inode *, struct file *);
++int Novfs_f_flush(struct file *);
++int Novfs_f_release(struct inode *, struct file *);
++int Novfs_f_fsync(struct file *, struct dentry *, int datasync);
++int Novfs_f_lock(struct file *, int, struct file_lock *);
++
++/*
++ * Declared inode_operations
++ */
++int Novfs_i_create(struct inode *,struct dentry *,int, struct nameidata *);
++struct dentry * Novfs_i_lookup(struct inode *,struct dentry *, struct nameidata *);
++int Novfs_i_mkdir(struct inode *,struct dentry *,int);
++int Novfs_i_unlink(struct inode *dir, struct dentry *dentry);
++int Novfs_i_rmdir(struct inode *,struct dentry *);
++int Novfs_i_mknod(struct inode *,struct dentry *,int,dev_t);
++int Novfs_i_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
++int Novfs_i_permission(struct inode *inode, int mask);
++int Novfs_i_setattr(struct dentry *, struct iattr *);
++int Novfs_i_getattr(struct vfsmount *mnt, struct dentry *, struct kstat *);
++int Novfs_i_revalidate(struct dentry *dentry);
++
++void update_inode(struct inode *Inode, PENTRY_INFO Info);
++
++/*
++ * Declared super_operations
++ */
++void Novfs_read_inode(struct inode *inode);
++void Novfs_write_inode(struct inode *inode);
++int Novfs_notify_change(struct dentry *dentry, struct iattr *attr);
++void Novfs_clear_inode(struct inode *inode);
++int Novfs_show_options( struct seq_file *s, struct vfsmount *m );
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
++    int Novfs_statfs(struct dentry *de, struct kstatfs *buf);
++#else
++    int Novfs_statfs(struct super_block *sb, struct kstatfs *buf);
++#endif
++
++/*
++ * Declared control interface functions
++ */
++ssize_t
++Novfs_Control_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos);
++
++ssize_t
++Novfs_Control_write(struct file * file, const char * buf, size_t nbytes, loff_t *ppos);
++
++int Novfs_Control_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
++
++int __init init_novfs(void);
++void __exit exit_novfs(void);
++
++int Novfs_lock_inode_cache( struct inode *i );
++void Novfs_unlock_inode_cache( struct inode *i );
++int Novfs_enumerate_inode_cache( struct inode *i, struct list_head **iteration, ino_t *ino, PENTRY_INFO info);
++int Novfs_get_entry( struct inode *i, struct qstr *name, ino_t *ino, PENTRY_INFO info);
++int Novfs_get_entry_by_pos( struct inode *i, loff_t pos, ino_t *ino, PENTRY_INFO info);
++int Novfs_get_entry_time( struct inode *i, struct qstr *name, ino_t *ino, PENTRY_INFO info, u64 *EntryTime);
++int Novfs_get_remove_entry( struct inode *i, ino_t *ino, PENTRY_INFO info);
++void Novfs_invalidate_inode_cache( struct inode *i );
++PDIR_CACHE Novfs_lookup_inode_cache( struct inode *i, struct qstr *name, ino_t ino );
++int Novfs_lookup_validate( struct inode *i, struct qstr *name, ino_t ino );
++int Novfs_add_inode_entry( struct inode *i, struct qstr *name, ino_t ino, PENTRY_INFO info);
++int Novfs_update_entry( struct inode *i, struct qstr *name, ino_t ino, PENTRY_INFO info);
++void Novfs_remove_inode_entry( struct inode *i, struct qstr *name, ino_t ino);
++void Novfs_free_invalid_entries( struct inode *i );
++void Novfs_free_inode_cache( struct inode *i );
++
++/*===[ Global variables ]=================================================*/
++struct dentry_operations Novfs_dentry_operations = {
++   .d_revalidate  = Novfs_d_revalidate,
++   .d_hash        = Novfs_d_hash,
++   .d_compare     = Novfs_d_compare,
++   .d_delete      = Novfs_d_delete,
++   .d_release     = Novfs_d_release,
++   .d_iput        = Novfs_d_iput,
++};
++
++struct file_operations Novfs_dir_operations = {
++	.owner	= THIS_MODULE,
++   .open    = Novfs_dir_open,
++   .release = Novfs_dir_release,
++   .llseek  = Novfs_dir_lseek,
++   .read    = Novfs_dir_read,
++   .readdir = Novfs_dir_readdir,
++   .fsync   = Novfs_dir_fsync,
++};
++
++static struct file_operations Novfs_file_operations = {
++	.owner	= THIS_MODULE,
++   .read    = Novfs_f_read,
++   .write   = Novfs_f_write,
++   .readdir = Novfs_f_readdir,
++   .ioctl   = Novfs_f_ioctl,
++   .mmap    = Novfs_f_mmap,
++   .open    = Novfs_f_open,
++   .flush   = Novfs_f_flush,
++   .release = Novfs_f_release,
++   .fsync   = Novfs_f_fsync,
++	.llseek  = generic_file_llseek,
++};
++
++static struct address_space_operations Novfs_aops = {
++   .readpage       = Novfs_a_readpage,
++   .readpages      = Novfs_a_readpages,
++   .writepage      = Novfs_a_writepage,
++   .writepages     = Novfs_a_writepages,
++   .prepare_write  = Novfs_a_prepare_write,
++   .commit_write   = Novfs_a_commit_write,
++	.set_page_dirty = __set_page_dirty_nobuffers,
++   .direct_IO      = Novfs_a_direct_IO,
++};
++
++static struct inode_operations Novfs_inode_operations = {
++   .create     = Novfs_i_create,
++   .lookup     = Novfs_i_lookup,
++   .unlink     = Novfs_i_unlink,
++   .mkdir      = Novfs_i_mkdir,
++   .rmdir      = Novfs_i_rmdir,
++   .mknod      = Novfs_i_mknod,
++   .rename     = Novfs_i_rename,
++   .setattr    = Novfs_i_setattr,
++   .getattr    = Novfs_i_getattr,
++};
++
++static struct inode_operations Novfs_file_inode_operations = {
++   .setattr    = Novfs_i_setattr,
++   .getattr    = Novfs_i_getattr,
++};
++
++static struct super_operations Novfs_ops = {
++   .read_inode    = Novfs_read_inode,
++   .statfs        = Novfs_statfs,
++   .clear_inode   = Novfs_clear_inode,
++	.drop_inode	   = generic_delete_inode,
++   .show_options  = Novfs_show_options,
++
++};
++
++/* Not currently used
++static struct file_operations Novfs_Control_operations = {
++   .read    = Novfs_Control_read,
++   .write   = Novfs_Control_write,
++   .ioctl   = Novfs_Control_ioctl,
++};
++*/
++
++ino_t Novfs_Inode_Number=1;
++
++static struct file_system_type Novfs_fs_type = {
++   .name    = "novfs", 
++   .get_sb  = Novfs_get_sb,
++   .kill_sb = Novfs_kill_sb,
++	.owner	= THIS_MODULE,
++};
++
++struct dentry *Novfs_root=NULL;
++
++int Novfs_Version_Major=NOVFS_VFS_MAJOR;
++int Novfs_Version_Minor=NOVFS_VFS_MINOR;
++int Novfs_Version_Sub=NOVFS_VFS_SUB;
++int Novfs_Version_Release=NOVFS_VFS_RELEASE;
++
++char *Novfs_CurrentMount=NULL;
++
++DECLARE_MUTEX(InodeList_lock);
++
++LIST_HEAD(InodeList);
++
++unsigned long InodeCount=0, DCCount=0;
++unsigned long File_update_timeout=FILE_UPDATE_TIMEOUT;
++int PageCache=1;
++
++/*===[ Code ]=============================================================*/
++static __inline__ void PRINT_DENTRY(const char *s, struct dentry *d)
++{
++   DbgPrint("%s: 0x%x\n",    s, d);
++   DbgPrint("   d_count:      0x%x\n", d->d_count);
++   DbgPrint("   d_lock:       0x%x\n", d->d_lock);
++   DbgPrint("   d_inode:      0x%x\n", d->d_inode);
++   DbgPrint("   d_lru:        0x%x\n" \
++            "      next:      0x%x\n" \
++            "      prev:      0x%x\n", &d->d_lru, d->d_lru.next, d->d_lru.prev);
++   DbgPrint("   d_child:      0x%x\n" \
++            "      next:      0x%x\n" \
++            "      prev:      0x%x\n", &d->D_CHILD, d->D_CHILD.next, d->D_CHILD.prev);
++   DbgPrint("   d_subdirs:    0x%x\n" \
++            "      next:      0x%x\n" \
++            "      prev:      0x%x\n", &d->d_subdirs, d->d_subdirs.next, d->d_subdirs.prev);
++   DbgPrint("   d_alias:      0x%x\n" \
++            "      next:      0x%x\n" \
++            "      prev:      0x%x\n", &d->d_alias, d->d_alias.next, d->d_alias.prev);
++   DbgPrint("   d_time:       0x%x\n", d->d_time);
++   DbgPrint("   d_op:         0x%x\n", d->d_op);
++   DbgPrint("   d_sb:         0x%x\n", d->d_sb);
++   DbgPrint("   d_flags:      0x%x\n", d->d_flags);
++   DbgPrint("   d_mounted:    0x%x\n", d->d_mounted);
++   DbgPrint("   d_fsdata:     0x%x\n", d->d_fsdata);
++/*   DbgPrint("   d_cookie:     0x%x\n", d->d_cookie); */
++   DbgPrint("   d_parent:     0x%x\n", d->d_parent);
++   DbgPrint("   d_name:       0x%x %.*s\n", &d->d_name, d->d_name.len, d->d_name.name);
++   DbgPrint("      name:      0x%x\n" \
++            "      len:       %d\n"   \
++            "      hash:      0x%x\n", d->d_name.name, d->d_name.len, d->d_name.hash);
++   DbgPrint("   d_hash:       0x%x\n" \
++            "      next:      0x%x\n" \
++            "      pprev:     0x%x\n", d->d_hash, d->d_hash.next, d->d_hash.pprev);
++}
++
++/*++======================================================================*/
++int Novfs_Remove_from_Root(char *RemoveName)
++/*
++ *  Arguments:
++ * 
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   struct qstr name;
++   struct dentry *dentry;
++   struct inode *dir;
++
++   DbgPrint( "Novfs_Remove_from_Root: %s\n", RemoveName);
++   name.len  = strlen(RemoveName);
++   name.name = RemoveName;
++   Novfs_d_hash(Novfs_root, &name);
++
++   dentry = d_lookup( Novfs_root, &name);
++   if (dentry)
++   {
++      if (dentry->d_inode && dentry->d_inode->u.generic_ip)
++      {
++         ((PINODE_DATA)(dentry->d_inode->u.generic_ip))->Scope = NULL;
++      }
++      dput(dentry);
++   }
++
++   
++   dir = Novfs_root->d_inode;
++
++   Novfs_lock_inode_cache( dir );
++   Novfs_remove_inode_entry( dir, &name, 0);
++   Novfs_unlock_inode_cache( dir );
++
++   return(0);
++}
++
++/*++======================================================================*/
++int Novfs_Add_to_Root(char *AddName)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   struct qstr name;
++   struct inode *dir;
++   ENTRY_INFO info;
++   ino_t ino;
++
++   DbgPrint( "Novfs_Add_to_Root: %s\n", AddName);
++   name.len  = strlen(AddName);
++   name.name = AddName;
++   Novfs_d_hash(Novfs_root, &name);
++
++   dir = Novfs_root->d_inode;
++
++   Novfs_lock_inode_cache( dir );
++
++   ino = 0;
++
++   if ( !Novfs_lookup_inode_cache(dir, &name, 0))
++   {
++      info.mode = S_IFDIR | 0700;
++      info.size = 0;
++      info.atime = info.ctime = info.mtime = CURRENT_TIME;
++
++      ino = (ino_t)InterlockedIncrement(&Novfs_Inode_Number);
++      Novfs_add_inode_entry( dir, &name, ino, &info);
++   }
++
++   Novfs_unlock_inode_cache( dir );
++
++   return(0);
++}
++
++/*++======================================================================*/
++int Novfs_Add_to_Root2(char *AddName)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   struct dentry *entry;
++   struct qstr name;
++   struct inode *inode;
++   void *scope;
++
++   DbgPrint( "Novfs_Add_to_Root: %s\n", AddName);
++   name.len  = strlen(AddName);
++   name.name = AddName;
++
++   Novfs_d_hash(Novfs_root, &name);
++
++   entry = Novfs_d_lookup(Novfs_root, &name);
++   DbgPrint( "Novfs_Add_to_Root: Novfs_d_lookup 0x%x\n", entry);
++   if ( NULL == entry )
++   {
++      scope = Scope_Lookup();
++
++      entry = d_alloc(Novfs_root, &name);
++      DbgPrint( "Novfs_Add_to_Root: d_alloc 0x%x\n", entry );
++      if (entry)
++      {
++         entry->d_op = &Novfs_dentry_operations;
++         entry->d_time = jiffies+(File_update_timeout*HZ);
++         /*
++          * done in Novfs_d_add now... entry->d_fsdata = (void *)Novfs_internal_hash( &name );
++          */
++         inode = Novfs_get_inode(Novfs_root->d_sb, S_IFDIR | 0700, 0, Scope_Get_Uid(scope), 0, &name);
++         DbgPrint( "Novfs_Add_to_Root: Inode=0x%x\n", inode);
++         if (inode)
++         {
++            inode->i_atime = 
++            inode->i_ctime = 
++            inode->i_mtime = CURRENT_TIME;
++            if ( !Novfs_d_add(Novfs_root, entry, inode, 1))
++            {
++               if (inode->u.generic_ip)
++               {
++                  ((PINODE_DATA)inode->u.generic_ip)->Flags = USER_INODE;
++               }
++               PRINT_DENTRY("After Novfs_d_add", entry);
++            }
++            else
++            {
++               dput(entry);
++               iput(inode);
++            }
++         }
++      }
++   }
++   else
++   {
++      dput(entry);
++      PRINT_DENTRY("Novfs_Add_to_Root: After dput Dentry", entry);
++   }
++   return(0);
++}
++
++/*++======================================================================*/
++char  *Novfs_dget_path( struct dentry *Dentry, char *Buf, unsigned int Buflen)
++/*
++ *  Arguments:   struct dentry *Dentry - starting entry
++ *               char *Buf - pointer to memory buffer
++ *               unsigned int Buflen - size of memory buffer
++ * 
++ *  Returns:     pointer to path.
++ * 
++ *  Abstract:    Walks the dentry chain building a path.
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   char *retval=&Buf[Buflen];
++   struct dentry *p=Dentry;
++
++   *(--retval) = '\0';
++   Buflen--;
++
++   if (!IS_ROOT(p) && !IS_ROOT(p->d_parent))
++   {
++      while (Buflen && !IS_ROOT(p) && !IS_ROOT(p->d_parent))
++      {
++         if (Buflen > p->d_name.len)
++         {
++            retval -= p->d_name.len;
++            Buflen -= p->d_name.len;
++            memcpy(retval, p->d_name.name, p->d_name.len);
++            *(--retval) = '\\';
++            Buflen--;
++            p = p->d_parent;
++         }
++         else
++         {
++            retval = NULL;
++            break;
++         }
++      }
++   }
++   else
++   {
++      *(--retval) = '\\';
++   }
++
++
++
++if (retval) DbgPrint("Novfs_dget_path: %s\n", retval);
++   return(retval);
++}
++
++/*++======================================================================*/
++int verify_dentry( struct dentry *dentry, int Flags )
++/*
++ *  Arguments:   struct dentry *dentry - entry to verify
++ *
++ *  Returns:     zero - Inode cache has been updated.  If not in the cache
++ *                      then file doesn't exist.
++ *               !zero - Error
++ *
++ *  Abstract:    This routine will verify if the file that dentry is pointing
++ *               at exist and if it does it will put it in the inode cache of
++ *               the parent.
++ *
++ *  Notes:
++ *
++ *  Environment: 
++ *
++ *========================================================================*/
++{
++   int retVal = -ENOENT;
++   struct inode *dir;
++   PENTRY_INFO info=NULL;
++   PINODE_DATA id;
++   session_t session;
++   char *path, *list=NULL, *cp;
++   ino_t ino;
++   struct qstr name;
++   int iLock=0;
++   struct dentry *parent=NULL;
++   u64 ctime;
++   struct inode *inode;
++
++   if ( IS_ROOT(dentry) )
++   {
++      DbgPrint("verify_dentry: Root entry\n");
++      return( 0 );
++   }
++
++   if ( dentry && dentry->d_parent && 
++        (dir = dentry->d_parent->d_inode) && 
++        (id = dir->u.generic_ip) )
++   {
++      parent = dget_parent(dentry);
++
++      info = Novfs_Malloc(sizeof(ENTRY_INFO)+PATH_LENGTH_BUFFER, GFP_KERNEL);
++
++      if (info)
++      {
++         if (Novfs_lock_inode_cache( dir ))
++         {
++            name.len = dentry->d_name.len;
++            name.name = dentry->d_name.name;
++            name.hash = Novfs_internal_hash( &name );
++            if ( !Novfs_get_entry_time(dir, &name, &ino, info, &ctime))
++            {
++               inode = dentry->d_inode;
++               if ( inode && 
++                    ( (inode->i_size != info->size) ||
++                      (inode->i_mtime.tv_sec != info->mtime.tv_sec) ||
++                      (inode->i_mtime.tv_nsec != info->mtime.tv_nsec) ))
++               {
++                  /*
++                   * Values don't match so update.
++                   */
++                  ((PINODE_DATA)inode->u.generic_ip)->Flags |= UPDATE_INODE;
++               }
++
++               ctime = get_jiffies_64() - ctime;
++               if ( Flags || ctime < (u64)(File_update_timeout*HZ) )
++               {
++                  retVal = 0;
++                  Novfs_unlock_inode_cache(dir);
++                  dput(parent);
++                  Novfs_Free(info);
++                  return(0);
++               }
++            }
++            Novfs_unlock_inode_cache(dir);
++         }
++
++         if ( IS_ROOT(dentry->d_parent) )
++         {
++            session = Scope_Get_SessionId(Scope_Get_ScopefromName(&dentry->d_name));
++         }
++         else
++         {
++            session = Scope_Get_SessionId( id->Scope );
++         }
++
++         if ( !session )
++         {
++            id->Scope = Scope_Get_ScopefromPath(dentry);
++            session = Scope_Get_SessionId( id->Scope );
++         }
++
++         ino = 0;
++         retVal = 0;
++
++         if ( IS_ROOT(dentry->d_parent) )
++         {
++            DbgPrint("verify_dentry: parent is Root directory\n");
++            list = Scope_Get_ScopeUsers();
++
++            iLock = Novfs_lock_inode_cache( dir );
++            Novfs_invalidate_inode_cache( dir );
++
++            if ( list )
++            {
++               cp = list;
++               while (*cp)
++               {
++                  name.name = cp;
++                  name.len  = strlen(cp);
++                  name.hash = Novfs_internal_hash( &name );
++                  cp += (name.len+1);
++                  ino = 0;
++                  if ( Novfs_get_entry( dir, &name, &ino, info ) )
++                  {
++                     info->mode = S_IFDIR | 0700;
++                     info->size = 0;
++                     info->atime = info->ctime = info->mtime = CURRENT_TIME;
++                     ino = (ino_t)InterlockedIncrement(&Novfs_Inode_Number);
++                     Novfs_add_inode_entry(dir, &name, ino, info);
++                  }
++               }
++            }
++            Novfs_free_invalid_entries( dir );
++         }
++         else
++         {
++            
++            path = Novfs_dget_path(dentry, info->name, PATH_LENGTH_BUFFER);
++            if (path)
++            {
++               if (dentry->d_name.len <= NW_MAX_PATH_LENGTH)
++               {
++                  name.hash = Novfs_internal_hash(&dentry->d_name);
++                  name.len  = dentry->d_name.len;
++                  name.name = dentry->d_name.name;
++
++
++                  
++                  retVal = Novfs_Get_File_Info( path, info, session );
++                  if ( 0 == retVal)
++                  {
++                     dentry->d_time = jiffies+(File_update_timeout*HZ);
++                     iLock = Novfs_lock_inode_cache( dir );
++                     if ( Novfs_update_entry( dir, &name, 0, info ) )
++                     {
++                        if (dentry->d_inode)
++                        {
++                           ino = dentry->d_inode->i_ino;
++                        }
++                        else
++                        {
++                           ino = (ino_t)InterlockedIncrement(&Novfs_Inode_Number);
++                        }
++                        Novfs_add_inode_entry( dir, &name, ino, info);
++                     }
++                     if ( dentry->d_inode )
++                     {
++                        update_inode(dentry->d_inode, info);
++                        id->Flags &= ~UPDATE_INODE;
++
++                        dentry->d_inode->i_flags &= ~S_DEAD;
++                        if (dentry->d_inode->u.generic_ip)
++                        {
++                           ((PINODE_DATA)dentry->d_inode->u.generic_ip)->Scope = id->Scope;
++                        }
++                     }
++                  }
++                  else if (-EINTR != retVal)
++                  {
++                     retVal = 0;
++                     iLock = Novfs_lock_inode_cache( dir );
++                     Novfs_remove_inode_entry( dir, &name, 0 );
++                     if ( dentry->d_inode  && !(dentry->d_inode->i_flags & S_DEAD) )
++                     {
++                        dentry->d_inode->i_flags |= S_DEAD;
++                        dentry->d_inode->i_size  = 0;
++                        dentry->d_inode->i_atime.tv_sec  =
++                        dentry->d_inode->i_atime.tv_nsec =
++                        dentry->d_inode->i_ctime.tv_sec  =
++                        dentry->d_inode->i_ctime.tv_nsec =
++                        dentry->d_inode->i_mtime.tv_sec  =
++                        dentry->d_inode->i_mtime.tv_nsec = 0;
++                        dentry->d_inode->i_blocks = 0;
++                        d_delete(dentry);   /* Remove from cache */
++                     }
++                  }
++               }
++               else
++               {
++                  retVal = -ENAMETOOLONG;
++               }
++            }
++         }
++      }
++      else
++      {
++         retVal = -ENOMEM;
++      }
++      if (iLock)
++      {
++         Novfs_unlock_inode_cache( dir );
++      }
++      dput(parent);
++   }
++
++   if (list) Novfs_Free(list);
++   if (info) Novfs_Free(info);
++
++   DbgPrint("verify_dentry: return=0x%x\n", retVal);
++
++   return(retVal);
++}
++
++/*++======================================================================*/
++struct dentry *Novfs_d_lookup(struct dentry *Parent, struct qstr *Name)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment: 
++ *
++ *========================================================================*/
++{
++   return( d_lookup( Parent, Name));
++}
++
++/*++======================================================================*/
++int Novfs_d_add(struct dentry *Parent, struct dentry *d, struct inode *i, int a)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment: 
++ *
++ *========================================================================*/
++{
++   void *scope;
++   PINODE_DATA id=NULL;
++
++   char *path, *buf;
++   
++   buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
++   if (buf)
++   {
++      path = Novfs_dget_path(d, buf, PATH_LENGTH_BUFFER);
++      if (path)
++      {
++         DbgPrint("Novfs_d_add: inode=0x%p ino=%d path %s\n", i, i->i_ino, path);
++      }
++      Novfs_Free(buf);
++   }
++
++   if ( Parent && Parent->d_inode && Parent->d_inode->u.generic_ip)
++   {
++      id = (PINODE_DATA)Parent->d_inode->u.generic_ip;
++   }
++
++   if (id && id->Scope)
++   {
++      scope = id->Scope;
++   }
++   else
++   {
++      scope = Scope_Get_ScopefromPath( d );
++   }
++
++   ((PINODE_DATA)i->u.generic_ip)->Scope = scope;
++
++   d->d_time = jiffies+(File_update_timeout*HZ);
++   if (a)
++   {
++      d_add(d, i);
++   }
++   else
++   {
++      d_instantiate(d, i);
++   }
++      
++   return(0);
++}
++
++/*++======================================================================*/
++int Novfs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
++/*
++ *  Arguments:   struct dentry *dentry - pointer to dentry to revalidate.
++ *               struct nameidata *nd - pointer to nameidata.
++ * 
++ *  Returns:     zero - dentry is not valid.
++ *               !zero - valid entry
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment: 
++ *
++ *========================================================================*/
++{
++   int retCode = 0;
++   struct inode *dir;
++   PINODE_DATA id;
++   struct qstr name;
++
++   UNUSED_VARIABLE( nd );
++
++   DbgPrint("Novfs_d_revalidate: 0x%p %.*s\n" \
++            "   d_count: %d\n" \
++            "   d_inode: 0x%p\n",
++      dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_count, dentry->d_inode);
++
++   if (IS_ROOT( dentry ))
++   {
++      retCode = 1;
++   }
++   else
++   {
++      if ( dentry->d_inode &&
++           dentry->d_parent && 
++           (dir = dentry->d_parent->d_inode) && 
++           (id = dir->u.generic_ip) )
++      {
++         /*
++          * Check timer to see if in valid time limit
++          */
++         if (jiffies > dentry->d_time)
++         {
++            /*
++             * Revalidate entry
++             */
++            name.len = dentry->d_name.len;
++            name.name = dentry->d_name.name;
++            name.hash = Novfs_internal_hash(&dentry->d_name);
++            dentry->d_time = 0;
++
++            if ( 0 == verify_dentry( dentry, 0 ))
++            {
++               if (Novfs_lock_inode_cache( dir ))
++               {
++                  if (Novfs_lookup_inode_cache( dir, &name, 0))
++                  {
++                     dentry->d_time = jiffies + (File_update_timeout*HZ);
++                     retCode = 1;
++                  }
++                  Novfs_unlock_inode_cache( dir );
++               }
++            }
++         }
++         else
++         {
++            retCode = 1;
++         }
++      }
++   }
++
++
++   if ( ( 0 == retCode ) && dentry->d_inode )
++   {
++      /*
++       * Entry has become invalid
++       */
++/*      dput(dentry);
++*/
++   }
++
++   DbgPrint("Novfs_d_revalidate: return 0x%x\n", retCode);
++
++   return(retCode);
++}
++
++/*++======================================================================*/
++unsigned long Novfs_internal_hash (struct qstr *name)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   unsigned long hash = 0;
++   unsigned int len = name->len;
++   unsigned char *c = (unsigned char *)name->name;
++
++   while(len--)
++   {
++      /*
++       * Lower case values for the hash.
++       */
++      hash = partial_name_hash(tolower(*c++), hash);
++   }
++
++   return(hash);
++}
++
++/*++======================================================================*/
++int Novfs_d_hash (struct dentry *dentry, struct qstr *name)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   UNUSED_VARIABLE( dentry );
++
++   DbgPrint("Novfs_d_hash: %.*s\n", name->len, name->name);
++
++   name->hash = Novfs_internal_hash( name );
++   
++   return(0);
++}
++
++/*++======================================================================*/
++int Novfs_d_strcmp (struct qstr *s1, struct qstr *s2)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   int retCode = 1;
++   unsigned char *str1, *str2;
++   unsigned int len;
++
++   DbgPrint("Novfs_d_strcmp: s1=%.*s s2=%.*s\n", s1->len, s1->name, s2->len, s2->name);
++
++   if (s1->len && (s1->len == s2->len) && (s1->hash == s2->hash) )
++   {
++      len = s1->len;
++      str1 = (unsigned char *)s1->name;
++      str2 = (unsigned char *)s2->name;
++      for ( retCode = 0; len-- ; str1++, str2++ )
++      {
++         if (*str1 != *str2)
++         {
++            if (tolower(*str1) != tolower(*str2))
++            {
++               retCode = 1;
++               break;
++            }
++         }
++      }
++   }
++
++   DbgPrint("Novfs_d_strcmp: retCode=0x%x\n", retCode);
++   return(retCode);
++}
++
++/*++======================================================================*/
++int Novfs_d_compare (struct dentry *parent, struct qstr *s1, struct qstr *s2)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   int retCode;
++
++   retCode = Novfs_d_strcmp(s1, s2);
++
++   DbgPrint("Novfs_d_compare: retCode=0x%x\n", retCode);
++   return(retCode);
++}
++
++/*++======================================================================*/
++int Novfs_d_delete(struct dentry *dentry)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   int retVal = 0;
++
++     DbgPrint("Novfs_d_delete: 0x%p %.*s\n" \
++            "   d_count: %d\n" \
++            "   d_inode: 0x%p\n",
++      dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_count, dentry->d_inode);
++
++   if (dentry->d_inode && (dentry->d_inode->i_flags & S_DEAD))
++   {
++      retVal = 1;
++   }
++
++   dentry->d_time = 0;
++
++   return( retVal );
++}
++
++/*++======================================================================*/
++void Novfs_d_release(struct dentry *dentry)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   DbgPrint("Novfs_d_release: 0x%x %.*s\n", dentry, dentry->d_name.len, dentry->d_name.name);
++}
++
++/*++======================================================================*/
++void Novfs_d_iput(struct dentry *dentry, struct inode *inode)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   DbgPrint("Novfs_d_iput: Inode=0x%x Ino=%d Dentry=0x%x Name=%.*s\n", 
++      inode, inode->i_ino, dentry, dentry->d_name.len, dentry->d_name.name);
++
++   iput(inode);
++
++}
++/*++======================================================================*/
++int Novfs_dir_open(struct inode *dir, struct file *file)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   char *path, *buf;
++   
++
++   DbgPrint("Novfs_dir_open: Inode 0x%x %d Name %.*s\n", dir, dir->i_ino, file->f_dentry->d_name.len, file->f_dentry->d_name.name);
++
++   buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
++   if (buf)
++   {
++      path = Novfs_dget_path(file->f_dentry, buf, PATH_LENGTH_BUFFER);
++      if (path)
++      {
++         DbgPrint("Novfs_dir_open: path %s\n", path);
++      }
++      Novfs_Free(buf);
++   }
++   file->private_data = NULL;
++   return(0);
++}
++
++/*++======================================================================*/
++int Novfs_dir_release(struct inode *dir, struct file *file)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   struct inode *inode;
++
++   DbgPrint("Novfs_dir_release: Inode 0x%x %d Name %.*s\n", dir, dir->i_ino, file->f_dentry->d_name.len, file->f_dentry->d_name.name);
++   if (file->private_data)
++   {
++      inode = file->private_data;
++      Novfs_free_inode_cache( inode );
++      Novfs_Free(file->private_data);
++   }
++
++   return(0);
++}
++
++/*++======================================================================*/
++loff_t  Novfs_dir_lseek(struct file *file, loff_t offset, int origin)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   return(default_llseek(file, offset, origin));
++}
++
++/*++======================================================================*/
++int Novfs_dir_read(struct file *file, char *buf, size_t len, loff_t *off)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++/*
++   int rlen = 0;
++
++   DbgPrint("Novfs_dir_readdir: dentry path %.*s buf=0x%p len=%d off=%lld\n", file->f_dentry->d_name.len, file->f_dentry->d_name.name, buf, len, *off);
++
++   if (0 == *off)
++   {
++      rlen = 8;
++      rlen -= copy_to_user(buf, "Testing\n", 8);
++      *off += rlen;
++   }
++   return(rlen);
++*/
++   return(generic_read_dir(file, buf, len, off));
++}
++
++/*++======================================================================*/
++void process_list(struct file *File, char *List, int Type, PENTRY_INFO Info, session_t SessionId)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   unsigned char *path, *buf=NULL, *cp;
++   struct inode *dir = File->f_dentry->d_inode;
++   struct qstr name;
++   ino_t ino=0;
++
++   buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
++   path = buf;
++   if (buf)
++   {
++      path = Novfs_dget_path(File->f_dentry, buf, PATH_LENGTH_BUFFER);
++      if (path)
++      {
++         strcpy(buf, path);
++      }
++      path = buf+strlen(buf);
++      *path++ = '\\';
++   }
++
++   if ( List )
++   {
++      cp = List;
++      while (*cp)
++      {
++         name.name = cp;
++         name.len  = strlen(cp);
++         name.hash = Novfs_internal_hash( &name );
++         cp += (name.len+1);
++
++         Info->mode = S_IFDIR | 0700;
++         Info->size = 0;
++         Info->atime = Info->ctime = Info->mtime = CURRENT_TIME;
++
++         if ( (USER_LIST != Type) && buf && ((int)(path-buf)+name.len < PATH_LENGTH_BUFFER) )
++         {
++            strcpy(path, name.name);
++            Novfs_Get_File_Info(buf, Info, SessionId);
++         }
++
++         if ( Novfs_update_entry( dir, &name, ino, Info ) )
++         {
++            Novfs_add_inode_entry(dir, &name, (ino_t)InterlockedIncrement(&Novfs_Inode_Number), Info);
++         }
++      }
++   }
++
++   if (buf) Novfs_Free(buf);
++
++}
++
++/*++======================================================================*/
++int Novfs_dir_readdir(struct file * file, void * dirent, filldir_t filldir)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++	unsigned char *path, *buf=NULL;
++	unsigned char *list=NULL;
++	PENTRY_INFO info=NULL, pinfo, iinfo;
++	int count;
++	
++	int status = -ENOMEM;
++	struct inode *inode;
++	session_t sessionId;
++	uid_t uid;
++	struct qstr name;
++	struct list_head *inter;
++	ino_t ino;
++	int iLock=0;
++	int type = 0;
++	
++	DbgPrint("Novfs_dir_readdir(%s): dentry path %.*s 0x%x\n", current->comm, file->f_dentry->d_name.len, file->f_dentry->d_name.name, file->f_dentry->d_fsdata);
++	
++	inode = file->f_dentry->d_inode;
++	
++	info = Novfs_Malloc(sizeof(ENTRY_INFO)+PATH_LENGTH_BUFFER, GFP_KERNEL);
++	if (info)
++	{
++		if (!file->private_data)
++		{
++			if ( inode && inode->u.generic_ip )
++			{
++				sessionId = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
++				if (0 == sessionId)
++				{
++					((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath(file->f_dentry);
++					sessionId = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
++				}
++				uid = Scope_Get_Uid(((PINODE_DATA)inode->u.generic_ip)->Scope);
++			}
++			else
++			{
++				sessionId = 0;
++				uid = current->euid;
++			}
++	
++			if ( IS_ROOT(file->f_dentry) ||  /* Root */
++				IS_ROOT(file->f_dentry->d_parent) || /* User */
++				IS_ROOT(file->f_dentry->d_parent->d_parent) ) /* Server */
++			{
++				if ( IS_ROOT(file->f_dentry) )
++				{
++					DbgPrint("Novfs_dir_readdir: Root directory\n");
++					list = Scope_Get_ScopeUsers();
++					type = USER_LIST;
++				
++				} 
++				else if ( IS_ROOT(file->f_dentry->d_parent) )
++				{
++					DbgPrint("Novfs_dir_readdir: Parent is Root directory\n");
++					Novfs_Get_Connected_Server_List( &list, sessionId );
++					type = SERVER_LIST;
++				}
++				else
++				{
++					DbgPrint("Novfs_dir_readdir: Parent-Parent is Root directory\n");
++					Novfs_Get_Server_Volume_List(&file->f_dentry->d_name, &list, sessionId);
++					type = VOLUME_LIST;
++				}
++			
++				iLock = Novfs_lock_inode_cache( inode );
++				Novfs_invalidate_inode_cache( inode );
++			
++				process_list(file, list, type, info, sessionId);
++			}
++			else
++			{
++				DbgPrint("Novfs_dir_readdir: Default directory\n");
++				buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
++				if (buf)
++				{
++					path = Novfs_dget_path(file->f_dentry, buf, PATH_LENGTH_BUFFER);
++					if (path)
++					{
++						unsigned long enumHandle=0;
++			
++						iLock = Novfs_lock_inode_cache( inode );
++						Novfs_invalidate_inode_cache(inode);
++						do
++						{
++							/*
++							* Novfs_Get_Directory_List will return 0 when no error or -1 when
++							* the last entry is returned.  Otherwise it will return an error.
++							*/
++							info->namelength = 0;
++							status = Novfs_Get_Directory_ListEx(path, &enumHandle, &count, &pinfo, sessionId);
++							DbgPrint("Novfs_dir_readdir: Novfs_Get_Directory_List return 0x%x count=%d pinfo=0x%p\n", status, count, pinfo);
++							iinfo = pinfo;
++							while ( (0 == status) && pinfo && count-- )
++							{
++								memcpy(info, pinfo, (int)((char *)&pinfo->name[pinfo->namelength]-(char *)pinfo));
++								pinfo = (PENTRY_INFO)&pinfo->name[pinfo->namelength];
++								name.len  = info->namelength;
++								name.name = info->name;
++								name.hash = Novfs_internal_hash(&name);
++								info->name[name.len] = '\0';
++						
++								DbgPrint("Novfs_dir_readdir: Got %s\n", name.name);
++						
++								if ( Novfs_update_entry( inode, &name, 0, info ))
++								{
++									Novfs_add_inode_entry(inode, &name, (ino_t)InterlockedIncrement(&Novfs_Inode_Number), info);
++								}
++							}
++					
++							if (iinfo)
++							{
++								Novfs_Free(iinfo);
++							}
++						
++						}
++						while ( !status );
++					}
++				}
++			}
++			
++			file->private_data = (PDIR_CACHE)Novfs_Malloc(sizeof(struct inode) + sizeof(DIR_CACHE), GFP_KERNEL);
++			if (file->private_data)
++			{
++				struct inode *dinode = file->private_data;
++				PINODE_DATA id = (PINODE_DATA)((char *)file->private_data+sizeof(struct inode));
++			
++				dinode->u.generic_ip = id;
++
++				id->Scope = ((PINODE_DATA)inode->u.generic_ip)->Scope;
++				id->Flags = 0;
++				INIT_LIST_HEAD( &id->DirCache );
++				init_MUTEX( &id->DirCacheLock );
++				
++				inter = NULL;
++				/*
++				* Copy rest of the files.
++				*/
++				while( !Novfs_enumerate_inode_cache(inode, &inter, &ino, info))
++				{
++					DbgPrint("Novfs_dir_readdir : BEGIN Calling filedir %llu with ino %d mode 0%o name %s\n", file->f_pos, ino, info->mode, info->name);
++					name.len  = info->namelength;
++					name.name = info->name;
++					name.hash = Novfs_internal_hash( &name );
++					Novfs_add_inode_entry(dinode, &name, ino, info);
++					DbgPrint("Novfs_dir_readdir : END Calling filedir %llu with ino %d mode 0%o name %s\n", file->f_pos, ino, info->mode, info->name);
++				}
++				file->private_data = dinode;
++			}
++
++			if ( iLock )
++			{
++				Novfs_free_invalid_entries( inode );
++			}
++		}
++	
++		switch ((int) file->f_pos) 
++		{
++			case 0:
++			DbgPrint("Novfs_dir_readdir : Calling filedir %llu with ino %d name .\n", file->f_pos, inode->i_ino);
++				if (filldir(dirent, ".", 1, file->f_pos, inode->i_ino, DT_DIR) < 0) 
++				{
++					break;
++				}
++				file->f_pos++;
++				/* fallthrough */
++			case 1:
++			DbgPrint("Novfs_dir_readdir : Calling filedir %llu with ino %d name ..\n", file->f_pos, parent_ino(file->f_dentry));
++				if (filldir(dirent, "..", 2, file->f_pos, parent_ino(file->f_dentry), DT_DIR) < 0) 
++				{
++					break;
++				}
++				file->f_pos++;
++				/* fallthrough */
++		}
++
++		status = 0;
++		inter = NULL;
++				
++		if(!Novfs_get_entry_by_pos(file->private_data, file->f_pos, &ino, info))
++		{
++			DbgPrint("Novfs_dir_readdir : Calling filedir %llu with ino %d mode 0%o name %s\n", file->f_pos, ino, info->mode, info->name);
++			filldir(dirent, info->name, info->namelength, file->f_pos, ino, info->mode >> 12);
++		}
++		file->f_pos++;
++		
++		if (iLock)
++		{
++			Novfs_unlock_inode_cache(inode);
++		}
++	}
++
++	if (info) Novfs_Free( info );
++	if (buf)  Novfs_Free( buf );
++	if (list) Novfs_Free( list );
++	
++	return(status);
++}
++
++
++/*++======================================================================*/
++int Novfs_dir_fsync(struct file * file, struct dentry *dentry, int datasync)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   return(simple_sync_file(file, dentry, datasync));
++}
++
++
++/*++======================================================================*/
++ssize_t Novfs_f_read(struct file *file, char *buf, size_t len, loff_t *off)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   size_t thisread, totalread=0;
++   loff_t offset = *off;
++   struct inode *inode;
++   session_t session;
++   PINODE_DATA id;
++
++   if ( file->f_dentry && 
++        (inode = file->f_dentry->d_inode) && 
++        (id = (PINODE_DATA)inode->u.generic_ip))
++   {
++
++      DbgPrint("Novfs_f_read(0x%x 0x%p %d %lld %.*s)\n", 
++         (unsigned long)file->private_data, 
++         buf, len, offset, 
++         file->f_dentry->d_name.len, 
++         file->f_dentry->d_name.name);
++
++      if ( PageCache && 
++           !(file->f_flags & O_DIRECT) && 
++           id->CacheFlag )
++      {
++         totalread = generic_file_read(file, buf, len, off);
++      }
++      else
++      {
++         session = Scope_Get_SessionId(id->Scope);
++         if (0 == session)
++         {
++            id->Scope = Scope_Get_ScopefromPath( file->f_dentry );
++            session = Scope_Get_SessionId(id->Scope);
++         }
++
++         while(len > 0 && (offset < i_size_read(inode)) )
++         {
++            thisread = len;
++            if (Novfs_Read_File((unsigned long)file->private_data, buf, &thisread, &offset, session) || !thisread)
++            {
++               break;
++            }
++            DbgPrint("Novfs_f_read thisread = 0x%x\n", thisread);
++            len -= thisread;
++            buf += thisread;
++            offset += thisread;
++            totalread += thisread;
++         }
++         *off = offset;
++      }
++   }  
++   DbgPrint("Novfs_f_read return = 0x%x\n", totalread);
++
++   return(totalread);
++}
++
++/*++======================================================================*/
++ssize_t Novfs_f_write(struct file *file, const char *buf, size_t len, loff_t *off)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   ssize_t thiswrite, totalwrite=0;
++   loff_t offset = *off;
++   session_t session;
++   struct inode *inode;
++   int status;
++   PINODE_DATA id;
++
++   if ( file->f_dentry && 
++        (inode = file->f_dentry->d_inode) && 
++        (id = file->f_dentry->d_inode->u.generic_ip) )
++   {
++      DbgPrint("Novfs_f_write(0x%x %d %lld %.*s)\n", (unsigned long)file->private_data, len, offset, file->f_dentry->d_name.len, file->f_dentry->d_name.name);
++
++      if ( PageCache && 
++           !(file->f_flags & O_DIRECT) &&
++           id->CacheFlag )
++      {
++         totalwrite = generic_file_write(file, buf, len, off);
++      }
++      else
++      {
++         if (file->f_flags & O_APPEND) 
++         {
++            offset = i_size_read(inode);
++            DbgPrint("Novfs_f_write appending to end %lld %.*s\n", offset, file->f_dentry->d_name.len, file->f_dentry->d_name.name);
++         }
++
++         session = Scope_Get_SessionId(id->Scope);
++         if (0 == session)
++         {
++            id->Scope = Scope_Get_ScopefromPath( file->f_dentry );
++            session = Scope_Get_SessionId(id->Scope);
++         }
++
++         while(len > 0)
++         {
++            thiswrite = len;
++            if ((status = Novfs_Write_File(
++                  (unsigned long)file->private_data, 
++                  (unsigned char *)buf, 
++                  &thiswrite, 
++                  &offset, 
++                  session)) || !thiswrite)
++            {
++               totalwrite = status;
++               break;
++            }
++            DbgPrint("Novfs_f_write thiswrite = 0x%x\n", thiswrite);
++            len -= thiswrite;
++            buf += thiswrite;
++            offset += thiswrite;
++            totalwrite += thiswrite;
++            if (offset > i_size_read(inode))
++            {
++               i_size_write(inode, offset);
++               inode->i_blocks = (offset + inode->i_blksize - 1) >> inode->i_blkbits;
++            }
++            inode->i_mtime = inode->i_atime = CURRENT_TIME;
++            id->Flags |= UPDATE_INODE;
++
++         }
++         *off = offset;
++      }
++   }
++   DbgPrint("Novfs_f_write return = 0x%x\n", totalwrite);
++
++   return(totalwrite);
++}
++
++/*++======================================================================*/
++int Novfs_f_readdir(struct file *file, void *data, filldir_t fill)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   UNUSED_VARIABLE(file);
++   UNUSED_VARIABLE(data);
++   UNUSED_VARIABLE(fill);
++   return(-EISDIR);
++}
++
++/*++======================================================================*/
++int Novfs_f_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   UNUSED_VARIABLE(inode);
++   UNUSED_VARIABLE(file);
++   UNUSED_VARIABLE(cmd);
++   UNUSED_VARIABLE(arg);
++   DbgPrint("Novfs_f_ioctl: file=0x%x cmd=0x%x arg=0x%x", file, cmd, arg);
++
++   return(-ENOSYS);
++}
++
++/*++======================================================================*/
++int Novfs_f_mmap(struct file * file, struct vm_area_struct * vma)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   int retCode = -EINVAL;
++
++   DbgPrint("Novfs_f_mmap: file=0x%x", file);
++
++   retCode = generic_file_mmap(file, vma);
++
++   DbgPrint("Novfs_f_mmap: retCode=0x%x\n", retCode);
++   return( retCode );
++}
++
++/*++======================================================================*/
++int Novfs_f_open(struct inode *inode, struct file *file)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PENTRY_INFO info=NULL;
++   int retCode = -ENOENT;
++   session_t session;
++   char *path;
++   struct dentry *parent;
++   ino_t ino;
++   PINODE_DATA id;
++
++   DbgPrint("Novfs_f_open: inode=0x%p file=0x%p dentry=0x%p dentry->d_inode=0x%p\n", inode, file, file->f_dentry, file->f_dentry->d_inode);
++   if (file->f_dentry)
++   {
++      DbgPrint("Novfs_f_open: %.*s f_flags=0%o f_mode=0%o i_mode=0%o\n", file->f_dentry->d_name.len, file->f_dentry->d_name.name, file->f_flags, file->f_mode, inode->i_mode);
++   }
++
++   if (inode && inode->u.generic_ip)
++   {
++      id = (PINODE_DATA)file->f_dentry->d_inode->u.generic_ip;
++      session = Scope_Get_SessionId(id->Scope);
++      if (0 == session)
++      {
++         id->Scope = Scope_Get_ScopefromPath( file->f_dentry );
++         session = Scope_Get_SessionId(id->Scope);
++      }
++
++      info = (PENTRY_INFO)Novfs_Malloc(sizeof(ENTRY_INFO) + PATH_LENGTH_BUFFER, GFP_KERNEL);
++      if (info)
++      {
++         path = Novfs_dget_path(file->f_dentry, info->name, PATH_LENGTH_BUFFER);
++         if (path)
++         {
++            DbgPrint("Novfs_f_open: %s\n", path);
++            retCode = Novfs_Open_File(
++                        path, 
++                        file->f_flags & ~O_EXCL, info, 
++                        (unsigned long *)&file->private_data,
++                        session);
++            if ( !retCode )
++            {
++               /*
++                *update_inode(inode, &info);
++                */
++               id->FileHandle = (unsigned long)file->private_data;
++               id->CacheFlag  = Novfs_Get_File_Cache_Flag( path, session );
++               
++               if( !Novfs_Get_File_Info(path, info, session))
++               {
++                  update_inode(inode, info);
++               }
++
++               parent = dget_parent(file->f_dentry);
++
++               if (parent && parent->d_inode)
++               {
++                  struct inode *dir = parent->d_inode;
++                  Novfs_lock_inode_cache(dir);
++                  ino = 0;
++                  if (Novfs_get_entry(dir, &file->f_dentry->d_name, &ino, info))
++                  {
++                     ((PINODE_DATA)inode->u.generic_ip)->Flags |= UPDATE_INODE;
++                  }
++
++                  Novfs_unlock_inode_cache(dir);
++               }
++               dput(parent);
++            }
++         }
++         Novfs_Free(info);
++      }
++   }
++   DbgPrint("Novfs_f_open: retCode=0x%x\n", retCode);
++   return( retCode );
++}
++
++/*++======================================================================*/
++int Novfs_f_flush(struct file *file)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   struct inode *inode;
++
++   if (file->f_dentry)
++   {
++      if( (file->f_flags & O_ACCMODE) != O_RDONLY)
++      {
++         inode = file->f_dentry->d_inode;
++         DbgPrint("Novfs_f_flush: %.*s f_flags=0x%x f_mode=0%o i_mode=0%o\n", file->f_dentry->d_name.len, file->f_dentry->d_name.name, file->f_flags, file->f_mode, inode->i_mode);
++         filemap_fdatawrite( file->f_dentry->d_inode->i_mapping );
++      }
++   }
++   return(0);
++}
++
++/*++======================================================================*/
++int Novfs_f_release(struct inode *inode, struct file *file)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   int retCode = -EACCES;
++   session_t session;
++   PINODE_DATA id;
++  
++   DbgPrint("Novfs_f_release: path=%.*s handle=%x\n", 
++      file->f_dentry->d_name.len, 
++      file->f_dentry->d_name.name, 
++      (unsigned long)file->private_data);
++
++   if ( file->f_dentry->d_inode && (id = file->f_dentry->d_inode->u.generic_ip))
++   {
++      session = Scope_Get_SessionId(id->Scope);
++      if (0 == session)
++      {
++         id->Scope = Scope_Get_ScopefromPath( file->f_dentry );
++         session = Scope_Get_SessionId(id->Scope);
++      }
++
++		//invalidate_remote_inode(file->f_dentry->d_inode);
++
++      retCode = Novfs_Close_File((unsigned long)file->private_data, session);
++      id->FileHandle = 0;
++   }
++   return(retCode);
++}
++
++/*++======================================================================*/
++int Novfs_f_fsync(struct file *file, struct dentry *dentry, int datasync)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   UNUSED_VARIABLE(file);
++   UNUSED_VARIABLE(dentry);
++   UNUSED_VARIABLE(datasync);
++   return(0);
++}
++
++/*++======================================================================*/
++int Novfs_f_llseek(struct file *file, loff_t offset, int origin)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   DbgPrint("Novfs_f_llseek: File=0x%x Name=%.*s offset=%lld origin=%d\n", file, file->f_dentry->d_name.len, file->f_dentry->d_name.name, offset, origin);
++   return(generic_file_llseek(file, offset, origin));
++}
++
++/*++======================================================================*/
++int Novfs_f_lock(struct file *file, int cmd, struct file_lock *lock)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   UNUSED_VARIABLE(file);
++   UNUSED_VARIABLE(cmd);
++   UNUSED_VARIABLE(lock);
++   return(-ENOSYS);
++}
++/*++======================================================================*/
++static void Novfs_copy_cache_pages(struct address_space *mapping, 
++	struct list_head *pages, int bytes_read, char *data,
++	struct pagevec *plru_pvec)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++	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);
++			data += PAGE_CACHE_SIZE;
++			bytes_read -= PAGE_CACHE_SIZE;
++			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;
++}
++
++/*++======================================================================*/
++int Novfs_a_writepage(struct page* page, struct writeback_control *wbc)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++	int retCode = -EFAULT;
++   struct inode *inode = page->mapping->host;
++   PINODE_DATA id = inode->u.generic_ip;
++	loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT);
++   session_t session=0;
++   DATA_LIST dlst[2];
++   size_t len = PAGE_CACHE_SIZE;
++
++   session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
++
++	page_cache_get(page);
++
++   pos =  ((loff_t)page->index << PAGE_CACHE_SHIFT);
++
++   /*
++    * Leave first dlst entry for reply header.
++    */
++   dlst[1].page   = page;
++   dlst[1].offset = NULL;
++   dlst[1].len    = len;
++   dlst[1].rwflag = DLREAD; 
++
++   /*
++    * Check size so we don't write pass end of file.
++    */
++   if ((pos + (loff_t)len) > i_size_read(inode))
++   {
++      len = (size_t)(i_size_read(inode) - pos);
++   }
++
++   retCode = Novfs_Write_Pages( id->FileHandle, dlst, 2, len, pos, session);
++   if ( !retCode )
++   {
++	   SetPageUptodate(page);
++   }
++
++	unlock_page(page);
++	page_cache_release(page);	
++
++	return( retCode );
++}
++
++/*++======================================================================*/
++int Novfs_a_writepages(struct address_space *mapping, struct writeback_control *wbc)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   int retCode = 0;
++   struct inode *inode=mapping->host;
++   session_t session=0;
++   unsigned long fh=0;
++
++   int max_page_lookup = MaxIoSize/PAGE_CACHE_SIZE;
++
++   PDATA_LIST dlist, dlptr;
++   struct page **pages;
++
++   int dlist_idx, i=0;
++   pgoff_t index, next_index=0;
++   loff_t pos=0;
++   size_t tsize;
++
++   DbgPrint("Novfs_a_writepages: mapping=0x%p wbc=0x%p\n", mapping, wbc);
++
++   if (inode)
++   {
++      DbgPrint(" Inode=0x%x Ino=%d\n", inode, inode->i_ino);
++
++      if (inode->u.generic_ip)
++      {
++         session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
++         fh = ((PINODE_DATA)inode->u.generic_ip)->FileHandle;
++      }
++   }
++
++   dlist = Novfs_Malloc( sizeof(DATA_LIST) * max_page_lookup, GFP_KERNEL);
++   pages = Novfs_Malloc( sizeof(struct page *) * max_page_lookup, GFP_KERNEL);
++
++   if ( fh && dlist && pages )
++   {
++	   struct backing_dev_info *bdi = mapping->backing_dev_info;
++	   int done = 0;
++	   int nr_pages=0;
++	   int scanned = 0;
++
++	   if (wbc->nonblocking && bdi_write_congested(bdi))
++	   {
++		   wbc->encountered_congestion = 1;
++		   return 0;
++	   }
++
++	   if (wbc->sync_mode == WB_SYNC_NONE) 
++	   {
++		   index = mapping->writeback_index; /* Start from prev offset */
++	   }
++	   else 
++	   {
++		   index = 0;			  /* whole-file sweep */
++		   scanned = 1;
++	   }
++
++      next_index = index;
++
++	   while (!done && (wbc->nr_to_write > 0))
++      {
++         dlist_idx = 0;
++         dlptr = &dlist[1];
++
++         DbgPrint("Novfs_a_writepages1: nr_pages=%d\n", nr_pages);
++         if ( !nr_pages )
++         {
++            memset(pages, 0, sizeof(struct page *)*max_page_lookup);
++
++	         AS_TREE_LOCK(&mapping->tree_lock);
++
++	         /*
++             * Need to ask for one less then max_page_lookup or we
++             * will overflow the request buffer.  This also frees
++             * the first entry for the reply buffer.
++             */
++	         nr_pages = radix_tree_gang_lookup_tag(&mapping->page_tree,
++				         (void **)pages, index, max_page_lookup-1, PAGECACHE_TAG_DIRTY);
++
++            DbgPrint("Novfs_a_writepages2: nr_pages=%d\n", nr_pages);
++
++
++	         for (i = 0; i < nr_pages; i++)
++            {
++		         page_cache_get(pages[i]);
++            }
++
++	         AS_TREE_UNLOCK(&mapping->tree_lock);
++
++	         if (nr_pages)
++            {
++		         index = pages[nr_pages - 1]->index + 1;
++               pos = (loff_t)pages[0]->index << PAGE_CACHE_SHIFT;
++            }
++
++            if ( !nr_pages )
++            {
++               if ( scanned )
++               {
++                  index = 0;
++                  scanned = 0;
++                  continue;
++               }
++               done = 1;
++            }
++            else
++            {
++               next_index = pages[0]->index;
++               i = 0;
++            }
++         }
++         else
++         {
++            if (pages[i])
++            {
++               pos = (loff_t)pages[i]->index << PAGE_CACHE_SHIFT;
++            }
++         }
++
++
++		   for ( ; i < nr_pages ; i++) 
++		   {
++			   struct page *page = pages[i];
++
++			   /*
++			    * At this point we hold neither mapping->tree_lock nor
++			    * lock on the page itself: the page may be truncated or
++			    * invalidated (changing page->mapping to NULL), or even
++			    * swizzled back from swapper_space to tmpfs file
++			    * mapping
++			    */
++
++            DbgPrint("Novfs_a_writepages: pos=0x%llx index=%d page->index=%d next_index=%d\n", pos, index, page->index, next_index);
++
++			   if (page->index != next_index)
++            {
++               next_index = page->index;
++               break;
++            }
++            next_index = page->index+1;
++
++			   lock_page(page);
++
++			   if (wbc->sync_mode != WB_SYNC_NONE)
++				   wait_on_page_writeback(page);
++
++			   if (page->mapping != mapping || PageWriteback(page) ||
++					   !clear_page_dirty_for_io(page)) 
++			   {
++				   unlock_page(page);
++				   continue;
++			   }
++
++            dlptr[dlist_idx].page   = page;
++            dlptr[dlist_idx].offset = NULL;
++            dlptr[dlist_idx].len    = PAGE_CACHE_SIZE;
++            dlptr[dlist_idx].rwflag = DLREAD;
++            dlist_idx++;
++            DbgPrint("Novfs_a_writepages: Add page=0x%p index=0x%lx\n", page, page->index);
++		   }
++
++         DbgPrint("Novfs_a_writepages: dlist_idx=%d\n", dlist_idx);
++			if ( dlist_idx )
++         {
++            tsize = dlist_idx * PAGE_CACHE_SIZE;
++            /*
++             * Check size so we don't write pass end of file.
++             */
++            if ((pos + tsize) > i_size_read(inode))
++            {
++               tsize = (size_t)(i_size_read(inode) - pos);
++            }
++
++            retCode = Novfs_Write_Pages(fh, dlist, dlist_idx+1, tsize, pos, session);
++            switch (retCode)
++            {
++               case 0:
++                  wbc->nr_to_write -= dlist_idx;
++                  break;
++
++               case -ENOSPC:
++						set_bit(AS_ENOSPC, &mapping->flags);
++                  done = 1;
++                  break;
++                  
++               default:
++						set_bit(AS_EIO, &mapping->flags);
++                  done = 1;
++                  break;
++            }
++
++            do
++            {
++               unlock_page((struct page *)dlptr[dlist_idx-1].page);
++               page_cache_release((struct page *)dlptr[dlist_idx-1].page);
++               DbgPrint("Novfs_a_writepages: release page=0x%p index=0x%lx\n", dlptr[dlist_idx-1].page, ((struct page *)dlptr[dlist_idx-1].page)->index);
++               if ( !retCode )
++               {
++                  wbc->nr_to_write--;
++               }
++            } while( --dlist_idx );
++         }
++
++         if ( i >= nr_pages )
++         {
++            nr_pages = 0;
++         }
++	   }
++
++	   mapping->writeback_index = index;
++
++   }
++   else
++   {
++	   set_bit(AS_EIO, &mapping->flags);
++   }
++   if (dlist) Novfs_Free(dlist);
++   if (pages) Novfs_Free(pages);
++
++   DbgPrint("Novfs_a_writepage: retCode=%d\n", retCode);
++   return (0);
++
++}
++
++/*++======================================================================*/
++int Novfs_a_readpage(struct file *file, struct page *page)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   int retCode = 0;
++   void *pbuf;
++   struct inode *inode=NULL;
++   struct dentry *dentry=NULL;
++   loff_t offset;
++   size_t len;
++   session_t session=0;
++
++   DbgPrint("Novfs_a_readpage: File=0x%x Name=%.*s Page=0x%x", file, file->f_dentry->d_name.len, file->f_dentry->d_name.name, page);
++
++   dentry = file->f_dentry;
++
++   if (dentry)
++   {
++      DbgPrint(" Dentry=0x%x Name=%.*s", dentry, dentry->d_name.len, dentry->d_name.name);
++      if (dentry->d_inode)
++      {
++         inode = dentry->d_inode;
++      }
++   }
++
++
++
++   if (inode)
++   {
++      DbgPrint(" Inode=0x%x Ino=%d", inode, inode->i_ino);
++
++      if (inode->u.generic_ip)
++      {
++         session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
++         if (0 == session)
++         {
++            ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( file->f_dentry );
++            session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
++         }
++      }
++   }
++
++   DbgPrint("\n");
++
++
++   if (!PageUptodate(page)) 
++   {
++      DATA_LIST dlst[2];
++
++      offset = page->index << PAGE_CACHE_SHIFT;
++      len = PAGE_CACHE_SIZE;
++
++      /*
++       * Save the first entry for the reply header.
++       */
++      dlst[1].page   = page;
++      dlst[1].offset = NULL;
++      dlst[1].len    = PAGE_CACHE_SIZE;
++      dlst[1].rwflag = DLWRITE;
++
++      retCode = Novfs_Read_Pages((unsigned long)file->private_data, dlst, 2, &len, &offset, session);
++      if ( len && (len < PAGE_CACHE_SIZE) ) 
++      {
++         pbuf = kmap_atomic(page, KM_USER0);
++         memset(&((char *)pbuf)[len], 0, PAGE_CACHE_SIZE-len);
++         kunmap_atomic(pbuf, KM_USER0);
++      }
++   
++      flush_dcache_page(page);
++      SetPageUptodate(page);
++   }
++   unlock_page(page);
++
++   DbgPrint("Novfs_a_readpage: retCode=%d\n", retCode);
++   return (retCode);
++
++}
++
++/*++======================================================================*/
++int Novfs_a_readpages(struct file *file, struct address_space *mapping, struct list_head *page_lst, unsigned nr_pages)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   int retCode = 0;
++   struct inode *inode=NULL;
++   struct dentry *dentry=NULL;
++   session_t session=0;
++   loff_t offset;
++   size_t len;
++
++   unsigned page_idx;
++	struct pagevec lru_pvec;
++   pgoff_t next_index;
++
++   char *rbuf, done=0;
++
++   DbgPrint("Novfs_a_readpages: File=0x%p Name=%.*s Pages=%d\n", file, file->f_dentry->d_name.len, file->f_dentry->d_name.name, nr_pages);
++
++   dentry = file->f_dentry;
++
++   if (dentry)
++   {
++      DbgPrint(" Dentry=0x%x Name=%.*s\n", dentry, dentry->d_name.len, dentry->d_name.name);
++      if (dentry->d_inode)
++      {
++         inode = dentry->d_inode;
++      }
++   }
++
++   if (inode)
++   {
++      DbgPrint(" Inode=0x%x Ino=%d\n", inode, inode->i_ino);
++
++      if (inode->u.generic_ip)
++      {
++         session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
++         if (0 == session)
++         {
++            ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( file->f_dentry );
++            session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
++         }
++      }
++   }
++
++   rbuf = (char *)Novfs_Malloc(MaxIoSize, GFP_KERNEL);
++   if (rbuf)
++   {
++      pagevec_init(&lru_pvec, 0);
++	   for (page_idx = 0; page_idx < nr_pages && !done; ) 
++	   {
++		   struct page *page, *tpage;
++
++		   if (list_empty(page_lst))
++			   break;
++	
++		   page = list_entry(page_lst->prev, struct page, lru);
++
++         next_index = page->index;
++         offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
++         len = 0;
++
++         /*
++          * Count number of contiguous pages.
++          */
++         list_for_each_entry_reverse(tpage, page_lst, lru)
++         {
++            if ( (next_index != tpage->index) ||
++                 (len >= MaxIoSize-PAGE_SIZE) )
++            {
++               break;
++            }
++            len += PAGE_SIZE;
++            next_index++;
++         }
++
++         if ( len && !done )
++         {        
++            DATA_LIST dllst[2];
++
++            dllst[1].page   = NULL;
++            dllst[1].offset = rbuf;
++            dllst[1].len    = len;
++            dllst[1].rwflag = DLWRITE;
++
++            if ( !Novfs_Read_Pages((unsigned long)file->private_data, dllst, 2, &len, &offset, session))
++            {
++               Novfs_copy_cache_pages(mapping, page_lst, len, rbuf, &lru_pvec);
++		         page_idx +=  len >> PAGE_CACHE_SHIFT;
++		         if ((int)(len & PAGE_CACHE_MASK) != len) 
++		         {
++			         page_idx++;
++               }
++            }
++            else
++            {
++               done = 1;
++            }
++         }
++	   }
++
++		/*
++		 * Free any remaining pages.
++		 */
++		while ( !list_empty(page_lst) )
++		{
++		   struct page *page = list_entry(page_lst->prev, struct page, lru);
++
++		   list_del(&page->lru);
++		   page_cache_release(page);
++      }
++
++      pagevec_lru_add(&lru_pvec);
++      Novfs_Free( rbuf );
++   }
++   else
++   {
++      retCode = -ENOMEM;
++   }
++
++   DbgPrint("Novfs_a_readpages: retCode=%d\n", retCode);
++   return (retCode);
++
++}
++
++/*++======================================================================*/
++int Novfs_a_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   int retVal = 0;
++   loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
++   size_t len=PAGE_CACHE_SIZE;
++   session_t session=0;
++   DATA_LIST dllst[2];
++   struct inode *inode = file->f_dentry->d_inode;
++
++   DbgPrint("Novfs_a_prepare_write: File=0x%x Page=0x%x offset=0x%llx From=%u To=%u filesize=%lld\n", file, page, offset, from, to, i_size_read(file->f_dentry->d_inode));
++   if (!PageUptodate(page)) 
++   {
++      /*
++       * Check to see if whole page
++       */
++      if((to==PAGE_CACHE_SIZE) && (from == 0))
++      {
++         SetPageUptodate(page);
++      }
++
++      /* 
++       * Check to see if we can read page. 
++       */
++      else if((file->f_flags & O_ACCMODE) != O_WRONLY)
++      {
++         /*
++          * Get session.
++          */
++         if (file->f_dentry && file->f_dentry->d_inode)
++         {
++            if (file->f_dentry->d_inode->u.generic_ip)
++            {
++               session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
++               if (0 == session)
++               {
++                  ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( file->f_dentry );
++                  session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
++               }
++            }
++         }
++
++         page_cache_get(page);
++
++         len = i_size_read(inode) - offset;
++         if (len > PAGE_CACHE_SIZE)
++         {
++            len = PAGE_CACHE_SIZE;
++         }
++
++         if( len )
++         {
++            /*
++             * Read page from server.
++             */
++
++            dllst[1].page   = page;
++            dllst[1].offset = 0;
++            dllst[1].len    = len;
++            dllst[1].rwflag = DLWRITE;
++
++            Novfs_Read_Pages((unsigned long)file->private_data, dllst, 2, &len, &offset, session);
++            /*
++             * Zero unnsed page.
++             */
++         }
++
++         if (len < PAGE_CACHE_SIZE)
++         {
++            char *adr = kmap_atomic(page, KM_USER0);
++            memset(adr+len, 0, PAGE_CACHE_SIZE-len);
++            kunmap_atomic(adr, KM_USER0);
++         }
++      }
++      else
++      {
++         /*
++          * Zero section of memory that not going to be used.
++          */
++         char *adr = kmap_atomic(page, KM_USER0);
++         memset(adr, 0, from);
++			memset(adr + to, 0, PAGE_CACHE_SIZE - to);
++         kunmap_atomic(adr, KM_USER0);
++
++         DbgPrint("Novfs_a_prepare_write: memset 0x%p\n", adr);
++      }
++		flush_dcache_page(page);
++	   SetPageUptodate(page);
++   }
++
++//   DbgPrint("Novfs_a_prepare_write: return %d\n", retVal);
++	return( retVal );
++}
++
++/*++======================================================================*/
++int Novfs_a_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++
++{
++	int retCode = 0;
++	struct inode *inode = page->mapping->host;
++	loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
++   session_t session=0;
++   PINODE_DATA id;
++   DATA_LIST dlst[1];
++   size_t len = to - offset;
++
++   DbgPrint("Novfs_a_commit_write: File=0x%p Page=0x%p offset=0x%x To=%u filesize=%lld\n", file, page, offset, to, i_size_read(file->f_dentry->d_inode));
++   if (file->f_dentry->d_inode && (id = file->f_dentry->d_inode->u.generic_ip))
++   {
++      session = Scope_Get_SessionId(id->Scope);
++      if (0 == session)
++      {
++         id->Scope = Scope_Get_ScopefromPath( file->f_dentry );
++         session = Scope_Get_SessionId(id->Scope);
++      }
++
++	   if (pos > inode->i_size) 
++	   {
++		   i_size_write(inode, pos);
++	   }
++
++	   if (!PageUptodate(page))
++	   {
++		   pos =  ((loff_t)page->index << PAGE_CACHE_SHIFT) + offset;
++
++		   if (to < offset)
++		   {
++	         return( retCode );
++		   }
++         dlst[0].page   = page;
++         dlst[0].offset = (void *)offset;
++         dlst[0].len    = len;
++         dlst[0].rwflag = DLREAD; 
++
++		   retCode = Novfs_Write_Pages( id->FileHandle, dlst, 1, len, pos, session);
++
++	   } else {	
++		   set_page_dirty(page);
++	   }
++   }
++
++	return( retCode );
++}
++
++/*++======================================================================*/
++ssize_t Novfs_a_direct_IO(int rw, struct kiocb *kiocb, 
++                          const struct iovec *iov,
++                          loff_t offset, 
++                          unsigned long nr_segs)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:        This is a dummy function so that we can allow a file
++ *                to get the direct IO flag set.  Novfs_f_read and 
++ *                Novfs_f_write will do the work.  Maybe not the best
++ *                way to do but it was the easiest to implement.
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   return( -EIO );
++}
++
++/*++======================================================================*/
++int Novfs_i_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   char *path, *buf;
++   ENTRY_INFO info;
++   unsigned long handle;
++   session_t session;
++   int retCode = -EACCES;
++
++
++   DbgPrint("Novfs_i_create: mode=0%o flags=0%o %.*s\n", mode, nd->NDOPENFLAGS, dentry->d_name.len, dentry->d_name.name);
++
++   if ( IS_ROOT(dentry) || /* Root */
++        IS_ROOT(dentry->d_parent) || /* User */
++        IS_ROOT(dentry->d_parent->d_parent) || /* Server */
++        IS_ROOT(dentry->d_parent->d_parent->d_parent) ) /* Volume */
++   {
++      return(-EACCES);
++   }
++
++   if (mode | S_IFREG)
++   {
++      if (dir->u.generic_ip)
++      {
++         session = Scope_Get_SessionId( ((PINODE_DATA)dir->u.generic_ip)->Scope);
++         if (0 == session)
++         {
++            ((PINODE_DATA)dir->u.generic_ip)->Scope = Scope_Get_ScopefromPath( dentry );
++            session = Scope_Get_SessionId(((PINODE_DATA)dir->u.generic_ip)->Scope);
++         }
++
++         buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
++         if (buf)
++         {
++            path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER);
++            if (path)
++            {
++               retCode = Novfs_Open_File(path, nd->NDOPENFLAGS|O_RDWR, &info, &handle, session);
++               if ( !retCode && handle )
++               {
++                  Novfs_Close_File(handle, session);
++                  if (!Novfs_i_mknod(dir, dentry, mode | S_IFREG, 0))
++                  {
++                     if (dentry->d_inode)
++                     {
++                        ((PINODE_DATA)dentry->d_inode->u.generic_ip)->Flags |= UPDATE_INODE;
++                     }
++                  }
++               }
++            }
++            Novfs_Free(buf);
++         }
++      }
++   }
++   return( retCode );
++}
++
++/*++======================================================================*/
++void update_inode(struct inode *Inode, PENTRY_INFO Info)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   static char dbuf[128];
++
++   DbgPrint("update_inode: Inode=0x%x I_ino=%d\n", Inode, Inode->i_ino);
++
++   DbgPrint("update_inode: atime=%s\n", ctime_r(&Info->atime.tv_sec, dbuf));
++   DbgPrint("update_inode: ctime=%s\n", ctime_r(&Info->ctime.tv_sec, dbuf));
++   DbgPrint("update_inode: mtime=%s %d\n", ctime_r(&Info->mtime.tv_sec, dbuf), Info->mtime.tv_nsec);
++   DbgPrint("update_inode: size=%lld\n", Info->size);
++   DbgPrint("update_inode: mode=0%o\n", Info->mode);
++
++   if ( Inode && 
++        ( (Inode->i_size != Info->size) ||
++          (Inode->i_mtime.tv_sec != Info->mtime.tv_sec) ||
++          (Inode->i_mtime.tv_nsec != Info->mtime.tv_nsec) ))
++   {
++      DbgPrint("update_inode: calling invalidate_remote_inode sz  %d %d\n", Inode->i_size, Info->size);
++      DbgPrint("update_inode: calling invalidate_remote_inode sec %d %d\n", Inode->i_mtime.tv_sec, Info->mtime.tv_sec);
++      DbgPrint("update_inode: calling invalidate_remote_inode ns  %d %d\n", Inode->i_mtime.tv_nsec, Info->mtime.tv_nsec);
++      invalidate_remote_inode( Inode );
++   }
++
++   Inode->i_mode  = Info->mode;
++   Inode->i_size  = Info->size;
++   Inode->i_atime = Info->atime;
++   Inode->i_ctime = Info->ctime;
++   Inode->i_mtime = Info->mtime;
++
++   if (Inode->i_size && Inode->i_blksize)
++   {
++      Inode->i_blocks = (u_long)(Info->size >> (loff_t)Inode->i_blkbits);
++      Inode->i_bytes = Info->size & (Inode->i_blksize - 1);
++
++      DbgPrint("update_inode: i_blksize=%d\n", Inode->i_blksize);
++      DbgPrint("update_inode: i_blkbits=%d\n", Inode->i_blkbits);
++      DbgPrint("update_inode: i_blocks=%d\n", Inode->i_blocks);
++      DbgPrint("update_inode: i_bytes=%d\n", Inode->i_bytes);
++   }
++}
++
++/*++======================================================================*/
++struct dentry * Novfs_i_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   struct dentry *retVal = ERR_PTR(-ENOENT);
++   struct dentry *parent;
++   PENTRY_INFO info=NULL;
++   PINODE_DATA id;
++   struct inode *inode=NULL;
++   uid_t uid=current->euid;
++   ino_t ino=0;
++   struct qstr name;
++
++   DbgPrint("Novfs_i_lookup: dir 0x%x %d name %.*s hash %d inode 0x%0p\n", dir, dir->i_ino, dentry->d_name.len, dentry->d_name.name, dentry->d_name.hash, dentry->d_inode);
++
++   if (dir && (id = dir->u.generic_ip) )
++   {
++      retVal = 0;
++      if ( IS_ROOT( dentry ))
++      {
++         DbgPrint("Novfs_i_lookup: Root entry=0x%x\n", Novfs_root);
++         inode = Novfs_root->d_inode;
++         return(0);
++      }
++      else
++      {
++         info = Novfs_Malloc(sizeof(ENTRY_INFO)+PATH_LENGTH_BUFFER, GFP_KERNEL);
++         if (info)
++         {
++            if ( NULL == (retVal = ERR_PTR(verify_dentry( dentry, 1 ))))
++            {
++               name.name = dentry->d_name.name;
++               name.len  = dentry->d_name.len;
++               name.hash = Novfs_internal_hash(&name);
++         
++               if (Novfs_lock_inode_cache( dir ))
++               {
++                  if ( !Novfs_get_entry(dir, &name, &ino, info) )
++                  {
++                     inode = ilookup(dentry->d_sb, ino);
++                     if ( inode )
++                     {
++                        update_inode(inode, info);
++                     }
++                  }
++                  Novfs_unlock_inode_cache( dir );
++               }
++
++               if ( !inode && ino )
++               {
++                  uid = Scope_Get_Uid( id->Scope );
++                  if (Novfs_lock_inode_cache( dir ))
++                  {
++                     inode = Novfs_get_inode(dentry->d_sb, info->mode, 0, uid, ino, &name);
++                     if ( inode )
++                     {
++                        if ( !Novfs_get_entry(dir, &dentry->d_name, &ino, info) )
++                        {
++                           update_inode(inode, info);
++                        }
++                     }
++                     Novfs_unlock_inode_cache( dir );
++                  }
++               }
++            }
++         }
++      }
++   }
++
++   if ( !retVal )
++   {
++      dentry->d_op = &Novfs_dentry_operations;
++      if (inode)
++      {
++         parent = dget_parent(dentry);
++         Novfs_d_add(dentry->d_parent, dentry, inode, 1);
++         dput(parent);
++      }
++      else
++      {
++         d_add( dentry, inode);
++      }
++   }
++
++   if (info) Novfs_Free(info);
++
++   DbgPrint("Novfs_i_lookup: inode=0x%x dentry->d_inode=0x%x return=0x%x\n", dir, dentry->d_inode, retVal);
++
++   return(retVal);
++}
++
++/*++======================================================================*/
++int Novfs_i_unlink(struct inode *dir, struct dentry *dentry)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   int retCode = -ENOENT;
++   struct inode *inode;
++   session_t session;
++   char *path, *buf;
++   uint64_t t64;
++
++   DbgPrint("Novfs_i_unlink: dir=0x%x dir->i_ino=%d %.*s\n", dir, dir->i_ino, dentry->d_name.len, dentry->d_name.name);
++   DbgPrint("Novfs_i_unlink: IS_ROOT(dentry)=%d\n", IS_ROOT(dentry));
++   DbgPrint("Novfs_i_unlink: IS_ROOT(dentry->d_parent)=%d\n", IS_ROOT(dentry->d_parent));
++   DbgPrint("Novfs_i_unlink: IS_ROOT(dentry->d_parent->d_parent)=%d\n", IS_ROOT(dentry->d_parent->d_parent));
++   DbgPrint("Novfs_i_unlink: IS_ROOT(dentry->d_parent->d_parent->d_parent)=%d\n", IS_ROOT(dentry->d_parent->d_parent->d_parent) );
++
++   if ( IS_ROOT(dentry) || /* Root */
++        IS_ROOT(dentry->d_parent) || /* User */
++        (!IS_ROOT(dentry->d_parent->d_parent) && /* Server */
++        IS_ROOT(dentry->d_parent->d_parent->d_parent)) ) /* Volume */
++   {
++      return(-EACCES);
++   }
++
++   inode = dentry->d_inode;
++   if ( inode )
++   {
++      DbgPrint("Novfs_i_unlink: dir=0x%x dir->i_ino=%d inode=0x%x ino=%d\n", dir, dir->i_ino, inode, inode->i_ino);
++      if (inode->u.generic_ip)
++      {
++         session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
++         if (0 == session)
++         {
++            ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( dentry );
++            session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
++         }
++
++         buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
++         if (buf)
++         {
++            path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER);
++            if (path)
++            {
++               DbgPrint("Novfs_i_unlink: path %s mode 0%o\n", path, inode->i_mode);
++               if (IS_ROOT(dentry->d_parent->d_parent))
++               {
++                  retCode = do_logout(&dentry->d_name);
++               }
++               else
++               {
++                  retCode = Novfs_Delete(path, S_ISDIR(inode->i_mode), session);
++               }
++               if ( !retCode || IS_DEADDIR(inode))
++               {
++                  Novfs_remove_inode_entry(dir, &dentry->d_name, 0);
++                  dentry->d_time = 0;
++                  t64 = 0;
++                  Scope_Set_UserSpace(&t64, &t64, &t64, &t64);
++                  retCode = 0;
++               }
++            }
++            Novfs_Free(buf);
++         }
++      }
++   }
++
++   DbgPrint("Novfs_i_unlink: retCode 0x%x\n", retCode);
++   return (retCode);
++}
++
++/*++======================================================================*/
++int Novfs_i_mkdir(struct inode *dir, struct dentry *dentry, int mode)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   char *path, *buf;
++   session_t session;
++   int retCode=0;
++   struct inode *inode;
++   ENTRY_INFO info;
++   uid_t uid;
++
++   DbgPrint("Novfs_i_mkdir: dir=0x%p ino=%d dentry=0x%p %.*s mode=0%o\n", dir, dir->i_ino, dentry, dentry->d_name.len, dentry->d_name.name, mode);
++
++   if ( IS_ROOT(dentry) || /* Root */
++        IS_ROOT(dentry->d_parent) || /* User */
++        IS_ROOT(dentry->d_parent->d_parent) || /* Server */
++        IS_ROOT(dentry->d_parent->d_parent->d_parent) ) /* Volume */
++   {
++      return(-EACCES);
++   }
++
++   mode |= S_IFDIR;
++   mode &= (S_IFMT | S_IRWXU);
++   if ( dir->u.generic_ip )
++   {
++      session = Scope_Get_SessionId( ((PINODE_DATA)dir->u.generic_ip)->Scope);
++      if (0 == session)
++      {
++         ((PINODE_DATA)dir->u.generic_ip)->Scope = Scope_Get_ScopefromPath( dentry );
++         session = Scope_Get_SessionId(((PINODE_DATA)dir->u.generic_ip)->Scope);
++      }
++
++      uid = Scope_Get_Uid( ((PINODE_DATA)dir->u.generic_ip)->Scope);
++      buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
++      if (buf)
++      {
++         path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER);
++         if (path)
++         {
++            DbgPrint("Novfs_i_mkdir: path %s\n", path);
++            retCode = Novfs_Create(path, S_ISDIR(mode), session);
++            if ( !retCode )
++            {
++                  retCode = Novfs_Get_File_Info(path, &info, session );
++                  if ( !retCode )
++                  {
++                     retCode = Novfs_i_mknod(dir, dentry, mode, 0);
++                     inode = dentry->d_inode;
++                     if (inode)
++                     {
++                        update_inode(inode, &info);
++                        ((PINODE_DATA)inode->u.generic_ip)->Flags &= ~UPDATE_INODE;
++
++                        dentry->d_time = jiffies+(File_update_timeout*HZ);
++
++                        Novfs_lock_inode_cache(dir);
++                        if (Novfs_update_entry( dir, &dentry->d_name, 0, &info ))
++                        {
++                           Novfs_add_inode_entry(dir, &dentry->d_name, inode->i_ino, &info);
++                        }
++                        Novfs_unlock_inode_cache(dir);
++                     }
++
++                  }
++               }
++         }
++         Novfs_Free(buf);
++      }
++   }
++
++   return( retCode );
++}
++
++/*++======================================================================*/
++int Novfs_i_rmdir(struct inode *inode, struct dentry *dentry)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   return(Novfs_i_unlink(inode, dentry));
++}
++
++/*++======================================================================*/
++int Novfs_i_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   struct inode *inode=NULL;
++   int retCode = -EACCES;
++   uid_t uid;
++   struct dentry *parent;
++
++   if ( IS_ROOT(dentry) || /* Root */
++        IS_ROOT(dentry->d_parent) || /* User */
++        IS_ROOT(dentry->d_parent->d_parent) || /* Server */
++        IS_ROOT(dentry->d_parent->d_parent->d_parent) ) /* Volume */
++   {
++      return(-EACCES);
++   }
++
++   if ( ((PINODE_DATA)dir->u.generic_ip) )
++   {
++      uid = Scope_Get_Uid( ((PINODE_DATA)dir->u.generic_ip)->Scope);
++      if (mode & (S_IFREG | S_IFDIR))
++      {
++         inode = Novfs_get_inode(dir->i_sb, mode, dev, uid, 0, &dentry->d_name);
++      }
++   }
++
++   if (inode) 
++   {
++      ENTRY_INFO info;
++
++      dentry->d_op = &Novfs_dentry_operations;
++      parent = dget_parent(dentry);
++      Novfs_d_add(parent, dentry, inode, 0);
++      memset(&info, 0, sizeof(info));
++      info.mode = inode->i_mode;
++      Novfs_lock_inode_cache( dir );
++      Novfs_add_inode_entry( dir, &dentry->d_name, inode->i_ino, &info);
++      Novfs_unlock_inode_cache( dir );
++
++      dput(parent);
++      
++      retCode = 0;
++   }
++   DbgPrint("Novfs_i_mknod: return 0x%x\n", retCode);
++   return retCode;
++}
++
++/*++======================================================================*/
++int Novfs_i_rename(struct inode *odir, struct dentry *od, struct inode *ndir, struct dentry *nd)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   int retCode = -ENOTEMPTY;
++   char *newpath, *newbuf, *newcon;
++   char *oldpath, *oldbuf, *oldcon;
++   struct qstr newname, oldname;
++   PENTRY_INFO info=NULL;
++   int oldlen, newlen;
++   session_t session;
++   ino_t ino;
++
++
++   if ( IS_ROOT(od) || /* Root */
++        IS_ROOT(od->d_parent) || /* User */
++        IS_ROOT(od->d_parent->d_parent) || /* Server */
++        IS_ROOT(od->d_parent->d_parent->d_parent) ) /* Volume */
++   {
++      return(-EACCES);
++   }
++
++   DbgPrint("Novfs_i_rename: odir=0x%p ino=%d ndir=0x%p ino=%d\n", odir, odir->i_ino, ndir, ndir->i_ino);
++
++   oldbuf = Novfs_Malloc(PATH_LENGTH_BUFFER*2, GFP_KERNEL);
++   newbuf = oldbuf+PATH_LENGTH_BUFFER;
++   if ( oldbuf && newbuf )
++   {
++      oldpath = Novfs_dget_path(od, oldbuf, PATH_LENGTH_BUFFER);
++      newpath = Novfs_dget_path(nd, newbuf, PATH_LENGTH_BUFFER);
++      if (oldpath && newpath)
++      {
++         oldlen = PATH_LENGTH_BUFFER-(int)(oldpath-oldbuf);
++         newlen = PATH_LENGTH_BUFFER-(int)(newpath-newbuf);
++
++         DbgPrint("Novfs_i_rename: odir=0x%x od->inode=0x%x\n", odir, od->d_inode);
++         DbgPrint("Novfs_i_rename: old path %s\n", oldpath);
++         DbgPrint("Novfs_i_rename: new path %s\n", newpath);
++
++         /*
++          * Check to see if two different servers or different volumes
++          */
++         newcon = strchr(newpath+1, '\\');
++         oldcon = strchr(oldpath+1, '\\');
++         DbgPrint("Novfs_i_rename: newcon=0x%x newpath=0x%x\n", newcon, newpath);
++         DbgPrint("Novfs_i_rename: oldcon=0x%x oldpath=0x%x\n", oldcon, oldpath);
++         retCode = -EXDEV;
++         if ( newcon && oldcon && ((int)(newcon-newpath) == (int)(oldcon-oldpath)) )
++         {
++            newcon = strchr(newcon+1, '\\');
++            oldcon = strchr(oldcon+1, '\\');
++            DbgPrint("Novfs_i_rename2: newcon=0x%x newpath=0x%x\n", newcon, newpath);
++            DbgPrint("Novfs_i_rename2: oldcon=0x%x oldpath=0x%x\n", oldcon, oldpath);
++            if ( newcon && oldcon && ((int)(newcon-newpath) == (int)(oldcon-oldpath)) )
++            {
++               newname.name = newpath;
++               newname.len = (int)(newcon-newpath);
++               newname.hash = 0;
++
++               oldname.name = oldpath;
++               oldname.len = (int)(oldcon-oldpath);
++               oldname.hash = 0;
++               if ( !Novfs_d_strcmp(&newname, &oldname))
++               {
++
++                  if ( od->d_inode && od->d_inode->u.generic_ip )
++                  {
++
++                     if (nd->d_inode && nd->d_inode->u.generic_ip)
++                     {
++                        session = Scope_Get_SessionId(((PINODE_DATA)ndir->u.generic_ip)->Scope);
++                        if (0 == session)
++                        {
++                           ((PINODE_DATA)ndir->u.generic_ip)->Scope = Scope_Get_ScopefromPath( nd );
++                           session = Scope_Get_SessionId(((PINODE_DATA)ndir->u.generic_ip)->Scope);
++                        }
++
++                        retCode = Novfs_Delete(newpath, S_ISDIR(nd->d_inode->i_mode), session);
++                     }
++
++
++                     session = Scope_Get_SessionId(((PINODE_DATA)ndir->u.generic_ip)->Scope);
++                     if (0 == session)
++                     {
++                        ((PINODE_DATA)ndir->u.generic_ip)->Scope = Scope_Get_ScopefromPath( nd );
++                        session = Scope_Get_SessionId(((PINODE_DATA)ndir->u.generic_ip)->Scope);
++                     }
++                     retCode = Novfs_Rename_File(
++                                 S_ISDIR(od->d_inode->i_mode),
++                                 oldpath,
++                                 oldlen-1,
++                                 newpath,
++                                 newlen-1, 
++                                 session);
++
++                     if ( !retCode )
++                     {
++                        info = (PENTRY_INFO)oldbuf;
++                        od->d_time = 0;
++                        Novfs_remove_inode_entry(odir, &od->d_name, 0);
++                        Novfs_Get_File_Info(newpath, info, session);
++                        nd->d_time = jiffies+(File_update_timeout*HZ);
++                        if (Novfs_update_entry(ndir, &nd->d_name, 0, info))
++                        {
++                           if (nd->d_inode && nd->d_inode->i_ino)
++                           {
++                              ino = nd->d_inode->i_ino;
++                           }
++                           else
++                           {
++                              ino = (ino_t)InterlockedIncrement(&Novfs_Inode_Number);
++                           }
++                           Novfs_add_inode_entry(ndir, &nd->d_name, ino, info);
++                        }
++                     }
++                  }
++               }
++            }
++         }
++      }
++   }
++
++   if (oldbuf) Novfs_Free(oldbuf);
++
++   return( retCode );
++}
++
++/*++======================================================================*/
++int Novfs_i_permission(struct inode *inode, int mask)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   int retCode=0;
++
++   return(retCode);
++}
++
++/*++======================================================================*/
++int Novfs_i_setattr(struct dentry *dentry, struct iattr *attr)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   char *path, *buf;
++   struct inode *inode=dentry->d_inode;
++   char atime_buf[32];
++   char mtime_buf[32];
++   char ctime_buf[32];
++   unsigned int ia_valid = attr->ia_valid;
++   session_t session;
++   int retVal = 0;
++
++   if ( IS_ROOT(dentry) || /* Root */
++        IS_ROOT(dentry->d_parent) || /* User */
++        IS_ROOT(dentry->d_parent->d_parent) || /* Server */
++        IS_ROOT(dentry->d_parent->d_parent->d_parent) ) /* Volume */
++   {
++      return(-EACCES);
++   }
++
++   if (inode && inode->u.generic_ip)
++   {
++      session = Scope_Get_SessionId( ((PINODE_DATA)inode->u.generic_ip)->Scope);
++      if (0 == session)
++      {
++         ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( dentry );
++         session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
++      }
++
++      buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
++      if (buf)
++      {
++         path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER);
++         if (path)
++         {
++            strcpy(atime_buf, "Unspecified");
++            strcpy(mtime_buf, "Unspecified");
++            strcpy(ctime_buf, "Unspecified");
++            if (attr->ia_valid & ATTR_ATIME)
++            {
++               ctime_r(&attr->ia_atime.tv_sec, atime_buf);
++            }
++            if (attr->ia_valid & ATTR_MTIME)
++            {
++               ctime_r(&attr->ia_mtime.tv_sec, mtime_buf);
++            }
++            if (attr->ia_valid & ATTR_CTIME)
++            {
++               ctime_r(&attr->ia_ctime.tv_sec, ctime_buf);
++            }
++            /* Removed for Bug 132374. jlt
++            DbgPrint("Novfs_i_setattr: %s\n" \
++                     "   ia_valid:      0x%x\n" \
++                     "   ia_mode:       0%o\n" \
++                     "   ia_uid:        %d\n" \
++                     "   ia_gid:        %d\n" \
++                     "   ia_size:       %lld\n" \
++                     "   ia_atime:      %s\n" \
++                     "   ia_mtime:      %s\n" \
++                     "   ia_ctime:      %s\n" \
++                     "   ia_attr_flags: 0x%x\n",
++               path,
++               attr->ia_valid,
++               attr->ia_mode,
++               attr->ia_uid,
++               attr->ia_gid,
++               attr->ia_size,
++               atime_buf,
++               mtime_buf,
++               ctime_buf,
++               attr->ia_attr_flags);
++            */
++            
++            if ( !(retVal = Novfs_Set_Attr(path, attr, session) ) )
++            {
++               ((PINODE_DATA)inode->u.generic_ip)->Flags |= UPDATE_INODE;
++
++               if (ia_valid & ATTR_ATIME)
++                  inode->i_atime = attr->ia_atime;
++               if (ia_valid & ATTR_MTIME)
++                  inode->i_mtime = attr->ia_mtime;
++               if (ia_valid & ATTR_CTIME)
++                  inode->i_ctime = attr->ia_ctime;
++               if (ia_valid & ATTR_MODE) {
++                  inode->i_mode = attr->ia_mode & (S_IFMT | S_IRWXU);
++               }
++            }
++         }
++      }
++      Novfs_Free(buf);
++   }
++
++   return(retVal);
++}
++
++/*++======================================================================*/
++int Novfs_i_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *kstat)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   int retCode = 0;
++   char atime_buf[32];
++   char mtime_buf[32];
++   char ctime_buf[32];
++   struct inode *inode = dentry->d_inode;
++
++   ENTRY_INFO info;
++   char *path, *buf;
++   session_t session;
++   PINODE_DATA id;
++
++   if ( !IS_ROOT(dentry) &&
++        !IS_ROOT(dentry->d_parent) )
++   {
++      session = 0;
++      id = dentry->d_inode->u.generic_ip;
++
++      if (id && (id->Flags & UPDATE_INODE) )
++      {
++         session = Scope_Get_SessionId( id->Scope );
++
++         if (0 == session)
++         {
++            id->Scope = Scope_Get_ScopefromPath( dentry );
++            session = Scope_Get_SessionId(id->Scope);
++         }
++
++         buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
++         if (buf)
++         {
++            path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER);
++            if (path)
++            {
++               retCode = Novfs_Get_File_Info(path, &info, session );
++               if ( !retCode )
++               {
++                  update_inode(inode, &info);
++                  id->Flags &= ~UPDATE_INODE;
++               }
++            }
++            Novfs_Free(buf);
++         }
++      }
++   }
++
++   kstat->ino     = inode->i_ino;
++   kstat->dev     = inode->i_sb->s_dev;
++   kstat->mode    = inode->i_mode;
++   kstat->nlink   = inode->i_nlink;
++   kstat->uid     = inode->i_uid;
++   kstat->gid     = inode->i_gid;
++   kstat->rdev    = inode->i_rdev;
++   kstat->size    = i_size_read(inode);
++   kstat->atime   = inode->i_atime;
++   kstat->mtime   = inode->i_mtime;
++   kstat->ctime   = inode->i_ctime;
++   kstat->blksize = inode->i_blksize;
++   kstat->blocks  = inode->i_blocks;
++   if (inode->i_bytes)
++   {
++   	kstat->blocks++;
++   }
++   ctime_r(&kstat->atime.tv_sec, atime_buf);
++   ctime_r(&kstat->mtime.tv_sec, mtime_buf);
++   ctime_r(&kstat->ctime.tv_sec, ctime_buf);
++
++
++   DbgPrint("Novfs_i_getattr: 0x%x <%.*s>\n" \
++            "   ino: %d\n" \
++            "   dev: 0x%x\n" \
++            "   mode: 0%o\n" \
++            "   nlink: 0x%x\n" \
++            "   uid: 0x%x\n" \
++            "   gid: 0x%x\n" \
++            "   rdev: 0x%x\n" \
++            "   size: 0x%llx\n" \
++            "   atime: %s\n" \
++            "   mtime: %s\n" \
++            "   ctime: %s\n" \
++            "   blksize: 0x%x\n" \
++            "   blocks: 0x%x\n",
++      retCode, dentry->d_name.len, dentry->d_name.name,
++      kstat->ino,
++      kstat->dev,
++      kstat->mode,
++      kstat->nlink,
++      kstat->uid,
++      kstat->gid,
++      kstat->rdev,
++      kstat->size,
++      atime_buf,
++      mtime_buf,
++      ctime_buf,
++      kstat->blksize,
++      kstat->blocks);
++   return( retCode );
++}
++
++
++/*++======================================================================*/
++int Novfs_i_revalidate(struct dentry *dentry)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++
++   DbgPrint("Novfs_i_revalidate: name %.*s\n", dentry->d_name.len, dentry->d_name.name);
++
++   return(0);
++}
++
++/*++======================================================================*/
++void Novfs_read_inode(struct inode *inode)
++/*
++ *  Arguments:
++ *
++ *  Returns:      nothing
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:  Superblock operation
++ *
++ *=======================================================================-*/
++{
++   DbgPrint( "Novfs_read_inode: 0x%x %d\n", inode, inode->i_ino);
++}
++
++/*++======================================================================*/
++void Novfs_write_inode(struct inode *inode)
++/*
++ *  Arguments:
++ *
++ *  Returns:      nothing
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:  Superblock operation
++ *
++ *=======================================================================-*/
++{
++   DbgPrint( "Novfs_write_inode: Inode=0x%x Ino=%d\n", inode, inode->i_ino);
++}
++
++/*++======================================================================*/
++int Novfs_notify_change(struct dentry *dentry, struct iattr *attr)
++/*
++ *  Arguments:
++ *
++ *  Returns:      error code
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:  Superblock operation
++ *
++ *=======================================================================-*/
++{
++   struct inode *inode = dentry->d_inode;
++
++   DbgPrint( "Novfs_notify_change: Dentry=0x%x Name=%.*s Inode=0x%x Ino=%d ia_valid=0x%x\n", 
++      dentry, dentry->d_name.len, dentry->d_name.name,inode, inode->i_ino, attr->ia_valid);
++   return(0);
++}
++
++/*++======================================================================*/
++void Novfs_clear_inode(struct inode *inode)
++/*
++ * Arguments:    sb - pointer to the super_block
++ *               buf - pointer to the statfs buffer
++ *
++ *  Returns:      0
++ * 
++ *  Abstract:     Called when statfs(2) system called.
++ * 
++ *  Notes:
++ * 
++ *  Environment:  Superblock operation
++ *
++ *========================================================================*/
++{
++   InodeCount--;
++   
++   if ( inode->u.generic_ip )
++   {
++      PINODE_DATA id=inode->u.generic_ip;
++
++      DbgPrint("Novfs_clear_inode: inode=0x%x ino=%d Scope=0x%p Name=%s\n", inode, inode->i_ino, id->Scope, id->Name);
++
++      Novfs_free_inode_cache(inode);
++
++      down( &InodeList_lock );
++      list_del( &id->IList );
++      up( &InodeList_lock );
++
++
++      Novfs_Free(inode->u.generic_ip);
++      inode->u.generic_ip = NULL;
++
++      remove_inode_hash( inode );
++
++   }
++   else
++   {
++      DbgPrint("Novfs_clear_inode: inode=0x%x ino=%d\n", inode, inode->i_ino);
++   }
++}
++
++/*++======================================================================*/
++int 
++NO_TRACE
++Novfs_show_options( struct seq_file *s, struct vfsmount *m )
++/*
++ * Arguments:    
++ *
++ *  Returns:      0
++ * 
++ *  Abstract:     Called when /proc/mounts is read
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   char *buf, *path, *tmp;
++
++   buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
++   if (buf)
++   {
++      path = d_path(m->mnt_root, m, buf, PATH_LENGTH_BUFFER);
++      if (path)
++      {
++         if ( !Novfs_CurrentMount || (Novfs_CurrentMount && strcmp(Novfs_CurrentMount, path)))
++         {
++            DbgPrint("Novfs_show_options: %.*s %.*s %s\n", m->mnt_root->d_name.len, m->mnt_root->d_name.name, 
++               m->mnt_mountpoint->d_name.len, m->mnt_mountpoint->d_name.name, path);
++            tmp = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER - (int)(path-buf), GFP_KERNEL);
++            if (tmp)
++            {
++               strcpy(tmp, path);
++               path = Novfs_CurrentMount;
++               Novfs_CurrentMount = tmp;
++               Daemon_SetMountPoint( Novfs_CurrentMount );
++
++               if (path)
++               {
++                  Novfs_Free(path);
++               }
++            }
++         }
++      }
++      Novfs_Free( buf );
++   }
++   return(0);
++}
++
++/*++======================================================================*/
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
++int Novfs_statfs(struct dentry *de, struct kstatfs *buf)
++#else
++int Novfs_statfs(struct super_block *sb, struct kstatfs *buf)
++#endif
++/*
++ * Arguments:    sb - pointer to the super_block
++ *               buf - pointer to the statfs buffer
++ *
++ *  Returns:      0
++ * 
++ *  Abstract:     Called when statfs(2) system called.
++ * 
++ *  Notes:
++ * 
++ *  Environment:  Superblock operation
++ *
++ *========================================================================*/
++{
++   uint64_t td, fd, te, fe;
++ 
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
++   struct super_block *sb = de->d_sb;
++#endif
++
++   UNUSED_VARIABLE(sb);
++
++   DbgPrint("Novfs_statfs:\n");
++
++   td = fd = te = fe = 0;
++
++   Scope_Get_UserSpace( &td, &fd, &te, &fe );
++
++   DbgPrint("td=%llu\n", td);
++   DbgPrint("fd=%llu\n", fd);
++   DbgPrint("te=%llu\n", te);
++   DbgPrint("fe=%llu\n", fd);
++
++   buf->f_type = sb->s_magic;
++   buf->f_bsize = sb->s_blocksize;
++   buf->f_namelen = NW_MAX_PATH_LENGTH;
++   buf->f_blocks = (sector_t)(td + (uint64_t)(sb->s_blocksize-1)) >> (uint64_t)sb->s_blocksize_bits;
++   buf->f_bfree = (sector_t)fd >> (uint64_t)sb->s_blocksize_bits;
++   buf->f_bavail = (sector_t)buf->f_bfree;
++   buf->f_files = (sector_t)te;
++   buf->f_ffree = (sector_t)fe;
++   buf->f_frsize = sb->s_blocksize;
++   if (te > 0xffffffff)
++      buf->f_files = 0xffffffff;
++
++   if (fe > 0xffffffff)
++      buf->f_ffree = 0xffffffff;
++
++
++   DbgPrint("f_type:    0x%x\n", buf->f_type);
++   DbgPrint("f_bsize:   %u\n", buf->f_bsize);
++   DbgPrint("f_namelen: %d\n", buf->f_namelen);
++   DbgPrint("f_blocks:  %llu\n", buf->f_blocks);
++   DbgPrint("f_bfree:   %llu\n", buf->f_bfree);
++   DbgPrint("f_bavail:  %llu\n", buf->f_bavail);
++   DbgPrint("f_files:   %llu\n", buf->f_files);
++   DbgPrint("f_ffree:   %llu\n", buf->f_ffree);
++   DbgPrint("f_frsize:  %u\n", buf->f_frsize);
++
++   return 0;
++}
++
++/*++======================================================================*/
++struct inode *Novfs_get_inode(struct super_block *sb, int mode, int dev, uid_t Uid, ino_t ino, struct qstr *name)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *=======================================================================-*/
++{
++   struct inode * inode = new_inode(sb);
++
++   if (inode) 
++   {
++      InodeCount++;
++      inode->i_mode = mode;
++      inode->i_uid = Uid;
++      inode->i_gid = 0;
++      inode->i_blksize = sb->s_blocksize;
++      inode->i_blkbits = sb->s_blocksize_bits;
++      inode->i_blocks = 0;
++      inode->i_rdev = 0;
++      inode->i_ino = (ino) ? ino: (ino_t)InterlockedIncrement(&Novfs_Inode_Number);
++      inode->i_mapping->a_ops = &Novfs_aops;
++      inode->i_atime.tv_sec = 0;
++      inode->i_atime.tv_nsec = 0;
++      inode->i_mtime = inode->i_ctime = inode->i_atime;
++
++      DbgPrint("Novfs_get_inode: Inode=0x%p I_ino=%d len=%d\n", inode, inode->i_ino, name->len);
++
++      if (NULL != (inode->u.generic_ip = Novfs_Malloc(sizeof(INODE_DATA)+name->len, GFP_KERNEL)))
++      {
++         PINODE_DATA id;
++         id = inode->u.generic_ip;
++
++         DbgPrint("Novfs_get_inode: u.generic_ip 0x%p\n", id);
++
++         id->Scope = NULL;
++         id->Flags = 0;
++         id->Inode = inode;
++         INIT_LIST_HEAD( &id->DirCache );
++         init_MUTEX( &id->DirCacheLock );
++
++         id->FileHandle = 0;
++         id->CacheFlag  = 0;
++ 
++         down( &InodeList_lock );
++
++         list_add_tail(&id->IList, &InodeList);
++         up( &InodeList_lock );
++
++         id->Name[0] = '\0';
++
++         memcpy(id->Name, name->name, name->len);
++         id->Name[name->len] = '\0';
++
++         DbgPrint("Novfs_get_inode: name %s\n", id->Name);
++      }
++
++		insert_inode_hash(inode);
++
++      switch (mode & S_IFMT) {
++
++      case S_IFREG:
++         inode->i_op = &Novfs_file_inode_operations;
++         inode->i_fop = &Novfs_file_operations;
++         break;
++
++      case S_IFDIR:
++         inode->i_op = &Novfs_inode_operations;
++         inode->i_fop = &Novfs_dir_operations;
++         inode->i_blksize = 0;
++         inode->i_blkbits = 0;
++         break;
++
++      default:
++         init_special_inode(inode, mode, dev);
++         break;
++      }
++
++      DbgPrint("Novfs_get_inode: size=%lld\n", inode->i_size);
++      DbgPrint("Novfs_get_inode: mode=0%o\n", inode->i_mode);
++      DbgPrint("Novfs_get_inode: i_blksize=%d\n", inode->i_blksize);
++      DbgPrint("Novfs_get_inode: i_blkbits=%d\n", inode->i_blkbits);
++      DbgPrint("Novfs_get_inode: i_blocks=%d\n", inode->i_blocks);
++      DbgPrint("Novfs_get_inode: i_bytes=%d\n", inode->i_bytes);
++   }
++
++   DbgPrint("Novfs_get_inode: 0x%p %d\n", inode, inode->i_ino);
++   return (inode);
++}
++
++/*++======================================================================*/
++int Novfs_fill_super (struct super_block *SB, void *Data, int Silent)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   struct inode * inode;
++   struct dentry *server, *tree;
++   struct qstr name;
++/*   PINODE_DATA id;
++*/
++   ENTRY_INFO info;
++
++   UNUSED_VARIABLE(Data);
++   UNUSED_VARIABLE(Silent);
++
++   SB->s_blocksize = PAGE_CACHE_SIZE;
++   SB->s_blocksize_bits = PAGE_CACHE_SHIFT;
++   SB->s_maxbytes = 0xFFFFFFFFFFFFFFFFULL;	/* Max file size */
++   SB->s_op = &Novfs_ops;
++   SB->s_flags |= (MS_NODIRATIME | MS_NODEV | MS_POSIXACL);
++   SB->s_magic = NOVFS_MAGIC;
++
++   
++   name.len = 1;
++   name.name = "/";
++
++   inode = Novfs_get_inode(SB, S_IFDIR | 0777, 0, 0, 0, &name);
++   if (!inode)
++   {
++      return( -ENOMEM );
++   }
++   
++   Novfs_root = d_alloc_root(inode);
++
++   if (!Novfs_root)
++   {
++      iput(inode);
++      return( -ENOMEM );
++   }
++   Novfs_root->d_time = jiffies+(File_update_timeout*HZ);
++
++   inode->i_atime = 
++   inode->i_ctime = 
++   inode->i_mtime = CURRENT_TIME;
++
++
++   SB->s_root = Novfs_root;
++
++   DbgPrint( "Novfs_fill_super: root 0x%x\n", Novfs_root);
++
++   if (Novfs_root)
++   {
++      Novfs_root->d_op = &Novfs_dentry_operations;
++
++      name.name = SERVER_DIRECTORY_NAME;
++      name.len  = strlen(SERVER_DIRECTORY_NAME);
++      name.hash = Novfs_internal_hash( &name );
++
++      inode = Novfs_get_inode(SB, S_IFDIR | 0777, 0, 0, 0, &name);
++      if (inode)
++      {
++         info.mode = inode->i_mode;
++         info.namelength = 0;
++         inode->i_size  = info.size = 0;
++         inode->i_uid   = info.uid  = 0;
++         inode->i_gid   = info.gid  = 0;
++         inode->i_atime = info.atime =
++         inode->i_ctime = info.ctime =
++         inode->i_mtime = info.mtime = CURRENT_TIME;
++
++         server = d_alloc(Novfs_root, &name);
++         if (server)
++         {
++            server->d_op = &Novfs_dentry_operations;
++            server->d_time = 0xffffffff;
++            d_add(server, inode);
++            DbgPrint( "Novfs_fill_super: d_add %s 0x%x\n", SERVER_DIRECTORY_NAME, server);
++            Novfs_add_inode_entry(Novfs_root->d_inode, &name, inode->i_ino, &info);
++         }
++      }
++
++      name.name = TREE_DIRECTORY_NAME;
++      name.len  = strlen(TREE_DIRECTORY_NAME);
++      name.hash =  Novfs_internal_hash( &name );
++
++      inode = Novfs_get_inode(SB, S_IFDIR | 0777, 0, 0, 0, &name);
++      if (inode)
++      {
++         info.mode = inode->i_mode;
++         info.namelength = 0;
++         inode->i_size  = info.size = 0;
++         inode->i_uid   = info.uid  = 0;
++         inode->i_gid   = info.gid  = 0;
++         inode->i_atime = info.atime =
++         inode->i_ctime = info.ctime =
++         inode->i_mtime = info.mtime = CURRENT_TIME;
++         tree = d_alloc(Novfs_root, &name);
++         if (tree)
++         {
++            tree->d_op = &Novfs_dentry_operations;
++            tree->d_time = 0xffffffff;
++
++            d_add(tree, inode);
++            DbgPrint( "Novfs_fill_super: d_add %s 0x%x\n", TREE_DIRECTORY_NAME, tree);
++            Novfs_add_inode_entry(Novfs_root->d_inode, &name, inode->i_ino, &info);
++         }
++      }
++   }
++
++   return( 0 );
++}
++
++/*++======================================================================*/
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
++int Novfs_get_sb(struct file_system_type *Fstype, int Flags, const char *Dev_name, void *Data, struct vfsmount *Mnt)
++#else
++struct super_block * Novfs_get_sb(struct file_system_type *Fstype, int Flags, const char *Dev_name, void *Data)
++#endif
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
++   int sb;
++#else
++    struct super_block *sb;
++#endif
++
++   UNUSED_VARIABLE(Dev_name);
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
++    sb = get_sb_nodev(Fstype, Flags, Data, Novfs_fill_super, Mnt);
++#else
++    sb = get_sb_nodev(Fstype, Flags, Data, Novfs_fill_super);
++#endif
++
++   DbgPrint( "Novfs_get_sb: sb=0x%x Fstype=0x%x Dev_name=%s\n", sb, Fstype, Dev_name);
++
++   return (sb );
++}
++
++/*++======================================================================*/
++void Novfs_kill_sb(struct super_block *SB)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   kill_litter_super(SB);
++}
++
++/*++======================================================================*/
++ssize_t Novfs_Control_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   ssize_t   retval=0;
++
++   UNUSED_VARIABLE(file);
++   UNUSED_VARIABLE(buf);
++   UNUSED_VARIABLE(nbytes);
++   UNUSED_VARIABLE(ppos);
++
++   DbgPrint( "Novfs_Control_read: kernel_locked 0x%x\n", kernel_locked());
++
++   return retval;
++}
++
++/*++======================================================================*/
++ssize_t Novfs_Control_write(struct file * file, const char * buf, size_t nbytes, loff_t *ppos)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   ssize_t   retval=0;
++
++   UNUSED_VARIABLE(file);
++   UNUSED_VARIABLE(buf);
++   UNUSED_VARIABLE(nbytes);
++   UNUSED_VARIABLE(ppos);
++
++   DbgPrint( "Novfs_Control_write: kernel_locked 0x%x\n", kernel_locked());
++   if (buf && nbytes)
++   {
++   }
++   
++   return(retval);
++}
++
++/*++======================================================================*/
++int Novfs_Control_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   int retval=0;
++
++   UNUSED_VARIABLE(inode);
++   UNUSED_VARIABLE(file);
++   UNUSED_VARIABLE(cmd);
++   UNUSED_VARIABLE(arg);
++
++   DbgPrint( "Novfs_Control_ioctl: kernel_locked 0x%x\n", kernel_locked());
++
++   return(retval);
++}
++
++/*++======================================================================*/
++int __init init_novfs (void)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   int retCode;
++   
++
++   retCode = Init_Procfs_Interface();
++
++   init_profile();
++
++   if ( !retCode )
++   {
++      DbgPrint("init_novfs: %s %s %s\n", __DATE__, __TIME__, NOVFS_VERSION_STRING);
++      Init_Daemon_Queue();
++      Scope_Init();
++      retCode = register_filesystem(&Novfs_fs_type);
++      if ( retCode )
++      {
++         Uninit_Procfs_Interface();
++         Uninit_Daemon_Queue();
++         Scope_Uninit();
++      }
++   }
++   return(retCode);
++}
++
++/*++======================================================================*/
++void __exit exit_novfs(void)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   printk( KERN_INFO "exit_novfs\n");
++
++   Scope_Uninit();
++   printk( KERN_INFO "exit_novfs after Scope_Uninit\n");
++
++   Uninit_Daemon_Queue();
++   printk( KERN_INFO "exit_novfs after Uninit_Daemon_Queue\n");
++
++   uninit_profile();
++   printk( KERN_INFO "exit_novfs after uninit_profile\n");
++
++   Uninit_Procfs_Interface();
++   printk( KERN_INFO "exit_novfs Uninit_Procfs_Interface\n");
++
++   unregister_filesystem(&Novfs_fs_type);
++   printk( KERN_INFO "exit_novfs: Exit\n");
++
++   if (Novfs_CurrentMount)
++   {
++      Novfs_Free(Novfs_CurrentMount);
++      Novfs_CurrentMount = NULL;
++   }
++}
++
++/*++======================================================================*/
++int Novfs_lock_inode_cache( struct inode *i )
++/*
++ *
++ *  Arguments:   struct inode *i - pointer to directory inode
++ *
++ *  Returns:     0 - locked
++ *              -1 - not locked
++ *
++ *  Abstract:    Locks the inode cache.
++ *
++ *  Notes:       
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PINODE_DATA id;
++   int retVal = 0;
++
++   DbgPrint("Novfs_lock_inode_cache: 0x%p\n", i);
++   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
++   {
++      down( &id->DirCacheLock );
++      retVal = 1;
++   }
++   DbgPrint("Novfs_lock_inode_cache: return %d\n", retVal);
++   return( retVal );
++}
++
++/*++======================================================================*/
++void Novfs_unlock_inode_cache( struct inode *i )
++/*
++ *  Arguments:   struct inode *i - pointer to directory inode
++ *
++ *  Returns:     nothing
++ * 
++ *  Abstract:    Unlocks inode cache.
++ * 
++ *  Notes:       
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PINODE_DATA id;
++
++   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
++   {
++      up( &id->DirCacheLock );
++   }
++}
++
++/*++======================================================================*/
++int Novfs_enumerate_inode_cache( struct inode *i, struct list_head **iteration, ino_t *ino, PENTRY_INFO info)
++/*
++ *  Arguments:   struct inode *i - pointer to directory inode
++ *
++ *  Returns:     0 - item found
++ *              -1 - done
++ *
++ *  Abstract:    Unlocks inode cache.
++ *
++ *  Notes:       DirCacheLock should be held before calling this routine.
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PINODE_DATA id;
++   PDIR_CACHE dc;
++   struct list_head *l=NULL;
++   int retVal = -1;
++
++
++   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
++   {
++      if ( (NULL == iteration) || (NULL == *iteration) )
++      {
++         l = id->DirCache.next;
++      }
++      else
++      {
++         l = *iteration;
++      }
++
++      if (l == &id->DirCache)
++      {
++         l = NULL;
++      }
++      else
++      {
++         dc = list_entry(l, DIR_CACHE, list);
++
++         *ino = dc->ino;
++         info->type = 0;
++         info->mode = dc->mode;
++         info->size = dc->size;
++         info->atime = dc->atime;
++         info->mtime = dc->mtime;
++         info->ctime = dc->ctime;
++         info->namelength = dc->nameLen;
++         memcpy(info->name, dc->name, dc->nameLen);
++         info->name[dc->nameLen] = '\0';
++         retVal = 0;
++
++         l = l->next;
++      }
++   }
++   *iteration = l;
++   return( retVal );
++}
++
++/*++======================================================================*/
++int Novfs_get_entry( struct inode *i, struct qstr *name, ino_t *ino, PENTRY_INFO info)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:       DirCacheLock should be held before calling this routine.
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PINODE_DATA id;
++   PDIR_CACHE dc;
++   int retVal = -1;
++   char *n="<NULL>";
++   int nl=6;
++
++   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
++   {
++      if (name && name->len)
++      {
++         n = (char *)name->name;
++         nl = name->len;
++      }
++      DbgPrint("Novfs_get_entry:\n" \
++               "   inode: 0x%p\n" \
++               "   name:  %.*s\n" \
++               "   ino:   %d\n",
++         i, nl, n, *ino);
++
++      dc = Novfs_lookup_inode_cache(i, name, *ino);
++      if (dc)
++      {
++         dc->flags |= ENTRY_VALID;
++         retVal = 0;
++         *ino = dc->ino;
++         info->type = 0;
++         info->mode = dc->mode;
++         info->size = dc->size;
++         info->atime = dc->atime;
++         info->mtime = dc->mtime;
++         info->ctime = dc->ctime;
++         info->namelength = dc->nameLen;
++         memcpy(info->name, dc->name, dc->nameLen);
++         info->name[dc->nameLen] = '\0';
++         retVal = 0;
++      }
++   }
++   DbgPrint("Novfs_get_entry: return %d\n", retVal);
++   return( retVal );
++}
++
++int Novfs_get_entry_by_pos( struct inode *i, loff_t pos, ino_t* ino, PENTRY_INFO info)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:       DirCacheLock should be held before calling this routine.
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++	int retVal = -1;
++	loff_t count = 0;
++	loff_t i_pos = pos - 2;
++	struct list_head *inter = NULL;
++	while( !Novfs_enumerate_inode_cache(i, &inter, ino, info))
++	{
++		DbgPrint("Novfs_dir_readdir : Novfs_get_entry_by_pos : info->name = %s\n", info->name);
++		if(count == i_pos)
++		{
++			retVal = 0;
++			break;
++		}
++		else
++			count++;
++	}
++
++	return retVal;
++}
++
++/*++======================================================================*/
++int Novfs_get_entry_time( struct inode *i, struct qstr *name, ino_t *ino, PENTRY_INFO info, u64 *EntryTime)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:       DirCacheLock should be held before calling this routine.
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PINODE_DATA id;
++   PDIR_CACHE dc;
++   int retVal = -1;
++   char *n="<NULL>";
++   int nl=6;
++
++   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
++   {
++      if (name && name->len)
++      {
++         n = (char *)name->name;
++         nl = name->len;
++      }
++      DbgPrint("Novfs_get_entry:\n" \
++               "   inode: 0x%p\n" \
++               "   name:  %.*s\n" \
++               "   ino:   %d\n",
++         i, nl, n, *ino);
++
++      dc = Novfs_lookup_inode_cache(i, name, *ino);
++      if (dc)
++      {
++         retVal = 0;
++         *ino = dc->ino;
++         info->type = 0;
++         info->mode = dc->mode;
++         info->size = dc->size;
++         info->atime = dc->atime;
++         info->mtime = dc->mtime;
++         info->ctime = dc->ctime;
++         info->namelength = dc->nameLen;
++         memcpy(info->name, dc->name, dc->nameLen);
++         info->name[dc->nameLen] = '\0';
++         if (EntryTime)
++         {
++            *EntryTime = dc->jiffies;
++         }
++         retVal = 0;
++      }
++   }
++   DbgPrint("Novfs_get_entry: return %d\n", retVal);
++   return( retVal );
++}
++
++/*++======================================================================*/
++int Novfs_get_remove_entry( struct inode *i, ino_t *ino, PENTRY_INFO info)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:    This routine will return the first entry on the list 
++ *               and then remove it.
++ *
++ *  Notes:       DirCacheLock should be held before calling this routine.
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PINODE_DATA id;
++   PDIR_CACHE dc;
++   struct list_head *l=NULL;
++   int retVal = -1;
++
++
++   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
++   {
++      l = id->DirCache.next;
++
++      if (l != &id->DirCache)
++      {
++         dc = list_entry(l, DIR_CACHE, list);
++
++         *ino = dc->ino;
++         info->type = 0;
++         info->mode = dc->mode;
++         info->size = dc->size;
++         info->atime = dc->atime;
++         info->mtime = dc->mtime;
++         info->ctime = dc->ctime;
++         info->namelength = dc->nameLen;
++         memcpy(info->name, dc->name, dc->nameLen);
++         info->name[dc->nameLen] = '\0';
++         retVal = 0;
++
++         list_del( &dc->list );
++         Novfs_Free( dc );
++         DCCount--;
++
++      }
++   }
++   return( retVal );
++}
++
++/*++======================================================================*/
++void Novfs_invalidate_inode_cache( struct inode *i )
++/*
++ *  Arguments:   struct inode *i - pointer to directory inode
++ *
++ *  Returns:     nothing
++ * 
++ *  Abstract:    Marks all entries in the directory cache as invalid.
++ * 
++ *  Notes:       DirCacheLock should be held before calling this routine.
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PINODE_DATA id;
++   PDIR_CACHE dc;
++   struct list_head *l;
++
++   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
++   {
++      list_for_each(l, &id->DirCache)
++      {
++         dc = list_entry(l, DIR_CACHE, list);
++         dc->flags &= ~ENTRY_VALID;
++      }
++   }
++}
++
++/*++======================================================================*/
++PDIR_CACHE Novfs_lookup_inode_cache( struct inode *i, struct qstr *name, ino_t ino )
++/*
++ *  Arguments:   struct inode *i - pointer to directory inode
++ *               struct qstr *name - pointer to name
++ *               ino_t - inode number
++ *
++ *  Returns:     DIR_CACHE entry if match
++ *               NULL - if there is no match.
++ *
++ *  Abstract:    Checks a inode directory to see if there are any enties
++ *               matching name or ino.  If name is specified then ino is 
++ *               not used.  ino is use if name is not specified.
++ *
++ *  Notes:       DirCacheLock should be held before calling this routine.
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PINODE_DATA id;
++   PDIR_CACHE dc, retVal=NULL;
++   struct list_head *l;
++   char *n="<NULL>";
++   int nl=6;
++   int hash=0;
++
++   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
++   {
++      if (name && name->name)
++      {
++         nl = name->len;
++         n = (char *)name->name;
++         hash = name->hash;
++      }
++      DbgPrint("Novfs_lookup_inode_cache:\n" \
++               "   inode: 0x%p\n" \
++               "   name:  %.*s\n" \
++               "   hash:  0x%x\n" \
++               "   len:   %d\n" \
++               "   ino:   %d\n",
++         i, nl, n, hash, nl, ino);
++
++      list_for_each(l, &id->DirCache)
++      {
++         dc = list_entry(l, DIR_CACHE, list);
++         if (name)
++         {
++            
++/*         DbgPrint("Novfs_lookup_inode_cache: 0x%p\n" \
++                  "   ino:   %d\n" \
++                  "   hash:  0x%x\n" \
++                  "   len:   %d\n" \
++                  "   name:  %.*s\n",
++            dc, dc->ino, dc->hash, dc->nameLen, dc->nameLen, dc->name);
++*/
++            if ( (name->hash == dc->hash) &&
++                 (name->len == dc->nameLen) &&
++                 (0 == memcmp(name->name, dc->name, name->len)) )
++            {
++               retVal = dc;
++               break;
++            }
++         }
++         else
++         {
++            if (ino == dc->ino)
++            {
++               retVal = dc;
++               break;
++            }
++         }
++      }
++   }
++
++   DbgPrint("Novfs_lookup_inode_cache: return 0x%p\n", retVal);
++   return( retVal );
++}
++
++/*++======================================================================*/
++int Novfs_lookup_validate( struct inode *i, struct qstr *name, ino_t ino )
++/*
++ *  Arguments:   struct inode *i - pointer to directory inode
++ *               struct qstr *name - pointer to name
++ *               ino_t - inode number
++ *
++ *  Returns:     0 if found
++ *               !0 if not found
++ *
++ *  Abstract:    Checks a inode directory to see if there are any enties
++ *               matching name or ino.  If entry is found the valid bit
++ *               is set.
++ *
++ *  Notes:       DirCacheLock should be held before calling this routine.
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PINODE_DATA id;
++   PDIR_CACHE dc;
++   int retVal = -1;
++   char *n="<NULL>";
++   int nl=6;
++
++   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
++   {
++      if (name && name->len)
++      {
++         n = (char *)name->name;
++         nl = name->len;
++      }
++      DbgPrint("Novfs_update_entry:\n" \
++               "   inode: 0x%p\n" \
++               "   name:  %.*s\n" \
++               "   ino:   %d\n",
++         i, nl, n, ino);
++
++      dc = Novfs_lookup_inode_cache( i, name, ino );
++      if (dc)
++      {
++         dc->flags |= ENTRY_VALID;
++         retVal = 0;
++      }
++   }
++   return( retVal );
++}
++
++/*++======================================================================*/
++int Novfs_add_inode_entry( 
++   struct inode    *i, 
++   struct qstr     *name, 
++   ino_t            ino, 
++   PENTRY_INFO      info)
++/*
++ *  Arguments:
++ *
++ *  Returns:     -ENOMEM - alloc error.
++ *                0 - success.
++ *
++ *  Abstract:    Added entry to directory cache.
++ *
++ *  Notes:       DirCacheLock should be held before calling this routine.
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PINODE_DATA id;
++   PDIR_CACHE new;
++   int retVal = -ENOMEM;
++
++   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
++   {
++      new = Novfs_Malloc(sizeof(DIR_CACHE)+name->len, GFP_KERNEL);
++      if (new)
++      {
++         DCCount++;
++         DbgPrint("Novfs_add_inode_entry:\n" \
++                  "   inode: 0x%p\n" \
++                  "   id:    0x%p\n" \
++                  "   DC:    0x%p\n" \
++                  "   new:   0x%p\n" \
++                  "   name:  %.*s\n" \
++                  "   ino:   %d\n"   \
++                  "   size:  %lld\n" \
++                  "   mode:  0x%x\n",
++            i, id, &id->DirCache, new, name->len, name->name, ino, info->size, info->mode);
++
++         retVal = 0;
++         new->flags   = ENTRY_VALID;
++         new->jiffies = get_jiffies_64();
++         new->size    = info->size;
++         new->mode    = info->mode;
++         new->atime   = info->atime;
++         new->mtime   = info->mtime;
++         new->ctime   = info->ctime;
++         new->ino     = ino;
++         new->hash    = name->hash;
++         new->nameLen = name->len;
++         memcpy(new->name, name->name, name->len);
++         new->name[new->nameLen] = '\0';
++         list_add(&new->list, &id->DirCache);
++
++/*         list_for_each(l, &id->DirCache)
++         {
++            dc = list_entry(l, DIR_CACHE, list);
++            if ( dc->hash > new->hash )
++            {
++               break;
++            }
++         }
++
++         DbgPrint("Novfs_add_inode_entry: adding 0x%p to 0x%p\n", new, l);
++         list_add(&new->list, l);
++*/
++      }
++   }
++   return( retVal );
++}
++
++/*++======================================================================*/
++int Novfs_update_entry( struct inode *i, struct qstr *name, ino_t ino, PENTRY_INFO info)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ * 
++ *  Abstract:
++ * 
++ *  Notes:       DirCacheLock should be held before calling this routine.
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PINODE_DATA id;
++   PDIR_CACHE dc;
++   int retVal = -1;
++   char *n="<NULL>";
++   int nl=6;
++   char atime_buf[32];
++   char mtime_buf[32];
++   char ctime_buf[32];
++
++   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
++   {
++
++      if (name && name->len)
++      {
++         n = (char *)name->name;
++         nl = name->len;
++      }
++      ctime_r(&info->atime.tv_sec, atime_buf);
++      ctime_r(&info->mtime.tv_sec, mtime_buf);
++      ctime_r(&info->ctime.tv_sec, ctime_buf);
++      DbgPrint("Novfs_update_entry:\n" \
++               "   inode: 0x%p\n" \
++               "   name:  %.*s\n" \
++               "   ino:   %d\n" \
++               "   size:  %lld\n" \
++               "   atime: %s\n" \
++               "   mtime: %s\n" \
++               "   ctime: %s\n",
++         i, nl, n, ino, info->size, atime_buf, mtime_buf, ctime_buf);
++
++
++      dc = Novfs_lookup_inode_cache(i, name, ino);
++      if (dc)
++      {
++         retVal = 0;
++         dc->flags   = ENTRY_VALID;
++         dc->jiffies = get_jiffies_64();
++         dc->size    = info->size;
++         dc->mode    = info->mode;
++         dc->atime   = info->atime;
++         dc->mtime   = info->mtime;
++         dc->ctime   = info->ctime;
++
++         ctime_r(&dc->atime.tv_sec, atime_buf);
++         ctime_r(&dc->mtime.tv_sec, mtime_buf);
++         ctime_r(&dc->ctime.tv_sec, ctime_buf);
++         DbgPrint("Novfs_update_entry entry: 0x%x\n" \
++                  "   flags:   0x%x\n" \
++                  "   jiffies: %lld\n" \
++                  "   ino:     %d\n"   \
++                  "   size:    %lld\n" \
++                  "   mode:    0%o\n"  \
++                  "   atime:   %s\n"   \
++                  "   mtime:   %s %d\n"   \
++                  "   ctime:   %s\n"   \
++                  "   hash:    0x%x\n" \
++                  "   nameLen: %d\n"   \
++                  "   name:    %s\n",
++            dc, dc->flags, dc->jiffies, dc->ino, dc->size, dc->mode,
++            atime_buf, mtime_buf, dc->mtime.tv_nsec, ctime_buf, dc->hash, dc->nameLen, dc->name);
++      }
++   }
++   DbgPrint("Novfs_update_entry: return %d\n", retVal);
++   return( retVal );
++}
++
++/*++======================================================================*/
++void Novfs_remove_inode_entry( struct inode *i, struct qstr *name, ino_t ino)
++/*
++ *  Arguments:
++ *
++ *  Returns:     nothing
++ *
++ *  Abstract:    Removes entry from directory cache.  You can specify a name
++ *               or an inode number.
++ *
++ *  Notes:       DirCacheLock should be held before calling this routine.
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PINODE_DATA id;
++   PDIR_CACHE dc;
++   char *n="<NULL>";
++   int nl=6;
++
++   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
++   {
++      dc = Novfs_lookup_inode_cache( i, name, ino );
++      if (dc)
++      {
++         if (name && name->name)
++         {
++            nl = name->len;
++            n = (char *)name->name;
++         }
++         DbgPrint("Novfs_remove_inode_entry:\n" \
++                  "   inode: 0x%p\n" \
++                  "   id:    0x%p\n" \
++                  "   DC:    0x%p\n" \
++                  "   name:  %.*s\n" \
++                  "   ino:   %d\n" \
++                  "   entry: 0x%p\n" \
++                  "      name: %.*s\n"\
++                  "      ino:  %d\n" \
++                  "      next: 0x%p\n" \
++                  "      prev: 0x%p\n",
++            i, id, &id->DirCache, nl, n, ino, dc, dc->nameLen, dc->name, dc->ino, dc->list.next, dc->list.prev);
++         list_del( &dc->list );
++         Novfs_Free( dc );
++         DCCount--;
++
++      }
++   }
++}
++
++/*++======================================================================*/
++void Novfs_free_invalid_entries( struct inode *i )
++/*
++ *  Arguments:   struct inode *i - pointer to directory inode.
++ *
++ *  Returns:     nothing
++ * 
++ *  Abstract:    Frees all invalid entries in the directory cache.
++ * 
++ *  Notes:       DirCacheLock should be held before calling this routine.
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PINODE_DATA id;
++   PDIR_CACHE dc;
++   struct list_head *l;
++
++   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
++   {
++      list_for_each( l, &id->DirCache )
++      {
++         dc = list_entry( l, DIR_CACHE, list );
++         if ( 0 == (dc->flags & ENTRY_VALID) )
++         {
++            DbgPrint("Novfs_free_invalid_entries:\n" \
++                     "   inode: 0x%p\n" \
++                     "   id:    0x%p\n" \
++                     "   entry:    0x%p\n" \
++                     "   name:  %.*s\n" \
++                     "   ino:   %d\n",
++               i, id, dc, dc->nameLen, dc->name, dc->ino);
++            l = l->prev;
++            list_del( &dc->list );
++            Novfs_Free( dc );
++            DCCount--;
++         }
++      }
++   }
++}
++
++/*++======================================================================*/
++void Novfs_free_inode_cache( struct inode *i )
++/*
++ *  Arguments:   struct inode *i - pointer to directory inode.
++ *
++ *  Returns:     nothing
++ * 
++ *  Abstract:    Frees all entries in the inode cache.
++ * 
++ *  Notes:       DirCacheLock should be held before calling this routine.
++ * 
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PINODE_DATA id;
++   PDIR_CACHE dc;
++   struct list_head *l;
++
++   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
++   {
++      list_for_each( l, &id->DirCache )
++      {
++         dc = list_entry( l, DIR_CACHE, list );
++         l = l->prev;
++         list_del( &dc->list );
++         Novfs_Free( dc );
++         DCCount--;
++      }
++   }
++}
++
++/*++======================================================================*/
++int
++NO_TRACE
++Novfs_dump_inode_cache(int argc, const char **argv, const char **envp, struct pt_regs *regs)
++/*
++ * Arguments:
++ * 
++ *  Returns:
++ *  
++ *  Abstract:
++ *  
++ *  Notes:
++ *  
++ *  Environment:
++ * 
++ *========================================================================*/
++{
++#ifdef	CONFIG_KDB
++   struct inode *inode=NULL;
++   PINODE_DATA id;
++   PDIR_CACHE dc;
++   struct list_head *l;
++   char atime_buf[32];
++   char mtime_buf[32];
++   char ctime_buf[32];
++
++   if (Novfs_root)
++   {
++      inode = Novfs_root->d_inode;
++   }
++
++   if (argc > 0)
++   {
++      inode = (void *)simple_strtoul(argv[1], NULL, 0);
++   }
++
++   kdb_printf("Inode: 0x%p\n", inode);
++   if (inode)
++   {
++      id = inode->u.generic_ip;
++      kdb_printf("INODE_DATA: 0x%p\n", id);
++
++      if ( id && id->DirCache.next )
++      {
++         list_for_each(l, &id->DirCache)
++         {
++            dc = list_entry(l, DIR_CACHE, list);
++            ctime_r(&dc->atime.tv_sec, atime_buf);
++            ctime_r(&dc->mtime.tv_sec, mtime_buf);
++            ctime_r(&dc->ctime.tv_sec, ctime_buf);
++
++            DbgPrint("Cache Entry: 0x%p\n" \
++                     "   flags:   0x%x\n" \
++                     "   jiffies: %llu\n" \
++                     "   ino:     %u\n" \
++                     "   size:    %llu\n" \
++                     "   mode:    0%o\n" \
++                     "   atime:   %s\n" \
++                     "   mtime:   %s\n" \
++                     "   ctime:   %s\n" \
++                     "   hash:    0x%x\n" \
++                     "   len:     %d\n" \
++                     "   name:    %s\n",
++               dc, dc->flags, dc->jiffies,
++               dc->ino, dc->size, dc->mode,
++               atime_buf, mtime_buf, ctime_buf,
++               dc->hash, dc->nameLen, dc->name);
++         }
++      }
++   }
++#endif
++   return(0);
++}
++
++/*++======================================================================*/
++void
++NO_TRACE
++Novfs_dump_inode( void *pf )
++/*
++ * Arguments:
++ * 
++ *  Returns:
++ *  
++ *  Abstract:
++ *  
++ *  Notes:
++ *  
++ *  Environment:
++ * 
++ *========================================================================*/
++{
++   struct inode *inode;
++   void (*pfunc)(char *Fmt, ...) = pf;
++   PINODE_DATA id;
++   PDIR_CACHE dc;
++   struct list_head *il, *l;
++   char atime_buf[32];
++   char mtime_buf[32];
++   char ctime_buf[32];
++   unsigned long icnt=0, dccnt=0;
++
++   down( &InodeList_lock );
++   list_for_each(il, &InodeList)
++   {
++      id  = list_entry(il, INODE_DATA, IList);
++      inode = id->Inode;
++      if (inode)
++      {
++         icnt++;
++
++         pfunc("Inode=0x%x I_ino=%d\n", inode, inode->i_ino);
++
++         pfunc("   atime=%s\n", ctime_r(&inode->i_atime.tv_sec, atime_buf));
++         pfunc("   ctime=%s\n", ctime_r(&inode->i_mtime.tv_sec, atime_buf));
++         pfunc("   mtime=%s\n", ctime_r(&inode->i_ctime.tv_sec, atime_buf));
++         pfunc("   size=%lld\n", inode->i_size);
++         pfunc("   mode=0%o\n", inode->i_mode);
++      }
++
++      pfunc("   INODE_DATA: 0x%p Name=%s Scope=0x%p\n", id, id->Name, id->Scope);
++
++      if (id->DirCache.next )
++      {
++         list_for_each(l, &id->DirCache)
++         {
++            dccnt++;
++            dc = list_entry(l, DIR_CACHE, list);
++            ctime_r(&dc->atime.tv_sec, atime_buf);
++            ctime_r(&dc->mtime.tv_sec, mtime_buf);
++            ctime_r(&dc->ctime.tv_sec, ctime_buf);
++
++            pfunc("   Cache Entry: 0x%p\n" \
++                       "      flags:   0x%x\n" \
++                       "      jiffies: %llu\n" \
++                       "      ino:     %u\n" \
++                       "      size:    %llu\n" \
++                       "      mode:    0%o\n" \
++                       "      atime:   %s\n" \
++                       "      mtime:   %s\n" \
++                       "      ctime:   %s\n" \
++                       "      hash:    0x%x\n" \
++                       "      len:     %d\n" \
++                       "      name:    %s\n",
++               dc, dc->flags, dc->jiffies,
++               dc->ino, dc->size, dc->mode,
++               atime_buf, mtime_buf, ctime_buf,
++               dc->hash, dc->nameLen, dc->name);
++         }
++      }
++   }
++   up( &InodeList_lock );
++
++   pfunc("Inodes: %d(%d) DirCache: %d(%d)\n", InodeCount, icnt, DCCount, dccnt );
++   
++}
++
++module_init(init_novfs)
++module_exit(exit_novfs)
++
++MODULE_LICENSE("GPL");
++MODULE_AUTHOR("Novell Inc.");
++MODULE_DESCRIPTION("Novell NetWare Client for Linux");
++MODULE_VERSION( NOVFS_VERSION_STRING );
+diff -uNr src.old/src/m src/src/m
+--- src.old/src/m	1970-01-01 01:00:00.000000000 +0100
++++ src/src/m	2006-10-16 15:08:22.000000000 +0200
+@@ -0,0 +1,12 @@
++#!/bin/sh
++
++VERSION=`uname -r`
++
++make -C /usr/src/linux SUBDIRS=$PWD modules
++
++if [ -e novfs.ko ]
++then
++	mkdir -p -m 755 /lib/modules/$VERSION/kernel/fs/novfs
++	echo "copying novfs.ko to /lib/modules/$VERSION/kernel/fs/novfs"
++	cp novfs.ko /lib/modules/$VERSION/kernel/fs/novfs
++fi
+diff -uNr src.old/src/mk_novfs src/src/mk_novfs
+--- src.old/src/mk_novfs	1970-01-01 01:00:00.000000000 +0100
++++ src/src/mk_novfs	2006-10-16 15:08:22.000000000 +0200
+@@ -0,0 +1,114 @@
++#!/bin/sh
++
++RVAL=1
++TO_BUILD=1
++
++BUILD_TYPE=modules
++
++if [ $1 ]
++then
++	if [ "$1" = "force" ]
++	then
++		FORCE=1
++	else
++		BUILD_TYPE=$1
++		FORCE=0
++	fi
++else
++	FORCE=0
++fi
++
++platform=`uname -i`
++
++if [ -d /usr/src/linux-obj/$platform ]
++then
++    for i in $(ls /usr/src/linux-obj/$platform) 
++    do
++		TO_BUILD=1
++    	VERSION=`cat /usr/src/linux-obj/$platform/$i/include/linux/version.h |grep UTS_RELEASE |awk '{printf("%s\n", substr($3, 2,length($3)-2))}'`
++		NOVFS_PATH=/lib/modules/$VERSION/kernel/fs/novfs
++
++    	if [ -e /lib/modules/$VERSION/extra/novfs.ko ]
++    	then
++			NOVFS_PATH=/lib/modules/$VERSION/extra
++		
++    	else
++	    	if [ -e /lib/modules/$VERSION/updates/novfs.ko ]
++	    	then
++				NOVFS_PATH=/lib/modules/$VERSION/updates
++			
++			fi
++		fi
++
++		if [ -d /lib/modules/$VERSION ]
++		then
++
++			if [ -e $NOVFS_PATH/novfs.ko ]
++			then
++				CUR_NOVFS_VERSION=`od --strings=8 $NOVFS_PATH/novfs.ko |grep version= |awk '{split($2,a,"="); if("version"==a[1]) printf("%s", a[2])}'`
++				CUR_NOVFS_VFS_MAJOR=`echo $CUR_NOVFS_VERSION |awk '{split($0,a,"."); printf("%d", a[1])}'`
++				CUR_NOVFS_VFS_MINOR=`echo $CUR_NOVFS_VERSION |awk '{split($0,a,"."); printf("%d", a[2])}'`
++				CUR_NOVFS_VFS_SUB=`echo $CUR_NOVFS_VERSION |awk '{split($0,a,"."); printf("%d", a[3])}'`
++				CUR_NOVFS_VFS_RELEASE=`echo $CUR_NOVFS_VERSION |awk '{split($0,a,"-"); printf("%d", a[2])}'`
++
++				NOVFS_VFS_MAJOR=`cat Makefile |grep 'NOVFS_VFS_MAJOR =' |awk '{printf("%d", $3)}'`
++				NOVFS_VFS_MINOR=`cat Makefile |grep 'NOVFS_VFS_MINOR =' |awk '{printf("%d", $3)}'`
++				NOVFS_VFS_SUB=`cat Makefile |grep 'NOVFS_VFS_SUB =' |awk '{printf("%d", $3)}'`
++				NOVFS_VFS_RELEASE=`cat Makefile |grep 'NOVFS_VFS_RELEASE =' |awk '{printf("%d", $3)}'`
++				NOVFS_VFS_VERSION="$NOVFS_VFS_MAJOR.$NOVFS_VFS_MINOR.$NOVFS_VFS_SUB-$NOVFS_VFS_RELEASE"
++
++				TO_BUILD=0
++
++				if [ $NOVFS_VFS_MAJOR -gt $CUR_NOVFS_VFS_MAJOR ]
++				then
++					TO_BUILD=1
++				else 
++					if [ $NOVFS_VFS_MAJOR -eq $CUR_NOVFS_VFS_MAJOR ]
++					then
++						if [ $NOVFS_VFS_MINOR -gt $CUR_NOVFS_VFS_MINOR ]
++						then
++							TO_BUILD=1
++						else
++							if [ $NOVFS_VFS_MINOR -eq $CUR_NOVFS_VFS_MINOR ]
++							then
++								if [ $NOVFS_VFS_SUB -gt $CUR_NOVFS_VFS_SUB ]
++								then
++									TO_BUILD=1
++								else
++									if [ $NOVFS_VFS_SUB -eq $CUR_NOVFS_VFS_SUB ]
++									then
++										if [ $NOVFS_VFS_RELEASE -gt $CUR_NOVFS_VFS_RELEASE ]
++										then
++											TO_BUILD=1
++										fi
++									fi
++								fi
++							fi
++						fi
++					fi
++				fi
++			fi
++
++			if [ $FORCE -eq 1 ]
++			then
++				TO_BUILD=1;
++			fi
++
++			if [ $TO_BUILD -eq 1 ]
++			then
++	    		echo Building novfs.ko for $VERSION
++	    		make -C /usr/src/linux-obj/$platform/$i SUBDIRS=$PWD $BUILD_TYPE 
++	    		RVAL=$?
++	    		if [ -e novfs.ko ]
++	    		then
++	    			mkdir -p -m 755 $NOVFS_PATH
++	    			echo "copying novfs.ko to $NOVFS_PATH"
++	    			cp novfs.ko $NOVFS_PATH
++	    			RVAL=$?
++	    		fi
++			fi
++		fi
++    done
++fi
++exit $RVAL
++
+diff -uNr src.old/src/nwcapi.c src/src/nwcapi.c
+--- src.old/src/nwcapi.c	1970-01-01 01:00:00.000000000 +0100
++++ src/src/nwcapi.c	2006-10-16 15:08:22.000000000 +0200
+@@ -0,0 +1,2410 @@
++/*++========================================================================
++ * Program Name:     Novell NCP Redirector for Linux
++ * File Name:        nwcapi.c
++ * Version:          v1.00
++ * Author:           James Turner/Richard Williams
++ *
++ * Abstract:         This module contains functions used to interface to
++ *                   the library interface of the daemon.
++ * Notes:
++ * Revision History: 
++ *
++ *
++ * Copyright (C) 2005 Novell, Inc.
++ *
++ * 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 files specific to Linux ]==================================*/
++
++/*===[ Include files specific to this module ]============================*/
++#include <linux/module.h>
++#include <linux/fs.h>
++#include <linux/slab.h>
++#include <linux/list.h>
++#include <linux/timer.h>
++#include <linux/poll.h>
++#include <asm/semaphore.h>
++#include <asm/uaccess.h>
++
++#include "nwcapi.h"
++#include "nwerror.h"
++#include "commands.h"
++
++#include "vfs.h"
++
++/*===[ External data ]====================================================*/
++
++/*===[ External prototypes ]==============================================*/
++
++extern int DbgPrint( char *Fmt, ... );
++extern void mydump(int size, void *dumpptr);
++
++extern session_t Scope_Get_SessionId( void *Scope );
++extern int Queue_Daemon_Command(void *request, u_long reqlen, void *data, int dlen, void **reply, u_long *replen, int interruptible);
++
++extern int do_login(NclString *Server, NclString *Username, NclString *Password, u_long *lgnId, session_t Session);
++
++void	GetUserData(NwcScanConnInfo *connInfo, PXPLAT_CALL_REQUEST cmd, PXPLAT_CALL_REPLY reply);
++void	GetConnData(NwcGetConnInfo *connInfo, PXPLAT_CALL_REQUEST cmd, PXPLAT_CALL_REPLY reply);
++
++/*===[ Manifest constants ]===============================================*/
++
++/*===[ Type definitions ]=================================================*/
++
++/*===[ Function prototypes ]==============================================*/
++
++/*===[ Global variables ]=================================================*/
++
++/*===[ Code ]=============================================================*/
++
++/*++======================================================================*/
++
++/*++======================================================================*/
++int NwOpenConnByName(PXPLAT pdata, u_long *Handle, session_t Session)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++PXPLAT_CALL_REQUEST		cmd;
++PXPLAT_CALL_REPLY		reply;
++PNwdCOpenConnByName	  	openConn, connReply;
++NwcOpenConnByName 		ocbn;
++u_long			retCode = 0, cmdlen, datalen, replylen, cpylen;
++char					*data;
++
++	cpylen = copy_from_user(&ocbn, pdata->reqData, sizeof(ocbn));
++	datalen = sizeof(*openConn) + strlen_user(ocbn.pName->pString) + strlen_user(ocbn.pServiceType);
++	cmdlen = datalen + sizeof(*cmd);
++	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++
++	if (cmd)
++	{
++		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++		cmd->Command.SequenceNumber = 0;
++		cmd->Command.SessionId      = Session;
++		cmd->NwcCommand = NWC_OPEN_CONN_BY_NAME;
++
++		cmd->dataLen = datalen;
++		openConn = (PNwdCOpenConnByName)cmd->data;					  
++
++		openConn->nameLen = strlen_user(ocbn.pName->pString);
++		openConn->serviceLen = strlen_user(ocbn.pServiceType);
++		openConn->uConnFlags = ocbn.uConnFlags;
++		openConn->ConnHandle = ocbn.ConnHandle;
++		data = (char *)openConn;
++		data += sizeof(*openConn);
++		openConn->oName = sizeof(*openConn);
++
++		openConn->oServiceType = openConn->oName + openConn->nameLen;
++		cpylen = copy_from_user(data, ocbn.pName->pString, openConn->nameLen);
++		data += openConn->nameLen;
++		cpylen = copy_from_user(data, ocbn.pServiceType, openConn->serviceLen);
++
++		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
++		if (reply)
++		{
++			/*
++			 * we got reply data from the daemon
++          */
++			connReply = (PNwdCOpenConnByName)reply->data;
++			retCode = reply->Reply.ErrorCode;
++			if (!retCode)
++			{
++				/*
++				 * we got valid data.
++             */
++				connReply = (PNwdCOpenConnByName)reply->data;
++                ocbn.RetConnHandle = connReply->newConnHandle;
++                *Handle = connReply->newConnHandle;
++				cpylen = copy_to_user(pdata->reqData, &ocbn, sizeof(ocbn));
++				DbgPrint("New Conn Handle = %X\n", connReply->newConnHandle);
++			}
++			Novfs_Free(reply);
++		}
++
++		Novfs_Free(cmd);
++	}
++
++	return((int)retCode);
++
++}
++
++/*++======================================================================*/
++int NwOpenConnByAddr(PXPLAT pdata, u_long *Handle, session_t Session)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++PXPLAT_CALL_REQUEST		cmd;
++PXPLAT_CALL_REPLY		reply;
++PNwdCOpenConnByAddr	  	openConn, connReply;
++NwcOpenConnByAddr 		ocba;
++NwcTranAddr            tranAddr;
++u_long			retCode = 0, cmdlen, datalen, replylen, cpylen;
++char                 addr[MAX_ADDRESS_LENGTH];
++
++	cpylen = copy_from_user(&ocba, pdata->reqData, sizeof(ocba));
++	datalen = sizeof(*openConn);
++	cmdlen = datalen + sizeof(*cmd);
++	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++
++	if (cmd)
++	{
++		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++		cmd->Command.SequenceNumber = 0;
++		cmd->Command.SessionId      = Session;
++		cmd->NwcCommand 			= NWC_OPEN_CONN_BY_ADDRESS;
++		cmd->dataLen 				= datalen;
++		openConn 					= (PNwdCOpenConnByAddr)cmd->data;
++
++		cpylen = copy_from_user(&tranAddr, ocba.pTranAddr, sizeof(tranAddr));
++
++	   DbgPrint("NwOpenConnByAddr: tranAddr\n");
++      mydump(sizeof(tranAddr), &tranAddr);
++
++      openConn->TranAddr.uTransportType = tranAddr.uTransportType;
++      openConn->TranAddr.uAddressLength = tranAddr.uAddressLength;
++      memset(addr, 0xcc, sizeof(addr)-1);
++
++      cpylen = copy_from_user(addr, tranAddr.puAddress, tranAddr.uAddressLength);
++
++	   DbgPrint("NwOpenConnByAddr: addr\n");
++      mydump(sizeof(addr), addr);
++      
++      openConn->TranAddr.oAddress = *(u_long *)(&addr[2]);
++
++		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
++		if (reply)
++		{
++			/*
++			 * we got reply data from the daemon
++          */
++			connReply = (PNwdCOpenConnByAddr)reply->data;
++			retCode = reply->Reply.ErrorCode;
++			if (!retCode)
++			{
++				/*
++				 * we got valid data.
++             */
++				connReply = (PNwdCOpenConnByAddr)reply->data;
++				ocba.ConnHandle = connReply->ConnHandle;
++            *Handle = connReply->ConnHandle;
++				cpylen = copy_to_user(pdata->reqData, &ocba, sizeof(ocba));
++				DbgPrint("New Conn Handle = %X\n", connReply->ConnHandle);
++			}
++			Novfs_Free(reply);
++		}
++
++		Novfs_Free(cmd);
++	}
++
++	return(retCode);
++
++}
++
++/*++======================================================================*/
++int NwOpenConnByRef(PXPLAT pdata, u_long *Handle, session_t Session)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++PXPLAT_CALL_REQUEST		cmd;
++PXPLAT_CALL_REPLY		reply;
++PNwdCOpenConnByRef	  	openConn;
++NwcOpenConnByReference 	ocbr;
++u_long			retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
++
++	
++	cpylen = copy_from_user(&ocbr, pdata->reqData, sizeof(ocbr));
++	datalen = sizeof(*openConn);
++	cmdlen = datalen + sizeof(*cmd);
++	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++	if (cmd)
++	{
++		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++		cmd->Command.SequenceNumber = 0;
++		cmd->Command.SessionId      = Session;
++		cmd->NwcCommand 			= NWC_OPEN_CONN_BY_REFERENCE;
++		cmd->dataLen 				= datalen;
++		openConn 					= (PNwdCOpenConnByRef)cmd->data;
++
++		memcpy(openConn, &ocbr, sizeof(ocbr));
++		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
++		if (reply)
++		{
++			/*
++			 * we got reply data from the daemon
++          */
++			openConn = (PNwdCOpenConnByRef)reply->data;
++			retCode = reply->Reply.ErrorCode;
++			if (!retCode)
++			{
++				/*
++				 * we got valid data.
++             */
++				ocbr.ConnHandle = openConn->ConnHandle;
++            *Handle = openConn->ConnHandle;
++
++				cpylen = copy_to_user(pdata->reqData, &ocbr, sizeof(ocbr));
++				DbgPrint("New Conn Handle = %X\n", openConn->ConnHandle);
++			}
++			Novfs_Free(reply);
++		}
++
++		Novfs_Free(cmd);
++	}
++	return(retCode);
++
++}
++
++/*++======================================================================*/
++int NwRawSend(PXPLAT pdata, session_t Session)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++NwcRequest           xRequest;
++PNwcFrag             frag, cFrag, reqFrag;
++PXPLAT_CALL_REQUEST  cmd;
++PXPLAT_CALL_REPLY    reply;
++u_long               retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
++u_long               x, totalLen;
++PNwdCNCPReq          ncpData;
++PNwdCNCPRep          ncpReply;
++u_char               *reqData;
++unsigned long        actualReplyLength=0;
++
++	DbgPrint("[XPLAT] Process Raw NCP Send\n");
++	cpylen = copy_from_user(&xRequest, pdata->reqData, sizeof(xRequest));
++
++	/*
++	 * Figure out the length of the request
++    */
++	frag = Novfs_Malloc(xRequest.uNumReplyFrags * sizeof(NwcFrag), GFP_KERNEL);
++
++	DbgPrint("[XPLAT RawNCP] - Reply Frag Count 0x%X\n", xRequest.uNumReplyFrags);
++
++	if (!frag)
++		return(retCode);		
++
++	cpylen = copy_from_user(frag, xRequest.pReplyFrags, xRequest.uNumReplyFrags * sizeof(NwcFrag));
++	totalLen = 0;
++
++	cFrag = frag;
++	for (x = 0; x < xRequest.uNumReplyFrags; x ++)
++	{
++		DbgPrint("[XPLAT - RawNCP] - Frag Len = %d\n", cFrag->uLength);
++		totalLen += cFrag->uLength;
++		cFrag++;
++	}
++
++
++	DbgPrint("[XPLAT - RawNCP] - totalLen = %d\n", totalLen);
++	datalen = 0;
++	reqFrag = Novfs_Malloc(xRequest.uNumRequestFrags * sizeof(NwcFrag), GFP_KERNEL);
++	if (!reqFrag)
++	{
++		Novfs_Free(frag);
++		return(retCode);
++	}
++
++	cpylen = copy_from_user(reqFrag, xRequest.pRequestFrags, xRequest.uNumRequestFrags * sizeof(NwcFrag));
++	cFrag = reqFrag;
++	for (x = 0; x < xRequest.uNumRequestFrags; x ++)
++	{
++		datalen += cFrag->uLength;
++		cFrag++;
++	}
++
++	/*
++	 * Allocate the cmd Request
++    */
++	cmdlen = datalen + sizeof(*cmd) + sizeof(*ncpData);
++	DbgPrint("[XPLAT RawNCP] - Frag Count 0x%X\n", xRequest.uNumRequestFrags);
++	DbgPrint("[XPLAT RawNCP] - Total Command Data Len = %x\n", cmdlen);	
++
++	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++	if (cmd)
++	{
++		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++		cmd->Command.SequenceNumber = 0;
++		cmd->Command.SessionId      = Session;
++		cmd->NwcCommand = NWC_RAW_NCP_REQUEST;
++
++		/*
++		 * build the NCP Request
++       */
++		cmd->dataLen = cmdlen - sizeof(*cmd);
++		ncpData = (PNwdCNCPReq)cmd->data;
++		ncpData->replyLen = totalLen;
++		ncpData->requestLen = datalen;
++		ncpData->ConnHandle = xRequest.ConnHandle;
++		ncpData->function = xRequest.uFunction;
++
++
++		reqData = ncpData->data;
++		cFrag = reqFrag;
++
++		for (x = 0; x < xRequest.uNumRequestFrags; x ++)
++		{
++			cpylen = copy_from_user(reqData, cFrag->pData, cFrag->uLength);
++			reqData += cFrag->uLength;
++			cFrag++;
++		}
++
++		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
++		DbgPrint("RawNCP - reply = %x\n", reply);	
++		DbgPrint("RawNCP - retCode = %x\n", retCode);	
++
++		if (reply)
++		{
++			/*
++			 * we got reply data from the daemon
++          */
++			ncpReply = (PNwdCNCPRep)reply->data;
++			retCode = reply->Reply.ErrorCode;
++
++			DbgPrint("RawNCP - Reply Frag Count 0x%X\n", xRequest.uNumReplyFrags);
++
++			/*
++			 * We need to copy the reply frags to the packet.
++          */
++			reqData = ncpReply->data;
++			cFrag = frag;
++
++			totalLen = ncpReply->replyLen;
++			for (x = 0; x < xRequest.uNumReplyFrags; x ++)
++			{
++		
++				DbgPrint("RawNCP - Copy Frag %d: 0x%X\n", x, cFrag->uLength);
++
++            datalen = min(cFrag->uLength, totalLen);
++						
++				cpylen = copy_to_user(cFrag->pData, reqData, datalen);
++				totalLen -= datalen;
++				reqData += datalen;
++            actualReplyLength += datalen;
++
++				cFrag++;
++			}
++
++			Novfs_Free(reply);
++		}
++      else
++      {
++         retCode = -EIO;
++      }
++		
++		Novfs_Free(cmd);
++	}
++   xRequest.uActualReplyLength = actualReplyLength;
++	cpylen = copy_to_user(pdata->reqData, &xRequest, sizeof(xRequest));
++
++	Novfs_Free(reqFrag);
++	Novfs_Free(frag);
++
++	return(retCode);		
++}
++
++/*++======================================================================*/
++int NwConnClose(PXPLAT pdata, u_long *Handle, session_t Session)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++PXPLAT_CALL_REQUEST		cmd;
++PXPLAT_CALL_REPLY		reply;
++NwcCloseConn			cc;
++PNwdCCloseConn			nwdClose;
++u_long			retCode = 0, cmdlen, datalen, replylen, cpylen;
++
++	cpylen = copy_from_user(&cc, pdata->reqData, sizeof(cc));
++
++	datalen = sizeof(*nwdClose);
++	cmdlen = datalen + sizeof(*cmd);
++	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++	if (cmd)
++	{
++		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++		cmd->Command.SequenceNumber = 0;
++		cmd->Command.SessionId      = Session;
++		cmd->NwcCommand = NWC_CLOSE_CONN;
++
++		nwdClose = (PNwdCCloseConn)cmd->data;
++		cmd->dataLen = sizeof(*nwdClose);
++		nwdClose->ConnHandle = cc.ConnHandle;
++      *Handle = cc.ConnHandle;
++
++		/*
++		 * send the request
++       */
++		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, 0);
++		if (reply)
++		{
++			retCode = reply->Reply.ErrorCode;
++			Novfs_Free(reply);
++		}
++		Novfs_Free(cmd);
++
++	}
++
++	return(retCode);		
++
++}
++
++/*++======================================================================*/
++int NwSysConnClose(PXPLAT pdata, u_long *Handle, session_t Session)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++PXPLAT_CALL_REQUEST		cmd;
++PXPLAT_CALL_REPLY		reply;
++NwcCloseConn			cc;
++PNwdCCloseConn			nwdClose;
++u_long			retCode = 0, cmdlen, datalen, replylen, cpylen;
++
++	cpylen = copy_from_user(&cc, pdata->reqData, sizeof(cc));
++
++	datalen = sizeof(*nwdClose);
++	cmdlen = datalen + sizeof(*cmd);
++	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++	if (cmd)
++	{
++		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++		cmd->Command.SequenceNumber = 0;
++		cmd->Command.SessionId      = Session;
++		cmd->NwcCommand = NWC_SYS_CLOSE_CONN;
++
++		nwdClose = (PNwdCCloseConn)cmd->data;
++		cmd->dataLen = sizeof(*nwdClose);
++		nwdClose->ConnHandle = cc.ConnHandle;
++      *Handle = cc.ConnHandle;
++
++		/*
++		 * send the request
++       */
++		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, 0);
++		if (reply)
++		{
++			retCode = reply->Reply.ErrorCode;
++			Novfs_Free(reply);
++		}
++		Novfs_Free(cmd);
++
++	}
++
++	return(retCode);		
++
++}
++
++/*++======================================================================*/
++int	NwLoginIdentity(PXPLAT pdata, session_t Session)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++NwcLoginIdentity	lgn, *plgn;
++int retCode = -ENOMEM;
++NclString  server;
++NclString  username;
++NclString  password;
++u_long cpylen;
++NwcString nwcStr;
++
++	cpylen = copy_from_user(&lgn, pdata->reqData, sizeof(lgn));
++
++   DbgPrint("NwLoginIdentity:\n");
++   mydump(sizeof(lgn), &lgn);
++
++
++
++   cpylen = copy_from_user(&nwcStr, lgn.pDomainName, sizeof(nwcStr));
++   DbgPrint("NwLoginIdentity: DomainName\n");
++   mydump(sizeof(nwcStr), &nwcStr);
++
++	if ( (server.buffer = Novfs_Malloc(nwcStr.DataLen, GFP_KERNEL)) )
++	{
++		server.type = nwcStr.DataType;
++      server.len  = nwcStr.DataLen;
++		if ( !copy_from_user((void *)server.buffer, nwcStr.pBuffer, server.len) )
++		{
++         DbgPrint("NwLoginIdentity: Server\n");
++         mydump(server.len, server.buffer);
++         
++         cpylen = copy_from_user(&nwcStr, lgn.pObjectName, sizeof(nwcStr));
++         DbgPrint("NwLoginIdentity: ObjectName\n");
++         mydump(sizeof(nwcStr), &nwcStr);
++
++			if ( (username.buffer = Novfs_Malloc(nwcStr.DataLen, GFP_KERNEL)) )
++			{
++				username.type = nwcStr.DataType;
++            username.len  = nwcStr.DataLen;
++				if ( !copy_from_user((void *)username.buffer, nwcStr.pBuffer, username.len) )
++				{
++               DbgPrint("NwLoginIdentity: User\n");
++               mydump(username.len, username.buffer);
++               
++               cpylen = copy_from_user(&nwcStr, lgn.pPassword, sizeof(nwcStr));
++               DbgPrint("NwLoginIdentity: Password\n");
++               mydump(sizeof(nwcStr), &nwcStr);
++
++					if ( (password.buffer = Novfs_Malloc(nwcStr.DataLen, GFP_KERNEL)) )
++					{
++						password.type = nwcStr.DataType;
++						password.len  = nwcStr.DataLen;
++						if ( !copy_from_user((void *)password.buffer, nwcStr.pBuffer, password.len) )
++						{
++							retCode = do_login(&server, &username, &password, (u_long *)&lgn.AuthenticationId, Session);
++                            if (retCode)
++                            {
++                                lgn.AuthenticationId = 0;
++                            }
++
++                            plgn = (NwcLoginIdentity *)pdata->reqData;
++                            cpylen = copy_to_user(&plgn->AuthenticationId, &lgn.AuthenticationId, sizeof(plgn->AuthenticationId));
++
++						}
++                  memset(password.buffer, 0, password.len);
++						Novfs_Free(password.buffer);
++					}
++				}
++            memset(username.buffer, 0, username.len);
++				Novfs_Free(username.buffer);
++			}
++		}
++		Novfs_Free(server.buffer);
++	}
++	return(retCode);
++}
++
++/*++======================================================================*/
++int	NwAuthConnWithId(PXPLAT pdata, session_t Session)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++NwcAuthenticateWithId 	pauth;
++PNwdCAuthenticateWithId pDauth;
++PXPLAT_CALL_REQUEST		cmd;
++PXPLAT_CALL_REPLY		reply;
++u_long			retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
++
++	datalen = sizeof(*pDauth);
++	cmdlen = datalen + sizeof(*cmd);
++	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++
++	if (cmd)
++	{
++		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++		cmd->Command.SequenceNumber = 0;
++		cmd->Command.SessionId      = Session;
++		cmd->NwcCommand = NWC_AUTHENTICATE_CONN_WITH_ID;
++
++
++		cpylen = copy_from_user(&pauth, pdata->reqData, sizeof(pauth));
++
++		pDauth = (PNwdCAuthenticateWithId)cmd->data;
++		cmd->dataLen = datalen;
++		pDauth->AuthenticationId = pauth.AuthenticationId;
++		pDauth->ConnHandle = pauth.ConnHandle;
++
++		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
++		if (reply)
++		{
++			retCode = reply->Reply.ErrorCode;
++			Novfs_Free(reply);
++		}
++		Novfs_Free(cmd);
++	}
++	return(retCode);
++}
++
++/*++======================================================================*/
++int	NwLicenseConn(PXPLAT pdata, session_t Session)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++PXPLAT_CALL_REQUEST		cmd;
++PXPLAT_CALL_REPLY		reply;
++NwcLicenseConn			lisc;
++PNwdCLicenseConn		pDLisc;
++u_long			retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
++
++	datalen = sizeof(*pDLisc);
++	cmdlen = datalen + sizeof(*cmd);
++	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++
++	if (cmd)
++	{
++		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++		cmd->Command.SequenceNumber = 0;
++		cmd->Command.SessionId      = Session;
++		cmd->NwcCommand = NWC_LICENSE_CONN;
++
++
++		cpylen = copy_from_user(&lisc, pdata->reqData, sizeof(lisc));
++
++		pDLisc = (PNwdCLicenseConn)cmd->data;
++		cmd->dataLen = datalen;
++		pDLisc->ConnHandle = lisc.ConnHandle;
++
++		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
++		if (reply)
++		{
++			retCode = reply->Reply.ErrorCode;
++			Novfs_Free(reply);
++		}
++		Novfs_Free(cmd);
++	}
++	return(retCode);
++}
++
++
++/*++======================================================================*/
++int	NwLogoutIdentity(PXPLAT pdata, session_t Session)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++PXPLAT_CALL_REQUEST		cmd;
++PXPLAT_CALL_REPLY		reply;
++NwcLogoutIdentity		logout;
++PNwdCLogoutIdentity		pDLogout;
++u_long			retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
++
++	datalen = sizeof(*pDLogout);
++	cmdlen = datalen + sizeof(*cmd);
++	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++
++	if (cmd)
++	{
++		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++		cmd->Command.SequenceNumber = 0;
++		cmd->Command.SessionId      = Session;
++		cmd->NwcCommand = NWC_LOGOUT_IDENTITY;
++
++		cpylen = copy_from_user(&logout, pdata->reqData, sizeof(logout));
++
++		pDLogout = (PNwdCLogoutIdentity)cmd->data;
++		cmd->dataLen = datalen;
++		pDLogout->AuthenticationId = logout.AuthenticationId;
++
++		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
++		if (reply)
++		{
++			retCode = reply->Reply.ErrorCode;
++			Novfs_Free(reply);
++		}
++		Novfs_Free(cmd);
++	}
++	return(retCode);
++}
++
++/*++======================================================================*/
++int	NwUnlicenseConn(PXPLAT pdata, session_t Session)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++PXPLAT_CALL_REQUEST		cmd;
++PXPLAT_CALL_REPLY		reply;
++PNwdCUnlicenseConn		pUconn;
++NwcUnlicenseConn 		ulc;
++u_long			retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
++
++	
++	cpylen = copy_from_user(&ulc, pdata->reqData, sizeof(ulc));
++	datalen = sizeof(*pUconn);
++	cmdlen = datalen + sizeof(*cmd);
++	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++	if (cmd)
++	{
++		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++		cmd->Command.SequenceNumber = 0;
++		cmd->Command.SessionId      = Session;
++		cmd->NwcCommand 			= NWC_UNLICENSE_CONN;
++		cmd->dataLen 				= datalen;
++		pUconn 						= (PNwdCUnlicenseConn)cmd->data;
++
++		pUconn->ConnHandle = ulc.ConnHandle;
++		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
++		if (reply)
++		{
++			/*
++			 * we got reply data from the daemon
++          */
++			retCode = reply->Reply.ErrorCode;
++			Novfs_Free(reply);
++		}
++
++		Novfs_Free(cmd);
++	}
++	return(retCode);
++
++}
++
++
++/*++======================================================================*/
++int	NwUnAuthenticate(PXPLAT pdata, session_t Session)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++PXPLAT_CALL_REQUEST		cmd;
++PXPLAT_CALL_REPLY		reply;
++NwcUnauthenticate		auth;
++PNwdCUnauthenticate		pDAuth;
++u_long			retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
++
++	datalen = sizeof(*pDAuth);
++	cmdlen = datalen + sizeof(*cmd);
++	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++
++	if (cmd)
++	{
++		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++		cmd->Command.SequenceNumber = 0;
++		cmd->Command.SessionId      = Session;
++		cmd->NwcCommand = NWC_UNAUTHENTICATE_CONN;
++
++		cpylen = copy_from_user(&auth, pdata->reqData, sizeof(auth));
++
++		pDAuth = (PNwdCUnauthenticate)cmd->data;
++		cmd->dataLen = datalen;
++		pDAuth->AuthenticationId = auth.AuthenticationId;
++		pDAuth->ConnHandle = auth.ConnHandle;
++
++		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
++		if (reply)
++		{
++			retCode = reply->Reply.ErrorCode;
++			Novfs_Free(reply);
++		}
++		Novfs_Free(cmd);
++	}
++	return(retCode);
++
++}
++
++
++/*++======================================================================*/
++int	NwGetConnInfo(PXPLAT pdata, session_t Session)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++PXPLAT_CALL_REQUEST		cmd;
++PXPLAT_CALL_REPLY		reply;
++NwcGetConnInfo			connInfo;
++PNwdCGetConnInfo		pDConnInfo;
++u_long			retCode = -ENOMEM, cmdlen, replylen, cpylen;
++
++	cmdlen = sizeof(*cmd) + sizeof(*pDConnInfo);
++	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++	cpylen = copy_from_user(&connInfo, pdata->reqData, sizeof(NwcGetConnInfo));
++
++	if (cmd)
++	{
++		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++		cmd->Command.SequenceNumber = 0;
++		cmd->Command.SessionId      = Session;
++		cmd->NwcCommand = NWC_GET_CONN_INFO;
++		
++		pDConnInfo = (PNwdCGetConnInfo)cmd->data;
++
++		pDConnInfo->ConnHandle = connInfo.ConnHandle;
++		pDConnInfo->uInfoLevel = connInfo.uInfoLevel;
++		pDConnInfo->uInfoLength = connInfo.uInfoLength;
++		cmd->dataLen = sizeof(*pDConnInfo);
++
++		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
++		if (reply)
++		{
++			retCode = reply->Reply.ErrorCode;
++			GetConnData(&connInfo, cmd, reply);
++
++			Novfs_Free(reply);
++		}
++		Novfs_Free(cmd);
++
++	}
++
++	return(retCode);
++
++}
++
++
++/*++======================================================================*/
++int	NwSetConnInfo(PXPLAT pdata, session_t Session)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++PXPLAT_CALL_REQUEST		cmd;
++PXPLAT_CALL_REPLY		reply;
++NwcSetConnInfo			connInfo;
++PNwdCSetConnInfo		pDConnInfo;
++u_long			retCode = -ENOMEM, cmdlen, replylen, cpylen;
++
++	cmdlen = sizeof(*cmd) + sizeof(*pDConnInfo);
++	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++	cpylen = copy_from_user(&connInfo, pdata->reqData, sizeof(NwcSetConnInfo));
++
++	if (cmd)
++	{
++		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++		cmd->Command.SequenceNumber = 0;
++		cmd->Command.SessionId      = Session;
++		cmd->NwcCommand = NWC_SET_CONN_INFO;
++		
++		pDConnInfo = (PNwdCSetConnInfo)cmd->data;
++
++		pDConnInfo->ConnHandle = connInfo.ConnHandle;
++		pDConnInfo->uInfoLevel = connInfo.uInfoLevel;
++		pDConnInfo->uInfoLength = connInfo.uInfoLength;
++		cmd->dataLen = sizeof(*pDConnInfo);
++
++		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
++		if (reply)
++		{
++			retCode = reply->Reply.ErrorCode;
++			Novfs_Free(reply);
++		}
++		Novfs_Free(cmd);
++
++	}
++
++	return(retCode);
++
++}
++
++/*++======================================================================*/
++int	NwGetIdentityInfo(PXPLAT pdata, session_t Session)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++PXPLAT_CALL_REQUEST		cmd;
++PXPLAT_CALL_REPLY		reply;
++NwcGetIdentityInfo		qidInfo, *gId;
++PNwdCGetIdentityInfo	idInfo;
++NwcString				xferStr;
++char					*str;
++u_long			retCode = -ENOMEM, cmdlen, replylen, cpylen;
++
++	cmdlen = sizeof(*cmd) + sizeof(*idInfo);
++	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++	cpylen = copy_from_user(&qidInfo, pdata->reqData, sizeof(qidInfo));
++
++	if (cmd)
++	{
++		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++		cmd->Command.SequenceNumber = 0;
++		cmd->Command.SessionId      = Session;
++		cmd->NwcCommand = NWC_GET_IDENTITY_INFO;
++		
++		idInfo = (PNwdCGetIdentityInfo)cmd->data;
++
++		idInfo->AuthenticationId = qidInfo.AuthenticationId;
++		cmd->dataLen = sizeof(*idInfo);
++
++		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
++		if (reply)
++		{
++			retCode = reply->Reply.ErrorCode;
++	
++            if (!reply->Reply.ErrorCode)
++            {
++			    /*
++			     * Save the return info to the user structure.
++              */
++			    gId = pdata->reqData;
++			    idInfo = (PNwdCGetIdentityInfo)reply->data;
++			    cpylen = copy_to_user(&gId->AuthenticationId, &idInfo->AuthenticationId, sizeof(idInfo->AuthenticationId));
++			    cpylen = copy_to_user(&gId->AuthType, &idInfo->AuthType, sizeof(idInfo->AuthType));
++			    cpylen = copy_to_user(&gId->IdentityFlags, &idInfo->IdentityFlags, sizeof(idInfo->IdentityFlags));
++			    cpylen = copy_to_user(&gId->NameType, &idInfo->NameType, sizeof(idInfo->NameType));
++			    cpylen = copy_to_user(&gId->ObjectType, &idInfo->ObjectType, sizeof(idInfo->ObjectType));
++
++			    cpylen = copy_from_user(&xferStr, gId->pDomainName, sizeof(NwcString));
++			    str = (char *)((char *)reply->data + idInfo->pDomainNameOffset);
++			    cpylen = copy_to_user(xferStr.pBuffer, str, idInfo->domainLen);
++			    xferStr.DataType = NWC_STRING_TYPE_ASCII;
++			    xferStr.DataLen = idInfo->domainLen;
++			    cpylen = copy_to_user(gId->pDomainName, &xferStr, sizeof(NwcString));
++
++
++			    cpylen = copy_from_user(&xferStr, gId->pObjectName, sizeof(NwcString));
++			    str = (char *)((char *)reply->data + idInfo->pObjectNameOffset);
++			    cpylen = copy_to_user(xferStr.pBuffer, str, idInfo->objectLen);
++			    xferStr.DataLen = idInfo->objectLen - 1;
++			    xferStr.DataType = NWC_STRING_TYPE_ASCII;
++			    cpylen = copy_to_user(gId->pObjectName, &xferStr, sizeof(NwcString));
++            }
++
++			Novfs_Free(reply);
++		}
++		Novfs_Free(cmd);
++
++	}
++
++	return(retCode);
++}
++
++/*++======================================================================*/
++int	NwScanConnInfo(PXPLAT pdata, session_t Session)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++PXPLAT_CALL_REQUEST		cmd;
++PXPLAT_CALL_REPLY		reply;
++NwcScanConnInfo			connInfo, *rInfo;
++PNwdCScanConnInfo		pDConnInfo;
++u_long			retCode = -ENOMEM, cmdlen, replylen, cpylen;
++u_char 			*localData;
++
++	cpylen = copy_from_user(&connInfo, pdata->reqData, sizeof(NwcScanConnInfo));
++
++	cmdlen = sizeof(*cmd) + sizeof(*pDConnInfo) + connInfo.uScanInfoLen;
++	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++
++	if (cmd)
++	{
++		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++		cmd->Command.SequenceNumber = 0;
++		cmd->Command.SessionId      = Session;
++		cmd->NwcCommand = NWC_SCAN_CONN_INFO;
++		
++		pDConnInfo = (PNwdCScanConnInfo)cmd->data;
++
++		DbgPrint("NwScanConnInfo: Input Data\n");
++		DbgPrint("connInfo.uScanIndex = 0x%X\n", connInfo.uScanIndex);
++		DbgPrint("connInfo.uConnectionReference = 0x%X\n", connInfo.uConnectionReference);
++		DbgPrint("connInfo.uScanInfoLevel = 0x%X\n", connInfo.uScanInfoLevel);
++		DbgPrint("connInfo.uScanInfoLen = 0x%X\n", connInfo.uScanInfoLen);
++		DbgPrint("connInfo.uReturnInfoLength = 0x%X\n", connInfo.uReturnInfoLength);
++		DbgPrint("connInfo.uReturnInfoLevel = 0x%X\n", connInfo.uReturnInfoLevel);
++		DbgPrint("connInfo.uScanFlags = 0x%X\n", connInfo.uScanFlags);
++
++
++		pDConnInfo->uScanIndex = connInfo.uScanIndex;
++		pDConnInfo->uConnectionReference = connInfo.uConnectionReference;
++		pDConnInfo->uScanInfoLevel = connInfo.uScanInfoLevel;
++		pDConnInfo->uScanInfoLen = connInfo.uScanInfoLen;
++		pDConnInfo->uReturnInfoLength = connInfo.uReturnInfoLength;
++		pDConnInfo->uReturnInfoLevel = connInfo.uReturnInfoLevel;
++		pDConnInfo->uScanFlags = connInfo.uScanFlags;
++
++		if (pDConnInfo->uScanInfoLen)
++		{
++			localData = (u_char *)pDConnInfo;
++			pDConnInfo->uScanConnInfoOffset = sizeof(*pDConnInfo);
++			localData += pDConnInfo->uScanConnInfoOffset;
++			cpylen = copy_from_user(localData, connInfo.pScanConnInfo, connInfo.uScanInfoLen);
++		}
++		else
++		{
++			pDConnInfo->uScanConnInfoOffset = 0;
++		}
++			
++
++		cmd->dataLen = sizeof(*pDConnInfo);
++
++		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
++		if (reply)
++		{
++			DbgPrint("NwScanConnInfo: Reply recieved\n");
++			DbgPrint("   NextIndex = %x\n", connInfo.uScanIndex);
++			DbgPrint("   ErrorCode = %x\n", reply->Reply.ErrorCode);
++			DbgPrint("   data = %x\n", reply->data);
++
++			pDConnInfo = (PNwdCScanConnInfo)reply->data;
++			retCode = (u_long)reply->Reply.ErrorCode;
++			if (!retCode)
++			{
++				GetUserData(&connInfo, cmd, reply);
++				rInfo = (NwcScanConnInfo *)pdata->repData;
++				cpylen = copy_to_user(pdata->repData, &pDConnInfo->uScanIndex, sizeof(pDConnInfo->uScanIndex));
++				cpylen = copy_to_user(&rInfo->uConnectionReference, &pDConnInfo->uConnectionReference, sizeof(pDConnInfo->uConnectionReference));
++			}
++			else
++			{
++			u_long x;
++
++				x = 0;
++				rInfo = (NwcScanConnInfo *)pdata->reqData;
++				cpylen = copy_to_user(&rInfo->uConnectionReference, &x, sizeof(rInfo->uConnectionReference));
++			}
++				
++			Novfs_Free(reply);
++		}
++      else
++      {
++         retCode = -EIO;
++      }
++		Novfs_Free(cmd);
++
++	}
++
++	return(retCode);
++}
++
++/*++======================================================================*/
++void	GetUserData(NwcScanConnInfo *connInfo, PXPLAT_CALL_REQUEST cmd, PXPLAT_CALL_REPLY reply)
++/*
++ *  Abstract:  Copies the user data out of the scan conn info call.
++ *
++ *========================================================================*/
++
++{
++u_long			uLevel;
++PNwdCScanConnInfo		pDConnInfo;
++
++u_char			*srcData = NULL;
++u_long			dataLen = 0, cpylen;
++
++	
++	pDConnInfo = (PNwdCScanConnInfo)reply->data;
++	uLevel = pDConnInfo->uReturnInfoLevel;
++	DbgPrint("[GetUserData] uLevel = %d, reply = 0x%X, reply->data = 0x%X\n", uLevel, reply, reply->data);
++
++	switch(uLevel)
++	{
++		case NWC_CONN_INFO_RETURN_ALL:
++		case NWC_CONN_INFO_TRAN_ADDR:
++		case NWC_CONN_INFO_NDS_STATE:
++		case NWC_CONN_INFO_MAX_PACKET_SIZE:
++		case NWC_CONN_INFO_LICENSE_STATE:
++		case NWC_CONN_INFO_PUBLIC_STATE:
++		case NWC_CONN_INFO_SERVICE_TYPE:
++		case NWC_CONN_INFO_DISTANCE:
++		case NWC_CONN_INFO_SERVER_VERSION:
++		case NWC_CONN_INFO_AUTH_ID:
++		case NWC_CONN_INFO_SUSPENDED:
++		case NWC_CONN_INFO_WORKGROUP_ID:
++		case NWC_CONN_INFO_SECURITY_STATE:
++		case NWC_CONN_INFO_CONN_NUMBER:
++		case NWC_CONN_INFO_USER_ID:
++		case NWC_CONN_INFO_BCAST_STATE:
++		case NWC_CONN_INFO_CONN_REF:
++		case NWC_CONN_INFO_AUTH_STATE:
++		case NWC_CONN_INFO_TREE_NAME:
++		case NWC_CONN_INFO_SERVER_NAME:
++		case NWC_CONN_INFO_VERSION:
++			srcData = (u_char *)pDConnInfo;
++			srcData += pDConnInfo->uReturnConnInfoOffset;
++			dataLen = pDConnInfo->uReturnInfoLength;
++			break;
++
++		case NWC_CONN_INFO_RETURN_NONE:
++		case NWC_CONN_INFO_TREE_NAME_UNICODE:
++		case NWC_CONN_INFO_SERVER_NAME_UNICODE:
++		case NWC_CONN_INFO_LOCAL_TRAN_ADDR:
++		case NWC_CONN_INFO_ALTERNATE_ADDR:
++		case NWC_CONN_INFO_SERVER_GUID:
++		default:
++		break;
++	}
++
++	if (srcData && dataLen)
++	{
++		DbgPrint("Copy Data in GetUserData 0x%X -> 0x%X :: 0x%X\n",
++						srcData, connInfo->pReturnConnInfo, dataLen);			
++		cpylen = copy_to_user(connInfo->pReturnConnInfo, srcData, dataLen);
++	}
++
++	return;
++}
++
++/*++======================================================================*/
++void	GetConnData(NwcGetConnInfo *connInfo, PXPLAT_CALL_REQUEST cmd, PXPLAT_CALL_REPLY reply)
++/*
++ *  Abstract:  Copies the user data out of the scan conn info call.
++ *
++ *========================================================================*/
++
++{
++u_long			uLevel;
++PNwdCGetConnInfo		pDConnInfo;
++
++u_char			*srcData = NULL;
++u_long			dataLen = 0, cpylen;
++
++	
++	pDConnInfo = (PNwdCGetConnInfo)cmd->data;
++	uLevel = pDConnInfo->uInfoLevel;
++
++	switch(uLevel)
++	{
++		case NWC_CONN_INFO_RETURN_ALL:
++			srcData = (u_char *)reply->data;
++			dataLen = reply->dataLen;
++		break;
++
++		case NWC_CONN_INFO_RETURN_NONE:
++			dataLen = 0;
++		break;
++
++		case NWC_CONN_INFO_TRAN_ADDR:
++      {
++         u_char *dstData = connInfo->pConnInfo;
++         NwcTranAddr tranAddr;
++
++         srcData = (u_char *)reply->data;
++
++         cpylen = copy_from_user(&tranAddr, dstData, sizeof(tranAddr));
++         tranAddr.uTransportType = ((PNwdTranAddr)srcData)->uTransportType;
++         tranAddr.uAddressLength = ((PNwdTranAddr)srcData)->uAddressLength;
++         cpylen = copy_to_user(dstData, &tranAddr, sizeof(tranAddr));
++         cpylen = copy_to_user(tranAddr.puAddress, ((PNwdTranAddr)srcData)->Buffer, ((PNwdTranAddr)srcData)->uAddressLength);
++         dataLen=0;
++         break;
++      }
++		case NWC_CONN_INFO_NDS_STATE:
++		case NWC_CONN_INFO_MAX_PACKET_SIZE:
++		case NWC_CONN_INFO_LICENSE_STATE:
++		case NWC_CONN_INFO_PUBLIC_STATE:
++		case NWC_CONN_INFO_SERVICE_TYPE:
++		case NWC_CONN_INFO_DISTANCE:
++		case NWC_CONN_INFO_SERVER_VERSION:
++		case NWC_CONN_INFO_AUTH_ID:
++		case NWC_CONN_INFO_SUSPENDED:
++		case NWC_CONN_INFO_WORKGROUP_ID:
++		case NWC_CONN_INFO_SECURITY_STATE:
++		case NWC_CONN_INFO_CONN_NUMBER:
++		case NWC_CONN_INFO_USER_ID:
++		case NWC_CONN_INFO_BCAST_STATE:
++		case NWC_CONN_INFO_CONN_REF:
++		case NWC_CONN_INFO_AUTH_STATE:
++		case NWC_CONN_INFO_VERSION:
++		case NWC_CONN_INFO_SERVER_NAME:
++		case NWC_CONN_INFO_TREE_NAME:
++			srcData = (u_char *)reply->data;
++			dataLen = reply->dataLen;
++		break;
++
++		case NWC_CONN_INFO_TREE_NAME_UNICODE:
++		case NWC_CONN_INFO_SERVER_NAME_UNICODE:
++		break;
++
++		case NWC_CONN_INFO_LOCAL_TRAN_ADDR:
++		break;
++
++		case NWC_CONN_INFO_ALTERNATE_ADDR:
++		break;
++
++		case NWC_CONN_INFO_SERVER_GUID:
++		break;
++
++		default:
++		break;
++	}
++
++	if (srcData && dataLen)
++	{
++		cpylen = copy_to_user(connInfo->pConnInfo, srcData, connInfo->uInfoLength);
++	}
++
++	return;
++}
++
++/*++======================================================================*/
++int	 NwGetDaemonVersion(PXPLAT pdata, session_t Session)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++
++{
++PXPLAT_CALL_REQUEST			cmd;
++PXPLAT_CALL_REPLY			reply;
++PNwdCGetRequesterVersion	pDVersion;
++u_long				retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
++
++	datalen = sizeof(*pDVersion);
++	cmdlen = datalen + sizeof(*cmd);
++	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++
++	if (cmd)
++	{
++		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++		cmd->Command.SequenceNumber = 0;
++		cmd->Command.SessionId      = Session;
++		cmd->NwcCommand = NWC_GET_REQUESTER_VERSION;
++		cmdlen = sizeof(*cmd);
++		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
++		if (reply)
++		{
++			retCode = reply->Reply.ErrorCode;
++			pDVersion = (PNwdCGetRequesterVersion)reply->data;
++			cpylen = copy_to_user(pDVersion, pdata->reqData, sizeof(*pDVersion));
++			Novfs_Free(reply);
++		}
++		Novfs_Free(cmd);
++	}
++	return(retCode);
++
++}
++
++
++/*++======================================================================*/
++int	 NwcGetPreferredDSTree(PXPLAT pdata, session_t Session)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++
++{
++PXPLAT_CALL_REQUEST			cmd;
++PXPLAT_CALL_REPLY			reply;
++PNwdCGetPreferredDsTree		pDGetTree;
++NwcGetPreferredDsTree		xplatCall, *p;
++u_long				retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
++u_char				*dPtr;
++
++	cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcGetPreferredDsTree));
++	datalen = sizeof(*pDGetTree) + xplatCall.uTreeLength;
++	cmdlen = datalen + sizeof(*cmd);
++	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++
++	if (cmd)
++	{
++		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++		cmd->Command.SequenceNumber = 0;
++		cmd->Command.SessionId      = Session;
++		cmd->NwcCommand = NWC_GET_PREFERRED_DS_TREE;
++		cmdlen = sizeof(*cmd);
++
++		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
++		if (reply)
++		{
++			retCode = reply->Reply.ErrorCode;
++			if (!retCode)
++			{
++				pDGetTree = (PNwdCGetPreferredDsTree)reply->data;
++				dPtr = reply->data + pDGetTree->DsTreeNameOffset;
++				p = (NwcGetPreferredDsTree *)pdata->reqData;
++
++				DbgPrint("NwcGetPreferredDSTree: Reply recieved\n");
++				DbgPrint("   TreeLen = %x\n", pDGetTree->uTreeLength);
++				DbgPrint("   TreeName = %s\n", dPtr);
++
++				cpylen = copy_to_user(p, &pDGetTree->uTreeLength, 4);
++				cpylen = copy_to_user(xplatCall.pDsTreeName, dPtr, pDGetTree->uTreeLength);
++			}
++         Novfs_Free(reply);
++		}
++		Novfs_Free(cmd);
++	}
++	return(retCode);
++
++}
++
++/*++======================================================================*/
++int	 NwcSetPreferredDSTree(PXPLAT pdata, session_t Session)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++
++{
++PXPLAT_CALL_REQUEST			cmd;
++PXPLAT_CALL_REPLY			reply;
++PNwdCSetPreferredDsTree		pDSetTree;
++NwcSetPreferredDsTree		xplatCall;
++u_long				retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
++u_char				*dPtr;
++
++	cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcSetPreferredDsTree));
++	datalen = sizeof(*pDSetTree) + xplatCall.uTreeLength;
++	cmdlen = datalen + sizeof(*cmd);
++	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++
++	if (cmd)
++	{
++		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++		cmd->Command.SequenceNumber = 0;
++		cmd->Command.SessionId      = Session;
++		cmd->NwcCommand = NWC_SET_PREFERRED_DS_TREE;
++
++		pDSetTree = (PNwdCSetPreferredDsTree)cmd->data;
++		pDSetTree->DsTreeNameOffset = sizeof(*pDSetTree);
++		pDSetTree->uTreeLength = xplatCall.uTreeLength;
++
++		dPtr = cmd->data + sizeof(*pDSetTree);
++		cpylen = copy_from_user(dPtr, xplatCall.pDsTreeName, xplatCall.uTreeLength);
++		
++
++		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
++		if (reply)
++		{
++         retCode = reply->Reply.ErrorCode;
++         Novfs_Free(reply);
++		}
++		Novfs_Free(cmd);
++	}
++	return(retCode);
++
++}
++
++
++/*++======================================================================*/
++int	 NwcSetDefaultNameCtx(PXPLAT pdata, session_t Session)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++
++{
++PXPLAT_CALL_REQUEST			cmd;
++PXPLAT_CALL_REPLY			reply;
++NwcSetDefaultNameContext	xplatCall;
++PNwdCSetDefaultNameContext	pDSet;
++u_long				retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen;
++u_char				*dPtr;
++
++	cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcSetDefaultNameContext));
++	datalen = sizeof(*pDSet) + xplatCall.uTreeLength + xplatCall.uNameLength;
++	cmdlen = datalen + sizeof(*cmd);
++	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++
++	if (cmd)
++	{
++		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++		cmd->Command.SequenceNumber = 0;
++		cmd->Command.SessionId      = Session;
++		cmd->NwcCommand = NWC_SET_DEFAULT_NAME_CONTEXT;
++      cmd->dataLen = sizeof(NwdCSetDefaultNameContext) + xplatCall.uTreeLength + xplatCall.uNameLength;
++
++		pDSet = (PNwdCSetDefaultNameContext)cmd->data;
++      dPtr  = cmd->data;
++
++      pDSet->TreeOffset = sizeof(NwdCSetDefaultNameContext);
++      pDSet->uTreeLength = xplatCall.uTreeLength;
++      pDSet->NameContextOffset = pDSet->TreeOffset+xplatCall.uTreeLength;
++      pDSet->uNameLength = xplatCall.uNameLength;
++
++      cpylen = copy_from_user(dPtr+pDSet->TreeOffset, xplatCall.pTreeName, xplatCall.uTreeLength);
++		cpylen = copy_from_user(dPtr+pDSet->NameContextOffset, xplatCall.pNameContext, xplatCall.uNameLength);
++
++		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
++		if (reply)
++		{
++            retCode = reply->Reply.ErrorCode;
++            Novfs_Free(reply);
++		}
++		Novfs_Free(cmd);
++	}
++	return(retCode);
++
++}
++
++/*++======================================================================*/
++int	 NwcGetDefaultNameCtx(PXPLAT pdata, session_t Session)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++
++{
++PXPLAT_CALL_REQUEST			cmd;
++PXPLAT_CALL_REPLY			reply;
++NwcGetDefaultNameContext	xplatCall;
++PNwdCGetDefaultNameContext pGet;
++char *dPtr;
++int retCode = -ENOMEM;
++u_long cmdlen, replylen, cpylen;
++
++	cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcGetDefaultNameContext));
++	cmdlen = sizeof(*cmd) + sizeof(NwdCGetDefaultNameContext) + xplatCall.uTreeLength;
++	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++
++	if (cmd)
++	{
++		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++		cmd->Command.SequenceNumber = 0;
++		cmd->Command.SessionId      = Session;
++		cmd->NwcCommand = NWC_GET_DEFAULT_NAME_CONTEXT;
++      cmd->dataLen = sizeof(NwdCGetDefaultNameContext)+xplatCall.uTreeLength;
++
++      pGet = (PNwdCGetDefaultNameContext)cmd->data;
++      dPtr = cmd->data;
++
++      pGet->TreeOffset = sizeof(NwdCGetDefaultNameContext);
++      pGet->uTreeLength = xplatCall.uTreeLength;
++
++      cpylen = copy_from_user( dPtr + pGet->TreeOffset, xplatCall.pTreeName, xplatCall.uTreeLength);
++      dPtr[pGet->TreeOffset+pGet->uTreeLength] = 0;
++
++		retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
++		if (reply)
++		{
++         retCode = reply->Reply.ErrorCode;
++         if (!retCode)
++         {
++            pGet = (PNwdCGetDefaultNameContext)reply->data;
++
++            DbgPrint("NwcGetDefaultNameCtx: retCode=0x%x uNameLength1=%d uNameLength2=%d\n", retCode, pGet->uNameLength, xplatCall.uNameLength);
++            if (xplatCall.uNameLength < pGet->uNameLength)
++            {
++               pGet->uNameLength = xplatCall.uNameLength;
++               retCode = NWE_BUFFER_OVERFLOW;
++            }
++            dPtr = (char *)pGet + pGet->NameContextOffset;
++            cpylen = copy_to_user(xplatCall.pNameContext, dPtr, pGet->uNameLength);
++         }
++
++         Novfs_Free(reply);
++		}
++		Novfs_Free(cmd);
++	}
++	return(retCode);
++
++}
++
++/*++======================================================================*/
++int NwQueryFeature(PXPLAT pdata, session_t Session)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   NwcQueryFeature xpCall;
++   int status = SUCCESS;
++   u_long cpylen;
++
++   cpylen = copy_from_user(&xpCall, pdata->reqData, sizeof(NwcQueryFeature));
++   switch (xpCall.Feature)   
++   {
++      case NWC_FEAT_NDS:
++      case NWC_FEAT_NDS_MTREE:
++      case NWC_FEAT_PRN_CAPTURE:
++      case NWC_FEAT_NDS_RESOLVE:
++
++      status = NWE_REQUESTER_FAILURE;  
++
++   }
++   return( status );
++}
++
++/*++======================================================================*/
++int	NwcGetTreeMonitoredConn(PXPLAT pdata, session_t Session)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++PXPLAT_CALL_REQUEST				cmd;
++PXPLAT_CALL_REPLY				reply;
++NwcGetTreeMonitoredConnRef		xplatCall, *p;
++PNwdCGetTreeMonitoredConnRef	pDConnRef;
++char							*dPtr;
++u_long					status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
++
++	cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcGetTreeMonitoredConnRef));
++	datalen = sizeof(*pDConnRef) + xplatCall.pTreeName->DataLen;
++	cmdlen = datalen + sizeof(*cmd);
++	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++
++	if (cmd)
++	{
++		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++		cmd->Command.SequenceNumber = 0;
++		cmd->Command.SessionId      = Session;
++		cmd->NwcCommand = NWC_GET_TREE_MONITORED_CONN_REF;
++
++		pDConnRef = (PNwdCGetTreeMonitoredConnRef)cmd->data;
++		pDConnRef->TreeName.boffset = sizeof(*pDConnRef);
++		pDConnRef->TreeName.len = xplatCall.pTreeName->DataLen;
++		pDConnRef->TreeName.type = xplatCall.pTreeName->DataType;
++
++		dPtr = cmd->data + sizeof(*pDConnRef);
++		cpylen = copy_from_user(dPtr, xplatCall.pTreeName->pBuffer, pDConnRef->TreeName.len);
++		status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
++		if (reply)
++		{
++			pDConnRef = (PNwdCGetTreeMonitoredConnRef)reply->data;
++			dPtr = reply->data + pDConnRef->TreeName.boffset;
++			p = (NwcGetTreeMonitoredConnRef *)pdata->reqData;
++			cpylen = copy_to_user(&p->uConnReference, &pDConnRef->uConnReference, 4);
++
++			status = reply->Reply.ErrorCode;
++         Novfs_Free(reply);
++		}
++		Novfs_Free(cmd);
++
++	}
++
++	return(status);
++}
++
++/*++======================================================================*/
++int	NwcEnumIdentities(PXPLAT pdata, session_t Session)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++PXPLAT_CALL_REQUEST				cmd;
++PXPLAT_CALL_REPLY				reply;
++NwcEnumerateIdentities			xplatCall, *eId;
++PNwdCEnumerateIdentities		pEnum;
++NwcString						xferStr;
++char							*str;
++u_long					status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
++
++	cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcEnumerateIdentities));
++	datalen = sizeof(*pEnum);
++	cmdlen = datalen + sizeof(*cmd);
++	cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++
++	if (cmd)
++	{
++		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++		cmd->Command.SequenceNumber = 0;
++		cmd->Command.SessionId      = Session;
++		cmd->NwcCommand = NWC_ENUMERATE_IDENTITIES;
++
++		DbgPrint("NwcEnumIdentities: Send Request\n");
++		DbgPrint("   iterator = %x\n", xplatCall.Iterator);
++		DbgPrint("   cmdlen = %d\n", cmdlen);
++
++		pEnum = (PNwdCEnumerateIdentities)cmd->data;
++		pEnum->Iterator = xplatCall.Iterator;
++		status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
++		if (reply)
++		{
++			status = reply->Reply.ErrorCode;
++			
++			eId = pdata->repData;
++			pEnum = (PNwdCEnumerateIdentities)reply->data;
++			cpylen = copy_to_user(&eId->Iterator, &pEnum->Iterator, sizeof(pEnum->Iterator));
++			DbgPrint("[XPLAT NWCAPI] Found AuthId 0x%X\n", pEnum->AuthenticationId);
++			cpylen = copy_to_user(&eId->AuthenticationId, &pEnum->AuthenticationId, sizeof(pEnum->AuthenticationId));
++			cpylen = copy_to_user(&eId->AuthType, &pEnum->AuthType, sizeof(pEnum->AuthType));
++			cpylen = copy_to_user(&eId->IdentityFlags, &pEnum->IdentityFlags, sizeof(pEnum->IdentityFlags));
++			cpylen = copy_to_user(&eId->NameType, &pEnum->NameType, sizeof(pEnum->NameType));
++			cpylen = copy_to_user(&eId->ObjectType, &pEnum->ObjectType, sizeof(pEnum->ObjectType));
++
++			if (!status)
++			{
++				cpylen = copy_from_user(&xferStr, eId->pDomainName, sizeof(NwcString));
++				str = (char *)((char *)reply->data + pEnum->domainNameOffset);
++				DbgPrint("[XPLAT NWCAPI] Found Domain %s\n", str);
++				cpylen = copy_to_user(xferStr.pBuffer, str, pEnum->domainNameLen);
++				xferStr.DataType = NWC_STRING_TYPE_ASCII;
++				xferStr.DataLen = pEnum->domainNameLen - 1;
++				cpylen = copy_to_user(eId->pDomainName, &xferStr, sizeof(NwcString));
++
++
++				cpylen = copy_from_user(&xferStr, eId->pObjectName, sizeof(NwcString));
++				str = (char *)((char *)reply->data + pEnum->objectNameOffset);
++				DbgPrint("[XPLAT NWCAPI] Found User %s\n", str);
++				cpylen = copy_to_user(xferStr.pBuffer, str, pEnum->objectNameLen);
++				xferStr.DataType = NWC_STRING_TYPE_ASCII;
++				xferStr.DataLen = pEnum->objectNameLen - 1;
++				cpylen = copy_to_user(eId->pObjectName, &xferStr, sizeof(NwcString));
++			}
++
++		    Novfs_Free(reply);
++
++		}
++		Novfs_Free(cmd);
++
++	}
++	return(status);
++}
++
++/*++======================================================================*/
++int	NwcChangeAuthKey(PXPLAT pdata, session_t Session)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract: Change the password on the server
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++PXPLAT_CALL_REQUEST				cmd;
++PXPLAT_CALL_REPLY				reply;
++NwcChangeKey			        xplatCall;
++PNwdCChangeKey		            pNewKey;
++NwcString						xferStr;
++char							*str;
++u_long                          status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
++
++	cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcChangeKey));
++
++    datalen = sizeof(NwdCChangeKey) + xplatCall.pDomainName->DataLen + xplatCall.pObjectName->DataLen
++        + xplatCall.pNewPassword->DataLen + xplatCall.pVerifyPassword->DataLen;
++
++    cmdlen = sizeof(*cmd) + datalen;
++    cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++
++    if (cmd)
++    {
++        pNewKey = (PNwdCChangeKey)cmd->data;
++        cmd->dataLen = datalen;
++   		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++		cmd->Command.SequenceNumber = 0;
++		cmd->Command.SessionId      = Session;
++		cmd->NwcCommand = NWC_CHANGE_KEY;
++
++        pNewKey->NameType = xplatCall.NameType;
++        pNewKey->ObjectType = xplatCall.ObjectType;
++        pNewKey->AuthType = xplatCall.AuthType;
++        str = (char *)pNewKey;
++
++        /*
++         * Get the tree name
++         */
++        str += sizeof(*pNewKey);
++        cpylen = copy_from_user(&xferStr, xplatCall.pDomainName, sizeof(NwcString));
++        pNewKey->domainNameOffset = sizeof(*pNewKey);
++        cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
++        pNewKey->domainNameLen = xferStr.DataLen;
++
++        /*
++         * Get the User Name
++         */
++        str += pNewKey->domainNameLen;
++        cpylen = copy_from_user(&xferStr, xplatCall.pObjectName, sizeof(NwcString));
++        pNewKey->objectNameOffset = pNewKey->domainNameOffset + pNewKey->domainNameLen;
++        cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
++        pNewKey->objectNameLen = xferStr.DataLen;
++
++        /*
++         * Get the New Password
++         */
++        str += pNewKey->objectNameLen;
++        cpylen = copy_from_user(&xferStr, xplatCall.pNewPassword, sizeof(NwcString));
++        pNewKey->newPasswordOffset = pNewKey->objectNameOffset + pNewKey->objectNameLen;
++        cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
++        pNewKey->newPasswordLen = xferStr.DataLen;
++
++        /*
++         * Get the Verify Password
++         */
++        str += pNewKey->newPasswordLen;
++        cpylen = copy_from_user(&xferStr, xplatCall.pVerifyPassword, sizeof(NwcString));
++        pNewKey->verifyPasswordOffset = pNewKey->newPasswordOffset + pNewKey->newPasswordLen;
++        cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
++        pNewKey->verifyPasswordLen = xferStr.DataLen;
++
++		status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
++        if (reply)
++        {
++            status = reply->Reply.ErrorCode;
++            Novfs_Free(reply);
++        }
++        memset(cmd, 0, cmdlen);
++
++        Novfs_Free(cmd);
++    }
++
++	return(status);
++}
++
++/*++======================================================================*/
++int	NwcSetPrimaryConn(PXPLAT pdata, session_t Session)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract: Set the primary connection Id
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++PXPLAT_CALL_REQUEST        cmd;
++PXPLAT_CALL_REPLY          reply;
++NwcSetPrimaryConnection    xplatCall;
++PNwdCSetPrimaryConnection  pConn;
++u_long                     status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
++
++   cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcSetPrimaryConnection));
++
++   datalen = sizeof(NwdCSetPrimaryConnection);
++   cmdlen = sizeof(*cmd) + datalen;
++   cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++   if (cmd)
++   {
++      pConn = (PNwdCSetPrimaryConnection)cmd->data;
++      cmd->dataLen = datalen;
++      cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++      cmd->Command.SequenceNumber = 0;
++      cmd->Command.SessionId      = Session;
++      cmd->NwcCommand = NWC_SET_PRIMARY_CONN;
++      pConn->ConnHandle = xplatCall.ConnHandle;
++      status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
++
++      if (reply)
++      {
++         status = reply->Reply.ErrorCode;
++         Novfs_Free(reply);
++      }
++
++      Novfs_Free(cmd);
++   }
++
++   return(status);
++}
++
++/*++======================================================================*/
++int	NwcGetPrimaryConn(PXPLAT pdata, session_t Session)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract: Get the Primary connection 
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++XPLAT_CALL_REQUEST   cmd;
++PXPLAT_CALL_REPLY    reply;
++u_long               status = -ENOMEM, cmdlen, replylen, cpylen;
++
++
++   cmdlen = (u_long)(&((PXPLAT_CALL_REQUEST)0)->data);
++
++   cmd.dataLen = 0;
++   cmd.Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++   cmd.Command.SequenceNumber = 0;
++   cmd.Command.SessionId      = Session;
++   cmd.NwcCommand = NWC_GET_PRIMARY_CONN;
++
++   status = Queue_Daemon_Command((void *)&cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
++
++   if (reply)
++   {
++      status = reply->Reply.ErrorCode;
++      if (!status)
++      {
++         cpylen = copy_to_user(pdata->repData, reply->data, sizeof(u_long));
++      }
++
++      Novfs_Free(reply);
++   }
++
++   return(status);
++}
++
++
++/*++======================================================================*/
++int	NwcSetMapDrive(PXPLAT pdata, session_t Session)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract: Get the Primary connection 
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++
++PXPLAT_CALL_REQUEST     cmd;
++PXPLAT_CALL_REPLY       reply;
++u_long                  status = 0, datalen, cmdlen, replylen, cpylen;
++NwcMapDriveEx           symInfo;
++
++    DbgPrint("Call to NwcSetMapDrive\n");
++    cpylen = copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo));
++    cmdlen = sizeof(*cmd);
++    datalen = sizeof(symInfo) + symInfo.dirPathOffsetLength + symInfo.linkOffsetLength;
++
++    DbgPrint(" cmdlen = %d\n", cmdlen);
++    DbgPrint(" dataLen = %d\n", datalen);
++    DbgPrint(" symInfo.dirPathOffsetLength = %d\n", symInfo.dirPathOffsetLength);
++    DbgPrint(" symInfo.linkOffsetLength = %d\n", symInfo.linkOffsetLength);
++    DbgPrint(" pdata->datalen = %d\n", pdata->reqLen);
++
++    mydump(sizeof(symInfo), &symInfo);
++
++    cmdlen += datalen;
++
++
++    cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++    if (cmd)
++    {
++        cmd->dataLen = datalen;
++        cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++        cmd->Command.SequenceNumber = 0;
++        cmd->Command.SessionId      = Session;
++        cmd->NwcCommand = NWC_MAP_DRIVE;
++
++        cpylen = copy_from_user(cmd->data, pdata->reqData, datalen);
++        status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
++
++        if (reply)
++        {
++            status = reply->Reply.ErrorCode;
++            Novfs_Free(reply);
++        }
++        Novfs_Free(cmd);
++    }
++    return(status);
++
++}
++
++/*++======================================================================*/
++int	NwcUnMapDrive(PXPLAT pdata, session_t Session)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract: Get the Primary connection 
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++PXPLAT_CALL_REQUEST     cmd;
++PXPLAT_CALL_REPLY       reply;
++u_long             status = 0, datalen, cmdlen, replylen, cpylen;
++NwcUnmapDriveEx    symInfo;
++
++    DbgPrint("Call to NwcUnMapDrive\n");
++
++    cpylen = copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo));
++    cmdlen = sizeof(*cmd);
++    datalen = sizeof(symInfo) + symInfo.linkLen;
++
++    cmdlen += datalen;
++    cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++    if (cmd)
++    {
++        cmd->dataLen = datalen;
++        cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++        cmd->Command.SequenceNumber = 0;
++        cmd->Command.SessionId      = Session;
++        cmd->NwcCommand = NWC_UNMAP_DRIVE;
++
++        cpylen = copy_from_user(cmd->data, pdata->reqData, datalen);
++        status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
++
++        if (reply)
++        {
++            status = reply->Reply.ErrorCode;
++            Novfs_Free(reply);
++        }
++        Novfs_Free(cmd);
++    }
++
++    return(status);
++}
++
++
++/*++======================================================================*/
++int	NwcEnumerateDrives(PXPLAT pdata, session_t Session)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract: Get the Primary connection 
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++PXPLAT_CALL_REQUEST     cmd;
++PXPLAT_CALL_REPLY       reply;
++u_long                  status = 0, cmdlen, replylen, cpylen;
++u_long                  offset;
++char                    *cp;
++
++    DbgPrint("Call to NwcEnumerateDrives\n");
++
++    cmdlen = sizeof(*cmd);
++    cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++    if (cmd)
++    {
++        cmd->dataLen = 0;
++        cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++        cmd->Command.SequenceNumber = 0;
++        cmd->Command.SessionId      = Session;
++        cmd->NwcCommand = NWC_ENUMERATE_DRIVES;
++        status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
++
++        if (reply)
++        {
++            status = reply->Reply.ErrorCode;
++            DbgPrint("Status Code = 0x%X\n", status);
++            if (!status)
++            {
++                offset = sizeof(u_long);
++                cp = reply->data;
++                replylen = ((PNwcGetMappedDrives)pdata->repData)->MapBuffLen;
++                cpylen = copy_to_user(pdata->repData, cp, offset);
++                cp += offset;
++                cpylen = copy_to_user(((PNwcGetMappedDrives)pdata->repData)->MapBuffer, cp, min(replylen - offset, reply->dataLen - offset));
++            }
++
++            Novfs_Free(reply);
++        }
++        Novfs_Free(cmd);
++    }
++
++    return(status);
++}
++
++
++/*++======================================================================*/
++int	NwcGetBroadcastMessage(PXPLAT pdata, session_t Session)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract: Get the Primary connection 
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++PXPLAT_CALL_REQUEST             cmd;
++PXPLAT_CALL_REPLY               reply;
++u_long                          status = 0x8866, cmdlen, replylen, cpylen;
++NwcGetBroadcastNotification     msg;
++PNwdCGetBroadcastNotification   dmsg;
++
++    cmdlen = sizeof(*cmd) + sizeof(*dmsg);
++    cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++    if (cmd)
++    {
++
++        cpylen = copy_from_user(&msg, pdata->reqData, sizeof(msg));
++        cmd->dataLen = sizeof(*dmsg);
++        cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++        cmd->Command.SequenceNumber = 0;
++        cmd->Command.SessionId      = Session;
++
++        cmd->NwcCommand = NWC_GET_BROADCAST_MESSAGE;
++        dmsg = (PNwdCGetBroadcastNotification)cmd->data;
++        dmsg->uConnReference = msg.uConnReference;
++        
++        status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
++
++        if (reply)
++        {
++            status = reply->Reply.ErrorCode;
++            DbgPrint("Status Code = 0x%X\n", status);
++            if (!status)
++            {
++                /* we have a message so copy it to the user buffer */
++                cpylen = copy_to_user(pdata->repData, reply->data, min(pdata->repLen, reply->dataLen));
++            }
++            else
++            {
++                msg.messageLen = 0;
++                msg.message[0] = 0;
++                cpylen = copy_to_user(pdata->repData, &msg, sizeof(msg));
++            }
++
++            Novfs_Free(reply);
++        }
++        Novfs_Free(cmd);
++    }
++    return(status);
++
++}
++
++
++int NwdSetKeyValue(PXPLAT pdata, session_t Session)
++{
++PXPLAT_CALL_REQUEST     cmd;
++PXPLAT_CALL_REPLY	    reply;
++NwcSetKey               xplatCall;
++PNwdCSetKey             pNewKey;
++NwcString               cstrObjectName, cstrPassword;
++char                    *str;
++u_long                  status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
++
++   cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcSetKey));
++   cpylen = copy_from_user(&cstrObjectName, xplatCall.pObjectName, sizeof(NwcString));
++   cpylen = copy_from_user(&cstrPassword, xplatCall.pNewPassword, sizeof(NwcString));
++
++   datalen = sizeof(NwdCSetKey) + cstrObjectName.DataLen + cstrPassword.DataLen;
++
++   cmdlen = sizeof(*cmd) + datalen;
++   cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++
++   if (cmd)
++   {
++      pNewKey = (PNwdCSetKey)cmd->data;
++      cmd->dataLen = datalen;
++      cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++      cmd->Command.SequenceNumber = 0;
++      cmd->Command.SessionId      = Session;
++      cmd->NwcCommand = NWC_SET_KEY;
++
++      pNewKey->ObjectType = xplatCall.ObjectType;
++      pNewKey->AuthenticationId = xplatCall.AuthenticationId;
++      pNewKey->ConnHandle = xplatCall.ConnHandle;
++      str = (char *)pNewKey;
++
++      /*
++       * Get the User Name
++       */
++      str += sizeof(NwdCSetKey);
++      cpylen = copy_from_user(str, cstrObjectName.pBuffer, cstrObjectName.DataLen);
++
++      str += 
++      pNewKey->objectNameLen = cstrObjectName.DataLen;
++      pNewKey->objectNameOffset = sizeof(NwdCSetKey);
++
++      /*
++       * Get the Verify Password
++       */
++      cpylen = copy_from_user(str, cstrPassword.pBuffer, cstrPassword.DataLen);
++
++      pNewKey->newPasswordLen = cstrPassword.DataLen;
++      pNewKey->newPasswordOffset = pNewKey->objectNameOffset+pNewKey->objectNameLen;
++
++      status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
++      if (reply)
++      {
++         status = reply->Reply.ErrorCode;
++         Novfs_Free(reply);
++      }
++      memset(cmd, 0, cmdlen);
++      Novfs_Free(cmd);
++   }
++
++   return(status);
++}
++ 
++/*++======================================================================*/
++int NwdVerifyKeyValue(PXPLAT pdata, session_t Session)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract: Change the password on the server
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++PXPLAT_CALL_REQUEST				cmd;
++PXPLAT_CALL_REPLY				reply;
++NwcVerifyKey			        xplatCall;
++PNwdCVerifyKey		            pNewKey;
++NwcString						xferStr;
++char							*str;
++u_long                          status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
++
++	cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcVerifyKey));
++
++    datalen = sizeof(NwdCVerifyKey) + xplatCall.pDomainName->DataLen + xplatCall.pObjectName->DataLen
++        + xplatCall.pVerifyPassword->DataLen;
++
++    cmdlen = sizeof(*cmd) + datalen;
++    cmd = Novfs_Malloc(cmdlen, GFP_KERNEL);
++
++    if (cmd)
++    {
++        pNewKey = (PNwdCVerifyKey)cmd->data;
++        cmd->dataLen = datalen;
++   		cmd->Command.CommandType    = VFS_COMMAND_XPLAT_CALL;
++		cmd->Command.SequenceNumber = 0;
++		cmd->Command.SessionId      = Session;
++		cmd->NwcCommand = NWC_VERIFY_KEY;
++
++        pNewKey->NameType = xplatCall.NameType;
++        pNewKey->ObjectType = xplatCall.ObjectType;
++        pNewKey->AuthType = xplatCall.AuthType;
++        str = (char *)pNewKey;
++
++        /*
++         * Get the tree name
++         */
++        str += sizeof(*pNewKey);
++        cpylen = copy_from_user(&xferStr, xplatCall.pDomainName, sizeof(NwcString));
++        pNewKey->domainNameOffset = sizeof(*pNewKey);
++        cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
++        pNewKey->domainNameLen = xferStr.DataLen;
++
++        /*
++         * Get the User Name
++         */
++        str += pNewKey->domainNameLen;
++        cpylen = copy_from_user(&xferStr, xplatCall.pObjectName, sizeof(NwcString));
++        pNewKey->objectNameOffset = pNewKey->domainNameOffset + pNewKey->domainNameLen;
++        cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
++        pNewKey->objectNameLen = xferStr.DataLen;
++
++        /*
++         * Get the Verify Password
++         */
++        str += pNewKey->objectNameLen;
++        cpylen = copy_from_user(&xferStr, xplatCall.pVerifyPassword, sizeof(NwcString));
++        pNewKey->verifyPasswordOffset = pNewKey->objectNameOffset + pNewKey->objectNameLen;
++        cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
++        pNewKey->verifyPasswordLen = xferStr.DataLen;
++
++		status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
++        if (reply)
++        {
++            status = reply->Reply.ErrorCode;
++            Novfs_Free(reply);
++        }
++        memset(cmd, 0, cmdlen);
++        Novfs_Free(cmd);
++    }
++
++	return(status);
++}
+diff -uNr src.old/src/proc.c src/src/proc.c
+--- src.old/src/proc.c	1970-01-01 01:00:00.000000000 +0100
++++ src/src/proc.c	2006-10-16 15:08:22.000000000 +0200
+@@ -0,0 +1,339 @@
++/*++========================================================================
++ * Program Name:     Novell NCP Redirector for Linux
++ * File Name:        proc.c
++ * Version:          v1.00
++ * Author:           James Turner
++ *
++ * Abstract:         This module contains functions that create the
++ *                   interface to the proc filesystem.
++ * Notes:
++ * Revision History: 
++ *
++ *
++ * Copyright (C) 2005 Novell, Inc.
++ *
++ * 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 files specific to Linux ]==================================*/
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/proc_fs.h>
++#include <linux/smp_lock.h>
++
++/*===[ Include files specific to this module ]============================*/
++#include "vfs.h"
++
++/*===[ External data ]====================================================*/
++extern char *Novfs_CurrentMount;
++
++/*===[ External prototypes ]==============================================*/
++extern int DbgPrint( char *Fmt, ... );
++
++extern ssize_t
++Daemon_Receive_Reply(struct file *file, const char *buf, size_t nbytes, loff_t *ppos);
++
++extern ssize_t 
++Daemon_Send_Command(struct file *file, char *buf, size_t len, loff_t *off);
++
++extern int Daemon_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
++
++extern int     Daemon_Library_close(struct inode *inode, struct file *file);
++extern int     Daemon_Library_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
++extern int     Daemon_Library_open(struct inode *inode, struct file *file);
++extern ssize_t Daemon_Library_read(struct file *file, char *buf, size_t len, loff_t *off);
++extern ssize_t Daemon_Library_write(struct file *file, const char *buf, size_t len, loff_t *off);
++extern loff_t  Daemon_Library_llseek(struct file *file, loff_t offset, int origin);
++
++extern int Daemon_Open_Control(struct inode *Inode, struct file *File);
++extern int Daemon_Close_Control(struct inode *Inode, struct file *File);
++
++extern int Daemon_getversion( char *Buf, int Length );
++
++/*===[ Manifest constants ]===============================================*/
++
++/*===[ Type definitions ]=================================================*/
++
++/*===[ Function prototypes ]==============================================*/
++ssize_t
++Novfs_User_proc_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos);
++
++ssize_t
++Novfs_User_proc_write(struct file * file, char * buf, size_t nbytes, loff_t *ppos);
++
++int Novfs_User_proc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
++
++int Init_Procfs_Interface( void );
++void Uninit_Procfs_Interface( void );
++
++/*===[ Global variables ]=================================================*/
++struct proc_dir_entry *Novfs_Procfs_dir, *Novfs_Control, *Novfs_Library, *Novfs_Version;
++static struct file_operations Daemon_proc_fops;
++static struct file_operations Library_proc_fops;
++
++/*===[ Code ]=============================================================*/
++
++/*++======================================================================*/
++int Novfs_Get_Version(char *page, char **start, off_t off, int count, int *eof, void *data)
++/*
++ * Arguments:
++ * 
++ * Returns:
++ * 
++ * Abstract:
++ * 
++ * Notes:
++ * 
++ * Environment:
++ * 
++ *========================================================================*/
++{
++   char *buf, tbuf[48];
++   int len=0, i;
++
++   if ( !off )   
++   {
++      buf = page+off;
++      *start = buf;
++      len = sprintf(buf, "Novfs Version=%s\n", NOVFS_VERSION_STRING);
++      i = Daemon_getversion(tbuf, sizeof(tbuf));
++      if ((i > 0) && i < (count-len))
++      {
++         len += sprintf(buf+len, "Novfsd Version=%s\n", tbuf);
++      }
++      
++      if (Novfs_CurrentMount)
++      {
++         i = strlen(Novfs_CurrentMount);
++         if ((i > 0) && i < (count-len))
++         {
++            len += sprintf(buf+len, "Novfs mount=%s\n", Novfs_CurrentMount);
++         }
++      }
++      DbgPrint("Novfs_Get_Version:\n%s\n", buf);
++   }
++	*eof = 1;
++   return(len);
++}
++
++/*++======================================================================*/
++ssize_t
++Novfs_User_proc_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++	ssize_t	retval=0;
++
++   UNUSED_VARIABLE(file);
++   UNUSED_VARIABLE(buf);
++   UNUSED_VARIABLE(nbytes);
++   UNUSED_VARIABLE(ppos);
++
++	DbgPrint( "Novfs_User_proc_read: kernel_locked 0x%x\n", kernel_locked());
++
++	return retval;
++}
++/*++======================================================================*/
++ssize_t
++Novfs_User_proc_write(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++	ssize_t	retval=0;
++
++   UNUSED_VARIABLE(file);
++   UNUSED_VARIABLE(ppos);
++	
++	DbgPrint( "Novfs_User_proc_write: kernel_locked 0x%x\n", kernel_locked());
++	if (buf && nbytes)
++	{
++	}
++	
++	return(retval);
++}
++
++/*++======================================================================*/
++int Novfs_User_proc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++	int retval=-ENOSYS;
++
++   UNUSED_VARIABLE(inode);
++   UNUSED_VARIABLE(file);
++   UNUSED_VARIABLE(cmd);
++   UNUSED_VARIABLE(arg);
++
++	DbgPrint( "Novfs_User_proc_ioctl: kernel_locked 0x%x\n", kernel_locked());
++
++	return(retval);
++}
++
++/*++======================================================================*/
++int Init_Procfs_Interface( void )
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++	int retCode=0;
++	
++	Novfs_Procfs_dir = proc_mkdir(MODULE_NAME, NULL);
++	if ( Novfs_Procfs_dir ) 
++	{
++		Novfs_Procfs_dir->owner = THIS_MODULE;
++		
++		Novfs_Control = create_proc_entry("Control", 0600, Novfs_Procfs_dir);
++
++		if ( Novfs_Control )
++		{
++			Novfs_Control->owner = THIS_MODULE;
++			Novfs_Control->size  = 0;
++			memcpy(&Daemon_proc_fops, Novfs_Control->proc_fops, sizeof(struct file_operations));
++			
++			/*
++			 * Setup our functions
++          */
++			Daemon_proc_fops.owner   = THIS_MODULE;
++			Daemon_proc_fops.open    = Daemon_Open_Control;
++			Daemon_proc_fops.release = Daemon_Close_Control;
++			Daemon_proc_fops.read    = Daemon_Send_Command;
++			Daemon_proc_fops.write   = Daemon_Receive_Reply;
++         Daemon_proc_fops.ioctl   = Daemon_ioctl;
++			
++			Novfs_Control->proc_fops = &Daemon_proc_fops;
++		}
++		else
++		{
++			remove_proc_entry(MODULE_NAME, NULL);
++			return(-ENOENT);
++		}
++      
++		Novfs_Library = create_proc_entry("Library", 0666, Novfs_Procfs_dir);
++      if ( Novfs_Library )
++      {
++			Novfs_Library->owner = THIS_MODULE;
++			Novfs_Library->size  = 0;
++			
++			/*
++			 * Setup our file functions
++          */
++			memcpy(&Library_proc_fops, Novfs_Library->proc_fops, sizeof(struct file_operations));
++			Library_proc_fops.owner   = THIS_MODULE;
++         Library_proc_fops.open    = Daemon_Library_open;
++			Library_proc_fops.release = Daemon_Library_close;
++			Library_proc_fops.read    = Daemon_Library_read;
++			Library_proc_fops.write   = Daemon_Library_write;
++         Library_proc_fops.llseek  = Daemon_Library_llseek;
++         Library_proc_fops.ioctl   = Daemon_Library_ioctl;
++			Novfs_Library->proc_fops  = &Library_proc_fops;
++      }
++      else
++      {
++         remove_proc_entry("Control", Novfs_Procfs_dir);
++         remove_proc_entry(MODULE_NAME, NULL);
++			return(-ENOENT);
++      }
++
++      Novfs_Version = create_proc_read_entry("Version", 0444, Novfs_Procfs_dir, Novfs_Get_Version, NULL);
++      if ( Novfs_Version )
++      {
++			Novfs_Version->owner = THIS_MODULE;
++			Novfs_Version->size  = 0;
++      }
++      else
++      {
++         remove_proc_entry("Library", Novfs_Procfs_dir);
++         remove_proc_entry("Control", Novfs_Procfs_dir);
++         remove_proc_entry(MODULE_NAME, NULL);
++			retCode = -ENOENT;
++      }
++	}
++	else
++	{
++		retCode = -ENOENT;
++	}
++	return(retCode);
++}
++
++/*++======================================================================*/
++void Uninit_Procfs_Interface( void )
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++
++   DbgPrint("Uninit_Procfs_Interface remove_proc_entry(Version, NULL)\n");
++   remove_proc_entry("Version", Novfs_Procfs_dir);
++
++   DbgPrint("Uninit_Procfs_Interface remove_proc_entry(Control, NULL)\n");
++   remove_proc_entry("Control", Novfs_Procfs_dir);
++
++   DbgPrint("Uninit_Procfs_Interface remove_proc_entry(Library, NULL)\n");
++   remove_proc_entry("Library", Novfs_Procfs_dir);
++
++   DbgPrint("Uninit_Procfs_Interface remove_proc_entry(%s, NULL)\n", MODULE_NAME);
++   remove_proc_entry(MODULE_NAME, NULL);
++
++   DbgPrint("Uninit_Procfs_Interface done\n");
++}
+diff -uNr src.old/src/profile.c src/src/profile.c
+--- src.old/src/profile.c	1970-01-01 01:00:00.000000000 +0100
++++ src/src/profile.c	2006-10-16 15:08:22.000000000 +0200
+@@ -0,0 +1,1199 @@
++/*++========================================================================
++ * Program Name:     Novell NCP Redirector for Linux
++ * File Name:        profile.c
++ * Version:          v1.00
++ * Author:           James Turner
++ *
++ * Abstract:         This module contains a debugging code for
++ *                   the novfs VFS.
++ * Notes:
++ * Revision History: 
++ *
++ *
++ * Copyright (C) 2005 Novell, Inc.
++ *
++ * 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 files specific to Linux ]==================================*/
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/proc_fs.h>
++#include <linux/sched.h>
++#include <asm/uaccess.h>
++#include <linux/vmalloc.h>
++#include <linux/time.h>
++
++#include <linux/profile.h>
++#include <linux/notifier.h>
++
++/*===[ Include files specific to this module ]============================*/
++#include "vfs.h"
++
++/*===[ External data ]====================================================*/
++extern struct dentry *Novfs_root;
++extern struct proc_dir_entry *Novfs_Procfs_dir;
++extern unsigned long File_update_timeout;
++extern int PageCache;
++
++/*===[ External prototypes ]==============================================*/
++extern void Scope_Dump_Tasklist( void );
++extern void Scope_Dump_Scopetable( void );
++extern void Daemon_Dumpque( void );
++extern char  *Scope_dget_path( struct dentry *Dentry, char *Buf, unsigned int Buflen, int Flags);
++extern int Novfs_dump_inode_cache(int argc, const char **argv, const char **envp, struct pt_regs *regs);
++extern void Novfs_dump_inode( void *pf );
++extern int Daemon_SendDebugCmd ( char *Command );
++
++
++/*===[ Manifest constants ]===============================================*/
++#define DBGBUFFERSIZE (1024*1024*32)
++
++/*===[ Type definitions ]=================================================*/
++typedef void daemon_command_t;
++
++typedef struct _SYMBOL_TABLE {
++	void *address;
++	char *name;
++} SYMBOL_TABLE, *PSYMBOL_TABLE;
++
++struct local_rtc_time {
++	int tm_sec;
++	int tm_min;
++	int tm_hour;
++	int tm_mday;
++	int tm_mon;
++	int tm_year;
++	int tm_wday;
++	int tm_yday;
++	int tm_isdst;
++};
++
++/*===[ Function prototypes ]==============================================*/
++int profile_task_exit_callback(struct notifier_block *self, unsigned long val, void *data) __attribute__((__no_instrument_function__));
++int init_profile( void );
++
++char *ctime_r(time_t *clock, char *buf);
++int LocalPrint( char *Fmt, ... ) __attribute__((__no_instrument_function__));
++int DbgPrint( char *Fmt, ... ) __attribute__((__no_instrument_function__));
++
++void __cyg_profile_func_enter (void *this_fn, void *call_site) __attribute__((__no_instrument_function__)) ;
++void __cyg_profile_func_exit (void *this_fn, void *call_site) __attribute__((__no_instrument_function__));
++void doline(unsigned char *b, unsigned char *p, unsigned char *l) __attribute__((__no_instrument_function__));
++void mydump(int size, void *dumpptr) __attribute__((__no_instrument_function__));
++void GregorianDay(struct local_rtc_time * tm) __attribute__((__no_instrument_function__));
++void to_tm(int tim, struct local_rtc_time * tm) __attribute__((__no_instrument_function__));
++char *ctime_r(time_t *clock, char *buf) __attribute__((__no_instrument_function__));
++int profile_dump_tasklist(int argc, const char **argv, const char **envp, struct pt_regs *regs);
++int profile_dump_scopetable(int argc, const char **argv, const char **envp, struct pt_regs *regs);
++int profile_dump_daemonque(int argc, const char **argv, const char **envp, struct pt_regs *regs);
++int profile_dump_DbgBuffer(int argc, const char **argv, const char **envp, struct pt_regs *regs);
++int profile_dump_DentryTree(int argc, const char **argv, const char **envp, struct pt_regs *regs);
++int profile_dump_inode(int argc, const char **argv, const char **envp, struct pt_regs *regs);
++
++void *Novfs_Malloc( size_t size, int flags ) __attribute__((__no_instrument_function__));
++void Novfs_Free( const void *p ) __attribute__((__no_instrument_function__));
++
++int profile_dump_memorylist_dbg(int argc, const char **argv, const char **envp, struct pt_regs *regs)  __attribute__((__no_instrument_function__));
++void profile_dump_memorylist( void *pf );
++
++static ssize_t User_proc_write_DbgBuffer(struct file * file, const char __user *buf, size_t nbytes, loff_t *ppos) __attribute__((__no_instrument_function__));
++static ssize_t User_proc_read_DbgBuffer(struct file * file, char * buf, size_t nbytes, loff_t *ppos) __attribute__((__no_instrument_function__));
++static int proc_read_DbgBuffer(char *page, char **start,
++                            off_t off, int count, 
++                            int *eof, void *data) __attribute__((__no_instrument_function__));
++
++void profile_dump_dt(struct dentry *parent, void *pf );
++ssize_t profile_inode_read(struct file *file, char *buf, size_t len, loff_t *off);
++ssize_t profile_dentry_read(struct file *file, char *buf, size_t len, loff_t *off);
++ssize_t profile_memory_read(struct file *file, char *buf, size_t len, loff_t *off);
++uint64_t get_nanosecond_time( void );
++
++/*===[ Global variables ]=================================================*/
++char *DbgPrintBuffer=NULL;
++char DbgPrintOn=0;
++char DbgSyslogOn=0;
++unsigned long DbgPrintBufferOffset=0;
++unsigned long DbgPrintBufferReadOffset=0;
++unsigned long DbgPrintBufferSize = DBGBUFFERSIZE;
++
++int Indent = 0;
++char IndentString[] = "                                       ";
++
++static struct file_operations Dbg_proc_file_operations;
++static struct file_operations dentry_proc_file_ops;
++static struct file_operations inode_proc_file_ops;
++static struct file_operations memory_proc_file_ops;
++
++static struct proc_dir_entry *dbg_dir=NULL, *dbg_file=NULL;
++static struct proc_dir_entry *dentry_file=NULL;
++static struct proc_dir_entry *inode_file=NULL;
++static struct proc_dir_entry *memory_file=NULL;
++
++static struct notifier_block taskexit_nb;
++
++
++DECLARE_MUTEX(LocalPrint_lock);
++spinlock_t Syslog_lock = SPIN_LOCK_UNLOCKED;
++
++#include "profile_funcs.h"
++
++
++/*===[ Code ]=============================================================*/
++int 
++profile_task_exit_callback(struct notifier_block *self, unsigned long val, void *data)
++{
++   struct task_struct *task = (struct task_struct *)data;
++
++	DbgPrint("profile_task_exit_callback: task 0x%p %u exiting %s\n", task, task->pid, task->comm);
++   return(0);
++}
++
++int init_profile( void )
++{
++   int retCode = 0;
++
++	if (Novfs_Procfs_dir)
++   {
++      dbg_dir = Novfs_Procfs_dir;
++   }
++   else
++   {
++		dbg_dir = proc_mkdir(MODULE_NAME, NULL);
++   }
++
++	if( dbg_dir ) 
++	{
++		dbg_dir->owner = THIS_MODULE;
++		dbg_file = create_proc_read_entry("Debug", 
++											0600, 
++											dbg_dir, 
++											proc_read_DbgBuffer,
++											NULL);
++		if ( dbg_file )
++		{
++			dbg_file->owner = THIS_MODULE;
++			dbg_file->size  = DBGBUFFERSIZE;
++			memcpy(&Dbg_proc_file_operations, dbg_file->proc_fops, sizeof(struct file_operations));
++			Dbg_proc_file_operations.read = User_proc_read_DbgBuffer;
++			Dbg_proc_file_operations.write = User_proc_write_DbgBuffer;
++			dbg_file->proc_fops = &Dbg_proc_file_operations;
++		}
++		else
++		{
++			remove_proc_entry(MODULE_NAME, NULL);
++			vfree( DbgPrintBuffer );
++			DbgPrintBuffer = NULL;
++		}
++   }
++
++	if ( DbgPrintBuffer )
++	{
++	   if( dbg_dir ) 
++	   {
++			inode_file = create_proc_entry("inode", 
++												0600, 
++												dbg_dir);
++			if ( inode_file )
++			{
++				inode_file->owner = THIS_MODULE;
++				inode_file->size  = 0;
++				memcpy(&inode_proc_file_ops, inode_file->proc_fops, sizeof(struct file_operations));
++		      inode_proc_file_ops.owner   = THIS_MODULE;
++		      inode_proc_file_ops.read    = profile_inode_read;
++				inode_file->proc_fops = &inode_proc_file_ops;
++			}
++
++			dentry_file = create_proc_entry("dentry", 
++												0600, 
++												dbg_dir);
++			if ( dentry_file )
++			{
++				dentry_file->owner = THIS_MODULE;
++				dentry_file->size  = 0;
++				memcpy(&dentry_proc_file_ops, dentry_file->proc_fops, sizeof(struct file_operations));
++		      dentry_proc_file_ops.owner   = THIS_MODULE;
++		      dentry_proc_file_ops.read    = profile_dentry_read;
++				dentry_file->proc_fops = &dentry_proc_file_ops;
++			}
++
++			memory_file = create_proc_entry("memory", 
++												0600, 
++												dbg_dir);
++			if ( memory_file )
++			{
++				memory_file->owner = THIS_MODULE;
++				memory_file->size  = 0;
++				memcpy(&memory_proc_file_ops, memory_file->proc_fops, sizeof(struct file_operations));
++		      memory_proc_file_ops.owner   = THIS_MODULE;
++		      memory_proc_file_ops.read    = profile_memory_read;
++				memory_file->proc_fops = &memory_proc_file_ops;
++			}
++
++		}
++		else
++		{
++			vfree( DbgPrintBuffer );
++			DbgPrintBuffer = NULL;
++		}
++	}
++   return( retCode );
++}
++
++
++void uninit_profile( void )
++{
++   if (dbg_file)    DbgPrint("Calling remove_proc_entry(Debug, NULL)\n"), remove_proc_entry( "Debug", dbg_dir );
++   if (inode_file)  DbgPrint("Calling remove_proc_entry(inode, NULL)\n"), remove_proc_entry( "inode", dbg_dir );
++   if (dentry_file) DbgPrint("Calling remove_proc_entry(dentry, NULL)\n"), remove_proc_entry( "dentry", dbg_dir );
++   if (memory_file) DbgPrint("Calling remove_proc_entry(memory, NULL)\n"), remove_proc_entry( "memory", dbg_dir );
++
++   if (dbg_dir && (dbg_dir != Novfs_Procfs_dir))  
++   {
++      DbgPrint("Calling remove_proc_entry(%s, NULL)\n", MODULE_NAME);
++	   remove_proc_entry( MODULE_NAME, NULL );
++   }
++}
++
++
++static 
++ssize_t
++User_proc_write_DbgBuffer(struct file * file, const char __user *buf, size_t nbytes, loff_t *ppos)
++{
++	ssize_t	retval=nbytes;
++   u_char *lbuf, *p;
++   int i;
++   u_long cpylen;
++
++
++   UNUSED_VARIABLE( *ppos );
++
++   lbuf = Novfs_Malloc(nbytes+1, GFP_KERNEL);
++   if (lbuf)
++   {
++      cpylen = copy_from_user(lbuf, buf, nbytes);
++   
++      lbuf[nbytes] = 0;
++      DbgPrint("User_proc_write_DbgBuffer: %s\n", lbuf);
++
++      for (i=0; lbuf[i] && lbuf[i] != '\n'; i++) ;
++
++      if ( '\n' == lbuf[i] )
++      {
++         lbuf[i] = '\0';
++      }
++
++      if ( !strcmp("on", lbuf))
++      {
++   	   DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
++         DbgPrintOn = 1;
++      }
++      else if ( !strcmp("off", lbuf))
++      {
++         DbgPrintOn = 0;
++      }
++      else if ( !strcmp("reset", lbuf))
++      {
++   	   DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
++      }
++      else if ( NULL != (p = strchr(lbuf, ' ')))
++      {
++         *p++ = '\0';
++         if ( !strcmp("syslog", lbuf))
++         {
++            
++            if (!strcmp("on", p))
++            {
++               DbgSyslogOn = 1;
++            }
++            else if (!strcmp("off", p))
++            {
++               DbgSyslogOn = 0;
++            }
++         }
++         else if ( !strcmp("novfsd", lbuf))
++         {
++            Daemon_SendDebugCmd( p );
++         }
++         else if ( !strcmp("file_update_timeout", lbuf))
++         {
++            File_update_timeout = simple_strtoul(p, NULL, 0);
++         }
++         else if ( !strcmp("cache", lbuf))
++         {
++            if (!strcmp("on", p))
++            {
++               PageCache = 1;
++            }
++            else if (!strcmp("off", p))
++            {
++               PageCache = 0;
++            }
++         }
++      }
++      Novfs_Free(lbuf);
++   }
++
++	return (retval);
++}
++
++static 
++ssize_t
++User_proc_read_DbgBuffer(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
++
++{
++	ssize_t	retval=0;
++	size_t	count;
++
++   UNUSED_VARIABLE( *ppos );
++
++	if (0 != (count = DbgPrintBufferOffset - DbgPrintBufferReadOffset))
++   {
++
++	   if (count > nbytes)
++	   {
++			   count = nbytes;
++	   }
++
++	   count -= copy_to_user(buf, &DbgPrintBuffer[DbgPrintBufferReadOffset], count);
++
++	   if (count == 0) 
++	   {
++		   if (retval == 0)
++			   retval = -EFAULT;
++	   }
++	   else
++	   {
++		   DbgPrintBufferReadOffset += count;
++		   if (DbgPrintBufferReadOffset >= DbgPrintBufferOffset)
++		   {
++			   DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
++		   }
++		   retval = count;
++	   }
++   }
++
++	return retval;
++}
++
++static 
++int 
++proc_read_DbgBuffer(char *page, char **start,
++                            off_t off, int count, 
++                            int *eof, void *data)
++{
++	int len;
++	static char bufd[512];
++
++   UNUSED_VARIABLE(start);
++   UNUSED_VARIABLE(eof);
++   UNUSED_VARIABLE(data);
++
++	sprintf(bufd, KERN_ALERT "proc_read_DbgBuffer: off=%ld count=%d DbgPrintBufferOffset=%lu DbgPrintBufferReadOffset=%lu\n", 
++			off, count, DbgPrintBufferOffset, DbgPrintBufferReadOffset);
++	printk(bufd);
++
++	len = DbgPrintBufferOffset - DbgPrintBufferReadOffset;
++
++	if ((int)(DbgPrintBufferOffset-DbgPrintBufferReadOffset) > count)
++	{
++		len = count;
++	}
++
++	if (len)
++	{
++		memcpy(page, &DbgPrintBuffer[DbgPrintBufferReadOffset], len);
++		DbgPrintBufferReadOffset += len;
++	}
++	
++
++	if (DbgPrintBufferReadOffset >= DbgPrintBufferOffset)
++	{
++		DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
++	}
++
++	sprintf(bufd, KERN_ALERT "proc_read_DbgBuffer: return %d\n", len);
++	printk(bufd);
++
++	return len;
++}
++
++#define DBG_BUFFER_SIZE (2*1024)
++
++int 
++LocalPrint( char *Fmt, ... )
++{
++	int len=0;
++	va_list args;
++
++   if (DbgPrintBuffer)
++   {
++		va_start(args, Fmt);
++   	len += vsnprintf(DbgPrintBuffer+DbgPrintBufferOffset, DbgPrintBufferSize-DbgPrintBufferOffset, Fmt, args);
++      DbgPrintBufferOffset += len;
++   }
++
++	return(len);
++}
++
++
++int 
++DbgPrint( char *Fmt, ... )
++{
++	char *buf;
++	int len=0;
++	unsigned long offset;
++	va_list args;
++
++   if ( (DbgPrintBuffer && DbgPrintOn) || DbgSyslogOn )
++   {
++      buf = kmalloc( DBG_BUFFER_SIZE, GFP_KERNEL );
++
++      if (buf)
++      {
++		   va_start(args, Fmt);
++         len = sprintf(buf, "[%d] ", current->pid);
++	
++		   len += vsnprintf(buf+len, DBG_BUFFER_SIZE-len, Fmt, args);
++		   if ( -1 == len )
++		   {
++			   len = DBG_BUFFER_SIZE-1;
++			   buf[len] = '\0';
++		   }
++         /*
++         len = sprintf(&DbgPrintBuffer[offset], "[%llu] ", ts);
++         len += vsprintf(&DbgPrintBuffer[offset+len], Fmt, args);
++         */
++
++		   if (len)
++		   {
++            if (DbgSyslogOn)
++            {
++			      printk("<6>%s", buf);
++            }
++            
++            if ( DbgPrintBuffer && DbgPrintOn )
++            {
++		         if ((DbgPrintBufferOffset+len) > DbgPrintBufferSize)
++               {
++                  offset = DbgPrintBufferOffset;
++                  DbgPrintBufferOffset = 0;
++                  memset(&DbgPrintBuffer[offset], 0, DbgPrintBufferSize-offset);
++               }
++
++               mb();
++
++		         if ((DbgPrintBufferOffset+len) < DbgPrintBufferSize)
++		         {
++			         DbgPrintBufferOffset += len;		
++			         offset = DbgPrintBufferOffset-len;
++                  memcpy(&DbgPrintBuffer[offset], buf, len+1);
++		         }
++            }
++		   }
++         kfree(buf);
++      }
++   }
++
++	return(len);
++}
++
++void
++__cyg_profile_func_enter (void *this_fn, void *call_site)
++{
++	PSYMBOL_TABLE sym;
++   uint64_t t64;
++
++	
++	if ((void *)init_novfs == this_fn)
++	{
++		DbgPrintBuffer = vmalloc(DBGBUFFERSIZE);
++      taskexit_nb.notifier_call = profile_task_exit_callback;
++
++#ifdef	CONFIG_KDB
++      kdb_register("novfs_tl", profile_dump_tasklist, "", "Dumps task list", 0);
++      kdb_register("novfs_st", profile_dump_scopetable, "", "Dumps the novfs scope table", 0);
++      kdb_register("novfs_dque", profile_dump_daemonque, "", "Dumps the novfs daemon que", 0);
++      kdb_register("novfs_db", profile_dump_DbgBuffer, "[-r] [-e size] [-i]", "Dumps the novfs DbgBuffer", 0);
++      kdb_register("novfs_den", profile_dump_DentryTree, "[dentry]", "Dumps a Dentry tree", 0);
++      kdb_register("novfs_ic", Novfs_dump_inode_cache, "[inode]", "Dumps a Inode Cache", 0);
++      kdb_register("novfs_inode", profile_dump_inode, "", "Dump allocated Inodes", 0);
++      kdb_register("novfs_mem", profile_dump_memorylist_dbg, "", "Dumps allocated memory", 0);
++#endif
++	}
++   else if (exit_novfs == this_fn)
++   {
++		/*
++		if (dbg_file)    DbgPrint("Calling remove_proc_entry(Debug, NULL)\n"), remove_proc_entry( "Debug", dbg_dir );
++		if (inode_file)  DbgPrint("Calling remove_proc_entry(inode, NULL)\n"), remove_proc_entry( "inode", dbg_dir );
++		if (dentry_file) DbgPrint("Calling remove_proc_entry(dentry, NULL)\n"), remove_proc_entry( "dentry", dbg_dir );
++		if (memory_file) DbgPrint("Calling remove_proc_entry(memory, NULL)\n"), remove_proc_entry( "memory", dbg_dir );
++
++		if (dbg_dir && (dbg_dir != Novfs_Procfs_dir))  
++		{
++         printk( KERN_INFO "Calling remove_proc_entry(%s, NULL)\n", MODULE_NAME);
++		   remove_proc_entry( MODULE_NAME, NULL );
++      }
++      */
++   }
++
++	sym = SymbolTable;
++	while (sym->address)
++	{
++		if (this_fn == sym->address )
++		{
++         t64 = get_nanosecond_time();
++			DbgPrint("[%llu]%sS %s (0x%p 0x%p)\n", t64, &IndentString[sizeof(IndentString)-Indent-1], sym->name, this_fn, call_site);
++
++	      Indent++;
++	      if (Indent > (int)(sizeof(IndentString)-1))
++		      Indent--;
++		
++			break;
++		}
++		sym++;
++	}
++}
++
++void
++__cyg_profile_func_exit (void *this_fn, void *call_site)
++{
++	PSYMBOL_TABLE sym;
++   uint64_t t64;
++
++	if (exit_novfs == this_fn)
++	{
++		if (DbgPrintBuffer) vfree( DbgPrintBuffer );
++		DbgPrintBuffer = NULL;
++
++#ifdef	CONFIG_KDB
++      kdb_unregister("novfs_tl");
++      kdb_unregister("novfs_st");
++      kdb_unregister("novfs_dque");
++      kdb_unregister("novfs_db");
++      kdb_unregister("novfs_den");
++      kdb_unregister("novfs_ic");
++      kdb_unregister("novfs_inode");
++      kdb_unregister("novfs_mem");
++#endif
++		return;
++	}
++
++	sym = SymbolTable;
++	while (sym->address)
++	{
++		if (this_fn == sym->address )
++		{
++	      Indent--;
++	      if (Indent < 0)
++		      Indent = 0;
++
++         t64 = get_nanosecond_time();
++			DbgPrint("[%llu]%sR %s (0x%p)\n", t64, &IndentString[sizeof(IndentString)-Indent-1], sym->name, call_site);
++			break;
++		}
++		sym++;
++	}
++}
++
++void
++doline(unsigned char *b, unsigned char *e, unsigned char *l)
++{
++	*b++ = ' ';
++	while (l < e) {
++		if ((*l < ' ') || (*l > '~')) 
++		{
++		   *b++ = '.';
++         *b = '\0';
++      }
++		else 
++		{
++		   b += sprintf(b, "%c", *l);
++      }
++		l++;
++	}
++}
++
++void
++mydump(int size, void *dumpptr)
++{
++	unsigned char *ptr = (unsigned char *)dumpptr;
++	unsigned char *line=0, buf[80], *bptr=buf;
++	int i;
++
++   if ( DbgPrintBuffer )
++   {
++      if (size)
++      {
++	      for (i=0; i < size; i++) 
++	      {
++		      if (0 == (i % 16)) 
++		      {
++			      if (line) 
++			      {
++				      doline(bptr, ptr, line);
++				      DbgPrint("%s\n", buf);
++                  bptr = buf;
++			      }
++			      bptr += sprintf(bptr, "0x%p: ", ptr);
++			      line = ptr;
++		      }
++		      bptr += sprintf(bptr, "%02x ", *ptr++);
++	      }
++	      doline(bptr, ptr, line);
++	      DbgPrint("%s\n", buf);
++      }
++   }
++}
++
++#define FEBRUARY	2
++#define	STARTOFTIME	1970
++#define SECDAY		86400L
++#define SECYR		(SECDAY * 365)
++#define	leapyear(year)		((year) % 4 == 0)
++#define	days_in_year(a) 	(leapyear(a) ? 366 : 365)
++#define	days_in_month(a) 	(month_days[(a) - 1])
++
++static int month_days[12] = {
++	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
++};
++
++/*
++ * This only works for the Gregorian calendar - i.e. after 1752 (in the UK)
++ */
++void 
++GregorianDay(struct local_rtc_time * tm)
++{
++	int leapsToDate;
++	int lastYear;
++	int day;
++	int MonthOffset[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
++
++	lastYear=tm->tm_year-1;
++
++	/*
++	 * Number of leap corrections to apply up to end of last year
++	 */
++	leapsToDate = lastYear/4 - lastYear/100 + lastYear/400;
++
++	/*
++	 * This year is a leap year if it is divisible by 4 except when it is
++	 * divisible by 100 unless it is divisible by 400
++	 *
++	 * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 will be
++	 */
++	if((tm->tm_year%4==0) &&
++	   ((tm->tm_year%100!=0) || (tm->tm_year%400==0)) &&
++	   (tm->tm_mon>2))
++	{
++		/*
++		 * We are past Feb. 29 in a leap year
++		 */
++		day=1;
++	}
++	else
++	{
++		day=0;
++	}
++
++	day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] +
++		   tm->tm_mday;
++
++	tm->tm_wday=day%7;
++}
++
++void 
++to_tm(int tim, struct local_rtc_time * tm)
++{
++	register int    i;
++	register long   hms, day;
++
++	day = tim / SECDAY;
++	hms = tim % SECDAY;
++
++	/* Hours, minutes, seconds are easy */
++	tm->tm_hour = hms / 3600;
++	tm->tm_min = (hms % 3600) / 60;
++	tm->tm_sec = (hms % 3600) % 60;
++
++	/* Number of years in days */
++	for (i = STARTOFTIME; day >= days_in_year(i); i++)
++		day -= days_in_year(i);
++	tm->tm_year = i;
++
++	/* Number of months in days left */
++	if (leapyear(tm->tm_year))
++		days_in_month(FEBRUARY) = 29;
++	for (i = 1; day >= days_in_month(i); i++)
++		day -= days_in_month(i);
++	days_in_month(FEBRUARY) = 28;
++	tm->tm_mon = i;
++
++	/* Days are what is left over (+1) from all that. */
++	tm->tm_mday = day + 1;
++
++	/*
++	 * Determine the day of week
++	 */
++	GregorianDay(tm);
++}
++
++char *
++ctime_r(time_t *clock, char *buf)
++{
++   struct local_rtc_time tm;
++   static char *DAYOFWEEK[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
++   static char *MONTHOFYEAR[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
++
++   to_tm(*clock, &tm);
++
++   sprintf(buf, "%s %s %d %d:%02d:%02d %d", DAYOFWEEK[tm.tm_wday], MONTHOFYEAR[tm.tm_mon-1], tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_year);
++   return(buf);
++}
++
++
++#ifdef	CONFIG_KDB
++
++int
++NO_TRACE
++profile_dump_tasklist(int argc, const char **argv, const char **envp, struct pt_regs *regs)
++{
++   Scope_Dump_Tasklist();
++   return( 0 );
++}
++
++int
++NO_TRACE
++profile_dump_scopetable(int argc, const char **argv, const char **envp, struct pt_regs *regs)
++{
++   Scope_Dump_Scopetable();
++   return( 0 );
++}
++
++int
++NO_TRACE
++profile_dump_daemonque(int argc, const char **argv, const char **envp, struct pt_regs *regs)
++{
++   Daemon_Dumpque();
++   return( 0 );
++}
++
++int
++NO_TRACE
++profile_dump_DbgBuffer(int argc, const char **argv, const char **envp, struct pt_regs *regs)
++{
++   unsigned long offset = DbgPrintBufferReadOffset;
++   if (argc > 0)
++   {
++      if (!strcmp("-r", argv[1]))
++      {
++         DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
++      }
++      else if (!strcmp("-e", argv[1]) && (argc > 1))
++      {
++         offset = simple_strtoul(argv[2], NULL, 0);
++         if (offset && offset < DbgPrintBufferOffset)
++         {
++            offset = DbgPrintBufferOffset - offset;
++         }
++         else
++         {
++            offset = DbgPrintBufferOffset;
++         }
++      }
++      else if (!strcmp("-i", argv[1]))
++      {
++         kdb_printf("DbgPrintBuffer       =0x%p\n", DbgPrintBuffer);
++         kdb_printf("DbgPrintBufferOffset =0x%lx\n", DbgPrintBufferOffset);
++         kdb_printf("DbgPrintBufferSize   =0x%lx\n", DbgPrintBufferSize);
++         offset = DbgPrintBufferOffset;
++         
++      }
++   }
++	while (DbgPrintBufferOffset > offset)
++   {
++      kdb_printf("%c", DbgPrintBuffer[offset++]);
++   }
++   return( 0 );
++}
++
++int
++NO_TRACE
++profile_dump_DentryTree(int argc, const char **argv, const char **envp, struct pt_regs *regs)
++{
++   struct dentry *parent=Novfs_root;
++
++   if (argc > 0)
++   {
++      parent = (void *)simple_strtoul(argv[1], NULL, 0);
++   }
++
++   if (parent)
++   {
++      profile_dump_dt(parent, kdb_printf );
++   }
++
++   return(0);
++}
++
++
++int
++NO_TRACE
++profile_dump_inode(int argc, const char **argv, const char **envp, struct pt_regs *regs)
++{
++   Novfs_dump_inode( kdb_printf );
++   return( 0 );
++}
++
++#endif	/* CONFIG_KDB */
++
++typedef struct memory_header
++{
++   struct list_head list;
++   void *caller;
++   size_t size;
++} MEMORY_LIST, *PMEMORY_LIST;
++
++spinlock_t Malloc_Lock = SPIN_LOCK_UNLOCKED;
++LIST_HEAD( Memory_List );
++
++void *Novfs_Malloc( size_t size, int flags )
++{
++   void *p=NULL;
++   PMEMORY_LIST mh;
++
++   mh = kmalloc(size + sizeof(MEMORY_LIST), flags);
++   if (mh)
++   {
++      mh->caller = __builtin_return_address(0);
++      mh->size = size;
++   	spin_lock(&Malloc_Lock);
++      list_add(&mh->list, &Memory_List);
++   	spin_unlock(&Malloc_Lock);
++      p = (char *)mh+sizeof(MEMORY_LIST);
++   	/*DbgPrint("Novfs_Malloc: 0x%p 0x%p %d\n", p, mh->caller, size);
++      */
++   }
++   return(p);
++}
++
++void Novfs_Free( const void *p )
++{
++   PMEMORY_LIST mh;
++
++   if (p)
++   {
++   	/*DbgPrint("Novfs_Free: 0x%p 0x%p\n", p, __builtin_return_address(0));
++      */
++      mh = (PMEMORY_LIST)((char *)p-sizeof(MEMORY_LIST));
++
++   	spin_lock(&Malloc_Lock);
++      list_del(&mh->list);
++   	spin_unlock(&Malloc_Lock);
++      kfree(mh);
++   }
++}
++
++
++int
++NO_TRACE
++profile_dump_memorylist_dbg(int argc, const char **argv, const char **envp, struct pt_regs *regs)
++{
++#ifdef	CONFIG_KDB
++   profile_dump_memorylist(kdb_printf);
++#endif	/* CONFIG_KDB */
++
++   return( 0 );
++}
++
++void
++NO_TRACE
++profile_dump_memorylist( void *pf )
++{
++   void (*pfunc)(char *Fmt, ...) = pf;
++
++   PMEMORY_LIST mh;
++   struct list_head *l;
++
++   size_t total=0;
++   int count=0;
++
++   spin_lock( &Malloc_Lock );
++
++   list_for_each( l, &Memory_List )
++   {
++      mh = list_entry(l, MEMORY_LIST, list);
++      pfunc("0x%p 0x%p 0x%p %d\n", mh, (char *)mh+sizeof(MEMORY_LIST), mh->caller, mh->size);
++      count++;
++      total += mh->size;
++   }
++   spin_unlock( &Malloc_Lock );
++
++   pfunc("Blocks=%d Total=%d\n", count, total);
++}
++
++void 
++NO_TRACE
++profile_dump_dt(struct dentry *parent, void *pf )
++{
++   void (*pfunc)(char *Fmt, ...) = pf;
++   struct l {
++      struct l *next;
++      struct dentry *dentry;
++   } *l, *n, *start;
++   struct list_head *p;
++   struct dentry *d;
++   char *buf, *path, *sd;
++   char inode_number[16];
++
++   buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
++
++   if( NULL == buf )
++   {
++      return;
++   }
++
++   if (parent)
++   {
++      pfunc("starting 0x%p %.*s\n", parent, parent->d_name.len, parent->d_name.name);
++      if (parent->d_subdirs.next == &parent->d_subdirs)
++      {
++         pfunc("No children...\n");
++      }
++      else
++      {
++         start = Novfs_Malloc(sizeof(*start), GFP_KERNEL);
++         if (start)
++         {
++            start->next = NULL;
++            start->dentry = parent;
++            l = start;
++            while(l)
++            {
++               p = l->dentry->d_subdirs.next;
++               while(p != &l->dentry->d_subdirs)
++               {
++                  d = list_entry(p, struct dentry, D_CHILD);
++                  p = p->next;
++
++                  if (d->d_subdirs.next != &d->d_subdirs)
++                  {
++                     n = Novfs_Malloc(sizeof(*n), GFP_KERNEL);
++                     if (n)
++                     {
++                        n->next = l->next;
++                        l->next = n;
++                        n->dentry = d;
++                     }
++                  }
++                  else
++                  {
++                     path = Scope_dget_path(d, buf, PATH_LENGTH_BUFFER, 1);
++                     if (path)
++                     {
++                        pfunc("1-0x%p %s\n" \
++                              "   d_name:    %.*s\n" \
++                              "   d_parent:  0x%p\n" \
++                              "   d_count:   %d\n" \
++                              "   d_flags:   0x%x\n" \
++                              "   d_subdirs: 0x%p\n" \
++                              "   d_inode:   0x%p\n",
++                           d, path, d->d_name.len, d->d_name.name, d->d_parent,
++                           atomic_read(&d->d_count), d->d_flags, d->d_subdirs.next, d->d_inode);
++                     }
++                  }
++               }
++               l = l->next;
++            }
++            l = start;
++            while(l)
++            {
++               d=l->dentry;
++               path = Scope_dget_path(d, buf, PATH_LENGTH_BUFFER, 1);
++               if (path)
++               {
++                  sd = " (None)";
++                  if (&d->d_subdirs != d->d_subdirs.next)
++                  {
++                     sd = "";
++                  }
++                  inode_number[0] = '\0';
++                  if (d->d_inode)
++                  {
++                     sprintf(inode_number, " (%lu)", d->d_inode->i_ino);
++                  }
++                  pfunc("0x%p %s\n" \
++                        "   d_parent:  0x%p\n" \
++                        "   d_count:   %d\n" \
++                        "   d_flags:   0x%x\n" \
++                        "   d_subdirs: 0x%p%s\n" \
++                        "   d_inode:   0x%p%s\n",
++                     d, path, d->d_parent,
++                     atomic_read(&d->d_count), d->d_flags, d->d_subdirs.next, sd, d->d_inode, inode_number);
++               }
++
++               n = l;
++               l = l->next;
++               Novfs_Free(n);
++            }
++         }
++      }
++   }
++
++   Novfs_Free(buf);
++
++}
++
++/*int profile_inode_open(struct inode *inode, struct file *file)
++{
++
++}
++
++int profile_inode_close(struct inode *inode, struct file *file)
++{
++}
++*/
++ssize_t profile_common_read( char *buf, size_t len, loff_t *off )
++{
++	ssize_t	retval=0;
++	size_t	count;
++   unsigned long offset = *off;
++
++	if (0 != (count = DbgPrintBufferOffset - offset))
++   {
++	   if (count > len)
++	   {
++			   count = len;
++	   }
++
++	   count -= copy_to_user(buf, &DbgPrintBuffer[offset], count);
++
++	   if (count == 0) 
++	   {
++			retval = -EFAULT;
++	   }
++	   else
++	   {
++         *off += (loff_t)count;
++		   retval = count;
++	   }
++   }
++	return retval;
++
++}
++
++//ssize_t NO_TRACE profile_inode_read(struct file *file, char *buf, size_t len, loff_t *off)
++ssize_t profile_inode_read(struct file *file, char *buf, size_t len, loff_t *off)
++{
++	ssize_t	retval=0;
++   unsigned long offset = *off;
++   static char save_DbgPrintOn;
++
++   if (offset == 0)
++   {
++      down(&LocalPrint_lock);
++      save_DbgPrintOn = DbgPrintOn;
++      DbgPrintOn = 0;
++
++   	DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
++      Novfs_dump_inode( LocalPrint );
++   }
++
++   retval = profile_common_read(buf, len, off);
++
++   if ( 0 == retval)
++   {
++      DbgPrintOn = save_DbgPrintOn;
++   	DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
++
++      up(&LocalPrint_lock);
++   }
++
++	return retval;
++
++}
++
++ssize_t NO_TRACE profile_dentry_read(struct file *file, char *buf, size_t len, loff_t *off)
++{
++	ssize_t	retval=0;
++   unsigned long offset = *off;
++   static char save_DbgPrintOn;
++
++   if (offset == 0)
++   {
++      down(&LocalPrint_lock);
++      save_DbgPrintOn = DbgPrintOn;
++      DbgPrintOn = 0;
++   	DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
++      profile_dump_dt(Novfs_root, LocalPrint);
++   }
++
++   retval = profile_common_read(buf, len, off);
++
++   if ( 0 == retval)
++   {
++   	DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
++      DbgPrintOn = save_DbgPrintOn;
++
++      up(&LocalPrint_lock);
++   }
++
++	return retval;
++
++}
++
++ssize_t NO_TRACE profile_memory_read(struct file *file, char *buf, size_t len, loff_t *off)
++{
++	ssize_t	retval=0;
++   unsigned long offset = *off;
++   static char save_DbgPrintOn;
++
++   if (offset == 0)
++   {
++      down(&LocalPrint_lock);
++      save_DbgPrintOn = DbgPrintOn;
++      DbgPrintOn = 0;
++   	DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
++      profile_dump_memorylist( LocalPrint );
++   }
++
++   retval = profile_common_read(buf, len, off);
++
++   if ( 0 == retval)
++   {
++   	DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
++      DbgPrintOn = save_DbgPrintOn;
++
++      up(&LocalPrint_lock);
++   }
++
++	return retval;
++
++}
++
++uint64_t get_nanosecond_time()
++{
++   struct timespec ts;
++   uint64_t retVal;
++
++   ts = current_kernel_time();
++
++   retVal = (uint64_t)NSEC_PER_SEC;
++   retVal *= (uint64_t)ts.tv_sec;
++   retVal += (uint64_t)ts.tv_nsec;
++
++   return( retVal );
++}
+diff -uNr src.old/src/profile_funcs.h src/src/profile_funcs.h
+--- src.old/src/profile_funcs.h	1970-01-01 01:00:00.000000000 +0100
++++ src/src/profile_funcs.h	2006-10-16 15:08:22.000000000 +0200
+@@ -0,0 +1,415 @@
++extern void Daemon_Added_Resource( void );
++extern void Daemon_Close_Control( void );
++extern void Daemon_CreateSessionId( void );
++extern void Daemon_DestroySessionId( void );
++extern void Daemon_Dumpque( void );
++extern void Daemon_Get_UserSpace( void );
++extern void Daemon_Library_close( void );
++extern void Daemon_Library_ioctl( void );
++extern void Daemon_Library_open( void );
++extern void Daemon_Library_read( void );
++extern void Daemon_Library_write( void );
++extern void Daemon_Login( void );
++extern void Daemon_Logout( void );
++extern void Daemon_Open_Control( void );
++extern void Daemon_Poll( void );
++extern void Daemon_Receive_Reply( void );
++extern void Daemon_Remove_Resource( void );
++extern void Daemon_Send_Command( void );
++extern void Daemon_SetMountPoint( void );
++extern void Daemon_getpwuid( void );
++extern void Daemon_getversion( void );
++extern void Daemon_ioctl( void );
++extern void GetConnData( void );
++extern void GetUserData( void );
++extern void Init_Daemon_Queue( void );
++extern void Init_Procfs_Interface( void );
++extern void Novfs_Add_to_Root( void );
++extern void Novfs_Add_to_Root2( void );
++extern void Novfs_Close_File( void );
++extern void Novfs_Close_Stream( void );
++extern void Novfs_Control_ioctl( void );
++extern void Novfs_Control_read( void );
++extern void Novfs_Control_write( void );
++extern void Novfs_Create( void );
++extern void Novfs_Delete( void );
++extern void Novfs_Find_Name_In_List( void );
++extern void Novfs_Get_Connected_Server_List( void );
++extern void Novfs_Get_Directory_List( void );
++extern void Novfs_Get_Directory_ListEx( void );
++extern void Novfs_Get_File_Info( void );
++extern void Novfs_Get_File_Info2( void );
++extern void Novfs_Get_Server_Volume_List( void );
++extern void Novfs_Get_Version( void );
++extern void Novfs_Open_File( void );
++extern void Novfs_Read_File( void );
++extern void Novfs_Read_Stream( void );
++extern void Novfs_Remove_from_Root( void );
++extern void Novfs_Rename_File( void );
++extern void Novfs_Set_Attr( void );
++extern void Novfs_Truncate_File( void );
++extern void Novfs_User_proc_ioctl( void );
++extern void Novfs_User_proc_read( void );
++extern void Novfs_User_proc_write( void );
++extern void Novfs_Verify_Server_Name( void );
++extern void Novfs_Verify_Volume_Name( void );
++extern void Novfs_Write_File( void );
++extern void Novfs_Write_Stream( void );
++extern void Novfs_a_readpage( void );
++extern void Novfs_add_inode_entry( void );
++extern void Novfs_clear_inode( void );
++extern void Novfs_d_add( void );
++extern void Novfs_d_compare( void );
++extern void Novfs_d_delete( void );
++extern void Novfs_d_hash( void );
++extern void Novfs_d_iput( void );
++extern void Novfs_d_lookup( void );
++extern void Novfs_d_release( void );
++extern void Novfs_d_revalidate( void );
++extern void Novfs_d_strcmp( void );
++extern void Novfs_dget_path( void );
++extern void Novfs_dir_fsync( void );
++extern void Novfs_dir_lseek( void );
++extern void Novfs_dir_open( void );
++extern void Novfs_dir_read( void );
++extern void Novfs_dir_readdir( void );
++extern void Novfs_dir_release( void );
++extern void Novfs_enumerate_inode_cache( void );
++extern void Novfs_f_flush( void );
++extern void Novfs_f_fsync( void );
++extern void Novfs_f_ioctl( void );
++extern void Novfs_f_llseek( void );
++extern void Novfs_f_lock( void );
++extern void Novfs_f_mmap( void );
++extern void Novfs_f_open( void );
++extern void Novfs_f_read( void );
++extern void Novfs_f_readdir( void );
++extern void Novfs_f_release( void );
++extern void Novfs_f_write( void );
++extern void Novfs_fill_super( void );
++extern void Novfs_free_inode_cache( void );
++extern void Novfs_free_invalid_entries( void );
++extern void Novfs_get_alltrees( void );
++extern void Novfs_get_entry( void );
++extern void Novfs_get_entry_time( void );
++extern void Novfs_get_inode( void );
++extern void Novfs_get_remove_entry( void );
++extern void Novfs_get_sb( void );
++extern void Novfs_i_create( void );
++extern void Novfs_i_getattr( void );
++extern void Novfs_i_lookup( void );
++extern void Novfs_i_mkdir( void );
++extern void Novfs_i_mknod( void );
++extern void Novfs_i_permission( void );
++extern void Novfs_i_rename( void );
++extern void Novfs_i_revalidate( void );
++extern void Novfs_i_rmdir( void );
++extern void Novfs_i_setattr( void );
++extern void Novfs_i_unlink( void );
++extern void Novfs_internal_hash( void );
++extern void Novfs_invalidate_inode_cache( void );
++extern void Novfs_kill_sb( void );
++extern void Novfs_lock_inode_cache( void );
++extern void Novfs_lookup_inode_cache( void );
++extern void Novfs_lookup_validate( void );
++extern void Novfs_notify_change( void );
++extern void Novfs_read_inode( void );
++extern void Novfs_remove_inode_entry( void );
++extern void Novfs_show_options( void );
++extern void Novfs_statfs( void );
++extern void Novfs_tree_read( void );
++extern void Novfs_unlock_inode_cache( void );
++extern void Novfs_update_entry( void );
++extern void Novfs_verify_file( void );
++extern void Novfs_write_inode( void );
++extern void NwAuthConnWithId( void );
++extern void NwConnClose( void );
++extern void NwGetConnInfo( void );
++extern void NwGetDaemonVersion( void );
++extern void NwGetIdentityInfo( void );
++extern void NwLicenseConn( void );
++extern void NwLoginIdentity( void );
++extern void NwLogoutIdentity( void );
++extern void NwOpenConnByAddr( void );
++extern void NwOpenConnByName( void );
++extern void NwOpenConnByRef( void );
++extern void NwQueryFeature( void );
++extern void NwRawSend( void );
++extern void NwScanConnInfo( void );
++extern void NwSetConnInfo( void );
++extern void NwSysConnClose( void );
++extern void NwUnAuthenticate( void );
++extern void NwUnlicenseConn( void );
++extern void NwcChangeAuthKey( void );
++extern void NwcEnumIdentities( void );
++extern void NwcEnumerateDrives( void );
++extern void NwcGetBroadcastMessage( void );
++extern void NwcGetDefaultNameCtx( void );
++extern void NwcGetPreferredDSTree( void );
++extern void NwcGetPrimaryConn( void );
++extern void NwcGetTreeMonitoredConn( void );
++extern void NwcSetDefaultNameCtx( void );
++extern void NwcSetMapDrive( void );
++extern void NwcSetPreferredDSTree( void );
++extern void NwcSetPrimaryConn( void );
++extern void NwcUnMapDrive( void );
++extern void NwdConvertLocalHandle( void );
++extern void NwdConvertNetwareHandle( void );
++extern void NwdGetMountPath( void );
++extern void NwdSetKeyValue( void );
++extern void NwdSetMapDrive( void );
++extern void NwdUnMapDrive( void );
++extern void NwdVerifyKeyValue( void );
++extern void Queue_Daemon_Command( void );
++extern void Queue_get( void );
++extern void Queue_put( void );
++extern void RemoveDriveMaps( void );
++extern void Scope_Cleanup( void );
++extern void Scope_Cleanup_Thread( void );
++extern void Scope_Dump_Scopetable( void );
++extern void Scope_Dump_Tasklist( void );
++extern void Scope_Find_Scope( void );
++extern void Scope_Get_Hash( void );
++extern void Scope_Get_ScopeUsers( void );
++extern void Scope_Get_ScopefromName( void );
++extern void Scope_Get_ScopefromPath( void );
++extern void Scope_Get_SessionId( void );
++extern void Scope_Get_Uid( void );
++extern void Scope_Get_UserName( void );
++extern void Scope_Get_UserSpace( void );
++extern void Scope_Init( void );
++extern void Scope_Lookup( void );
++extern void Scope_Search4Scope( void );
++extern void Scope_Set_UserSpace( void );
++extern void Scope_Timer_Function( void );
++extern void Scope_Uninit( void );
++extern void Scope_Validate_Scope( void );
++extern void Uninit_Daemon_Queue( void );
++extern void Uninit_Procfs_Interface( void );
++extern void add_to_list( void );
++extern void begin_directory_enumerate( void );
++extern void directory_enumerate( void );
++extern void directory_enumerate_ex( void );
++extern void do_login( void );
++extern void do_logout( void );
++extern void end_directory_enumerate( void );
++extern void exit_novfs( void );
++extern void find_queue( void );
++extern void get_next_queue( void );
++extern void init_novfs( void );
++extern void local_unlink( void );
++extern void process_list( void );
++extern void update_inode( void );
++extern void verify_dentry( void );
++
++SYMBOL_TABLE SymbolTable[] = {
++   {Scope_Get_UserSpace, "Scope_Get_UserSpace"},
++   {NwLoginIdentity, "NwLoginIdentity"},
++   {Novfs_d_revalidate, "Novfs_d_revalidate"},
++   {Daemon_SetMountPoint, "Daemon_SetMountPoint"},
++   {Scope_Get_Hash, "Scope_Get_Hash"},
++   {Queue_get, "Queue_get"},
++   {Queue_Daemon_Command, "Queue_Daemon_Command"},
++   {Novfs_dir_fsync, "Novfs_dir_fsync"},
++   {Novfs_Read_File, "Novfs_Read_File"},
++   {Daemon_Library_close, "Daemon_Library_close"},
++   {NwRawSend, "NwRawSend"},
++   {Novfs_get_inode, "Novfs_get_inode"},
++   {Novfs_Remove_from_Root, "Novfs_Remove_from_Root"},
++   {Novfs_Find_Name_In_List, "Novfs_Find_Name_In_List"},
++   {Scope_Get_SessionId, "Scope_Get_SessionId"},
++   {NwOpenConnByAddr, "NwOpenConnByAddr"},
++   {Novfs_read_inode, "Novfs_read_inode"},
++   {Novfs_Truncate_File, "Novfs_Truncate_File"},
++   {Daemon_Login, "Daemon_Login"},
++   {Scope_Get_ScopefromPath, "Scope_Get_ScopefromPath"},
++   {NwcGetTreeMonitoredConn, "NwcGetTreeMonitoredConn"},
++   {Novfs_write_inode, "Novfs_write_inode"},
++   {Scope_Lookup, "Scope_Lookup"},
++   {NwQueryFeature, "NwQueryFeature"},
++   {Novfs_get_entry_time, "Novfs_get_entry_time"},
++   {Novfs_Control_write, "Novfs_Control_write"},
++   {Scope_Get_Uid, "Scope_Get_Uid"},
++   {NwSysConnClose, "NwSysConnClose"},
++   {NwConnClose, "NwConnClose"},
++   {Novfs_get_entry, "Novfs_get_entry"},
++   {Novfs_Rename_File, "Novfs_Rename_File"},
++   {NwdConvertLocalHandle, "NwdConvertLocalHandle"},
++   {Novfs_dir_lseek, "Novfs_dir_lseek"},
++   {Scope_Get_ScopefromName, "Scope_Get_ScopefromName"},
++   {NwcGetPrimaryConn, "NwcGetPrimaryConn"},
++   {Novfs_d_strcmp, "Novfs_d_strcmp"},
++   {Daemon_Library_ioctl, "Daemon_Library_ioctl"},
++   {end_directory_enumerate, "end_directory_enumerate"},
++   {directory_enumerate, "directory_enumerate"},
++   {begin_directory_enumerate, "begin_directory_enumerate"},
++   {NwdGetMountPath, "NwdGetMountPath"},
++   {NwAuthConnWithId, "NwAuthConnWithId"},
++   {Novfs_Set_Attr, "Novfs_Set_Attr"},
++   {Daemon_getversion, "Daemon_getversion"},
++   {Scope_Dump_Scopetable, "Scope_Dump_Scopetable"},
++   {NwcSetMapDrive, "NwcSetMapDrive"},
++   {Novfs_lookup_inode_cache, "Novfs_lookup_inode_cache"},
++   {Novfs_i_mkdir, "Novfs_i_mkdir"},
++   {Novfs_free_invalid_entries, "Novfs_free_invalid_entries"},
++   {Novfs_dump_inode_cache, "Novfs_dump_inode_cache"},
++   {Novfs_Write_Stream, "Novfs_Write_Stream"},
++   {Novfs_Verify_Server_Name, "Novfs_Verify_Server_Name"},
++   {GetConnData, "GetConnData"},
++   {Uninit_Procfs_Interface, "Uninit_Procfs_Interface"},
++   {Scope_Validate_Scope, "Scope_Validate_Scope"},
++   {Scope_Timer_Function, "Scope_Timer_Function"},
++   {Novfs_i_setattr, "Novfs_i_setattr"},
++   {Novfs_i_mknod, "Novfs_i_mknod"},
++   {Novfs_Verify_Volume_Name, "Novfs_Verify_Volume_Name"},
++   {Novfs_Close_Stream, "Novfs_Close_Stream"},
++   {Novfs_Add_to_Root, "Novfs_Add_to_Root"},
++   {Init_Procfs_Interface, "Init_Procfs_Interface"},
++   {Novfs_dump_inode, "Novfs_dump_inode"},
++   {Novfs_Get_Directory_List, "Novfs_Get_Directory_List"},
++   {Novfs_Get_Connected_Server_List, "Novfs_Get_Connected_Server_List"},
++   {Daemon_Logout, "Daemon_Logout"},
++   {do_logout, "do_logout"},
++   {Scope_Search4Scope, "Scope_Search4Scope"},
++   {NwdUnMapDrive, "NwdUnMapDrive"},
++   {Novfs_Control_read, "Novfs_Control_read"},
++   {Scope_Cleanup_Thread, "Scope_Cleanup_Thread"},
++   {Novfs_invalidate_inode_cache, "Novfs_invalidate_inode_cache"},
++   {Novfs_f_flush, "Novfs_f_flush"},
++   {Novfs_enumerate_inode_cache, "Novfs_enumerate_inode_cache"},
++   {Novfs_d_compare, "Novfs_d_compare"},
++   {Daemon_Library_write, "Daemon_Library_write"},
++   {GetUserData, "GetUserData"},
++   {Daemon_Remove_Resource, "Daemon_Remove_Resource"},
++   {Scope_Set_UserSpace, "Scope_Set_UserSpace"},
++   {Novfs_get_alltrees, "Novfs_get_alltrees"},
++   {Daemon_Get_UserSpace, "Daemon_Get_UserSpace"},
++   {Uninit_Daemon_Queue, "Uninit_Daemon_Queue"},
++   {NwcChangeAuthKey, "NwcChangeAuthKey"},
++   {NwLicenseConn, "NwLicenseConn"},
++   {Init_Daemon_Queue, "Init_Daemon_Queue"},
++   {Novfs_tree_read, "Novfs_tree_read"},
++   {Novfs_f_llseek, "Novfs_f_llseek"},
++   {find_queue, "find_queue"},
++   {Scope_Find_Scope, "Scope_Find_Scope"},
++   {Novfs_lookup_validate, "Novfs_lookup_validate"},
++   {Novfs_d_hash, "Novfs_d_hash"},
++   {Novfs_a_readpage, "Novfs_a_readpage"},
++   {Novfs_Create, "Novfs_Create"},
++   {Novfs_Close_File, "Novfs_Close_File"},
++   {Daemon_getpwuid, "Daemon_getpwuid"},
++   {Daemon_CreateSessionId, "Daemon_CreateSessionId"},
++   {Scope_dget_path, "Scope_dget_path"},
++   {NwcSetDefaultNameCtx, "NwcSetDefaultNameCtx"},
++   {NwcGetDefaultNameCtx, "NwcGetDefaultNameCtx"},
++   {NwUnAuthenticate, "NwUnAuthenticate"},
++   {Novfs_i_getattr, "Novfs_i_getattr"},
++   {Novfs_get_remove_entry, "Novfs_get_remove_entry"},
++   {Novfs_f_ioctl, "Novfs_f_ioctl"},
++   {Scope_Get_ScopeUsers, "Scope_Get_ScopeUsers"},
++   {Scope_Dump_Tasklist, "Scope_Dump_Tasklist"},
++   {NwOpenConnByRef, "NwOpenConnByRef"},
++   {Novfs_unlock_inode_cache, "Novfs_unlock_inode_cache"},
++   {Novfs_lock_inode_cache, "Novfs_lock_inode_cache"},
++   {Daemon_DestroySessionId, "Daemon_DestroySessionId"},
++   {do_login, "do_login"},
++   {Novfs_free_inode_cache, "Novfs_free_inode_cache"},
++   {Novfs_Read_Stream, "Novfs_Read_Stream"},
++   {Daemon_Library_read, "Daemon_Library_read"},
++   {NwdSetMapDrive, "NwdSetMapDrive"},
++   {Novfs_internal_hash, "Novfs_internal_hash"},
++   {Daemon_Receive_Reply, "Daemon_Receive_Reply"},
++   {Daemon_Library_open, "Daemon_Library_open"},
++   {get_next_queue, "get_next_queue"},
++   {exit_novfs, "exit_novfs"},
++   {NwcGetBroadcastMessage, "NwcGetBroadcastMessage"},
++   {Novfs_d_lookup, "Novfs_d_lookup"},
++   {Novfs_clear_inode, "Novfs_clear_inode"},
++   {Daemon_Open_Control, "Daemon_Open_Control"},
++   {NwdConvertNetwareHandle, "NwdConvertNetwareHandle"},
++   {NwcUnMapDrive, "NwcUnMapDrive"},
++   {Novfs_notify_change, "Novfs_notify_change"},
++   {Novfs_dir_release, "Novfs_dir_release"},
++   {directory_enumerate_ex, "directory_enumerate_ex"},
++   {RemoveDriveMaps, "RemoveDriveMaps"},
++   {NwOpenConnByName, "NwOpenConnByName"},
++   {Novfs_verify_file, "Novfs_verify_file"},
++   {Novfs_statfs, "Novfs_statfs"},
++   {Novfs_f_write, "Novfs_f_write"},
++   {Novfs_Get_File_Info, "Novfs_Get_File_Info"},
++   {Novfs_Delete, "Novfs_Delete"},
++   {update_inode, "update_inode"},
++   {NwcSetPreferredDSTree, "NwcSetPreferredDSTree"},
++   {NwcGetPreferredDSTree, "NwcGetPreferredDSTree"},
++   {Novfs_update_entry, "Novfs_update_entry"},
++   {Novfs_kill_sb, "Novfs_kill_sb"},
++   {Daemon_ioctl, "Daemon_ioctl"},
++   {Scope_Get_UserName, "Scope_Get_UserName"},
++   {NwcEnumerateDrives, "NwcEnumerateDrives"},
++   {Novfs_i_revalidate, "Novfs_i_revalidate"},
++   {Novfs_f_release, "Novfs_f_release"},
++   {Novfs_f_read, "Novfs_f_read"},
++   {Novfs_d_delete, "Novfs_d_delete"},
++   {Novfs_Write_File, "Novfs_Write_File"},
++   {Novfs_User_proc_ioctl, "Novfs_User_proc_ioctl"},
++   {Novfs_Get_File_Info2, "Novfs_Get_File_Info2"},
++   {NwdSetKeyValue, "NwdSetKeyValue"},
++   {Novfs_remove_inode_entry, "Novfs_remove_inode_entry"},
++   {Novfs_i_rename, "Novfs_i_rename"},
++   {Novfs_f_open, "Novfs_f_open"},
++   {Novfs_d_iput, "Novfs_d_iput"},
++   {Novfs_Get_Directory_ListEx, "Novfs_Get_Directory_ListEx"},
++   {Daemon_Close_Control, "Daemon_Close_Control"},
++   {verify_dentry, "verify_dentry"},
++   {process_list, "process_list"},
++   {local_unlink, "local_unlink"},
++   {init_novfs, "init_novfs"},
++   {NwUnlicenseConn, "NwUnlicenseConn"},
++   {NwGetConnInfo, "NwGetConnInfo"},
++   {Novfs_i_permission, "Novfs_i_permission"},
++   {Novfs_dir_read, "Novfs_dir_read"},
++   {NwcSetPrimaryConn, "NwcSetPrimaryConn"},
++   {Novfs_f_lock, "Novfs_f_lock"},
++   {Novfs_dir_readdir, "Novfs_dir_readdir"},
++   {Novfs_dir_open, "Novfs_dir_open"},
++   {Queue_put, "Queue_put"},
++   {NwLogoutIdentity, "NwLogoutIdentity"},
++   {NwGetIdentityInfo, "NwGetIdentityInfo"},
++   {Novfs_i_rmdir, "Novfs_i_rmdir"},
++   {Novfs_i_create, "Novfs_i_create"},
++   {Novfs_f_mmap, "Novfs_f_mmap"},
++   {Novfs_User_proc_read, "Novfs_User_proc_read"},
++   {Novfs_show_options, "Novfs_show_options"},
++   {Novfs_add_inode_entry, "Novfs_add_inode_entry"},
++   {Novfs_Open_File, "Novfs_Open_File"},
++   {Novfs_Get_Version, "Novfs_Get_Version"},
++   {Daemon_Poll, "Daemon_Poll"},
++   {add_to_list, "add_to_list"},
++   {Scope_Init, "Scope_Init"},
++   {Scope_Cleanup, "Scope_Cleanup"},
++   {NwSetConnInfo, "NwSetConnInfo"},
++   {Novfs_i_unlink, "Novfs_i_unlink"},
++   {Novfs_get_sb, "Novfs_get_sb"},
++   {Novfs_f_readdir, "Novfs_f_readdir"},
++   {Novfs_f_fsync, "Novfs_f_fsync"},
++   {Novfs_d_release, "Novfs_d_release"},
++   {Novfs_User_proc_write, "Novfs_User_proc_write"},
++   {Daemon_Send_Command, "Daemon_Send_Command"},
++   {Daemon_Dumpque, "Daemon_Dumpque"},
++   {NwcEnumIdentities, "NwcEnumIdentities"},
++   {NwGetDaemonVersion, "NwGetDaemonVersion"},
++   {Novfs_i_lookup, "Novfs_i_lookup"},
++   {Novfs_fill_super, "Novfs_fill_super"},
++   {Novfs_Get_Server_Volume_List, "Novfs_Get_Server_Volume_List"},
++   {Novfs_Add_to_Root2, "Novfs_Add_to_Root2"},
++   {Daemon_SendDebugCmd, "Daemon_SendDebugCmd"},
++   {Daemon_Added_Resource, "Daemon_Added_Resource"},
++   {Scope_Uninit, "Scope_Uninit"},
++   {NwdVerifyKeyValue, "NwdVerifyKeyValue"},
++   {NwScanConnInfo, "NwScanConnInfo"},
++   {Novfs_dget_path, "Novfs_dget_path"},
++   {Novfs_d_add, "Novfs_d_add"},
++   {Novfs_Control_ioctl, "Novfs_Control_ioctl"},
++   // Terminate the table
++   {NULL, NULL}
++};
+diff -uNr src.old/src/scope.c src/src/scope.c
+--- src.old/src/scope.c	1970-01-01 01:00:00.000000000 +0100
++++ src/src/scope.c	2006-10-16 15:08:22.000000000 +0200
+@@ -0,0 +1,1214 @@
++/*++========================================================================
++ * Program Name:     Novell NCP Redirector for Linux
++ * File Name:        scope.c
++ * Version:          v1.00
++ * Author:           James Turner
++ *
++ * Abstract:         This module contains functions used to scope
++ *                   users.
++ * Notes:
++ * Revision History: 
++ *
++ *
++ * Copyright (C) 2005 Novell, Inc.
++ *
++ * 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 files specific to Linux ]==================================*/
++#include <linux/version.h>
++#include <linux/module.h>
++#include <linux/kthread.h>
++#include <linux/fs.h>
++#include <linux/file.h>
++#include <linux/sched.h>
++#include <linux/personality.h>
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/synclink.h>
++#include <linux/smp_lock.h>
++#include <asm/semaphore.h>
++#include <linux/security.h>
++#include <linux/syscalls.h>
++
++/*===[ Include files specific to this module ]============================*/
++#include "vfs.h"
++#define LEADER signal->leader
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
++    typedef struct task_struct task_t;
++#endif
++
++/*===[ External data ]====================================================*/
++
++/*===[ External prototypes ]==============================================*/
++extern int DbgPrint( char *Fmt, ... );
++extern int Daemon_CreateSessionId( uint64_t *SessionId );
++extern int Daemon_DestroySessionId( uint64_t SessionId );
++extern int Daemon_getpwuid( uid_t uid, int unamelen, char *uname );
++extern int Daemon_Get_UserSpace( uint64_t SessionId,  uint64_t *TotalSize, uint64_t *TotalFree, uint64_t *TotalDirectoryEnties, uint64_t *FreeDirectoryEnties);
++
++extern int Novfs_Remove_from_Root(char *);
++extern int Novfs_Add_to_Root(char *);
++
++/*===[ Manifest constants ]===============================================*/
++#define CLEANUP_INTERVAL      10
++#define MAX_USERNAME_LENGTH   32
++
++/*===[ Type definitions ]=================================================*/
++typedef struct _SCOPE_LIST_
++{
++   struct list_head  ScopeList;
++   scope_t           ScopeId;
++   session_t         SessionId;
++   pid_t             ScopePid;
++   task_t           *ScopeTask;
++   unsigned long     ScopeHash;
++   uid_t             ScopeUid;
++   uint64_t          ScopeUSize;
++   uint64_t          ScopeUFree;
++   uint64_t          ScopeUTEnties;
++   uint64_t          ScopeUAEnties;
++   int               ScopeUserNameLength;
++   unsigned char     ScopeUserName[MAX_USERNAME_LENGTH];
++} SCOPE_LIST, *PSCOPE_LIST;
++
++/*===[ Function prototypes ]==============================================*/
++void Scope_Init( void );
++void Scope_Uninit( void );
++
++PSCOPE_LIST Scope_Search4Scope( session_t Id, BOOLEAN Session, BOOLEAN Locked );
++PSCOPE_LIST Scope_Find_Scope( BOOLEAN Create );
++unsigned long Scope_Get_Hash( PSCOPE_LIST Scope );
++uid_t Scope_Get_Uid( PSCOPE_LIST Scope );
++int Scope_Validate_Scope( PSCOPE_LIST Scope );
++char *Scope_Get_UserName( PSCOPE_LIST Scope );
++session_t Scope_Get_SessionId( PSCOPE_LIST Scope );
++PSCOPE_LIST Scope_Get_ScopefromName( struct qstr *Name );
++int Scope_Set_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties );
++int Scope_Get_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties );
++
++char *Scope_Get_ScopeUsers( void );
++void *Scope_Lookup( void );
++
++void Scope_Timer_Function(unsigned long Context);
++int Scope_Cleanup_Thread(void *Args);
++void Scope_Cleanup( void );
++char  *Scope_dget_path( struct dentry *Dentry, char *Buf, unsigned int Buflen, int Flags);
++void Scope_Dump_Tasklist( void );
++void Scope_Dump_Scopetable( void );
++
++/*===[ Global variables ]=================================================*/
++struct list_head  Scope_List;
++struct semaphore  Scope_Lock;
++struct semaphore  Scope_Thread_Delay;
++int               Scope_Thread_Terminate=0;
++struct semaphore  Scope_Delay_Event;
++struct timer_list Scope_Timer;
++unsigned long     Scope_Hash_Val=1;
++
++/*===[ Code ]=============================================================*/
++
++/*++======================================================================*/
++void Scope_Init( void )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   INIT_LIST_HEAD( &Scope_List );
++   init_MUTEX( &Scope_Lock );
++   init_MUTEX_LOCKED( &Scope_Thread_Delay );
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7)
++   kernel_thread( Scope_Cleanup_Thread, NULL, 0 );
++#else
++   kthread_run(Scope_Cleanup_Thread, NULL, "novfs_ST");
++#endif
++}
++
++/*++======================================================================*/
++void Scope_Uninit( void )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   Scope_Thread_Terminate = 1;
++
++   up(&Scope_Thread_Delay);
++
++   mb();
++   while( Scope_Thread_Terminate )
++   {
++      yield();
++   }
++   printk( KERN_INFO "Scope_Uninit: Exit\n");
++   
++}
++
++/*++======================================================================*/
++PSCOPE_LIST Scope_Search4Scope( session_t Id, BOOLEAN Session, BOOLEAN Locked )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PSCOPE_LIST scope, rscope=NULL;
++   struct list_head *sl;
++   int  offset;
++
++   DbgPrint("Scope_Search4Scope: 0x%llx 0x%x 0x%x\n", Id, Session, Locked);
++
++   if ( Session )
++   {
++      offset = (int)(&((PSCOPE_LIST)0)->SessionId);
++   }
++   else
++   {
++      offset = (int)(&((PSCOPE_LIST)0)->ScopeId);
++   }
++
++   if ( !Locked ) 
++   {
++      down( &Scope_Lock );
++   }
++
++   sl = Scope_List.next;
++   DbgPrint("Scope_Search4Scope: 0x%x\n", sl);
++   while (sl != &Scope_List)
++   {
++      scope = list_entry(sl, SCOPE_LIST, ScopeList);
++
++      if ( Id == *(session_t *)((char *)scope+offset) )
++      {
++         rscope = scope;
++         break;
++      }
++
++      sl = sl->next;
++   }
++
++   if ( !Locked )
++   {
++      up( &Scope_Lock );
++   }
++
++   DbgPrint("Scope_Search4Scope: return 0x%x\n", rscope);
++   return( rscope );
++}
++
++/*++======================================================================*/
++PSCOPE_LIST Scope_Find_Scope( BOOLEAN Create )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PSCOPE_LIST scope=NULL, pscope=NULL;
++   task_t *task;
++   scope_t scopeId;
++   int addscope=0;
++
++   task = current;
++
++   DbgPrint("Scope_Find_Scope: %d %d %d %d\n", task->uid, task->euid, task->suid, task->fsuid);
++
++   scopeId = task->euid;
++
++   scope = Scope_Search4Scope( scopeId, FALSE, FALSE );
++   
++   if ( !scope && Create )
++   {
++      scope = Novfs_Malloc( sizeof(*pscope), GFP_KERNEL );
++      if ( scope )
++      {
++         scope->ScopeId          = scopeId;
++         scope->SessionId        = 0;
++         scope->ScopePid         = task->pid;
++         scope->ScopeTask        = task;
++         scope->ScopeHash        = 0;
++         scope->ScopeUid         = task->euid;
++         scope->ScopeUserName[0] = '\0';
++
++         if ( !Daemon_CreateSessionId( &scope->SessionId ) )
++         {
++            DbgPrint("Scope_Find_Scope2: %d %d %d %d\n", task->uid, task->euid, task->suid, task->fsuid);
++            memset(scope->ScopeUserName, 0, sizeof(scope->ScopeUserName));
++            scope->ScopeUserNameLength = 0;
++            Daemon_getpwuid(task->euid, sizeof(scope->ScopeUserName), scope->ScopeUserName);
++            scope->ScopeUserNameLength = strlen(scope->ScopeUserName);
++            addscope = 1;
++         }
++
++         scope->ScopeHash = Scope_Hash_Val++;
++         DbgPrint("Scope_Find_Scope: Adding 0x%x\n" \
++                  "   ScopeId:             0x%llx\n" \
++                  "   SessionId:           0x%llx\n" \
++                  "   ScopePid:            %d\n" \
++                  "   ScopeTask:           0x%x\n" \
++                  "   ScopeHash:           %d\n" \
++                  "   ScopeUid:            %d\n" \
++                  "   ScopeUserNameLength: %d\n" \
++                  "   ScopeUserName:       %s\n",
++            scope, 
++            scope->ScopeId, 
++            scope->SessionId, 
++            scope->ScopePid, 
++            scope->ScopeTask, 
++            scope->ScopeHash,
++            scope->ScopeUid,
++            scope->ScopeUserNameLength,
++            scope->ScopeUserName);
++
++         if ( scope->SessionId )
++         {
++            down( &Scope_Lock );
++            list_add(&scope->ScopeList, &Scope_List);
++            up( &Scope_Lock );
++         }
++         else
++         {
++            Novfs_Free(scope);
++            scope = NULL;
++         }
++      }
++
++      if (addscope)
++      {
++         Novfs_Add_to_Root( scope->ScopeUserName );
++      }
++   }
++
++   return(scope);
++}
++
++/*++======================================================================*/
++unsigned long Scope_Get_Hash( PSCOPE_LIST Scope )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   unsigned long hash=0;
++   
++   if ( NULL == Scope)
++   {
++      Scope = Scope_Find_Scope( TRUE );
++   }
++
++   if ( Scope && Scope_Validate_Scope( Scope ))
++   {
++      hash = Scope->ScopeHash;
++   }
++   return( hash );
++}
++
++/*++======================================================================*/
++uid_t Scope_Get_Uid( PSCOPE_LIST Scope )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   uid_t uid=0;
++   
++   if ( NULL == Scope)
++   {
++      Scope = Scope_Find_Scope( TRUE );
++   }
++
++   if ( Scope && Scope_Validate_Scope( Scope ))
++   {
++      uid = Scope->ScopeUid;
++   }
++   return( uid );
++}
++
++/*++======================================================================*/
++int Scope_Validate_Scope( PSCOPE_LIST Scope )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PSCOPE_LIST s;
++   struct list_head *sl;
++   int retVal = 0;
++
++   DbgPrint("Scope_Validate_Scope: 0x%x\n", Scope);
++
++   down( &Scope_Lock );
++
++   sl = Scope_List.next;
++   while (sl != &Scope_List)
++   {
++      s = list_entry(sl, SCOPE_LIST, ScopeList);
++
++      if ( s == Scope )
++      {
++         retVal = 1;
++         break;
++      }
++
++      sl = sl->next;
++   }
++
++   up( &Scope_Lock );
++
++   return( retVal );
++}
++
++/*++======================================================================*/
++char *Scope_Get_UserName( PSCOPE_LIST Scope )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   char *name=NULL;
++   
++   if ( !Scope )
++   {
++      Scope = Scope_Find_Scope( TRUE );
++   }
++
++   if ( Scope && Scope_Validate_Scope( Scope ))
++   {
++      name = Scope->ScopeUserName;
++   }
++   return( name );
++}
++
++/*++======================================================================*/
++session_t Scope_Get_SessionId( PSCOPE_LIST Scope )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   session_t sessionId=0;
++   
++   DbgPrint("Scope_Get_SessionId: 0x%p\n", Scope);
++   if ( !Scope )
++   {
++      Scope = Scope_Find_Scope( TRUE );
++   }
++
++   if ( Scope && Scope_Validate_Scope( Scope ))
++   {
++      sessionId = Scope->SessionId;
++   }
++   DbgPrint("Scope_Get_SessionId: return 0x%llx\n", sessionId);
++   return( sessionId );
++}
++
++/*++======================================================================*/
++PSCOPE_LIST Scope_Get_ScopefromName( struct qstr *Name )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PSCOPE_LIST scope, rscope=NULL;
++   struct list_head *sl;
++
++   DbgPrint("Scope_Get_ScopefromName: %.*s\n", Name->len, Name->name);
++
++   down( &Scope_Lock );
++
++   sl = Scope_List.next;
++   while (sl != &Scope_List)
++   {
++      scope = list_entry(sl, SCOPE_LIST, ScopeList);
++
++      if ( (Name->len == scope->ScopeUserNameLength) &&
++           (0 == strncmp(scope->ScopeUserName, Name->name, Name->len)) )
++      {
++         rscope = scope;
++         break;
++      }
++
++      sl = sl->next;
++   }
++
++   up( &Scope_Lock );
++
++   return( rscope );
++}
++
++/*++======================================================================*/
++int Scope_Set_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PSCOPE_LIST scope;
++   int retVal=0;
++
++   scope = Scope_Find_Scope( TRUE );
++
++   if ( scope )
++   {
++      if (TotalSize)    scope->ScopeUSize = *TotalSize;
++      if (Free)         scope->ScopeUFree = *Free;
++      if (TotalEnties)  scope->ScopeUTEnties = *TotalEnties;
++      if (FreeEnties)   scope->ScopeUAEnties = *FreeEnties;
++   }
++
++
++   return( retVal );
++}
++
++/*++======================================================================*/
++int Scope_Get_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PSCOPE_LIST scope;
++   int retVal=0;
++
++   uint64_t td, fd, te, fe;
++
++   scope = Scope_Find_Scope( TRUE );
++
++   td = fd = te = fe = 0;
++   if ( scope )
++   {
++
++      retVal = Daemon_Get_UserSpace(scope->SessionId, &td, &fd, &te, &fe);
++
++      scope->ScopeUSize = td;
++      scope->ScopeUFree = fd;
++      scope->ScopeUTEnties = te;
++      scope->ScopeUAEnties = fe;
++   }
++
++   if (TotalSize) *TotalSize = td;
++   if (Free) *Free = fd;
++   if (TotalEnties) *TotalEnties = te;
++   if (FreeEnties) *FreeEnties = fe;
++
++   return( retVal );
++}
++
++/*++======================================================================*/
++PSCOPE_LIST Scope_Get_ScopefromPath( struct dentry *Dentry )
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PSCOPE_LIST scope=NULL;
++   char *buf, *path, *cp;
++   struct qstr name;
++
++   buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
++   if (buf)
++   {
++      path = Scope_dget_path( Dentry, buf, PATH_LENGTH_BUFFER, 0 );
++      if (path)
++      {
++         DbgPrint("Scope_Get_ScopefromPath: %s\n", path );
++
++         if (*path == '/') path++;
++
++         cp = path;
++         if ( *cp )
++         {
++            while ( *cp && (*cp != '/') ) cp++;
++
++            *cp = '\0';
++            name.hash = 0;
++            name.len = (int)(cp-path);
++            name.name = path;
++            scope = Scope_Get_ScopefromName( &name );
++         }
++      }
++      Novfs_Free(buf);
++   }
++
++   return( scope );
++}
++
++/*++======================================================================*/
++char *add_to_list(char *Name, char *List, char *EndOfList)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   while (*Name && (List < EndOfList) )
++   {
++      *List++ = *Name++;
++   }
++
++   if (List < EndOfList)
++   {
++      *List++ = '\0';
++   }
++   return(List);
++}
++
++/*++======================================================================*/
++char *Scope_Get_ScopeUsers()
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PSCOPE_LIST scope;
++   struct list_head *sl;
++   int asize=8*MAX_USERNAME_LENGTH;
++   char *list, *cp, *ep;
++   
++   DbgPrint("Scope_Get_ScopeUsers\n");
++
++   do /* Copy list until done or out of memory */
++   {
++      list = Novfs_Malloc(asize, GFP_KERNEL);
++
++      DbgPrint("Scope_Get_ScopeUsers list=0x%p\n", list);
++      if (list)
++      {
++         cp = list;
++         ep = cp+asize;
++
++         /*
++          * Add the tree and server entries
++          */
++         cp = add_to_list(TREE_DIRECTORY_NAME, cp, ep);
++         cp = add_to_list(SERVER_DIRECTORY_NAME, cp, ep);
++
++         down( &Scope_Lock );
++
++         sl = Scope_List.next;
++         while ( (sl != &Scope_List) && (cp < ep) )
++         {
++            scope = list_entry(sl, SCOPE_LIST, ScopeList);
++
++            DbgPrint("Scope_Get_ScopeUsers found 0x%p %s\n", scope, scope->ScopeUserName);
++
++            cp = add_to_list(scope->ScopeUserName, cp, ep);
++            
++            sl = sl->next;
++         }
++
++         up( &Scope_Lock );
++
++         if (cp < ep)
++         {
++            *cp++ = '\0';
++            asize = 0;
++         }
++         else  /* Allocation was to small, up size */
++         {
++            asize *= 4;
++            Novfs_Free(list);
++            list=NULL;
++         }
++      }
++      else /* if allocation fails return an empty list */
++      {
++         break;
++      }
++   } while ( !list );  /* List was to small try again */
++
++   return( list );
++}
++
++/*++======================================================================*/
++void *Scope_Lookup()
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PSCOPE_LIST scope;
++
++   scope = Scope_Find_Scope( TRUE );
++   return( scope );
++}
++
++/*++======================================================================*/
++void 
++NO_TRACE
++Scope_Timer_Function(unsigned long Context)
++/*
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   up(&Scope_Thread_Delay);
++}
++
++/*++======================================================================*/
++int Scope_Cleanup_Thread(void *Args)
++/*
++ *
++ *  Arguments:
++ *
++ *  Returns:
++ *
++ *  Abstract:
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PSCOPE_LIST scope, rscope;
++   struct list_head *sl, cleanup;
++   task_t *task;
++
++   DbgPrint( "Scope_Cleanup_Thread: %d\n", current->pid);
++
++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7)
++   lock_kernel();
++   snprintf(current->comm, 16, "novfs_ST");
++   unlock_kernel();
++   sys_close(0);
++   sys_close(1);
++   sys_close(2);
++#endif
++
++	/*
++	 * Setup and start que timer
++    */
++	init_timer( &Scope_Timer );
++
++   for ( ;; )
++   {
++      DbgPrint( "Scope_Cleanup_Thread: looping\n");
++      if ( Scope_Thread_Terminate )
++      {
++         break;
++      }
++
++      /*
++       * Check scope list for any terminated processes
++       */
++      down( &Scope_Lock );
++
++      sl = Scope_List.next;
++      INIT_LIST_HEAD( &cleanup );
++
++      while (sl != &Scope_List)
++      {
++         scope = list_entry(sl, SCOPE_LIST, ScopeList);
++         sl = sl->next;
++
++         rscope = NULL;
++         read_lock(&tasklist_lock);
++         for_each_process(task)
++         {
++            if ( (task->uid == scope->ScopeUid) || (task->euid == scope->ScopeUid) )
++            {
++               rscope = scope;
++               break;
++            }
++         }
++         read_unlock(&tasklist_lock);
++         if ( !rscope )
++         {
++            list_move( &scope->ScopeList, &cleanup );
++            DbgPrint("Scope_Cleanup_Thread: Scope=0x%x\n", rscope);
++         }
++      }         
++
++      up(&Scope_Lock);
++
++      sl = cleanup.next;
++      while ( sl != &cleanup )
++      {
++         scope = list_entry(sl, SCOPE_LIST, ScopeList);
++         sl = sl->next;
++
++         DbgPrint("Scope_Cleanup_Thread: Removing 0x%x\n" \
++                  "   ScopeId:       0x%llx\n" \
++                  "   SessionId:     0x%llx\n" \
++                  "   ScopePid:      %d\n" \
++                  "   ScopeTask:     0x%x\n" \
++                  "   ScopeHash:     %d\n" \
++                  "   ScopeUid:      %d\n" \
++                  "   ScopeUserName: %s\n",
++            scope, 
++            scope->ScopeId, 
++            scope->SessionId, 
++            scope->ScopePid, 
++            scope->ScopeTask, 
++            scope->ScopeHash,
++            scope->ScopeUid,
++            scope->ScopeUserName);
++         if ( !Scope_Search4Scope(scope->SessionId, TRUE, FALSE) )
++         {
++            Novfs_Remove_from_Root( scope->ScopeUserName );
++            Daemon_DestroySessionId( scope->SessionId );
++         }
++         Novfs_Free( scope );
++      }
++
++      Scope_Timer.expires = jiffies + HZ*CLEANUP_INTERVAL;
++      Scope_Timer.data = (unsigned long)0;
++      Scope_Timer.function = Scope_Timer_Function;
++      add_timer(&Scope_Timer);
++      DbgPrint( "Scope_Cleanup_Thread: sleeping\n");
++
++      if (down_interruptible( &Scope_Thread_Delay ))
++      {
++         break;
++      }
++      del_timer(&Scope_Timer);
++   }
++   Scope_Thread_Terminate = 0;
++
++   printk( KERN_INFO "Scope_Cleanup_Thread: Exit\n");
++   DbgPrint( "Scope_Cleanup_Thread: Exit\n");
++   return(0);
++}
++
++/*++======================================================================*/
++void Scope_Cleanup( void )
++/*
++ *
++ *  Arguments:   None
++ *
++ *  Returns:     Nothing
++ *
++ *  Abstract:    Removes all knows scopes.
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   PSCOPE_LIST scope;
++   struct list_head *sl;
++
++   DbgPrint( "Scope_Cleanup:\n");
++
++   /*
++    * Check scope list for any terminated processes
++    */
++   down( &Scope_Lock );
++
++   sl = Scope_List.next;
++
++   while (sl != &Scope_List)
++   {
++      scope = list_entry( sl, SCOPE_LIST, ScopeList );
++      sl = sl->next;
++
++      list_del( &scope->ScopeList );
++
++      DbgPrint("Scope_Cleanup: Removing 0x%x\n" \
++               "   ScopeId:       0x%llx\n" \
++               "   SessionId:     0x%llx\n" \
++               "   ScopePid:      %d\n" \
++               "   ScopeTask:     0x%x\n" \
++               "   ScopeHash:     %d\n" \
++               "   ScopeUid:      %d\n" \
++               "   ScopeUserName: %s\n",
++         scope, 
++         scope->ScopeId, 
++         scope->SessionId, 
++         scope->ScopePid, 
++         scope->ScopeTask, 
++         scope->ScopeHash,
++         scope->ScopeUid,
++         scope->ScopeUserName);
++      if ( !Scope_Search4Scope( scope->SessionId, TRUE, TRUE ) )
++      {
++         Novfs_Remove_from_Root( scope->ScopeUserName );
++         Daemon_DestroySessionId( scope->SessionId );
++      }
++      Novfs_Free( scope );
++   }         
++
++   up(&Scope_Lock);
++
++}
++
++/*++======================================================================*/
++char  *
++NO_TRACE
++Scope_dget_path( struct dentry *Dentry, char *Buf, unsigned int Buflen, int Flags)
++/*
++ *  Arguments:   struct dentry *Dentry - starting entry
++ *               char *Buf - pointer to memory buffer
++ *               unsigned int Buflen - size of memory buffer
++ *
++ *  Returns:     pointer to path.
++ *
++ *  Abstract:    Walks the dentry chain building a path.
++ *
++ *  Notes:
++ *
++ *  Environment:
++ *
++ *========================================================================*/
++{
++   char *retval=&Buf[Buflen];
++   struct dentry *p=Dentry;
++   int len;
++
++   *(--retval) = '\0';
++   Buflen--;
++
++/*
++   if (!IS_ROOT(p))
++   {
++      while (Buflen && !IS_ROOT(p))
++      {
++         if (Buflen > p->d_name.len)
++         {
++            retval -= p->d_name.len;
++            Buflen -= p->d_name.len;
++            memcpy(retval, p->d_name.name, p->d_name.len);
++            *(--retval) = '/';
++            Buflen--;
++            p = p->d_parent;
++         }
++         else
++         {
++            retval = NULL;
++            break;
++         }
++      }
++   }
++   if (Flags)
++   {
++      len = strlen(p->d_sb->s_type->name);
++      if (Buflen-len > 0)
++      {
++         retval -= len;
++         Buflen -= len;
++         memcpy(retval, p->d_sb->s_type->name, len);
++         *(--retval) = '/';
++         Buflen--;
++      }
++   }
++   else
++   {
++      *(--retval) = '/';
++      Buflen--;
++   }
++*/
++   do
++   {
++      if (Buflen > p->d_name.len)
++      {
++         retval -= p->d_name.len;
++         Buflen -= p->d_name.len;
++         memcpy(retval, p->d_name.name, p->d_name.len);
++         *(--retval) = '/';
++         Buflen--;
++         p = p->d_parent;
++      }
++      else
++      {
++         retval = NULL;
++         break;
++      }
++   } while (!IS_ROOT(p));
++
++   if (IS_ROOT(Dentry))
++   {
++      retval++;
++   }
++   
++   if (Flags)
++   {
++      len = strlen(p->d_sb->s_type->name);
++      if (Buflen-len > 0)
++      {
++         retval -= len;
++         Buflen -= len;
++         memcpy(retval, p->d_sb->s_type->name, len);
++         *(--retval) = '/';
++         Buflen--;
++      }
++   }
++
++   return(retval);
++}
++
++void Scope_Dump_Tasklist( void )
++{
++#ifdef	OLD_DEBUG_KERNEL
++   task_t *task;
++   struct files_struct *fs;
++   int i, open_files=0;
++   static char buf[1024];
++   char *path;
++
++   
++   for_each_process(task)
++   {
++      kdb_printf("Task List:\n" \
++                 "   Task:           0x%p\n" \
++                 "   pid:            %d\n" \
++                 "   tgid:           %d\n" \
++                 "   uid:            %d %d %d %d\n" \
++                 "   gid:            %d\n" \
++                 "   parent:         0x%p\n" \
++                 "   comm:           %s\n" \
++                 "   user:           0x%p\n" \
++                 "   real_parent:    0x%p\n" \
++                 "   parent_exec_id: 0x%x\n" \
++                 "   self_exec_id:   0x%x\n" \
++                 "   did_exec:       0x%x\n" \
++                 "   signal:         0x%p\n" \
++                 "   thread_info:    0x%p\n" \
++                 "   security:       0x%p\n",
++            task,
++            task->pid,
++            task->tgid,
++            task->uid,task->euid,task->suid,task->fsuid,
++            task->gid,
++            task->parent,
++            task->comm,
++            task->user,
++            task->real_parent,
++            task->parent_exec_id,
++            task->self_exec_id,
++            task->did_exec,
++            task->signal,
++            task->thread_info,
++            task->security);
++      
++      fs = task->files;
++      kdb_printf("   File List:      0x%p\n", fs);
++      if (fs)
++      {
++         open_files = fs->max_fds;
++         kdb_printf("   Max fds:        %d\n", open_files);
++         for (i = 0; i<open_files; i++) 
++         {
++            struct file *f = fs->fd[i];
++            if (f && (f->f_dentry))
++            {
++               path = Scope_dget_path(f->f_dentry, buf, sizeof(buf), 1);
++               if ( !path )
++               {
++                  path = buf;
++                  memcpy(path, f->f_dentry->d_name.name, f->f_dentry->d_name.len);
++                  path[f->f_dentry->d_name.len] = '\0';
++               }
++               kdb_printf("      file(%d): 0x%p\n" \
++                          "         f_dentry: 0x%p\n" \
++                          "            d_name:  %s\n" \
++                          "            d_count: %d\n" \
++                          "            d_inode: 0x%p\n",
++                  i, f, f->f_dentry, path, 
++                  atomic_read(&f->f_dentry->d_count), 
++                  f->f_dentry->d_inode);
++            }
++         }
++      }
++   }
++#endif
++}
++
++void Scope_Dump_Scopetable( void )
++{
++#ifdef	CONFIG_KDB
++   PSCOPE_LIST scope;
++   struct list_head *sl;
++
++   sl = Scope_List.next;
++   while (sl != &Scope_List)
++   {
++      scope = list_entry(sl, SCOPE_LIST, ScopeList);
++      sl = sl->next;
++      kdb_printf("Scope List:\n" \
++                 "   Scope:         0x%p\n" \
++                 "   ScopeId:       0x%llx\n" \
++                 "   SessionId:     0x%llx\n" \
++                 "   ScopePid:      %u\n" \
++                 "   ScopeTask:     0x%p\n" \
++                 "   ScopeHash:     0x%lx\n" \
++                 "   ScopeUid:      %ld\n" \
++                 "   ScopeUserName: %s\n",
++         scope, 
++         scope->ScopeId, 
++         scope->SessionId, 
++         scope->ScopePid, 
++         scope->ScopeTask, 
++         scope->ScopeHash,
++         (long)scope->ScopeUid,
++         scope->ScopeUserName);
++
++   }         
++
++#endif
++}
+diff -uNr src.old/src/vfs.h src/src/vfs.h
+--- src.old/src/vfs.h	1970-01-01 01:00:00.000000000 +0100
++++ src/src/vfs.h	2006-10-16 15:08:22.000000000 +0200
+@@ -0,0 +1,283 @@
++/*++========================================================================
++ * Program Name:     Novell NCP Redirector for Linux
++ * File Name:        vfs.h
++ * Version:          v1.00
++ * Author:           James Turner
++ *
++ * Abstract:         Include module for novfs.
++ * Notes:
++ * Revision History: 
++ *
++ *
++ * Copyright (C) 2005 Novell, Inc.
++ *
++ * 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.
++ *======================================================================--*/
++#ifndef __STDC_VERSION__
++#define __STDC_VERSION__ 0L
++#endif
++
++/*===[ Include files specific to Linux ]==================================*/
++#ifdef	CONFIG_KDB
++#include <linux/kdb.h>
++#include <linux/kdbprivate.h>
++
++#endif	/* CONFIG_KDB */
++
++#include <linux/version.h>
++#include <linux/namei.h>
++
++/*===[ Include files specific to this module ]============================*/
++
++/*===[ External data ]====================================================*/
++extern int Novfs_Version_Major;
++extern int Novfs_Version_Minor;
++extern int Novfs_Version_Sub;
++extern int Novfs_Version_Release;
++
++/*===[ External prototypes ]==============================================*/
++extern void *Novfs_Malloc( size_t, int );
++extern void  Novfs_Free( const void * );
++
++
++/*===[ Manifest constants ]===============================================*/
++#define NOVFS_MAGIC	0x4e574653
++#define MODULE_NAME "novfs"
++
++#define UNUSED_VARIABLE(a) (a) = (a)
++
++#define TREE_DIRECTORY_NAME   ".Trees"
++#define SERVER_DIRECTORY_NAME ".Servers"
++
++#define PATH_LENGTH_BUFFER	PATH_MAX
++#define NW_MAX_PATH_LENGTH 255
++
++#define IOC_LOGIN    0x4a540000
++#define IOC_LOGOUT	0x4a540001
++#define IOC_XPLAT    0x4a540002
++#define IOC_SESSION  0x4a540003
++#define IOC_DEBUGPRINT  0x4a540004
++
++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
++#define D_CHILD d_u.d_child
++#define AS_TREE_LOCK(l)   read_lock_irq(l)
++#define AS_TREE_UNLOCK(l) read_unlock_irq(l)
++#else
++#define D_CHILD d_child
++#define AS_TREE_LOCK(l)   spin_lock_irq(l)
++#define AS_TREE_UNLOCK(l) spin_unlock_irq(l)
++#endif
++
++/*
++ * NetWare file attributes
++ */
++
++#define  NW_ATTRIBUTE_NORMAL                    0x00
++#define  NW_ATTRIBUTE_READ_ONLY                 0x01
++#define  NW_ATTRIBUTE_HIDDEN                    0x02
++#define  NW_ATTRIBUTE_SYSTEM                    0x04
++#define  NW_ATTRIBUTE_EXECUTE_ONLY              0x08
++#define  NW_ATTRIBUTE_DIRECTORY                 0x10
++#define  NW_ATTRIBUTE_ARCHIVE                   0x20
++#define  NW_ATTRIBUTE_EXECUTE                   0x40
++#define  NW_ATTRIBUTE_SHAREABLE                 0x80
++
++/*
++ * Define READ/WRITE flag for DATA_LIST
++ */
++#define DLREAD    0
++#define DLWRITE   1
++
++/*
++ * Define list type
++ */
++#define USER_LIST    1
++#define SERVER_LIST  2
++#define VOLUME_LIST  3
++
++/*
++ * Define flags used in for inodes
++ */
++#define  USER_INODE     1
++#define  UPDATE_INODE   2
++
++/*
++ * Define flags for directory cache flags
++ */
++#define ENTRY_VALID  0x00000001
++
++#ifdef INTENT_MAGIC
++#define NDOPENFLAGS intent.it_flags
++#else
++#define NDOPENFLAGS intent.open.flags
++#endif
++
++/*
++ * daemon_command_t flags values
++ */
++#define INTERRUPTIBLE   1
++
++#define NO_TRACE __attribute__((__no_instrument_function__))
++
++#ifndef NOVFS_VFS_MAJOR
++#define NOVFS_VFS_MAJOR 0
++#endif
++
++#ifndef NOVFS_VFS_MINOR
++#define NOVFS_VFS_MINOR 0
++#endif
++
++#ifndef NOVFS_VFS_SUB
++#define NOVFS_VFS_SUB 0
++#endif
++
++#ifndef NOVFS_VFS_RELEASE
++#define NOVFS_VFS_RELEASE 0
++#endif
++
++#define VALUE_TO_STR( value ) #value
++#define DEFINE_TO_STR(value) VALUE_TO_STR(value)
++
++
++#define NOVFS_VERSION_STRING \
++         DEFINE_TO_STR(NOVFS_VFS_MAJOR)"." \
++         DEFINE_TO_STR(NOVFS_VFS_MINOR)"." \
++         DEFINE_TO_STR(NOVFS_VFS_SUB)"-" \
++         DEFINE_TO_STR(NOVFS_VFS_RELEASE) \
++         "\0"
++
++/*===[ Type definitions ]=================================================*/
++typedef struct _ENTRY_INFO
++{
++	int			    type;
++	umode_t		    mode;
++	uid_t		       uid;
++	gid_t		       gid;
++	loff_t		    size;
++	struct timespec atime;
++	struct timespec mtime;
++	struct timespec ctime;
++	int			    namelength;
++	unsigned char   name[1];
++} ENTRY_INFO, *PENTRY_INFO;
++
++typedef struct _STRING_
++{
++	int Length;
++	unsigned char *Data;
++} STRING, *PSTRING;
++
++typedef struct _LOGIN_
++{
++	STRING Server;
++	STRING UserName;
++	STRING Password;
++} LOGIN, *PLOGIN;
++
++typedef struct _LOGOUT_
++{
++	STRING Server;
++} LOGOUT, *PLOGOUT;
++
++typedef uint64_t scope_t;
++typedef uint64_t session_t;
++
++typedef struct _DIR_CACHE_
++{
++   struct list_head list;
++   int flags;
++   u64 jiffies;
++   ino_t ino;
++	loff_t size;
++   umode_t mode; 
++	struct timespec atime;
++	struct timespec mtime;
++	struct timespec ctime;
++   unsigned long hash;
++   int nameLen;
++   char name[1];
++} DIR_CACHE, *PDIR_CACHE;
++
++typedef struct _INODE_DATA_
++{
++	void            *Scope;
++	unsigned long    Flags;
++	struct list_head IList;
++	struct inode    *Inode;
++	struct list_head DirCache;
++	struct semaphore DirCacheLock;
++   unsigned long    FileHandle;
++   int              CacheFlag;
++	char             Name[1]; /* Needs to be last entry */
++} INODE_DATA, *PINODE_DATA;
++
++typedef struct _DATA_LIST_
++{
++   void *page;
++   void *offset;
++   int   len;
++   int   rwflag;
++} DATA_LIST, *PDATA_LIST;
++
++typedef struct	_XPLAT_
++{
++	int				xfunction;
++	unsigned long	reqLen;
++	void			*reqData;
++	unsigned long	repLen;
++	void			*repData;
++
++} XPLAT, *PXPLAT;
++
++
++/*===[ Function prototypes ]==============================================*/
++
++extern int DbgPrint( char *Fmt, ... );
++extern char *ctime_r(time_t *clock, char *buf);
++
++
++/*++======================================================================*/
++static inline unsigned long InterlockedIncrement( unsigned long *p )
++/*
++ *
++ *  Arguments:   unsigned long *p - pointer to value. 
++ *
++ *  Returns:     unsigned long - value prior to increment.
++ *
++ *  Abstract:    The value of *p is incremented and the value of *p before
++ *               it was incremented is returned.  This is an atomic operation.
++ *
++ *  Notes:       
++ *
++ *  Environment: 
++ *
++ *========================================================================*/
++{
++	unsigned long x = 1;
++
++	mb();
++
++#if   defined(__i386) || defined(__i386__)
++	__asm__ __volatile__(
++        " lock xadd %0,(%2)"
++		: "+r"(x), "=m"(p)
++		: "r"(p), "m"(p)
++		: "memory");
++
++#else
++   x = *p++;
++#endif
++	return( x );
++}
diff --git a/trunk/novell4gentoo/net-fs/novell-novfs/files/novell-novfs-2.0.0-config_h.patch b/trunk/novell4gentoo/net-fs/novell-novfs/files/novell-novfs-2.0.0-config_h.patch
new file mode 100644
index 00000000..98d01e79
--- /dev/null
+++ b/trunk/novell4gentoo/net-fs/novell-novfs/files/novell-novfs-2.0.0-config_h.patch
@@ -0,0 +1,12 @@
+Index: novfs-2.0.0/src/inode.c
+===================================================================
+--- novfs-2.0.0.orig/src/inode.c
++++ novfs-2.0.0/src/inode.c
+@@ -29,7 +29,6 @@
+ 
+ /*===[ Include files specific to Linux ]==================================*/
+ #include <linux/module.h>
+-#include <linux/config.h>
+ #include <linux/init.h>
+ #include <linux/fs.h>
+ #include <linux/dcache.h>
diff --git a/trunk/novell4gentoo/net-fs/novell-novfs/files/novell-novfs-2.0.0-dont_use_tasklist_lock.patch b/trunk/novell4gentoo/net-fs/novell-novfs/files/novell-novfs-2.0.0-dont_use_tasklist_lock.patch
new file mode 100644
index 00000000..4e9d495d
--- /dev/null
+++ b/trunk/novell4gentoo/net-fs/novell-novfs/files/novell-novfs-2.0.0-dont_use_tasklist_lock.patch
@@ -0,0 +1,21 @@
+diff -uNr novfs-1.2.0.orig/novfs/scope.c novfs-1.2.0/novfs/scope.c
+--- novfs-1.2.0.orig/src/scope.c	2006-08-30 22:32:57.000000000 +0200
++++ novfs-1.2.0/src/scope.c	2006-10-15 16:35:47.000000000 +0200
+@@ -869,7 +869,7 @@
+          sl = sl->next;
+ 
+          rscope = NULL;
+-         read_lock(&tasklist_lock);
++         rcu_read_lock();
+          for_each_process(task)
+          {
+             if ( (task->uid == scope->ScopeUid) || (task->euid == scope->ScopeUid) )
+@@ -878,7 +878,7 @@
+                break;
+             }
+          }
+-         read_unlock(&tasklist_lock);
++         rcu_read_unlock();
+          if ( !rscope )
+          {
+             list_move( &scope->ScopeList, &cleanup );
diff --git a/trunk/novell4gentoo/net-fs/novell-novfs/files/novell-novfs-2.0.0-generic_file_read.patch b/trunk/novell4gentoo/net-fs/novell-novfs/files/novell-novfs-2.0.0-generic_file_read.patch
new file mode 100644
index 00000000..85e733c4
--- /dev/null
+++ b/trunk/novell4gentoo/net-fs/novell-novfs/files/novell-novfs-2.0.0-generic_file_read.patch
@@ -0,0 +1,22 @@
+Index: novfs-2.0.0/src/inode.c
+===================================================================
+--- novfs-2.0.0.orig/src/inode.c
++++ novfs-2.0.0/src/inode.c
+@@ -1629,7 +1629,7 @@ ssize_t Novfs_f_read(struct file *file, 
+            !(file->f_flags & O_DIRECT) && 
+            id->CacheFlag )
+       {
+-         totalread = generic_file_read(file, buf, len, off);
++         totalread = do_sync_read(file, buf, len, off);
+       }
+       else
+       {
+@@ -1693,7 +1693,7 @@ ssize_t Novfs_f_write(struct file *file,
+            !(file->f_flags & O_DIRECT) &&
+            id->CacheFlag )
+       {
+-         totalwrite = generic_file_write(file, buf, len, off);
++         totalwrite = do_sync_write(file, buf, len, off);
+       }
+       else
+       {
diff --git a/trunk/novell4gentoo/net-fs/novell-novfs/files/novell-novfs-2.0.0-i_blksize.patch b/trunk/novell4gentoo/net-fs/novell-novfs/files/novell-novfs-2.0.0-i_blksize.patch
new file mode 100644
index 00000000..9fdc37ef
--- /dev/null
+++ b/trunk/novell4gentoo/net-fs/novell-novfs/files/novell-novfs-2.0.0-i_blksize.patch
@@ -0,0 +1,67 @@
+---
+ src/inode.c |   14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+Index: novfs-2.0.0/src/inode.c
+===================================================================
+--- novfs-2.0.0.orig/src/inode.c
++++ novfs-2.0.0/src/inode.c
+@@ -1731,7 +1731,7 @@ ssize_t Novfs_f_write(struct file *file,
+             if (offset > i_size_read(inode))
+             {
+                i_size_write(inode, offset);
+-               inode->i_blocks = (offset + inode->i_blksize - 1) >> inode->i_blkbits;
++               inode->i_blocks = (offset + inode->i_sb->s_blocksize - 1) >> inode->i_blkbits;
+             }
+             inode->i_mtime = inode->i_atime = CURRENT_TIME;
+             id->Flags |= UPDATE_INODE;
+@@ -2913,12 +2913,12 @@ void update_inode(struct inode *Inode, P
+    Inode->i_ctime = Info->ctime;
+    Inode->i_mtime = Info->mtime;
+ 
+-   if (Inode->i_size && Inode->i_blksize)
++   if (Inode->i_size && Inode->i_sb->s_blocksize)
+    {
+       Inode->i_blocks = (u_long)(Info->size >> (loff_t)Inode->i_blkbits);
+-      Inode->i_bytes = Info->size & (Inode->i_blksize - 1);
++      Inode->i_bytes = Info->size & (Inode->i_sb->s_blocksize - 1);
+ 
+-      DbgPrint("update_inode: i_blksize=%d\n", Inode->i_blksize);
++      DbgPrint("update_inode: i_blksize=%d\n", Inode->i_sb->s_blocksize);
+       DbgPrint("update_inode: i_blkbits=%d\n", Inode->i_blkbits);
+       DbgPrint("update_inode: i_blocks=%d\n", Inode->i_blocks);
+       DbgPrint("update_inode: i_bytes=%d\n", Inode->i_bytes);
+@@ -3604,7 +3604,7 @@ int Novfs_i_getattr(struct vfsmount *mnt
+    kstat->atime   = inode->i_atime;
+    kstat->mtime   = inode->i_mtime;
+    kstat->ctime   = inode->i_ctime;
+-   kstat->blksize = inode->i_blksize;
++   kstat->blksize = inode->i_sb->s_blocksize;
+    kstat->blocks  = inode->i_blocks;
+    if (inode->i_bytes)
+    {
+@@ -3909,7 +3909,6 @@ struct inode *Novfs_get_inode(struct sup
+       inode->i_mode = mode;
+       inode->i_uid = Uid;
+       inode->i_gid = 0;
+-      inode->i_blksize = sb->s_blocksize;
+       inode->i_blkbits = sb->s_blocksize_bits;
+       inode->i_blocks = 0;
+       inode->i_rdev = 0;
+@@ -3962,7 +3961,6 @@ struct inode *Novfs_get_inode(struct sup
+       case S_IFDIR:
+          inode->i_op = &Novfs_inode_operations;
+          inode->i_fop = &Novfs_dir_operations;
+-         inode->i_blksize = 0;
+          inode->i_blkbits = 0;
+          break;
+ 
+@@ -3973,7 +3971,7 @@ struct inode *Novfs_get_inode(struct sup
+ 
+       DbgPrint("Novfs_get_inode: size=%lld\n", inode->i_size);
+       DbgPrint("Novfs_get_inode: mode=0%o\n", inode->i_mode);
+-      DbgPrint("Novfs_get_inode: i_blksize=%d\n", inode->i_blksize);
++      DbgPrint("Novfs_get_inode: i_blksize=%d\n", inode->i_sb->s_blocksize);
+       DbgPrint("Novfs_get_inode: i_blkbits=%d\n", inode->i_blkbits);
+       DbgPrint("Novfs_get_inode: i_blocks=%d\n", inode->i_blocks);
+       DbgPrint("Novfs_get_inode: i_bytes=%d\n", inode->i_bytes);
diff --git a/trunk/novell4gentoo/net-fs/novell-novfs/files/novell-novfs-2.0.0-u.generic_ip.patch b/trunk/novell4gentoo/net-fs/novell-novfs/files/novell-novfs-2.0.0-u.generic_ip.patch
new file mode 100644
index 00000000..827a8a2f
--- /dev/null
+++ b/trunk/novell4gentoo/net-fs/novell-novfs/files/novell-novfs-2.0.0-u.generic_ip.patch
@@ -0,0 +1,609 @@
+---
+ src/inode.c |  194 ++++++++++++++++++++++++++++++------------------------------
+ 1 file changed, 97 insertions(+), 97 deletions(-)
+
+Index: novfs-2.0.0/src/inode.c
+===================================================================
+--- novfs-2.0.0.orig/src/inode.c
++++ novfs-2.0.0/src/inode.c
+@@ -422,9 +422,9 @@ int Novfs_Remove_from_Root(char *RemoveN
+    dentry = d_lookup( Novfs_root, &name);
+    if (dentry)
+    {
+-      if (dentry->d_inode && dentry->d_inode->u.generic_ip)
++      if (dentry->d_inode && dentry->d_inode->i_private)
+       {
+-         ((PINODE_DATA)(dentry->d_inode->u.generic_ip))->Scope = NULL;
++         ((PINODE_DATA)(dentry->d_inode->i_private))->Scope = NULL;
+       }
+       dput(dentry);
+    }
+@@ -535,9 +535,9 @@ int Novfs_Add_to_Root2(char *AddName)
+             inode->i_mtime = CURRENT_TIME;
+             if ( !Novfs_d_add(Novfs_root, entry, inode, 1))
+             {
+-               if (inode->u.generic_ip)
++               if (inode->i_private)
+                {
+-                  ((PINODE_DATA)inode->u.generic_ip)->Flags = USER_INODE;
++                  ((PINODE_DATA)inode->i_private)->Flags = USER_INODE;
+                }
+                PRINT_DENTRY("After Novfs_d_add", entry);
+             }
+@@ -651,7 +651,7 @@ int verify_dentry( struct dentry *dentry
+ 
+    if ( dentry && dentry->d_parent && 
+         (dir = dentry->d_parent->d_inode) && 
+-        (id = dir->u.generic_ip) )
++        (id = dir->i_private) )
+    {
+       parent = dget_parent(dentry);
+ 
+@@ -675,7 +675,7 @@ int verify_dentry( struct dentry *dentry
+                   /*
+                    * Values don't match so update.
+                    */
+-                  ((PINODE_DATA)inode->u.generic_ip)->Flags |= UPDATE_INODE;
++                  ((PINODE_DATA)inode->i_private)->Flags |= UPDATE_INODE;
+                }
+ 
+                ctime = get_jiffies_64() - ctime;
+@@ -776,9 +776,9 @@ int verify_dentry( struct dentry *dentry
+                         id->Flags &= ~UPDATE_INODE;
+ 
+                         dentry->d_inode->i_flags &= ~S_DEAD;
+-                        if (dentry->d_inode->u.generic_ip)
++                        if (dentry->d_inode->i_private)
+                         {
+-                           ((PINODE_DATA)dentry->d_inode->u.generic_ip)->Scope = id->Scope;
++                           ((PINODE_DATA)dentry->d_inode->i_private)->Scope = id->Scope;
+                         }
+                      }
+                   }
+@@ -877,9 +877,9 @@ int Novfs_d_add(struct dentry *Parent, s
+       Novfs_Free(buf);
+    }
+ 
+-   if ( Parent && Parent->d_inode && Parent->d_inode->u.generic_ip)
++   if ( Parent && Parent->d_inode && Parent->d_inode->i_private)
+    {
+-      id = (PINODE_DATA)Parent->d_inode->u.generic_ip;
++      id = (PINODE_DATA)Parent->d_inode->i_private;
+    }
+ 
+    if (id && id->Scope)
+@@ -891,7 +891,7 @@ int Novfs_d_add(struct dentry *Parent, s
+       scope = Scope_Get_ScopefromPath( d );
+    }
+ 
+-   ((PINODE_DATA)i->u.generic_ip)->Scope = scope;
++   ((PINODE_DATA)i->i_private)->Scope = scope;
+ 
+    d->d_time = jiffies+(File_update_timeout*HZ);
+    if (a)
+@@ -944,7 +944,7 @@ int Novfs_d_revalidate(struct dentry *de
+       if ( dentry->d_inode &&
+            dentry->d_parent && 
+            (dir = dentry->d_parent->d_inode) && 
+-           (id = dir->u.generic_ip) )
++           (id = dir->i_private) )
+       {
+          /*
+           * Check timer to see if in valid time limit
+@@ -1399,15 +1399,15 @@ int Novfs_dir_readdir(struct file * file
+ 	{
+ 		if (!file->private_data)
+ 		{
+-			if ( inode && inode->u.generic_ip )
++			if ( inode && inode->i_private )
+ 			{
+-				sessionId = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
++				sessionId = Scope_Get_SessionId(((PINODE_DATA)inode->i_private)->Scope);
+ 				if (0 == sessionId)
+ 				{
+-					((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath(file->f_dentry);
+-					sessionId = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
++					((PINODE_DATA)inode->i_private)->Scope = Scope_Get_ScopefromPath(file->f_dentry);
++					sessionId = Scope_Get_SessionId(((PINODE_DATA)inode->i_private)->Scope);
+ 				}
+-				uid = Scope_Get_Uid(((PINODE_DATA)inode->u.generic_ip)->Scope);
++				uid = Scope_Get_Uid(((PINODE_DATA)inode->i_private)->Scope);
+ 			}
+ 			else
+ 			{
+@@ -1501,9 +1501,9 @@ int Novfs_dir_readdir(struct file * file
+ 				struct inode *dinode = file->private_data;
+ 				PINODE_DATA id = (PINODE_DATA)((char *)file->private_data+sizeof(struct inode));
+ 			
+-				dinode->u.generic_ip = id;
++				dinode->i_private = id;
+ 
+-				id->Scope = ((PINODE_DATA)inode->u.generic_ip)->Scope;
++				id->Scope = ((PINODE_DATA)inode->i_private)->Scope;
+ 				id->Flags = 0;
+ 				INIT_LIST_HEAD( &id->DirCache );
+ 				init_MUTEX( &id->DirCacheLock );
+@@ -1616,7 +1616,7 @@ ssize_t Novfs_f_read(struct file *file, 
+ 
+    if ( file->f_dentry && 
+         (inode = file->f_dentry->d_inode) && 
+-        (id = (PINODE_DATA)inode->u.generic_ip))
++        (id = (PINODE_DATA)inode->i_private))
+    {
+ 
+       DbgPrint("Novfs_f_read(0x%x 0x%p %d %lld %.*s)\n", 
+@@ -1685,7 +1685,7 @@ ssize_t Novfs_f_write(struct file *file,
+ 
+    if ( file->f_dentry && 
+         (inode = file->f_dentry->d_inode) && 
+-        (id = file->f_dentry->d_inode->u.generic_ip) )
++        (id = file->f_dentry->d_inode->i_private) )
+    {
+       DbgPrint("Novfs_f_write(0x%x %d %lld %.*s)\n", (unsigned long)file->private_data, len, offset, file->f_dentry->d_name.len, file->f_dentry->d_name.name);
+ 
+@@ -1844,9 +1844,9 @@ int Novfs_f_open(struct inode *inode, st
+       DbgPrint("Novfs_f_open: %.*s f_flags=0%o f_mode=0%o i_mode=0%o\n", file->f_dentry->d_name.len, file->f_dentry->d_name.name, file->f_flags, file->f_mode, inode->i_mode);
+    }
+ 
+-   if (inode && inode->u.generic_ip)
++   if (inode && inode->i_private)
+    {
+-      id = (PINODE_DATA)file->f_dentry->d_inode->u.generic_ip;
++      id = (PINODE_DATA)file->f_dentry->d_inode->i_private;
+       session = Scope_Get_SessionId(id->Scope);
+       if (0 == session)
+       {
+@@ -1888,7 +1888,7 @@ int Novfs_f_open(struct inode *inode, st
+                   ino = 0;
+                   if (Novfs_get_entry(dir, &file->f_dentry->d_name, &ino, info))
+                   {
+-                     ((PINODE_DATA)inode->u.generic_ip)->Flags |= UPDATE_INODE;
++                     ((PINODE_DATA)inode->i_private)->Flags |= UPDATE_INODE;
+                   }
+ 
+                   Novfs_unlock_inode_cache(dir);
+@@ -1956,7 +1956,7 @@ int Novfs_f_release(struct inode *inode,
+       file->f_dentry->d_name.name, 
+       (unsigned long)file->private_data);
+ 
+-   if ( file->f_dentry->d_inode && (id = file->f_dentry->d_inode->u.generic_ip))
++   if ( file->f_dentry->d_inode && (id = file->f_dentry->d_inode->i_private))
+    {
+       session = Scope_Get_SessionId(id->Scope);
+       if (0 == session)
+@@ -2109,13 +2109,13 @@ int Novfs_a_writepage(struct page* page,
+ {
+ 	int retCode = -EFAULT;
+    struct inode *inode = page->mapping->host;
+-   PINODE_DATA id = inode->u.generic_ip;
++   PINODE_DATA id = inode->i_private;
+ 	loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT);
+    session_t session=0;
+    DATA_LIST dlst[2];
+    size_t len = PAGE_CACHE_SIZE;
+ 
+-   session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
++   session = Scope_Get_SessionId(((PINODE_DATA)inode->i_private)->Scope);
+ 
+ 	page_cache_get(page);
+ 
+@@ -2185,10 +2185,10 @@ int Novfs_a_writepages(struct address_sp
+    {
+       DbgPrint(" Inode=0x%x Ino=%d\n", inode, inode->i_ino);
+ 
+-      if (inode->u.generic_ip)
++      if (inode->i_private)
+       {
+-         session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
+-         fh = ((PINODE_DATA)inode->u.generic_ip)->FileHandle;
++         session = Scope_Get_SessionId(((PINODE_DATA)inode->i_private)->Scope);
++         fh = ((PINODE_DATA)inode->i_private)->FileHandle;
+       }
+    }
+ 
+@@ -2427,13 +2427,13 @@ int Novfs_a_readpage(struct file *file, 
+    {
+       DbgPrint(" Inode=0x%x Ino=%d", inode, inode->i_ino);
+ 
+-      if (inode->u.generic_ip)
++      if (inode->i_private)
+       {
+-         session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
++         session = Scope_Get_SessionId(((PINODE_DATA)inode->i_private)->Scope);
+          if (0 == session)
+          {
+-            ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( file->f_dentry );
+-            session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
++            ((PINODE_DATA)inode->i_private)->Scope = Scope_Get_ScopefromPath( file->f_dentry );
++            session = Scope_Get_SessionId(((PINODE_DATA)inode->i_private)->Scope);
+          }
+       }
+    }
+@@ -2519,13 +2519,13 @@ int Novfs_a_readpages(struct file *file,
+    {
+       DbgPrint(" Inode=0x%x Ino=%d\n", inode, inode->i_ino);
+ 
+-      if (inode->u.generic_ip)
++      if (inode->i_private)
+       {
+-         session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
++         session = Scope_Get_SessionId(((PINODE_DATA)inode->i_private)->Scope);
+          if (0 == session)
+          {
+-            ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( file->f_dentry );
+-            session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
++            ((PINODE_DATA)inode->i_private)->Scope = Scope_Get_ScopefromPath( file->f_dentry );
++            session = Scope_Get_SessionId(((PINODE_DATA)inode->i_private)->Scope);
+          }
+       }
+    }
+@@ -2653,13 +2653,13 @@ int Novfs_a_prepare_write(struct file *f
+           */
+          if (file->f_dentry && file->f_dentry->d_inode)
+          {
+-            if (file->f_dentry->d_inode->u.generic_ip)
++            if (file->f_dentry->d_inode->i_private)
+             {
+-               session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
++               session = Scope_Get_SessionId(((PINODE_DATA)inode->i_private)->Scope);
+                if (0 == session)
+                {
+-                  ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( file->f_dentry );
+-                  session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
++                  ((PINODE_DATA)inode->i_private)->Scope = Scope_Get_ScopefromPath( file->f_dentry );
++                  session = Scope_Get_SessionId(((PINODE_DATA)inode->i_private)->Scope);
+                }
+             }
+          }
+@@ -2741,7 +2741,7 @@ int Novfs_a_commit_write(struct file *fi
+    size_t len = to - offset;
+ 
+    DbgPrint("Novfs_a_commit_write: File=0x%p Page=0x%p offset=0x%x To=%u filesize=%lld\n", file, page, offset, to, i_size_read(file->f_dentry->d_inode));
+-   if (file->f_dentry->d_inode && (id = file->f_dentry->d_inode->u.generic_ip))
++   if (file->f_dentry->d_inode && (id = file->f_dentry->d_inode->i_private))
+    {
+       session = Scope_Get_SessionId(id->Scope);
+       if (0 == session)
+@@ -2836,13 +2836,13 @@ int Novfs_i_create(struct inode *dir, st
+ 
+    if (mode | S_IFREG)
+    {
+-      if (dir->u.generic_ip)
++      if (dir->i_private)
+       {
+-         session = Scope_Get_SessionId( ((PINODE_DATA)dir->u.generic_ip)->Scope);
++         session = Scope_Get_SessionId( ((PINODE_DATA)dir->i_private)->Scope);
+          if (0 == session)
+          {
+-            ((PINODE_DATA)dir->u.generic_ip)->Scope = Scope_Get_ScopefromPath( dentry );
+-            session = Scope_Get_SessionId(((PINODE_DATA)dir->u.generic_ip)->Scope);
++            ((PINODE_DATA)dir->i_private)->Scope = Scope_Get_ScopefromPath( dentry );
++            session = Scope_Get_SessionId(((PINODE_DATA)dir->i_private)->Scope);
+          }
+ 
+          buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+@@ -2859,7 +2859,7 @@ int Novfs_i_create(struct inode *dir, st
+                   {
+                      if (dentry->d_inode)
+                      {
+-                        ((PINODE_DATA)dentry->d_inode->u.generic_ip)->Flags |= UPDATE_INODE;
++                        ((PINODE_DATA)dentry->d_inode->i_private)->Flags |= UPDATE_INODE;
+                      }
+                   }
+                }
+@@ -2951,7 +2951,7 @@ struct dentry * Novfs_i_lookup(struct in
+ 
+    DbgPrint("Novfs_i_lookup: dir 0x%x %d name %.*s hash %d inode 0x%0p\n", dir, dir->i_ino, dentry->d_name.len, dentry->d_name.name, dentry->d_name.hash, dentry->d_inode);
+ 
+-   if (dir && (id = dir->u.generic_ip) )
++   if (dir && (id = dir->i_private) )
+    {
+       retVal = 0;
+       if ( IS_ROOT( dentry ))
+@@ -3066,13 +3066,13 @@ int Novfs_i_unlink(struct inode *dir, st
+    if ( inode )
+    {
+       DbgPrint("Novfs_i_unlink: dir=0x%x dir->i_ino=%d inode=0x%x ino=%d\n", dir, dir->i_ino, inode, inode->i_ino);
+-      if (inode->u.generic_ip)
++      if (inode->i_private)
+       {
+-         session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
++         session = Scope_Get_SessionId(((PINODE_DATA)inode->i_private)->Scope);
+          if (0 == session)
+          {
+-            ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( dentry );
+-            session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
++            ((PINODE_DATA)inode->i_private)->Scope = Scope_Get_ScopefromPath( dentry );
++            session = Scope_Get_SessionId(((PINODE_DATA)inode->i_private)->Scope);
+          }
+ 
+          buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+@@ -3142,16 +3142,16 @@ int Novfs_i_mkdir(struct inode *dir, str
+ 
+    mode |= S_IFDIR;
+    mode &= (S_IFMT | S_IRWXU);
+-   if ( dir->u.generic_ip )
++   if ( dir->i_private )
+    {
+-      session = Scope_Get_SessionId( ((PINODE_DATA)dir->u.generic_ip)->Scope);
++      session = Scope_Get_SessionId( ((PINODE_DATA)dir->i_private)->Scope);
+       if (0 == session)
+       {
+-         ((PINODE_DATA)dir->u.generic_ip)->Scope = Scope_Get_ScopefromPath( dentry );
+-         session = Scope_Get_SessionId(((PINODE_DATA)dir->u.generic_ip)->Scope);
++         ((PINODE_DATA)dir->i_private)->Scope = Scope_Get_ScopefromPath( dentry );
++         session = Scope_Get_SessionId(((PINODE_DATA)dir->i_private)->Scope);
+       }
+ 
+-      uid = Scope_Get_Uid( ((PINODE_DATA)dir->u.generic_ip)->Scope);
++      uid = Scope_Get_Uid( ((PINODE_DATA)dir->i_private)->Scope);
+       buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+       if (buf)
+       {
+@@ -3170,7 +3170,7 @@ int Novfs_i_mkdir(struct inode *dir, str
+                      if (inode)
+                      {
+                         update_inode(inode, &info);
+-                        ((PINODE_DATA)inode->u.generic_ip)->Flags &= ~UPDATE_INODE;
++                        ((PINODE_DATA)inode->i_private)->Flags &= ~UPDATE_INODE;
+ 
+                         dentry->d_time = jiffies+(File_update_timeout*HZ);
+ 
+@@ -3238,9 +3238,9 @@ int Novfs_i_mknod(struct inode *dir, str
+       return(-EACCES);
+    }
+ 
+-   if ( ((PINODE_DATA)dir->u.generic_ip) )
++   if ( ((PINODE_DATA)dir->i_private) )
+    {
+-      uid = Scope_Get_Uid( ((PINODE_DATA)dir->u.generic_ip)->Scope);
++      uid = Scope_Get_Uid( ((PINODE_DATA)dir->i_private)->Scope);
+       if (mode & (S_IFREG | S_IFDIR))
+       {
+          inode = Novfs_get_inode(dir->i_sb, mode, dev, uid, 0, &dentry->d_name);
+@@ -3344,27 +3344,27 @@ int Novfs_i_rename(struct inode *odir, s
+                if ( !Novfs_d_strcmp(&newname, &oldname))
+                {
+ 
+-                  if ( od->d_inode && od->d_inode->u.generic_ip )
++                  if ( od->d_inode && od->d_inode->i_private )
+                   {
+ 
+-                     if (nd->d_inode && nd->d_inode->u.generic_ip)
++                     if (nd->d_inode && nd->d_inode->i_private)
+                      {
+-                        session = Scope_Get_SessionId(((PINODE_DATA)ndir->u.generic_ip)->Scope);
++                        session = Scope_Get_SessionId(((PINODE_DATA)ndir->i_private)->Scope);
+                         if (0 == session)
+                         {
+-                           ((PINODE_DATA)ndir->u.generic_ip)->Scope = Scope_Get_ScopefromPath( nd );
+-                           session = Scope_Get_SessionId(((PINODE_DATA)ndir->u.generic_ip)->Scope);
++                           ((PINODE_DATA)ndir->i_private)->Scope = Scope_Get_ScopefromPath( nd );
++                           session = Scope_Get_SessionId(((PINODE_DATA)ndir->i_private)->Scope);
+                         }
+ 
+                         retCode = Novfs_Delete(newpath, S_ISDIR(nd->d_inode->i_mode), session);
+                      }
+ 
+ 
+-                     session = Scope_Get_SessionId(((PINODE_DATA)ndir->u.generic_ip)->Scope);
++                     session = Scope_Get_SessionId(((PINODE_DATA)ndir->i_private)->Scope);
+                      if (0 == session)
+                      {
+-                        ((PINODE_DATA)ndir->u.generic_ip)->Scope = Scope_Get_ScopefromPath( nd );
+-                        session = Scope_Get_SessionId(((PINODE_DATA)ndir->u.generic_ip)->Scope);
++                        ((PINODE_DATA)ndir->i_private)->Scope = Scope_Get_ScopefromPath( nd );
++                        session = Scope_Get_SessionId(((PINODE_DATA)ndir->i_private)->Scope);
+                      }
+                      retCode = Novfs_Rename_File(
+                                  S_ISDIR(od->d_inode->i_mode),
+@@ -3458,13 +3458,13 @@ int Novfs_i_setattr(struct dentry *dentr
+       return(-EACCES);
+    }
+ 
+-   if (inode && inode->u.generic_ip)
++   if (inode && inode->i_private)
+    {
+-      session = Scope_Get_SessionId( ((PINODE_DATA)inode->u.generic_ip)->Scope);
++      session = Scope_Get_SessionId( ((PINODE_DATA)inode->i_private)->Scope);
+       if (0 == session)
+       {
+-         ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( dentry );
+-         session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope);
++         ((PINODE_DATA)inode->i_private)->Scope = Scope_Get_ScopefromPath( dentry );
++         session = Scope_Get_SessionId(((PINODE_DATA)inode->i_private)->Scope);
+       }
+ 
+       buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+@@ -3513,7 +3513,7 @@ int Novfs_i_setattr(struct dentry *dentr
+             
+             if ( !(retVal = Novfs_Set_Attr(path, attr, session) ) )
+             {
+-               ((PINODE_DATA)inode->u.generic_ip)->Flags |= UPDATE_INODE;
++               ((PINODE_DATA)inode->i_private)->Flags |= UPDATE_INODE;
+ 
+                if (ia_valid & ATTR_ATIME)
+                   inode->i_atime = attr->ia_atime;
+@@ -3563,7 +3563,7 @@ int Novfs_i_getattr(struct vfsmount *mnt
+         !IS_ROOT(dentry->d_parent) )
+    {
+       session = 0;
+-      id = dentry->d_inode->u.generic_ip;
++      id = dentry->d_inode->i_private;
+ 
+       if (id && (id->Flags & UPDATE_INODE) )
+       {
+@@ -3744,9 +3744,9 @@ void Novfs_clear_inode(struct inode *ino
+ {
+    InodeCount--;
+    
+-   if ( inode->u.generic_ip )
++   if ( inode->i_private )
+    {
+-      PINODE_DATA id=inode->u.generic_ip;
++      PINODE_DATA id=inode->i_private;
+ 
+       DbgPrint("Novfs_clear_inode: inode=0x%x ino=%d Scope=0x%p Name=%s\n", inode, inode->i_ino, id->Scope, id->Name);
+ 
+@@ -3757,8 +3757,8 @@ void Novfs_clear_inode(struct inode *ino
+       up( &InodeList_lock );
+ 
+ 
+-      Novfs_Free(inode->u.generic_ip);
+-      inode->u.generic_ip = NULL;
++      Novfs_Free(inode->i_private);
++      inode->i_private = NULL;
+ 
+       remove_inode_hash( inode );
+ 
+@@ -3921,12 +3921,12 @@ struct inode *Novfs_get_inode(struct sup
+ 
+       DbgPrint("Novfs_get_inode: Inode=0x%p I_ino=%d len=%d\n", inode, inode->i_ino, name->len);
+ 
+-      if (NULL != (inode->u.generic_ip = Novfs_Malloc(sizeof(INODE_DATA)+name->len, GFP_KERNEL)))
++      if (NULL != (inode->i_private = Novfs_Malloc(sizeof(INODE_DATA)+name->len, GFP_KERNEL)))
+       {
+          PINODE_DATA id;
+-         id = inode->u.generic_ip;
++         id = inode->i_private;
+ 
+-         DbgPrint("Novfs_get_inode: u.generic_ip 0x%p\n", id);
++         DbgPrint("Novfs_get_inode: i_private 0x%p\n", id);
+ 
+          id->Scope = NULL;
+          id->Flags = 0;
+@@ -4343,7 +4343,7 @@ int Novfs_lock_inode_cache( struct inode
+    int retVal = 0;
+ 
+    DbgPrint("Novfs_lock_inode_cache: 0x%p\n", i);
+-   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
++   if ( i && (id = i->i_private) && id->DirCache.next )
+    {
+       down( &id->DirCacheLock );
+       retVal = 1;
+@@ -4369,7 +4369,7 @@ void Novfs_unlock_inode_cache( struct in
+ {
+    PINODE_DATA id;
+ 
+-   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
++   if ( i && (id = i->i_private) && id->DirCache.next )
+    {
+       up( &id->DirCacheLock );
+    }
+@@ -4397,7 +4397,7 @@ int Novfs_enumerate_inode_cache( struct 
+    int retVal = -1;
+ 
+ 
+-   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
++   if ( i && (id = i->i_private) && id->DirCache.next )
+    {
+       if ( (NULL == iteration) || (NULL == *iteration) )
+       {
+@@ -4456,7 +4456,7 @@ int Novfs_get_entry( struct inode *i, st
+    char *n="<NULL>";
+    int nl=6;
+ 
+-   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
++   if ( i && (id = i->i_private) && id->DirCache.next )
+    {
+       if (name && name->len)
+       {
+@@ -4545,7 +4545,7 @@ int Novfs_get_entry_time( struct inode *
+    char *n="<NULL>";
+    int nl=6;
+ 
+-   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
++   if ( i && (id = i->i_private) && id->DirCache.next )
+    {
+       if (name && name->len)
+       {
+@@ -4605,7 +4605,7 @@ int Novfs_get_remove_entry( struct inode
+    int retVal = -1;
+ 
+ 
+-   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
++   if ( i && (id = i->i_private) && id->DirCache.next )
+    {
+       l = id->DirCache.next;
+ 
+@@ -4653,7 +4653,7 @@ void Novfs_invalidate_inode_cache( struc
+    PDIR_CACHE dc;
+    struct list_head *l;
+ 
+-   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
++   if ( i && (id = i->i_private) && id->DirCache.next )
+    {
+       list_for_each(l, &id->DirCache)
+       {
+@@ -4690,7 +4690,7 @@ PDIR_CACHE Novfs_lookup_inode_cache( str
+    int nl=6;
+    int hash=0;
+ 
+-   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
++   if ( i && (id = i->i_private) && id->DirCache.next )
+    {
+       if (name && name->name)
+       {
+@@ -4768,7 +4768,7 @@ int Novfs_lookup_validate( struct inode 
+    char *n="<NULL>";
+    int nl=6;
+ 
+-   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
++   if ( i && (id = i->i_private) && id->DirCache.next )
+    {
+       if (name && name->len)
+       {
+@@ -4815,7 +4815,7 @@ int Novfs_add_inode_entry( 
+    PDIR_CACHE new;
+    int retVal = -ENOMEM;
+ 
+-   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
++   if ( i && (id = i->i_private) && id->DirCache.next )
+    {
+       new = Novfs_Malloc(sizeof(DIR_CACHE)+name->len, GFP_KERNEL);
+       if (new)
+@@ -4888,7 +4888,7 @@ int Novfs_update_entry( struct inode *i,
+    char mtime_buf[32];
+    char ctime_buf[32];
+ 
+-   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
++   if ( i && (id = i->i_private) && id->DirCache.next )
+    {
+ 
+       if (name && name->len)
+@@ -4966,7 +4966,7 @@ void Novfs_remove_inode_entry( struct in
+    char *n="<NULL>";
+    int nl=6;
+ 
+-   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
++   if ( i && (id = i->i_private) && id->DirCache.next )
+    {
+       dc = Novfs_lookup_inode_cache( i, name, ino );
+       if (dc)
+@@ -5015,7 +5015,7 @@ void Novfs_free_invalid_entries( struct 
+    PDIR_CACHE dc;
+    struct list_head *l;
+ 
+-   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
++   if ( i && (id = i->i_private) && id->DirCache.next )
+    {
+       list_for_each( l, &id->DirCache )
+       {
+@@ -5057,7 +5057,7 @@ void Novfs_free_inode_cache( struct inod
+    PDIR_CACHE dc;
+    struct list_head *l;
+ 
+-   if ( i && (id = i->u.generic_ip) && id->DirCache.next )
++   if ( i && (id = i->i_private) && id->DirCache.next )
+    {
+       list_for_each( l, &id->DirCache )
+       {
+@@ -5109,7 +5109,7 @@ Novfs_dump_inode_cache(int argc, const c
+    kdb_printf("Inode: 0x%p\n", inode);
+    if (inode)
+    {
+-      id = inode->u.generic_ip;
++      id = inode->i_private;
+       kdb_printf("INODE_DATA: 0x%p\n", id);
+ 
+       if ( id && id->DirCache.next )
diff --git a/trunk/novell4gentoo/net-fs/novell-novfs/novell-novfs-2.0.0_p2.ebuild b/trunk/novell4gentoo/net-fs/novell-novfs/novell-novfs-2.0.0_p2.ebuild
new file mode 100644
index 00000000..0998ce42
--- /dev/null
+++ b/trunk/novell4gentoo/net-fs/novell-novfs/novell-novfs-2.0.0_p2.ebuild
@@ -0,0 +1,59 @@
+# Copyright 1999-2007 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: $
+
+inherit eutils rpm linux-mod
+
+MY_PV="${PV/_p/-}"
+
+DESCRIPTION="Novell Client for Linux Filesystem"
+HOMEPAGE="http://www.novell.com"
+SRC_URI="http://${NOVELL_ACCOUNT_USERNAME}:${NOVELL_ACCOUNT_PASSWORD}@cdn.novell.com/prot/2JyMn7sWP_Q~/novell-client-1.2-SLE10.tar.gz"
+
+LICENSE="GPL-2"
+SLOT="0"
+KEYWORDS="~x86 ~amd64"
+IUSE=""
+
+DEPEND=""
+
+RDEPEND="virtual/linux-sources
+	!net-misc/novell-novfs"
+
+RESTRICT="nomirror"
+
+BUILD_PARAMS="-C $KERNEL_DIR SUBDIRS=${WORKDIR}/${PN}-${MY_PV}/opt/novell/ncl/src/src"
+MODULE_NAMES="novfs(novfs:${WORKDIR}/${PN}-${MY_PV}/opt/novell/ncl/src/src:${WORKDIR}/${PN}-${MY_PV}/opt/novell/ncl/src/src"
+BUILD_TARGETS="modules"
+MODULESD_NOVFS_ENABLED=""
+
+src_unpack() {
+	unpack ${A}
+	mkdir -p ${WORKDIR}/${PN}-${MY_PV}
+	cd ${PN}-${MY_PV}
+	rpm_unpack ${WORKDIR}/ncl_build_711/NCL_disk/novell/i586/${PN}-1.2.0-17.i586.rpm
+	cd ${WORKDIR}/${PN}-${MY_PV}/opt/novell/ncl/src
+	epatch ${FILESDIR}/novell-novfs-1.2.0_to_2.0.0.patch
+	epatch ${FILESDIR}/novell-novfs-2.0.0-config_h.patch
+	epatch ${FILESDIR}/novell-novfs-2.0.0-generic_file_read.patch
+	epatch ${FILESDIR}/novell-novfs-2.0.0-i_blksize.patch
+	epatch ${FILESDIR}/novell-novfs-2.0.0-u.generic_ip.patch
+	epatch ${FILESDIR}/novell-novfs-2.0.0-dont_use_tasklist_lock.patch
+}
+
+src_compile() { 
+	linux-mod_src_compile
+}
+
+src_install() {
+	linux-mod_src_install
+	generate_modulesd	
+}
+
+pkg_postinst() {
+	linux-mod_pkg_postinst
+}
+
+pkg_postrm() {
+	linux-mod_pkg_postrm
+}