From 9297af3ffd8a1c98f35fb7a273386576e061ff16 Mon Sep 17 00:00:00 2001
From: Greg Kroah-Hartman <gregkh@suse.de>
Date: Thu, 27 Mar 2008 10:40:48 -0700
Subject: novfs: Add the Novell filesystem client kernel module
Patch-mainline: not yet, being worked on.

This adds the Novell filesystem client kernel module.

Things to do before it can be submitted:
	- coding style cleanups
		- remove typedefs
		- function name lowercase
		- 80 chars wide
	- sparse cleanups
		- __user markings
		- endian markings
	- remove functions that are never called and structures never used
		- yeah, there are a lot of them...
	- remove wrapper functions
		- private kmalloc/free?
	- resolve FIXME markings that have been added to the code
		- wrong types passed to functions!!!
	- userspace interface revisit
		- uses /proc/novfs, not nice.
		- might need userspace tools rework
	- use of semaphore as mutex
	- abuse of semaphore in lieu of completions.

Update May 13 2009 jeffm:
- Merged patches back into master novfs patch

Cc: Lonnie Iverson <ldiverson@novell.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

---
 fs/Kconfig          |    1 
 fs/Makefile         |    1 
 fs/novfs/Kconfig    |    8 
 fs/novfs/Makefile   |   19 
 fs/novfs/commands.h |  955 ++++++++++
 fs/novfs/daemon.c   | 2085 +++++++++++++++++++++++
 fs/novfs/file.c     | 1921 +++++++++++++++++++++
 fs/novfs/inode.c    | 4638 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/novfs/nwcapi.c   | 2202 ++++++++++++++++++++++++
 fs/novfs/nwcapi.h   | 1416 +++++++++++++++
 fs/novfs/nwerror.h  |  658 +++++++
 fs/novfs/proc.c     |  149 +
 fs/novfs/profile.c  |  704 +++++++
 fs/novfs/scope.c    |  659 +++++++
 fs/novfs/vfs.h      |  454 +++++
 15 files changed, 15870 insertions(+)

--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -241,6 +241,7 @@ source "fs/ncpfs/Kconfig"
 source "fs/coda/Kconfig"
 source "fs/afs/Kconfig"
 source "fs/9p/Kconfig"
+source "fs/novfs/Kconfig"
 
 endif # NETWORK_FILESYSTEMS
 
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -125,4 +125,5 @@ obj-$(CONFIG_OCFS2_FS)		+= ocfs2/
 obj-$(CONFIG_BTRFS_FS)		+= btrfs/
 obj-$(CONFIG_GFS2_FS)           += gfs2/
 obj-$(CONFIG_EXOFS_FS)          += exofs/
+obj-$(CONFIG_NOVFS)		+= novfs/
 obj-$(CONFIG_CEPH_FS)		+= ceph/
--- /dev/null
+++ b/fs/novfs/Kconfig
@@ -0,0 +1,8 @@
+config NOVFS
+	tristate "Novell Netware Filesystem support (novfs) (EXPERIMENTAL)"
+	depends on INET && EXPERIMENTAL
+	help
+	  If you say Y here, you will get an experimental Novell Netware
+	  filesystem driver.
+
+	  If unsure, say N.
--- /dev/null
+++ b/fs/novfs/Makefile
@@ -0,0 +1,19 @@
+#
+# Makefile for the Novell NetWare Client for Linux filesystem.
+#
+
+NOVFS_VFS_MAJOR = 2
+NOVFS_VFS_MINOR = 0
+NOVFS_VFS_SUB = 0
+NOVFS_VFS_RELEASE = 440
+
+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-$(CONFIG_NOVFS) += novfs.o
+
+novfs-objs := inode.o proc.o profile.o daemon.o file.o scope.o nwcapi.o
+
--- /dev/null
+++ b/fs/novfs/commands.h
@@ -0,0 +1,955 @@
+/*
+ * NetWare Redirector for Linux
+ * Author: James Turner/Richard Williams
+ *
+ * This file contains all defined commands.
+ *
+ * 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.
+ */
+
+#ifndef __NOVFS_COMMANDS_H
+#define __NOVFS_COMMANDS_H
+
+#define VFS_COMMAND_GET_CONNECTED_SERVER_LIST   0
+#define VFS_COMMAND_GET_SERVER_VOLUME_LIST      1
+#define VFS_COMMAND_VERIFY_FILE                 2
+#define VFS_COMMAND_OPEN_CONNECTION_BY_ADDR     3
+#define VFS_COMMAND_LOGIN_IDENTITY              4
+#define VFS_COMMAND_ENUMERATE_DIRECTORY         5
+#define VFS_COMMAND_OPEN_FILE                   6
+#define VFS_COMMAND_CREATE_FILE                 7
+#define VFS_COMMAND_CLOSE_FILE                  8
+#define VFS_COMMAND_READ_FILE                   9
+#define VFS_COMMAND_WRITE_FILE                  10
+#define VFS_COMMAND_DELETE_FILE                 11
+#define VFS_COMMAND_CREATE_DIRECOTRY            12
+#define VFS_COMMAND_START_ENUMERATE             13
+#define VFS_COMMAND_END_ENUMERATE               14
+#define VFS_COMMAND_LOGIN_USER                  15
+#define VFS_COMMAND_LOGOUT_USER                 16
+#define VFS_COMMAND_CREATE_CONTEXT              17
+#define VFS_COMMAND_DESTROY_CONTEXT             18
+#define VFS_COMMAND_SET_FILE_INFO               19
+#define VFS_COMMAND_TRUNCATE_FILE               20
+#define VFS_COMMAND_OPEN_CONNECTION_BY_NAME     21
+#define VFS_COMMAND_XPLAT_CALL                  22
+#define VFS_COMMAND_RENAME_FILE                 23
+#define VFS_COMMAND_ENUMERATE_DIRECTORY_EX      24
+#define VFS_COMMAND_GETPWUD                     25
+#define VFS_COMMAND_ENUM_XCONN                  26
+#define VFS_COMMAND_READ_STREAM                 27
+#define VFS_COMMAND_WRITE_STREAM                28
+#define VFS_COMMAND_CLOSE_STREAM                29
+#define VFS_COMMAND_GET_VERSION                 30
+#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 VFS_COMMAND_GET_EXTENDED_ATTRIBUTE		35
+#define VFS_COMMAND_LIST_EXTENDED_ATTRIBUTES	36
+#define VFS_COMMAND_SET_EXTENDED_ATTRIBUTE		37
+#define VFS_COMMAND_SET_FILE_LOCK				38
+
+#define  NWD_ACCESS_QUERY                        0x00000001
+#define  NWD_ACCESS_READ                         0x00000002
+#define  NWD_ACCESS_WRITE                        0x00000004
+#define  NWD_ACCESS_EXECUTE                      0x00000008
+#define  NWD_ACCESS_VALID                        0x0000000F
+
+/*
+   Share Mode
+
+   A value of zero in a shared mode field specifies the caller
+   desires exclusive access to the object.
+*/
+
+#define  NWD_SHARE_READ                          0x00000001
+#define  NWD_SHARE_WRITE                         0x00000002
+#define  NWD_SHARE_DELETE                        0x00000004
+#define  NWD_SHARE_VALID                         0x00000007
+
+/*
+   Creates a new file.  The create API will fail if the specified
+   file already exists.
+*/
+#define  NWD_DISP_CREATE_NEW                     0x00000001
+
+/*
+   Creates a new file.  If the specified file already exists,
+   the create API will overwrite the old file and clear the
+   existing attributes.
+*/
+#define  NWD_DISP_CREATE_ALWAYS                  0x00000002
+
+/*
+   Opens the file.  The API will fail if the file does not exist.
+*/
+#define  NWD_DISP_OPEN_EXISTING                  0x00000003
+
+/*
+   Opens the file.  If the file does not exist, the API will
+   create the file.
+*/
+#define  NWD_DISP_OPEN_ALWAYS                    0x00000004
+
+/*
+   Opens the file.  When the file is opened the API will truncate
+   the stream to zero bytes.  The API will fail if the file
+   does not exist.
+*/
+#define  NWD_DISP_TRUNCATE_EXISTING              0x00000005
+#define  NWD_DISP_MAXIMUM                        0x00000005
+
+/*
+   Open/Create returned information values
+
+   The bottom two bytes of NWD_ACTION are returned
+   as a value.  All values are mutually exclusive.
+*/
+
+#define  NWD_ACTION_OPENED                       0x00000001
+#define  NWD_ACTION_CREATED                      0x00000002
+
+#define  MAX_IO_SIZE							(1024 * 32)
+
+#define  MAX_XATTR_NAME_LEN			255
+#define	 MAX_PATH_LENGTH			255
+#define  ENOATTR				ENODATA
+/*===[ Type definitions ]=================================================*/
+
+/*===[ Function prototypes ]==============================================*/
+
+#pragma pack(push, 1)
+
+/*struct _ncl_string
+{
+	unsigned int  	type;
+	unsigned char 	*buffer;
+	unsigned int	len;
+
+} NclString, *PNclString;
+*/
+struct ncl_string {
+	unsigned int type;
+	unsigned char *buffer;
+	u32 len;
+};
+
+struct nwd_string {
+	unsigned int type;
+	unsigned int len;
+	unsigned int boffset;
+};
+
+struct novfs_command_request_header {
+	unsigned int CommandType;
+	unsigned long SequenceNumber;
+	struct novfs_schandle SessionId;
+
+};
+
+struct novfs_command_reply_header {
+	unsigned long Sequence_Number;
+	unsigned int ErrorCode;
+
+};
+
+
+struct novfs_delete_file_request {
+	struct novfs_command_request_header Command;
+	unsigned int isDirectory;
+	unsigned int pathlength;
+	unsigned char path[1];
+};
+
+struct novfs_delete_file_reply {
+	struct novfs_command_reply_header Reply;
+};
+
+struct novfs_get_connected_server_list {
+	struct novfs_command_request_header Command;
+};
+
+struct novfs_get_connected_server_list_reply {
+	struct novfs_command_reply_header Reply;
+	unsigned char List[1];
+};
+
+struct novfs_get_connected_server_list_request_ex {
+	struct novfs_command_request_header Command;
+};
+
+struct novfs_get_connected_server_list_reply_ex {
+
+	struct novfs_command_reply_header Reply;
+	unsigned int bufferLen;
+	unsigned char List[1];
+
+};
+
+struct novfs_get_server_volume_list {
+	struct novfs_command_request_header Command;
+	unsigned int Length;
+	unsigned char Name[1];
+};
+
+struct novfs_get_server_volume_list_reply {
+	struct novfs_command_reply_header Reply;
+	unsigned char List[1];
+};
+
+struct novfs_verify_file_request {
+	struct novfs_command_request_header Command;
+	unsigned int pathLen;
+	unsigned char path[1];
+
+};
+
+struct novfs_verify_file_reply {
+	struct novfs_command_reply_header Reply;
+	unsigned int lastAccessTime;
+	unsigned int modifyTime;
+	unsigned int createTime;
+	unsigned long long fileSize;
+	unsigned int fileMode;
+
+};
+
+struct novfs_begin_enumerate_directory_request {
+	struct novfs_command_request_header Command;
+	unsigned int pathLen;
+	unsigned char path[1];
+
+};
+
+struct novfs_begin_enumerate_directory_reply {
+	struct novfs_command_reply_header Reply;
+	void *enumerateHandle;
+
+};
+
+struct novfs_end_enumerate_directory_request {
+	struct novfs_command_request_header Command;
+	void *enumerateHandle;
+
+};
+
+struct novfs_end_enumerate_directory_reply {
+	struct novfs_command_reply_header Reply;
+
+};
+
+struct novfs_enumerate_directory_request {
+	struct novfs_command_request_header Command;
+	void *enumerateHandle;
+	unsigned int pathLen;
+	unsigned char path[1];
+
+};
+
+struct novfs_enumerate_directory_reply {
+	struct novfs_command_reply_header Reply;
+	void *enumerateHandle;
+	unsigned int lastAccessTime;
+	unsigned int modifyTime;
+	unsigned int createTime;
+	unsigned long long size;
+	unsigned int mode;
+	unsigned int nameLen;
+	unsigned char name[1];
+
+};
+
+struct novfs_enumerate_directory_ex_request {
+	struct novfs_command_request_header Command;
+	void *enumerateHandle;
+	unsigned int pathLen;
+	unsigned char path[1];
+
+};
+
+struct novfs_enumerate_directory_ex_data {
+	unsigned int length;
+	unsigned int lastAccessTime;
+	unsigned int modifyTime;
+	unsigned int createTime;
+	unsigned long long size;
+	unsigned int mode;
+	unsigned int nameLen;
+	unsigned char name[1];
+
+};
+
+struct novfs_enumerate_directory_ex_reply {
+	struct novfs_command_reply_header Reply;
+	void *enumerateHandle;
+	unsigned int enumCount;
+
+};
+
+struct novfs_open_file_request {
+	struct novfs_command_request_header Command;
+	unsigned int access;	/* File Access */
+	unsigned int mode;	/* Sharing Mode */
+	unsigned int disp;	/* Create Disposition */
+	unsigned int pathLen;
+	unsigned char path[1];
+
+};
+
+struct novfs_open_file_reply {
+	struct novfs_command_reply_header Reply;
+	void *handle;
+	unsigned int lastAccessTime;
+	unsigned int modifyTime;
+	unsigned int createTime;
+	unsigned int attributes;
+	loff_t size;
+
+};
+
+struct novfs_create_file_request {
+
+	struct novfs_command_request_header Command;
+	unsigned int pathlength;
+	unsigned char path[1];
+
+};
+
+struct novfs_create_file_reply {
+	struct novfs_command_reply_header Reply;
+
+};
+
+struct novfs_close_file_request {
+	struct novfs_command_request_header Command;
+	void *handle;
+
+};
+
+struct novfs_close_file_reply {
+	struct novfs_command_reply_header Reply;
+
+};
+
+struct novfs_read_file_request {
+	struct novfs_command_request_header Command;
+	void *handle;
+	loff_t offset;
+	size_t len;
+
+};
+
+struct novfs_read_file_reply {
+	struct novfs_command_reply_header Reply;
+	unsigned long long bytesRead;
+	unsigned char data[1];
+
+};
+
+struct novfs_write_file_request {
+	struct novfs_command_request_header Command;
+	void *handle;
+	loff_t offset;
+	size_t len;
+	unsigned char data[1];
+
+};
+
+struct novfs_write_file_reply {
+	struct novfs_command_reply_header Reply;
+	unsigned long long bytesWritten;
+};
+
+struct novfs_read_stream_request {
+	struct novfs_command_request_header Command;
+	void *connection;
+	unsigned char handle[6];
+	loff_t offset;
+	size_t len;
+};
+
+struct novfs_read_stream_reply {
+	struct novfs_command_reply_header Reply;
+	size_t bytesRead;
+	unsigned char data[1];
+};
+
+struct novfs_write_stream_request {
+	struct novfs_command_request_header Command;
+	void *connection;
+	unsigned char handle[6];
+	loff_t offset;
+	size_t len;
+	unsigned char data[1];
+};
+
+struct novfs_write_stream_reply {
+	struct novfs_command_reply_header Reply;
+	size_t bytesWritten;
+};
+
+struct novfs_close_stream_request {
+	struct novfs_command_request_header Command;
+	void *connection;
+	unsigned char handle[6];
+};
+
+struct novfs_close_stream_reply {
+	struct novfs_command_reply_header Reply;
+
+};
+
+struct novfs_login_user_request {
+	struct novfs_command_request_header Command;
+	unsigned int srvNameType;
+	unsigned int serverLength;
+	unsigned int serverOffset;
+	unsigned int usrNameType;
+	unsigned int userNameLength;
+	unsigned int userNameOffset;
+	unsigned int pwdNameType;
+	unsigned int passwordLength;
+	unsigned int passwordOffset;
+
+};
+
+struct novfs_login_user_reply {
+	struct novfs_command_reply_header Reply;
+	unsigned int connectionHandle;
+	void *loginIdentity;
+
+};
+
+struct novfs_logout_request {
+	struct novfs_command_request_header Command;
+	unsigned int length;
+	unsigned char Name[1];
+
+};
+
+struct novfs_logout_reply {
+	struct novfs_command_reply_header Reply;
+
+};
+
+struct novfs_create_context_request {
+	struct novfs_command_request_header Command;
+
+};
+
+struct novfs_create_context_reply {
+	struct novfs_command_reply_header Reply;
+	struct novfs_schandle SessionId;
+
+};
+
+struct novfs_destroy_context_request {
+	struct novfs_command_request_header Command;
+
+};
+
+struct novfs_destroy_context_reply {
+	struct novfs_command_reply_header Reply;
+
+};
+
+/*
+ * Attribute flags.  These should be or-ed together to figure out what
+ * has been changed!
+ */
+#ifndef ATTR_MODE
+#define ATTR_MODE	1
+#define ATTR_UID	2
+#define ATTR_GID	4
+#define ATTR_SIZE	8
+#define ATTR_ATIME	16
+#define ATTR_MTIME	32
+#define ATTR_CTIME	64
+#define ATTR_ATIME_SET	128
+#define ATTR_MTIME_SET	256
+#define ATTR_FORCE	512	/* Not a change, but a change it */
+#define ATTR_ATTR_FLAG	1024
+#endif
+
+struct novfs_lnx_file_info {
+	unsigned int ia_valid;
+	unsigned int ia_mode;
+	uid_t ia_uid;
+	gid_t ia_gid;
+	loff_t ia_size;
+	time_t ia_atime;
+	time_t ia_mtime;
+	time_t ia_ctime;
+	unsigned int ia_attr_flags;
+};
+
+struct novfs_set_file_info_request {
+	struct novfs_command_request_header Command;
+	struct novfs_lnx_file_info fileInfo;
+	unsigned int pathlength;
+	char path[1];
+};
+
+struct novfs_set_file_info_reply {
+	struct novfs_command_reply_header Reply;
+
+};
+
+struct novfs_truncate_file_request {
+	struct novfs_command_request_header Command;
+	unsigned int pathLen;
+	char path[1];
+
+};
+
+struct novfs_truncate_file_reply {
+	struct novfs_command_reply_header Reply;
+
+};
+
+struct novfs_getpwuid_request {
+	struct novfs_command_request_header Command;
+	unsigned int uid;
+};
+
+struct novfs_getpwuid_reply {
+	struct novfs_command_reply_header Reply;
+	unsigned char UserName[1];
+};
+
+struct novfs_get_version_request {
+	struct novfs_command_request_header Command;
+};
+
+struct novfs_get_version_reply {
+	struct novfs_command_reply_header Reply;
+	unsigned char Version[1];
+};
+
+struct novfs_set_mount_path {
+	struct novfs_command_request_header Command;
+	unsigned int PathLength;
+	unsigned char Path[1];
+};
+
+struct novfs_set_mount_path_reply {
+	struct novfs_command_reply_header Reply;
+};
+
+struct novfs_get_user_space {
+	struct novfs_command_request_header Command;
+};
+
+struct novfs_get_user_space_reply {
+	struct novfs_command_reply_header Reply;
+	uint64_t TotalSpace;
+	uint64_t FreeSpace;
+	uint64_t TotalEnties;
+	uint64_t FreeEnties;
+};
+
+struct novfs_xplat_call_request {
+	struct novfs_command_request_header Command;
+	unsigned int NwcCommand;
+	unsigned long dataLen;
+	unsigned char data[1];
+
+};
+
+struct novfs_xplat_call_reply {
+	struct novfs_command_reply_header Reply;
+	unsigned long dataLen;
+	unsigned char data[1];
+
+};
+
+/* XPlat NWC structures used by the daemon */
+
+struct nwd_open_conn_by_name {
+	void *ConnHandle;
+	unsigned int nameLen;
+	unsigned int oName;	/* Ofset to the Name */
+	unsigned int serviceLen;
+	unsigned int oServiceType;	/* Offset to service Type; */
+	unsigned int uConnFlags;
+	unsigned int uTranType;
+	void *newConnHandle;
+
+};
+
+struct nwd_tran_addr {
+	unsigned int uTransportType;
+	unsigned int uAddressLength;
+	unsigned int oAddress;
+
+};
+
+struct nwd_open_conn_by_addr {
+	void *ConnHandle;
+	unsigned int oServiceType;
+	unsigned int uConnFlags;
+	struct nwd_tran_addr TranAddr;
+
+};
+
+struct nwd_close_conn {
+	void *ConnHandle;
+
+};
+
+struct nwd_ncp_req {
+	void *ConnHandle;
+	unsigned int replyLen;
+	unsigned int requestLen;
+	unsigned int function;
+/*	unsigned int 	subFunction; */
+/*	unsigned int 	verb; */
+	unsigned int flags;
+	unsigned char data[1];
+
+};
+
+struct nwd_ncp_rep {
+	unsigned int replyLen;
+	unsigned char data[1];
+
+};
+
+struct nwc_auth_wid {
+	void *ConnHandle;
+	u32 AuthenticationId;
+
+};
+
+struct nwc_unauthenticate {
+	void *ConnHandle;
+	unsigned int AuthenticationId;
+
+};
+
+struct nwc_lisc_id {
+	void *ConnHandle;
+
+};
+
+struct nwc_unlic_conn {
+	void *ConnHandle;
+
+};
+
+struct nwd_get_id_info {
+	u32 AuthenticationId;
+	unsigned int AuthType;
+	unsigned int NameType;
+	unsigned short int ObjectType;
+	unsigned int IdentityFlags;
+	unsigned int domainLen;
+	unsigned int pDomainNameOffset;
+	unsigned int objectLen;
+	unsigned int pObjectNameOffset;
+
+};
+
+struct nwc_lo_id {
+	u32 AuthenticationId;
+
+};
+
+struct novfs_rename_file_request {
+	struct novfs_command_request_header Command;
+	int directoryFlag;
+	unsigned int newnameLen;
+	unsigned char newname[256];
+	unsigned int oldnameLen;
+	unsigned char oldname[256];
+};
+
+struct novfs_rename_file_reply {
+	struct novfs_command_reply_header Reply;
+
+};
+
+struct nwd_server_version {
+	unsigned int uMajorVersion;
+	unsigned short int uMinorVersion;
+	unsigned short int uRevision;
+};
+
+
+#define	MAX_ADDRESS_LENGTH	32
+
+struct tagNwdTranAddrEx {
+	unsigned int uTransportType;
+	unsigned int uAddressLength;
+	unsigned char Buffer[MAX_ADDRESS_LENGTH];
+
+};
+
+struct __NWD_CONN_INFO {
+	unsigned int uInfoVersion;
+	unsigned int uAuthenticationState;
+	unsigned int uBroadcastState;
+	u32 uConnectionReference;
+	unsigned int pTreeNameOffset;
+/*	unsigned int		pWorkGroupIdOffset;  Not used */
+	unsigned int uSecurityState;
+	unsigned int uConnectionNumber;
+	unsigned int uUserId;
+	unsigned int pServerNameOffset;
+	unsigned int uNdsState;
+	unsigned int uMaxPacketSize;
+	unsigned int uLicenseState;
+	unsigned int uPublicState;
+	unsigned int bcastState;
+	unsigned int pServiceTypeOffset;
+	unsigned int uDistance;
+	u32 uAuthId;
+	unsigned int uDisconnected;
+	struct nwd_server_version ServerVersion;
+	struct nwd_tran_addr TranAddress;
+};
+
+struct nwd_conn_info {
+	void *ConnHandle;
+	unsigned int uInfoLevel;
+	unsigned int uInfoLength;
+};
+
+struct nwd_open_conn_by_ref {
+	void *uConnReference;
+	unsigned int uConnFlags;
+	void *ConnHandle;
+
+};
+
+struct nwd_get_reqversion {
+	unsigned int uMajorVersion;
+	unsigned int uMinorVersion;
+	unsigned int uRevision;
+
+};
+
+struct nwd_scan_conn_info {
+	unsigned int uScanIndex;
+	unsigned int uScanInfoLevel;
+	unsigned int uScanInfoLen;
+	unsigned int uScanConnInfoOffset;
+	unsigned int uScanFlags;
+	unsigned int uReturnInfoLevel;
+	unsigned int uReturnInfoLength;
+	unsigned int uConnectionReference;
+	unsigned int uReturnConnInfoOffset;
+
+};
+
+struct nwd_get_pref_ds_tree {
+	unsigned int uTreeLength;
+	unsigned int DsTreeNameOffset;
+
+};
+
+struct nwd_set_pref_ds_tree {
+	unsigned int uTreeLength;
+	unsigned int DsTreeNameOffset;
+
+};
+
+struct nwd_set_def_name_ctx {
+	unsigned int uTreeLength;
+	unsigned int TreeOffset;
+	unsigned int uNameLength;
+	unsigned int NameContextOffset;
+
+};
+
+struct nwd_get_def_name_ctx {
+	unsigned int uTreeLength;
+	unsigned int TreeOffset;
+	unsigned int uNameLength;
+	unsigned int NameContextOffset;
+
+};
+
+struct nwd_get_tree_monitored_conn_ref {
+	struct nwd_string TreeName;
+	void *uConnReference;
+
+};
+
+struct nwd_enum_ids {
+	unsigned int Iterator;
+	unsigned int domainNameLen;
+	unsigned int domainNameOffset;
+	unsigned int AuthType;
+	unsigned int objectNameLen;
+	unsigned int objectNameOffset;
+	unsigned int NameType;
+	unsigned short int ObjectType;
+	unsigned int IdentityFlags;
+	u32 AuthenticationId;
+
+};
+
+struct nwd_change_key {
+	unsigned int domainNameOffset;
+	unsigned int domainNameLen;
+	unsigned int AuthType;
+	unsigned int objectNameOffset;
+	unsigned int objectNameLen;
+	unsigned int NameType;
+	unsigned short int ObjectType;
+	unsigned int verifyPasswordOffset;
+	unsigned int verifyPasswordLen;
+	unsigned int newPasswordOffset;
+	unsigned int newPasswordLen;
+
+};
+
+struct nwd_set_primary_conn {
+	void *ConnHandle;
+
+};
+
+struct nwd_get_bcast_notification {
+	unsigned int uMessageFlags;
+	void *uConnReference;
+	unsigned int messageLen;
+	char message[1];
+
+};
+
+struct nwd_set_conn_info {
+	void *ConnHandle;
+	unsigned int uInfoLevel;
+	unsigned int uInfoLength;
+	unsigned int offsetConnInfo;
+
+};
+
+struct novfs_debug_request {
+	struct novfs_command_request_header Command;
+	int cmdlen;
+	char dbgcmd[1];
+
+};
+
+struct novfs_debug_reply {
+	struct novfs_command_reply_header Reply;
+
+};
+
+struct nwd_set_key {
+	void *ConnHandle;
+	unsigned int AuthenticationId;
+	unsigned int objectNameLen;
+	unsigned int objectNameOffset;
+	unsigned short int ObjectType;
+	unsigned int newPasswordLen;
+	unsigned int newPasswordOffset;
+
+};
+
+struct nwd_verify_key {
+	unsigned int AuthType;
+	unsigned int NameType;
+	unsigned short int ObjectType;
+	unsigned int domainNameLen;
+	unsigned int domainNameOffset;
+	unsigned int objectNameLen;
+	unsigned int objectNameOffset;
+	unsigned int verifyPasswordLen;
+	unsigned int verifyPasswordOffset;
+
+};
+
+struct novfs_get_cache_flag {
+	struct novfs_command_request_header Command;
+	int pathLen;
+	unsigned char path[0];
+
+};
+
+struct novfs_get_cache_flag_reply {
+	struct novfs_command_reply_header Reply;
+	int CacheFlag;
+
+};
+
+struct novfs_xa_list_reply {
+	struct novfs_command_reply_header Reply;
+	unsigned char *pData;
+
+};
+
+struct novfs_xa_get_request {
+	struct novfs_command_request_header Command;
+	unsigned int pathLen;
+	unsigned int nameLen;
+	unsigned char data[1];	//hold path, attribute name
+
+};
+
+struct novfs_xa_get_reply {
+	struct novfs_command_reply_header Reply;
+	unsigned char *pData;
+
+};
+
+struct novfs_xa_set_request {
+	struct novfs_command_request_header Command;
+	unsigned int TtlWriteDataSize;
+	unsigned int WritePosition;
+	int flags;
+	unsigned int pathLen;
+	unsigned int nameLen;
+	unsigned int valueLen;
+	unsigned char data[1];	//hold path, attribute name, value data
+
+};
+
+struct novfs_xa_set_reply {
+	struct novfs_command_reply_header Reply;
+	unsigned char *pData;
+
+};
+
+struct novfs_set_file_lock_request {
+	struct novfs_command_request_header Command;
+	void *handle;
+	unsigned char fl_type;
+	loff_t fl_start;
+	loff_t fl_len;
+
+};
+
+struct novfs_set_file_lock_reply {
+	struct novfs_command_reply_header Reply;
+
+};
+
+
+struct novfs_scope_list{
+	struct list_head ScopeList;
+	struct novfs_schandle ScopeId;
+	struct novfs_schandle SessionId;
+	pid_t ScopePid;
+	struct task_struct *ScopeTask;
+	unsigned int ScopeHash;
+	uid_t ScopeUid;
+	uint64_t ScopeUSize;
+	uint64_t ScopeUFree;
+	uint64_t ScopeUTEnties;
+	uint64_t ScopeUAEnties;
+	int ScopeUserNameLength;
+	unsigned char ScopeUserName[32];
+};
+
+#pragma pack(pop)
+
+#endif	/* __NOVFS_COMMANDS_H */
--- /dev/null
+++ b/fs/novfs/daemon.c
@@ -0,0 +1,2085 @@
+/*
+ * Novell NCP Redirector for Linux
+ * Author: James Turner
+ *
+ * This file contains all the functions necessary for sending commands to our
+ * daemon module.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/mount.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 <linux/semaphore.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/time.h>
+
+#include "vfs.h"
+#include "nwcapi.h"
+#include "commands.h"
+#include "nwerror.h"
+
+#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
+
+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 */
+};
+
+struct daemon_cmd {
+	struct list_head list;	/* Must be first entry */
+	atomic_t reference;
+	unsigned int status;
+	unsigned int flags;
+	struct semaphore semaphore;
+	unsigned long sequence;
+	struct timer_list timer;
+	void *request;
+	unsigned long reqlen;
+	void *data;
+	int datalen;
+	void *reply;
+	unsigned long replen;
+};
+
+struct daemon_handle {
+	struct list_head list;
+	rwlock_t lock;
+	struct novfs_schandle session;
+};
+
+struct daemon_resource {
+	struct list_head list;
+	int type;
+	void *connection;
+	unsigned char handle[6];
+	mode_t mode;
+	loff_t size;
+};
+
+struct drive_map {
+	struct list_head list;	/* Must be first item */
+	struct novfs_schandle session;
+	unsigned long hash;
+	int namelen;
+	char name[1];
+};
+
+static void Queue_get(struct daemon_cmd * Que);
+static void Queue_put(struct daemon_cmd * Que);
+static void RemoveDriveMaps(void);
+static int NwdConvertLocalHandle(struct novfs_xplat *pdata, struct daemon_handle * DHandle);
+static int NwdConvertNetwareHandle(struct novfs_xplat *pdata, struct daemon_handle * DHandle);
+static int set_map_drive(struct novfs_xplat *pdata, struct novfs_schandle Session);
+static int unmap_drive(struct novfs_xplat *pdata, struct novfs_schandle Session);
+static int NwdGetMountPath(struct novfs_xplat *pdata);
+static long local_unlink(const char *pathname);
+
+
+/*===[ Global variables ]=================================================*/
+static struct daemon_queue Daemon_Queue;
+
+static DECLARE_WAIT_QUEUE_HEAD(Read_waitqueue);
+
+static atomic_t Sequence = ATOMIC_INIT(-1);
+static atomic_t Daemon_Open_Count = ATOMIC_INIT(0);
+
+static unsigned long Daemon_Command_Timeout = TIMEOUT_VALUE;
+
+static DECLARE_MUTEX(DriveMapLock);
+static LIST_HEAD(DriveMapList);
+
+int novfs_max_iosize = PAGE_SIZE;
+
+void novfs_daemon_queue_init()
+{
+	INIT_LIST_HEAD(&Daemon_Queue.list);
+	spin_lock_init(&Daemon_Queue.lock);
+	init_MUTEX_LOCKED(&Daemon_Queue.semaphore);
+}
+
+void novfs_daemon_queue_exit(void)
+{
+	/* Does nothing for now but we maybe should clear the queue. */
+}
+
+/*++======================================================================*/
+static void novfs_daemon_timer(unsigned long data)
+{
+	struct daemon_cmd *que = (struct daemon_cmd *) data;
+
+	if (QUEUE_ACKED != que->status) {
+		que->status = QUEUE_TIMEOUT;
+	}
+	up(&que->semaphore);
+}
+
+/*++======================================================================*/
+int Queue_Daemon_Command(void *request,
+			 unsigned long reqlen,
+			 void *data,
+			 int dlen,
+			 void **reply, unsigned long * replen, int interruptible)
+{
+	struct daemon_cmd *que;
+	int retCode = 0;
+	uint64_t ts1, ts2;
+
+	ts1 = get_nanosecond_time();
+
+	DbgPrint("0x%p %d", request, reqlen);
+
+	if (atomic_read(&Daemon_Open_Count)) {
+
+		que = kmalloc(sizeof(*que), GFP_KERNEL);
+
+		DbgPrint("que=0x%p", que);
+		if (que) {
+			atomic_set(&que->reference, 0);
+			que->status = QUEUE_SENDING;
+			que->flags = 0;
+
+			init_MUTEX_LOCKED(&que->semaphore);
+
+			que->sequence = atomic_inc_return(&Sequence);
+
+			((struct novfs_command_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 = (unsigned long) que;
+			que->timer.function = novfs_daemon_timer;
+			add_timer(&que->timer);
+
+			/*
+			 * Setup request
+			 */
+			que->request = request;
+			que->reqlen = reqlen;
+			que->data = data;
+			que->datalen = dlen;
+			que->reply = NULL;
+			que->replen = 0;
+
+			/*
+			 * Added entry to queue.
+			 */
+			/*
+			 * 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);
+
+			/*
+			 * Signal that there is data to be read
+			 */
+			up(&Daemon_Queue.semaphore);
+
+			/*
+			 * Give a change to the other processes.
+			 */
+			yield();
+
+			/*
+			 * Block waiting for reply or timeout
+			 */
+			down(&que->semaphore);
+
+			if (QUEUE_ACKED == que->status) {
+				que->status = QUEUE_WAITING;
+				mod_timer(&que->timer,
+					  jiffies +
+					  (HZ * 2 * Daemon_Command_Timeout));
+				if (interruptible) {
+					retCode =
+					    down_interruptible(&que->semaphore);
+				} else {
+					down(&que->semaphore);
+				}
+			}
+
+			/*
+			 * Delete timer
+			 */
+			del_timer(&que->timer);
+
+			/*
+			 * Check for timeout
+			 */
+			if ((QUEUE_TIMEOUT == que->status)
+			    && (NULL == que->reply)) {
+				DbgPrint("Timeout");
+				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("%llu retCode=%d", ts2, retCode);
+	return (retCode);
+}
+
+static void Queue_get(struct daemon_cmd * Que)
+{
+	DbgPrint("que=0x%p %d", Que, atomic_read(&Que->reference));
+	atomic_inc(&Que->reference);
+}
+
+static void Queue_put(struct daemon_cmd * Que)
+{
+
+	DbgPrint("que=0x%p %d", 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
+		 */
+		kfree(Que);
+	} else {
+		spin_unlock(&Daemon_Queue.lock);
+	}
+}
+
+struct daemon_cmd *get_next_queue(int Set_Queue_Waiting)
+{
+	struct daemon_cmd *que;
+
+	DbgPrint("que=0x%p", Daemon_Queue.list.next);
+
+	spin_lock(&Daemon_Queue.lock);
+	que = (struct daemon_cmd *) Daemon_Queue.list.next;
+
+	while (que && (que != (struct daemon_cmd *) & Daemon_Queue.list.next)
+	       && (que->status != QUEUE_SENDING)) {
+		que = (struct daemon_cmd *) que->list.next;
+	}
+
+	if ((NULL == que) || (que == (struct daemon_cmd *) & 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("return=0x%p", que);
+	return (que);
+}
+
+static struct daemon_cmd *find_queue(unsigned long sequence)
+{
+	struct daemon_cmd *que;
+
+	DbgPrint("0x%x", sequence);
+
+	spin_lock(&Daemon_Queue.lock);
+	que = (struct daemon_cmd *) Daemon_Queue.list.next;
+
+	while (que && (que != (struct daemon_cmd *) & Daemon_Queue.list.next)
+	       && (que->sequence != sequence)) {
+		que = (struct daemon_cmd *) que->list.next;
+	}
+
+	if ((NULL == que)
+	    || (que == (struct daemon_cmd *) & Daemon_Queue.list.next)
+	    || (que->sequence != sequence)) {
+		que = NULL;
+	}
+
+	if (que) {
+		atomic_inc(&que->reference);
+	}
+
+	spin_unlock(&Daemon_Queue.lock);
+
+	DbgPrint("return 0x%p", que);
+	return (que);
+}
+
+int novfs_daemon_open_control(struct inode *Inode, struct file *File)
+{
+	DbgPrint("pid=%d Count=%d", current->pid,
+		 atomic_read(&Daemon_Open_Count));
+	atomic_inc(&Daemon_Open_Count);
+
+	return (0);
+}
+
+int novfs_daemon_close_control(struct inode *Inode, struct file *File)
+{
+	struct daemon_cmd *que;
+
+	DbgPrint("pid=%d Count=%d", 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 = (struct daemon_cmd *) Daemon_Queue.list.next;
+
+		while (que
+		       && (que != (struct daemon_cmd *) & Daemon_Queue.list.next)
+		       && (que->status != QUEUE_DONE)) {
+			que->status = QUEUE_TIMEOUT;
+			up(&que->semaphore);
+
+			que = (struct daemon_cmd *) que->list.next;
+		}
+		spin_unlock(&Daemon_Queue.lock);
+
+		RemoveDriveMaps();
+
+		novfs_scope_cleanup();
+	}
+
+	return (0);
+}
+
+ssize_t novfs_daemon_cmd_send(struct file * file, char *buf, size_t len, loff_t * off)
+{
+	struct daemon_cmd *que;
+	size_t retValue = 0;
+	int Finished = 0;
+	struct novfs_data_list *dlist;
+	int i, dcnt, bcnt, ccnt, error;
+	char *vadr;
+	unsigned long cpylen;
+
+	DbgPrint("%u %lld", len, *off);
+	if (len > novfs_max_iosize) {
+		novfs_max_iosize = len;
+	}
+
+	while (!Finished) {
+		que = get_next_queue(1);
+		DbgPrint("0x%p", que);
+		if (que) {
+			retValue = que->reqlen;
+			if (retValue > len) {
+				retValue = len;
+			}
+			if (retValue > 0x80)
+				novfs_dump(0x80, que->request);
+			else
+				novfs_dump(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("page=0x%p "
+						         "offset=0x%p len=%d",
+							 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 +=
+								    (unsigned long)
+								    dlist->
+								    offset;
+							} else {
+								vadr =
+								    dlist->
+								    offset;
+							}
+
+							ccnt =
+							    copy_to_user(buf,
+									 vadr,
+									 bcnt);
+
+							DbgPrint("Copy %d from 0x%p to 0x%p.",
+							     bcnt, vadr, buf);
+							if (bcnt > 0x80)
+								novfs_dump(0x80,
+								       vadr);
+							else
+								novfs_dump(bcnt,
+								       vadr);
+
+							if (km_adr) {
+								kunmap(dlist->
+								       page);
+							}
+
+							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("after down_interruptible error...%d",
+					 error);
+				retValue = -EINTR;
+				break;
+			}
+			DbgPrint("after down_interruptible");
+		}
+	}
+
+	*off = *off;
+
+	DbgPrint("return 0x%x", retValue);
+
+	return (retValue);
+}
+
+ssize_t novfs_daemon_recv_reply(struct file *file, const char *buf, size_t nbytes, loff_t * ppos)
+{
+	struct daemon_cmd *que;
+	size_t retValue = 0;
+	void *reply;
+	unsigned long sequence, cpylen;
+
+	struct novfs_data_list *dlist;
+	char *vadr;
+	int i;
+
+	DbgPrint("buf=0x%p nbytes=%d ppos=%llx", 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("0x%x 0x%p %d", 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;
+			}
+
+			if (NULL != (dlist = que->data)) {
+				int thiscopy, left = nbytes;
+				retValue = 0;
+
+				DbgPrint("dlist=0x%p count=%d",
+				     dlist, que->datalen);
+				for (i = 0;
+				     (i < que->datalen) && (retValue < nbytes);
+				     i++, dlist++) {
+					__DbgPrint("\n"
+						 "   dlist[%d].page:   0x%p\n"
+						 "   dlist[%d].offset: 0x%p\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 +=
+							    (unsigned long) 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 (thiscopy > 0x80)
+							novfs_dump(0x80, vadr);
+						else
+							novfs_dump(thiscopy, vadr);
+
+						if (km_adr) {
+							kunmap(dlist->page);
+						}
+
+						left -= thiscopy;
+						retValue += thiscopy;
+						buf += thiscopy;
+					}
+				}
+				que->replen = retValue;
+			} else {
+				reply = kmalloc(nbytes, GFP_KERNEL);
+				DbgPrint("reply=0x%p", reply);
+				if (reply) {
+					retValue = nbytes;
+					que->reply = reply;
+					que->replen = nbytes;
+
+					retValue -=
+					    copy_from_user(reply, buf,
+							   retValue);
+					if (retValue > 0x80)
+						novfs_dump(0x80, reply);
+					else
+						novfs_dump(retValue, reply);
+
+				} else {
+					retValue = -ENOMEM;
+				}
+			}
+
+			/*
+			 * Set status that packet is done.
+			 */
+			que->status = QUEUE_DONE;
+
+		} while (0);
+		up(&que->semaphore);
+		Queue_put(que);
+	}
+
+	DbgPrint("return 0x%x", retValue);
+
+	return (retValue);
+}
+
+int novfs_do_login(struct ncl_string *Server, struct ncl_string *Username,
+struct ncl_string *Password, void **lgnId, struct novfs_schandle *Session)
+{
+	struct novfs_login_user_request *cmd;
+	struct novfs_login_user_reply *reply;
+	unsigned long replylen = 0;
+	int retCode, cmdlen, datalen;
+	unsigned char *data;
+
+	datalen = Server->len + Username->len + Password->len;
+	cmdlen = sizeof(*cmd) + datalen;
+	cmd = kmalloc(cmdlen, GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+
+	data = (unsigned char *) cmd + sizeof(*cmd);
+	cmd->Command.CommandType = VFS_COMMAND_LOGIN_USER;
+	cmd->Command.SequenceNumber = 0;
+	memcpy(&cmd->Command.SessionId, Session, sizeof(*Session));
+
+	cmd->srvNameType = Server->type;
+	cmd->serverLength = Server->len;
+	cmd->serverOffset = (unsigned long) (data - (unsigned char *) cmd);
+	memcpy(data, Server->buffer, Server->len);
+	data += Server->len;
+
+	cmd->usrNameType = Username->type;
+	cmd->userNameLength = Username->len;
+	cmd->userNameOffset = (unsigned long) (data - (unsigned char *) cmd);
+	memcpy(data, Username->buffer, Username->len);
+	data += Username->len;
+
+	cmd->pwdNameType = Password->type;
+	cmd->passwordLength = Password->len;
+	cmd->passwordOffset = (unsigned long) (data - (unsigned 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;
+			}
+		}
+		kfree(reply);
+	}
+	memset(cmd, 0, cmdlen);
+	kfree(cmd);
+	return (retCode);
+
+}
+
+int novfs_daemon_logout(struct qstr *Server, struct novfs_schandle *Session)
+{
+	struct novfs_logout_request *cmd;
+	struct novfs_logout_reply *reply;
+	unsigned long replylen = 0;
+	int retCode, cmdlen;
+
+	cmdlen = offsetof(struct novfs_logout_request, Name) + Server->len;
+	cmd = kmalloc(cmdlen, GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+
+	cmd->Command.CommandType = VFS_COMMAND_LOGOUT_USER;
+	cmd->Command.SequenceNumber = 0;
+	memcpy(&cmd->Command.SessionId, Session, sizeof(*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;
+		}
+		kfree(reply);
+	}
+	kfree(cmd);
+	return (retCode);
+
+}
+
+int novfs_daemon_getpwuid(uid_t uid, int unamelen, char *uname)
+{
+	struct novfs_getpwuid_request cmd;
+	struct novfs_getpwuid_reply *reply;
+	unsigned long replylen = 0;
+	int retCode;
+
+	cmd.Command.CommandType = VFS_COMMAND_GETPWUD;
+	cmd.Command.SequenceNumber = 0;
+	SC_INITIALIZE(cmd.Command.SessionId);
+	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 - offsetof(struct
+					    novfs_getpwuid_reply, UserName);
+			if (replylen) {
+				if (replylen > unamelen) {
+					retCode = -EINVAL;
+					replylen = unamelen - 1;
+				}
+				memcpy(uname, reply->UserName, replylen);
+			}
+		}
+		kfree(reply);
+	}
+	return (retCode);
+
+}
+
+int novfs_daemon_getversion(char *Buf, int length)
+{
+	struct novfs_get_version_request cmd;
+	struct novfs_get_version_reply *reply;
+	unsigned long replylen = 0;
+	int retVal = 0;
+
+	cmd.Command.CommandType = VFS_COMMAND_GET_VERSION;
+	cmd.Command.SequenceNumber = 0;
+	SC_INITIALIZE(cmd.Command.SessionId);
+
+	Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply,
+			     &replylen, INTERRUPTIBLE);
+	if (reply) {
+		if (reply->Reply.ErrorCode) {
+			retVal = -EIO;
+		} else {
+			retVal =
+			    replylen - offsetof(struct
+					    novfs_get_version_reply, Version);
+			if (retVal < length) {
+				memcpy(Buf, reply->Version, retVal);
+				Buf[retVal] = '\0';
+			}
+		}
+		kfree(reply);
+	}
+	return (retVal);
+
+}
+
+static int daemon_login(struct novfs_login *Login, struct novfs_schandle *Session)
+{
+	int retCode = -ENOMEM;
+	struct novfs_login lLogin;
+	struct ncl_string server;
+	struct ncl_string username;
+	struct ncl_string password;
+
+	if (!copy_from_user(&lLogin, Login, sizeof(lLogin))) {
+		server.buffer = kmalloc(lLogin.Server.length, GFP_KERNEL);
+		if (server.buffer) {
+			server.len = lLogin.Server.length;
+			server.type = NWC_STRING_TYPE_ASCII;
+			if (!copy_from_user((void *)server.buffer, lLogin.Server.data, server.len)) {
+				username.buffer =	kmalloc(lLogin.UserName.length,	GFP_KERNEL);
+				if (username.buffer) {
+					username.len = lLogin.UserName.length;
+					username.type = NWC_STRING_TYPE_ASCII;
+					if (!copy_from_user((void *)username.buffer, lLogin.UserName.data, username.len)) {
+						password.buffer =	kmalloc(lLogin.Password.length,	GFP_KERNEL);
+						if (password.buffer)
+						{
+							password.len = lLogin.Password.length;
+							password.type = NWC_STRING_TYPE_ASCII;
+							if (!copy_from_user((void *)password.buffer, lLogin.Password.data, password.len)) {
+								retCode = novfs_do_login (&server, &username, &password, NULL, Session);
+								if (!retCode) {
+									char *username;
+									username = novfs_scope_get_username();
+									if (username) {
+										novfs_add_to_root(username);
+									}
+								}
+							}
+							kfree(password.buffer);
+						}
+					}
+					kfree(username.buffer);
+				}
+			}
+			kfree(server.buffer);
+		}
+	}
+
+	return (retCode);
+}
+
+static int daemon_logout(struct novfs_logout *Logout, struct novfs_schandle *Session)
+{
+	struct novfs_logout lLogout;
+	struct qstr server;
+	int retCode = 0;
+
+	if (copy_from_user(&lLogout, Logout, sizeof(lLogout)))
+		return -EFAULT;
+	server.name = kmalloc(lLogout.Server.length, GFP_KERNEL);
+	if (!server.name)
+		return -ENOMEM;
+	server.len = lLogout.Server.length;
+	if (copy_from_user((void *)server.name, lLogout.Server.data, server.len))
+		goto exit;
+	retCode = novfs_daemon_logout(&server, Session);
+exit:
+	kfree(server.name);
+	return (retCode);
+}
+
+int novfs_daemon_create_sessionId(struct novfs_schandle * SessionId)
+{
+	struct novfs_create_context_request cmd;
+	struct novfs_create_context_reply *reply;
+	unsigned long replylen = 0;
+	int retCode = 0;
+
+	DbgPrint("%d", current->pid);
+
+	cmd.Command.CommandType = VFS_COMMAND_CREATE_CONTEXT;
+	cmd.Command.SequenceNumber = 0;
+	SC_INITIALIZE(cmd.Command.SessionId);
+
+	retCode =
+	    Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply,
+				 &replylen, INTERRUPTIBLE);
+	if (reply) {
+		if (!reply->Reply.ErrorCode
+		    && replylen > sizeof(struct novfs_command_reply_header)) {
+			*SessionId = reply->SessionId;
+			retCode = 0;
+		} else {
+			SessionId->hTypeId = 0;
+			SessionId->hId = 0;
+			retCode = -EIO;
+		}
+		kfree(reply);
+	}
+	DbgPrint("SessionId=0x%llx", *SessionId);
+	return (retCode);
+}
+
+int novfs_daemon_destroy_sessionId(struct novfs_schandle SessionId)
+{
+	struct novfs_destroy_context_request cmd;
+	struct novfs_destroy_context_reply *reply;
+	unsigned long replylen = 0;
+	int retCode = 0;
+
+	DbgPrint("0x%p:%p", SessionId.hTypeId,
+		 SessionId.hId);
+
+	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) {
+			struct drive_map *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, struct drive_map, list);
+				if (SC_EQUAL(SessionId, dm->session)) {
+					local_unlink(dm->name);
+					list = list->prev;
+					list_del(&dm->list);
+					kfree(dm);
+				}
+
+			}
+			up(&DriveMapLock);
+
+		} else {
+			retCode = -EIO;
+		}
+		kfree(reply);
+	}
+	return (retCode);
+}
+
+int novfs_daemon_get_userspace(struct novfs_schandle SessionId, uint64_t * TotalSize,
+			 uint64_t * Free, uint64_t * TotalEnties,
+			 uint64_t * FreeEnties)
+{
+	struct novfs_get_user_space cmd;
+	struct novfs_get_user_space_reply *reply;
+	unsigned long replylen = 0;
+	int retCode = 0;
+
+	DbgPrint("0x%p:%p", SessionId.hTypeId,
+		 SessionId.hId);
+
+	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;
+		}
+		kfree(reply);
+	}
+	return (retCode);
+}
+
+int novfs_daemon_set_mnt_point(char *Path)
+{
+	struct novfs_set_mount_path *cmd;
+	struct novfs_set_mount_path_reply *reply;
+	unsigned long replylen, cmdlen;
+	int retCode = -ENOMEM;
+
+	DbgPrint("%s", Path);
+
+	replylen = strlen(Path);
+
+	cmdlen = sizeof(struct novfs_set_mount_path) + replylen;
+
+	cmd = kmalloc(cmdlen, GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+	cmd->Command.CommandType = VFS_COMMAND_SET_MOUNT_PATH;
+	cmd->Command.SequenceNumber = 0;
+	SC_INITIALIZE(cmd->Command.SessionId);
+	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;
+		}
+		kfree(reply);
+	}
+	kfree(cmd);
+	return retCode;
+}
+
+int novfs_daemon_debug_cmd_send(char *Command)
+{
+	struct novfs_debug_request cmd;
+	struct novfs_debug_reply *reply;
+	struct novfs_debug_reply lreply;
+	unsigned long replylen, cmdlen;
+	struct novfs_data_list dlist[2];
+
+	int retCode = -ENOMEM;
+
+	DbgPrint("%s", 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 = offsetof(struct novfs_debug_request, dbgcmd);
+
+	cmd.Command.CommandType = VFS_COMMAND_DBG;
+	cmd.Command.SequenceNumber = 0;
+	SC_INITIALIZE(cmd.Command.SessionId);
+	cmd.cmdlen = strlen(Command);
+
+	replylen = 0;
+
+	retCode =
+	    Queue_Daemon_Command(&cmd, cmdlen, dlist, 2, (void *)&reply,
+				 &replylen, INTERRUPTIBLE);
+	if (reply) {
+		kfree(reply);
+	}
+	if (0 == retCode) {
+		retCode = lreply.Reply.ErrorCode;
+	}
+
+	return (retCode);
+}
+
+int novfs_daemon_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	int retCode = -ENOSYS;
+	unsigned long cpylen;
+	struct novfs_schandle session_id;
+	session_id = novfs_scope_get_sessionId(NULL);
+
+	switch (cmd) {
+	case IOC_LOGIN:
+		retCode = daemon_login((struct novfs_login *) arg, &session_id);
+		break;
+
+	case IOC_LOGOUT:
+		retCode = daemon_logout((struct novfs_logout *)arg, &session_id);
+		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 = kmalloc(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);
+					kfree(buf);
+					retCode = 0;
+				}
+			}
+			break;
+		}
+
+	case IOC_XPLAT:
+		{
+			struct novfs_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("Call NwdGetMountPath");
+				retCode = NwdGetMountPath(&data);
+				break;
+			}
+
+			DbgPrint("[NOVFS XPLAT] status Code = %X\n", retCode);
+			break;
+		}
+
+	}
+	return (retCode);
+}
+
+static int daemon_added_resource(struct daemon_handle * DHandle, int Type, void *CHandle,
+			  unsigned char * FHandle, unsigned long Mode, u_long Size)
+{
+	struct daemon_resource *resource;
+
+	if (FHandle)
+		DbgPrint("DHandle=0x%p Type=%d CHandle=0x%p FHandle=0x%x "
+			 "Mode=0x%x Size=%d", DHandle, Type, CHandle,
+			 *(u32 *) & FHandle[2], Mode, Size);
+	else
+		DbgPrint("DHandle=0x%p Type=%d CHandle=0x%p\n",
+			 DHandle, Type, CHandle);
+
+	resource = kmalloc(sizeof(struct daemon_resource), GFP_KERNEL);
+	if (!resource)
+		return -ENOMEM;
+
+	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("Adding resource=0x%p", resource);
+	return 0;
+}
+
+static int daemon_remove_resource(struct daemon_handle * DHandle, int Type, void *CHandle,
+			   unsigned long FHandle)
+{
+	struct daemon_resource *resource;
+	struct list_head *l;
+	int retVal = -ENOMEM;
+
+	DbgPrint("DHandle=0x%p Type=%d CHandle=0x%p FHandle=0x%x",
+		 DHandle, Type, CHandle, FHandle);
+
+	write_lock(&DHandle->lock);
+
+	list_for_each(l, &DHandle->list) {
+		resource = list_entry(l, struct daemon_resource, list);
+
+		if ((Type == resource->type) &&
+		    (resource->connection == CHandle)) {
+			DbgPrint("Found resource=0x%p", resource);
+			l = l->prev;
+			list_del(&resource->list);
+			kfree(resource);
+			break;
+		}
+	}
+
+	write_unlock(&DHandle->lock);
+
+	return (retVal);
+}
+
+int novfs_daemon_lib_open(struct inode *inode, struct file *file)
+{
+	struct daemon_handle *dh;
+
+	DbgPrint("inode=0x%p file=0x%p", inode, file);
+	dh = kmalloc(sizeof(struct daemon_handle), GFP_KERNEL);
+	if (!dh)
+		return -ENOMEM;
+	file->private_data = dh;
+	INIT_LIST_HEAD(&dh->list);
+	rwlock_init(&dh->lock);
+	dh->session = novfs_scope_get_sessionId(NULL);
+	return 0;
+}
+
+int novfs_daemon_lib_close(struct inode *inode, struct file *file)
+{
+	struct daemon_handle *dh;
+	struct daemon_resource *resource;
+	struct list_head *l;
+
+	char commanddata[sizeof(struct novfs_xplat_call_request) + sizeof(struct nwd_close_conn)];
+	struct novfs_xplat_call_request *cmd;
+	struct xplat_call_reply *reply;
+	struct nwd_close_conn *nwdClose;
+	unsigned long cmdlen, replylen;
+
+	DbgPrint("inode=0x%p file=0x%p", inode, file);
+	if (file->private_data) {
+		dh = (struct daemon_handle *) file->private_data;
+
+		list_for_each(l, &dh->list) {
+			resource = list_entry(l, struct daemon_resource, list);
+
+			if (DH_TYPE_STREAM == resource->type) {
+				novfs_close_stream(resource->connection,
+						   resource->handle,
+						   dh->session);
+			} else if (DH_TYPE_CONNECTION == resource->type) {
+				cmd = (struct novfs_xplat_call_request *) commanddata;
+				cmdlen =
+				    offsetof(struct novfs_xplat_call_request,
+					     data) + sizeof(struct nwd_close_conn);
+				cmd->Command.CommandType =
+				    VFS_COMMAND_XPLAT_CALL;
+				cmd->Command.SequenceNumber = 0;
+				cmd->Command.SessionId = dh->session;
+				cmd->NwcCommand = NWC_CLOSE_CONN;
+
+				cmd->dataLen = sizeof(struct nwd_close_conn);
+				nwdClose = (struct nwd_close_conn *) cmd->data;
+				nwdClose->ConnHandle =
+				    (void *) resource->connection;
+
+				Queue_Daemon_Command((void *)cmd, cmdlen, NULL,
+						     0, (void **)&reply,
+						     &replylen, 0);
+				if (reply)
+					kfree(reply);
+			}
+			l = l->prev;
+			list_del(&resource->list);
+			kfree(resource);
+		}
+		kfree(dh);
+		file->private_data = NULL;
+	}
+
+	return (0);
+}
+
+ssize_t novfs_daemon_lib_read(struct file * file, char *buf, size_t len,
+			    loff_t * off)
+{
+	struct daemon_handle *dh;
+	struct daemon_resource *resource;
+
+	size_t thisread, totalread = 0;
+	loff_t offset = *off;
+
+	DbgPrint("file=0x%p len=%d off=%lld", 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, struct daemon_resource, 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("return = 0x%x", totalread);
+	return (totalread);
+}
+
+ssize_t novfs_daemon_lib_write(struct file * file, const char *buf, size_t len,
+			     loff_t * off)
+{
+	struct daemon_handle *dh;
+	struct daemon_resource *resource;
+
+	size_t thiswrite, totalwrite = -EINVAL;
+	loff_t offset = *off;
+	int status;
+
+	DbgPrint("file=0x%p len=%d off=%lld", 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, struct daemon_resource, list);
+
+			if ((DH_TYPE_STREAM == resource->type) && (len >= 0)) {
+				totalwrite = 0;
+				do {
+					thiswrite = len;
+					status =
+					    novfs_write_stream(resource->
+							       connection,
+							       resource->handle,
+							       (void *)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("return = 0x%x", totalwrite);
+
+	return (totalwrite);
+}
+
+loff_t novfs_daemon_lib_llseek(struct file * file, loff_t offset, int origin)
+{
+	struct daemon_handle *dh;
+	struct daemon_resource *resource;
+
+	loff_t retVal = -EINVAL;
+
+	DbgPrint("file=0x%p offset=%lld origin=%d", 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, struct daemon_resource, 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("ret %lld", retVal);
+
+	return retVal;
+}
+
+#define DbgIocCall(str)		__DbgPrint("[VFS XPLAT] Call " str "\n")
+
+int novfs_daemon_lib_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	int retCode = -ENOSYS;
+	struct daemon_handle *dh;
+	void *handle = NULL;
+	unsigned long cpylen;
+
+	dh = file->private_data;
+
+	DbgPrint("file=0x%p 0x%x 0x%p dh=0x%p", file, cmd, arg, dh);
+
+	if (dh) {
+
+		switch (cmd) {
+		case IOC_LOGIN:
+			retCode = daemon_login((struct novfs_login *)arg, &dh->session);
+			break;
+
+		case IOC_LOGOUT:
+			retCode = daemon_logout((struct novfs_logout *)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, (void *)arg,
+						   sizeof(io));
+				if (io.length) {
+					buf =
+					    kmalloc(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);
+						kfree(buf);
+						retCode = 0;
+					}
+				}
+				break;
+			}
+
+		case IOC_XPLAT:
+			{
+				struct novfs_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:
+					DbgIocCall("NwOpenConnByName");
+					retCode =
+					    novfs_open_conn_by_name(&data,
+						    &handle, dh->session);
+					if (!retCode)
+						daemon_added_resource(dh,
+								      DH_TYPE_CONNECTION,handle, 0, 0, 0);
+					break;
+
+				case NWC_OPEN_CONN_BY_ADDRESS:
+					DbgIocCall("NwOpenConnByAddress");
+					retCode =
+					    novfs_open_conn_by_addr(&data, &handle,
+							     dh->session);
+					if (!retCode)
+						daemon_added_resource(dh,
+								      DH_TYPE_CONNECTION,
+								      handle, 0,
+								      0, 0);
+					break;
+
+				case NWC_OPEN_CONN_BY_REFERENCE:
+
+					DbgIocCall("NwOpenConnByReference");
+					retCode =
+					    novfs_open_conn_by_ref(&data, &handle,
+							    dh->session);
+					if (!retCode)
+						daemon_added_resource(dh,
+								      DH_TYPE_CONNECTION,
+								      handle, 0,
+								      0, 0);
+					break;
+
+				case NWC_SYS_CLOSE_CONN:
+					DbgIocCall("NwSysCloseConn");
+					retCode =
+						novfs_sys_conn_close(&data, (unsigned long *)&handle, dh->session);
+					daemon_remove_resource(dh, DH_TYPE_CONNECTION, handle, 0);
+					break;
+
+				case NWC_CLOSE_CONN:
+					DbgIocCall("NwCloseConn");
+					retCode =
+					    novfs_conn_close(&data, &handle,
+							dh->session);
+					daemon_remove_resource(dh,
+							       DH_TYPE_CONNECTION,
+							       handle, 0);
+					break;
+
+				case NWC_LOGIN_IDENTITY:
+					DbgIocCall(""
+						 "NwLoginIdentity");
+					retCode =
+					    novfs_login_id(&data, dh->session);
+					break;
+
+				case NWC_RAW_NCP_REQUEST:
+					DbgIocCall("[VFS XPLAT] Send Raw "
+						 "NCP Request");
+					retCode = novfs_raw_send(&data, dh->session);
+					break;
+
+				case NWC_AUTHENTICATE_CONN_WITH_ID:
+					DbgIocCall("[VFS XPLAT] Authenticate "
+						 "Conn With ID");
+					retCode =
+					    novfs_auth_conn(&data,
+							     dh->session);
+					break;
+
+				case NWC_UNAUTHENTICATE_CONN:
+					DbgIocCall("[VFS XPLAT] UnAuthenticate "
+						 "Conn With ID");
+					retCode =
+					    novfs_unauthenticate(&data,
+							     dh->session);
+					break;
+
+				case NWC_LICENSE_CONN:
+					DbgIocCall("Call NwLicenseConn");
+					retCode =
+					    novfs_license_conn(&data, dh->session);
+					break;
+
+				case NWC_LOGOUT_IDENTITY:
+					DbgIocCall("NwLogoutIdentity");
+					retCode =
+					    novfs_logout_id(&data,
+							     dh->session);
+					break;
+
+				case NWC_UNLICENSE_CONN:
+					DbgIocCall("NwUnlicense");
+					retCode =
+					    novfs_unlicense_conn(&data, dh->session);
+					break;
+
+				case NWC_GET_CONN_INFO:
+					DbgIocCall("NwGetConnInfo");
+					retCode =
+					    novfs_get_conn_info(&data, dh->session);
+					break;
+
+				case NWC_SET_CONN_INFO:
+					DbgIocCall("NwGetConnInfo");
+					retCode =
+					    novfs_set_conn_info(&data, dh->session);
+					break;
+
+				case NWC_SCAN_CONN_INFO:
+					DbgIocCall("NwScanConnInfo");
+					retCode =
+					    novfs_scan_conn_info(&data, dh->session);
+					break;
+
+				case NWC_GET_IDENTITY_INFO:
+					DbgIocCall("NwGetIdentityInfo");
+					retCode =
+					    novfs_get_id_info(&data,
+							      dh->session);
+					break;
+
+				case NWC_GET_REQUESTER_VERSION:
+					DbgIocCall("NwGetDaemonVersion");
+					retCode =
+					    novfs_get_daemon_ver(&data,
+							       dh->session);
+					break;
+
+				case NWC_GET_PREFERRED_DS_TREE:
+					DbgIocCall("NwcGetPreferredDsTree");
+					retCode =
+					    novfs_get_preferred_DS_tree(&data,
+								  dh->session);
+					break;
+
+				case NWC_SET_PREFERRED_DS_TREE:
+					DbgIocCall("NwcSetPreferredDsTree");
+					retCode =
+					    novfs_set_preferred_DS_tree(&data,
+								  dh->session);
+					break;
+
+				case NWC_GET_DEFAULT_NAME_CONTEXT:
+					DbgIocCall("NwcGetDefaultNameContext");
+					retCode =
+					    novfs_get_default_ctx(&data,
+								 dh->session);
+					break;
+
+				case NWC_SET_DEFAULT_NAME_CONTEXT:
+					DbgIocCall("NwcSetDefaultNameContext");
+					retCode =
+					    novfs_set_default_ctx(&data,
+								 dh->session);
+					break;
+
+				case NWC_QUERY_FEATURE:
+					DbgIocCall("NwQueryFeature");
+					retCode =
+					    novfs_query_feature(&data, dh->session);
+					break;
+
+				case NWC_GET_TREE_MONITORED_CONN_REF:
+					DbgIocCall("NwcGetTreeMonitoredConn");
+					retCode =
+					    novfs_get_tree_monitored_conn(&data,
+								    dh->
+								    session);
+					break;
+
+				case NWC_ENUMERATE_IDENTITIES:
+					DbgIocCall("NwcEnumerateIdentities");
+					retCode =
+					    novfs_enum_ids(&data,
+							      dh->session);
+					break;
+
+				case NWC_CHANGE_KEY:
+					DbgIocCall("NwcChangeAuthKey");
+					retCode =
+					    novfs_change_auth_key(&data,
+							     dh->session);
+					break;
+
+				case NWC_CONVERT_LOCAL_HANDLE:
+					DbgIocCall("NwdConvertLocalHandle");
+					retCode =
+					    NwdConvertLocalHandle(&data, dh);
+					break;
+
+				case NWC_CONVERT_NETWARE_HANDLE:
+					DbgIocCall("NwdConvertNetwareHandle");
+					retCode =
+					    NwdConvertNetwareHandle(&data, dh);
+					break;
+
+				case NWC_SET_PRIMARY_CONN:
+					DbgIocCall("NwcSetPrimaryConn");
+					retCode =
+					    novfs_set_pri_conn(&data,
+							      dh->session);
+					break;
+
+				case NWC_GET_PRIMARY_CONN:
+					DbgIocCall("NwcGetPrimaryConn");
+					retCode =
+					    novfs_get_pri_conn(&data,
+							      dh->session);
+					break;
+
+				case NWC_MAP_DRIVE:
+					DbgIocCall("NwcMapDrive");
+					retCode =
+					    set_map_drive(&data, dh->session);
+					break;
+
+				case NWC_UNMAP_DRIVE:
+					DbgIocCall("NwcUnMapDrive");
+					retCode =
+					    unmap_drive(&data, dh->session);
+					break;
+
+				case NWC_ENUMERATE_DRIVES:
+					DbgIocCall("NwcEnumerateDrives");
+					retCode =
+					    novfs_enum_drives(&data,
+							       dh->session);
+					break;
+
+				case NWC_GET_MOUNT_PATH:
+					DbgIocCall("NwdGetMountPath");
+					retCode = NwdGetMountPath(&data);
+					break;
+
+				case NWC_GET_BROADCAST_MESSAGE:
+					DbgIocCall("NwdGetBroadcastMessage");
+					retCode =
+					    novfs_get_bcast_msg(&data,
+								   dh->session);
+					break;
+
+				case NWC_SET_KEY:
+					DbgIocCall("NwdSetKey");
+					retCode =
+					    novfs_set_key_value(&data, dh->session);
+					break;
+
+				case NWC_VERIFY_KEY:
+					DbgIocCall("NwdVerifyKey");
+					retCode =
+					    novfs_verify_key_value(&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 novfs_daemon_poll(struct file *file,
+			 struct poll_table_struct *poll_table)
+{
+	struct daemon_cmd *que;
+	unsigned int mask = POLLOUT | POLLWRNORM;
+
+	que = get_next_queue(0);
+	if (que)
+		mask |= (POLLIN | POLLRDNORM);
+	return mask;
+}
+
+static int NwdConvertNetwareHandle(struct novfs_xplat *pdata, struct daemon_handle * DHandle)
+{
+	int retVal;
+	struct nwc_convert_netware_handle nh;
+	unsigned long cpylen;
+
+	DbgPrint("DHandle=0x%p", DHandle);
+
+	cpylen =
+	    copy_from_user(&nh, pdata->reqData,
+			   sizeof(struct nwc_convert_netware_handle));
+
+	retVal =
+	    daemon_added_resource(DHandle, DH_TYPE_STREAM,
+				  Uint32toHandle(nh.ConnHandle),
+				  nh.NetWareHandle, nh.uAccessMode,
+				  nh.uFileSize);
+
+	return (retVal);
+}
+
+static int NwdConvertLocalHandle(struct novfs_xplat *pdata, struct daemon_handle * DHandle)
+{
+	int retVal = NWE_REQUESTER_FAILURE;
+	struct daemon_resource *resource;
+	struct nwc_convert_local_handle lh;
+	struct list_head *l;
+	unsigned long cpylen;
+
+	DbgPrint("DHandle=0x%p", DHandle);
+
+	read_lock(&DHandle->lock);
+
+	list_for_each(l, &DHandle->list) {
+		resource = list_entry(l, struct daemon_resource, list);
+
+		if (DH_TYPE_STREAM == resource->type) {
+			lh.uConnReference =
+			    HandletoUint32(resource->connection);
+
+//sgled         memcpy(lh.NwWareHandle, resource->handle, sizeof(resource->handle));
+			memcpy(lh.NetWareHandle, resource->handle, sizeof(resource->handle));	//sgled
+			if (pdata->repLen >= sizeof(struct nwc_convert_local_handle)) {
+				cpylen =
+				    copy_to_user(pdata->repData, &lh,
+						 sizeof(struct nwc_convert_local_handle));
+				retVal = 0;
+			} else {
+				retVal = NWE_BUFFER_OVERFLOW;
+			}
+			break;
+		}
+	}
+
+	read_unlock(&DHandle->lock);
+
+	return (retVal);
+}
+
+static int NwdGetMountPath(struct novfs_xplat *pdata)
+{
+	int retVal = NWE_REQUESTER_FAILURE;
+	int len;
+	unsigned long cpylen;
+	struct nwc_get_mount_path mp;
+
+	cpylen = copy_from_user(&mp, pdata->reqData, pdata->reqLen);
+
+	if (novfs_current_mnt) {
+
+		len = strlen(novfs_current_mnt) + 1;
+		if ((len > mp.MountPathLen) && mp.pMountPath) {
+			retVal = NWE_BUFFER_OVERFLOW;
+		} else {
+			if (mp.pMountPath) {
+				cpylen =
+				    copy_to_user(mp.pMountPath,
+						 novfs_current_mnt, len);
+			}
+			retVal = 0;
+		}
+
+		mp.MountPathLen = len;
+
+		if (pdata->repData && (pdata->repLen >= sizeof(mp))) {
+			cpylen = copy_to_user(pdata->repData, &mp, sizeof(mp));
+		}
+	}
+
+	return (retVal);
+}
+
+static int set_map_drive(struct novfs_xplat *pdata, struct novfs_schandle Session)
+{
+	int retVal;
+	unsigned long cpylen;
+	struct nwc_map_drive_ex symInfo;
+	char *path;
+	struct drive_map *drivemap, *dm;
+	struct list_head *list;
+
+	retVal = novfs_set_map_drive(pdata, Session);
+	if (retVal)
+		return retVal;
+	if (copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo)))
+		return -EFAULT;
+	drivemap =
+		kmalloc(sizeof(struct drive_map) + symInfo.linkOffsetLength,
+				GFP_KERNEL);
+	if (!drivemap)
+		return -ENOMEM;
+
+	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("hash=0x%lx path=%s", drivemap->hash, drivemap->name);
+
+	dm = (struct drive_map *) & DriveMapList.next;
+
+	down(&DriveMapLock);
+
+	list_for_each(list, &DriveMapList) {
+		dm = list_entry(list, struct drive_map, list);
+		__DbgPrint("%s: dm=0x%p\n"
+				"   hash:    0x%lx\n"
+				"   namelen: %d\n"
+				"   name:    %s\n", __func__,
+				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 == (struct drive_map *) & DriveMapList) ||
+				(dm->hash < drivemap->hash)) {
+			list_add(&drivemap->list, &dm->list);
+		} else {
+			list_add_tail(&drivemap->list,
+					&dm->list);
+		}
+	}
+	else
+		kfree(drivemap);
+	up(&DriveMapLock);
+	return (retVal);
+}
+
+static int unmap_drive(struct novfs_xplat *pdata, struct novfs_schandle Session)
+{
+	int retVal = NWE_REQUESTER_FAILURE;
+	struct nwc_unmap_drive_ex symInfo;
+	char *path;
+	struct drive_map *dm;
+	struct list_head *list;
+	unsigned long hash;
+
+
+	retVal = novfs_unmap_drive(pdata, Session);
+	if (retVal)
+		return retVal;
+	if (copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo)))
+		return -EFAULT;
+
+	path = kmalloc(symInfo.linkLen, GFP_KERNEL);
+	if (!path)
+		return -ENOMEM;
+	if (copy_from_user(path,((struct nwc_unmap_drive_ex *) pdata->reqData)->linkData, symInfo.linkLen)) {
+		kfree(path);
+		return -EFAULT;
+	}
+
+	hash = full_name_hash(path, symInfo.linkLen - 1);
+	DbgPrint("hash=0x%x path=%s", hash, path);
+
+	dm = NULL;
+
+	down(&DriveMapLock);
+
+	list_for_each(list, &DriveMapList) {
+		dm = list_entry(list, struct drive_map, list);
+		__DbgPrint("%s: dm=0x%p %s\n"
+				"   hash:    0x%x\n"
+				"   namelen: %d\n", __func__,
+				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("%s: Remove dm=0x%p %s\n"
+				"   hash:    0x%x\n"
+				"   namelen: %d\n", __func__,
+				dm, dm->name, dm->hash, dm->namelen);
+		list_del(&dm->list);
+		kfree(dm);
+	}
+
+	up(&DriveMapLock);
+	return (retVal);
+}
+
+static void RemoveDriveMaps(void)
+{
+	struct drive_map *dm;
+	struct list_head *list;
+
+	down(&DriveMapLock);
+	list_for_each(list, &DriveMapList) {
+		dm = list_entry(list, struct drive_map, list);
+
+		__DbgPrint("%s: dm=0x%p\n"
+			 "   hash:    0x%x\n"
+			 "   namelen: %d\n"
+			 "   name:    %s\n", __func__,
+			 dm, dm->hash, dm->namelen, dm->name);
+		local_unlink(dm->name);
+		list = list->prev;
+		list_del(&dm->list);
+		kfree(dm);
+	}
+	up(&DriveMapLock);
+}
+
+/* As picked from do_unlinkat() */
+
+static long local_unlink(const char *pathname)
+{
+	int error;
+	struct dentry *dentry;
+	char *name, *c;
+	struct nameidata nd;
+	struct inode *inode = NULL;
+
+	error = path_lookup(pathname, LOOKUP_PARENT, &nd);
+	DbgPrint("path_lookup %s error: %d\n", pathname, error);
+	if (error)
+		return error;
+
+	error = -EISDIR;
+	if (nd.last_type != LAST_NORM)
+		goto exit1;
+	mutex_lock(&nd.path.dentry->d_inode->i_mutex);
+	/* Get the filename of pathname */
+	name=c=(char *)pathname;
+	while (*c!='\0') {
+		if (*c=='/')
+			name=++c;
+		c++;
+	}
+	dentry = lookup_one_len(name, nd.path.dentry, strlen(name));
+	error = PTR_ERR(dentry);
+	DbgPrint("dentry %p", dentry);
+	if (!(dentry->d_inode->i_mode & S_IFLNK)) {
+		DbgPrint("%s not a link", name);
+		error=-ENOENT;
+		goto exit1;
+	}
+
+	if (!IS_ERR(dentry)) {
+		/* Why not before? Because we want correct error value */
+		if (nd.last.name[nd.last.len])
+			goto slashes;
+		inode = dentry->d_inode;
+		if (inode)
+			atomic_inc(&inode->i_count);
+		error = mnt_want_write(nd.path.mnt);
+		DbgPrint("inode %p mnt_want_write error %d", inode, error);
+		if (error)
+			goto exit2;
+		error = vfs_unlink(nd.path.dentry->d_inode, dentry);
+		mnt_drop_write(nd.path.mnt);
+	exit2:
+		dput(dentry);
+	}
+	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
+	if (inode)
+		iput(inode);	/* truncate the inode here */
+exit1:
+	path_put(&nd.path);
+	DbgPrint("returning error %d", error);
+	return error;
+
+slashes:
+	error = !dentry->d_inode ? -ENOENT :
+		S_ISDIR(dentry->d_inode->i_mode) ? -EISDIR : -ENOTDIR;
+	goto exit2;
+}
+
--- /dev/null
+++ b/fs/novfs/file.c
@@ -0,0 +1,1921 @@
+/*
+ * Novell NCP Redirector for Linux
+ * Author: James Turner
+ *
+ * This file contains functions for accessing files through the daemon.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/kthread.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <linux/sched.h>
+#include <linux/dcache.h>
+#include <linux/pagemap.h>
+#include <linux/stat.h>
+#include <linux/slab.h>
+#include <asm/uaccess.h>
+
+#include "vfs.h"
+#include "commands.h"
+#include "nwerror.h"
+
+static ssize_t novfs_tree_read(struct file * file, char *buf, size_t len, loff_t * off);
+extern struct dentry_operations novfs_dentry_operations;
+
+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.
+ */
+static int StripTrailingDots = 1;
+
+int novfs_get_alltrees(struct dentry *parent)
+{
+	unsigned char *p;
+	struct novfs_command_reply_header * reply = NULL;
+	unsigned long replylen = 0;
+	struct novfs_command_request_header cmd;
+	int retCode;
+	struct dentry *entry;
+	struct qstr name;
+	struct inode *inode;
+
+	cmd.CommandType = 0;
+	cmd.SequenceNumber = 0;
+//sg ???   cmd.SessionId = 0x1234;
+	SC_INITIALIZE(cmd.SessionId);
+
+	DbgPrint("");
+
+	retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE);
+	DbgPrint("reply=0x%p replylen=%d", reply, replylen);
+	if (reply) {
+		novfs_dump(replylen, reply);
+		if (!reply->ErrorCode
+		    && (replylen > sizeof(struct novfs_command_reply_header))) {
+			p = (char *)reply + 8;
+			while (*p) {
+				DbgPrint("%s", 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("adding %s", 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, 0, &name);
+						if (inode) {
+							inode->i_fop = &novfs_tree_operations;
+							d_add(entry, inode);
+						}
+					}
+				}
+				p += (name.len + 1);
+			}
+		}
+		kfree(reply);
+	}
+	return (retCode);
+}
+
+static ssize_t novfs_tree_read(struct file * file, char *buf, size_t len, loff_t * off)
+{
+	if (file->f_pos != 0) {
+		return (0);
+	}
+	if (copy_to_user(buf, "Tree\n", 5)) {
+		return (0);
+	}
+	return (5);
+}
+
+int novfs_get_servers(unsigned char ** ServerList, struct novfs_schandle SessionId)
+{
+	struct novfs_get_connected_server_list req;
+	struct novfs_get_connected_server_list_reply *reply = NULL;
+	unsigned 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("reply");
+		replylen -= sizeof(struct novfs_command_reply_header);
+		if (!reply->Reply.ErrorCode && replylen) {
+			memcpy(reply, reply->List, replylen);
+			*ServerList = (unsigned char *) reply;
+			retCode = 0;
+		} else {
+			kfree(reply);
+			retCode = -ENOENT;
+		}
+	}
+	return (retCode);
+}
+
+int novfs_get_vols(struct qstr *Server, unsigned char ** VolumeList,
+				 struct novfs_schandle SessionId)
+{
+	struct novfs_get_server_volume_list *req;
+	struct novfs_get_server_volume_list_reply *reply = NULL;
+	unsigned long replylen = 0, reqlen;
+	int retCode;
+
+	*VolumeList = NULL;
+	reqlen = sizeof(struct novfs_get_server_volume_list) + Server->len;
+	req = kmalloc(reqlen, GFP_KERNEL);
+	if (!req)
+		return -ENOMEM;
+	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("reply");
+		novfs_dump(replylen, reply);
+		replylen -= sizeof(struct novfs_command_reply_header);
+
+		if (!reply->Reply.ErrorCode && replylen) {
+			memcpy(reply, reply->List, replylen);
+			*VolumeList = (unsigned char *) reply;
+			retCode = 0;
+		} else {
+			kfree(reply);
+			retCode = -ENOENT;
+		}
+	}
+	kfree(req);
+	return (retCode);
+}
+
+int novfs_get_file_info(unsigned char * Path, struct novfs_entry_info * Info, struct novfs_schandle SessionId)
+{
+	struct novfs_verify_file_reply *reply = NULL;
+	unsigned long replylen = 0;
+	struct novfs_verify_file_request * cmd;
+	int cmdlen;
+	int retCode = -ENOENT;
+	int pathlen;
+
+	DbgPrint("Path = %s", 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 = offsetof(struct novfs_verify_file_request,path) + pathlen;
+		cmd = kmalloc(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("replylen=%d sizeof(VERIFY_FILE_REPLY)=%d",
+					     replylen,
+					     sizeof(struct novfs_verify_file_reply));
+					if (replylen >
+					    sizeof(struct novfs_verify_file_reply)) {
+						unsigned int *lp =
+						    &reply->fileMode;
+						lp++;
+						DbgPrint("extra data 0x%x",
+							 *lp);
+						Info->mtime.tv_nsec = *lp;
+					}
+					retCode = 0;
+				}
+
+				kfree(reply);
+			}
+			kfree(cmd);
+		}
+	}
+
+	DbgPrint("return 0x%x", retCode);
+	return (retCode);
+}
+
+int novfs_getx_file_info(char *Path, const char *Name, char *buffer,
+			 ssize_t buffer_size, ssize_t * dataLen,
+			 struct novfs_schandle SessionId)
+{
+	struct novfs_xa_get_reply *reply = NULL;
+	unsigned long replylen = 0;
+	struct novfs_xa_get_request *cmd;
+	int cmdlen;
+	int retCode = -ENOENT;
+
+	int namelen = strlen(Name);
+	int pathlen = strlen(Path);
+
+	DbgPrint("xattr: Path = %s, pathlen = %i, Name = %s, namelen = %i",
+		 Path, pathlen, Name, namelen);
+
+	if (namelen > MAX_XATTR_NAME_LEN) {
+		return ENOATTR;
+	}
+
+	cmdlen = offsetof(struct novfs_xa_get_request, data) + pathlen + 1 + namelen + 1;	// two '\0'
+	cmd = (struct novfs_xa_get_request *) kmalloc(cmdlen, GFP_KERNEL);
+	if (cmd) {
+		cmd->Command.CommandType = VFS_COMMAND_GET_EXTENDED_ATTRIBUTE;
+		cmd->Command.SequenceNumber = 0;
+		cmd->Command.SessionId = SessionId;
+
+		cmd->pathLen = pathlen;
+		memcpy(cmd->data, Path, cmd->pathLen + 1);	//+ '\0'
+
+		cmd->nameLen = namelen;
+		memcpy(cmd->data + cmd->pathLen + 1, Name, cmd->nameLen + 1);
+
+		DbgPrint("xattr: PXA_GET_REQUEST BEGIN");
+		DbgPrint("xattr: Queue_Daemon_Command %d",
+			 cmd->Command.CommandType);
+		DbgPrint("xattr: Command.SessionId = %d",
+			 cmd->Command.SessionId);
+		DbgPrint("xattr: pathLen = %d", cmd->pathLen);
+		DbgPrint("xattr: Path = %s", cmd->data);
+		DbgPrint("xattr: nameLen = %d", cmd->nameLen);
+		DbgPrint("xattr: name = %s", (cmd->data + cmd->pathLen + 1));
+		DbgPrint("xattr: PXA_GET_REQUEST END");
+
+		retCode =
+		    Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply,
+					 &replylen, INTERRUPTIBLE);
+
+		if (reply) {
+
+			if (reply->Reply.ErrorCode) {
+				DbgPrint("xattr: reply->Reply.ErrorCode=%d, %X",
+					 reply->Reply.ErrorCode,
+					 reply->Reply.ErrorCode);
+				DbgPrint("xattr: replylen=%d", replylen);
+
+				//0xC9 = EA not found (C9), 0xD1 = EA access denied
+				if ((reply->Reply.ErrorCode == 0xC9)
+				    || (reply->Reply.ErrorCode == 0xD1)) {
+					retCode = -ENOATTR;
+				} else {
+					retCode = -ENOENT;
+				}
+			} else {
+
+				*dataLen =
+				    replylen - sizeof(struct novfs_command_reply_header);
+				DbgPrint("xattr: replylen=%u, dataLen=%u",
+					 replylen, *dataLen);
+
+				if (buffer_size >= *dataLen) {
+					DbgPrint("xattr: copying to buffer from &reply->pData");
+					memcpy(buffer, &reply->pData, *dataLen);
+
+					retCode = 0;
+				} else {
+					DbgPrint("xattr: (!!!) buffer is smaller then reply");
+					retCode = -ERANGE;
+				}
+				DbgPrint("xattr: /dumping buffer");
+				novfs_dump(*dataLen, buffer);
+				DbgPrint("xattr: \\after dumping buffer");
+			}
+
+			kfree(reply);
+		} else {
+			DbgPrint("xattr: reply = NULL");
+		}
+		kfree(cmd);
+
+	}
+
+	return retCode;
+}
+
+int novfs_setx_file_info(char *Path, const char *Name, const void *Value,
+			 unsigned long valueLen, unsigned long *bytesWritten,
+			 int flags, struct novfs_schandle SessionId)
+{
+	struct novfs_xa_set_reply *reply = NULL;
+	unsigned long replylen = 0;
+	struct novfs_xa_set_request *cmd;
+	int cmdlen;
+	int retCode = -ENOENT;
+
+	int namelen = strlen(Name);
+	int pathlen = strlen(Path);
+
+	DbgPrint("xattr: Path = %s, pathlen = %i, Name = %s, namelen = %i, "
+		 "value len = %u", Path, pathlen, Name, namelen, valueLen);
+
+	if (namelen > MAX_XATTR_NAME_LEN) {
+		return ENOATTR;
+	}
+
+	cmdlen = offsetof(struct novfs_xa_set_request, data) + pathlen + 1 + namelen + 1 + valueLen;
+	cmd = (struct novfs_xa_set_request *) kmalloc(cmdlen, GFP_KERNEL);
+	if (cmd) {
+		cmd->Command.CommandType = VFS_COMMAND_SET_EXTENDED_ATTRIBUTE;
+		cmd->Command.SequenceNumber = 0;
+		cmd->Command.SessionId = SessionId;
+
+		cmd->flags = flags;
+		cmd->pathLen = pathlen;
+		memcpy(cmd->data, Path, cmd->pathLen);
+
+		cmd->nameLen = namelen;
+		memcpy(cmd->data + cmd->pathLen + 1, Name, cmd->nameLen + 1);
+
+		cmd->valueLen = valueLen;
+		memcpy(cmd->data + cmd->pathLen + 1 + cmd->nameLen + 1, Value,
+		       valueLen);
+
+		DbgPrint("xattr: PXA_SET_REQUEST BEGIN");
+		DbgPrint("attr: Queue_Daemon_Command %d",
+			 cmd->Command.CommandType);
+		DbgPrint("xattr: Command.SessionId = %d",
+			 cmd->Command.SessionId);
+		DbgPrint("xattr: pathLen = %d", cmd->pathLen);
+		DbgPrint("xattr: Path = %s", cmd->data);
+		DbgPrint("xattr: nameLen = %d", cmd->nameLen);
+		DbgPrint("xattr: name = %s", (cmd->data + cmd->pathLen + 1));
+		novfs_dump(valueLen < 16 ? valueLen : 16, (char *)Value);
+
+		DbgPrint("xattr: PXA_SET_REQUEST END");
+
+		retCode =
+		    Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply,
+					 &replylen, INTERRUPTIBLE);
+
+		if (reply) {
+
+			if (reply->Reply.ErrorCode) {
+				DbgPrint("xattr: reply->Reply.ErrorCode=%d, %X",
+					 reply->Reply.ErrorCode,
+					 reply->Reply.ErrorCode);
+				DbgPrint("xattr: replylen=%d", replylen);
+
+				retCode = -reply->Reply.ErrorCode;	//-ENOENT;
+			} else {
+
+				DbgPrint("xattr: replylen=%u, real len = %u",
+					 replylen,
+					 replylen - sizeof(struct novfs_command_reply_header));
+				memcpy(bytesWritten, &reply->pData,
+				       replylen - sizeof(struct novfs_command_reply_header));
+
+				retCode = 0;
+			}
+
+			kfree(reply);
+		} else {
+			DbgPrint("xattr: reply = NULL");
+		}
+		kfree(cmd);
+
+	}
+
+	return retCode;
+}
+
+int novfs_listx_file_info(char *Path, char *buffer, ssize_t buffer_size,
+			  ssize_t * dataLen, struct novfs_schandle SessionId)
+{
+	struct novfs_xa_list_reply *reply = NULL;
+	unsigned long replylen = 0;
+	struct novfs_verify_file_request *cmd;
+	int cmdlen;
+	int retCode = -ENOENT;
+
+	int pathlen = strlen(Path);
+	DbgPrint("xattr: Path = %s, pathlen = %i", Path, pathlen);
+
+	*dataLen = 0;
+	cmdlen = offsetof(struct novfs_verify_file_request, path) + pathlen;
+	cmd = (struct novfs_verify_file_request *) kmalloc(cmdlen, GFP_KERNEL);
+	if (cmd) {
+		cmd->Command.CommandType = VFS_COMMAND_LIST_EXTENDED_ATTRIBUTES;
+		cmd->Command.SequenceNumber = 0;
+		cmd->Command.SessionId = SessionId;
+		cmd->pathLen = pathlen;
+		memcpy(cmd->path, Path, cmd->pathLen + 1);	//+ '\0'
+		DbgPrint("xattr: PVERIFY_FILE_REQUEST BEGIN");
+		DbgPrint("xattr: Queue_Daemon_Command %d",
+		     cmd->Command.CommandType);
+		DbgPrint("xattr: Command.SessionId = %d",
+		     cmd->Command.SessionId);
+		DbgPrint("xattr: pathLen = %d", cmd->pathLen);
+		DbgPrint("xattr: Path = %s", cmd->path);
+		DbgPrint("xattr: PVERIFY_FILE_REQUEST END");
+
+		retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0,
+					       (void *)&reply, &replylen,
+					       INTERRUPTIBLE);
+
+		if (reply) {
+
+			if (reply->Reply.ErrorCode) {
+				DbgPrint("xattr: reply->Reply.ErrorCode=%d, %X",
+					 reply->Reply.ErrorCode,
+					 reply->Reply.ErrorCode);
+				DbgPrint("xattr: replylen=%d", replylen);
+
+				retCode = -ENOENT;
+			} else {
+				*dataLen =
+				    replylen - sizeof(struct novfs_command_reply_header);
+				DbgPrint("xattr: replylen=%u, dataLen=%u",
+					 replylen, *dataLen);
+
+				if (buffer_size >= *dataLen) {
+					DbgPrint("xattr: copying to buffer "
+						 "from &reply->pData");
+					memcpy(buffer, &reply->pData, *dataLen);
+				} else {
+					DbgPrint("xattr: (!!!) buffer is "
+						 "smaller then reply\n");
+					retCode = -ERANGE;
+				}
+				DbgPrint("xattr: /dumping buffer");
+				novfs_dump(*dataLen, buffer);
+				DbgPrint("xattr: \\after dumping buffer");
+
+				retCode = 0;
+			}
+
+			kfree(reply);
+		} else {
+			DbgPrint("xattr: reply = NULL");
+		}
+		kfree(cmd);
+
+	}
+
+	return retCode;
+}
+
+static int begin_directory_enumerate(unsigned char * Path, int PathLen, void ** EnumHandle,
+			      struct novfs_schandle SessionId)
+{
+	struct novfs_begin_enumerate_directory_request *cmd;
+	struct novfs_begin_enumerate_directory_reply *reply = NULL;
+	unsigned long replylen = 0;
+	int retCode, cmdlen;
+
+	*EnumHandle = 0;
+
+	cmdlen = offsetof(struct
+			novfs_begin_enumerate_directory_request, path) + PathLen;
+	cmd = kmalloc(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;
+			}
+			kfree(reply);
+		}
+		kfree(cmd);
+	} else {
+		retCode = -ENOMEM;
+	}
+	return (retCode);
+}
+
+int novfs_end_directory_enumerate(void *EnumHandle, struct novfs_schandle SessionId)
+{
+	struct novfs_end_enumerate_directory_request cmd;
+	struct novfs_end_enumerate_directory_reply *reply = NULL;
+	unsigned 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;
+		}
+		kfree(reply);
+	}
+
+	return (retCode);
+}
+
+static int directory_enumerate_ex(void ** EnumHandle, struct novfs_schandle SessionId, int *Count,
+			   struct novfs_entry_info **PInfo, int Interrupt)
+{
+	struct novfs_enumerate_directory_ex_request cmd;
+	struct novfs_enumerate_directory_ex_reply *reply = NULL;
+	unsigned long replylen = 0;
+	int retCode = 0;
+	struct novfs_entry_info * info;
+	struct novfs_enumerate_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(struct novfs_command_reply_header)) &&
+		     (reply->enumCount > 0))) {
+			DbgPrint("isize=%d", replylen);
+			data =
+			    (struct novfs_enumerate_directory_ex_data *) ((char *)reply +
+							    sizeof
+							    (struct novfs_enumerate_directory_ex_reply));
+			isize =
+			    replylen - sizeof(struct novfs_enumerate_directory_ex_reply *) -
+			    reply->enumCount *
+			    offsetof(struct
+					    novfs_enumerate_directory_ex_data, name);
+			isize +=
+			    (reply->enumCount *
+			     offsetof(struct novfs_entry_info, name));
+
+			if (PInfo) {
+				*PInfo = info = kmalloc(isize, GFP_KERNEL);
+				if (*PInfo) {
+					DbgPrint("data=0x%p info=0x%p",
+						 data, info);
+					*Count = reply->enumCount;
+					do {
+						DbgPrint("data=0x%p length=%d",
+							 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 =
+						    (struct novfs_enumerate_directory_ex_data *)
+						    & data->name[data->nameLen];
+						replylen =
+						    (int)((char *)&info->
+							  name[info->
+							       namelength] -
+							  (char *)info);
+						DbgPrint("info=0x%p", info);
+						novfs_dump(replylen, info);
+
+						info =
+						    (struct novfs_entry_info *) & info->
+						    name[info->namelength];
+
+					} while (--reply->enumCount);
+				}
+			}
+
+			if (reply->Reply.ErrorCode) {
+				retCode = -1;	/* Eof of data */
+			}
+			*EnumHandle = reply->enumerateHandle;
+		} else {
+			retCode = -ENODATA;
+		}
+		kfree(reply);
+	}
+
+	return (retCode);
+}
+
+int novfs_get_dir_listex(unsigned char * Path, void ** EnumHandle, int *Count,
+			       struct novfs_entry_info **Info,
+			       struct novfs_schandle SessionId)
+{
+	int retCode = -ENOENT;
+
+	if (Count)
+		*Count = 0;
+	if (Info)
+		*Info = NULL;
+
+	if ((void *) - 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) {
+			novfs_end_directory_enumerate(*EnumHandle, SessionId);
+			retCode = 0;
+			*EnumHandle = Uint32toHandle(-1);
+		}
+	}
+	return (retCode);
+}
+
+int novfs_open_file(unsigned char * Path, int Flags, struct novfs_entry_info * Info,
+		void ** Handle,
+		struct novfs_schandle SessionId)
+{
+	struct novfs_open_file_request *cmd;
+	struct novfs_open_file_reply *reply;
+	unsigned long replylen = 0;
+	int retCode, cmdlen, pathlen;
+
+	pathlen = strlen(Path);
+
+	if (StripTrailingDots) {
+		if ('.' == Path[pathlen - 1])
+			pathlen--;
+	}
+
+	*Handle = 0;
+
+	cmdlen = offsetof(struct novfs_open_file_request, path) + pathlen;
+	cmd = kmalloc(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 if (NWE_FILE_IN_USE ==
+					   reply->Reply.ErrorCode) {
+					retCode = -EBUSY;
+				} else {
+					retCode = -ENOENT;
+				}
+			} else {
+				*Handle = reply->handle;
+				retCode = 0;
+			}
+			kfree(reply);
+		}
+		kfree(cmd);
+	} else {
+		retCode = -ENOMEM;
+	}
+	return (retCode);
+}
+
+int novfs_create(unsigned char * Path, int DirectoryFlag, struct novfs_schandle SessionId)
+{
+	struct novfs_create_file_request *cmd;
+	struct novfs_create_file_reply *reply;
+	unsigned long replylen = 0;
+	int retCode, cmdlen, pathlen;
+
+	pathlen = strlen(Path);
+
+	if (StripTrailingDots) {
+		if ('.' == Path[pathlen - 1])
+			pathlen--;
+	}
+
+	cmdlen = offsetof(struct novfs_create_file_request, path) + pathlen;
+	cmd = kmalloc(cmdlen, GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+	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;
+			if (reply->Reply.ErrorCode == NWE_ACCESS_DENIED)
+				retCode = -EACCES;
+
+		}
+		kfree(reply);
+	}
+	kfree(cmd);
+	return (retCode);
+}
+
+int novfs_close_file(void *Handle, struct novfs_schandle SessionId)
+{
+	struct novfs_close_file_request cmd;
+	struct novfs_close_file_reply *reply;
+	unsigned 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;
+		}
+		kfree(reply);
+	}
+	return (retCode);
+}
+
+int novfs_read_file(void *Handle, unsigned char * Buffer, size_t * Bytes,
+		    loff_t * Offset, struct novfs_schandle SessionId)
+{
+	struct novfs_read_file_request cmd;
+	struct novfs_read_file_reply * reply = NULL;
+	unsigned long replylen = 0;
+	int retCode = 0;
+	size_t len;
+
+	len = *Bytes;
+	*Bytes = 0;
+
+	if (offsetof(struct novfs_read_file_reply, data) + len
+			> novfs_max_iosize) {
+		len = novfs_max_iosize - offsetof(struct
+				novfs_read_file_reply, 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("Queue_Daemon_Command 0x%x replylen=%d", retCode, replylen);
+
+	if (!retCode) {
+		if (reply->Reply.ErrorCode) {
+			if (NWE_FILE_IO_LOCKED == reply->Reply.ErrorCode) {
+				retCode = -EBUSY;
+			} else {
+				retCode = -EIO;
+			}
+		} else {
+			replylen -= offsetof(struct
+					novfs_read_file_reply, data);
+
+			if (replylen > 0) {
+				replylen -=
+				    copy_to_user(Buffer, reply->data, replylen);
+				*Bytes = replylen;
+			}
+		}
+	}
+
+	if (reply) {
+		kfree(reply);
+	}
+
+	DbgPrint("*Bytes=0x%x retCode=0x%x", *Bytes, retCode);
+
+	return (retCode);
+}
+
+int novfs_read_pages(void *Handle, struct novfs_data_list *DList,
+		int DList_Cnt, size_t * Bytes, loff_t * Offset,
+		struct novfs_schandle SessionId)
+{
+	struct novfs_read_file_request cmd;
+	struct novfs_read_file_reply * reply = NULL;
+	struct novfs_read_file_reply lreply;
+	unsigned long replylen = 0;
+	int retCode = 0;
+	size_t len;
+
+	len = *Bytes;
+	*Bytes = 0;
+
+	DbgPrint("Handle=0x%p Dlst=0x%p Dlcnt=%d Bytes=%d Offset=%lld "
+		 "SessionId=0x%p:%p", Handle, DList, DList_Cnt, len, *Offset,
+		 SessionId.hTypeId, SessionId.hId);
+
+	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 = offsetof(struct novfs_read_file_reply, data);
+	DList[0].rwflag = DLWRITE;
+
+	retCode =
+	    Queue_Daemon_Command(&cmd, sizeof(cmd), DList, DList_Cnt,
+				 (void *)&reply, &replylen, INTERRUPTIBLE);
+
+	DbgPrint("Queue_Daemon_Command 0x%x", retCode);
+
+	if (!retCode) {
+		if (reply) {
+			memcpy(&lreply, reply, sizeof(lreply));
+		}
+
+		if (lreply.Reply.ErrorCode) {
+			if (NWE_FILE_IO_LOCKED == lreply.Reply.ErrorCode) {
+				retCode = -EBUSY;
+			} else {
+				retCode = -EIO;
+			}
+		}
+		*Bytes = replylen - offsetof(struct
+				novfs_read_file_reply, data);
+	}
+
+	if (reply) {
+		kfree(reply);
+	}
+
+	DbgPrint("retCode=0x%x", retCode);
+
+	return (retCode);
+}
+
+int novfs_write_file(void *Handle, unsigned char * Buffer, size_t * Bytes,
+		     loff_t * Offset, struct novfs_schandle SessionId)
+{
+	struct novfs_write_file_request cmd;
+	struct novfs_write_file_reply *reply = NULL;
+	unsigned long replylen = 0;
+	int retCode = 0, cmdlen;
+	size_t len;
+
+	unsigned long boff;
+	struct page **pages;
+	struct novfs_data_list *dlist;
+	int res = 0, npage, i;
+	struct novfs_write_file_reply lreply;
+
+	len = *Bytes;
+	cmdlen = offsetof(struct novfs_write_file_request, data);
+
+	*Bytes = 0;
+
+	memset(&lreply, 0, sizeof(lreply));
+
+	DbgPrint("cmdlen=%ld len=%ld", cmdlen, len);
+
+	if ((cmdlen + len) > novfs_max_iosize) {
+		len = novfs_max_iosize - 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("cmdlen=%ld len=%ld", cmdlen, len);
+
+	npage =
+	    (((unsigned long)Buffer & ~PAGE_MASK) + len +
+	     (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+
+	dlist = kmalloc(sizeof(struct novfs_data_list) * (npage + 1), GFP_KERNEL);
+	if (NULL == dlist) {
+		return (-ENOMEM);
+	}
+
+	pages = kmalloc(sizeof(struct page *) * npage, GFP_KERNEL);
+
+	if (NULL == pages) {
+		kfree(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("res=%d", 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("page=0x%p offset=0x%p len=%d",
+			 dlist[0].page, dlist[0].offset, dlist[0].len);
+
+		boff = dlist[0].len;
+
+		DbgPrint("len=%d boff=%d", 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("%d: page=0x%p offset=0x%p len=%d", 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("Buffer=0x%p boff=0x%x len=%d", Buffer, boff, len);
+
+		retCode =
+		    Queue_Daemon_Command(&cmd, cmdlen, dlist, res,
+					 (void *)&reply, &replylen,
+					 INTERRUPTIBLE);
+
+	} else {
+		char *kdata;
+
+		res = 0;
+
+		kdata = kmalloc(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);
+
+			kfree(kdata);
+		}
+	}
+
+	DbgPrint("retCode=0x%x reply=0x%p", 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);
+			}
+		}
+	}
+
+	kfree(pages);
+	kfree(dlist);
+
+	DbgPrint("*Bytes=0x%x retCode=0x%x", *Bytes,
+		 retCode);
+
+	return (retCode);
+}
+
+/*
+ *  Arguments: HANDLE Handle - novfsd file handle
+ *             struct page *Page - Page to be written out
+ *             struct novfs_schandle SessionId - novfsd session handle
+ *
+ *  Returns:   0 - Success
+ *             -ENOSPC - Out of space on server
+ *             -EACCES - Access denied
+ *             -EIO - Any other error
+ *
+ *  Abstract:  Write page to file.
+ */
+int novfs_write_page(void *Handle, struct page *Page, struct novfs_schandle SessionId)
+{
+	struct novfs_write_file_request cmd;
+	struct novfs_write_file_reply lreply;
+	struct novfs_write_file_reply *reply = NULL;
+	unsigned long replylen = 0;
+	int retCode = 0, cmdlen;
+	struct novfs_data_list dlst[2];
+
+	DbgPrint("Handle=0x%p Page=0x%p Index=%lu SessionId=0x%llx",
+		 Handle, Page, Page->index, SessionId);
+
+	dlst[0].page = NULL;
+	dlst[0].offset = &lreply;
+	dlst[0].len = sizeof(lreply);
+	dlst[0].rwflag = DLWRITE;
+
+	dlst[1].page = Page;
+	dlst[1].offset = 0;
+	dlst[1].len = PAGE_CACHE_SIZE;
+	dlst[1].rwflag = DLREAD;
+
+	cmdlen = offsetof(struct novfs_write_file_request, data);
+
+	cmd.Command.CommandType = VFS_COMMAND_WRITE_FILE;
+	cmd.Command.SequenceNumber = 0;
+	cmd.Command.SessionId = SessionId;
+
+	cmd.handle = Handle;
+	cmd.len = PAGE_CACHE_SIZE;
+	cmd.offset = (loff_t) Page->index << PAGE_CACHE_SHIFT;;
+
+	retCode =
+	    Queue_Daemon_Command(&cmd, cmdlen, &dlst, 2, (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) {
+		kfree(reply);
+	}
+
+	DbgPrint("retCode=0x%x", retCode);
+
+	return (retCode);
+}
+
+int novfs_write_pages(void *Handle, struct novfs_data_list *DList, int DList_Cnt,
+		      size_t Bytes, loff_t Offset, struct novfs_schandle SessionId)
+{
+	struct novfs_write_file_request cmd;
+	struct novfs_write_file_reply lreply;
+	struct novfs_write_file_reply *reply = NULL;
+	unsigned long replylen = 0;
+	int retCode = 0, cmdlen;
+	size_t len;
+
+	DbgPrint("Handle=0x%p 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 = offsetof(struct novfs_write_file_request, 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) {
+			kfree(reply);
+		}
+	}
+	DbgPrint("retCode=0x%x", retCode);
+
+	return (retCode);
+}
+
+int novfs_read_stream(void *ConnHandle, unsigned char * Handle, u_char * Buffer,
+		      size_t * Bytes, loff_t * Offset, int User,
+		      struct novfs_schandle SessionId)
+{
+	struct novfs_read_stream_request cmd;
+	struct novfs_read_stream_reply *reply = NULL;
+	unsigned long replylen = 0;
+	int retCode = 0;
+	size_t len;
+
+	len = *Bytes;
+	*Bytes = 0;
+
+	if (offsetof(struct novfs_read_file_reply, data) + len
+			> novfs_max_iosize) {
+		len = novfs_max_iosize - offsetof(struct
+				novfs_read_file_reply, 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("Queue_Daemon_Command 0x%x replylen=%d", retCode, replylen);
+
+	if (reply) {
+		retCode = 0;
+		if (reply->Reply.ErrorCode) {
+			retCode = -EIO;
+		} else {
+			replylen -= offsetof(struct
+					novfs_read_stream_reply, data);
+			if (replylen > 0) {
+				if (User) {
+					replylen -=
+					    copy_to_user(Buffer, reply->data,
+							 replylen);
+				} else {
+					memcpy(Buffer, reply->data, replylen);
+				}
+
+				*Bytes = replylen;
+			}
+		}
+		kfree(reply);
+	}
+
+	DbgPrint("*Bytes=0x%x retCode=0x%x", *Bytes, retCode);
+
+	return (retCode);
+}
+
+int novfs_write_stream(void *ConnHandle, unsigned char * Handle, u_char * Buffer,
+		       size_t * Bytes, loff_t * Offset, struct novfs_schandle SessionId)
+{
+	struct novfs_write_stream_request * cmd;
+	struct novfs_write_stream_reply * reply = NULL;
+	unsigned long replylen = 0;
+	int retCode = 0, cmdlen;
+	size_t len;
+
+	len = *Bytes;
+	cmdlen = len + offsetof(struct novfs_write_stream_request, data);
+	*Bytes = 0;
+
+	if (cmdlen > novfs_max_iosize) {
+		cmdlen = novfs_max_iosize;
+		len = cmdlen - offsetof(struct
+				novfs_write_stream_request, data);
+	}
+
+	DbgPrint("cmdlen=%d len=%d", cmdlen, len);
+
+	cmd = kmalloc(cmdlen, GFP_KERNEL);
+
+	if (cmd) {
+		if (Buffer && len) {
+			len -= copy_from_user(cmd->data, Buffer, len);
+		}
+
+		DbgPrint("len=%d", 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("reply->bytesWritten=0x%lx",
+			     reply->bytesWritten);
+			*Bytes = reply->bytesWritten;
+			kfree(reply);
+		}
+		kfree(cmd);
+	}
+	DbgPrint("*Bytes=0x%x retCode=0x%x", *Bytes, retCode);
+
+	return (retCode);
+}
+
+int novfs_close_stream(void *ConnHandle, unsigned char * Handle, struct novfs_schandle SessionId)
+{
+	struct novfs_close_stream_request cmd;
+	struct novfs_close_stream_reply *reply;
+	unsigned 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;
+		}
+		kfree(reply);
+	}
+	return (retCode);
+}
+
+int novfs_delete(unsigned char * Path, int DirectoryFlag, struct novfs_schandle SessionId)
+{
+	struct novfs_delete_file_request *cmd;
+	struct novfs_delete_file_reply *reply;
+	unsigned long replylen = 0;
+	int retCode, cmdlen, pathlen;
+
+	pathlen = strlen(Path);
+
+	if (StripTrailingDots) {
+		if ('.' == Path[pathlen - 1])
+			pathlen--;
+	}
+
+	cmdlen = offsetof(struct novfs_delete_file_request, path) + pathlen;
+	cmd = kmalloc(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;
+				}
+			}
+			kfree(reply);
+		}
+		kfree(cmd);
+	} else {
+		retCode = -ENOMEM;
+	}
+	return (retCode);
+}
+
+int novfs_trunc(unsigned char * Path, int PathLen,
+		struct novfs_schandle SessionId)
+{
+	struct novfs_truncate_file_request *cmd;
+	struct novfs_truncate_file_reply *reply = NULL;
+	unsigned long replylen = 0;
+	int retCode, cmdlen;
+
+	if (StripTrailingDots) {
+		if ('.' == Path[PathLen - 1])
+			PathLen--;
+	}
+	cmdlen = offsetof(struct novfs_truncate_file_request, path)
+		+ PathLen;
+	cmd = kmalloc(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;
+			}
+			kfree(reply);
+		}
+		kfree(cmd);
+	} else {
+		retCode = -ENOMEM;
+	}
+	return (retCode);
+}
+
+int novfs_trunc_ex(void *Handle, loff_t Offset,
+		struct novfs_schandle SessionId)
+{
+	struct novfs_write_file_request cmd;
+	struct novfs_write_file_reply *reply = NULL;
+	unsigned long replylen = 0;
+	int retCode = 0, cmdlen;
+
+	DbgPrint("Handle=0x%p Offset=%lld", Handle, Offset);
+
+	cmdlen = offsetof(struct novfs_write_file_request, data);
+
+	cmd.Command.CommandType = VFS_COMMAND_WRITE_FILE;
+	cmd.Command.SequenceNumber = 0;
+	cmd.Command.SessionId = SessionId;
+	cmd.handle = Handle;
+	cmd.len = 0;
+	cmd.offset = Offset;
+
+	retCode =
+	    Queue_Daemon_Command(&cmd, cmdlen, NULL, 0, (void *)&reply,
+				 &replylen, INTERRUPTIBLE);
+
+	DbgPrint("retCode=0x%x reply=0x%p", retCode, reply);
+
+	if (!retCode) {
+		switch (reply->Reply.ErrorCode) {
+		case 0:
+			retCode = 0;
+			break;
+
+		case NWE_INSUFFICIENT_SPACE:
+			retCode = -ENOSPC;
+			break;
+
+		case NWE_ACCESS_DENIED:
+			retCode = -EACCES;
+			break;
+
+		case NWE_FILE_IO_LOCKED:
+			retCode = -EBUSY;
+			break;
+
+		default:
+			retCode = -EIO;
+			break;
+		}
+	}
+
+	if (reply) {
+		kfree(reply);
+	}
+
+	DbgPrint("retCode=%d", retCode);
+
+	return (retCode);
+}
+
+int novfs_rename_file(int DirectoryFlag, unsigned char * OldName, int OldLen,
+		      unsigned char * NewName, int NewLen,
+		      struct novfs_schandle SessionId)
+{
+	struct novfs_rename_file_request cmd;
+	struct novfs_rename_file_reply *reply;
+	unsigned long replylen = 0;
+	int retCode;
+
+	__DbgPrint("%s:\n"
+		 "   DirectoryFlag: %d\n"
+		 "   OldName:       %.*s\n"
+		 "   NewName:       %.*s\n"
+		 "   SessionId:     0x%llx\n", __func__,
+		 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;
+		}
+		kfree(reply);
+	}
+	return (retCode);
+}
+
+int novfs_set_attr(unsigned char * Path, struct iattr *Attr,
+		struct novfs_schandle SessionId)
+{
+	struct novfs_set_file_info_request *cmd;
+	struct novfs_set_file_info_reply *reply;
+	unsigned long replylen = 0;
+	int retCode, cmdlen, pathlen;
+
+	pathlen = strlen(Path);
+
+	if (StripTrailingDots) {
+		if ('.' == Path[pathlen - 1])
+			pathlen--;
+	}
+
+	cmdlen = offsetof(struct novfs_set_file_info_request,path) + pathlen;
+	cmd = kmalloc(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;
+
+			case NWE_FILE_IO_LOCKED:
+				retCode = -EBUSY;
+				break;
+
+			default:
+				retCode = -EIO;
+				break;
+			}
+			kfree(reply);
+		}
+		kfree(cmd);
+	} else {
+		retCode = -ENOMEM;
+	}
+	return (retCode);
+}
+
+int novfs_get_file_cache_flag(unsigned char * Path,
+		struct novfs_schandle SessionId)
+{
+	struct novfs_get_cache_flag *cmd;
+	struct novfs_get_cache_flag_reply *reply = NULL;
+	unsigned long replylen = 0;
+	int cmdlen;
+	int retCode = 0;
+	int pathlen;
+
+	DbgPrint("Path = %s", Path);
+
+	if (Path && *Path) {
+		pathlen = strlen(Path);
+		if (StripTrailingDots) {
+			if ('.' == Path[pathlen - 1])
+				pathlen--;
+		}
+		cmdlen = offsetof(struct novfs_get_cache_flag, path) +
+			pathlen;
+		cmd = (struct novfs_get_cache_flag *)
+			kmalloc(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;
+				}
+
+				kfree(reply);
+			}
+			kfree(cmd);
+		}
+	}
+
+	DbgPrint("return %d", retCode);
+	return (retCode);
+}
+
+/*
+ *  Arguments:
+ *      SessionId, file handle, type of lock (read/write or unlock),
+ *	    start of lock area, length of lock area
+ *
+ *  Notes: lock type - fcntl
+ */
+int novfs_set_file_lock(struct novfs_schandle SessionId, void *Handle,
+			unsigned char fl_type, loff_t fl_start, loff_t fl_len)
+{
+	struct novfs_set_file_lock_request *cmd;
+	struct novfs_set_file_lock_reply *reply = NULL;
+	unsigned long replylen = 0;
+	int retCode;
+
+	retCode = -1;
+
+	DbgPrint("SessionId:     0x%llx\n", SessionId);
+
+	cmd =
+	    (struct novfs_set_file_lock_request *) kmalloc(sizeof(struct novfs_set_file_lock_request), GFP_KERNEL);
+
+	if (cmd) {
+		DbgPrint("2");
+
+		cmd->Command.CommandType = VFS_COMMAND_SET_FILE_LOCK;
+		cmd->Command.SequenceNumber = 0;
+		cmd->Command.SessionId = SessionId;
+
+		cmd->handle = Handle;
+		if (F_RDLCK == fl_type) {
+			fl_type = 1;	// LockRegionExclusive
+		} else if (F_WRLCK == fl_type) {
+			fl_type = 0;	// LockRegionShared
+		}
+
+		cmd->fl_type = fl_type;
+		cmd->fl_start = fl_start;
+		cmd->fl_len = fl_len;
+
+		DbgPrint("3");
+
+		DbgPrint("BEGIN dump arguments");
+		DbgPrint("Queue_Daemon_Command %d",
+			 cmd->Command.CommandType);
+		DbgPrint("cmd->handle   = 0x%p", cmd->handle);
+		DbgPrint("cmd->fl_type  = %u", cmd->fl_type);
+		DbgPrint("cmd->fl_start = 0x%X", cmd->fl_start);
+		DbgPrint("cmd->fl_len   = 0x%X", cmd->fl_len);
+		DbgPrint("sizeof(SET_FILE_LOCK_REQUEST) = %u",
+		     sizeof(struct novfs_set_file_lock_request));
+		DbgPrint("END dump arguments");
+
+		retCode =
+		    Queue_Daemon_Command(cmd, sizeof(struct novfs_set_file_lock_request),
+					 NULL, 0, (void *)&reply, &replylen,
+					 INTERRUPTIBLE);
+		DbgPrint("4");
+
+		if (reply) {
+			DbgPrint("5, ErrorCode = %X", reply->Reply.ErrorCode);
+
+			if (reply->Reply.ErrorCode) {
+				retCode = reply->Reply.ErrorCode;
+			}
+			kfree(reply);
+		}
+		kfree(cmd);
+	}
+
+	DbgPrint("6");
+
+	return (retCode);
+}
--- /dev/null
+++ b/fs/novfs/inode.c
@@ -0,0 +1,4638 @@
+/*
+ * Novell NCP Redirector for Linux
+ * Author: James Turner
+ *
+ * This file contains functions used to control access to the Linux file
+ * system.
+ *
+ * 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.
+ */
+
+#include <linux/module.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 <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 <linux/mm.h>
+#include <linux/file.h>
+
+/*===[ Include files specific to this module ]============================*/
+#include "vfs.h"
+
+
+struct inode_data {
+	void *Scope;
+	unsigned long Flags;
+	struct list_head IList;
+	struct inode *Inode;
+	unsigned long cntDC;
+	struct list_head DirCache;
+	struct semaphore DirCacheLock;
+	void * FileHandle;
+	int CacheFlag;
+	char Name[1];		/* Needs to be last entry */
+};
+
+#define FILE_UPDATE_TIMEOUT   2
+
+/*===[ Function prototypes ]=============================================*/
+
+static unsigned long novfs_internal_hash(struct qstr *name);
+static int novfs_d_add(struct dentry *p, struct dentry *d, struct inode *i, int add);
+
+static int novfs_get_sb(struct file_system_type *Fstype, int Flags,
+		 const char *Dev_name, void *Data, struct vfsmount *Mnt);
+
+static void novfs_kill_sb(struct super_block *SB);
+
+
+/*
+ * 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);
+ssize_t 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_write_begin(struct file *file, struct address_space *mapping,
+			loff_t pos, unsigned len, unsigned flags,
+			struct page **pagep, void **fsdata);
+int novfs_a_write_end(struct file *file, struct address_space *mapping,
+			  loff_t pos, unsigned len, unsigned copied,
+			  struct page *pagep, void *fsdata);
+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 *, fl_owner_t);
+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_setattr(struct dentry *, struct iattr *);
+int novfs_i_getattr(struct vfsmount *mnt, struct dentry *, struct kstat *);
+int novfs_i_revalidate(struct dentry *dentry);
+
+/*
+ * Extended attributes operations
+ */
+
+ssize_t novfs_i_getxattr(struct dentry *dentry, const char *name, void *buffer,
+		     size_t size);
+int novfs_i_setxattr(struct dentry *dentry, const char *name, const void *value,
+		     size_t value_size, int flags);
+ssize_t novfs_i_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size);
+
+void update_inode(struct inode *Inode, struct novfs_entry_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 dentry *de, 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, struct novfs_entry_info *info);
+int novfs_get_entry(struct inode *i, struct qstr *name, ino_t * ino,
+		    struct novfs_entry_info *info);
+int novfs_get_entry_by_pos(struct inode *i, loff_t pos, ino_t * ino,
+			   struct novfs_entry_info *info);
+int novfs_get_entry_time(struct inode *i, struct qstr *name, ino_t * ino,
+			 struct novfs_entry_info *info, u64 * EntryTime);
+int novfs_get_remove_entry(struct inode *i, ino_t * ino, struct novfs_entry_info *info);
+void novfs_invalidate_inode_cache(struct inode *i);
+struct novfs_dir_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,
+			  struct novfs_entry_info *info);
+int novfs_update_entry(struct inode *i, struct qstr *name, ino_t ino,
+		       struct novfs_entry_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,
+	.lock = novfs_f_lock,
+};
+
+static struct address_space_operations novfs_nocache_aops = {
+	.readpage = novfs_a_readpage,
+};
+
+struct backing_dev_info novfs_backing_dev_info = {
+	.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE,
+	.state = 0,
+	.capabilities = BDI_CAP_NO_WRITEBACK | BDI_CAP_MAP_COPY,
+	.unplug_io_fn = default_unplug_io_fn,
+};
+
+static struct address_space_operations novfs_aops = {
+	.readpage = novfs_a_readpage,
+	.readpages = novfs_a_readpages,
+	.writepage = novfs_a_writepage,
+	.writepages = novfs_a_writepages,
+	.write_begin = novfs_a_write_begin,
+	.write_end = novfs_a_write_end,
+	.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,
+	.getxattr = novfs_i_getxattr,
+	.setxattr = novfs_i_setxattr,
+	.listxattr = novfs_i_listxattr,
+};
+
+static struct inode_operations novfs_file_inode_operations = {
+	.setattr = novfs_i_setattr,
+	.getattr = novfs_i_getattr,
+	.getxattr = novfs_i_getxattr,
+	.setxattr = novfs_i_setxattr,
+	.listxattr = novfs_i_listxattr,
+};
+
+static struct super_operations novfs_ops = {
+	.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,
+};
+*/
+
+static atomic_t novfs_Inode_Number = ATOMIC_INIT(0);
+
+
+struct dentry *novfs_root = NULL;
+char *novfs_current_mnt = NULL;
+
+DECLARE_MUTEX(InodeList_lock);
+
+LIST_HEAD(InodeList);
+
+DECLARE_MUTEX(TimeDir_Lock);
+uint64_t lastTime;
+char lastDir[PATH_MAX];
+
+uint64_t inHAXTime;
+int inHAX;
+
+unsigned long InodeCount = 0, DCCount = 0;
+unsigned long novfs_update_timeout = FILE_UPDATE_TIMEOUT;
+int novfs_page_cache = 0;
+
+struct file_private {
+	int listedall;
+	void *enumHandle;
+};
+
+static void PRINT_DENTRY(const char *s, struct dentry *d)
+{
+	__DbgPrint("%s: 0x%p\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%p\n"
+		   "      next:      0x%p\n"
+		   "      prev:      0x%p\n", &d->d_lru, d->d_lru.next,
+		   d->d_lru.prev);
+	__DbgPrint("   d_child:      0x%p\n" "      next:      0x%p\n"
+		   "      prev:      0x%p\n", &d->d_u.d_child,
+		   d->d_u.d_child.next, d->d_u.d_child.prev);
+	__DbgPrint("   d_subdirs:    0x%p\n" "      next:      0x%p\n"
+		   "      prev:      0x%p\n", &d->d_subdirs, d->d_subdirs.next,
+		   d->d_subdirs.prev);
+	__DbgPrint("   d_alias:      0x%p\n" "      next:      0x%p\n"
+		   "      prev:      0x%p\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%p\n", d->d_op);
+	__DbgPrint("   d_sb:         0x%p\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%p\n", d->d_fsdata);
+/*   DbgPrint("   d_cookie:     0x%x\n", d->d_cookie); */
+	__DbgPrint("   d_parent:     0x%p\n", d->d_parent);
+	__DbgPrint("   d_name:       0x%p %.*s\n", &d->d_name, d->d_name.len,
+		   d->d_name.name);
+	__DbgPrint("      name:      0x%p\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)
+{
+	struct qstr name;
+	struct dentry *dentry;
+	struct inode *dir;
+
+	DbgPrint("%s", 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->i_private) {
+			struct inode_data *n_inode =
+				dentry->d_inode->i_private;
+			n_inode->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)
+{
+	struct qstr name;
+	struct inode *dir;
+	struct novfs_entry_info info;
+	ino_t ino;
+
+	DbgPrint("%s", 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)atomic_inc_return(&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)
+{
+	struct dentry *entry;
+	struct qstr name;
+	struct inode *inode;
+	void *scope;
+
+	DbgPrint("%s", AddName);
+	name.len = strlen(AddName);
+	name.name = AddName;
+
+	novfs_d_hash(novfs_root, &name);
+
+	entry = d_lookup(novfs_root, &name);
+	DbgPrint("novfs_d_lookup 0x%p", entry);
+	if (NULL == entry) {
+		scope = novfs_scope_lookup();
+
+		entry = d_alloc(novfs_root, &name);
+		DbgPrint("d_alloc 0x%p", entry);
+		if (entry) {
+			entry->d_op = &novfs_dentry_operations;
+			entry->d_time = jiffies + (novfs_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, novfs_scope_get_uid(scope), 0, &name);
+			DbgPrint("Inode=0x%p", 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->i_private) {
+						struct inode_data *n_inode = inode->i_private;
+						n_inode->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)
+{
+	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("%s", retval);
+	return (retval);
+}
+
+int verify_dentry(struct dentry *dentry, int Flags)
+{
+	int retVal = -ENOENT;
+	struct inode *dir;
+	struct novfs_entry_info *info = NULL;
+	struct inode_data *id;
+	struct novfs_schandle session;
+	char *path, *list = NULL, *cp;
+	ino_t ino = 0;
+	struct qstr name;
+	int iLock = 0;
+	struct dentry *parent = NULL;
+	u64 ctime;
+	struct inode *inode;
+
+	if (IS_ROOT(dentry)) {
+		DbgPrint("Root entry");
+		return (0);
+	}
+
+	if (dentry && dentry->d_parent &&
+	    (dir = dentry->d_parent->d_inode) && (id = dir->i_private)) {
+		parent = dget_parent(dentry);
+
+		info = kmalloc(sizeof(struct novfs_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_private &&
+					    ((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.
+						 */
+						struct inode_data *n_inode = inode->i_private;
+						n_inode->Flags |= UPDATE_INODE;
+					}
+
+					ctime = get_jiffies_64() - ctime;
+					if (Flags || ctime < (u64) (novfs_update_timeout * HZ)) {
+						retVal = 0;
+						novfs_unlock_inode_cache(dir);
+						dput(parent);
+						kfree(info);
+						return (0);
+					}
+				}
+				novfs_unlock_inode_cache(dir);
+			}
+
+			if (IS_ROOT(dentry->d_parent)) {
+				session =	novfs_scope_get_sessionId(
+				novfs_get_scope_from_name(&dentry->d_name));
+			} else
+				session = novfs_scope_get_sessionId(id->Scope);
+
+			if (!SC_PRESENT(session)) {
+				id->Scope = novfs_get_scope(dentry);
+				session = novfs_scope_get_sessionId(id->Scope);
+			}
+
+			ino = 0;
+			retVal = 0;
+
+			if (IS_ROOT(dentry->d_parent)) {
+				DbgPrint("parent is Root directory");
+				list = novfs_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)atomic_inc_return(&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 +
+							    (novfs_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)atomic_inc_return(&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->
+								    i_private) {
+									((struct inode_data *) dentry->d_inode->i_private)->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)
+		kfree(list);
+	if (info)
+		kfree(info);
+
+	DbgPrint("return=0x%x", retVal);
+
+	return (retVal);
+}
+
+
+static int novfs_d_add(struct dentry *Parent, struct dentry *d, struct inode *i, int a)
+{
+	void *scope;
+	struct inode_data *id = NULL;
+
+	char *path, *buf;
+
+	buf = kmalloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+	if (buf) {
+		path = novfs_dget_path(d, buf, PATH_LENGTH_BUFFER);
+		if (path) {
+			DbgPrint("inode=0x%p ino=%d path %s", i,
+				 i->i_ino, path);
+		}
+		kfree(buf);
+	}
+
+	if (Parent && Parent->d_inode && Parent->d_inode->i_private) {
+		id = (struct inode_data *) Parent->d_inode->i_private;
+	}
+
+	if (id && id->Scope) {
+		scope = id->Scope;
+	} else {
+		scope = novfs_get_scope(d);
+	}
+
+	((struct inode_data *) i->i_private)->Scope = scope;
+
+	d->d_time = jiffies + (novfs_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)
+{
+	int retCode = 0;
+	struct inode *dir;
+	struct inode_data *id;
+	struct qstr name;
+
+	__DbgPrint("%s: 0x%p %.*s\n"
+		   "   d_count: %d\n"
+		   "   d_inode: 0x%p\n", __func__,
+		 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->i_private)) {
+			/*
+			 * 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 +
+							    (novfs_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("return 0x%x %.*s", retCode,
+		 dentry->d_name.len, dentry->d_name.name);
+
+	return (retCode);
+}
+
+static unsigned long novfs_internal_hash(struct qstr *name)
+{
+	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)
+{
+	DbgPrint("%.*s", name->len, name->name);
+
+	name->hash = novfs_internal_hash(name);
+
+	return (0);
+}
+
+int novfs_d_strcmp(struct qstr *s1, struct qstr *s2)
+{
+	int retCode = 1;
+	unsigned char *str1, *str2;
+	unsigned int len;
+
+	DbgPrint("s1=%.*s s2=%.*s", 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("retCode=0x%x", retCode);
+	return (retCode);
+}
+
+int novfs_d_compare(struct dentry *parent, struct qstr *s1, struct qstr *s2)
+{
+	int retCode;
+
+	retCode = novfs_d_strcmp(s1, s2);
+
+	DbgPrint("retCode=0x%x", retCode);
+	return (retCode);
+}
+
+int novfs_d_delete(struct dentry *dentry)
+{
+	int retVal = 0;
+
+	DbgPrint("0x%p %.*s; d_count: %d; d_inode: 0x%p",
+		 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)
+{
+	DbgPrint("0x%p %.*s", dentry, dentry->d_name.len,
+		 dentry->d_name.name);
+}
+
+void novfs_d_iput(struct dentry *dentry, struct inode *inode)
+{
+	DbgPrint("Inode=0x%p Ino=%d Dentry=0x%p i_state=%d Name=%.*s",
+	     inode, inode->i_ino, dentry, inode->i_state, dentry->d_name.len,
+	     dentry->d_name.name);
+
+	iput(inode);
+
+}
+
+int novfs_dir_open(struct inode *dir, struct file *file)
+{
+	char *path, *buf;
+	struct file_private *file_private = NULL;
+
+	DbgPrint("Inode 0x%p %d Name %.*s", dir, dir->i_ino,
+		 file->f_dentry->d_name.len, file->f_dentry->d_name.name);
+
+	buf = kmalloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+	if (buf) {
+		path = novfs_dget_path(file->f_dentry, buf, PATH_LENGTH_BUFFER);
+		if (path) {
+			DbgPrint("path %s", path);
+		}
+		kfree(buf);
+	}
+
+	file_private = kmalloc(sizeof(struct file_private), GFP_KERNEL);
+	file_private->listedall = 0;
+	file_private->enumHandle = NULL;
+
+	file->private_data = file_private;
+
+	return (0);
+}
+
+int novfs_dir_release(struct inode *dir, struct file *file)
+{
+	struct file_private *file_private = file->private_data;
+	struct inode *inode = file->f_dentry->d_inode;
+	struct novfs_schandle sessionId;
+
+	DbgPrint("Inode 0x%p %d Name %.*s", dir, dir->i_ino,
+		 file->f_dentry->d_name.len, file->f_dentry->d_name.name);
+
+	if (file_private) {
+		if (file_private->enumHandle && (file_private->enumHandle != ((void *)-1))) {
+			sessionId = novfs_scope_get_sessionId(((struct inode_data *)inode->i_private)->Scope);
+			if (SC_PRESENT(sessionId) == 0) {
+				((struct inode_data *)inode->i_private)->Scope = novfs_get_scope(file->f_dentry);
+				sessionId = novfs_scope_get_sessionId(((struct inode_data *)inode->i_private)->Scope);
+			}
+			novfs_end_directory_enumerate(file_private->enumHandle, sessionId);
+		}
+		kfree(file_private);
+		file->private_data = NULL;
+	}
+
+	return (0);
+}
+
+loff_t novfs_dir_lseek(struct file * file, loff_t offset, int origin)
+{
+	struct file_private *file_private = NULL;
+
+	DbgPrint("offset %lld %d Name %.*s", offset, origin,
+		 file->f_dentry->d_name.len, file->f_dentry->d_name.name);
+	//printk("<1> seekdir file = %.*s offset = %i\n", file->f_dentry->d_name.len, file->f_dentry->d_name.name, (int)offset);
+
+	if (0 != offset) {
+		return -ESPIPE;
+	}
+
+	file->f_pos = 0;
+
+	file_private = (struct file_private *) file->private_data;
+	file_private->listedall = 0;
+	if (file_private->enumHandle && (file_private->enumHandle != ((void *)-1))) {
+		struct novfs_schandle sessionId;
+		struct inode *inode = file->f_dentry->d_inode;
+		sessionId = novfs_scope_get_sessionId(((struct inode_data *)inode->i_private)->Scope);
+		if (SC_PRESENT(sessionId) == 0) {
+			((struct inode_data *)inode->i_private)->Scope = novfs_get_scope(file->f_dentry);
+			sessionId = novfs_scope_get_sessionId(((struct inode_data *)inode->i_private)->Scope);
+		}
+		novfs_end_directory_enumerate(file_private->enumHandle, sessionId);
+	}
+	file_private->enumHandle = NULL;
+
+	return 0;
+	//return(default_llseek(file, offset, origin));
+}
+
+ssize_t novfs_dir_read(struct file * file, char *buf, size_t len, loff_t * off)
+{
+/*
+   int rlen = 0;
+
+   DbgPrint("dentry path %.*s buf=0x%p len=%d off=%lld", 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);
+*/
+	DbgPrint("%lld %d Name %.*s", *off, len,
+		 file->f_dentry->d_name.len, file->f_dentry->d_name.name);
+	return (generic_read_dir(file, buf, len, off));
+}
+
+static void novfs_Dump_Info(struct novfs_entry_info *info)
+{
+	char atime_buf[32], mtime_buf[32], ctime_buf[32];
+	char namebuf[512];
+	int len = 0;
+
+	if (info == NULL) {
+		DbgPrint("Dump_Info info == NULL");
+		return;
+	}
+
+	if (info->namelength >= 512) {
+		len = 511;
+	} else {
+		len = info->namelength;
+	}
+
+	memcpy(namebuf, info->name, len);
+	namebuf[len] = '\0';
+
+	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("type = %i", info->type);
+	DbgPrint("mode = %x", info->mode);
+	DbgPrint("uid = %d", info->uid);
+	DbgPrint("gid = %d", info->gid);
+	DbgPrint("size = %i", info->size);
+	DbgPrint("atime = %s", atime_buf);
+	DbgPrint("mtime = %s", mtime_buf);
+	DbgPrint("ctime = %s", ctime_buf);
+	DbgPrint("namelength = %i", info->namelength);
+	DbgPrint("name = %s", namebuf);
+}
+
+void processList(struct file *file, void *dirent, filldir_t filldir, char *list,
+		 int type, struct novfs_schandle SessionId)
+{
+	unsigned char *path, *buf = NULL, *cp;
+	struct qstr name;
+	struct novfs_entry_info *pinfo = NULL;
+
+	buf = kmalloc(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;
+			DbgPrint("name.name = %s", name.name);
+			name.len = strlen(cp);
+			name.hash = novfs_internal_hash(&name);
+			cp += (name.len + 1);
+
+			pinfo =
+			    kmalloc(sizeof(struct novfs_entry_info) +
+					 PATH_LENGTH_BUFFER, GFP_KERNEL);
+			pinfo->mode = S_IFDIR | 0700;
+			pinfo->size = 0;
+			pinfo->atime = pinfo->ctime = pinfo->mtime =
+			    CURRENT_TIME;
+			strcpy(pinfo->name, name.name);
+			pinfo->namelength = name.len;
+
+			novfs_Dump_Info(pinfo);
+
+			filldir(dirent, pinfo->name, pinfo->namelength,
+				file->f_pos, file->f_pos, pinfo->mode >> 12);
+			file->f_pos += 1;
+
+			kfree(pinfo);
+		}
+	}
+
+	if (buf) {
+		kfree(buf);
+	}
+}
+
+int processEntries(struct file *file, void *dirent, filldir_t filldir,
+		   void ** enumHandle, struct novfs_schandle sessionId)
+{
+	unsigned char *path = NULL, *buf = NULL;
+	int count = 0, status = 0;
+	struct novfs_entry_info *pinfo = NULL;
+	struct novfs_entry_info *pInfoMem = NULL;
+
+	buf = kmalloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+	if (!buf) {
+		return -ENOMEM;
+	}
+
+	path = novfs_dget_path(file->f_dentry, buf, PATH_LENGTH_BUFFER);
+	if (!path) {
+		kfree(buf);
+		return -ENOMEM;
+	}
+	//NWSearchfiles
+	count = 0;
+	status =
+	    novfs_get_dir_listex(path, enumHandle, &count, &pinfo,
+				       sessionId);
+	pInfoMem = pinfo;
+
+	if ((count == -1) || (count == 0) || (status != 0)) {
+		kfree(pInfoMem);
+		kfree(buf);
+		return -1;
+	}
+	// parse resultset
+	while (pinfo && count--) {
+		filldir(dirent, pinfo->name, pinfo->namelength, file->f_pos,
+			file->f_pos, pinfo->mode >> 12);
+		file->f_pos += 1;
+
+		pinfo = (struct novfs_entry_info *) (pinfo->name + pinfo->namelength);
+	}
+
+	kfree(pInfoMem);
+	kfree(buf);
+	return 0;
+}
+
+int novfs_dir_readdir(struct file *file, void *dirent, filldir_t filldir)
+{
+	unsigned char *list = NULL;
+	int status = 0;		//-ENOMEM;
+	struct inode *inode = file->f_dentry->d_inode;
+	struct novfs_schandle sessionId;
+	uid_t uid;
+	int type = 0;
+	struct file_private *file_private = NULL;
+	int lComm;
+
+	file_private = (struct file_private *) file->private_data;
+	DbgPrint("Name %.*s", file->f_dentry->d_name.len,
+		 file->f_dentry->d_name.name);
+
+	//printk("<1> file = %.*s\n", file->f_dentry->d_name.len, file->f_dentry->d_name.name);
+
+// Use this hack by default
+#ifndef SKIP_CROSSOVER_HACK
+	// Hack for crossover - begin
+	down(&TimeDir_Lock);
+	if ((file->f_dentry->d_name.len == 7) &&
+	    ((0 == strncmp(file->f_dentry->d_name.name, " !xover", 7)) ||
+	     (0 == strncmp(file->f_dentry->d_name.name, "z!xover", 7)))) {
+		//printk("<1> xoverhack: we are in xoverHack\n");
+
+		inHAX = 1;
+		inHAXTime = get_nanosecond_time();
+		//up( &TimeDir_Lock );
+		//return 0;
+		file_private->listedall = 1;
+	} else {
+		if (inHAX) {
+			if (get_nanosecond_time() - inHAXTime >
+			    100 * 1000 * 1000) {
+				//printk("<1> xoverhack: it was long, long, long ago...\n");
+				inHAX = 0;
+			} else {
+				//printk("<1> xoverhack: word gotcha in xoverHack...\n");
+				inHAXTime = get_nanosecond_time();
+				//up( &TimeDir_Lock );
+				//return 0;
+				file_private->listedall = 1;
+			}
+		}
+	}
+
+	up(&TimeDir_Lock);
+	// Hack for crossover - end
+#endif
+
+	if (file->f_pos == 0) {
+		if (filldir(dirent, ".", 1, file->f_pos, inode->i_ino, DT_DIR) <
+		    0)
+			return 1;
+		file->f_pos++;
+		return 1;
+	}
+
+	if (file->f_pos == 1) {
+		if (filldir
+		    (dirent, "..", 2, file->f_pos,
+		     file->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0)
+			return 1;
+		file->f_pos++;
+		return 1;
+	}
+
+	if (file_private->listedall != 0) {
+		return 0;
+	}
+
+	inode = file->f_dentry->d_inode;
+	if (inode && inode->i_private) {
+		sessionId =
+		    novfs_scope_get_sessionId(((struct inode_data *) inode->i_private)->
+					Scope);
+		if (0 == SC_PRESENT(sessionId)) {
+			((struct inode_data *) inode->i_private)->Scope =
+			    novfs_get_scope(file->f_dentry);
+			sessionId =
+			    novfs_scope_get_sessionId(((struct inode_data *) inode->
+						 i_private)->Scope);
+		}
+		uid = novfs_scope_get_uid(((struct inode_data *) inode->i_private)->Scope);
+	} else {
+		SC_INITIALIZE(sessionId);
+		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("Root directory");
+			list = novfs_get_scopeusers();
+			type = USER_LIST;
+		} else if (IS_ROOT(file->f_dentry->d_parent)) {
+			DbgPrint("Parent is Root directory");
+			novfs_get_servers(&list, sessionId);
+			type = SERVER_LIST;
+		} else {
+			DbgPrint("Parent-Parent is Root directory");
+			novfs_get_vols(&file->f_dentry->d_name,
+						     &list, sessionId);
+			type = VOLUME_LIST;
+		}
+
+		processList(file, dirent, filldir, list, type, sessionId);
+		file_private->listedall = 1;
+	} else {
+		status =
+		    processEntries(file, dirent, filldir,
+				   &file_private->enumHandle, sessionId);
+
+		if (status != 0) {
+			file_private->listedall = 1;
+#ifndef SKIP_CROSSOVER_HACK
+			// Hack for crossover part 2 - begin
+			lComm = strlen(current->comm);
+			if ((lComm > 4)
+			    && (0 ==
+				strcmp(current->comm + lComm - 4, ".EXE"))) {
+				if (filldir
+				    (dirent, " !xover", 7, file->f_pos,
+				     inode->i_ino, DT_DIR) < 0)
+					return 1;
+				if (filldir
+				    (dirent, "z!xover", 7, file->f_pos,
+				     inode->i_ino, DT_DIR) < 0)
+					return 1;
+				file->f_pos += 2;
+			}
+			// Hack for crossover part2 - end
+#endif
+		}
+	}
+
+	file->private_data = file_private;
+	return 1;
+}
+
+int novfs_dir_fsync(struct file *file, struct dentry *dentry, int datasync)
+{
+	DbgPrint("Name %.*s", file->f_dentry->d_name.len,
+		 file->f_dentry->d_name.name);
+	return (simple_sync_file(file, dentry, datasync));
+}
+
+ssize_t novfs_f_read(struct file * file, char *buf, size_t len, loff_t * off)
+{
+	size_t thisread, totalread = 0;
+	loff_t offset = *off;
+	struct inode *inode;
+	struct novfs_schandle session;
+	struct inode_data *id;
+
+	if (file->f_dentry &&
+	    (inode = file->f_dentry->d_inode) &&
+	    (id = (struct inode_data *) inode->i_private)) {
+
+		DbgPrint("(0x%p 0x%p %d %lld %.*s)",
+			 file->private_data,
+			 buf, len, offset,
+			 file->f_dentry->d_name.len,
+			 file->f_dentry->d_name.name);
+
+		if (novfs_page_cache && !(file->f_flags & O_DIRECT) && id->CacheFlag) {
+			totalread = do_sync_read(file, buf, len, off);
+		} else {
+			session = novfs_scope_get_sessionId(id->Scope);
+			if (0 == SC_PRESENT(session)) {
+				id->Scope =
+				    novfs_get_scope(file->f_dentry);
+				session = novfs_scope_get_sessionId(id->Scope);
+			}
+
+			while (len > 0 && (offset < i_size_read(inode))) {
+				int retval;
+				thisread = len;
+				retval =
+				    novfs_read_file(file->private_data, buf,
+						    &thisread, &offset,
+						    session);
+				if (retval || !thisread) {
+					if (retval) {
+						totalread = retval;
+					}
+					break;
+				}
+				DbgPrint("thisread = 0x%x", thisread);
+				len -= thisread;
+				buf += thisread;
+				offset += thisread;
+				totalread += thisread;
+			}
+			*off = offset;
+		}
+	}
+	DbgPrint("return = %d", totalread);
+
+	return (totalread);
+}
+
+ssize_t novfs_f_write(struct file * file, const char *buf, size_t len,
+		      loff_t * off)
+{
+	ssize_t thiswrite, totalwrite = 0;
+	loff_t offset = *off;
+	struct novfs_schandle session;
+	struct inode *inode;
+	int status;
+	struct inode_data *id;
+
+	if (file->f_dentry &&
+	    (inode = file->f_dentry->d_inode) &&
+	    (id = file->f_dentry->d_inode->i_private)) {
+		DbgPrint("(0x%p 0x%p 0x%p %d %lld %.*s)",
+			 file->private_data, inode, id->FileHandle, len, offset,
+			 file->f_dentry->d_name.len,
+			 file->f_dentry->d_name.name);
+
+		if (novfs_page_cache &&
+		    !(file->f_flags & O_DIRECT) &&
+		    id->CacheFlag && !(file->f_flags & O_WRONLY)) {
+			totalwrite = do_sync_write(file, buf, len, off);
+		} else {
+			if (file->f_flags & O_APPEND) {
+				offset = i_size_read(inode);
+				DbgPrint("appending to end %lld %.*s",
+				     offset, file->f_dentry->d_name.len,
+				     file->f_dentry->d_name.name);
+			}
+
+			session = novfs_scope_get_sessionId(id->Scope);
+			if (0 == SC_PRESENT(session)) {
+				id->Scope =
+				    novfs_get_scope(file->f_dentry);
+				session = novfs_scope_get_sessionId(id->Scope);
+			}
+
+			while (len > 0) {
+				thiswrite = len;
+				if ((status =
+				     novfs_write_file(file->private_data,
+						      (unsigned char *)buf,
+						      &thiswrite, &offset,
+						      session)) || !thiswrite) {
+					totalwrite = status;
+					break;
+				}
+				DbgPrint("thiswrite = 0x%x",
+					 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_sb->s_blocksize -
+					     1) >> inode->i_blkbits;
+				}
+				inode->i_mtime = inode->i_atime = CURRENT_TIME;
+				id->Flags |= UPDATE_INODE;
+
+			}
+			*off = offset;
+		}
+	}
+	DbgPrint("return = 0x%x", totalwrite);
+
+	return (totalwrite);
+}
+
+int novfs_f_readdir(struct file *file, void *data, filldir_t fill)
+{
+	return -EISDIR;
+}
+
+int novfs_f_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+		  unsigned long arg)
+{
+	DbgPrint("file=0x%p cmd=0x%x arg=0x%p", file, cmd, arg);
+
+	return -ENOSYS;
+}
+
+int novfs_f_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	int retCode = -EINVAL;
+
+	DbgPrint("file=0x%p %.*s", file, file->f_dentry->d_name.len,
+		 file->f_dentry->d_name.name);
+
+	retCode = generic_file_mmap(file, vma);
+
+	DbgPrint("retCode=0x%x", retCode);
+	return (retCode);
+}
+
+int novfs_f_open(struct inode *inode, struct file *file)
+{
+	struct novfs_entry_info *info = NULL;
+	int retCode = -ENOENT;
+	struct novfs_schandle session;
+	char *path;
+	struct dentry *parent;
+	ino_t ino;
+	struct inode_data *id;
+	int errInfo;
+
+	DbgPrint("inode=0x%p file=0x%p dentry=0x%p dentry->d_inode=0x%p %.*s",
+		 inode, file, file->f_dentry, file->f_dentry->d_inode,
+	     file->f_dentry->d_name.len, file->f_dentry->d_name.name);
+	if (file->f_dentry) {
+		DbgPrint("%.*s f_flags=0%o f_mode=0%o i_mode=0%o",
+			 file->f_dentry->d_name.len,
+			 file->f_dentry->d_name.name,
+			 file->f_flags, file->f_mode, inode->i_mode);
+	}
+
+	if (inode && inode->i_private) {
+		id = (struct inode_data *) file->f_dentry->d_inode->i_private;
+		session = novfs_scope_get_sessionId(id->Scope);
+		if (0 == SC_PRESENT(session)) {
+			id->Scope = novfs_get_scope(file->f_dentry);
+			session = novfs_scope_get_sessionId(id->Scope);
+		}
+
+		info = kmalloc(sizeof(struct novfs_entry_info) +
+					       PATH_LENGTH_BUFFER, GFP_KERNEL);
+		if (info) {
+			path =
+			    novfs_dget_path(file->f_dentry, info->name,
+					    PATH_LENGTH_BUFFER);
+			if (path) {
+				if (file->f_flags & O_TRUNC) {
+					errInfo =
+					    novfs_get_file_info(path, info,
+								session);
+
+					if (errInfo || info->size == 0) {
+						// clear O_TRUNC flag, bug #275366
+						file->f_flags =
+						    file->f_flags & (~O_TRUNC);
+					}
+				}
+
+				DbgPrint("%s", path);
+				retCode = novfs_open_file(path,
+							  file->
+							  f_flags & ~O_EXCL,
+							  info,
+							  &file->private_data,
+							  session);
+
+				DbgPrint("0x%x 0x%p", retCode,
+					 file->private_data);
+				if (!retCode) {
+					/*
+					 *update_inode(inode, &info);
+					 */
+					//id->FileHandle = 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)) {
+							((struct inode_data *) inode->
+							 i_private)->Flags |=
+				       UPDATE_INODE;
+						}
+
+						novfs_unlock_inode_cache(dir);
+					}
+					dput(parent);
+				}
+			}
+			kfree(info);
+		}
+	}
+	DbgPrint("retCode=0x%x", retCode);
+	return (retCode);
+}
+
+int novfs_flush_mapping(void *Handle, struct address_space *mapping,
+			struct novfs_schandle Session)
+{
+	struct pagevec pagevec;
+	unsigned nrpages;
+	pgoff_t index = 0;
+	int done, rc = 0;
+
+	pagevec_init(&pagevec, 0);
+
+	do {
+		done = 1;
+		nrpages = pagevec_lookup_tag(&pagevec,
+					     mapping,
+					     &index,
+					     PAGECACHE_TAG_DIRTY, PAGEVEC_SIZE);
+
+		if (nrpages) {
+			struct page *page;
+			int i;
+
+			DbgPrint("%u", nrpages);
+
+			done = 0;
+			for (i = 0; !rc && (i < nrpages); i++) {
+				page = pagevec.pages[i];
+
+				DbgPrint("page 0x%p %lu", page, page->index);
+
+				lock_page(page);
+				page_cache_get(page);
+				if (page->mapping == mapping) {
+					if (clear_page_dirty_for_io(page)) {
+						rc = novfs_write_page(Handle,
+								      page,
+								      Session);
+						if (!rc) {
+							//ClearPageDirty(page);
+							radix_tree_tag_clear
+							    (&mapping->
+							     page_tree,
+							     page_index(page),
+							     PAGECACHE_TAG_DIRTY);
+						}
+					}
+				}
+
+				page_cache_release(page);
+				unlock_page(page);
+			}
+			pagevec_release(&pagevec);
+		}
+	} while (!rc && !done);
+
+	DbgPrint("return %d", rc);
+
+	return (rc);
+}
+
+int novfs_f_flush(struct file *file, fl_owner_t ownid)
+{
+
+	int rc = 0;
+#ifdef FLUSH
+	struct inode *inode;
+	struct novfs_schandle session;
+	struct inode_data *id;
+
+	DbgPrint("Called from 0x%p", __builtin_return_address(0));
+	if (file->f_dentry && (inode = file->f_dentry->d_inode)
+	    && (id = file->f_dentry->d_inode->i_private)) {
+
+		if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
+			inode = file->f_dentry->d_inode;
+			DbgPrint("%.*s f_flags=0%o f_mode=0%o i_mode=0%o",
+				 file->f_dentry->d_name.len,
+				 file->f_dentry->d_name.name, file->f_flags,
+				 file->f_mode, inode->i_mode);
+
+			session = novfs_scope_get_sessionId(id->Scope);
+			if (0 == SC_PRESENT(session)) {
+				id->Scope =
+				    novfs_get_scope(file->f_dentry);
+				session = novfs_scope_get_sessionId(id->Scope);
+			}
+
+			if (inode &&
+			    inode->i_mapping && inode->i_mapping->nrpages) {
+
+				DbgPrint("%.*s pages=%lu",
+					 file->f_dentry->d_name.len,
+					 file->f_dentry->d_name.name,
+					 inode->i_mapping->nrpages);
+
+				if (file->f_dentry &&
+				    file->f_dentry->d_inode &&
+				    file->f_dentry->d_inode->i_mapping &&
+				    file->f_dentry->d_inode->i_mapping->a_ops &&
+				    file->f_dentry->d_inode->i_mapping->a_ops->
+				    writepage) {
+					rc = filemap_fdatawrite(file->f_dentry->
+								d_inode->
+								i_mapping);
+				} else {
+					rc = novfs_flush_mapping(file->
+								 private_data,
+								 file->
+								 f_dentry->
+								 d_inode->
+								 i_mapping,
+								 session);
+				}
+			}
+		}
+	}
+#endif
+	return (rc);
+}
+
+int novfs_f_release(struct inode *inode, struct file *file)
+{
+	int retCode = -EACCES;
+	struct novfs_schandle session;
+	struct inode_data *id;
+
+	DbgPrint("path=%.*s handle=%p",
+		 file->f_dentry->d_name.len,
+		 file->f_dentry->d_name.name, file->private_data);
+
+	if (inode && (id = inode->i_private)) {
+		session = novfs_scope_get_sessionId(id->Scope);
+		if (0 == SC_PRESENT(session)) {
+			id->Scope = novfs_get_scope(file->f_dentry);
+			session = novfs_scope_get_sessionId(id->Scope);
+		}
+
+		if ((file->f_flags & O_ACCMODE) != O_RDONLY) {
+			DbgPrint("%.*s f_flags=0%o f_mode=0%o i_mode=0%o",
+			     file->f_dentry->d_name.len,
+			     file->f_dentry->d_name.name, file->f_flags,
+			     file->f_mode, inode->i_mode);
+
+			if (inode->i_mapping && inode->i_mapping->nrpages) {
+
+				DbgPrint("%.*s pages=%lu",
+					 file->f_dentry->d_name.len,
+					 file->f_dentry->d_name.name,
+					 inode->i_mapping->nrpages);
+
+				if (inode->i_mapping->a_ops &&
+				    inode->i_mapping->a_ops->writepage) {
+					filemap_fdatawrite(file->f_dentry->
+							   d_inode->i_mapping);
+				} else {
+					novfs_flush_mapping(file->private_data,
+							    file->f_dentry->
+							    d_inode->i_mapping,
+							    session);
+				}
+			}
+		}
+
+		if (file->f_dentry && file->f_dentry->d_inode) {
+			invalidate_remote_inode(file->f_dentry->d_inode);
+		}
+
+		retCode = novfs_close_file(file->private_data, session);
+		//id->FileHandle = 0;
+	}
+	return (retCode);
+}
+
+int novfs_f_fsync(struct file *file, struct dentry *dentry, int datasync)
+{
+	return 0;
+}
+
+int novfs_f_llseek(struct file *file, loff_t offset, int origin)
+{
+	DbgPrint("File=0x%p Name=%.*s offset=%lld origin=%d",
+		 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:
+ *      "file" - pointer to file structure - contains file handle in "file->private_data"
+ *
+ *      "cmd" could be F_SETLK, F_SETLKW, F_GETLK
+ *      F_SETLK/F_SETLKW are for setting/unsetting file lock
+ *      F_GETLK is for getting infomation about region - is it locked, or not
+ *
+ *      "lock" structure - contains "start" and "end" of locking region
+ *
+ *  Returns:
+ *      0 on success
+ *      -ENOSYS on F_GETLK cmd. It's not implemented.
+ *      -EINVAL if (lock->fl_start > lock->fl_end)
+ *      -EAGAIN on all other errors
+ *  Abstract:
+ *
+ *  Notes:
+ *      "lock->fl_start" and "lock->fl_end" are of type "long long",
+ *      but xtier functions in novfsd "NCFsdLockFile" and "NCFsdUnlockFile"
+ *      receive arguments in u64 type.
+ *
+ *
+ *========================================================================*/
+{
+	int err_code;
+
+	struct inode *inode;
+	struct novfs_schandle session;
+	struct inode_data *id;
+	loff_t len;
+
+	DbgPrint("(0x%p): begin in novfs_f_lock 0x%p",
+		 __builtin_return_address(0), file->private_data);
+	DbgPrint("cmd = %d, F_GETLK = %d, F_SETLK = %d, F_SETLKW = %d",
+		 cmd, F_GETLK, F_SETLK, F_SETLKW);
+	DbgPrint("lock->fl_start = 0x%llX, lock->fl_end = 0x%llX",
+		 lock->fl_start, lock->fl_end);
+
+	err_code = -1;
+	if (lock->fl_start <= lock->fl_end) {
+		/* Get len from "start" and "end" */
+		len = lock->fl_end - lock->fl_start + 1;
+		if ((0 == lock->fl_start) && (OFFSET_MAX == lock->fl_end)) {
+			len = 0;
+		}
+
+		if (file->f_dentry &&
+		    (inode = file->f_dentry->d_inode) &&
+		    (id = (struct inode_data *) inode->i_private)) {
+			DbgPrint("(0x%p 0x%p %.*s)",
+				 file->private_data, inode,
+				 file->f_dentry->d_name.len,
+				 file->f_dentry->d_name.name);
+
+			session = novfs_scope_get_sessionId(id->Scope);
+			if (0 == SC_PRESENT(session)) {
+				id->Scope =
+				    novfs_get_scope(file->f_dentry);
+				session = novfs_scope_get_sessionId(id->Scope);
+			}
+
+			/* fl_type = F_RDLCK, F_WRLCK, F_UNLCK */
+			switch (cmd) {
+			case F_SETLK:
+#ifdef F_GETLK64
+			case F_SETLK64:
+#endif
+
+				err_code =
+				    novfs_set_file_lock(session,
+							file->private_data,
+							lock->fl_type,
+							lock->fl_start, len);
+				break;
+
+			case F_SETLKW:
+#ifdef F_GETLK64
+			case F_SETLKW64:
+#endif
+				err_code =
+				    novfs_set_file_lock(session,
+							file->private_data,
+							lock->fl_type,
+							lock->fl_start, len);
+				break;
+
+			case F_GETLK:
+#ifdef F_GETLK64
+			case F_GETLK64:
+#endif
+				err_code = -ENOSYS;
+				/*
+				 * Not implemented. We doesn't have appropriate xtier function.
+				 * */
+				break;
+
+			default:
+				printk
+				    ("<1> novfs in novfs_f_lock, not implemented cmd = %d\n",
+				     cmd);
+				DbgPrint("novfs in novfs_f_lock, not implemented cmd = %d",
+				     cmd);
+				break;
+			}
+		}
+
+		DbgPrint("lock->fl_type = %u, err_code 0x%X",
+			 lock->fl_type, err_code);
+
+		if ((err_code != 0) && (err_code != -1)
+		    && (err_code != -ENOSYS)) {
+			err_code = -EAGAIN;
+		}
+	} else {
+		err_code = -EINVAL;
+	}
+
+	return (err_code);
+}
+
+/*++======================================================================*/
+static void novfs_copy_cache_pages(struct address_space *mapping,
+				   struct list_head *pages, int bytes_read,
+				   char *data, struct pagevec *plru_pvec)
+{
+	struct page *page;
+	char *target;
+
+	while (bytes_read > 0) {
+		if (list_empty(pages))
+			break;
+
+		page = list_entry(pages->prev, struct page, lru);
+		list_del(&page->lru);
+
+		if (add_to_page_cache(page, mapping, page->index, GFP_KERNEL)) {
+			page_cache_release(page);
+			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_file(plru_pvec);
+		data += PAGE_CACHE_SIZE;
+	}
+	return;
+}
+
+int novfs_a_writepage(struct page *page, struct writeback_control *wbc)
+{
+	int retCode = -EFAULT;
+	struct inode *inode = page->mapping->host;
+	struct inode_data *id = inode->i_private;
+	loff_t pos = ((loff_t) page->index << PAGE_CACHE_SHIFT);
+	struct novfs_schandle session;
+	struct novfs_data_list dlst[2];
+	size_t len = PAGE_CACHE_SIZE;
+
+	session = novfs_scope_get_sessionId(((struct inode_data *) inode->i_private)->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)
+{
+	int retCode = 0;
+	struct inode *inode = mapping->host;
+	struct novfs_schandle session;
+	void *fh = NULL;
+	struct inode_data *id = NULL;
+
+	int max_page_lookup = novfs_max_iosize / PAGE_CACHE_SIZE;
+
+	struct novfs_data_list *dlist, *dlptr;
+	struct page **pages;
+
+	int dlist_idx, i = 0;
+	pgoff_t index, next_index = 0;
+	loff_t pos = 0;
+	size_t tsize;
+
+	SC_INITIALIZE(session);
+	DbgPrint("inode=0x%p mapping=0x%p wbc=0x%p nr_to_write=%d",
+	     inode, mapping, wbc, wbc->nr_to_write);
+
+	if (inode) {
+		DbgPrint("Inode=0x%p Ino=%d Id=0x%p", inode, inode->i_ino,
+			 inode->i_private);
+
+		if (NULL != (id = inode->i_private)) {
+			session =
+			    novfs_scope_get_sessionId(((struct inode_data *) inode->
+						 i_private)->Scope);
+			fh = ((struct inode_data *) inode->i_private)->FileHandle;
+		}
+	}
+
+	dlist = kmalloc(sizeof(struct novfs_data_list) * max_page_lookup, GFP_KERNEL);
+	pages =
+	    kmalloc(sizeof(struct page *) * max_page_lookup, GFP_KERNEL);
+
+	if (id)
+		DbgPrint("inode=0x%p fh=0x%p dlist=0x%p pages=0x%p %s",
+		     inode, fh, dlist, pages, id->Name);
+	else
+		DbgPrint("inode=0x%p fh=0x%p dlist=0x%p pages=0x%p",
+		     inode, fh, dlist, pages);
+
+	if (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("nr_pages=%d", nr_pages);
+			if (!nr_pages) {
+				memset(pages, 0,
+				       sizeof(struct page *) * max_page_lookup);
+
+				spin_lock_irq(&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("2; nr_pages=%d\n", nr_pages);
+				/*
+				 * Check to see if there are dirty pages and there is a valid
+				 * file handle.
+				 */
+				if (nr_pages && !fh) {
+					set_bit(AS_EIO, &mapping->flags);
+					done = 1;
+					DbgPrint("set_bit AS_EIO");
+					break;
+				}
+
+				for (i = 0; i < nr_pages; i++) {
+					page_cache_get(pages[i]);
+				}
+
+				spin_unlock_irq(&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("Add page=0x%p index=0x%lx",
+				     page, page->index);
+			}
+
+			DbgPrint("dlist_idx=%d", 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("release page=0x%p index=0x%lx",
+					     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 {
+		DbgPrint("set_bit AS_EIO");
+		set_bit(AS_EIO, &mapping->flags);
+	}
+	if (dlist)
+		kfree(dlist);
+	if (pages)
+		kfree(pages);
+
+	DbgPrint("retCode=%d", retCode);
+	return (0);
+
+}
+
+int novfs_a_readpage(struct file *file, struct page *page)
+{
+	int retCode = 0;
+	void *pbuf;
+	struct inode *inode = NULL;
+	struct dentry *dentry = NULL;
+	loff_t offset;
+	size_t len;
+	struct novfs_schandle session;
+
+	SC_INITIALIZE(session);
+	DbgPrint("File=0x%p Name=%.*s Page=0x%p", file,
+		 file->f_dentry->d_name.len, file->f_dentry->d_name.name, page);
+
+	dentry = file->f_dentry;
+
+	if (dentry) {
+		DbgPrint("Dentry=0x%p Name=%.*s", dentry, dentry->d_name.len,
+			 dentry->d_name.name);
+		if (dentry->d_inode) {
+			inode = dentry->d_inode;
+		}
+	}
+
+	if (inode) {
+		DbgPrint("Inode=0x%p Ino=%d", inode, inode->i_ino);
+
+		if (inode->i_private) {
+			session =
+			    novfs_scope_get_sessionId(((struct inode_data *) inode->
+						 i_private)->Scope);
+			if (0 == SC_PRESENT(session)) {
+				((struct inode_data *) inode->i_private)->Scope =
+				    novfs_get_scope(file->f_dentry);
+				session =
+				    novfs_scope_get_sessionId(((struct inode_data *) inode->
+							 i_private)->Scope);
+			}
+		}
+	}
+
+	if (!PageUptodate(page)) {
+		struct novfs_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;
+
+		DbgPrint("calling= novfs_Read_Pages %lld",
+			 offset);
+		retCode =
+		    novfs_read_pages(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("retCode=%d", retCode);
+	return (retCode);
+
+}
+
+int novfs_a_readpages(struct file *file, struct address_space *mapping,
+		      struct list_head *page_lst, unsigned nr_pages)
+{
+	int retCode = 0;
+	struct inode *inode = NULL;
+	struct dentry *dentry = NULL;
+	struct novfs_schandle session;
+	loff_t offset;
+	size_t len;
+
+	unsigned page_idx;
+	struct pagevec lru_pvec;
+	pgoff_t next_index;
+
+	char *rbuf, done = 0;
+	SC_INITIALIZE(session);
+
+	DbgPrint("File=0x%p Name=%.*s Pages=%d", file,
+		 file->f_dentry->d_name.len, file->f_dentry->d_name.name,
+		 nr_pages);
+
+	dentry = file->f_dentry;
+
+	if (dentry) {
+		DbgPrint("Dentry=0x%p Name=%.*s", dentry, dentry->d_name.len,
+			 dentry->d_name.name);
+		if (dentry->d_inode) {
+			inode = dentry->d_inode;
+		}
+	}
+
+	if (inode) {
+		DbgPrint("Inode=0x%p Ino=%d", inode, inode->i_ino);
+
+		if (inode->i_private) {
+			session =
+			    novfs_scope_get_sessionId(((struct inode_data *) inode->
+						 i_private)->Scope);
+			if (0 == SC_PRESENT(session)) {
+				((struct inode_data *) inode->i_private)->Scope =
+				    novfs_get_scope(file->f_dentry);
+				session =
+				    novfs_scope_get_sessionId(((struct inode_data *) inode->
+							 i_private)->Scope);
+			}
+		}
+	}
+
+	rbuf = kmalloc(novfs_max_iosize, 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 >= novfs_max_iosize - PAGE_SIZE)) {
+					break;
+				}
+				len += PAGE_SIZE;
+				next_index++;
+			}
+
+			if (len && !done) {
+				struct novfs_data_list dllst[2];
+
+				dllst[1].page = NULL;
+				dllst[1].offset = rbuf;
+				dllst[1].len = len;
+				dllst[1].rwflag = DLWRITE;
+
+				DbgPrint("calling novfs_Read_Pages %lld",
+				     offset);
+				if (!novfs_read_pages
+				    (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++;
+					}
+					if (len == 0) {
+						done = 1;
+					}
+				} 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_file(&lru_pvec);
+		kfree(rbuf);
+	} else {
+		retCode = -ENOMEM;
+	}
+
+	DbgPrint("retCode=%d", retCode);
+	return (retCode);
+
+}
+
+int novfs_a_write_begin(struct file *file, struct address_space *mapping,
+			loff_t pos, unsigned len, unsigned flags,
+			struct page **pagep, void **fsdata)
+{
+	int retVal = 0;
+	loff_t offset = pos;
+	struct novfs_schandle session;
+	struct novfs_data_list dllst[2];
+	struct inode *inode = file->f_dentry->d_inode;
+	struct page *page;
+	pgoff_t index;
+	unsigned from, to;
+	SC_INITIALIZE(session);
+
+	index = pos >> PAGE_CACHE_SHIFT;
+	from = pos & (PAGE_CACHE_SIZE - 1);
+	to = from + len;
+
+	page = grab_cache_page_write_begin(mapping, index, flags);
+	if (!page)
+		return -ENOMEM;
+
+	*pagep = page;
+
+	DbgPrint("File=0x%p Page=0x%p 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->i_private) {
+					session =
+					    novfs_scope_get_sessionId(((struct inode_data *)
+								 inode->
+								 i_private)->
+								Scope);
+					if (0 == SC_PRESENT(session)) {
+						((struct inode_data *) inode->
+						 i_private)->Scope =
+			       novfs_get_scope(file->f_dentry);
+						session =
+						    novfs_scope_get_sessionId(((struct inode_data *) inode->i_private)->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;
+
+				DbgPrint("calling novfs_Read_Pages %lld",
+				     offset);
+				novfs_read_pages(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("memset 0x%p", adr);
+		}
+		flush_dcache_page(page);
+		SetPageUptodate(page);
+	}
+//   DbgPrint("return %d", retVal);
+	return (retVal);
+}
+
+int novfs_a_write_end(struct file *file, struct address_space *mapping,
+		      loff_t pos, unsigned len, unsigned copied,
+		      struct page *page, void *fsdata)
+{
+	int retCode = 0;
+	struct inode *inode = page->mapping->host;
+	loff_t offset = pos;
+	struct novfs_schandle session;
+	struct inode_data *id;
+	struct novfs_data_list dlst[1];
+	pgoff_t index;
+	unsigned from, to;
+	SC_INITIALIZE(session);
+
+	index = pos >> PAGE_CACHE_SHIFT;
+	from = pos & (PAGE_CACHE_SIZE - 1);
+	to = from + len;
+
+
+	DbgPrint("File=0x%p Page=0x%p offset=0x%x To=%u filesize=%lld",
+		 file, page, offset, to, i_size_read(file->f_dentry->d_inode));
+	if (file->f_dentry->d_inode
+	    && (id = file->f_dentry->d_inode->i_private)) {
+		session = novfs_scope_get_sessionId(id->Scope);
+		if (0 == SC_PRESENT(session)) {
+			id->Scope = novfs_get_scope(file->f_dentry);
+			session = novfs_scope_get_sessionId(id->Scope);
+		}
+
+		/*
+		 * Setup file handle
+		 */
+		id->FileHandle = file->private_data;
+
+		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 *)(unsigned long) 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)
+/*
+ *
+ *  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.
+ *
+ *========================================================================*/
+{
+	return (-EIO);
+}
+
+/*++======================================================================*/
+int novfs_i_create(struct inode *dir, struct dentry *dentry, int mode,
+		   struct nameidata *nd)
+{
+	char *path, *buf;
+	struct novfs_entry_info info;
+	void *handle;
+	struct novfs_schandle session;
+	int retCode = -EACCES;
+
+	DbgPrint("mode=0%o flags=0%o %.*s", 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->i_private) {
+			session =
+			    novfs_scope_get_sessionId(((struct inode_data *) dir->i_private)->
+						Scope);
+			if (0 == SC_PRESENT(session)) {
+				((struct inode_data *) dir->i_private)->Scope =
+				    novfs_get_scope(dentry);
+				session =
+				    novfs_scope_get_sessionId(((struct inode_data *) dir->
+							 i_private)->Scope);
+			}
+
+			buf = kmalloc(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) {
+								((struct inode_data *)
+								 dentry->
+								 d_inode->
+								 i_private)->
+						      Flags |= UPDATE_INODE;
+							}
+						}
+					}
+				}
+				kfree(buf);
+			}
+		}
+	}
+	return (retCode);
+}
+
+void update_inode(struct inode *Inode, struct novfs_entry_info *Info)
+{
+	static char dbuf[128];
+
+	DbgPrint("Inode=0x%p I_ino=%d", Inode, Inode->i_ino);
+
+	DbgPrint("atime=%s", ctime_r(&Info->atime.tv_sec, dbuf));
+	DbgPrint("ctime=%s", ctime_r(&Info->ctime.tv_sec, dbuf));
+	DbgPrint("mtime=%s %d", ctime_r(&Info->mtime.tv_sec, dbuf),
+		 Info->mtime.tv_nsec);
+	DbgPrint("size=%lld", Info->size);
+	DbgPrint("mode=0%o", 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 ("calling invalidate_remote_inode sz  %d %d",
+		     Inode->i_size, Info->size);
+		DbgPrint ("calling invalidate_remote_inode sec %d %d",
+		     Inode->i_mtime.tv_sec, Info->mtime.tv_sec);
+		DbgPrint ("calling invalidate_remote_inode ns  %d %d",
+		     Inode->i_mtime.tv_nsec, Info->mtime.tv_nsec);
+
+		if (Inode && Inode->i_mapping) {
+			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_sb->s_blocksize) {
+		Inode->i_blocks =
+		    (unsigned long) (Info->size >> (loff_t) Inode->i_blkbits);
+		Inode->i_bytes = Info->size & (Inode->i_sb->s_blocksize - 1);
+
+		DbgPrint("i_sb->s_blocksize=%d", Inode->i_sb->s_blocksize);
+		DbgPrint("i_blkbits=%d", Inode->i_blkbits);
+		DbgPrint("i_blocks=%d", Inode->i_blocks);
+		DbgPrint("i_bytes=%d", Inode->i_bytes);
+	}
+}
+
+struct dentry *novfs_i_lookup(struct inode *dir, struct dentry *dentry,
+			      struct nameidata *nd)
+{
+	struct dentry *retVal = ERR_PTR(-ENOENT);
+	struct dentry *parent;
+	struct novfs_entry_info *info = NULL;
+	struct inode_data *id;
+	struct inode *inode = NULL;
+	uid_t uid = current_euid();
+	ino_t ino = 0;
+	struct qstr name;
+	char *buf;
+
+	buf = kmalloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+	if (buf) {
+		char *path;
+		path = novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER);
+		if (path) {
+			DbgPrint("dir 0x%p %d hash %d inode 0x%0p %s",
+			     dir, dir->i_ino, dentry->d_name.hash,
+			     dentry->d_inode, path);
+		}
+		kfree(buf);
+	} else {
+		DbgPrint("dir 0x%p %d name %.*s hash %d inode 0x%0p",
+		     dir, dir->i_ino, dentry->d_name.len, dentry->d_name.name,
+		     dentry->d_name.hash, dentry->d_inode);
+	}
+
+	if ((dentry->d_name.len == 7)
+	    && (0 == strncmp(dentry->d_name.name, " !xover", 7))) {
+		dentry->d_op = &novfs_dentry_operations;
+		igrab(dir);
+		d_add(dentry, dir);
+		return NULL;
+	}
+	if ((dentry->d_name.len == 7)
+	    && (0 == strncmp(dentry->d_name.name, "z!xover", 7))) {
+		dentry->d_op = &novfs_dentry_operations;
+		igrab(dir);
+		d_add(dentry, dir);
+		return NULL;
+	}
+
+	if (dir && (id = dir->i_private)) {
+		retVal = 0;
+		if (IS_ROOT(dentry)) {
+			DbgPrint("Root entry=0x%p", novfs_root);
+			inode = novfs_root->d_inode;
+			return (0);
+		} else {
+			info =
+			    kmalloc(sizeof(struct novfs_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 = novfs_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)
+		kfree(info);
+
+	DbgPrint("inode=0x%p dentry->d_inode=0x%p return=0x%p",
+	     dir, dentry->d_inode, retVal);
+
+	return (retVal);
+}
+
+int novfs_i_unlink(struct inode *dir, struct dentry *dentry)
+{
+	int retCode = -ENOENT;
+	struct inode *inode;
+	struct novfs_schandle session;
+	char *path, *buf;
+	uint64_t t64;
+
+	DbgPrint("dir=0x%p dir->i_ino=%d %.*s", dir,
+		 dir->i_ino, dentry->d_name.len, dentry->d_name.name);
+	DbgPrint("IS_ROOT(dentry)=%d", IS_ROOT(dentry));
+	DbgPrint("IS_ROOT(dentry->d_parent)=%d",
+		 IS_ROOT(dentry->d_parent));
+	DbgPrint("IS_ROOT(dentry->d_parent->d_parent)=%d",
+		 IS_ROOT(dentry->d_parent->d_parent));
+	DbgPrint("IS_ROOT(dentry->d_parent->d_parent->d_parent)=%d",
+	     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("dir=0x%p dir->i_ino=%d inode=0x%p ino=%d",
+		     dir, dir->i_ino, inode, inode->i_ino);
+		if (inode->i_private) {
+			session =
+			    novfs_scope_get_sessionId(((struct inode_data *) inode->
+						 i_private)->Scope);
+			if (0 == SC_PRESENT(session)) {
+				((struct inode_data *) inode->i_private)->Scope =
+				    novfs_get_scope(dentry);
+				session =
+				    novfs_scope_get_sessionId(((struct inode_data *) inode->
+							 i_private)->Scope);
+			}
+
+			buf = kmalloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+			if (buf) {
+				path =
+				    novfs_dget_path(dentry, buf,
+						    PATH_LENGTH_BUFFER);
+				if (path) {
+					DbgPrint("path %s mode 0%o",
+						 path, inode->i_mode);
+					if (IS_ROOT(dentry->d_parent->d_parent)) {
+						retCode = novfs_daemon_logout(&dentry->d_name, &session);
+					} else {
+						retCode =
+						    novfs_delete(path,
+								 S_ISDIR(inode->i_mode), session);
+						if (retCode) {
+							struct iattr ia;
+							memset(&ia, 0, sizeof(ia));
+							ia.ia_valid = ATTR_MODE;
+							ia.ia_mode = S_IRWXU;
+							novfs_set_attr(path, &ia, session);
+							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;
+						novfs_scope_set_userspace(&t64, &t64,
+								    &t64, &t64);
+						retCode = 0;
+					}
+				}
+				kfree(buf);
+			}
+		}
+	}
+
+	DbgPrint("retCode 0x%x", retCode);
+	return (retCode);
+}
+
+int novfs_i_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+	char *path, *buf;
+	struct novfs_schandle session;
+	int retCode = 0;
+	struct inode *inode;
+	struct novfs_entry_info info;
+	uid_t uid;
+
+	DbgPrint("dir=0x%p ino=%d dentry=0x%p %.*s mode=0%lo",
+		 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->i_private) {
+		session =
+		    novfs_scope_get_sessionId(((struct inode_data *) dir->i_private)->Scope);
+		if (0 == SC_PRESENT(session)) {
+			((struct inode_data *) dir->i_private)->Scope =
+			    novfs_get_scope(dentry);
+			session =
+			    novfs_scope_get_sessionId(((struct inode_data *) dir->i_private)->
+						Scope);
+		}
+
+		uid = novfs_scope_get_uid(((struct inode_data *) dir->i_private)->Scope);
+		buf = kmalloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+		if (buf) {
+			path = novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER);
+			if (path) {
+				DbgPrint("path %s", 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);
+							((struct inode_data *) inode->
+							 i_private)->Flags &=
+				       ~UPDATE_INODE;
+
+							dentry->d_time =
+							    jiffies +
+							    (novfs_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);
+						}
+
+					}
+				}
+			}
+			kfree(buf);
+		}
+	}
+
+	return (retCode);
+}
+
+int novfs_i_rmdir(struct inode *inode, struct dentry *dentry)
+{
+	return (novfs_i_unlink(inode, dentry));
+}
+
+int novfs_i_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
+{
+	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 (((struct inode_data *) dir->i_private)) {
+		uid = novfs_scope_get_uid(((struct inode_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);
+		}
+	}
+	if (inode) {
+		struct novfs_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("return 0x%x", retCode);
+	return retCode;
+}
+
+int novfs_i_rename(struct inode *odir, struct dentry *od, struct inode *ndir,
+		   struct dentry *nd)
+{
+	int retCode = -ENOTEMPTY;
+	char *newpath, *newbuf, *newcon;
+	char *oldpath, *oldbuf, *oldcon;
+	struct qstr newname, oldname;
+	struct novfs_entry_info *info = NULL;
+	int oldlen, newlen;
+	struct novfs_schandle 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("odir=0x%p ino=%d ndir=0x%p ino=%d", odir,
+		 odir->i_ino, ndir, ndir->i_ino);
+
+	oldbuf = kmalloc(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("od=0x%p od->inode=0x%p od->inode->i_ino=%d %s",
+			     od, od->d_inode, od->d_inode->i_ino, oldpath);
+			if (nd->d_inode) {
+				DbgPrint("nd=0x%p nd->inode=0x%p nd->inode->i_ino=%d %s",
+				     nd, nd->d_inode, nd->d_inode->i_ino,
+				     newpath);
+			} else {
+				DbgPrint("nd=0x%p nd->inode=0x%p %s",
+				     nd, nd->d_inode, newpath);
+			}
+
+			/*
+			 * Check to see if two different servers or different volumes
+			 */
+			newcon = strchr(newpath + 1, '\\');
+			oldcon = strchr(oldpath + 1, '\\');
+			DbgPrint("newcon=0x%p newpath=0x%p", newcon, newpath);
+			DbgPrint("oldcon=0x%p oldpath=0x%p", oldcon, oldpath);
+			retCode = -EXDEV;
+			if (newcon && oldcon
+			    && ((int)(newcon - newpath) ==
+				(int)(oldcon - oldpath))) {
+				newcon = strchr(newcon + 1, '\\');
+				oldcon = strchr(oldcon + 1, '\\');
+				DbgPrint("2; newcon=0x%p newpath=0x%p",
+					 newcon, newpath);
+				DbgPrint("2; oldcon=0x%p oldpath=0x%p",
+					 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->i_private) {
+
+							if (nd->d_inode
+							    && nd->d_inode->
+							    i_private) {
+								session =
+								    novfs_scope_get_sessionId
+								    (((struct inode_data *) ndir->i_private)->Scope);
+								if (0 ==
+								    SC_PRESENT
+								    (session)) {
+									((struct inode_data *) ndir->i_private)->Scope = novfs_get_scope(nd);
+									session
+									    =
+									    novfs_scope_get_sessionId
+									    (((struct inode_data *) ndir->i_private)->Scope);
+								}
+
+								retCode =
+								    novfs_delete(newpath, S_ISDIR(nd->d_inode->i_mode), session);
+								if (retCode) {
+									struct iattr ia;
+									memset(&ia, 0, sizeof(ia));
+									ia.ia_valid = ATTR_MODE;
+									ia.ia_mode = S_IRWXU;
+									novfs_set_attr(newpath, &ia, session);
+									retCode = novfs_delete(newpath, S_ISDIR(nd->d_inode->i_mode), session);
+								}
+
+							}
+
+							session = novfs_scope_get_sessionId(((struct inode_data *) ndir->i_private)->Scope);
+							if (0 == SC_PRESENT(session)) {
+								((struct inode_data *)ndir->i_private)->Scope = novfs_get_scope(nd);
+								session = novfs_scope_get_sessionId(((struct inode_data *) ndir->i_private)->Scope);
+							}
+							retCode = novfs_rename_file(S_ISDIR(od->d_inode->i_mode), oldpath, oldlen - 1, newpath, newlen - 1, session);
+
+							if (!retCode) {
+								info = (struct novfs_entry_info *) oldbuf;
+								od->d_time = 0;
+								novfs_remove_inode_entry(odir, &od->d_name, 0);
+								novfs_remove_inode_entry(ndir, &nd->d_name, 0);
+								novfs_get_file_info(newpath, info, session);
+								nd->d_time = jiffies + (novfs_update_timeout * HZ);
+
+								if (od->d_inode && od->d_inode->i_ino) {
+									ino = od->d_inode-> i_ino;
+								} else {
+									ino = (ino_t)atomic_inc_return(&novfs_Inode_Number);
+								}
+								novfs_add_inode_entry(ndir, &nd->d_name, ino, info);
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+
+	if (oldbuf)
+		kfree(oldbuf);
+
+	DbgPrint("return %d", retCode);
+	return (retCode);
+}
+
+
+int novfs_i_setattr(struct dentry *dentry, struct iattr *attr)
+{
+	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;
+	struct novfs_schandle session;
+	int retVal = 0;
+	struct iattr mattr;
+
+	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->i_private) {
+		session =
+		    novfs_scope_get_sessionId(((struct inode_data *) inode->i_private)->
+					Scope);
+		if (0 == SC_PRESENT(session)) {
+			((struct inode_data *) inode->i_private)->Scope =
+			    novfs_get_scope(dentry);
+			session =
+			    novfs_scope_get_sessionId(((struct inode_data *) inode->
+						 i_private)->Scope);
+		}
+
+		buf = kmalloc(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("%s: %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", __func__,
+					 path,
+					 attr->ia_valid,
+					 attr->ia_mode,
+					 attr->ia_uid,
+					 attr->ia_gid,
+					 attr->ia_size,
+					 atime_buf, mtime_buf, ctime_buf);
+
+				if ((attr->ia_valid & ATTR_FILE)
+				    && (attr->ia_valid & ATTR_SIZE)) {
+					memcpy(&mattr, attr, sizeof(mattr));
+					mattr.ia_valid &=
+					    ~(ATTR_FILE | ATTR_SIZE);
+					attr = &mattr;
+					ia_valid = attr->ia_valid;
+#if 0   // thanks to vfs changes in our tree...
+					retVal =
+					    novfs_trunc_ex(attr->
+								   ia_file->
+								   private_data,
+								   attr->
+								   ia_size,
+								   session);
+					if (!retVal) {
+						inode->i_size = attr->ia_size;
+						((struct inode_data *) inode->
+						 i_private)->Flags |=
+			       UPDATE_INODE;
+					}
+#endif
+				}
+
+				if (ia_valid
+				    && !(retVal =
+					 novfs_set_attr(path, attr, session))) {
+					((struct inode_data *) inode->i_private)->
+					    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);
+					}
+				}
+			}
+		}
+		kfree(buf);
+	}
+	DbgPrint("return 0x%x", retVal);
+
+	return (retVal);
+}
+
+int novfs_i_getattr(struct vfsmount *mnt, struct dentry *dentry,
+		    struct kstat *kstat)
+{
+	int retCode = 0;
+	char atime_buf[32];
+	char mtime_buf[32];
+	char ctime_buf[32];
+	struct inode *inode = dentry->d_inode;
+
+	struct novfs_entry_info info;
+	char *path, *buf;
+	struct novfs_schandle session;
+	struct inode_data *id;
+
+	if (!IS_ROOT(dentry) && !IS_ROOT(dentry->d_parent)) {
+		SC_INITIALIZE(session);
+		id = dentry->d_inode->i_private;
+
+		if (id && (id->Flags & UPDATE_INODE)) {
+			session = novfs_scope_get_sessionId(id->Scope);
+
+			if (0 == SC_PRESENT(session)) {
+				id->Scope = novfs_get_scope(dentry);
+				session = novfs_scope_get_sessionId(id->Scope);
+			}
+
+			buf = kmalloc(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;
+					}
+				}
+				kfree(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_sb->s_blocksize;
+	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("%s: 0x%x 0x%p <%.*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", __func__,
+		 retCode, dentry, 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);
+}
+
+ssize_t novfs_i_getxattr(struct dentry *dentry, const char *name, void *buffer,
+		     size_t buffer_size)
+{
+	struct inode *inode = dentry->d_inode;
+	struct novfs_schandle sessionId;
+	char *path, *buf, *bufRead;
+	ssize_t dataLen;
+
+	int retxcode = 0;
+
+	SC_INITIALIZE(sessionId);
+
+	DbgPrint("Ian");	/*%.*s\n", dentry->d_name.len, dentry->d_name.name); */
+	DbgPrint("dentry->d_name.len %u, dentry->d_name.name %s",
+	     dentry->d_name.len, dentry->d_name.name);
+	DbgPrint("name %s", name);
+	DbgPrint("size %u", buffer_size);
+
+	if (inode && inode->i_private) {
+		sessionId =
+		    novfs_scope_get_sessionId(((struct inode_data *) inode->i_private)->
+					Scope);
+		DbgPrint("SessionId = %u", sessionId);
+		//if (0 == sessionId)
+		if (0 == SC_PRESENT(sessionId)) {
+			((struct inode_data *) inode->i_private)->Scope =
+			    novfs_get_scope(dentry);
+			sessionId =
+			    novfs_scope_get_sessionId(((struct inode_data *) inode->
+						 i_private)->Scope);
+			DbgPrint("SessionId = %u", sessionId);
+		}
+	}
+
+	dataLen = 0;
+	buf = kmalloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+	if (buf) {
+		path = novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER);
+		if (path) {
+			bufRead = kmalloc(XA_BUFFER, GFP_KERNEL);
+			if (bufRead) {
+				retxcode =
+				    novfs_getx_file_info(path, name, bufRead,
+							 XA_BUFFER, &dataLen,
+							 sessionId);
+				DbgPrint("after novfs_GetX_File_Info retxcode = %d",
+				     retxcode);
+				if (!retxcode) {
+					novfs_dump(64, bufRead);
+					if (buffer_size != 0) {
+						if (buffer_size >= dataLen) {
+							memcpy(buffer, bufRead,
+							       dataLen);
+						} else {
+							DbgPrint("(!!!) not enough buffer_size. buffer_size = %d, dataLen = %d",
+							     buffer_size,
+							     dataLen);
+							retxcode = -ERANGE;
+						}
+					}
+
+					if (bufRead) {
+						kfree(bufRead);
+					}
+				}
+			}
+		}
+		kfree(buf);
+	}
+
+	if (retxcode) {
+		dataLen = retxcode;
+	} else {
+		if ((buffer_size > 0) && (buffer_size < dataLen)) {
+			dataLen = -ERANGE;
+		}
+	}
+
+	return (dataLen);
+}
+
+int novfs_i_setxattr(struct dentry *dentry, const char *name, const void *value,
+		     size_t value_size, int flags)
+{
+
+	struct inode *inode = dentry->d_inode;
+	struct novfs_schandle sessionId;
+	char *path, *buf;
+	unsigned long bytesWritten = 0;
+	int retError = 0;
+	int retxcode = 0;
+
+	SC_INITIALIZE(sessionId);
+
+	DbgPrint("Ian");	/*%.*s\n", dentry->d_name.len, dentry->d_name.name); */
+	DbgPrint("dentry->d_name.len %u, dentry->d_name.name %s",
+		 dentry->d_name.len, dentry->d_name.name);
+	DbgPrint("name %s", name);
+	DbgPrint("value_size %u", value_size);
+	DbgPrint("flags %d", flags);
+
+	if (inode && inode->i_private) {
+		sessionId =
+		    novfs_scope_get_sessionId(((struct inode_data *) inode->i_private)->
+					Scope);
+		DbgPrint("SessionId = %u", sessionId);
+		//if (0 == sessionId)
+		if (0 == SC_PRESENT(sessionId)) {
+			((struct inode_data *) inode->i_private)->Scope =
+			    novfs_get_scope(dentry);
+			sessionId =
+			    novfs_scope_get_sessionId(((struct inode_data *) inode->
+						 i_private)->Scope);
+			DbgPrint("SessionId = %u", sessionId);
+		}
+	}
+
+	buf = kmalloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+	if (buf) {
+		path = novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER);
+		if (path) {
+			retxcode =
+			    novfs_setx_file_info(path, name, value, value_size,
+						 &bytesWritten, flags,
+						 sessionId);
+			if (!retxcode) {
+				DbgPrint("bytesWritten = %u", bytesWritten);
+			}
+		}
+		kfree(buf);
+	}
+
+	if (retxcode) {
+		retError = retxcode;
+	}
+
+	if (bytesWritten < value_size) {
+		retError = retxcode;
+	}
+	return (retError);
+}
+
+ssize_t novfs_i_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
+{
+	struct inode *inode = dentry->d_inode;
+	struct novfs_schandle sessionId;
+	char *path, *buf, *bufList;
+	ssize_t dataLen;
+	int retxcode = 0;
+
+	SC_INITIALIZE(sessionId);
+
+	DbgPrint("Ian");	//%.*s\n", dentry->d_name.len, dentry->d_name.name);
+	DbgPrint("dentry->d_name.len %u, dentry->d_name.name %s",
+	     dentry->d_name.len, dentry->d_name.name);
+	DbgPrint("size %u", buffer_size);
+
+	if (inode && inode->i_private) {
+		sessionId =
+		    novfs_scope_get_sessionId(((struct inode_data *) inode->i_private)->
+					Scope);
+		DbgPrint("SessionId = %u", sessionId);
+		//if (0 == sessionId)
+		if (0 == SC_PRESENT(sessionId)) {
+			((struct inode_data *) inode->i_private)->Scope =
+			    novfs_get_scope(dentry);
+			sessionId =
+			    novfs_scope_get_sessionId(((struct inode_data *) inode->
+						 i_private)->Scope);
+			DbgPrint("SessionId = %u", sessionId);
+		}
+	}
+
+	dataLen = 0;
+	buf = kmalloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+	if (buf) {
+		path = novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER);
+		if (path) {
+			bufList = kmalloc(XA_BUFFER, GFP_KERNEL);
+			if (bufList) {
+				retxcode =
+				    novfs_listx_file_info(path, bufList,
+							  XA_BUFFER, &dataLen,
+							  sessionId);
+
+				novfs_dump(64, bufList);
+				if (buffer_size != 0) {
+					if (buffer_size >= dataLen) {
+						memcpy(buffer, bufList,
+						       dataLen);
+					} else {
+						DbgPrint("(!!!) not enough buffer_size. buffer_size = %d, dataLen = %d",
+						     buffer_size, dataLen);
+						retxcode = -1;
+					}
+				}
+
+				if (bufList) {
+					kfree(bufList);
+				}
+			}
+
+		}
+		kfree(buf);
+	}
+
+	if (retxcode) {
+		dataLen = -1;
+	} else {
+
+		if ((buffer_size > 0) && (buffer_size < dataLen)) {
+			dataLen = -ERANGE;
+		}
+	}
+	return (dataLen);
+}
+
+int novfs_i_revalidate(struct dentry *dentry)
+{
+
+	DbgPrint("name %.*s", dentry->d_name.len, dentry->d_name.name);
+
+	return (0);
+}
+
+void novfs_read_inode(struct inode *inode)
+{
+	DbgPrint("0x%p %d", inode, inode->i_ino);
+}
+
+void novfs_write_inode(struct inode *inode)
+{
+	DbgPrint("Inode=0x%p Ino=%d", inode, inode->i_ino);
+}
+
+int novfs_notify_change(struct dentry *dentry, struct iattr *attr)
+{
+	struct inode *inode = dentry->d_inode;
+
+	DbgPrint("Dentry=0x%p Name=%.*s Inode=0x%p Ino=%d ia_valid=0x%x",
+	     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)
+{
+	InodeCount--;
+
+	if (inode->i_private) {
+		struct inode_data *id = inode->i_private;
+
+		DbgPrint("inode=0x%p ino=%d Scope=0x%p Name=%s",
+		     inode, inode->i_ino, id->Scope, id->Name);
+
+		novfs_free_inode_cache(inode);
+
+		down(&InodeList_lock);
+		list_del(&id->IList);
+		up(&InodeList_lock);
+
+		kfree(inode->i_private);
+		inode->i_private = NULL;
+
+		remove_inode_hash(inode);
+
+	} else {
+		DbgPrint("inode=0x%p ino=%d", inode, inode->i_ino);
+	}
+}
+
+/* Called when /proc/mounts is read */
+int novfs_show_options(struct seq_file *s, struct vfsmount *m)
+{
+	char *buf, *path, *tmp;
+
+	buf = kmalloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+	if (buf) {
+		struct path my_path;
+		my_path.mnt = m;
+		my_path.dentry = m->mnt_root;
+		path = d_path(&my_path, buf, PATH_LENGTH_BUFFER);
+		if (path) {
+			if (!novfs_current_mnt
+			    || (novfs_current_mnt
+				&& strcmp(novfs_current_mnt, path))) {
+				DbgPrint("%.*s %.*s %s",
+					 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 = kmalloc(PATH_LENGTH_BUFFER -
+							 (int)(path - buf),
+							 GFP_KERNEL);
+				if (tmp) {
+					strcpy(tmp, path);
+					path = novfs_current_mnt;
+					novfs_current_mnt = tmp;
+					novfs_daemon_set_mnt_point(novfs_current_mnt);
+
+					if (path) {
+						kfree(path);
+					}
+				}
+			}
+		}
+		kfree(buf);
+	}
+	return (0);
+}
+
+/*   Called when statfs(2) system called. */
+int novfs_statfs(struct dentry *de, struct kstatfs *buf)
+{
+	uint64_t td, fd, te, fe;
+	struct super_block *sb = de->d_sb;
+
+	DbgPrint("");
+
+	td = fd = te = fe = 0;
+
+	novfs_scope_get_userspace(&td, &fd, &te, &fe);
+
+	DbgPrint("td=%llu", td);
+	DbgPrint("fd=%llu", fd);
+	DbgPrint("te=%llu", te);
+	DbgPrint("fe=%llu", fd);
+	/* fix for Nautilus */
+	if (sb->s_blocksize == 0)
+		sb->s_blocksize = 4096;
+
+	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", buf->f_type);
+	DbgPrint("f_bsize:   %u", buf->f_bsize);
+	DbgPrint("f_namelen: %d", buf->f_namelen);
+	DbgPrint("f_blocks:  %llu", buf->f_blocks);
+	DbgPrint("f_bfree:   %llu", buf->f_bfree);
+	DbgPrint("f_bavail:  %llu", buf->f_bavail);
+	DbgPrint("f_files:   %llu", buf->f_files);
+	DbgPrint("f_ffree:   %llu", buf->f_ffree);
+	DbgPrint("f_frsize:  %u", 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)
+{
+	struct inode *inode = new_inode(sb);
+
+	if (inode) {
+		InodeCount++;
+		inode->i_mode = mode;
+		inode->i_uid = Uid;
+		inode->i_gid = 0;
+		inode->i_blkbits = sb->s_blocksize_bits;
+		inode->i_blocks = 0;
+		inode->i_rdev = 0;
+		inode->i_ino = (ino) ? ino : (ino_t)atomic_inc_return(&novfs_Inode_Number);
+		if (novfs_page_cache) {
+			inode->i_mapping->a_ops = &novfs_aops;
+		} else {
+			inode->i_mapping->a_ops = &novfs_nocache_aops;
+		}
+		inode->i_mapping->backing_dev_info = &novfs_backing_dev_info;
+		inode->i_atime.tv_sec = 0;
+		inode->i_atime.tv_nsec = 0;
+		inode->i_mtime = inode->i_ctime = inode->i_atime;
+
+		DbgPrint("Inode=0x%p I_ino=%d len=%d",
+			 inode, inode->i_ino, name->len);
+
+		if (NULL !=
+		    (inode->i_private =
+		     kmalloc(sizeof(struct inode_data) + name->len,
+				  GFP_KERNEL))) {
+			struct inode_data *id;
+			id = inode->i_private;
+
+			DbgPrint("i_private 0x%p", id);
+
+			id->Scope = NULL;
+			id->Flags = 0;
+			id->Inode = inode;
+
+			id->cntDC = 1;
+
+			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("name %s", 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_blkbits = 0;
+			break;
+
+		default:
+			init_special_inode(inode, mode, dev);
+			break;
+		}
+
+		DbgPrint("size=%lld", inode->i_size);
+		DbgPrint("mode=0%o", inode->i_mode);
+		DbgPrint("i_sb->s_blocksize=%d", inode->i_sb->s_blocksize);
+		DbgPrint("i_blkbits=%d", inode->i_blkbits);
+		DbgPrint("i_blocks=%d", inode->i_blocks);
+		DbgPrint("i_bytes=%d", inode->i_bytes);
+	}
+
+	DbgPrint("0x%p %d", inode, inode->i_ino);
+	return (inode);
+}
+
+int novfs_fill_super(struct super_block *SB, void *Data, int Silent)
+{
+	struct inode *inode;
+	struct dentry *server, *tree;
+	struct qstr name;
+	struct novfs_entry_info info;
+
+	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 + (novfs_update_timeout * HZ);
+
+	inode->i_atime = inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+
+	SB->s_root = novfs_root;
+
+	DbgPrint("root 0x%p", 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("d_add %s 0x%p",
+					 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("d_add %s 0x%p",
+					 TREE_DIRECTORY_NAME, tree);
+				novfs_add_inode_entry(novfs_root->d_inode,
+						      &name, inode->i_ino,
+						      &info);
+			}
+		}
+	}
+
+	return (0);
+}
+
+static int novfs_get_sb(struct file_system_type *Fstype, int Flags,
+		 const char *Dev_name, void *Data, struct vfsmount *Mnt)
+{
+	DbgPrint("Fstype=0x%x Dev_name=%s", Fstype, Dev_name);
+	return get_sb_nodev(Fstype, Flags, Data, novfs_fill_super, Mnt);
+}
+
+static void novfs_kill_sb(struct super_block *super)
+{
+	shrink_dcache_sb(super);
+	kill_litter_super(super);
+}
+
+ssize_t novfs_Control_read(struct file *file, char *buf, size_t nbytes,
+			   loff_t * ppos)
+{
+	ssize_t retval = 0;
+
+	DbgPrint("kernel_locked 0x%x", kernel_locked());
+
+	return retval;
+}
+
+ssize_t novfs_Control_write(struct file * file, const char *buf, size_t nbytes,
+			    loff_t * ppos)
+{
+	ssize_t retval = 0;
+
+	DbgPrint("kernel_locked 0x%x", kernel_locked());
+	if (buf && nbytes) {
+	}
+
+	return (retval);
+}
+
+int novfs_Control_ioctl(struct inode *inode, struct file *file,
+			unsigned int cmd, unsigned long arg)
+{
+	int retval = 0;
+
+	DbgPrint("kernel_locked 0x%x", kernel_locked());
+
+	return (retval);
+}
+
+static struct file_system_type novfs_fs_type = {
+	.name = "novfs",
+	.get_sb = novfs_get_sb,
+	.kill_sb = novfs_kill_sb,
+	.owner = THIS_MODULE,
+};
+
+int __init init_novfs(void)
+{
+	int retCode;
+
+	lastDir[0] = 0;
+	lastTime = get_nanosecond_time();
+
+	inHAX = 0;
+	inHAXTime = get_nanosecond_time();
+
+	retCode = novfs_proc_init();
+
+	novfs_profile_init();
+
+	if (!retCode) {
+		DbgPrint("%s %s %s", __DATE__, __TIME__, NOVFS_VERSION_STRING);
+		novfs_daemon_queue_init();
+		novfs_scope_init();
+		retCode = register_filesystem(&novfs_fs_type);
+		if (retCode) {
+			novfs_proc_exit();
+			novfs_daemon_queue_exit();
+			novfs_scope_exit();
+		}
+	}
+	return (retCode);
+}
+
+void __exit exit_novfs(void)
+{
+	novfs_scope_exit();
+	novfs_daemon_queue_exit();
+	novfs_profile_exit();
+	novfs_proc_exit();
+	unregister_filesystem(&novfs_fs_type);
+
+	if (novfs_current_mnt) {
+		kfree(novfs_current_mnt);
+		novfs_current_mnt = NULL;
+	}
+}
+
+int novfs_lock_inode_cache(struct inode *i)
+{
+	struct inode_data *id;
+	int retVal = 0;
+
+	DbgPrint("0x%p", i);
+	if (i && (id = i->i_private) && id->DirCache.next) {
+		down(&id->DirCacheLock);
+		retVal = 1;
+	}
+	DbgPrint("return %d", retVal);
+	return (retVal);
+}
+
+void novfs_unlock_inode_cache(struct inode *i)
+{
+	struct inode_data *id;
+
+	if (i && (id = i->i_private) && id->DirCache.next) {
+		up(&id->DirCacheLock);
+	}
+}
+
+int novfs_enumerate_inode_cache(struct inode *i, struct list_head **iteration,
+				ino_t * ino, struct novfs_entry_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.
+ *========================================================================*/
+{
+	struct inode_data *id;
+	struct novfs_dir_cache *dc;
+	struct list_head *l = NULL;
+	int retVal = -1;
+
+	if (i && (id = i->i_private) && 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, struct novfs_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);
+}
+
+/* DirCacheLock should be held before calling this routine. */
+int novfs_get_entry(struct inode *i, struct qstr *name, ino_t * ino,
+		    struct novfs_entry_info *info)
+{
+	struct inode_data *id;
+	struct novfs_dir_cache *dc;
+	int retVal = -1;
+	char *n = "<NULL>";
+	int nl = 6;
+
+	if (i && (id = i->i_private) && id->DirCache.next) {
+		if (name && name->len) {
+			n = (char *)name->name;
+			nl = name->len;
+		}
+
+		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("inode: 0x%p; name: %.*s; ino: %d\n", i, nl, n, *ino);
+	}
+	DbgPrint("return %d", retVal);
+	return (retVal);
+}
+
+ /*DirCacheLock should be held before calling this routine. */
+int novfs_get_entry_by_pos(struct inode *i, loff_t pos, ino_t * ino,
+			   struct novfs_entry_info *info)
+{
+	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("info->name = %s", info->name);
+		if (count == i_pos) {
+			retVal = 0;
+			break;
+		} else
+			count++;
+	}
+
+	return retVal;
+}
+
+/* DirCacheLock should be held before calling this routine. */
+int novfs_get_entry_time(struct inode *i, struct qstr *name, ino_t * ino,
+			 struct novfs_entry_info *info, u64 * EntryTime)
+{
+	struct inode_data *id;
+	struct novfs_dir_cache *dc;
+	int retVal = -1;
+	char *n = "<NULL>";
+	int nl = 6;
+
+	if (i && (id = i->i_private) && id->DirCache.next) {
+		if (name && name->len) {
+			n = (char *)name->name;
+			nl = name->len;
+		}
+		DbgPrint("inode: 0x%p; name:  %.*s; ino: %d", 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("return %d", retVal);
+	return (retVal);
+}
+
+/*
+ *  Abstract:    This routine will return the first entry on the list
+ *               and then remove it.
+ *
+ *  Notes:       DirCacheLock should be held before calling this routine.
+ *
+ */
+int novfs_get_remove_entry(struct inode *i, ino_t * ino, struct novfs_entry_info *info)
+{
+	struct inode_data *id;
+	struct novfs_dir_cache *dc;
+	struct list_head *l = NULL;
+	int retVal = -1;
+
+	if (i && (id = i->i_private) && id->DirCache.next) {
+		l = id->DirCache.next;
+
+		if (l != &id->DirCache) {
+			dc = list_entry(l, struct novfs_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);
+			kfree(dc);
+			DCCount--;
+
+			id->cntDC--;
+		}
+	}
+	return (retVal);
+}
+
+/*
+ *  Abstract:    Marks all entries in the directory cache as invalid.
+ *
+ *  Notes:       DirCacheLock should be held before calling this routine.
+ *
+ *========================================================================*/
+void novfs_invalidate_inode_cache(struct inode *i)
+{
+	struct inode_data *id;
+	struct novfs_dir_cache *dc;
+	struct list_head *l;
+
+	if (i && (id = i->i_private) && id->DirCache.next) {
+		list_for_each(l, &id->DirCache) {
+			dc = list_entry(l, struct novfs_dir_cache, list);
+			dc->flags &= ~ENTRY_VALID;
+		}
+	}
+}
+
+/*++======================================================================*/
+struct novfs_dir_cache *novfs_lookup_inode_cache(struct inode *i, struct qstr *name,
+				    ino_t ino)
+/*
+ *  Returns:     struct novfs_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.
+ *
+ *========================================================================*/
+{
+	struct inode_data *id;
+	struct novfs_dir_cache *dc, *retVal = NULL;
+	struct list_head *l;
+	char *n = "<NULL>";
+	int nl = 6;
+	int hash = 0;
+
+	if (i && (id = i->i_private) && id->DirCache.next) {
+		if (name && name->name) {
+			nl = name->len;
+			n = (char *)name->name;
+			hash = name->hash;
+		}
+		DbgPrint("inode: 0x%p; name:  %.*s; hash:  0x%x;\n"
+			 "   len:   %d; ino:   %d", i, nl, n, hash, nl, ino);
+
+		list_for_each(l, &id->DirCache) {
+			dc = list_entry(l, struct novfs_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("return 0x%p", retVal);
+	return (retVal);
+}
+
+/*
+ * Checks a inode directory to see if there are any enties matching name
+ * or ino.  If entry is found the valid bit is set.
+ *
+ * DirCacheLock should be held before calling this routine.
+ */
+int novfs_lookup_validate(struct inode *i, struct qstr *name, ino_t ino)
+{
+	struct inode_data *id;
+	struct novfs_dir_cache *dc;
+	int retVal = -1;
+	char *n = "<NULL>";
+	int nl = 6;
+
+	if (i && (id = i->i_private) && id->DirCache.next) {
+		if (name && name->len) {
+			n = (char *)name->name;
+			nl = name->len;
+		}
+		DbgPrint("inode: 0x%p; name:  %.*s; ino:   %d", i, nl, n, ino);
+
+		dc = novfs_lookup_inode_cache(i, name, ino);
+		if (dc) {
+			dc->flags |= ENTRY_VALID;
+			retVal = 0;
+		}
+	}
+	return (retVal);
+}
+
+/*
+ * Added entry to directory cache.
+ *
+ * DirCacheLock should be held before calling this routine.
+ */
+int novfs_add_inode_entry(struct inode *i,
+			  struct qstr *name, ino_t ino, struct novfs_entry_info *info)
+{
+	struct inode_data *id;
+	struct novfs_dir_cache *new;
+	int retVal = -ENOMEM;
+	struct novfs_dir_cache *todel;
+	struct list_head *todeltmp;
+
+	//SClark
+	DbgPrint("i: %p", i);
+	if ((id = i->i_private)) {
+		DbgPrint("i->i_private: %p", id);
+		if (id->DirCache.next)
+			DbgPrint("id->DirCache.next: %p", id->DirCache.next);
+	}
+	//SClark
+
+	if (i && (id = i->i_private) && id->DirCache.next) {
+		new = kmalloc(sizeof(struct novfs_dir_cache) + name->len, GFP_KERNEL);
+		if (new) {
+			id->cntDC++;
+
+			DCCount++;
+			DbgPrint("inode: 0x%p; id: 0x%p; DC: 0x%p; new: 0x%p; "
+				 "name:  %.*s; ino: %d; size: %lld; mode: 0x%x",
+				 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);
+
+			if (id->cntDC > 20) {
+				todeltmp = id->DirCache.prev;
+				todel = list_entry(todeltmp, struct novfs_dir_cache, list);
+
+				list_del(&todel->list);
+
+				kfree(todel);
+
+				DCCount--;
+				id->cntDC--;
+			}
+
+		}
+	}
+	return (retVal);
+}
+
+/*
+ *  DirCacheLock should be held before calling this routine.
+ */
+int novfs_update_entry(struct inode *i, struct qstr *name, ino_t ino,
+		       struct novfs_entry_info *info)
+{
+	struct inode_data *id;
+	struct novfs_dir_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->i_private) && 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("inode: 0x%p; name: %.*s; ino: %d; size: %lld; "
+			 "atime: %s; mtime: %s; ctime: %s",
+			 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("entry: 0x%p; flags: 0x%x; jiffies: %lld; "
+				 "ino: %d; size: %lld; mode: 0%o; atime: %s; "
+				 "mtime: %s %d; ctime: %s; hash: 0x%x; "
+				 " nameLen: %d; name: %s",
+				 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("return %d", retVal);
+	return (retVal);
+}
+
+/*
+ *  Removes entry from directory cache.  You can specify a name
+ *  or an inode number.
+ *
+ *  DirCacheLock should be held before calling this routine.
+ */
+void novfs_remove_inode_entry(struct inode *i, struct qstr *name, ino_t ino)
+{
+	struct inode_data *id;
+	struct novfs_dir_cache *dc;
+	char *n = "<NULL>";
+	int nl = 6;
+
+	if (i && (id = i->i_private) && 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("inode: 0x%p; id: 0x%p; DC: 0x%p; "
+				 "name: %.*s; ino: %d entry: 0x%p "
+				 "[name: %.*s; ino: %d; next: 0x%p; "
+				 "prev: 0x%p]",
+				 i, id, &id->DirCache, nl, n, ino, dc,
+				 dc->nameLen, dc->name, dc->ino, dc->list.next,
+				 dc->list.prev);
+			list_del(&dc->list);
+			kfree(dc);
+			DCCount--;
+
+			id->cntDC--;
+		}
+	}
+}
+
+/*
+ * Frees all invalid entries in the directory cache.
+ *
+ * DirCacheLock should be held before calling this routine.
+ */
+void novfs_free_invalid_entries(struct inode *i)
+{
+	struct inode_data *id;
+	struct novfs_dir_cache *dc;
+	struct list_head *l;
+
+	if (i && (id = i->i_private) && id->DirCache.next) {
+		list_for_each(l, &id->DirCache) {
+			dc = list_entry(l, struct novfs_dir_cache, list);
+			if (0 == (dc->flags & ENTRY_VALID)) {
+				DbgPrint("inode: 0x%p; id: 0x%p; entry: 0x%p; "
+					 "name: %.*s; ino: %d",
+					 i, id, dc, dc->nameLen, dc->name,
+					 dc->ino);
+				l = l->prev;
+				list_del(&dc->list);
+				kfree(dc);
+				DCCount--;
+
+				id->cntDC--;
+			}
+		}
+	}
+}
+
+/*
+ *  Frees all entries in the inode cache.
+ *
+ *  DirCacheLock should be held before calling this routine.
+ */
+void novfs_free_inode_cache(struct inode *i)
+{
+	struct inode_data *id;
+	struct novfs_dir_cache *dc;
+	struct list_head *l;
+
+	if (i && (id = i->i_private) && id->DirCache.next) {
+		list_for_each(l, &id->DirCache) {
+			dc = list_entry(l, struct novfs_dir_cache, list);
+			l = l->prev;
+			list_del(&dc->list);
+			kfree(dc);
+			DCCount--;
+
+			id->cntDC--;
+		}
+	}
+}
+
+void novfs_dump_inode(void *pf)
+{
+	struct inode *inode;
+	void (*pfunc) (char *Fmt, ...) = pf;
+	struct inode_data *id;
+	struct novfs_dir_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, struct inode_data, IList);
+		inode = id->Inode;
+		if (inode) {
+			icnt++;
+
+			pfunc("Inode=0x%p 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("   count=0%o\n", atomic_read(&inode->i_count));
+		}
+
+		pfunc("   nofs_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, struct novfs_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);
--- /dev/null
+++ b/fs/novfs/nwcapi.c
@@ -0,0 +1,2202 @@
+/*
+ * Novell NCP Redirector for Linux
+ * Author: James Turner/Richard Williams
+ *
+ * This file contains functions used to interface to the library interface of
+ * the daemon.
+ *
+ * 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.
+ */
+
+#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/semaphore.h>
+#include <asm/uaccess.h>
+
+#include "nwcapi.h"
+#include "nwerror.h"
+#include "vfs.h"
+#include "commands.h"
+
+#ifndef strlen_user
+#define strlen_user(str) strnlen_user(str, ~0UL >> 1)
+#endif
+
+static void GetUserData(struct nwc_scan_conn_info * connInfo, struct novfs_xplat_call_request *cmd, struct novfs_xplat_call_reply *reply);
+static void GetConnData(struct nwc_get_conn_info * connInfo, struct novfs_xplat_call_request *cmd, struct novfs_xplat_call_reply *reply);
+
+/*++======================================================================*/
+int novfs_open_conn_by_name(struct novfs_xplat *pdata, void ** Handle, struct novfs_schandle Session)
+{
+	struct novfs_xplat_call_request *cmd;
+	struct novfs_xplat_call_reply *reply;
+	struct nwd_open_conn_by_name *openConn, *connReply;
+	struct nwc_open_conn_by_name ocbn;
+	int retCode = 0;
+	unsigned long 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 = kmalloc(cmdlen, GFP_KERNEL);
+
+	if (!cmd)
+		return -ENOMEM;
+
+	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 = (struct nwd_open_conn_by_name *) cmd->data;
+
+	openConn->nameLen = strlen_user(ocbn.pName->pString);
+	openConn->serviceLen = strlen_user(ocbn.pServiceType);
+	openConn->uConnFlags = ocbn.uConnFlags;
+	openConn->ConnHandle = Uint32toHandle(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 = (struct nwd_open_conn_by_name *) reply->data;
+		retCode = reply->Reply.ErrorCode;
+		if (!retCode) {
+			/*
+			 * we got valid data.
+			 */
+			connReply = (struct nwd_open_conn_by_name *) reply->data;
+			ocbn.RetConnHandle = HandletoUint32(connReply->newConnHandle);
+			*Handle = connReply->newConnHandle;
+
+			cpylen = copy_to_user(pdata->reqData, &ocbn, sizeof(ocbn));
+			DbgPrint("New Conn Handle = %X", connReply->newConnHandle);
+		}
+		kfree(reply);
+	}
+
+	kfree(cmd);
+	return ((int)retCode);
+
+}
+
+int novfs_open_conn_by_addr(struct novfs_xplat *pdata, void ** Handle, struct novfs_schandle Session)
+{
+	struct novfs_xplat_call_request *cmd;
+	struct novfs_xplat_call_reply *reply;
+	struct nwd_open_conn_by_addr *openConn, *connReply;
+	struct nwc_open_conn_by_addr ocba;
+	struct nwc_tran_addr tranAddr;
+	int retCode = 0;
+	unsigned long 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 = kmalloc(cmdlen, GFP_KERNEL);
+
+	if (!cmd)
+		return -ENOMEM;
+
+	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 = (struct nwd_open_conn_by_addr *) cmd->data;
+
+	cpylen =
+		copy_from_user(&tranAddr, ocba.pTranAddr, sizeof(tranAddr));
+
+	DbgPrint("tranAddr");
+	novfs_dump(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("addr");
+	novfs_dump(sizeof(addr), addr);
+
+	openConn->TranAddr.oAddress = *(unsigned int *) (&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 = (struct nwd_open_conn_by_addr *) reply->data;
+		retCode = reply->Reply.ErrorCode;
+		if (!retCode) {
+			/*
+			 * we got valid data.
+			 */
+			connReply = (struct nwd_open_conn_by_addr *) reply->data;
+			ocba.ConnHandle =
+				HandletoUint32(connReply->ConnHandle);
+			*Handle = connReply->ConnHandle;
+			cpylen =
+				copy_to_user(pdata->reqData, &ocba,
+						sizeof(ocba));
+			DbgPrint("New Conn Handle = %X", connReply->ConnHandle);
+		}
+		kfree(reply);
+	}
+
+	kfree(cmd);
+
+	return (retCode);
+
+}
+
+int novfs_open_conn_by_ref(struct novfs_xplat *pdata, void ** Handle, struct novfs_schandle Session)
+{
+	struct novfs_xplat_call_request *cmd;
+	struct novfs_xplat_call_reply *reply;
+	struct nwd_open_conn_by_ref *openConn;
+	struct nwc_open_conn_by_ref ocbr;
+	int retCode = -ENOMEM;
+	unsigned long cmdlen, datalen, replylen, cpylen;
+
+	cpylen = copy_from_user(&ocbr, pdata->reqData, sizeof(ocbr));
+	datalen = sizeof(*openConn);
+	cmdlen = datalen + sizeof(*cmd);
+	cmd = kmalloc(cmdlen, GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+
+	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 = (struct nwd_open_conn_by_ref *) cmd->data;
+
+	openConn->uConnReference =
+		(void *) (unsigned long) ocbr.uConnReference;
+	openConn->uConnFlags = ocbr.uConnFlags;
+
+	retCode =
+		Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0,
+				(void **)&reply, &replylen,
+				INTERRUPTIBLE);
+	if (reply) {
+		/*
+		 * we got reply data from the daemon
+		 */
+		openConn = (struct nwd_open_conn_by_ref *) reply->data;
+		retCode = reply->Reply.ErrorCode;
+		if (!retCode) {
+			/*
+			 * we got valid data.
+			 */
+			ocbr.ConnHandle =
+				HandletoUint32(openConn->ConnHandle);
+			*Handle = openConn->ConnHandle;
+
+			cpylen =
+				copy_to_user(pdata->reqData, &ocbr,
+						sizeof(ocbr));
+			DbgPrint("New Conn Handle = %X", openConn->ConnHandle);
+		}
+		kfree(reply);
+	}
+
+	kfree(cmd);
+	return (retCode);
+
+}
+
+int novfs_raw_send(struct novfs_xplat *pdata, struct novfs_schandle Session)
+{
+	struct nwc_request xRequest;
+	struct nwc_frag *frag, *cFrag, *reqFrag;
+	struct novfs_xplat_call_request *cmd;
+	struct novfs_xplat_call_reply *reply;
+	int retCode = -ENOMEM;
+	unsigned long cmdlen, datalen, replylen, cpylen, totalLen;
+	unsigned int x;
+	struct nwd_ncp_req *ncpData;
+	struct nwd_ncp_rep *ncpReply;
+	unsigned char *reqData;
+	unsigned long actualReplyLength = 0;
+
+	DbgPrint("[XPLAT] Process Raw NCP Send");
+	cpylen = copy_from_user(&xRequest, pdata->reqData, sizeof(xRequest));
+
+	/*
+	 * Figure out the length of the request
+	 */
+	frag =
+	    kmalloc(xRequest.uNumReplyFrags * sizeof(struct nwc_frag), GFP_KERNEL);
+
+	DbgPrint("[XPLAT RawNCP] - Reply Frag Count 0x%X",
+		 xRequest.uNumReplyFrags);
+
+	if (!frag)
+		return (retCode);
+
+	cpylen =
+	    copy_from_user(frag, xRequest.pReplyFrags,
+			   xRequest.uNumReplyFrags * sizeof(struct nwc_frag));
+	totalLen = 0;
+
+	cFrag = frag;
+	for (x = 0; x < xRequest.uNumReplyFrags; x++) {
+		DbgPrint("[XPLAT - RawNCP] - Frag Len = %d", cFrag->uLength);
+		totalLen += cFrag->uLength;
+		cFrag++;
+	}
+
+	DbgPrint("[XPLAT - RawNCP] - totalLen = %d", totalLen);
+	datalen = 0;
+	reqFrag =
+	    kmalloc(xRequest.uNumRequestFrags * sizeof(struct nwc_frag),
+			 GFP_KERNEL);
+	if (!reqFrag) {
+		kfree(frag);
+		return (retCode);
+	}
+
+	cpylen =
+	    copy_from_user(reqFrag, xRequest.pRequestFrags,
+			   xRequest.uNumRequestFrags * sizeof(struct nwc_frag));
+	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",
+		 xRequest.uNumRequestFrags);
+	DbgPrint("[XPLAT RawNCP] - Total Command Data Len = %x", cmdlen);
+
+	cmd = kmalloc(cmdlen, GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+
+	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 = (struct nwd_ncp_req *) cmd->data;
+	ncpData->replyLen = totalLen;
+	ncpData->requestLen = datalen;
+	ncpData->ConnHandle = (void *) (unsigned long) 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", reply);
+	DbgPrint("RawNCP - retCode = %x", retCode);
+
+	if (reply) {
+		/*
+		 * we got reply data from the daemon
+		 */
+		ncpReply = (struct nwd_ncp_rep *) reply->data;
+		retCode = reply->Reply.ErrorCode;
+
+		DbgPrint("RawNCP - Reply Frag Count 0x%X",
+				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", x,
+					cFrag->uLength);
+
+			datalen =
+				min((unsigned long) cFrag->uLength, totalLen);
+
+			cpylen =
+				copy_to_user(cFrag->pData, reqData,
+						datalen);
+			totalLen -= datalen;
+			reqData += datalen;
+			actualReplyLength += datalen;
+
+			cFrag++;
+		}
+
+		kfree(reply);
+	} else {
+		retCode = -EIO;
+	}
+
+	kfree(cmd);
+	xRequest.uActualReplyLength = actualReplyLength;
+	cpylen = copy_to_user(pdata->reqData, &xRequest, sizeof(xRequest));
+
+	kfree(reqFrag);
+	kfree(frag);
+
+	return (retCode);
+}
+
+int novfs_conn_close(struct novfs_xplat *pdata, void ** Handle, struct novfs_schandle Session)
+{
+	struct novfs_xplat_call_request *cmd;
+	struct novfs_xplat_call_reply *reply;
+	struct nwc_close_conn cc;
+	struct nwd_close_conn *nwdClose;
+	int retCode = 0;
+	unsigned long cmdlen, datalen, replylen, cpylen;
+
+	cpylen = copy_from_user(&cc, pdata->reqData, sizeof(cc));
+
+	datalen = sizeof(*nwdClose);
+	cmdlen = datalen + sizeof(*cmd);
+	cmd = kmalloc(cmdlen, GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+	cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+	cmd->Command.SequenceNumber = 0;
+	cmd->Command.SessionId = Session;
+	cmd->NwcCommand = NWC_CLOSE_CONN;
+
+	nwdClose = (struct nwd_close_conn *) cmd->data;
+	cmd->dataLen = sizeof(*nwdClose);
+	*Handle = nwdClose->ConnHandle = Uint32toHandle(cc.ConnHandle);
+
+	/*
+	 * send the request
+	 */
+	retCode =
+		Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0,
+				(void **)&reply, &replylen, 0);
+	if (reply) {
+		retCode = reply->Reply.ErrorCode;
+		kfree(reply);
+	}
+	kfree(cmd);
+	return (retCode);
+
+}
+
+int novfs_sys_conn_close(struct novfs_xplat *pdata, unsigned long *Handle, struct novfs_schandle Session)
+{
+	struct novfs_xplat_call_request *cmd;
+	struct novfs_xplat_call_reply *reply;
+	struct nwc_close_conn cc;
+	struct nwd_close_conn *nwdClose;
+	unsigned int retCode = 0;
+	unsigned long cmdlen, datalen, replylen, cpylen;
+
+	cpylen = copy_from_user(&cc, pdata->reqData, sizeof(cc));
+
+	datalen = sizeof(*nwdClose);
+	cmdlen = datalen + sizeof(*cmd);
+	cmd = kmalloc(cmdlen, GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+	cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+	cmd->Command.SequenceNumber = 0;
+	cmd->Command.SessionId = Session;
+	cmd->NwcCommand = NWC_SYS_CLOSE_CONN;
+
+	nwdClose = (struct nwd_close_conn *) cmd->data;
+	cmd->dataLen = sizeof(*nwdClose);
+	nwdClose->ConnHandle = (void *) (unsigned long) cc.ConnHandle;
+	*Handle = (unsigned long) cc.ConnHandle;
+
+	/*
+	 * send the request
+	 */
+	retCode =
+		Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, 0);
+	if (reply) {
+		retCode = reply->Reply.ErrorCode;
+		kfree(reply);
+	}
+	kfree(cmd);
+	return (retCode);
+
+}
+
+int novfs_login_id(struct novfs_xplat *pdata, struct novfs_schandle Session)
+{
+	struct nwc_login_id lgn, *plgn;
+	int retCode = -ENOMEM;
+	struct ncl_string server;
+	struct ncl_string username;
+	struct ncl_string password;
+	unsigned long cpylen;
+	struct nwc_string nwcStr;
+
+	cpylen = copy_from_user(&lgn, pdata->reqData, sizeof(lgn));
+
+	DbgPrint("");
+	novfs_dump(sizeof(lgn), &lgn);
+
+	cpylen = copy_from_user(&nwcStr, lgn.pDomainName, sizeof(nwcStr));
+	DbgPrint("DomainName\n");
+	novfs_dump(sizeof(nwcStr), &nwcStr);
+
+	if ((server.buffer = kmalloc(nwcStr.DataLen, GFP_KERNEL))) {
+		server.type = nwcStr.DataType;
+		server.len = nwcStr.DataLen;
+		if (!copy_from_user((void *)server.buffer, nwcStr.pBuffer, server.len)) {
+			DbgPrint("Server");
+			novfs_dump(server.len, server.buffer);
+
+			cpylen = copy_from_user(&nwcStr, lgn.pObjectName, sizeof(nwcStr));
+			DbgPrint("ObjectName");
+			novfs_dump(sizeof(nwcStr), &nwcStr);
+
+			if ((username.buffer = kmalloc(nwcStr.DataLen, GFP_KERNEL))) {
+				username.type = nwcStr.DataType;
+				username.len = nwcStr.DataLen;
+				if (!copy_from_user((void *)username.buffer, nwcStr.pBuffer, username.len)) {
+					DbgPrint("User");
+					novfs_dump(username.len, username.buffer);
+
+					cpylen = copy_from_user(&nwcStr, lgn.pPassword, sizeof(nwcStr));
+					DbgPrint("Password");
+					novfs_dump(sizeof(nwcStr), &nwcStr);
+
+					if ((password.buffer = kmalloc(nwcStr.DataLen, GFP_KERNEL))) {
+						password.type = nwcStr.DataType;
+						password.len = nwcStr.DataLen;
+						if (!copy_from_user((void *)password.buffer, nwcStr.pBuffer, password.len)) {
+							retCode =  novfs_do_login(&server, &username, &password, (void **)&lgn.AuthenticationId, &Session);
+							if (retCode) {
+								lgn.AuthenticationId = 0;
+							}
+
+							plgn = (struct nwc_login_id *)pdata->reqData;
+							cpylen = copy_to_user(&plgn->AuthenticationId, &lgn.AuthenticationId, sizeof(plgn->AuthenticationId));
+						}
+						memset(password.buffer, 0, password.len);
+						kfree(password.buffer);
+					}
+				}
+				memset(username.buffer, 0, username.len);
+				kfree(username.buffer);
+			}
+		}
+		kfree(server.buffer);
+	}
+	return (retCode);
+}
+
+int novfs_auth_conn(struct novfs_xplat *pdata, struct novfs_schandle Session)
+{
+	struct nwc_auth_with_id pauth;
+	struct nwc_auth_wid *pDauth;
+	struct novfs_xplat_call_request *cmd;
+	struct novfs_xplat_call_reply *reply;
+	int retCode = -ENOMEM;
+	unsigned long cmdlen, datalen, replylen, cpylen;
+
+	datalen = sizeof(*pDauth);
+	cmdlen = datalen + sizeof(*cmd);
+	cmd = kmalloc(cmdlen, GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+
+	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 = (struct nwc_auth_wid *) cmd->data;
+	cmd->dataLen = datalen;
+	pDauth->AuthenticationId = pauth.AuthenticationId;
+	pDauth->ConnHandle = (void *) (unsigned long) pauth.ConnHandle;
+
+	retCode =
+		Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0,
+				(void **)&reply, &replylen,
+				INTERRUPTIBLE);
+	if (reply) {
+		retCode = reply->Reply.ErrorCode;
+		kfree(reply);
+	}
+	return (retCode);
+}
+
+int novfs_license_conn(struct novfs_xplat *pdata, struct novfs_schandle Session)
+{
+	struct novfs_xplat_call_request *cmd;
+	struct novfs_xplat_call_reply *reply;
+	struct nwc_license_conn lisc;
+	struct nwc_lisc_id * pDLisc;
+	int retCode = -ENOMEM;
+	unsigned long cmdlen, datalen, replylen, cpylen;
+
+	datalen = sizeof(*pDLisc);
+	cmdlen = datalen + sizeof(*cmd);
+	cmd = kmalloc(cmdlen, GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+
+	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 = (struct nwc_lisc_id *) cmd->data;
+	cmd->dataLen = datalen;
+	pDLisc->ConnHandle = (void *) (unsigned long) lisc.ConnHandle;
+
+	retCode =
+		Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0,
+				(void **)&reply, &replylen,
+				INTERRUPTIBLE);
+	if (reply) {
+		retCode = reply->Reply.ErrorCode;
+		kfree(reply);
+	}
+	kfree(cmd);
+	return (retCode);
+}
+
+int novfs_logout_id(struct novfs_xplat *pdata, struct novfs_schandle Session)
+{
+	struct novfs_xplat_call_request *cmd;
+	struct novfs_xplat_call_reply *reply;
+	struct nwc_lo_id logout, *pDLogout;
+	int retCode = -ENOMEM;
+	unsigned long cmdlen, datalen, replylen, cpylen;
+
+	datalen = sizeof(*pDLogout);
+	cmdlen = datalen + sizeof(*cmd);
+	cmd = kmalloc(cmdlen, GFP_KERNEL);
+
+	if (!cmd)
+		return -ENOMEM;
+	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 = (struct nwc_lo_id *) 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;
+		kfree(reply);
+	}
+	kfree(cmd);
+	return (retCode);
+}
+
+int novfs_unlicense_conn(struct novfs_xplat *pdata, struct novfs_schandle Session)
+{
+	struct novfs_xplat_call_request *cmd;
+	struct novfs_xplat_call_reply *reply;
+	struct nwc_unlic_conn *pUconn, ulc;
+	int retCode = -ENOMEM;
+	unsigned long cmdlen, datalen, replylen, cpylen;
+
+	cpylen = copy_from_user(&ulc, pdata->reqData, sizeof(ulc));
+	datalen = sizeof(*pUconn);
+	cmdlen = datalen + sizeof(*cmd);
+	cmd = kmalloc(cmdlen, GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+
+	cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+	cmd->Command.SequenceNumber = 0;
+	cmd->Command.SessionId = Session;
+	cmd->NwcCommand = NWC_UNLICENSE_CONN;
+	cmd->dataLen = datalen;
+	pUconn = (struct nwc_unlic_conn *) cmd->data;
+
+	pUconn->ConnHandle = (void *) (unsigned long) 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;
+		kfree(reply);
+	}
+	return (retCode);
+
+}
+
+int novfs_unauthenticate(struct novfs_xplat *pdata, struct novfs_schandle Session)
+{
+	struct novfs_xplat_call_request *cmd;
+	struct novfs_xplat_call_reply *reply;
+	struct nwc_unauthenticate auth, *pDAuth;
+	int retCode = -ENOMEM;
+	unsigned long cmdlen, datalen, replylen, cpylen;
+
+	datalen = sizeof(*pDAuth);
+	cmdlen = datalen + sizeof(*cmd);
+	cmd = (struct novfs_xplat_call_request *)kmalloc(cmdlen, GFP_KERNEL);
+
+	if (!cmd)
+		return -ENOMEM;
+	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 = (struct nwc_unauthenticate *) cmd->data;
+	cmd->dataLen = datalen;
+	pDAuth->AuthenticationId = auth.AuthenticationId;
+	pDAuth->ConnHandle = (void *) (unsigned long) auth.ConnHandle;
+
+	retCode =
+		Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0,
+				(void **)&reply, &replylen,
+				INTERRUPTIBLE);
+	if (reply) {
+		retCode = reply->Reply.ErrorCode;
+		kfree(reply);
+	}
+	kfree(cmd);
+	return (retCode);
+
+}
+
+int novfs_get_conn_info(struct novfs_xplat *pdata, struct novfs_schandle Session)
+{
+	struct novfs_xplat_call_request *cmd;
+	struct novfs_xplat_call_reply *reply;
+	struct nwc_get_conn_info connInfo;
+	struct nwd_conn_info *pDConnInfo;
+	int retCode = -ENOMEM;
+	unsigned long cmdlen, replylen, cpylen;
+
+	cmdlen = sizeof(*cmd) + sizeof(*pDConnInfo);
+	cmd = kmalloc(cmdlen, GFP_KERNEL);
+	cpylen =
+	    copy_from_user(&connInfo, pdata->reqData, sizeof(struct nwc_get_conn_info));
+
+	if (!cmd)
+		return -ENOMEM;
+
+	cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+	cmd->Command.SequenceNumber = 0;
+	cmd->Command.SessionId = Session;
+	cmd->NwcCommand = NWC_GET_CONN_INFO;
+
+	pDConnInfo = (struct nwd_conn_info *) cmd->data;
+
+	pDConnInfo->ConnHandle = (void *) (unsigned long) 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;
+		if (!retCode) {
+			GetConnData(&connInfo, cmd, reply);
+		}
+
+		kfree(reply);
+	}
+	kfree(cmd);
+	return (retCode);
+
+}
+
+int novfs_set_conn_info(struct novfs_xplat *pdata, struct novfs_schandle Session)
+{
+	struct novfs_xplat_call_request *cmd;
+	struct novfs_xplat_call_reply *reply;
+	struct nwc_set_conn_info connInfo;
+	struct nwd_set_conn_info *pDConnInfo;
+	int retCode = -ENOMEM;
+	unsigned long cmdlen, replylen, cpylen;
+
+	cmdlen = sizeof(*cmd) + sizeof(*pDConnInfo);
+	cmd = kmalloc(cmdlen, GFP_KERNEL);
+	cpylen =
+	    copy_from_user(&connInfo, pdata->reqData, sizeof(struct nwc_set_conn_info));
+
+	if (!cmd)
+		return -ENOMEM;
+
+	cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+	cmd->Command.SequenceNumber = 0;
+	cmd->Command.SessionId = Session;
+	cmd->NwcCommand = NWC_SET_CONN_INFO;
+
+	pDConnInfo = (struct nwd_set_conn_info *) cmd->data;
+
+	pDConnInfo->ConnHandle = (void *) (unsigned long) 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;
+		kfree(reply);
+	}
+	kfree(cmd);
+	return (retCode);
+
+}
+
+int novfs_get_id_info(struct novfs_xplat *pdata, struct novfs_schandle Session)
+{
+	struct novfs_xplat_call_request *cmd;
+	struct novfs_xplat_call_reply *reply;
+	struct nwc_get_id_info qidInfo, *gId;
+	struct nwd_get_id_info *idInfo;
+	struct nwc_string xferStr;
+	char *str;
+	int retCode = -ENOMEM;
+	unsigned long cmdlen, replylen, cpylen;
+
+	cmdlen = sizeof(*cmd) + sizeof(*idInfo);
+	cmd = kmalloc(cmdlen, GFP_KERNEL);
+	cpylen = copy_from_user(&qidInfo, pdata->reqData, sizeof(qidInfo));
+
+	if (!cmd)
+		return -ENOMEM;
+
+	cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+	cmd->Command.SequenceNumber = 0;
+	cmd->Command.SessionId = Session;
+	cmd->NwcCommand = NWC_GET_IDENTITY_INFO;
+
+	idInfo = (struct nwd_get_id_info *) 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 = (struct nwd_get_id_info *) 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(struct nwc_string));
+			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(struct nwc_string));
+
+			cpylen =
+				copy_from_user(&xferStr, gId->pObjectName,
+						sizeof(struct nwc_string));
+			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(struct nwc_string));
+		}
+
+		kfree(reply);
+	}
+	kfree(cmd);
+	return (retCode);
+}
+
+int novfs_scan_conn_info(struct novfs_xplat *pdata, struct novfs_schandle Session)
+{
+	struct novfs_xplat_call_request *cmd;
+	struct novfs_xplat_call_reply *reply;
+	struct nwc_scan_conn_info connInfo, *rInfo;
+	struct nwd_scan_conn_info *pDConnInfo;
+	int retCode = -ENOMEM;
+	unsigned long cmdlen, replylen, cpylen;
+	unsigned char *localData;
+
+	cpylen =
+	    copy_from_user(&connInfo, pdata->reqData, sizeof(struct nwc_scan_conn_info));
+
+	cmdlen = sizeof(*cmd) + sizeof(*pDConnInfo) + connInfo.uScanInfoLen;
+	cmd = kmalloc(cmdlen, GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+
+	cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+	cmd->Command.SequenceNumber = 0;
+	cmd->Command.SessionId = Session;
+	cmd->NwcCommand = NWC_SCAN_CONN_INFO;
+
+	pDConnInfo = (struct nwd_scan_conn_info *) cmd->data;
+
+	DbgPrint("Input Data");
+	__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 = (unsigned 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("Reply recieved");
+		__DbgPrint("   NextIndex = %x\n", connInfo.uScanIndex);
+		__DbgPrint("   ErrorCode = %x\n", reply->Reply.ErrorCode);
+		__DbgPrint("   data = %p\n", reply->data);
+
+		pDConnInfo = (struct nwd_scan_conn_info *) reply->data;
+		retCode = (unsigned long) reply->Reply.ErrorCode;
+		if (!retCode) {
+			GetUserData(&connInfo, cmd, reply);
+			rInfo = (struct nwc_scan_conn_info *) 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 {
+			unsigned long x;
+
+			x = 0;
+			rInfo = (struct nwc_scan_conn_info *) pdata->reqData;
+			cpylen =
+				copy_to_user(&rInfo->uConnectionReference,
+						&x,
+						sizeof(rInfo->
+							uConnectionReference));
+		}
+
+		kfree(reply);
+	} else {
+		retCode = -EIO;
+	}
+	kfree(cmd);
+	return (retCode);
+}
+
+/*
+ *  Copies the user data out of the scan conn info call.
+ */
+static void GetUserData(struct nwc_scan_conn_info * connInfo, struct novfs_xplat_call_request *cmd, struct novfs_xplat_call_reply *reply)
+{
+	unsigned long uLevel;
+	struct nwd_scan_conn_info *pDConnInfo;
+
+	unsigned char *srcData = NULL;
+	unsigned long dataLen = 0, cpylen;
+
+	pDConnInfo = (struct nwd_scan_conn_info *) reply->data;
+	uLevel = pDConnInfo->uReturnInfoLevel;
+	DbgPrint("uLevel = %d, reply = 0x%p, reply->data = 0x%X",
+	     uLevel, reply, reply->data);
+
+	switch (uLevel) {
+	case NWC_CONN_INFO_RETURN_ALL:
+	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 = (unsigned char *) pDConnInfo;
+		srcData += pDConnInfo->uReturnConnInfoOffset;
+		dataLen = pDConnInfo->uReturnInfoLength;
+		break;
+
+	case NWC_CONN_INFO_TRAN_ADDR:
+		{
+			unsigned char *dstData = connInfo->pReturnConnInfo;
+			struct nwc_tran_addr tranAddr;
+
+			srcData = (unsigned char *) reply->data;
+			dataLen = reply->dataLen;
+
+			DbgPrint("NWC_CONN_INFO_TRAN_ADDR 0x%p -> 0x%p :: 0x%X",
+			     srcData, connInfo->pReturnConnInfo, dataLen);
+
+			cpylen =
+			    copy_from_user(&tranAddr, dstData,
+					   sizeof(tranAddr));
+
+			srcData +=
+			    ((struct nwd_scan_conn_info *) srcData)->
+			    uReturnConnInfoOffset;
+
+			tranAddr.uTransportType =
+			    ((struct nwd_tran_addr *)  srcData)->uTransportType;
+			tranAddr.uAddressLength =
+			    ((struct tagNwdTranAddrEx *) srcData)->uAddressLength;
+
+			cpylen =
+			    copy_to_user(dstData, &tranAddr, sizeof(tranAddr));
+			cpylen =
+			    copy_to_user(tranAddr.puAddress,
+					 ((struct tagNwdTranAddrEx *) srcData)->Buffer,
+					 ((struct tagNwdTranAddrEx *) srcData)->
+					 uAddressLength);
+			dataLen = 0;
+			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 0x%p -> 0x%p :: 0x%X",
+			 srcData, connInfo->pReturnConnInfo, dataLen);
+		cpylen =
+		    copy_to_user(connInfo->pReturnConnInfo, srcData, dataLen);
+	}
+
+	return;
+}
+
+/*
+ *  Copies the user data out of the scan conn info call.
+ */
+static void GetConnData(struct nwc_get_conn_info * connInfo, struct novfs_xplat_call_request *cmd, struct novfs_xplat_call_reply *reply)
+{
+	unsigned long uLevel;
+	struct nwd_conn_info * pDConnInfo;
+
+	unsigned char *srcData = NULL;
+	unsigned long dataLen = 0, cpylen;
+
+	pDConnInfo = (struct nwd_conn_info *) cmd->data;
+	uLevel = pDConnInfo->uInfoLevel;
+
+	switch (uLevel) {
+	case NWC_CONN_INFO_RETURN_ALL:
+		srcData = (unsigned char *) reply->data;
+		dataLen = reply->dataLen;
+		break;
+
+	case NWC_CONN_INFO_RETURN_NONE:
+		dataLen = 0;
+		break;
+
+	case NWC_CONN_INFO_TRAN_ADDR:
+		{
+			unsigned char *dstData = connInfo->pConnInfo;
+			struct nwc_tran_addr tranAddr;
+
+			srcData = (unsigned char *) reply->data;
+
+			cpylen =
+			    copy_from_user(&tranAddr, dstData,
+					   sizeof(tranAddr));
+			tranAddr.uTransportType =
+			    ((struct tagNwdTranAddrEx *) srcData)->uTransportType;
+			tranAddr.uAddressLength =
+			    ((struct tagNwdTranAddrEx *) srcData)->uAddressLength;
+
+			cpylen =
+			    copy_to_user(dstData, &tranAddr, sizeof(tranAddr));
+			cpylen =
+			    copy_to_user(tranAddr.puAddress,
+					 ((struct tagNwdTranAddrEx *) srcData)->Buffer,
+					 ((struct tagNwdTranAddrEx *) 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 = (unsigned 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 novfs_get_daemon_ver(struct novfs_xplat *pdata, struct novfs_schandle Session)
+{
+	struct novfs_xplat_call_request *cmd;
+	struct novfs_xplat_call_reply *reply;
+	struct nwd_get_reqversion *pDVersion;
+	int retCode = -ENOMEM;
+	unsigned long cmdlen, datalen, replylen, cpylen;
+
+	datalen = sizeof(*pDVersion);
+	cmdlen = datalen + sizeof(*cmd);
+	cmd = kmalloc(cmdlen, GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+
+	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 = (struct nwd_get_reqversion *) reply->data;
+		cpylen =
+			copy_to_user(pDVersion, pdata->reqData,
+					sizeof(*pDVersion));
+		kfree(reply);
+	}
+	kfree(cmd);
+	return (retCode);
+
+}
+
+int novfs_get_preferred_DS_tree(struct novfs_xplat *pdata, struct novfs_schandle Session)
+{
+	struct novfs_xplat_call_request *cmd;
+	struct novfs_xplat_call_reply *reply;
+	struct nwd_get_pref_ds_tree *pDGetTree;
+	struct nwc_get_pref_ds_tree xplatCall, *p;
+	int retCode = -ENOMEM;
+	unsigned long cmdlen, datalen, replylen, cpylen;
+	unsigned char *dPtr;
+
+	cpylen =
+	    copy_from_user(&xplatCall, pdata->reqData,
+			   sizeof(struct nwc_get_pref_ds_tree));
+	datalen = sizeof(*pDGetTree) + xplatCall.uTreeLength;
+	cmdlen = datalen + sizeof(*cmd);
+	cmd = kmalloc(cmdlen, GFP_KERNEL);
+
+	if (!cmd)
+		return -ENOMEM;
+
+	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 =
+				(struct nwd_get_pref_ds_tree *) reply->data;
+			dPtr =
+				reply->data + pDGetTree->DsTreeNameOffset;
+			p = (struct nwc_get_pref_ds_tree *) pdata->reqData;
+
+			DbgPrint("Reply recieved");
+			__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);
+		}
+		kfree(reply);
+	}
+	kfree(cmd);
+	return (retCode);
+
+}
+
+int novfs_set_preferred_DS_tree(struct novfs_xplat *pdata, struct novfs_schandle Session)
+{
+	struct novfs_xplat_call_request *cmd;
+	struct novfs_xplat_call_reply *reply;
+	struct nwd_set_pref_ds_tree *pDSetTree;
+	struct nwc_set_pref_ds_tree xplatCall;
+	int retCode = -ENOMEM;
+	unsigned long cmdlen, datalen, replylen, cpylen;
+	unsigned char *dPtr;
+
+	cpylen =
+	    copy_from_user(&xplatCall, pdata->reqData,
+			   sizeof(struct nwc_set_pref_ds_tree));
+	datalen = sizeof(*pDSetTree) + xplatCall.uTreeLength;
+	cmdlen = datalen + sizeof(*cmd);
+	cmd = kmalloc(cmdlen, GFP_KERNEL);
+
+	if (!cmd)
+		return -ENOMEM;
+
+	cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+	cmd->Command.SequenceNumber = 0;
+	cmd->Command.SessionId = Session;
+	cmd->NwcCommand = NWC_SET_PREFERRED_DS_TREE;
+
+	pDSetTree = (struct nwd_set_pref_ds_tree *) 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;
+		kfree(reply);
+	}
+	kfree(cmd);
+	return (retCode);
+
+}
+
+int novfs_set_default_ctx(struct novfs_xplat *pdata,
+		struct novfs_schandle Session)
+{
+	struct novfs_xplat_call_request *cmd;
+	struct novfs_xplat_call_reply *reply;
+	struct nwc_set_def_name_ctx xplatCall;
+	struct nwd_set_def_name_ctx * pDSet;
+	int retCode = -ENOMEM;
+	unsigned long cmdlen, datalen, replylen, cpylen;
+	unsigned char *dPtr;
+
+	cpylen =
+	    copy_from_user(&xplatCall, pdata->reqData,
+			   sizeof(struct nwc_set_def_name_ctx));
+	datalen =
+	    sizeof(*pDSet) + xplatCall.uTreeLength + xplatCall.uNameLength;
+	cmdlen = datalen + sizeof(*cmd);
+	cmd = kmalloc(cmdlen, GFP_KERNEL);
+
+	if (!cmd)
+		return -ENOMEM;
+	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(struct nwd_set_def_name_ctx) +
+		xplatCall.uTreeLength + xplatCall.uNameLength;
+
+	pDSet = (struct nwd_set_def_name_ctx *) cmd->data;
+	dPtr = cmd->data;
+
+	pDSet->TreeOffset = sizeof(struct nwd_set_def_name_ctx);
+	pDSet->uTreeLength = xplatCall.uTreeLength;
+	pDSet->NameContextOffset =
+		pDSet->TreeOffset + xplatCall.uTreeLength;
+	pDSet->uNameLength = xplatCall.uNameLength;
+
+	//sgled      cpylen = copy_from_user(dPtr+pDSet->TreeOffset, xplatCall.pTreeName, xplatCall.uTreeLength);
+	cpylen = copy_from_user(dPtr + pDSet->TreeOffset, xplatCall.pDsTreeName, xplatCall.uTreeLength);	//sgled
+	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;
+		kfree(reply);
+	}
+	kfree(cmd);
+	return (retCode);
+
+}
+
+int novfs_get_default_ctx(struct novfs_xplat *pdata,
+		struct novfs_schandle Session)
+{
+	struct novfs_xplat_call_request *cmd;
+	struct novfs_xplat_call_reply *reply;
+	struct nwc_get_def_name_ctx xplatCall;
+	struct nwd_get_def_name_ctx * pGet;
+	char *dPtr;
+	int retCode = -ENOMEM;
+	unsigned long cmdlen, replylen, cpylen;
+
+	cpylen =
+	    copy_from_user(&xplatCall, pdata->reqData,
+			   sizeof(struct nwc_get_def_name_ctx));
+	cmdlen =
+	    sizeof(*cmd) + sizeof(struct nwd_get_def_name_ctx ) +
+	    xplatCall.uTreeLength;
+	cmd = kmalloc(cmdlen, GFP_KERNEL);
+
+	if (!cmd)
+		return -ENOMEM;
+	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(struct nwd_get_def_name_ctx) + xplatCall.uTreeLength;
+
+	pGet = (struct nwd_get_def_name_ctx *) cmd->data;
+	dPtr = cmd->data;
+
+	pGet->TreeOffset = sizeof(struct nwd_get_def_name_ctx );
+	pGet->uTreeLength = xplatCall.uTreeLength;
+
+	//sgled      cpylen = copy_from_user( dPtr + pGet->TreeOffset, xplatCall.pTreeName, xplatCall.uTreeLength);
+	cpylen = copy_from_user(dPtr + pGet->TreeOffset, xplatCall.pDsTreeName, xplatCall.uTreeLength);	//sgled
+	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 = (struct nwd_get_def_name_ctx *) reply->data;
+
+			DbgPrint("retCode=0x%x uNameLength1=%d uNameLength2=%d",
+				 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);
+		}
+
+		kfree(reply);
+	}
+	kfree(cmd);
+	return (retCode);
+
+}
+
+int novfs_query_feature(struct novfs_xplat *pdata, struct novfs_schandle Session)
+{
+	struct nwc_query_feature xpCall;
+	int status = 0;
+	unsigned long cpylen;
+
+	cpylen =
+	    copy_from_user(&xpCall, pdata->reqData, sizeof(struct nwc_query_feature));
+	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 novfs_get_tree_monitored_conn(struct novfs_xplat *pdata,
+		struct novfs_schandle Session)
+{
+	struct novfs_xplat_call_request *cmd;
+	struct novfs_xplat_call_reply *reply;
+	struct nwc_get_tree_monitored_conn_ref xplatCall, *p;
+	struct nwd_get_tree_monitored_conn_ref *pDConnRef;
+	char *dPtr;
+	unsigned long status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+
+	cpylen =
+	    copy_from_user(&xplatCall, pdata->reqData,
+			   sizeof(struct nwc_get_tree_monitored_conn_ref));
+	datalen = sizeof(*pDConnRef) + xplatCall.pTreeName->DataLen;
+	cmdlen = datalen + sizeof(*cmd);
+	cmd = kmalloc(cmdlen, GFP_KERNEL);
+
+	if (!cmd)
+		return -ENOMEM;
+
+	cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+	cmd->Command.SequenceNumber = 0;
+	cmd->Command.SessionId = Session;
+	cmd->NwcCommand = NWC_GET_TREE_MONITORED_CONN_REF;
+
+	pDConnRef = (struct nwd_get_tree_monitored_conn_ref *) 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 = (struct nwd_get_tree_monitored_conn_ref *) reply->data;
+		dPtr = reply->data + pDConnRef->TreeName.boffset;
+		p = (struct nwc_get_tree_monitored_conn_ref *) pdata->reqData;
+		cpylen =
+			copy_to_user(&p->uConnReference,
+					&pDConnRef->uConnReference, 4);
+
+		status = reply->Reply.ErrorCode;
+		kfree(reply);
+	}
+	kfree(cmd);
+	return (status);
+}
+
+int novfs_enum_ids(struct novfs_xplat *pdata, struct novfs_schandle Session)
+{
+	struct novfs_xplat_call_request *cmd;
+	struct novfs_xplat_call_reply *reply;
+	struct nwc_enum_ids xplatCall, *eId;
+	struct nwd_enum_ids *pEnum;
+	struct nwc_string xferStr;
+	char *str;
+	unsigned long status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+
+	cpylen =
+	    copy_from_user(&xplatCall, pdata->reqData,
+			   sizeof(struct nwc_enum_ids));
+	datalen = sizeof(*pEnum);
+	cmdlen = datalen + sizeof(*cmd);
+	cmd = kmalloc(cmdlen, GFP_KERNEL);
+
+	if (!cmd)
+		return -ENOMEM;
+
+	cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+	cmd->Command.SequenceNumber = 0;
+	cmd->Command.SessionId = Session;
+	cmd->NwcCommand = NWC_ENUMERATE_IDENTITIES;
+
+	DbgPrint("Send Request");
+	__DbgPrint("   iterator = %x\n", xplatCall.Iterator);
+	__DbgPrint("   cmdlen = %d\n", cmdlen);
+
+	pEnum = (struct nwd_enum_ids *) 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 = (struct nwd_enum_ids *) reply->data;
+		cpylen =
+			copy_to_user(&eId->Iterator, &pEnum->Iterator,
+					sizeof(pEnum->Iterator));
+		DbgPrint("[XPLAT NWCAPI] Found AuthId 0x%X",
+				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(struct nwc_string));
+			str =
+				(char *)((char *)reply->data +
+						pEnum->domainNameOffset);
+			DbgPrint("[XPLAT NWCAPI] Found Domain %s",
+					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(struct nwc_string));
+
+			cpylen =
+				copy_from_user(&xferStr, eId->pObjectName,
+						sizeof(struct nwc_string));
+			str =
+				(char *)((char *)reply->data +
+						pEnum->objectNameOffset);
+			DbgPrint("[XPLAT NWCAPI] Found User %s", 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(struct nwc_string));
+		}
+
+		kfree(reply);
+
+	}
+	kfree(cmd);
+	return (status);
+}
+
+int novfs_change_auth_key(struct novfs_xplat *pdata, struct novfs_schandle Session)
+{
+	struct novfs_xplat_call_request *cmd;
+	struct novfs_xplat_call_reply *reply;
+	struct nwc_change_key xplatCall;
+	struct nwd_change_key *pNewKey;
+	struct nwc_string xferStr;
+	char *str;
+	unsigned long status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+
+	cpylen =
+	    copy_from_user(&xplatCall, pdata->reqData, sizeof(struct nwc_change_key));
+
+	datalen =
+	    sizeof(struct nwd_change_key) + xplatCall.pDomainName->DataLen +
+	    xplatCall.pObjectName->DataLen + xplatCall.pNewPassword->DataLen +
+	    xplatCall.pVerifyPassword->DataLen;
+
+	cmdlen = sizeof(*cmd) + datalen;
+	cmd = kmalloc(cmdlen, GFP_KERNEL);
+
+	if (!cmd)
+		return -ENOMEM;
+
+	pNewKey = (struct nwd_change_key *) 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(struct nwc_string));
+	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(struct nwc_string));
+	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(struct nwc_string));
+	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(struct nwc_string));
+	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;
+		kfree(reply);
+	}
+	memset(cmd, 0, cmdlen);
+
+	kfree(cmd);
+	return (status);
+}
+
+int novfs_set_pri_conn(struct novfs_xplat *pdata, struct novfs_schandle Session)
+{
+	struct novfs_xplat_call_request *cmd;
+	struct novfs_xplat_call_reply *reply;
+	struct nwc_set_primary_conn xplatCall;
+	struct nwd_set_primary_conn *pConn;
+	unsigned long status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+
+	cpylen =
+	    copy_from_user(&xplatCall, pdata->reqData,
+			   sizeof(struct nwc_set_primary_conn));
+
+	datalen = sizeof(struct nwd_set_primary_conn);
+	cmdlen = sizeof(*cmd) + datalen;
+	cmd = kmalloc(cmdlen, GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+
+	pConn = (struct nwd_set_primary_conn *) 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 = (void *) (unsigned long) xplatCall.ConnHandle;
+	status =
+		Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0,
+				(void **)&reply, &replylen,
+				INTERRUPTIBLE);
+
+	if (reply) {
+		status = reply->Reply.ErrorCode;
+		kfree(reply);
+	}
+	kfree(cmd);
+	return (status);
+}
+
+int novfs_get_pri_conn(struct novfs_xplat *pdata, struct novfs_schandle Session)
+{
+	struct novfs_xplat_call_request cmd;
+	struct novfs_xplat_call_reply *reply;
+	unsigned long status = -ENOMEM, cmdlen, replylen, cpylen;
+
+	cmdlen = (unsigned long) (&((struct novfs_xplat_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(unsigned long));
+		}
+
+		kfree(reply);
+	}
+
+	return (status);
+}
+
+int novfs_set_map_drive(struct novfs_xplat *pdata, struct novfs_schandle Session)
+{
+
+	struct novfs_xplat_call_request *cmd;
+	struct novfs_xplat_call_reply *reply;
+	unsigned long status = 0, datalen, cmdlen, replylen;
+	struct nwc_map_drive_ex symInfo;
+
+	DbgPrint("");
+	cmdlen = sizeof(*cmd);
+	if (copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo)))
+		return -EFAULT;
+	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);
+
+	novfs_dump(sizeof(symInfo), &symInfo);
+
+	cmdlen += datalen;
+
+	cmd = kmalloc(cmdlen, GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+
+	cmd->dataLen = datalen;
+	cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
+	cmd->Command.SequenceNumber = 0;
+	cmd->Command.SessionId = Session;
+	cmd->NwcCommand = NWC_MAP_DRIVE;
+
+	if (copy_from_user(cmd->data, pdata->reqData, datalen)) {
+		kfree(cmd);
+		return -EFAULT;
+	}
+	status =
+		Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0,
+				(void **)&reply, &replylen,
+				INTERRUPTIBLE);
+
+	if (reply) {
+		status = reply->Reply.ErrorCode;
+		kfree(reply);
+	}
+	kfree(cmd);
+	return (status);
+
+}
+
+int novfs_unmap_drive(struct novfs_xplat *pdata, struct novfs_schandle Session)
+{
+	struct novfs_xplat_call_request *cmd;
+	struct novfs_xplat_call_reply *reply;
+	unsigned long status = 0, datalen, cmdlen, replylen, cpylen;
+	struct nwc_unmap_drive_ex symInfo;
+
+	DbgPrint("");
+
+	cpylen = copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo));
+	cmdlen = sizeof(*cmd);
+	datalen = sizeof(symInfo) + symInfo.linkLen;
+
+	cmdlen += datalen;
+	cmd = kmalloc(cmdlen, GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+
+	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;
+		kfree(reply);
+	}
+	kfree(cmd);
+	return (status);
+}
+
+int novfs_enum_drives(struct novfs_xplat *pdata, struct novfs_schandle Session)
+{
+	struct novfs_xplat_call_request *cmd;
+	struct novfs_xplat_call_reply *reply;
+	unsigned long status = 0, cmdlen, replylen, cpylen;
+	unsigned long offset;
+	char *cp;
+
+	DbgPrint("");
+
+	cmdlen = sizeof(*cmd);
+	cmd = kmalloc(cmdlen, GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+
+	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", status);
+		if (!status) {
+			offset =
+				sizeof(((struct nwc_get_mapped_drives *) pdata->
+							repData)->MapBuffLen);
+			cp = reply->data;
+			replylen =
+				((struct nwc_get_mapped_drives *) pdata->repData)->
+				MapBuffLen;
+			cpylen =
+				copy_to_user(pdata->repData, cp, offset);
+			cp += offset;
+			cpylen =
+				copy_to_user(((struct nwc_get_mapped_drives *) pdata->
+							repData)->MapBuffer, cp,
+						min(replylen - offset,
+							reply->dataLen - offset));
+		}
+
+		kfree(reply);
+	}
+	kfree(cmd);
+	return (status);
+}
+
+int novfs_get_bcast_msg(struct novfs_xplat *pdata, struct novfs_schandle Session)
+{
+	struct novfs_xplat_call_request *cmd;
+	struct novfs_xplat_call_reply *reply;
+	unsigned long cmdlen, replylen;
+	int status = 0x8866, cpylen;
+	struct nwc_get_bcast_notification msg;
+	struct nwd_get_bcast_notification *dmsg;
+
+	cmdlen = sizeof(*cmd) + sizeof(*dmsg);
+	cmd = kmalloc(cmdlen, GFP_KERNEL);
+	if (!cmd)
+		return -ENOMEM;
+
+	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 = (struct nwd_get_bcast_notification *) cmd->data;
+	dmsg->uConnReference = (void *) (unsigned long) msg.uConnReference;
+
+	status =
+		Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0,
+				(void **)&reply, &replylen,
+				INTERRUPTIBLE);
+
+	if (reply) {
+		status = reply->Reply.ErrorCode;
+
+		if (!status) {
+			char *cp = pdata->repData;
+
+			dmsg =
+				(struct nwd_get_bcast_notification *) reply->data;
+			if (pdata->repLen < dmsg->messageLen) {
+				dmsg->messageLen = pdata->repLen;
+			}
+			msg.messageLen = dmsg->messageLen;
+			cpylen =
+				offsetof(struct
+						nwc_get_bcast_notification,
+						message);
+			cp += cpylen;
+			cpylen =
+				copy_to_user(pdata->repData, &msg, cpylen);
+			cpylen =
+				copy_to_user(cp, dmsg->message,
+						msg.messageLen);
+		} else {
+			msg.messageLen = 0;
+			msg.message[0] = 0;
+			cpylen = offsetof(struct
+					nwc_get_bcast_notification,
+					message);
+			cpylen =
+				copy_to_user(pdata->repData, &msg,
+						sizeof(msg));
+		}
+
+		kfree(reply);
+	}
+	kfree(cmd);
+	return (status);
+}
+
+int novfs_set_key_value(struct novfs_xplat *pdata, struct novfs_schandle Session)
+{
+	struct novfs_xplat_call_request *cmd;
+	struct novfs_xplat_call_reply *reply;
+	struct nwc_set_key xplatCall;
+	struct nwd_set_key *pNewKey;
+	struct nwc_string cstrObjectName, cstrPassword;
+	char *str;
+	unsigned long status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+
+	cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(struct nwc_set_key));
+	cpylen =
+	    copy_from_user(&cstrObjectName, xplatCall.pObjectName,
+			   sizeof(struct nwc_string));
+	cpylen =
+	    copy_from_user(&cstrPassword, xplatCall.pNewPassword,
+			   sizeof(struct nwc_string));
+
+	datalen =
+	    sizeof(struct nwd_set_key ) + cstrObjectName.DataLen + cstrPassword.DataLen;
+
+	cmdlen = sizeof(*cmd) + datalen;
+	cmd = kmalloc(cmdlen, GFP_KERNEL);
+
+	if (!cmd)
+		return -ENOMEM;
+
+	pNewKey = (struct nwd_set_key *) 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 = (void *) (unsigned long) xplatCall.ConnHandle;
+	str = (char *)pNewKey;
+
+	/*
+	 * Get the User Name
+	 */
+	str += sizeof(struct nwd_set_key );
+	cpylen =
+		copy_from_user(str, cstrObjectName.pBuffer,
+				cstrObjectName.DataLen);
+
+	str += pNewKey->objectNameLen = cstrObjectName.DataLen;
+	pNewKey->objectNameOffset = sizeof(struct nwd_set_key );
+
+	/*
+	 * 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;
+		kfree(reply);
+	}
+	kfree(cmd);
+	return (status);
+}
+
+int novfs_verify_key_value(struct novfs_xplat *pdata, struct novfs_schandle Session)
+{
+	struct novfs_xplat_call_request *cmd;
+	struct novfs_xplat_call_reply *reply;
+	struct nwc_verify_key xplatCall;
+	struct nwd_verify_key *pNewKey;
+	struct nwc_string xferStr;
+	char *str;
+	unsigned long status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
+
+	cpylen =
+	    copy_from_user(&xplatCall, pdata->reqData, sizeof(struct nwc_verify_key));
+
+	datalen =
+	    sizeof(struct nwd_verify_key) + xplatCall.pDomainName->DataLen +
+	    xplatCall.pObjectName->DataLen + xplatCall.pVerifyPassword->DataLen;
+
+	cmdlen = sizeof(*cmd) + datalen;
+	cmd = (struct novfs_xplat_call_request *)kmalloc(cmdlen, GFP_KERNEL);
+
+	if (!cmd)
+		return -ENOMEM;
+
+	pNewKey = (struct nwd_verify_key *) 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(struct nwc_string));
+	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(struct nwc_string));
+	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(struct nwc_string));
+	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;
+		kfree(reply);
+	}
+	kfree(cmd);
+	return (status);
+}
--- /dev/null
+++ b/fs/novfs/nwcapi.h
@@ -0,0 +1,1416 @@
+/*
+ * NetWare Redirector for Linux
+ * Author: Sheffer Clark
+ *
+ * This file contains all typedefs and constants for the NetWare Client APIs.
+ *
+ * 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.
+ */
+#ifndef __NWCLNX_H__
+#define __NWCLNX_H__
+
+#if 0                          //sgled hack
+#else //sgled hack (up to endif)
+
+#define NW_MAX_TREE_NAME_LEN              33
+#define NW_MAX_SERVICE_TYPE_LEN           49
+/* Transport Type - (nuint32 value) */
+#define NWC_TRAN_TYPE_IPX                 0x0001
+#define NWC_TRAN_TYPE_DDP                 0x0003
+#define NWC_TRAN_TYPE_ASP                 0x0004
+#define NWC_TRAN_TYPE_UDP                 0x0008
+#define NWC_TRAN_TYPE_TCP                 0x0009
+#define NWC_TRAN_TYPE_UDP6                0x000A
+#define NWC_TRAN_TYPE_TCP6                0x000B
+#define NWC_TRAN_TYPE_WILD                0x8000
+
+//
+// DeviceIoControl requests for the NetWare Redirector
+//
+// Macro definition for defining DeviceIoControl function control codes.
+// The function codes 0 - 2047 are reserved for Microsoft.
+// Function codes 2048 - 4096 are reserved for customers.
+// The NetWare Redirector will use codes beginning at 3600.
+//
+// METHOD_NEITHER User buffers will be passed directly from the application
+// to the file system.  The redirector is responsible for either probing
+// and locking the buffers or using a try - except around access of the
+// buffers.
+
+#define  BASE_REQ_NUM                  0x4a541000
+
+// Connection functions
+#define  NWC_OPEN_CONN_BY_NAME         (BASE_REQ_NUM + 0)
+#define  NWC_OPEN_CONN_BY_ADDRESS      (BASE_REQ_NUM + 1)
+#define  NWC_OPEN_CONN_BY_REFERENCE    (BASE_REQ_NUM + 2)
+#define  NWC_CLOSE_CONN                (BASE_REQ_NUM + 3)
+#define  NWC_SYS_CLOSE_CONN            (BASE_REQ_NUM + 4)
+#define  NWC_GET_CONN_INFO             (BASE_REQ_NUM + 5)
+#define  NWC_SET_CONN_INFO             (BASE_REQ_NUM + 6)
+#define  NWC_SCAN_CONN_INFO            (BASE_REQ_NUM + 7)
+#define  NWC_MAKE_CONN_PERMANENT       (BASE_REQ_NUM + 8)
+#define  NWC_LICENSE_CONN              (BASE_REQ_NUM + 9)
+#define  NWC_UNLICENSE_CONN            (BASE_REQ_NUM + 10)
+#define  NWC_GET_NUM_CONNS             (BASE_REQ_NUM + 11)
+#define  NWC_GET_PREFERRED_SERVER      (BASE_REQ_NUM + 12)
+#define  NWC_SET_PREFERRED_SERVER      (BASE_REQ_NUM + 13)
+#define  NWC_GET_PRIMARY_CONN          (BASE_REQ_NUM + 14)
+#define  NWC_SET_PRIMARY_CONN          (BASE_REQ_NUM + 15)
+
+// Authentication functions
+#define  NWC_CHANGE_KEY                (BASE_REQ_NUM + 20)
+#define  NWC_ENUMERATE_IDENTITIES      (BASE_REQ_NUM + 21)
+#define  NWC_GET_IDENTITY_INFO         (BASE_REQ_NUM + 22)
+#define  NWC_LOGIN_IDENTITY            (BASE_REQ_NUM + 23)
+#define  NWC_LOGOUT_IDENTITY           (BASE_REQ_NUM + 24)
+#define  NWC_SET_KEY                   (BASE_REQ_NUM + 25)
+#define  NWC_VERIFY_KEY                (BASE_REQ_NUM + 26)
+#define  NWC_AUTHENTICATE_CONN_WITH_ID (BASE_REQ_NUM + 27)
+#define  NWC_UNAUTHENTICATE_CONN       (BASE_REQ_NUM + 28)
+
+// Directory Services functions
+#define  NWC_GET_DEFAULT_NAME_CONTEXT  (BASE_REQ_NUM + 30)
+#define  NWC_SET_DEFAULT_NAME_CONTEXT  (BASE_REQ_NUM + 31)
+#define  NWC_GET_PREFERRED_DS_TREE     (BASE_REQ_NUM + 32)
+#define  NWC_SET_PREFERRED_DS_TREE     (BASE_REQ_NUM + 33)
+#define  NWC_GET_TREE_MONITORED_CONN_REF  (BASE_REQ_NUM + 34)
+#define  NWC_NDS_RESOLVE_NAME_TO_ID    (BASE_REQ_NUM + 35)
+
+// NCP Request functions
+#define  NWC_FRAGMENT_REQUEST          (BASE_REQ_NUM + 40)
+#define  NWC_NCP_ORDERED_REQUEST_ALL   (BASE_REQ_NUM + 41)
+#define  NWC_RAW_NCP_REQUEST           (BASE_REQ_NUM + 42)
+#define  NWC_RAW_NCP_REQUEST_ALL       (BASE_REQ_NUM + 43)
+
+// File Handle Conversion functions
+#define  NWC_CONVERT_LOCAL_HANDLE      (BASE_REQ_NUM + 50)
+#define  NWC_CONVERT_NETWARE_HANDLE    (BASE_REQ_NUM + 51)
+
+// Misc. functions
+#define  NWC_MAP_DRIVE                 (BASE_REQ_NUM + 60)
+#define  NWC_UNMAP_DRIVE               (BASE_REQ_NUM + 61)
+#define  NWC_ENUMERATE_DRIVES          (BASE_REQ_NUM + 62)
+
+#define  NWC_GET_REQUESTER_VERSION     (BASE_REQ_NUM + 63)
+#define  NWC_QUERY_FEATURE             (BASE_REQ_NUM + 64)
+
+#define  NWC_GET_CONFIGURED_NSPS       (BASE_REQ_NUM + 65)
+
+#define  NWC_GET_MOUNT_PATH            (BASE_REQ_NUM + 66)
+
+#define  NWC_GET_BROADCAST_MESSAGE     (BASE_REQ_NUM + 67)
+
+#endif //sgled hack -------------------------------
+
+#define IOC_XPLAT    0x4a540002
+
+struct novfs_xplat {
+	int xfunction;
+	unsigned long reqLen;
+	void *reqData;
+	unsigned long repLen;
+	void *repData;
+
+};
+
+#if 0
+N_EXTERN_LIBRARY(NWRCODE)
+    NWCLnxReq
+    (nuint32 request, nptr pInBuf, nuint32 inLen, nptr pOutBuf, nuint32 outLen);
+#endif
+//
+// Network Name Format Type
+//
+
+#define  NWC_NAME_FORMAT_NDS              0x0001
+#define  NWC_NAME_FORMAT_BIND             0x0002
+#define  NWC_NAME_FORMAT_BDP              0x0004
+#define  NWC_NAME_FORMAT_NDS_TREE         0x0008
+#define  NWC_NAME_FORMAT_WILD             0x8000
+
+//
+// API String Types
+//
+
+#define  NWC_STRING_TYPE_ASCII            0x0001	// multi-byte, not really ascii
+#define  NWC_STRING_TYPE_UNICODE          0x0002
+#define  NWC_STRING_TYPE_UTF8             0x0003
+
+//
+// Open Connection Flags
+//
+
+#define  NWC_OPEN_LICENSED                0x0001
+#define  NWC_OPEN_UNLICENSED              0x0002
+#define  NWC_OPEN_PRIVATE                 0x0004
+#define  NWC_OPEN_PUBLIC                  0x0008
+#define  NWC_OPEN_EXISTING_HANDLE         0x0010
+#define  NWC_OPEN_NO_HANDLE               0x0020
+#define  NWC_OPEN_PERMANENT               0x0040
+#define  NWC_OPEN_DISCONNECTED            0x0080
+#define  NWC_OPEN_NEAREST                 0x0100
+#define  NWC_OPEN_IGNORE_CACHE            0x0200
+
+//
+// Close Connection Flags
+//
+
+#define  NWC_CLOSE_TEMPORARY              0x0000
+#define  NWC_CLOSE_PERMANENT              0x0001
+
+//
+// Connection Information Levels
+//
+
+#define  NWC_CONN_INFO_RETURN_ALL            0xFFFF
+#define  NWC_CONN_INFO_RETURN_NONE           0x0000
+#define  NWC_CONN_INFO_VERSION               0x0001
+#define  NWC_CONN_INFO_AUTH_STATE            0x0002
+#define  NWC_CONN_INFO_BCAST_STATE           0x0003
+#define  NWC_CONN_INFO_CONN_REF              0x0004
+#define  NWC_CONN_INFO_TREE_NAME             0x0005
+#define  NWC_CONN_INFO_WORKGROUP_ID          0x0006
+#define  NWC_CONN_INFO_SECURITY_STATE        0x0007
+#define  NWC_CONN_INFO_CONN_NUMBER           0x0008
+#define  NWC_CONN_INFO_USER_ID               0x0009
+#define  NWC_CONN_INFO_SERVER_NAME           0x000A
+#define  NWC_CONN_INFO_TRAN_ADDR             0x000B
+#define  NWC_CONN_INFO_NDS_STATE             0x000C
+#define  NWC_CONN_INFO_MAX_PACKET_SIZE       0x000D
+#define  NWC_CONN_INFO_LICENSE_STATE         0x000E
+#define  NWC_CONN_INFO_PUBLIC_STATE          0x000F
+#define  NWC_CONN_INFO_SERVICE_TYPE          0x0010
+#define  NWC_CONN_INFO_DISTANCE              0x0011
+#define  NWC_CONN_INFO_SERVER_VERSION        0x0012
+#define  NWC_CONN_INFO_AUTH_ID               0x0013
+#define  NWC_CONN_INFO_SUSPENDED             0x0014
+#define  NWC_CONN_INFO_TREE_NAME_UNICODE     0x0015
+#define  NWC_CONN_INFO_SERVER_NAME_UNICODE   0x0016
+#define  NWC_CONN_INFO_LOCAL_TRAN_ADDR       0x0017
+#define  NWC_CONN_INFO_ALTERNATE_ADDR        0x0018
+#define  NWC_CONN_INFO_SERVER_GUID           0x0019
+
+#define  NWC_CONN_INFO_MAX_LEVEL             0x0014
+
+//
+// Information Versions
+//
+
+#define  NWC_INFO_VERSION_1               0x0001
+#define  NWC_INFO_VERSION_2               0x0002
+
+//
+// Authentication State
+//
+
+#define  NWC_AUTH_TYPE_NONE               0x0000
+#define  NWC_AUTH_TYPE_BINDERY            0x0001
+#define  NWC_AUTH_TYPE_NDS                0x0002
+#define  NWC_AUTH_TYPE_PNW                0x0003
+
+#define  NWC_AUTH_STATE_NONE              0x0000
+#define  NWC_AUTH_STATE_BINDERY           0x0001
+#define  NWC_AUTH_STATE_NDS               0x0002
+#define  NWC_AUTH_STATE_PNW               0x0003
+
+//
+// Authentication Flags
+//
+
+#define  NWC_AUTH_PRIVATE                 0x00000004
+#define  NWC_AUTH_PUBLIC                  0x00000008
+
+//
+// Broadcast State
+//
+
+#define  NWC_BCAST_PERMIT_ALL             0x0000
+#define  NWC_BCAST_PERMIT_SYSTEM          0x0001
+#define  NWC_BCAST_PERMIT_NONE            0x0002
+#define  NWC_BCAST_PERMIT_SYSTEM_POLLED   0x0003
+#define  NWC_BCAST_PERMIT_ALL_POLLED      0x0004
+
+//
+// Broadcast State
+//
+
+#define  NWC_NDS_NOT_CAPABLE              0x0000
+#define  NWC_NDS_CAPABLE                  0x0001
+
+//
+// License State
+//
+
+#define  NWC_NOT_LICENSED                 0x0000
+#define  NWC_CONNECTION_LICENSED          0x0001
+#define  NWC_HANDLE_LICENSED              0x0002
+
+//
+// Public State
+//
+
+#define  NWC_CONN_PUBLIC                  0x0000
+#define  NWC_CONN_PRIVATE                 0x0001
+
+//
+// Scan Connection Information Flags used
+// for finding connections by specific criteria
+//
+
+#define  NWC_MATCH_NOT_EQUALS             0x0000
+#define  NWC_MATCH_EQUALS                 0x0001
+#define  NWC_RETURN_PUBLIC                0x0002
+#define  NWC_RETURN_PRIVATE               0x0004
+#define  NWC_RETURN_LICENSED              0x0008
+#define  NWC_RETURN_UNLICENSED            0x0010
+
+//
+// Authentication Types
+//
+
+#define  NWC_AUTHENT_BIND                 0x0001
+#define  NWC_AUTHENT_NDS                  0x0002
+#define  NWC_AUTHENT_PNW                  0x0003
+
+//
+// Disconnected info
+//
+
+#define  NWC_SUSPENDED                    0x0001
+
+//
+// Maximum object lengths
+//
+
+#define  MAX_DEVICE_LENGTH                16
+#define  MAX_NETWORK_NAME_LENGTH          1024
+#define  MAX_OBJECT_NAME_LENGTH           48
+#define  MAX_PASSWORD_LENGTH              128
+#define  MAX_SERVER_NAME_LENGTH           48
+#define  MAX_SERVICE_TYPE_LENGTH          48
+#define  MAX_TREE_NAME_LENGTH             32
+#define  MAX_ADDRESS_LENGTH               32
+#define  MAX_NAME_SERVICE_PROVIDERS       10
+
+//
+// Flags for the GetBroadcastMessage API
+//
+
+#define  MESSAGE_GET_NEXT_MESSAGE         1
+#define  MESSAGE_RECEIVED_FOR_CONNECTION  2
+
+//
+// This constant must always be equal to the last device
+//
+
+#define  DEVICE_LAST_DEVICE               0x00000003
+
+//
+// Defined feature set provided by requester
+//
+
+#ifndef  NWC_FEAT_PRIV_CONN
+#define  NWC_FEAT_PRIV_CONN               1
+#define  NWC_FEAT_REQ_AUTH                2
+#define  NWC_FEAT_SECURITY                3
+#define  NWC_FEAT_NDS                     4
+#define  NWC_FEAT_NDS_MTREE               5
+#define  NWC_FEAT_PRN_CAPTURE             6
+#define  NWC_FEAT_NDS_RESOLVE             7
+#endif
+
+//===[ Type definitions ]==================================================
+
+
+//
+// Structure for defining what a transport
+// address looks like
+//
+
+struct nwc_tran_addr {
+	u32 uTransportType;
+	u32 uAddressLength;
+	unsigned char *puAddress;
+};
+
+
+struct nwc_conn_string {
+	char *pString;
+	u32 uStringType;
+	u32 uNameFormatType;
+
+};
+
+//#if defined(NTYPES_H)
+//typedef NWCString    NwcString, *PNwcString;
+//#else
+struct nwc_string {
+	u32 DataType;
+	u32 BuffSize;
+	u32 DataLen;
+	void *pBuffer;
+	u32 CodePage;
+	u32 CountryCode;
+
+};
+//#endif
+
+//
+// Definition of a fragment for the Raw NCP requests
+//
+
+struct nwc_frag {
+	void *pData;
+	u32 uLength;
+
+};
+
+//
+// Current connection information available for
+// enumeration using GetConnInfo and ScanConnInfo
+//
+
+#define NW_INFO_BUFFER_SIZE   NW_MAX_TREE_NAME_LEN + \
+                              NW_MAX_TREE_NAME_LEN + \
+                              NW_MAX_SERVICE_TYPE_LEN
+//++=======================================================================
+//  API Name:        NwcCloseConn
+//
+//  Arguments In:    ConnHandle - The handle to a connection that is
+//                   no longer needed.
+//
+//  Arguments Out:   NONE
+//
+//  Returns:         STATUS_SUCCESS
+//                   NWE_ACCESS_VIOLATION
+//                   NWE_CONN_INVALID
+//                   NWE_INVALID_OWNER
+//                   NWE_RESOURCE_LOCK
+//
+//  Abstract:        This API is used by an application that opened the
+//                   connection using one of the open connection calls
+//                   is finished using the connection.  After it is closed,
+//                   the handle may no longer be used to access the
+//                   connection.
+//
+//  Notes:
+//
+//  Environment:     PASSIVE_LEVEL, LINUX
+//
+//=======================================================================--
+
+struct nwc_close_conn {
+	u32 ConnHandle;
+
+};
+
+//++=======================================================================
+//  API Name:        NwcConvertLocalFileHandle
+//
+//  Arguments In:    NONE
+//
+//  Arguments Out:   uConnReference - The connection reference associated
+//                   with the returned NetWare file handle.
+//
+//                   pNetWareFileHandle - The six byte NetWare file handle
+//                   associated with the given local file handle.
+//
+//  Returns:         STATUS_SUCCESS
+//                   NWE_ACCESS_VIOLATION
+//                   NWE_RESOURCE_NOT_OWNED
+//
+//  Abstract:        This API is used to return the NetWare handle that
+//                   has been associated to a local file handle.
+//                   In addition to returning the NetWare file handle,
+//                   this API also returns the connection reference to
+//                   the connection that owns the file.
+//
+//  Notes:           This API does not create a new NetWare handle, it
+//                   only returns the existing handle associated to the
+//                   local handle.
+//
+//  Environment:     PASSIVE_LEVEL, LINUX
+//
+//=======================================================================--
+
+struct nwc_convert_local_handle {
+	u32 uConnReference;
+	unsigned char NetWareHandle[6];
+
+};
+
+//++=======================================================================
+//  API Name:        NwcConvertNetWareHandle
+//
+//  Arguments In:    ConnHandle - The connection associated with the
+//                   NetWare file handle to convert.
+//
+//                   uAccessMode - The access rights to be used when
+//                   allocating the local file handle.
+//
+//                   pNetWareHandle - The NetWare handle that will be
+//                   bound to the new local handle being created.
+//
+//                   uFileSize - The current file size of the NetWare
+//                   file associated with the given NetWare file handle.
+//
+//  Arguments Out:   NONE
+//
+//  Returns:         STATUS_SUCCESS
+//                   NWE_ACCESS_VIOLATION
+//                   NWE_RESOURCE_NOT_OWNED
+//
+//  Abstract:        This API is used to convert a NetWare file handle
+//                   to a local file handle.
+//
+//                   The local handle must have been created previously
+//                   by doing a local open to \Special\$Special.net.
+//
+//                   Then an Ioctl to this function must be issued using the
+//                   handle returned from the special net open.
+//
+//  Notes:           After making this call, the NetWare file handle
+//                   should not be closed using the NetWare library
+//                   call, instead it should be closed using the local
+//                   operating system's close call.
+//
+//  Environment:     PASSIVE_LEVEL, LINUX
+//
+//=======================================================================--
+struct nwc_convert_netware_handle {
+	u32 ConnHandle;
+	u32 uAccessMode;
+	unsigned char NetWareHandle[6];
+	u32 uFileSize;
+};
+
+
+//++=======================================================================
+//  API Name:        NwcGetConnInfo
+//
+//  Arguments In:    ConnHandle - Connection handle for the connection to
+//                   get information on.
+//                   uInfoLevel - Specifies what information should be
+//                   returned.
+//                   uInfoLen - Length of the ConnInfo buffer.
+//
+//  Arguments Out:   pConnInfo - A pointer to a buffer to return connection
+//                   information in.  If the caller is requesting all
+//                   information the pointer will be to a structure of
+//                   type NwcConnInfo.  If the caller is requesting just
+//                   a single piece of information, the pointer is the
+//                   type of information being requested.
+//
+//  Returns:         STATUS_SUCCESS
+//                   NWE_ACCESS_VIOLATION
+//                   NWE_CONN_INVALID
+//                   NWE_INVALID_OWNER
+//                   NWE_RESOURCE_LOCK
+//                   NWE_STRING_TRANSLATION
+//
+//  Abstract:        This API returns connection information for the specified
+//                   connection.  The requester can receive one piece of
+//                   information or the whole information structure.
+//                   Some of the entries in the NwcConnInfo structure are
+//                   pointers.  The requester is responsible for supplying
+//                   valid pointers for any info specified to be returned.
+//                   If the requester does not want a piece of information
+//                   returned, a NULL pointer should be placed in the field.
+//
+//  Notes:
+//
+//  Environment:     PASSIVE_LEVEL, LINUX
+//
+//=======================================================================--
+
+struct nwc_get_conn_info {
+	u32 ConnHandle;
+	u32 uInfoLevel;
+	u32 uInfoLength;
+	void *pConnInfo;
+
+};
+
+//++=======================================================================
+//  API Name:        NwcGetDefaultNameContext
+//
+//  Arguments In::   uTreeLength - Length of tree string.
+//
+//                   pDsTreeName - Pointer to tree string (multi-byte)
+//
+//                   pNameLength - On input, this is the length of the
+//                   name context buffer. On output, this is the actual
+//                   length of the name context string.
+//
+//  Arguments Out:   pNameContext - The buffer to copy the default name
+//                   context into (multi-byte).
+//
+//  Returns:         STATUS_SUCCESS
+//                   NWE_ACCESS_VIOLATION
+//                   NWE_BUFFER_OVERFLOW
+//                   NWE_OBJECT_NOT_FOUND
+//                   NWE_PARAM_INVALID
+//                   NWE_RESOURCE_LOCK
+//
+//  Abstract:        This API returns the default name context that
+//                   was previously set either by configuration or
+//                   by calling NwcSetDefaultNameContext.
+//
+//  Notes:
+//
+//  Environment:     PASSIVE_LEVEL, LINUX
+//
+//=======================================================================--
+
+struct nwc_get_def_name_ctx {
+	u32 uTreeLength;
+	unsigned char *pDsTreeName;
+	u32 uNameLength;
+// unsigned short *pNameContext;
+	unsigned char *pNameContext;
+
+};
+
+//++=======================================================================
+//  API Name:        NwcGetTreeMonitoredConnReference
+//
+//  Arguments In:    NONE
+//
+//  Arguments Out:   uConnReference - The connection reference associated
+//                   with the monitored connection.
+//
+//  Returns:         STATUS_SUCCESS
+//                   NWE_ACCESS_VIOLATION
+//                   NWE_OBJECT_NOT_FOUND
+//                   NWE_RESOURCE_LOCK
+//
+//  Abstract:        This call returns a connection reference to a
+//                   connection that is monitored.  This connection
+//                   reference may be used to open the connection.
+//
+//  Notes:
+//
+//  Environment:     PASSIVE_LEVEL, LINUX
+//
+//=======================================================================--
+
+struct nwc_get_tree_monitored_conn_ref {
+	struct nwc_string *pTreeName;
+	u32 uConnReference;
+
+};
+
+
+//++=======================================================================
+//  API Name:        NwcGetPreferredDsTree
+//
+//  Arguments In:    uTreeLength - On input, this is the length in bytes
+//                   of the DS tree name buffer.  On output, this is the
+//                   actual length of the DS tree name string in bytes.
+//
+//  Arguments Out:   pDsTreeName - The buffer to copy the DS tree name into.
+//
+//  Returns:         STATUS_SUCCESS
+//                   NWE_ACCESS_VIOLATION
+//                   NWE_BUFFER_OVERFLOW
+//                   NWE_PARAM_INVALID
+//                   NWE_DS_PREFERRED_NOT_FOUND
+//                   NWE_RESOURCE_LOCK
+//
+//  Abstract:        This API returns the preferred DS tree name that was
+//                   previously set either by configuration or
+//                   by calling NwcSetPreferredDsTree.
+//
+//  Notes:
+//
+//  Environment:     PASSIVE_LEVEL, LINUX
+//
+//=======================================================================--
+struct nwc_get_pref_ds_tree {
+	u32 uTreeLength;
+	unsigned char *pDsTreeName;
+};
+
+//++=======================================================================
+//  API Name:        NwcLicenseConn
+//
+//  Arguments In:    ConnHandle - An open connection handle that is in
+//                   an unlicensed state.
+//
+//  Arguments Out:   NONE
+//
+//  Returns:         STATUS_SUCCESS
+//                   NWE_ACCESS_VIOLATION
+//                   NWE_CONN_INVALID
+//                   NWE_HANDLE_ALREADY_LICENSED
+//
+//
+//  Abstract:        This API changes a connections state to licensed.
+//                   The licensed count will be incremented, and if
+//                   necessary, the license NCP will be sent.
+//                   If this handle is already in a licensed state,
+//                   an error will be returned.
+//
+//  Notes:
+//
+//  Environment:     PASSIVE_LEVEL, LINUX
+//
+//=======================================================================--
+
+struct nwc_license_conn {
+	u32 ConnHandle;
+};
+
+
+//++=======================================================================
+//  API Name:        NWCGetMappedDrives
+//
+//  Arguments In:
+//  Arguments Out:
+//
+//  Returns:         STATUS_SUCCESS
+//                   NWE_ACCESS_VIOLATION
+//                   NWE_BUFFER_OVERFLOW
+//
+//  Abstract:        This API returns the NetWare mapped drive info
+//                   per user.
+//
+//  Notes:
+//
+//  Environment:     PASSIVE_LEVEL, LINUX
+//
+//=======================================================================--
+
+struct nwc_get_mapped_drives {
+	u32 MapBuffLen;		// Buffer length (actual buffer size returned)
+	struct nwc_mapped_drive_buf *MapBuffer;	// Pointer to map buffer
+
+};
+
+//++=======================================================================
+//  API Name:        NwcGetMountPath
+//
+//  Arguments In:    MountPathLen - Length of mount path buffer
+//                   including nul terminator.
+//
+//  Arguments Out:   MountPath - Pointer to mount path buffer
+//
+//  Returns:         STATUS_SUCCESS
+//                   NWE_ACCESS_VIOLATION
+//                   NWE_BUFFER_OVERFLOW
+//
+//  Abstract:        This API returns the mount point of the NOVFS file
+//                   system.
+//
+//  Notes:
+//
+//  Environment:     PASSIVE_LEVEL, LINUX
+//
+//=======================================================================--
+
+struct nwc_get_mount_path {
+	u32 MountPathLen;
+	unsigned char *pMountPath;
+
+};
+
+//++=======================================================================
+//  API Name:        NwcOpenConnByAddr
+//
+//  Arguments In:    pServiceType - The type of service required.
+//
+//                   uConnFlags - Specifies whether this connection
+//                   should be public or private.
+//
+//                   pTranAddress - Specifies the transport address of
+//                   the service to open a connection on.
+//                   a connection to.
+//
+//  Arguments Out:   ConnHandle - The new connection handle returned.
+//                   This handle may in turn be used for all requests
+//                   directed to this connection.
+//
+//  Returns:         STATUS_SUCCESS
+//                   NWE_ACCESS_VIOLATION
+//                   NWE_INSUFFICIENT_RESOURCES
+//                   NWE_TRAN_INVALID_TYPE
+//                   NWE_RESOURCE_LOCK
+//                   NWE_UNSUPPORTED_TRAN_TYPE
+//
+//  Abstract:        This API will create a service connection to
+//                   the service specified by the transport address.
+//
+//  Notes:
+//
+//  Environment:     PASSIVE_LEVEL, LINUX
+//
+//=======================================================================--
+
+struct nwc_open_conn_by_addr {
+	char *pServiceType;
+	u32 uConnFlags;
+	struct nwc_tran_addr *pTranAddr;
+	u32 ConnHandle;
+
+};
+
+//++=======================================================================
+//  API Name:        NwcOpenConnByName
+//
+//  Arguments In:    ConnHandle - The connection to use when resolving
+//                   a name.  For instance, if the name is a bindery name
+//                   the requester will scan the bindery of the given
+//                   connection to retrieve the service's address.  This
+//                   value can also be NULL if the caller doesn't care
+//                   which connection is used to resolve the address.
+//
+//                   pName - A pointer to the name of the service trying
+//                   to be connected to.  This string is NULL terminated,
+//                   contains no wild cards, and is a maximum of 512
+//                   characters long.
+//
+//                   pServiceType - The type of service required.
+//
+//                   uConnFlags - Specifies whether this connection
+//                   should be public or private.
+//
+//                   uTranType - Specifies the preferred or required
+//                   transport type to be used.
+//                   NWC_TRAN_TYPE_WILD may be ORed with the other values
+//                   or used alone.  When ORed with another value, the
+//                   wild value indicates an unmarked alternative is
+//                   acceptable.  When used alone, the current preferred
+//                   transport is used.
+//
+//  Arguments Out:   ConnHandle - The new connection handle returned.
+//                   This handle may in turn be used for all requests
+//                   directed to this connection.
+//
+//  Returns:         STATUS_SUCCESS
+//                   NWE_ACCESS_VIOLATION
+//                   NWE_BUFFER_OVERFLOW
+//                   NWE_INSUFFICIENT_RESOURCES
+//                   NWE_INVALID_STRING_TYPE
+//                   NWE_RESOURCE_LOCK
+//                   NWE_STRING_TRANSLATION
+//                   NWE_TRAN_INVALID_TYPE
+//                   NWE_UNSUPPORTED_TRAN_TYPE
+//
+//  Abstract:        This API will resolve the given name to a network
+//                   address then create a service connection to the
+//                   specified service.
+//
+//  Notes:
+//
+//  Environment:     PASSIVE_LEVEL, LINUX
+//
+//=======================================================================--
+
+struct nwc_open_conn_by_name {
+	u32 ConnHandle;
+	struct nwc_conn_string *pName;
+	char *pServiceType;
+	u32 uConnFlags;
+	u32 uTranType;
+	u32 RetConnHandle;
+
+};
+
+//++=======================================================================
+//  API Name:        NwcOpenConnByReference
+//
+//  Arguments In:    uConnReference - A reference handle which identifies
+//                   a valid connection that the caller wants to obtain
+//                   a connection handle to.  A reference handle can be
+//                   used to get information about the connection without
+//                   actually getting a handle to it.  A connection handle
+//                   must be used to make actual requests to that
+//                   connection.
+//
+//                   uConnFlags - Currently unused.
+//
+//  Arguments Out:   ConnHandle - The new connection handle returned.
+//                   This handle may in turn be used for all requests
+//                   directed to this connection.
+//
+//  Returns:         STATUS_SUCCESS
+//                   NWE_ACCESS_VIOLATION
+//                   NWE_CONN_INVALID
+//
+//  Abstract:        This API will open the connection associated with
+//                   the given connection reference.  The connection
+//                   reference can be obtained by calling the
+//                   NwcScanConnInfo API.
+//
+//  Notes:
+//
+//  Environment:     PASSIVE_LEVEL, LINUX
+//
+//=======================================================================--
+
+struct nwc_open_conn_by_ref {
+	u32 uConnReference;
+	u32 uConnFlags;
+	u32 ConnHandle;
+
+};
+
+//++=======================================================================
+//  API Name:        NwcRawRequest
+//
+//  Arguments In:    ConnHandle - The connection handle of the connection
+//                   that the request is being directed to.
+//
+//                   uFunction - The NCP function that is being called.
+//
+//                   uNumRequestFrags - The number of fragments that the
+//                   request packet has been broken into.
+//
+//                   pRequestFrags - List of fragments that make up the
+//                   request packet.  Each fragment includes the length
+//                   of the fragment data and a pointer to the data.
+//
+//                   uNumReplyFrags - The number of fragments the reply
+//                   packet has been broken into.
+//
+//  Arguments Out:   pReplyFrags - List of fragments that make up the
+//                   request packet.  Each fragment includes the length
+//                   of the fragment data and a pointer to the data.
+//
+//                   uActualReplyLength - Total size of the reply packet
+//                   after any header and tail information is removed.
+//
+//  Returns:         STATUS_SUCCESS
+//                   NWE_ACCESS_VIOLATION
+//                   NWE_CONN_INVALID
+//
+//  Abstract:        API for sending raw NCP packets directly to a server.
+//
+//  Notes:
+//
+//  Environment:     PASSIVE_LEVEL, LINUX
+//
+//=======================================================================--
+
+struct nwc_request {
+	u32 ConnHandle;
+	u32 uFunction;
+	u32 uNumRequestFrags;
+	struct nwc_frag *pRequestFrags;
+	u32 uNumReplyFrags;
+	struct nwc_frag *pReplyFrags;
+	u32 uActualReplyLength;
+
+};
+
+//++=======================================================================
+//  API Name:        NwcScanConnInfo
+//
+//  Arguments In:    uScanIndex - The index to be used on the next
+//                   iteration of the scan.  This value should be initially
+//                   set to zero.  The output of this parameter will be
+//                   used in subsequent calls to this function.
+//
+//                   uScanInfoLevel - Describes the composition of the
+//                   pScanConnInfo pointer.  If this parameter contains
+//                   NWC_CONN_INFO_RETURN_ALL, information for all
+//                   connections will be returned.
+//
+//                   uScanInfoLen - Lenght of pScanConnInfo buffer
+//
+//                   pScanConnInfo - This parameter is a pointer to
+//                   data that describes one piece of connection
+//                   information.  The type of this data depends on
+//                   which level of information is being scanned for.
+//                   For instance, if the scan is being used to find all
+//                   connections with a particular authentication state,
+//                   pScanConnInfo would be a "pnuint" since
+//                   authentication state is described as nuint in the
+//                   NwcConnInfo structure.
+//
+//                   uScanFlag - This parameter tells whether to return
+//                   connection information for connections that match
+//                   the scan criteria or that do not match the scan
+//                   criteria.  If the caller wants to find all the
+//                   connections that are not in the "NOVELL_INC" DS
+//                   tree, he would use the call as described below in
+//                   the description except the uScanFlag parameter would
+//                   have  the value of NWC_MATCH_NOT_EQUALS.  This flag
+//                   is also used to tell the requester whether to
+//                   return private or public, licensed or unlicensed
+//                   connections.
+//
+//                   uReturnInfoLevel - Specifies what information
+//                   should be returned.
+//
+//                   uReturnInfoLength - The size in bytes of pConnInfo.
+//
+//  Arguments Out:   uConnectionReference - Connection reference
+//                   associated with the information that is being
+//                   returned.
+//
+//                   pReturnConnInfo - A pointer to the NwcConnInfo
+//                   structure defined above.  In some of the
+//                   structures within the union, there are pointers to
+//                   data to be returned.  It is the responsibility of
+//                   the caller to provide pointers to valid memory
+//                   to copy this data into.
+//
+//  Returns:         STATUS_SUCCESS
+//                   NWE_ACCESS_VIOLATION
+//                   NWE_RESOURCE_LOCK
+//                   NWE_CONN_INVALID
+//                   NWE_INVALID_LEVEL
+//                   NWE_STRING_TRANSLATION
+//                   NWE_INVALID_MATCH_DATA
+//                   NWE_MATCH_FAILED
+//                   NWE_BUFFER_OVERFLOW
+//                   NWE_NO_MORE_ENTRIES
+//
+//  Abstract:        This API is used to return connection information
+//                   for multiple connections.  It will return one
+//                   piece or the full structure of connection information
+//                   for one connection at a time.  This call is designed
+//                   to scan for connections based on any piece of
+//                   connection information as described in the
+//                   NwcConnInfo structure.  For instance, if the caller
+//                   wants to scan for all connections in the DS tree
+//                   "NOVELL_INC", the call would be made with the
+//                   following paramters:
+//
+//                      uScanLevelInfo = NWC_CONN_INFO_TREE_NAME
+//                      pScanConnInfo = "NOVELL_INC"
+//                      uScanFlag = NWC_MATCH_EQUALS |
+//                                  NWC_RETURN_PUBLIC |
+//                                  NWC_RETURN_LICENSED
+//
+//                   The scan flag is used to tell if the scan is
+//                   supposed to return connections that match or don't
+//                   match.  This design doesn't allow any other
+//                   conditions for this flag (such as greater than or
+//                   less than).
+//
+//                   If the caller specifies the uReturnInfoLevel =
+//                   NWC_CONN_INFO_RETURN_ALL, the full NwcConnInfo
+//                   structure is returned.  The caller must supply
+//                   data for any pointers in the NwcConnInfo structure
+//                   (these include tree name, workgroup id, server name
+//                   and transport address).  However if the caller
+//                   doesn't want to get a particular piece of info
+//                   that is expecting a pointer to some data, a NULL
+//                   pointer may be used to indicate to the requester
+//                   that it should not return that piece of information.
+//
+//  Notes:
+//
+//  Environment:     PASSIVE_LEVEL, LINUX
+//
+//=======================================================================--
+
+struct nwc_scan_conn_info {
+	u32 uScanIndex;
+	u32 uScanInfoLevel;
+	u32 uScanInfoLen;
+	void *pScanConnInfo;
+	u32 uScanFlags;
+	u32 uReturnInfoLevel;
+	u32 uReturnInfoLength;
+	u32 uConnectionReference;
+	void *pReturnConnInfo;
+
+};
+
+//++=======================================================================
+//  API Name:        NwcSetConnInfo
+//
+//  Arguments In:    ConnHandle - Connection handle for the connection to
+//                   set information on.
+//
+//                   uInfoLevel - Specifies what information should be set.
+//
+//                   uInfoLen - Length in bytes of the information being set.
+//
+//                   pConnInfo - Connection information to set.
+//
+//  Arguments Out:   NONE
+//
+//  Returns:         STATUS_SUCCESS
+//                   NWE_ACCESS_VIOLATION
+//                   NWE_RESOURCE_LOCK
+//                   NWE_CONN_INVALID
+//                   NWE_INVALID_LEVEL
+//
+//
+//  Abstract:        This API sets information in the connection associated
+//                   with the connection handle.
+//
+//  Notes:           At this time the only setable information levels are:
+//                      NWC_CONN_INFO_AUTH_STATE
+//                      NWC_CONN_INFO_BCAST_STATE
+//
+//  Environment:     PASSIVE_LEVEL, LINUX
+//
+//=======================================================================--
+
+struct nwc_set_conn_info {
+	u32 ConnHandle;
+	u32 uInfoLevel;
+	u32 uInfoLength;
+	void *pConnInfo;
+
+};
+
+//++=======================================================================
+//  API Name:        NwcSetDefaultNameContext
+//
+//  Arguments In::   uTreeLength - Length of tree string.
+//
+//                   pDsTreeName - The tree string (multi-byte).
+//
+//                   uNameLength - The length in bytes of the name
+//                   context string.
+//
+//                   pNameContext - The string to be used as the default
+//                   name context (multi-byte).
+//
+//  Arguments Out:   NONE
+//
+//  Returns:         STATUS_SUCCESS
+//                   NWE_ACCESS_VIOLATION
+//                   NWE_PARAM_INVALID
+//                   NWE_RESOURCE_LOCK
+//                   NWE_STRING_TRANSLATION
+//
+//  Abstract:        This API sets the default name context.
+//
+//  Notes:
+//
+//  Environment:     PASSIVE_LEVEL, LINUX
+//
+//=======================================================================--
+
+struct nwc_set_def_name_ctx {
+	u32 uTreeLength;
+	unsigned char *pDsTreeName;
+	u32 uNameLength;
+// unsined short *pNameContext;
+	unsigned char *pNameContext;
+
+};
+
+//++=======================================================================
+//  API Name:        NwcSetPreferredDsTree
+//
+//  Arguments In:    uTreeLength - The length in bytes of the DS tree name.
+//
+//                   pDsTreeName - The string to be used as the preferred
+//                   DS tree name.
+//
+//  Arguments Out:   NONE
+//
+//  Returns:         STATUS_SUCCESS
+//                   NWE_ACCESS_VIOLATION
+//                   NWE_INSUFFICIENT_RESOURCES
+//                   NWE_RESOURCE_LOCK
+//
+//  Abstract:        This API sets the preferred DS tree name.
+//
+//  Notes:
+//
+//  Environment:     PASSIVE_LEVEL, LINUX
+//
+//=======================================================================--
+
+struct nwc_set_pref_ds_tree {
+	u32 uTreeLength;
+	unsigned char *pDsTreeName;
+
+};
+
+//++=======================================================================
+//  API Name:        NwcSetPrimaryConnection
+//
+//  Arguments In:    ConnHandle - Connection handle associated to the
+//                   connection reference which the caller wishes to set
+//                   as primary.
+//
+//  Arguments Out:   NONE
+//
+//  Returns:         STATUS_SUCCESS
+//                   NWE_ACCESS_VIOLATION
+//                   NWE_CONN_PRIMARY_NOT_SET
+//
+//  Abstract:        This API sets the primary connection according to
+//                   the connection handle passed in by the caller.
+//
+//  Notes:
+//
+//  Environment:     PASSIVE_LEVEL, LINUX
+//
+//=======================================================================--
+
+struct nwc_set_primary_conn {
+	u32 ConnHandle;
+
+};
+
+
+//++=======================================================================
+//  API Name:        NwcQueryFeature
+//
+//  Arguments In:    Feature - The number associated with a particular
+//                   feature that the caller wants to know if the requester
+//                   is supporting
+//
+//  Arguments Out:
+//
+//  Returns:         STATUS_SUCCESS
+//                   NWE_REQUESTER_FAILURE
+//                   NWE_ACCESS_VIOLATION
+//
+//  Abstract:
+//
+//  Notes:
+//
+//  Environment:     PASSIVE_LEVEL, LINUX
+//
+//=======================================================================--
+
+struct nwc_query_feature {
+	u32 Feature;
+
+};
+
+//++=======================================================================
+//  API Name:        NWCChangePassword
+//
+//  Arguments In:
+//
+//  Arguments Out:
+//
+//  Returns:         STATUS_SUCCESS
+//                   NWE_ACCESS_VIOLATION
+//
+//  Abstract:
+//
+//  Notes:
+//
+//  Environment:     PASSIVE_LEVEL, LINUX
+//
+//=======================================================================--
+
+struct nwc_change_key {
+	struct nwc_string *pDomainName;
+	u32 AuthType;
+	struct nwc_string *pObjectName;
+	u32 NameType;
+	u16 ObjectType;
+	struct nwc_string *pVerifyPassword;
+	struct nwc_string *pNewPassword;
+
+};
+
+//++=======================================================================
+//  API Name:        NWCEnumerateIdentities            `
+//
+//  Arguments In:
+//
+//  Arguments Out:
+//
+//  Returns:         STATUS_SUCCESS
+//                   NWE_ACCESS_VIOLATION
+//
+//  Abstract:
+//
+//  Notes:
+//
+//  Environment:     PASSIVE_LEVEL, LINUX
+//
+//=======================================================================--
+
+struct nwc_enum_ids {
+	u32 Iterator;
+	struct nwc_string *pDomainName;
+	u32 AuthType;
+	struct nwc_string *pObjectName;
+	u32 NameType;
+	u16 ObjectType;
+	u32 IdentityFlags;
+	u32 AuthenticationId;
+
+};
+
+//++=======================================================================
+//  API Name:        NWCGetIdentityInfo
+//
+//  Arguments In:
+//
+//  Arguments Out:
+//
+//  Returns:         STATUS_SUCCESS
+//                   NWE_ACCESS_VIOLATION
+//
+//  Abstract:
+//
+//  Notes:
+//
+//  Environment:     PASSIVE_LEVEL, LINUX
+//
+//=======================================================================--
+
+struct nwc_get_id_info {
+	u32 AuthenticationId;
+	struct nwc_string *pDomainName;
+	u32 AuthType;
+	struct nwc_string *pObjectName;
+	u32 NameType;
+	u16 ObjectType;
+	u32 IdentityFlags;
+
+};
+
+//++=======================================================================
+//  API Name:        NWCLoginIdentity
+//
+//  Arguments In:
+//
+//  Arguments Out:
+//
+//  Returns:         STATUS_SUCCESS
+//                   NWE_ACCESS_VIOLATION
+//
+//  Abstract:
+//
+//  Notes:
+//
+//  Environment:     PASSIVE_LEVEL, LINUX
+//
+//=======================================================================--
+
+struct nwc_login_id {
+	struct nwc_string *pDomainName;
+	u32 AuthType;
+	struct nwc_string *pObjectName;
+	u32 NameType;
+	u16 ObjectType;
+	u32 IdentityFlags;
+	struct nwc_string *pPassword;
+	u32 AuthenticationId;
+
+};
+
+
+//++=======================================================================
+//  API Name:        NWCSetPassword
+//
+//  Arguments In:
+//
+//  Arguments Out:
+//
+//  Returns:         STATUS_SUCCESS
+//                   NWE_ACCESS_VIOLATION
+//
+//  Abstract:
+//
+//  Notes:
+//
+//  Environment:     PASSIVE_LEVEL, LINUX
+//
+//=======================================================================--
+
+struct nwc_set_key {
+	u32 ConnHandle;
+	u32 AuthenticationId;
+	struct nwc_string *pObjectName;
+	u16 ObjectType;
+	struct nwc_string *pNewPassword;
+
+};
+
+//++=======================================================================
+//  API Name:        NWCVerifyPassword
+//
+//  Arguments In:
+//
+//  Arguments Out:
+//
+//  Returns:         STATUS_SUCCESS
+//                   NWE_ACCESS_VIOLATION
+//
+//  Abstract:
+//
+//  Notes:
+//
+//  Environment:     PASSIVE_LEVEL, LINUX
+//
+//++=======================================================================
+
+struct nwc_verify_key {
+	struct nwc_string *pDomainName;
+	u32 AuthType;
+	struct nwc_string *pObjectName;
+	u32 NameType;
+	u16 ObjectType;
+	struct nwc_string *pVerifyPassword;
+
+};
+
+//++=======================================================================
+//  API Name:        NwcAuthenticateWithId
+//
+//  Arguments In:    ConnHandle - The connection to be authenticated
+//
+//                   AuthenticationId - the authentication Id associated
+//                   to the information necessary to authenticate this
+//                   connection.
+//
+//  Arguments Out:   NONE
+//
+//  Returns:         STATUS_SUCCESS
+//                   NWE_ACCESS_VIOLATION
+//
+//  Abstract:        This API is used to authenticate a connection using
+//                   an authentication ID that has already been created.
+//
+//  Notes:
+//
+//  Environment:     PASSIVE_LEVEL, LINUX
+//
+//=======================================================================--
+
+struct nwc_auth_with_id {
+	u32 ConnHandle;
+	u32 AuthenticationId;
+
+};
+
+
+struct nwc_unmap_drive_ex {
+//         unsigned long      connHdl;
+	unsigned int linkLen;
+	char linkData[1];
+
+};
+
+struct nwc_map_drive_ex {
+	u32 ConnHandle;
+	unsigned int localUid;
+	unsigned int linkOffsetLength;
+	unsigned int linkOffset;
+	unsigned int dirPathOffsetLength;
+	unsigned int dirPathOffset;
+};
+
+struct nwc_get_bcast_notification {
+	u32 uMessageFlags;
+	u32 uConnReference;
+	u32 messageLen;
+	char message[1];
+};
+
+#endif /* __NWCLNX_H__ */
--- /dev/null
+++ b/fs/novfs/nwerror.h
@@ -0,0 +1,658 @@
+/*
+ * NetWare Redirector for Linux
+ * Author: Tom Buckley
+ *
+ * This file contains all return error codes.
+ *
+ * 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.
+ */
+#ifndef __NOVFS_ERROR_H
+#define __NOVFS_ERROR_H
+
+
+/*
+ * Network errors
+ * Decimal values at end of line are 32768 lower than actual
+ */
+
+#define SHELL_ERROR			0x8800
+#define VLM_ERROR			0x8800
+#define ALREADY_ATTACHED		0x8800	// 0    - Attach attempted to server with valid, existing connection
+#define INVALID_CONNECTION		0x8801	// 1    - Request attempted with invalid or non-attached connection handle
+#define DRIVE_IN_USE			0x8802	// 2    - OS/2 only (NOT USED)
+#define CANT_ADD_CDS			0x8803	// 3    - Map drive attempted but unable to add new current directory structure
+#define DRIVE_CANNOT_MAP		0x8803
+#define BAD_DRIVE_BASE			0x8804	// 4    - Map drive attempted with invalid path specification
+#define NET_READ_ERROR			0x8805	// 5    - Attempt to receive from the selected transport failed
+#define NET_RECV_ERROR			0x8805	// 5
+#define UNKNOWN_NET_ERROR		0x8806	// 6    - Network send attempted with an un-specific network error
+#define SERVER_INVALID_SLOT		0x8807	// 7    - Server request attempted with invalid server connection slot
+#define BAD_SERVER_SLOT			0x8807	// 7
+#define NO_SERVER_SLOTS			0x8808	// 8    - Attach attempted to server with no connection slots available
+#define NET_WRITE_ERROR			0x8809	// 9    - Attempt to send on the selected transport failed
+#define CONNECTION_IN_ERROR_STATE	0x8809	// Client-32
+#define NET_SEND_ERROR			0x8809	// 9
+#define SERVER_NO_ROUTE			0x880A	// 10 - Attempted to find route to server where no route exists
+#define BAD_LOCAL_TARGET		0x880B	// 11 - OS/2 only
+#define TOO_MANY_REQ_FRAGS		0x880C	// 12 - Attempted request with too many request fragments specified
+#define CONNECT_LIST_OVERFLOW		0x880D	// 13
+#define BUFFER_OVERFLOW			0x880E	// 14 - Attempt to receive more data than the reply buffer had room for
+#define MORE_DATA_ERROR			0x880E	// Client-32
+#define NO_CONN_TO_SERVER		0x880F	// 15
+#define NO_CONNECTION_TO_SERVER		0x880F	// 15 - Attempt to get connection for a server not connected
+#define NO_ROUTER_FOUND			0x8810	// 16 - OS/2 only
+#define BAD_FUNC_ERROR			0x8811	// 17
+#define INVALID_SHELL_CALL		0x8811	// 17 - Attempted function call to non- existent or illegal function
+#define SCAN_COMPLETE			0x8812
+#define LIP_RESIZE_ERROR		0x8812	// Client-32
+#define UNSUPPORTED_NAME_FORMAT_TYPE	0x8813
+#define INVALID_DIR_HANDLE		0x8813	// Client-32
+#define HANDLE_ALREADY_LICENSED		0x8814
+#define OUT_OF_CLIENT_MEMORY		0x8814	// Client-32
+#define HANDLE_ALREADY_UNLICENSED	0x8815
+#define PATH_NOT_OURS			0x8815	// Client-32
+#define INVALID_NCP_PACKET_LENGTH	0x8816
+#define PATH_IS_PRINT_DEVICE		0x8816	// Client-32
+#define SETTING_UP_TIMEOUT		0x8817
+#define PATH_IS_EXCLUDED_DEVICE		0x8817	// Client-32
+#define SETTING_SIGNALS			0x8818
+#define PATH_IS_INVALID			0x8818	// Client-32
+#define SERVER_CONNECTION_LOST		0x8819
+#define NOT_SAME_DEVICE			0x8819	// Client-32
+#define OUT_OF_HEAP_SPACE		0x881A
+#define INVALID_SERVICE_REQUEST		0x881B
+#define INVALID_SEARCH_HANDLE		0x881B	// Client-32
+#define INVALID_TASK_NUMBER		0x881C
+#define INVALID_DEVICE_HANDLE		0x881C	// Client-32
+#define INVALID_MESSAGE_LENGTH		0x881D
+#define INVALID_SEM_HANDLE		0x881D	// Client-32
+#define EA_SCAN_DONE			0x881E
+#define INVALID_CFG_HANDLE		0x881E	// Client-32
+#define BAD_CONNECTION_NUMBER		0x881F
+#define INVALID_MOD_HANDLE		0x881F	// Client-32
+#define ASYN_FIRST_PASS			0x8820
+#define INVALID_DEVICE_INDEX		0x8821
+#define INVALID_CONN_HANDLE		0x8822
+#define INVALID_QUEUE_ID		0x8823
+#define INVALID_PDEVICE_HANDLE		0x8824
+#define INVALID_JOB_HANDLE		0x8825
+#define INVALID_ELEMENT_ID		0x8826
+#define ALIAS_NOT_FOUND			0x8827
+#define RESOURCE_SUSPENDED		0x8828
+#define INVALID_QUEUE_SPECIFIED		0x8829
+#define DEVICE_ALREADY_OPEN		0x882A
+#define JOB_ALREADY_OPEN		0x882B
+#define QUEUE_NAME_ID_MISMATCH		0x882C
+#define JOB_ALREADY_STARTED		0x882D
+#define SPECT_DAA_TYPE_NOT_SUPPORTED	0x882E
+#define INVALID_ENVIR_HANDLE		0x882F
+#define NOT_SAME_CONNECTION		0x8830	// 48 - Internal server request attempted accross different server connections
+#define PRIMARY_CONNECTION_NOT_SET	0x8831	// 49 - Attempt to retrieve default connection with no primary connection set
+#define NO_PRIMARY_SET			0x8831	// 49
+#define KEYWORD_NOT_FOUND		0x8832	// Client-32
+#define PRINT_CAPTURE_NOT_IN_PROGRESS	0x8832	// Client-32
+#define NO_CAPTURE_SET			0x8832	// 50
+#define NO_CAPTURE_IN_PROGRESS		0x8832	// 50 - Capture information requested on port with no capture in progress
+#define BAD_BUFFER_LENGTH		0x8833	// 51
+#define INVALID_BUFFER_LENGTH		0x8833	// 51 - Used to indicate length which caller requested on a GetDNC or SetDNC was too large
+#define NO_USER_NAME			0x8834	// 52
+#define NO_NETWARE_PRINT_SPOOLER	0x8835	// 53 - Capture requested without having the local print spooler installed
+#define INVALID_PARAMETER		0x8836	// 54 - Attempted function with an invalid function parameter specified
+#define CONFIG_FILE_OPEN_FAILED		0x8837	// 55 - OS/2 only
+#define NO_CONFIG_FILE			0x8838	// 56 - OS/2 only
+#define CONFIG_FILE_READ_FAILED		0x8839	// 57 - OS/2 only
+#define CONFIG_LINE_TOO_LONG		0x883A	// 58 - OS/2 only
+#define CONFIG_LINES_IGNORED		0x883B	// 59 - OS/2 only
+#define NOT_MY_RESOURCE			0x883C	// 60 - Attempted request made with a parameter using foriegn resource
+#define DAEMON_INSTALLED		0x883D	// 61 - OS/2 only
+#define SPOOLER_INSTALLED		0x883E	// 62 - Attempted load of print spooler with print spooler already installed
+#define CONN_TABLE_FULL			0x883F	// 63
+#define CONNECTION_TABLE_FULL		0x883F	// 63 - Attempted to allocate a connection handle with no more local connection table entries
+#define CONFIG_SECTION_NOT_FOUND	0x8840	// 64 - OS/2 only
+#define BAD_TRAN_TYPE			0x8841	// 65
+#define INVALID_TRANSPORT_TYPE		0x8841	// 65 - Attempted function on a connection with an invalid transport selected
+#define TDS_TAG_IN_USE			0x8842	// 66 - OS/2 only
+#define TDS_OUT_OF_MEMORY		0x8843	// 67 - OS/2 only
+#define TDS_INVALID_TAG			0x8844	// 68 - Attempted TDS function with invalid tag
+#define TDS_WRITE_TRUNCATED		0x8845	// 69 - Attempted TDS write with buffer that exceeded buffer
+#define NO_CONNECTION_TO_DS		0x8846	// Client-32
+#define NO_DIRECTORY_SERVICE_CONNECTION	0x8846	// 70
+#define SERVICE_BUSY			0x8846	// 70 - Attempted request made to partially asynchronous function in busy state
+#define NO_SERVER_ERROR			0x8847	// 71 - Attempted connect failed to find any servers responding
+#define BAD_VLM_ERROR			0x8848	// 72 - Attempted function call to non-existant or not-loaded overlay
+#define NETWORK_DRIVE_IN_USE		0x8849	// 73 - Attempted map to network drive that was already mapped
+#define LOCAL_DRIVE_IN_USE		0x884A	// 74 - Attempted map to local drive that was in use
+#define NO_DRIVES_AVAILABLE		0x884B	// 75 - Attempted map to next available drive when none were available
+#define DEVICE_NOT_REDIRECTED		0x884C	// 76 - The device is not redirected
+#define NO_MORE_SFT_ENTRIES		0x884D	// 77 - Maximum number of files was reached
+#define UNLOAD_ERROR			0x884E	// 78 - Attempted unload failed
+#define IN_USE_ERROR			0x884F	// 79 - Attempted re-use of already in use connection entry
+#define TOO_MANY_REP_FRAGS		0x8850	// 80 - Attempted request with too many reply fragments specified
+#define TABLE_FULL			0x8851	// 81 - Attempted to add a name into the name table after it was full
+#ifndef SOCKET_NOT_OPEN
+#define SOCKET_NOT_OPEN			0x8852	// 82 - Listen was posted on unopened socket
+#endif
+#define MEM_MGR_ERROR			0x8853	// 83 - Attempted enhanced memory operation failed
+#define SFT3_ERROR			0x8854	// 84 - An SFT3 switch occured mid-transfer
+#define PREFERRED_NOT_FOUND		0x8855	// 85 - the preferred directory server was not established but another directory server was returned
+#define DEVICE_NOT_RECOGNIZED		0x8856	// 86 - used to determine if the device is not used by VISE so pass it on to the next redirector, if any.
+#define BAD_NET_TYPE			0x8857	// 87 - the network type (Bind/NDS) does not match the server version
+#define ERROR_OPENING_FILE		0x8858	// 88 - generic open failure error, invalid path, access denied, etc..
+#define NO_PREFERRED_SPECIFIED		0x8859	// 89 - no preferred name specified
+#define ERROR_OPENING_SOCKET		0x885A	// 90 - error opening a socket
+#define REQUESTER_FAILURE		0x885A	// Client-32
+#define RESOURCE_ACCESS_DENIED		0x885B	// Client-32
+#define SIGNATURE_LEVEL_CONFLICT	0x8861
+#define NO_LOCK_FOUND			0x8862	// OS/2 - process lock on conn handle failed, process ID not recognized
+#define LOCK_TABLE_FULL			0x8863	// OS/2 - process lock on conn handle failed, process lock table full
+#define INVALID_MATCH_DATA		0x8864
+#define MATCH_FAILED			0x8865
+#define NO_MORE_ENTRIES			0x8866
+#define INSUFFICIENT_RESOURCES		0x8867
+#define STRING_TRANSLATION		0x8868
+#define STRING_TRANSLATION_NEEDED	0x8868	// Client-32
+#define ACCESS_VIOLATION		0x8869
+#define NOT_AUTHENTICATED		0x886A
+#define INVALID_LEVEL			0x886B
+#define RESOURCE_LOCK_ERROR		0x886C
+#define INVALID_NAME_FORMAT		0x886D
+#define OBJECT_EXISTS			0x886E
+#define OBJECT_NOT_FOUND		0x886F
+#define UNSUPPORTED_TRAN_TYPE		0x8870
+#define INVALID_STRING_TYPE		0x8871
+#define INVALID_OWNER			0x8872
+#define UNSUPPORTED_AUTHENTICATOR	0x8873
+#define IO_PENDING			0x8874
+#define INVALID_DRIVE_NUM		0x8875
+#define SHELL_FAILURE			0x88FF
+#define VLM_FAILURE			0x88FF
+
+#define SVC_ALREADY_REGISTERED		0x8880	// Client-32
+#define SVC_REGISTRY_FULL		0x8881	// Client-32
+#define SVC_NOT_REGISTERED		0x8882	// Client-32
+#define OUT_OF_RESOURCES		0x8883	// Client-32
+#define RESOLVE_SVC_FAILED		0x8884	// Client-32
+#define CONNECT_FAILED			0x8885	// Client-32
+#define PROTOCOL_NOT_BOUND		0x8886	// Client-32
+#define AUTHENTICATION_FAILED		0x8887	// Client-32
+#define INVALID_AUTHEN_HANDLE		0x8888	// Client-32
+#define AUTHEN_HANDLE_ALREADY_EXISTS	0x8889	// Client-32
+
+#define DIFF_OBJECT_ALREADY_AUTHEN	0x8890	// Client-32
+#define REQUEST_NOT_SERVICEABLE		0x8891	// Client-32
+#define AUTO_RECONNECT_SO_REBUILD	0x8892	// Client-32
+#define AUTO_RECONNECT_RETRY_REQUEST	0x8893	// Client-32
+#define ASYNC_REQUEST_IN_USE		0x8894	// Client-32
+#define ASYNC_REQUEST_CANCELED		0x8895	// Client-32
+#define SESS_SVC_ALREADY_REGISTERED	0x8896	// Client-32
+#define SESS_SVC_NOT_REGISTERED		0x8897	// Client-32
+#define PREVIOUSLY_AUTHENTICATED	0x8899	// Client-32
+#define RESOLVE_SVC_PARTIAL		0x889A	// Client-32
+#define NO_DEFAULT_SPECIFIED		0x889B	// Client-32
+#define HOOK_REQUEST_NOT_HANDLED	0x889C	// Client-32
+#define HOOK_REQUEST_BUSY		0x889D	// Client-32
+#define HOOK_REQUEST_QUEUED		0x889D	// Client-32
+#define AUTO_RECONNECT_SO_IGNORE	0x889E	// Client-32
+#define ASYNC_REQUEST_NOT_IN_USE	0x889F	// Client-32
+#define AUTO_RECONNECT_FAILURE		0x88A0	// Client-32
+#define NET_ERROR_ABORT_APPLICATION	0x88A1	// Client-32
+#define NET_ERROR_SUSPEND_APPLICATION	0x88A2	// Client-32
+#define NET_ERROR_ABORTED_PROCESS_GROUP	0x88A3	// Client-32
+#define NET_ERROR_PASSWORD_HAS_EXPIRED	0x88A5	// Client-32
+#define NET_ERROR_NETWORK_INACTIVE	0x88A6	// Client-32
+#define REPLY_TRUNCATED			0x88E6	// 230 NLM
+#define UTF8_CONVERSION_FAILED		0x88F0	// NWCALLS
+
+/*
+ * Server Errors
+ */
+
+#define ERR_INSUFFICIENT_SPACE		0x8901	// 001
+#define NLM_INVALID_CONNECTION		0x890A	// 010
+#define ERR_TIMEOUT			0x8910	// 016 - nlm connection timeout
+#define ERR_NO_MORE_ENTRY		0x8914	// 020
+#define ERR_BUFFER_TOO_SMALL		0x8977	// 119
+#define ERR_VOLUME_FLAG_NOT_SET		0x8978	// 120 the service requested, not avail. on the selected vol.
+#define ERR_NO_ITEMS_FOUND		0x8979	// 121
+#define ERR_CONN_ALREADY_TEMP		0x897A	// 122
+#define ERR_CONN_ALREADY_LOGGED_IN	0x897B	// 123
+#define ERR_CONN_NOT_AUTHENTICATED	0x897C	// 124
+#define ERR_CONN_NOT_LOGGED_IN		0x897D	// 125
+#define NCP_BOUNDARY_CHECK_FAILED	0x897E	// 126
+#define ERR_LOCK_WAITING		0x897F	// 127
+#define ERR_LOCK_FAIL			0x8980	// 128
+#define FILE_IN_USE_ERROR		0x8980	// 128
+#define NO_MORE_FILE_HANDLES		0x8981	// 129
+#define NO_OPEN_PRIVILEGES		0x8982	// 130
+#define IO_ERROR_NETWORK_DISK		0x8983	// 131
+#define ERR_AUDITING_HARD_IO_ERROR	0x8983	// 131
+#define NO_CREATE_PRIVILEGES		0x8984	// 132
+#define ERR_AUDITING_NOT_SUPV		0x8984	// 132
+#define NO_CREATE_DELETE_PRIVILEGES	0x8985	// 133
+#define CREATE_FILE_EXISTS_READ_ONLY	0x8986	// 134
+#define WILD_CARDS_IN_CREATE_FILE_NAME	0x8987	// 135
+#define CREATE_FILENAME_ERROR		0x8987	// 135
+#define INVALID_FILE_HANDLE		0x8988	// 136
+#define NO_SEARCH_PRIVILEGES		0x8989	// 137
+#define NO_DELETE_PRIVILEGES		0x898A	// 138
+#define NO_RENAME_PRIVILEGES		0x898B	// 139
+#define NO_MODIFY_PRIVILEGES		0x898C	// 140
+#define SOME_FILES_AFFECTED_IN_USE	0x898D	// 141
+#define NO_FILES_AFFECTED_IN_USE	0x898E	// 142
+#define SOME_FILES_AFFECTED_READ_ONLY	0x898F	// 143
+#define NO_FILES_AFFECTED_READ_ONLY	0x8990	// 144
+#define SOME_FILES_RENAMED_NAME_EXISTS	0x8991	// 145
+#define NO_FILES_RENAMED_NAME_EXISTS	0x8992	// 146
+#define NO_READ_PRIVILEGES		0x8993	// 147
+#define NO_WRITE_PRIVILEGES_OR_READONLY	0x8994	// 148
+#define FILE_DETACHED			0x8995	// 149
+#define SERVER_OUT_OF_MEMORY		0x8996	// 150
+#define ERR_TARGET_NOT_A_SUBDIRECTORY	0x8996	// 150 can be changed later (note written by server people).
+#define NO_DISK_SPACE_FOR_SPOOL_FILE	0x8997	// 151
+#define ERR_AUDITING_NOT_ENABLED	0x8997	// 151
+#define VOLUME_DOES_NOT_EXIST		0x8998	// 152
+#define DIRECTORY_FULL			0x8999	// 153
+#define RENAMING_ACROSS_VOLUMES		0x899A	// 154
+#define BAD_DIRECTORY_HANDLE		0x899B	// 155
+#define INVALID_PATH			0x899C	// 156
+#define NO_MORE_TRUSTEES		0x899C	// 156
+#define NO_MORE_DIRECTORY_HANDLES	0x899D	// 157
+#define INVALID_FILENAME		0x899E	// 158
+#define DIRECTORY_ACTIVE		0x899F	// 159
+#define DIRECTORY_NOT_EMPTY		0x89A0	// 160
+#define DIRECTORY_IO_ERROR		0x89A1	// 161
+#define READ_FILE_WITH_RECORD_LOCKED	0x89A2	// 162
+#define ERR_TRANSACTION_RESTARTED	0x89A3	// 163
+#define ERR_RENAME_DIR_INVALID		0x89A4	// 164
+#define ERR_INVALID_OPENCREATE_MODE	0x89A5	// 165
+#define ERR_ALREADY_IN_USE		0x89A6	// 166
+#define ERR_AUDITING_ACTIVE		0x89A6	// 166
+#define ERR_INVALID_RESOURCE_TAG	0x89A7	// 167
+#define ERR_ACCESS_DENIED		0x89A8	// 168
+#define ERR_AUDITING_NO_RIGHTS		0x89A8	// 168
+#define ERR_LINK_IN_PATH		0x89A9	// 169
+#define INVALID_DATA_TYPE		0x89AA	// 170
+#define INVALID_DATA_STREAM		0x89BE	// 190
+#define INVALID_NAME_SPACE		0x89BF	// 191
+#define NO_ACCOUNTING_PRIVILEGES	0x89C0	// 192
+#define LOGIN_DENIED_NO_ACCOUNT_BALANCE	0x89C1	// 193
+#define LOGIN_DENIED_NO_CREDIT		0x89C2	// 194
+#define ERR_AUDITING_RECORD_SIZE	0x89C2	// 194
+#define ERR_TOO_MANY_HOLDS		0x89C3	// 195
+#define ACCOUNTING_DISABLED		0x89C4	// 196
+#define INTRUDER_DETECTION_LOCK		0x89C5	// 197
+#define NO_CONSOLE_OPERATOR		0x89C6	// 198
+#define NO_CONSOLE_PRIVILEGES		0x89C6	// 198
+#define ERR_Q_IO_FAILURE		0x89D0	// 208
+#define ERR_NO_QUEUE			0x89D1	// 209
+#define ERR_NO_Q_SERVER			0x89D2	// 210
+#define ERR_NO_Q_RIGHTS			0x89D3	// 211
+#define ERR_Q_FULL			0x89D4	// 212
+#define ERR_NO_Q_JOB			0x89D5	// 213
+#define ERR_NO_Q_JOB_RIGHTS		0x89D6	// 214
+#define ERR_Q_IN_SERVICE		0x89D7	// 215
+#define PASSWORD_NOT_UNIQUE		0x89D7	// 215
+#define ERR_Q_NOT_ACTIVE		0x89D8	// 216
+#define PASSWORD_TOO_SHORT		0x89D8	// 216
+#define ERR_Q_STN_NOT_SERVER		0x89D9	// 217
+#define LOGIN_DENIED_NO_CONNECTION	0x89D9	// 217
+#define ERR_MAXIMUM_LOGINS_EXCEEDED	0x89D9	// 217
+#define ERR_Q_HALTED			0x89DA	// 218
+#define UNAUTHORIZED_LOGIN_TIME		0x89DA	// 218
+#define UNAUTHORIZED_LOGIN_STATION	0x89DB	// 219
+#define ERR_Q_MAX_SERVERS		0x89DB	// 219
+#define ACCOUNT_DISABLED		0x89DC	// 220
+#define PASSWORD_HAS_EXPIRED_NO_GRACE	0x89DE	// 222
+#define PASSWORD_HAS_EXPIRED		0x89DF	// 223
+#define E_NO_MORE_USERS			0x89E7	// 231
+#define NOT_ITEM_PROPERTY		0x89E8	// 232
+#define WRITE_PROPERTY_TO_GROUP		0x89E8	// 232
+#define MEMBER_ALREADY_EXISTS		0x89E9	// 233
+#define NO_SUCH_MEMBER			0x89EA	// 234
+#define NOT_GROUP_PROPERTY		0x89EB	// 235
+#define NO_SUCH_SEGMENT			0x89EC	// 236
+#define PROPERTY_ALREADY_EXISTS		0x89ED	// 237
+#define OBJECT_ALREADY_EXISTS		0x89EE	// 238
+#define INVALID_NAME			0x89EF	// 239
+#define WILD_CARD_NOT_ALLOWED		0x89F0	// 240
+#define INVALID_BINDERY_SECURITY	0x89F1	// 241
+#define NO_OBJECT_READ_PRIVILEGE	0x89F2	// 242
+#define NO_OBJECT_RENAME_PRIVILEGE	0x89F3	// 243
+#define NO_OBJECT_DELETE_PRIVILEGE	0x89F4	// 244
+#define NO_OBJECT_CREATE_PRIVILEGE	0x89F5	// 245
+#define NO_PROPERTY_DELETE_PRIVILEGE	0x89F6	// 246
+#define NO_PROPERTY_CREATE_PRIVILEGE	0x89F7	// 247
+#define NO_PROPERTY_WRITE_PRIVILEGE	0x89F8	// 248
+#define NO_FREE_CONNECTION_SLOTS	0x89F9	// 249
+#define NO_PROPERTY_READ_PRIVILEGE	0x89F9	// 249
+#define NO_MORE_SERVER_SLOTS		0x89FA	// 250
+#define TEMP_REMAP_ERROR		0x89FA	// 250
+#define INVALID_PARAMETERS		0x89FB	// 251
+#define NO_SUCH_PROPERTY		0x89FB	// 251
+#define ERR_NCP_NOT_SUPPORTED		0x89FB	// 251
+#define INTERNET_PACKET_REQT_CANCELED	0x89FC	// 252
+#define UNKNOWN_FILE_SERVER		0x89FC	// 252
+#define MESSAGE_QUEUE_FULL		0x89FC	// 252
+#define NO_SUCH_OBJECT			0x89FC	// 252
+#define LOCK_COLLISION			0x89FD	// 253
+#define BAD_STATION_NUMBER		0x89FD	// 253
+#define INVALID_PACKET_LENGTH		0x89FD	// 253
+#define UNKNOWN_REQUEST			0x89FD	// 253
+#define BINDERY_LOCKED			0x89FE	// 254
+#define TRUSTEE_NOT_FOUND		0x89FE	// 254
+#define DIRECTORY_LOCKED		0x89FE	// 254
+#define INVALID_SEMAPHORE_NAME_LENGTH	0x89FE	// 254
+#define PACKET_NOT_DELIVERABLE		0x89FE	// 254
+#define SERVER_BINDERY_LOCKED		0x89FE	// 254
+#define SOCKET_TABLE_FULL		0x89FE	// 254
+#define SPOOL_DIRECTORY_ERROR		0x89FE	// 254
+#define SUPERVISOR_HAS_DISABLED_LOGIN	0x89FE	// 254
+#define TIMEOUT_FAILURE			0x89FE	// 254
+#define BAD_PRINTER_ERROR		0x89FF	// 255
+#define BAD_RECORD_OFFSET		0x89FF	// 255
+#define CLOSE_FCB_ERROR			0x89FF	// 255
+#define FILE_EXTENSION_ERROR		0x89FF	// 255
+#define FILE_NAME_ERROR			0x89FF	// 255
+#define HARDWARE_FAILURE		0x89FF	// 255
+#define INVALID_DRIVE_NUMBER		0x89FF	// 255
+#define DOS_INVALID_DRIVE		0x000F	// 255
+#define INVALID_INITIAL_SEMAPHORE_VALUE	0x89FF	// 255
+#define INVALID_SEMAPHORE_HANDLE	0x89FF	// 255
+#define IO_BOUND_ERROR			0x89FF	// 255
+#define NO_FILES_FOUND_ERROR		0x89FF	// 255
+#define NO_RESPONSE_FROM_SERVER		0x89FF	// 255
+#define NO_SUCH_OBJECT_OR_BAD_PASSWORD	0x89FF	// 255
+#define PATH_NOT_LOCATABLE		0x89FF	// 255
+#define QUEUE_FULL_ERROR		0x89FF	// 255
+#define REQUEST_NOT_OUTSTANDING		0x89FF	// 255
+#ifndef SOCKET_ALREADY_OPEN
+#define SOCKET_ALREADY_OPEN		0x89FF	// 255
+#endif
+#define LOCK_ERROR			0x89FF	// 255
+#ifndef FAILURE
+#define FAILURE				0x89FF	// 255 Generic Failure
+#endif
+
+#if 0
+#define NOT_SAME_LOCAL_DRIVE		0x89F6
+#define TARGET_DRIVE_NOT_LOCAL	0x89F7
+#define ALREADY_ATTACHED_TO_SERVER	0x89F8	// 248
+#define NOT_ATTACHED_TO_SERVER	0x89F8
+#endif
+
+/*
+ * Network errors
+ * Decimal values at end of line are 32768 lower than actual
+ */
+#define NWE_ALREADY_ATTACHED		0x8800	// 0    - Attach attempted to server with valid, existing connection
+#define NWE_CONN_INVALID		0x8801	// 1    - Request attempted with invalid or non-attached connection handle
+#define NWE_DRIVE_IN_USE		0x8802	// 2    - OS/2 only (NOT USED)
+#define NWE_DRIVE_CANNOT_MAP		0x8803	// 3    - Map drive attempted but unable to add new current directory structure
+#define NWE_DRIVE_BAD_PATH		0x8804	// 4    - Map drive attempted with invalid path specification
+#define NWE_NET_RECEIVE			0x8805	// 5    - Attempt to receive from the selected transport failed
+#define NWE_NET_UNKNOWN			0x8806	// 6    - Network send attempted with an un-specific network error
+#define NWE_SERVER_BAD_SLOT		0x8807	// 7    - Server request attempted with invalid server connection slot
+#define NWE_SERVER_NO_SLOTS		0x8808	// 8    - Attach attempted to server with no connection slots available
+#define NWE_NET_SEND			0x8809	// 9    - Attempt to send on the selected transport failed
+#define NWE_SERVER_NO_ROUTE		0x880A	// 10 - Attempted to find route to server where no route exists
+#define NWE_BAD_LOCAL_TARGET		0x880B	// 11 - OS/2 only
+#define NWE_REQ_TOO_MANY_REQ_FRAGS	0x880C	// 12 - Attempted request with too many request fragments specified
+#define NWE_CONN_LIST_OVERFLOW		0x880D	// 13
+#define NWE_BUFFER_OVERFLOW		0x880E	// 14 - Attempt to receive more data than the reply buffer had room for
+#define NWE_SERVER_NO_CONN		0x880F	// 15 - Attempt to get connection for a server not connected
+#define NWE_NO_ROUTER_FOUND		0x8810	// 16 - OS/2 only
+#define NWE_FUNCTION_INVALID		0x8811	// 17 - Attempted function call to non- existent or illegal function
+#define NWE_SCAN_COMPLETE		0x8812
+#define NWE_UNSUPPORTED_NAME_FORMAT_TYP	0x8813
+#define NWE_HANDLE_ALREADY_LICENSED	0x8814
+#define NWE_HANDLE_ALREADY_UNLICENSED	0x8815
+#define NWE_INVALID_NCP_PACKET_LENGTH	0x8816
+#define NWE_SETTING_UP_TIMEOUT		0x8817
+#define NWE_SETTING_SIGNALS		0x8818
+#define NWE_SERVER_CONNECTION_LOST	0x8819
+#define NWE_OUT_OF_HEAP_SPACE		0x881A
+#define NWE_INVALID_SERVICE_REQUEST	0x881B
+#define NWE_INVALID_TASK_NUMBER		0x881C
+#define NWE_INVALID_MESSAGE_LENGTH	0x881D
+#define NWE_EA_SCAN_DONE		0x881E
+#define NWE_BAD_CONNECTION_NUMBER	0x881F
+#define NWE_MULT_TREES_NOT_SUPPORTED	0x8820	// 32 - Attempt to open a connection to a DS tree other than the default tree
+#define NWE_CONN_NOT_SAME		0x8830	// 48 - Internal server request attempted across different server connections
+#define NWE_CONN_PRIMARY_NOT_SET	0x8831	// 49 - Attempt to retrieve default connection with no primary connection set
+#define NWE_PRN_CAPTURE_NOT_IN_PROGRESS	0x8832	// 50 - Capture information requested on port with no capture in progress
+#define NWE_BUFFER_INVALID_LEN		0x8833	// 51 - Used to indicate length which caller requested on a GetDNC or SetDNC was too large
+#define NWE_USER_NO_NAME		0x8834	// 52
+#define NWE_PRN_NO_LOCAL_SPOOLER	0x8835	// 53 - Capture requested without having the local print spooler installed
+#define NWE_PARAM_INVALID		0x8836	// 54 - Attempted function with an invalid function parameter specified
+#define NWE_CFG_OPEN_FAILED		0x8837	// 55 - OS/2 only
+#define NWE_CFG_NO_FILE			0x8838	// 56 - OS/2 only
+#define NWE_CFG_READ_FAILED		0x8839	// 57 - OS/2 only
+#define NWE_CFG_LINE_TOO_LONG		0x883A	// 58 - OS/2 only
+#define NWE_CFG_LINES_IGNORED		0x883B	// 59 - OS/2 only
+#define NWE_RESOURCE_NOT_OWNED		0x883C	// 60 - Attempted request made with a parameter using foriegn resource
+#define NWE_DAEMON_INSTALLED		0x883D	// 61 - OS/2 only
+#define NWE_PRN_SPOOLER_INSTALLED	0x883E	// 62 - Attempted load of print spooler with print spooler already installed
+#define NWE_CONN_TABLE_FULL		0x883F	// 63 - Attempted to allocate a connection handle with no more local connection table entries
+#define NWE_CFG_SECTION_NOT_FOUND	0x8840	// 64 - OS/2 only
+#define NWE_TRAN_INVALID_TYPE		0x8841	// 65 - Attempted function on a connection with an invalid transport selected
+#define NWE_TDS_TAG_IN_USE		0x8842	// 66 - OS/2 only
+#define NWE_TDS_OUT_OF_MEMORY		0x8843	// 67 - OS/2 only
+#define NWE_TDS_INVALID_TAG		0x8844	// 68 - Attempted TDS function with invalid tag
+#define NWE_TDS_WRITE_TRUNCATED		0x8845	// 69 - Attempted TDS write with buffer that exceeded buffer
+#define NWE_DS_NO_CONN			0x8846	// 70
+#define NWE_SERVICE_BUSY		0x8846	// 70 - Attempted request made to partially asynchronous function in busy state
+#define NWE_SERVER_NOT_FOUND		0x8847	// 71 - Attempted connect failed to find any servers responding
+#define NWE_VLM_INVALID			0x8848	// 72 - Attempted function call to non-existant or not-loaded overlay
+#define NWE_DRIVE_ALREADY_MAPPED	0x8849	// 73 - Attempted map to network drive that was already mapped
+#define NWE_DRIVE_LOCAL_IN_USE		0x884A	// 74 - Attempted map to local drive that was in use
+#define NWE_DRIVE_NONE_AVAILABLE	0x884B	// 75 - Attempted map to next available drive when none were available
+#define NWE_DEVICE_NOT_REDIRECTED	0x884C	// 76 - The device is not redirected
+#define NWE_FILE_MAX_REACHED		0x884D	// 77 - Maximum number of files was reached
+#define NWE_UNLOAD_FAILED		0x884E	// 78 - Attempted unload failed
+#define NWE_CONN_IN_USE			0x884F	// 79 - Attempted re-use of already in use connection entry
+#define NWE_REQ_TOO_MANY_REP_FRAGS	0x8850	// 80 - Attempted request with too many reply fragments specified
+#define NWE_NAME_TABLE_FULL		0x8851	// 81 - Attempted to add a name into the name table after it was full
+#define NWE_SOCKET_NOT_OPEN		0x8852	// 82 - Listen was posted on unopened socket
+#define NWE_MEMORY_MGR_ERROR		0x8853	// 83 - Attempted enhanced memory operation failed
+#define NWE_SFT3_ERROR			0x8854	// 84 - An SFT3 switch occured mid-transfer
+#define NWE_DS_PREFERRED_NOT_FOUND	0x8855	// 85 - the preferred directory server was not established but another directory server was returned
+#define NWE_DEVICE_NOT_RECOGNIZED	0x8856	// 86 - used to determine if the device is not used by VISE so pass it on to the next redirector, if any.
+#define NWE_NET_INVALID_TYPE		0x8857	// 87 - the network type (Bind/NDS) does not match the server version
+#define NWE_FILE_OPEN_FAILED		0x8858	// 88 - generic open failure error, invalid path, access denied, etc..
+#define NWE_DS_PREFERRED_NOT_SPECIFIED	0x8859	// 89 - no preferred name specified
+#define NWE_SOCKET_OPEN_FAILED		0x885A	// 90 - error opening a socket
+#define NWE_SIGNATURE_LEVEL_CONFLICT	0x8861
+#define NWE_NO_LOCK_FOUND		0x8862	// OS/2 - process lock on conn handle failed, process ID not recognized
+#define NWE_LOCK_TABLE_FULL		0x8863	// OS/2 - process lock on conn handle failed, process lock table full
+#define NWE_INVALID_MATCH_DATA		0x8864
+#define NWE_MATCH_FAILED		0x8865
+#define NWE_NO_MORE_ENTRIES		0x8866
+#define NWE_INSUFFICIENT_RESOURCES	0x8867
+#define NWE_STRING_TRANSLATION		0x8868
+#define NWE_ACCESS_VIOLATION		0x8869
+#define NWE_NOT_AUTHENTICATED		0x886A
+#define NWE_INVALID_LEVEL		0x886B
+#define NWE_RESOURCE_LOCK		0x886C
+#define NWE_INVALID_NAME_FORMAT		0x886D
+#define NWE_OBJECT_EXISTS		0x886E
+#define NWE_OBJECT_NOT_FOUND		0x886F
+#define NWE_UNSUPPORTED_TRAN_TYPE	0x8870
+#define NWE_INVALID_STRING_TYPE		0x8871
+#define NWE_INVALID_OWNER		0x8872
+#define NWE_UNSUPPORTED_AUTHENTICATOR	0x8873
+#define NWE_IO_PENDING			0x8874
+#define NWE_INVALID_DRIVE_NUMBER	0x8875
+#define NWE_REPLY_TRUNCATED		0x88e6	// 230 NLM
+#define NWE_REQUESTER_FAILURE		0x88FF
+
+/*
+ * Server Errors
+ */
+#define NWE_INSUFFICIENT_SPACE		0x8901	// 001
+#define NWE_INVALID_CONNECTION		0x890a	// 010 - nlm invalid connection
+#define NWE_TIMEOUT			0x8910	// 016 - nlm connection timeout
+#define NWE_NO_MORE_ENTRY		0x8914	// 020
+#define NWE_BUFFER_TOO_SMALL		0x8977	// 119
+#define NWE_VOL_FLAG_NOT_SET		0x8978	// 120 the service requested, not avail. on the selected vol.
+#define NWE_NO_ITEMS_FOUND		0x8979	// 121
+#define NWE_CONN_ALREADY_TEMP		0x897a	// 122
+#define NWE_CONN_ALREADY_LOGGED_IN	0x897b	// 123
+#define NWE_CONN_NOT_AUTHENTICATED	0x897c	// 124
+#define NWE_CONN_NOT_LOGGED_IN		0x897d	// 125
+#define NWE_NCP_BOUNDARY_CHECK_FAILED	0x897e	// 126
+#define NWE_LOCK_WAITING		0x897f	// 127
+#define NWE_LOCK_FAIL			0x8980	// 128
+#define NWE_FILE_IN_USE			0x8980	// 128
+#define NWE_FILE_NO_HANDLES		0x8981	// 129
+#define NWE_FILE_NO_OPEN_PRIV		0x8982	// 130
+#define NWE_DISK_IO_ERROR		0x8983	// 131
+#define NWE_AUDITING_HARD_IO_ERROR	0x8983	// 131
+#define NWE_FILE_NO_CREATE_PRIV		0x8984	// 132
+#define NWE_AUDITING_NOT_SUPV		0x8984	// 132
+#define NWE_FILE_NO_CREATE_DEL_PRIV	0x8985	// 133
+#define NWE_FILE_EXISTS_READ_ONLY	0x8986	// 134
+#define NWE_FILE_WILD_CARDS_IN_NAME	0x8987	// 135
+#define NWE_FILE_INVALID_HANDLE		0x8988	// 136
+#define NWE_FILE_NO_SRCH_PRIV		0x8989	// 137
+#define NWE_FILE_NO_DEL_PRIV		0x898A	// 138
+#define NWE_FILE_NO_RENAME_PRIV		0x898B	// 139
+#define NWE_FILE_NO_MOD_PRIV		0x898C	// 140
+#define NWE_FILE_SOME_IN_USE		0x898D	// 141
+#define NWE_FILE_NONE_IN_USE		0x898E	// 142
+#define NWE_FILE_SOME_READ_ONLY		0x898F	// 143
+#define NWE_FILE_NONE_READ_ONLY		0x8990	// 144
+#define NWE_FILE_SOME_RENAMED_EXIST	0x8991	// 145
+#define NWE_FILE_NONE_RENAMED_EXIST	0x8992	// 146
+#define NWE_FILE_NO_READ_PRIV		0x8993	// 147
+#define NWE_FILE_NO_WRITE_PRIV		0x8994	// 148
+#define NWE_FILE_READ_ONLY		0x8994	// 148
+#define NWE_FILE_DETACHED		0x8995	// 149
+#define NWE_SERVER_OUT_OF_MEMORY	0x8996	// 150
+#define NWE_DIR_TARGET_INVALID		0x8996	// 150
+#define NWE_DISK_NO_SPOOL_SPACE		0x8997	// 151
+#define NWE_AUDITING_NOT_ENABLED	0x8997	// 151
+#define NWE_VOL_INVALID			0x8998	// 152
+#define NWE_DIR_FULL			0x8999	// 153
+#define NWE_VOL_RENAMING_ACROSS		0x899A	// 154
+#define NWE_DIRHANDLE_INVALID		0x899B	// 155
+#define NWE_PATH_INVALID		0x899C	// 156
+#define NWE_TRUSTEES_NO_MORE		0x899C	// 156
+#define NWE_DIRHANDLE_NO_MORE		0x899D	// 157
+#define NWE_FILE_NAME_INVALID		0x899E	// 158
+#define NWE_DIR_ACTIVE			0x899F	// 159
+#define NWE_DIR_NOT_EMPTY		0x89A0	// 160
+#define NWE_DIR_IO_ERROR		0x89A1	// 161
+#define NWE_FILE_IO_LOCKED		0x89A2	// 162
+#define NWE_TTS_RANSACTION_RESTARTED	0x89A3	// 163
+#define NWE_TTS_TRANSACTION_RESTARTED	0x89A3	// 163
+#define NWE_DIR_RENAME_INVALID		0x89A4	// 164
+#define NWE_FILE_OPENCREAT_MODE_INVALID	0x89A5	// 165
+#define NWE_ALREADY_IN_USE		0x89A6	// 166
+#define NWE_AUDITING_ACTIVE		0x89A6	// 166
+#define NWE_RESOURCE_TAG_INVALID	0x89A7	// 167
+#define NWE_ACCESS_DENIED		0x89A8	// 168
+#define NWE_AUDITING_NO_RIGHTS		0x89A8	// 168
+#define NWE_LINK_IN_PATH		0x89A9	// 169
+#define NWE_INVALID_DATA_TYPE_FLAG	0x89AA	// 170 (legacy vol with UTF8)
+#define NWE_DATA_STREAM_INVALID		0x89BE	// 190
+#define NWE_NAME_SPACE_INVALID		0x89BF	// 191
+#define NWE_ACCTING_NO_PRIV		0x89C0	// 192
+#define NWE_ACCTING_NO_BALANCE		0x89C1	// 193
+#define NWE_ACCTING_NO_CREDIT		0x89C2	// 194
+#define NWE_AUDITING_RECORD_SIZE	0x89C2	// 194
+#define NWE_ACCTING_TOO_MANY_HOLDS	0x89C3	// 195
+#define NWE_ACCTING_DISABLED		0x89C4	// 196
+#define NWE_LOGIN_LOCKOUT		0x89C5	// 197
+#define NWE_CONSOLE_NO_PRIV		0x89C6	// 198
+#define NWE_Q_IO_FAILURE		0x89D0	// 208
+#define NWE_Q_NONE			0x89D1	// 209
+#define NWE_Q_NO_SERVER			0x89D2	// 210
+#define NWE_Q_NO_RIGHTS			0x89D3	// 211
+#define NWE_Q_FULL			0x89D4	// 212
+#define NWE_Q_NO_JOB			0x89D5	// 213
+#define NWE_Q_NO_JOB_RIGHTS		0x89D6	// 214
+#define NWE_PASSWORD_UNENCRYPTED	0x89D6	// 214
+#define NWE_Q_IN_SERVICE		0x89D7	// 215
+#define NWE_PASSWORD_NOT_UNIQUE		0x89D7	// 215
+#define NWE_Q_NOT_ACTIVE		0x89D8	// 216
+#define NWE_PASSWORD_TOO_SHORT		0x89D8	// 216
+#define NWE_Q_STN_NOT_SERVER		0x89D9	// 217
+#define NWE_LOGIN_NO_CONN		0x89D9	// 217
+#define NWE_LOGIN_MAX_EXCEEDED		0x89D9	// 217
+#define NWE_Q_HALTED			0x89DA	// 218
+#define NWE_LOGIN_UNAUTHORIZED_TIME	0x89DA	// 218
+#define NWE_LOGIN_UNAUTHORIZED_STATION	0x89DB	// 219
+#define NWE_Q_MAX_SERVERS		0x89DB	// 219
+#define NWE_ACCT_DISABLED		0x89DC	// 220
+#define NWE_PASSWORD_INVALID		0x89DE	// 222
+#define NWE_PASSWORD_EXPIRED		0x89DF	// 223
+#define NWE_LOGIN_NO_CONN_AVAIL		0x89E0	// 224
+#define NWE_E_NO_MORE_USERS		0x89E7	// 231
+#define NWE_BIND_NOT_ITEM_PROP		0x89E8	// 232
+#define NWE_BIND_WRITE_TO_GROUP_PROP	0x89E8	// 232
+#define NWE_BIND_MEMBER_ALREADY_EXISTS	0x89E9	// 233
+#define NWE_BIND_NO_SUCH_MEMBER		0x89EA	// 234
+#define NWE_BIND_NOT_GROUP_PROP		0x89EB	// 235
+#define NWE_BIND_NO_SUCH_SEGMENT	0x89EC	// 236
+#define NWE_BIND_PROP_ALREADY_EXISTS	0x89ED	// 237
+#define NWE_BIND_OBJ_ALREADY_EXISTS	0x89EE	// 238
+#define NWE_BIND_NAME_INVALID		0x89EF	// 239
+#define NWE_BIND_WILDCARD_INVALID	0x89F0	// 240
+#define NWE_BIND_SECURITY_INVALID	0x89F1	// 241
+#define NWE_BIND_OBJ_NO_READ_PRIV	0x89F2	// 242
+#define NWE_BIND_OBJ_NO_RENAME_PRIV	0x89F3	// 243
+#define NWE_BIND_OBJ_NO_DELETE_PRIV	0x89F4	// 244
+#define NWE_BIND_OBJ_NO_CREATE_PRIV	0x89F5	// 245
+#define NWE_BIND_PROP_NO_DELETE_PRIV	0x89F6	// 246
+#define NWE_BIND_PROP_NO_CREATE_PRIV	0x89F7	// 247
+#define NWE_BIND_PROP_NO_WRITE_PRIV	0x89F8	// 248
+#define NWE_BIND_PROP_NO_READ_PRIV	0x89F9	// 249
+#define NWE_NO_FREE_CONN_SLOTS		0x89F9	// 249
+#define NWE_NO_MORE_SERVER_SLOTS	0x89FA	// 250
+#define NWE_TEMP_REMAP_ERROR		0x89FA	// 250
+#define NWE_PARAMETERS_INVALID		0x89FB	// 251
+#define NWE_BIND_NO_SUCH_PROP		0x89FB	// 251
+#define NWE_NCP_NOT_SUPPORTED		0x89FB	// 251
+#define NWE_INET_PACKET_REQ_CANCELED	0x89FC	// 252
+#define NWE_SERVER_UNKNOWN		0x89FC	// 252
+#define NWE_MSG_Q_FULL			0x89FC	// 252
+#define NWE_BIND_NO_SUCH_OBJ		0x89FC	// 252
+#define NWE_LOCK_COLLISION		0x89FD	// 253
+#define NWE_CONN_NUM_INVALID		0x89FD	// 253
+#define NWE_PACKET_LEN_INVALID		0x89FD	// 253
+#define NWE_UNKNOWN_REQ			0x89FD	// 253
+#define NWE_BIND_LOCKED			0x89FE	// 254
+#define NWE_TRUSTEE_NOT_FOUND		0x89FE	// 254
+#define NWE_DIR_LOCKED			0x89FE	// 254
+#define NWE_SEM_INVALID_NAME_LEN	0x89FE	// 254
+#define NWE_PACKET_NOT_DELIVERABLE	0x89FE	// 254
+#define NWE_SOCKET_TABLE_FULL		0x89FE	// 254
+#define NWE_SPOOL_DIR_ERROR		0x89FE	// 254
+#define NWE_LOGIN_DISABLED_BY_SUPER	0x89FE	// 254
+#define NWE_TIMEOUT_FAILURE		0x89FE	// 254
+#define NWE_FILE_EXT			0x89FF	// 255
+#define NWE_FILE_NAME			0x89FF	// 255
+#define NWE_HARD_FAILURE		0x89FF	// 255
+#define NWE_FCB_CLOSE			0x89FF	// 255
+#define NWE_IO_BOUND			0x89FF	// 255
+#define NWE_BAD_SPOOL_PRINTER		0x89FF	// 255
+#define NWE_BAD_RECORD_OFFSET		0x89FF	// 255
+#define NWE_DRIVE_INVALID_NUM		0x89FF	// 255
+#define NWE_SEM_INVALID_INIT_VAL	0x89FF	// 255
+#define NWE_SEM_INVALID_HANDLE		0x89FF	// 255
+#define NWE_NO_FILES_FOUND_ERROR	0x89FF	// 255
+#define NWE_NO_RESPONSE_FROM_SERVER	0x89FF	// 255
+#define NWE_NO_OBJ_OR_BAD_PASSWORD	0x89FF	// 255
+#define NWE_PATH_NOT_LOCATABLE		0x89FF	// 255
+#define NWE_Q_FULL_ERROR		0x89FF	// 255
+#define NWE_REQ_NOT_OUTSTANDING		0x89FF	// 255
+#define NWE_SOCKET_ALREADY_OPEN		0x89FF	// 255
+#define NWE_LOCK_ERROR			0x89FF	// 255
+#define NWE_FAILURE			0x89FF	// 255 Generic Failure
+
+#endif	/* __NOVFS_ERROR_H */
--- /dev/null
+++ b/fs/novfs/proc.c
@@ -0,0 +1,149 @@
+/*
+ * Novell NCP Redirector for Linux
+ * Author: James Turner
+ *
+ * This module contains functions that create the interface to the proc
+ * filesystem.
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/proc_fs.h>
+#include <linux/smp_lock.h>
+
+#include "vfs.h"
+
+struct proc_dir_entry *novfs_procfs_dir;
+struct proc_dir_entry *Novfs_Control;
+struct proc_dir_entry *Novfs_Library;
+struct proc_dir_entry *Novfs_Version;
+
+static struct file_operations novfs_daemon_proc_fops;
+static struct file_operations novfs_lib_proc_fops;
+
+/*===[ Code ]=============================================================*/
+
+static int Novfs_Get_Version(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	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 = novfs_daemon_getversion(tbuf, sizeof(tbuf));
+		if ((i > 0) && i < (count - len)) {
+			len += sprintf(buf + len, "Novfsd Version=%s\n", tbuf);
+		}
+
+		if (novfs_current_mnt) {
+			i = strlen(novfs_current_mnt);
+			if ((i > 0) && i < (count - len)) {
+				len +=
+				    sprintf(buf + len, "Novfs mount=%s\n",
+					    novfs_current_mnt);
+			}
+		}
+		DbgPrint("%s", buf);
+	}
+	*eof = 1;
+	return (len);
+}
+
+int novfs_proc_init(void)
+{
+	int retCode = 0;
+
+	novfs_procfs_dir = proc_mkdir(MODULE_NAME, NULL);
+	if (novfs_procfs_dir) {
+
+		Novfs_Control = create_proc_entry("Control", 0600, novfs_procfs_dir);
+
+		if (Novfs_Control) {
+			Novfs_Control->size = 0;
+			memcpy(&novfs_daemon_proc_fops,
+					Novfs_Control->proc_fops,
+					sizeof(struct file_operations));
+
+			/*
+			 * Setup our functions
+			 */
+			novfs_daemon_proc_fops.owner = THIS_MODULE;
+			novfs_daemon_proc_fops.open = novfs_daemon_open_control;
+			novfs_daemon_proc_fops.release = novfs_daemon_close_control;
+			novfs_daemon_proc_fops.read = novfs_daemon_cmd_send;
+			novfs_daemon_proc_fops.write = novfs_daemon_recv_reply;
+			novfs_daemon_proc_fops.ioctl = novfs_daemon_ioctl;
+
+			Novfs_Control->proc_fops = &novfs_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->size = 0;
+
+			/*
+			 * Setup our file functions
+			 */
+			memcpy(&novfs_lib_proc_fops, Novfs_Library->proc_fops,
+			       sizeof(struct file_operations));
+			novfs_lib_proc_fops.owner = THIS_MODULE;
+			novfs_lib_proc_fops.open = novfs_daemon_lib_open;
+			novfs_lib_proc_fops.release = novfs_daemon_lib_close;
+			novfs_lib_proc_fops.read = novfs_daemon_lib_read;
+			novfs_lib_proc_fops.write = novfs_daemon_lib_write;
+			novfs_lib_proc_fops.llseek = novfs_daemon_lib_llseek;
+			novfs_lib_proc_fops.ioctl = novfs_daemon_lib_ioctl;
+			Novfs_Library->proc_fops = &novfs_lib_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->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 novfs_proc_exit(void)
+{
+
+	DbgPrint("remove_proc_entry(Version, NULL)\n");
+	remove_proc_entry("Version", novfs_procfs_dir);
+
+	DbgPrint("remove_proc_entry(Control, NULL)\n");
+	remove_proc_entry("Control", novfs_procfs_dir);
+
+	DbgPrint("remove_proc_entry(Library, NULL)\n");
+	remove_proc_entry("Library", novfs_procfs_dir);
+
+	DbgPrint("remove_proc_entry(%s, NULL)\n",
+		 MODULE_NAME);
+	remove_proc_entry(MODULE_NAME, NULL);
+
+	DbgPrint("done\n");
+}
--- /dev/null
+++ b/fs/novfs/profile.c
@@ -0,0 +1,704 @@
+/*
+ * Novell NCP Redirector for Linux
+ * Author: James Turner
+ *
+ * This file contains a debugging code for the novfs VFS.
+ *
+ * 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.
+ */
+
+#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 "vfs.h"
+
+/*===[ Manifest constants ]===============================================*/
+#define DBGBUFFERSIZE (1024*1024*32)
+
+/*===[ Type definitions ]=================================================*/
+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;
+};
+
+char *DbgPrintBuffer = NULL;
+char DbgPrintOn = 0;
+char DbgSyslogOn = 0;
+char DbgProfileOn = 0;
+
+static unsigned long DbgPrintBufferOffset = 0;
+static unsigned long DbgPrintBufferReadOffset = 0;
+static unsigned long DbgPrintBufferSize = DBGBUFFERSIZE;
+
+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 proc_dir_entry *dbg_dir = NULL;
+static struct proc_dir_entry *dbg_file = NULL;
+static struct proc_dir_entry *dentry_file = NULL;
+static struct proc_dir_entry *inode_file = NULL;
+
+static DECLARE_MUTEX(LocalPrint_lock);
+
+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;
+
+	lbuf = kmalloc(nbytes + 1, GFP_KERNEL);
+	if (lbuf) {
+		cpylen = copy_from_user(lbuf, buf, nbytes);
+
+		lbuf[nbytes] = 0;
+		DbgPrint("%s", 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)) {
+				novfs_daemon_debug_cmd_send(p);
+			} else if (!strcmp("file_update_timeout", lbuf)) {
+				novfs_update_timeout =
+				    simple_strtoul(p, NULL, 0);
+			} else if (!strcmp("cache", lbuf)) {
+				if (!strcmp("on", p)) {
+					novfs_page_cache = 1;
+				} else if (!strcmp("off", p)) {
+					novfs_page_cache = 0;
+				}
+			} else if (!strcmp("profile", lbuf)) {
+				if (!strcmp("on", p)) {
+					DbgProfileOn = 1;
+				} else if (!strcmp("off", p)) {
+					DbgProfileOn = 0;
+				}
+			}
+		}
+		kfree(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;
+
+	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;
+
+	printk(KERN_ALERT "proc_read_DbgBuffer: off=%ld count=%d DbgPrintBufferOffset=%lu DbgPrintBufferReadOffset=%lu\n", off, count, DbgPrintBufferOffset, DbgPrintBufferReadOffset);
+
+	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;
+
+	printk(KERN_ALERT "proc_read_DbgBuffer: return %d\n", len);
+
+	return len;
+}
+
+#define DBG_BUFFER_SIZE (2*1024)
+
+static 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(const char *site, const 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 = snprintf(buf, DBG_BUFFER_SIZE, "[%d] %s ", current->pid, site);
+			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);
+}
+
+static void doline(unsigned char *b, unsigned char *e, unsigned char *l)
+{
+	unsigned char c;
+
+	*b++ = ' ';
+
+	while (l < e) {
+		c = *l++;
+		if ((c < ' ') || (c > '~')) {
+			c = '.';
+		}
+		*b++ = c;
+		*b = '\0';
+	}
+}
+
+void novfs_dump(int size, void *dumpptr)
+{
+	unsigned char *ptr = (unsigned char *)dumpptr;
+	unsigned char *line = NULL, buf[100], *bptr = buf;
+	int i;
+
+	if (DbgPrintBuffer || DbgSyslogOn) {
+		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)
+ */
+static void NovfsGregorianDay(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;
+}
+
+static void private_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
+	 */
+	NovfsGregorianDay(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" };
+
+	private_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);
+}
+
+static void dump(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 *)kmalloc(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 = kmalloc(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_u.d_child);
+						p = p->next;
+
+						if (d->d_subdirs.next !=
+						    &d->d_subdirs) {
+							n = kmalloc(sizeof
+									 (*n),
+									 GFP_KERNEL);
+							if (n) {
+								n->next =
+								    l->next;
+								l->next = n;
+								n->dentry = d;
+							}
+						} else {
+							path = novfs_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 =
+					    novfs_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;
+					kfree(n);
+				}
+			}
+		}
+	}
+
+	kfree(buf);
+
+}
+
+static ssize_t 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;
+
+}
+
+static ssize_t novfs_profile_read_inode(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 = common_read(buf, len, off);
+
+	if (0 == retval) {
+		DbgPrintOn = save_DbgPrintOn;
+		DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0;
+
+		up(&LocalPrint_lock);
+	}
+
+	return retval;
+
+}
+
+static ssize_t novfs_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;
+		dump(novfs_root, LocalPrint);
+	}
+
+	retval = 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);
+}
+
+void novfs_profile_init()
+{
+	if (novfs_procfs_dir)
+		dbg_dir = novfs_procfs_dir;
+	else
+		dbg_dir = proc_mkdir(MODULE_NAME, NULL);
+
+	if (dbg_dir) {
+		dbg_file = create_proc_read_entry("Debug",
+						  0600,
+						  dbg_dir,
+						  proc_read_DbgBuffer, NULL);
+		if (dbg_file) {
+			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->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 =
+					novfs_profile_read_inode;
+				inode_file->proc_fops = &inode_proc_file_ops;
+			}
+
+			dentry_file = create_proc_entry("dentry",
+							0600, dbg_dir);
+			if (dentry_file) {
+				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 = novfs_profile_dentry_read;
+				dentry_file->proc_fops = &dentry_proc_file_ops;
+			}
+
+		} else {
+			vfree(DbgPrintBuffer);
+			DbgPrintBuffer = NULL;
+		}
+	}
+}
+
+void novfs_profile_exit(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 (dbg_dir && (dbg_dir != novfs_procfs_dir)) {
+		DbgPrint("Calling remove_proc_entry(%s, NULL)\n", MODULE_NAME);
+		remove_proc_entry(MODULE_NAME, NULL);
+	}
+}
+
+
--- /dev/null
+++ b/fs/novfs/scope.c
@@ -0,0 +1,659 @@
+/*
+ * Novell NCP Redirector for Linux
+ * Author:           James Turner
+ *
+ * This file contains functions used to scope users.
+ *
+ * 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.
+ */
+
+#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 <linux/semaphore.h>
+#include <linux/security.h>
+#include <linux/syscalls.h>
+
+#include "vfs.h"
+
+#define SHUTDOWN_INTERVAL     5
+#define CLEANUP_INTERVAL      10
+#define MAX_USERNAME_LENGTH   32
+
+
+static struct list_head Scope_List;
+static struct semaphore Scope_Lock;
+static struct semaphore Scope_Thread_Delay;
+static int Scope_Thread_Terminate = 0;
+static struct timer_list Scope_Timer;
+static unsigned int Scope_Hash_Val = 1;
+
+static struct novfs_scope_list *Scope_Search4Scope(struct novfs_schandle Id,
+		int Session, int Locked)
+{
+	struct novfs_scope_list *scope, *rscope = NULL;
+	struct novfs_schandle cur_scope;
+	struct list_head *sl;
+	int offset;
+
+	DbgPrint("Scope_Search4Scope: 0x%p:%p 0x%x 0x%x\n", Id.hTypeId, Id.hId,
+		 Session, Locked);
+
+	if (Session)
+		offset = offsetof(struct novfs_scope_list, SessionId);
+	else
+		offset = offsetof(struct novfs_scope_list, ScopeId);
+
+	if (!Locked) {
+		down(&Scope_Lock);
+	}
+
+	sl = Scope_List.next;
+	DbgPrint("Scope_Search4Scope: 0x%p\n", sl);
+	while (sl != &Scope_List) {
+		scope = list_entry(sl, struct novfs_scope_list, ScopeList);
+
+		cur_scope = *(struct novfs_schandle *) ((char *)scope + offset);
+		if (SC_EQUAL(Id, cur_scope)) {
+			rscope = scope;
+			break;
+		}
+
+		sl = sl->next;
+	}
+
+	if (!Locked) {
+		up(&Scope_Lock);
+	}
+
+	DbgPrint("Scope_Search4Scope: return 0x%p\n", rscope);
+	return (rscope);
+}
+
+static struct novfs_scope_list *Scope_Find_Scope(int Create)
+{
+	struct novfs_scope_list *scope = NULL, *pscope = NULL;
+	struct task_struct *task;
+	struct novfs_schandle scopeId;
+	int addscope = 0;
+
+	task = current;
+
+	DbgPrint("Scope_Find_Scope: %d %d %d %d\n", current_uid(),
+		current_euid(), current_suid(), current_fsuid());
+
+	//scopeId = task->euid;
+	UID_TO_SCHANDLE(scopeId, current_euid());
+
+	scope = Scope_Search4Scope(scopeId, 0, 0);
+
+	if (!scope && Create) {
+		scope = kmalloc(sizeof(*pscope), GFP_KERNEL);
+		if (scope) {
+			scope->ScopeId = scopeId;
+			SC_INITIALIZE(scope->SessionId);
+			scope->ScopePid = task->pid;
+			scope->ScopeTask = task;
+			scope->ScopeHash = 0;
+			scope->ScopeUid = current_euid();
+			scope->ScopeUserName[0] = '\0';
+
+			if (!novfs_daemon_create_sessionId(&scope->SessionId)) {
+				DbgPrint("Scope_Find_Scope2: %d %d %d %d\n",
+					 current_uid(), current_euid(),
+					 current_suid(), current_fsuid());
+				memset(scope->ScopeUserName, 0,
+				       sizeof(scope->ScopeUserName));
+				scope->ScopeUserNameLength = 0;
+				novfs_daemon_getpwuid(current_euid(),
+						sizeof(scope->ScopeUserName),
+						scope->ScopeUserName);
+				scope->ScopeUserNameLength =
+				    strlen(scope->ScopeUserName);
+				addscope = 1;
+			}
+
+			scope->ScopeHash = Scope_Hash_Val++;
+			DbgPrint("Scope_Find_Scope: Adding 0x%p\n"
+				 "   ScopeId:             0x%p:%p\n"
+				 "   SessionId:           0x%p:%p\n"
+				 "   ScopePid:            %d\n"
+				 "   ScopeTask:           0x%p\n"
+				 "   ScopeHash:           %u\n"
+				 "   ScopeUid:            %u\n"
+				 "   ScopeUserNameLength: %u\n"
+				 "   ScopeUserName:       %s\n",
+				 scope,
+				 scope->ScopeId.hTypeId, scope->ScopeId.hId,
+				 scope->SessionId.hTypeId, scope->SessionId.hId,
+				 scope->ScopePid,
+				 scope->ScopeTask,
+				 scope->ScopeHash,
+				 scope->ScopeUid,
+				 scope->ScopeUserNameLength,
+				 scope->ScopeUserName);
+
+			if (SC_PRESENT(scope->SessionId)) {
+				down(&Scope_Lock);
+				pscope =
+				    Scope_Search4Scope(scopeId, 0, 1);
+
+				if (!pscope) {
+					list_add(&scope->ScopeList,
+						 &Scope_List);
+				}
+				up(&Scope_Lock);
+
+				if (pscope) {
+					printk
+					    ("<6>Scope_Find_Scope scope not added because it was already there...\n");
+					novfs_daemon_destroy_sessionId(scope->
+								SessionId);
+					kfree(scope);
+					scope = pscope;
+					addscope = 0;
+				}
+			} else {
+				kfree(scope);
+				scope = NULL;
+			}
+		}
+
+		if (addscope) {
+			novfs_add_to_root(scope->ScopeUserName);
+		}
+	}
+
+	return (scope);
+}
+
+static int Scope_Validate_Scope(struct novfs_scope_list *Scope)
+{
+	struct novfs_scope_list *s;
+	struct list_head *sl;
+	int retVal = 0;
+
+	DbgPrint("Scope_Validate_Scope: 0x%p\n", Scope);
+
+	down(&Scope_Lock);
+
+	sl = Scope_List.next;
+	while (sl != &Scope_List) {
+		s = list_entry(sl, struct novfs_scope_list, ScopeList);
+
+		if (s == Scope) {
+			retVal = 1;
+			break;
+		}
+
+		sl = sl->next;
+	}
+
+	up(&Scope_Lock);
+
+	return (retVal);
+}
+
+uid_t novfs_scope_get_uid(struct novfs_scope_list *scope)
+{
+	uid_t uid = 0;
+	if (!scope)
+		scope = Scope_Find_Scope(1);
+
+	if (scope && Scope_Validate_Scope(scope))
+		uid = scope->ScopeUid;
+	return uid;
+}
+
+char *novfs_scope_get_username(void)
+{
+	char *name = NULL;
+	struct novfs_scope_list *Scope;
+
+	Scope = Scope_Find_Scope(1);
+
+	if (Scope && Scope_Validate_Scope(Scope))
+		name = Scope->ScopeUserName;
+
+	return name;
+}
+
+struct novfs_schandle novfs_scope_get_sessionId(struct novfs_scope_list
+		*Scope)
+{
+	struct novfs_schandle sessionId;
+	DbgPrint("Scope_Get_SessionId: 0x%p\n", Scope);
+	SC_INITIALIZE(sessionId);
+	if (!Scope)
+		Scope = Scope_Find_Scope(1);
+
+	if (Scope && Scope_Validate_Scope(Scope))
+		sessionId = Scope->SessionId;
+	DbgPrint("Scope_Get_SessionId: return 0x%p:%p\n", sessionId.hTypeId,
+		 sessionId.hId);
+	return (sessionId);
+}
+
+struct novfs_scope_list *novfs_get_scope_from_name(struct qstr * Name)
+{
+	struct novfs_scope_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, struct novfs_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 novfs_scope_set_userspace(uint64_t * TotalSize, uint64_t * Free,
+			uint64_t * TotalEnties, uint64_t * FreeEnties)
+{
+	struct novfs_scope_list *scope;
+	int retVal = 0;
+
+	scope = Scope_Find_Scope(1);
+
+	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 novfs_scope_get_userspace(uint64_t * TotalSize, uint64_t * Free,
+			uint64_t * TotalEnties, uint64_t * FreeEnties)
+{
+	struct novfs_scope_list *scope;
+	int retVal = 0;
+
+	uint64_t td, fd, te, fe;
+
+	scope = Scope_Find_Scope(1);
+
+	td = fd = te = fe = 0;
+	if (scope) {
+
+		retVal =
+		    novfs_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);
+}
+
+struct novfs_scope_list *novfs_get_scope(struct dentry * Dentry)
+{
+	struct novfs_scope_list *scope = NULL;
+	char *buf, *path, *cp;
+	struct qstr name;
+
+	buf = (char *)kmalloc(PATH_LENGTH_BUFFER, GFP_KERNEL);
+	if (buf) {
+		path = novfs_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 = novfs_get_scope_from_name(&name);
+			}
+		}
+		kfree(buf);
+	}
+
+	return (scope);
+}
+
+static char *add_to_list(char *Name, char *List, char *EndOfList)
+{
+	while (*Name && (List < EndOfList)) {
+		*List++ = *Name++;
+	}
+
+	if (List < EndOfList) {
+		*List++ = '\0';
+	}
+	return (List);
+}
+
+char *novfs_get_scopeusers(void)
+{
+	struct novfs_scope_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 = kmalloc(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, struct novfs_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;
+				kfree(list);
+				list = NULL;
+			}
+		} else {	/* if allocation fails return an empty list */
+
+			break;
+		}
+	} while (!list);	/* List was to small try again */
+
+	return (list);
+}
+
+void *novfs_scope_lookup(void)
+{
+	return Scope_Find_Scope(1);
+}
+
+static void Scope_Timer_Function(unsigned long context)
+{
+	up(&Scope_Thread_Delay);
+}
+
+static int Scope_Cleanup_Thread(void *Args)
+{
+	struct novfs_scope_list *scope, *rscope;
+	struct list_head *sl, cleanup;
+	struct task_struct *task;
+
+	DbgPrint("Scope_Cleanup_Thread: %d\n", current->pid);
+
+	/*
+	 * Setup and start que timer
+	 */
+	init_timer(&Scope_Timer);
+
+	while (0 == Scope_Thread_Terminate) {
+		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, struct novfs_scope_list, ScopeList);
+			sl = sl->next;
+
+			rscope = NULL;
+			rcu_read_lock();
+			for_each_process(task) {
+				if ((task->cred->uid == scope->ScopeUid)
+				    || (task->cred->euid == scope->ScopeUid)) {
+					rscope = scope;
+					break;
+				}
+			}
+			rcu_read_unlock();
+
+			if (!rscope) {
+				list_move(&scope->ScopeList, &cleanup);
+				DbgPrint("Scope_Cleanup_Thread: Scope=0x%p\n",
+					 rscope);
+			}
+		}
+
+		up(&Scope_Lock);
+
+		sl = cleanup.next;
+		while (sl != &cleanup) {
+			scope = list_entry(sl, struct novfs_scope_list, ScopeList);
+			sl = sl->next;
+
+			DbgPrint("Scope_Cleanup_Thread: Removing 0x%p\n"
+				 "   ScopeId:       0x%p:%p\n"
+				 "   SessionId:     0x%p:%p\n"
+				 "   ScopePid:      %d\n"
+				 "   ScopeTask:     0x%p\n"
+				 "   ScopeHash:     %u\n"
+				 "   ScopeUid:      %u\n"
+				 "   ScopeUserName: %s\n",
+				 scope,
+				 scope->ScopeId,
+				 scope->SessionId,
+				 scope->ScopePid,
+				 scope->ScopeTask,
+				 scope->ScopeHash,
+				 scope->ScopeUid, scope->ScopeUserName);
+			if (!Scope_Search4Scope(scope->SessionId, 1, 0)) {
+				novfs_remove_from_root(scope->ScopeUserName);
+				novfs_daemon_destroy_sessionId(scope->SessionId);
+			}
+			kfree(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 novfs_scope_cleanup(void)
+{
+	struct novfs_scope_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, struct novfs_scope_list, ScopeList);
+		sl = sl->next;
+
+		list_del(&scope->ScopeList);
+
+		DbgPrint("Scope_Cleanup: Removing 0x%p\n"
+			 "   ScopeId:       0x%p:%p\n"
+			 "   SessionId:     0x%p:%p\n"
+			 "   ScopePid:      %d\n"
+			 "   ScopeTask:     0x%p\n"
+			 "   ScopeHash:     %u\n"
+			 "   ScopeUid:      %u\n"
+			 "   ScopeUserName: %s\n",
+			 scope,
+			 scope->ScopeId,
+			 scope->SessionId,
+			 scope->ScopePid,
+			 scope->ScopeTask,
+			 scope->ScopeHash,
+			 scope->ScopeUid, scope->ScopeUserName);
+		if (!Scope_Search4Scope(scope->SessionId, 1, 1)) {
+			novfs_remove_from_root(scope->ScopeUserName);
+			novfs_daemon_destroy_sessionId(scope->SessionId);
+		}
+		kfree(scope);
+	}
+
+	up(&Scope_Lock);
+
+}
+
+/*
+ *  Walks the dentry chain building a path.
+ */
+char *novfs_scope_dget_path(struct dentry *Dentry, char *Buf, unsigned int Buflen,
+		int Flags)
+{
+	char *retval = &Buf[Buflen];
+	struct dentry *p = Dentry;
+	int len;
+
+	*(--retval) = '\0';
+	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 novfs_scope_init(void)
+{
+	INIT_LIST_HEAD(&Scope_List);
+	init_MUTEX(&Scope_Lock);
+	init_MUTEX_LOCKED(&Scope_Thread_Delay);
+	kthread_run(Scope_Cleanup_Thread, NULL, "novfs_ST");
+}
+
+void novfs_scope_exit(void)
+{
+	unsigned long expires = jiffies + HZ * SHUTDOWN_INTERVAL;
+
+	printk(KERN_INFO "Scope_Uninit: Start\n");
+
+	Scope_Thread_Terminate = 1;
+
+	up(&Scope_Thread_Delay);
+
+	mb();
+	while (Scope_Thread_Terminate && (jiffies < expires))
+		yield();
+	/* down(&Scope_Thread_Delay); */
+	printk(KERN_INFO "Scope_Uninit: Exit\n");
+
+}
+
+
--- /dev/null
+++ b/fs/novfs/vfs.h
@@ -0,0 +1,454 @@
+/*
+ * Novell NCP Redirector for Linux
+ * Author: James Turner
+ *
+ * Include file for novfs.
+ *
+ * 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.
+ */
+#ifndef __NOVFS_H
+#define __NOVFS_H
+
+#ifndef __STDC_VERSION__
+#define __STDC_VERSION__ 0L
+#endif
+
+#include <linux/version.h>
+#include <linux/namei.h>
+
+#include "nwcapi.h"
+
+
+#ifndef  XTIER_SCHANDLE
+struct novfs_schandle {
+	void * hTypeId;
+	void * hId;
+
+};
+
+#include "commands.h"
+
+#define SC_PRESENT(X)		((X.hTypeId != NULL) || (X.hId != NULL)) ? 1 : 0
+#define SC_EQUAL(X, Y)		((X.hTypeId == Y.hTypeId) && (X.hId == Y.hId)) ? 1 : 0
+#define SC_INITIALIZE(X)	{X.hTypeId = X.hId = NULL;}
+
+#define UID_TO_SCHANDLE(hSC, uid)	\
+		{ \
+			hSC.hTypeId = NULL; \
+			hSC.hId = (void *)(unsigned long)(uid); \
+		}
+
+#define XTIER_SCHANDLE
+#endif
+
+
+/*===[ Manifest constants ]===============================================*/
+#define NOVFS_MAGIC		0x4e574653
+#define MODULE_NAME		"novfs"
+
+#define TREE_DIRECTORY_NAME	".Trees"
+#define SERVER_DIRECTORY_NAME	".Servers"
+
+#define PATH_LENGTH_BUFFER	PATH_MAX
+#define NW_MAX_PATH_LENGTH	255
+
+#define XA_BUFFER		(8 * 1024)
+
+#define IOC_LOGIN		0x4a540000
+#define IOC_LOGOUT		0x4a540001
+#define IOC_XPLAT		0x4a540002
+#define IOC_SESSION		0x4a540003
+#define IOC_DEBUGPRINT		0x4a540004
+
+/*
+ * 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
+
+#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 ]=================================================*/
+struct novfs_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];
+};
+
+struct novfs_string {
+	int length;
+	unsigned char *data;
+};
+
+struct novfs_login {
+	struct novfs_string Server;
+	struct novfs_string UserName;
+	struct novfs_string Password;
+};
+
+struct novfs_logout {
+	struct novfs_string Server;
+};
+
+struct novfs_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];
+};
+
+struct novfs_data_list {
+	void *page;
+	void *offset;
+	int len;
+	int rwflag;
+};
+
+
+extern char *ctime_r(time_t * clock, char *buf);
+
+/*
+ *  Converts a HANDLE to a u32 type.
+ */
+static inline u32 HandletoUint32(void * h)
+{
+	return (u32) ((unsigned long) h);
+}
+
+/*
+ * Converts a u32 to a HANDLE type.
+ */
+static inline void *Uint32toHandle(u32 ui32)
+{
+	return ((void *) (unsigned long) ui32);
+}
+
+/* Global variables */
+
+extern struct dentry *novfs_root;
+extern struct proc_dir_entry *novfs_procfs_dir;
+extern unsigned long novfs_update_timeout;
+extern int novfs_page_cache;
+extern char *novfs_current_mnt;
+extern int novfs_max_iosize;
+
+
+/* Global functions */
+extern int novfs_remove_from_root(char *);
+extern void novfs_dump_inode(void *pf);
+
+extern void novfs_dump(int size, void *dumpptr);
+
+extern int Queue_Daemon_Command(void *request, unsigned long reqlen, void *data,
+				int dlen, void **reply, unsigned long * replen,
+				int interruptible);
+extern int novfs_do_login(struct ncl_string * Server, struct ncl_string* Username, struct ncl_string * Password, void **lgnId, struct novfs_schandle *Session);
+
+extern int novfs_proc_init(void);
+extern void novfs_proc_exit(void);
+
+/*
+ * daemon.c functions
+ */
+extern void novfs_daemon_queue_init(void);
+extern void novfs_daemon_queue_exit(void);
+extern int novfs_daemon_logout(struct qstr *Server, struct novfs_schandle *Session);
+extern int novfs_daemon_set_mnt_point(char *Path);
+extern int novfs_daemon_create_sessionId(struct novfs_schandle * SessionId);
+extern int novfs_daemon_destroy_sessionId(struct novfs_schandle SessionId);
+extern int novfs_daemon_getpwuid(uid_t uid, int unamelen, char *uname);
+extern int novfs_daemon_get_userspace(struct novfs_schandle SessionId,
+		uint64_t * TotalSize, uint64_t * TotalFree,
+		uint64_t * TotalDirectoryEnties,
+		uint64_t * FreeDirectoryEnties);
+extern int novfs_daemon_debug_cmd_send(char *Command);
+extern ssize_t novfs_daemon_recv_reply(struct file *file,
+		const char *buf, size_t nbytes, loff_t * ppos);
+extern ssize_t novfs_daemon_cmd_send(struct file *file, char *buf,
+		size_t len, loff_t * off);
+extern int novfs_daemon_ioctl(struct inode *inode, struct file *file,
+		unsigned int cmd, unsigned long arg);
+extern int novfs_daemon_lib_close(struct inode *inode, struct file *file);
+extern int novfs_daemon_lib_ioctl(struct inode *inode, struct file *file,
+		unsigned int cmd, unsigned long arg);
+extern int novfs_daemon_lib_open(struct inode *inode, struct file *file);
+extern ssize_t novfs_daemon_lib_read(struct file *file, char *buf,
+		size_t len, loff_t * off);
+extern ssize_t novfs_daemon_lib_write(struct file *file, const char *buf,
+		size_t len, loff_t * off);
+extern loff_t novfs_daemon_lib_llseek(struct file *file, loff_t offset,
+		int origin);
+extern int novfs_daemon_open_control(struct inode *Inode, struct file *File);
+extern int novfs_daemon_close_control(struct inode *Inode, struct file *File);
+extern int novfs_daemon_getversion(char *Buf, int Length);
+
+
+/*
+ * file.c functions
+ */
+extern int novfs_verify_file(struct qstr *Path, struct novfs_schandle SessionId);
+extern int novfs_get_alltrees(struct dentry *parent);
+extern int novfs_get_servers(unsigned char **ServerList,
+		struct novfs_schandle SessionId);
+extern int novfs_get_vols(struct qstr *Server,
+		unsigned char **VolumeList, struct novfs_schandle SessionId);
+extern int novfs_get_file_info(unsigned char *Path,
+		struct novfs_entry_info *Info, struct novfs_schandle SessionId);
+extern int novfs_getx_file_info(char *Path, const char *Name,
+		char *buffer, ssize_t buffer_size, ssize_t *dataLen,
+		struct novfs_schandle SessionId);
+extern int novfs_listx_file_info(char *Path, char *buffer,
+		ssize_t buffer_size, ssize_t *dataLen,
+		struct novfs_schandle SessionId);
+extern int novfs_setx_file_info(char *Path, const char *Name, const void *Value,
+				unsigned long valueLen,
+				unsigned long *bytesWritten, int flags,
+				struct novfs_schandle SessionId);
+
+extern int novfs_get_dir_listex(unsigned char *Path, void **EnumHandle,
+	int *Count, struct novfs_entry_info **Info,
+	struct novfs_schandle SessionId);
+extern int novfs_open_file(unsigned char *Path, int Flags,
+		struct novfs_entry_info * Info, void **Handle,
+		struct novfs_schandle SessionId);
+extern int novfs_create(unsigned char *Path, int DirectoryFlag,
+			struct novfs_schandle SessionId);
+extern int novfs_close_file(void * Handle, struct novfs_schandle SessionId);
+extern int novfs_read_file(void * Handle, unsigned char *Buffer,
+		size_t * Bytes, loff_t * Offset,
+		struct novfs_schandle SessionId);
+extern int novfs_read_pages(void * Handle, struct novfs_data_list *DList,
+		int DList_Cnt, size_t * Bytes, loff_t * Offset,
+			    struct novfs_schandle SessionId);
+extern int novfs_write_file(void * Handle, unsigned char *Buffer,
+			    size_t * Bytes, loff_t * Offset,
+			    struct novfs_schandle SessionId);
+extern int novfs_write_page(void * Handle, struct page *Page,
+			    struct novfs_schandle SessionId);
+extern int novfs_write_pages(void * Handle, struct novfs_data_list *DList,
+		int DList_Cnt, size_t Bytes, loff_t Offset,
+		struct novfs_schandle SessionId);
+extern int novfs_delete(unsigned char *Path, int DirectoryFlag,
+			struct novfs_schandle SessionId);
+extern int novfs_trunc(unsigned char *Path, int PathLen,
+		       struct novfs_schandle SessionId);
+extern int novfs_trunc_ex(void * Handle, loff_t Offset,
+				  struct novfs_schandle SessionId);
+extern int novfs_rename_file(int DirectoryFlag, unsigned char *OldName,
+			     int OldLen, unsigned char *NewName, int NewLen,
+			     struct novfs_schandle SessionId);
+extern int novfs_set_attr(unsigned char *Path, struct iattr *Attr,
+			  struct novfs_schandle SessionId);
+extern int novfs_get_file_cache_flag(unsigned char * Path,
+		struct novfs_schandle SessionId);
+extern int novfs_set_file_lock(struct novfs_schandle SessionId, void * fhandle,
+			       unsigned char fl_type, loff_t fl_start,
+			       loff_t len);
+
+extern struct inode *novfs_get_inode(struct super_block *sb, int mode,
+		int dev, uid_t uid, ino_t ino, struct qstr *name);
+extern int novfs_read_stream(void * ConnHandle, unsigned char * Handle,
+			     unsigned char * Buffer, size_t * Bytes, loff_t * Offset,
+			     int User, struct novfs_schandle SessionId);
+extern int novfs_write_stream(void * ConnHandle, unsigned char * Handle,
+			      unsigned char * Buffer, size_t * Bytes, loff_t * Offset,
+			      struct novfs_schandle SessionId);
+extern int novfs_close_stream(void * ConnHandle, unsigned char * Handle,
+			      struct novfs_schandle SessionId);
+
+extern int novfs_add_to_root(char *);
+extern int novfs_end_directory_enumerate(void *EnumHandle,
+					struct novfs_schandle SessionId);
+
+/*
+ * scope.c functions
+ */
+extern void novfs_scope_init(void);
+extern void novfs_scope_exit(void);
+extern void *novfs_scope_lookup(void);
+extern uid_t novfs_scope_get_uid(struct novfs_scope_list *);
+extern struct novfs_schandle novfs_scope_get_sessionId(struct
+		novfs_scope_list *);
+extern char *novfs_get_scopeusers(void);
+extern int novfs_scope_set_userspace(uint64_t * TotalSize, uint64_t * Free,
+			       uint64_t * TotalEnties, uint64_t * FreeEnties);
+extern int novfs_scope_get_userspace(uint64_t * TotalSize, uint64_t * Free,
+			       uint64_t * TotalEnties, uint64_t * FreeEnties);
+extern char *novfs_scope_dget_path(struct dentry *Dentry, char *Buf,
+			     unsigned int Buflen, int Flags);
+extern void novfs_scope_cleanup(void);
+extern struct novfs_scope_list *novfs_get_scope_from_name(struct qstr *);
+extern struct novfs_scope_list *novfs_get_scope(struct dentry *);
+extern char *novfs_scope_get_username(void);
+
+/*
+ * profile.c functions
+ */
+extern u64 get_nanosecond_time(void);
+extern int ___DbgPrint(const char *site, const char *Fmt, ...);
+#define DbgPrint(fmt, args...)	___DbgPrint(__func__, ": " fmt "\n", ##args)
+#define __DbgPrint(fmt, args...)	___DbgPrint("", fmt, ##args)
+
+extern void novfs_profile_init(void);
+extern void novfs_profile_exit(void);
+
+/*
+ * nwcapi.c functions
+ */
+extern int novfs_auth_conn(struct novfs_xplat *pdata,
+		struct novfs_schandle Session);
+extern int novfs_conn_close(struct novfs_xplat *pdata,
+		void **Handle, struct novfs_schandle Session);
+extern int novfs_get_conn_info(struct novfs_xplat *pdata,
+		struct novfs_schandle Session);
+extern int novfs_set_conn_info(struct novfs_xplat *pdata,
+		struct novfs_schandle Session);
+extern int novfs_get_daemon_ver(struct novfs_xplat *pdata,
+		struct novfs_schandle Session);
+extern int novfs_get_id_info(struct novfs_xplat *pdata,
+		struct novfs_schandle Session);
+extern int novfs_license_conn(struct novfs_xplat *pdata,
+		struct novfs_schandle Session);
+extern int novfs_login_id(struct novfs_xplat *pdata,
+		struct novfs_schandle Session);
+extern int novfs_logout_id(struct novfs_xplat *pdata,
+		struct novfs_schandle Session);
+extern int novfs_open_conn_by_addr(struct novfs_xplat *pdata,
+		void **Handle, struct novfs_schandle Session);
+extern int novfs_open_conn_by_name(struct novfs_xplat *pdata,
+		void **Handle, struct novfs_schandle Session);
+extern int novfs_open_conn_by_ref(struct novfs_xplat *pdata,
+		void **Handle, struct novfs_schandle Session);
+extern int novfs_query_feature(struct novfs_xplat *pdata,
+		struct novfs_schandle Session);
+extern int novfs_raw_send(struct novfs_xplat *pdata,
+		struct novfs_schandle Session);
+extern int novfs_scan_conn_info(struct novfs_xplat *pdata,
+		struct novfs_schandle Session);
+extern int novfs_sys_conn_close(struct novfs_xplat *pdata,
+		unsigned long *Handle, struct novfs_schandle Session);
+extern int novfs_unauthenticate(struct novfs_xplat *pdata,
+		struct novfs_schandle Session);
+extern int novfs_unlicense_conn(struct novfs_xplat *pdata,
+		struct novfs_schandle Session);
+extern int novfs_change_auth_key(struct novfs_xplat *pdata,
+		struct novfs_schandle Session);
+extern int novfs_enum_ids(struct novfs_xplat *pdata,
+		struct novfs_schandle Session);
+extern int novfs_get_default_ctx(struct novfs_xplat *pdata,
+		struct novfs_schandle Session);
+extern int novfs_get_preferred_DS_tree(struct novfs_xplat *pdata,
+		struct novfs_schandle Session);
+extern int novfs_get_tree_monitored_conn(struct novfs_xplat *pdata,
+		struct novfs_schandle Session);
+extern int novfs_set_default_ctx(struct novfs_xplat *pdata,
+		struct novfs_schandle Session);
+extern int novfs_set_preferred_DS_tree(struct novfs_xplat *pdata,
+		struct novfs_schandle Session);
+extern int novfs_set_pri_conn(struct novfs_xplat *pdata,
+		struct novfs_schandle Session);
+extern int novfs_get_pri_conn(struct novfs_xplat *pdata,
+		struct novfs_schandle Session);
+extern int novfs_set_map_drive(struct novfs_xplat *pdata,
+		struct novfs_schandle Session);
+extern int novfs_unmap_drive(struct novfs_xplat *pdata,
+		struct novfs_schandle Session);
+extern int novfs_enum_drives(struct novfs_xplat *pdata,
+		struct novfs_schandle Session);
+extern int novfs_get_bcast_msg(struct novfs_xplat *pdata,
+		struct novfs_schandle Session);
+extern int novfs_set_key_value(struct novfs_xplat *pdata,
+		struct novfs_schandle Session);
+extern int novfs_verify_key_value(struct novfs_xplat *pdata,
+		struct novfs_schandle Session);
+
+
+#endif	/* __NOVFS_H */
+
