Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Marek <mmarek@suse.cz>2011-06-16 12:16:16 +0200
committerMichal Marek <mmarek@suse.cz>2011-06-16 12:17:01 +0200
commitbc3a79d83165d5cca2759b0e4d3ec1427d5058fa (patch)
treed4af66715e008571997c8dcacdd01b08a13d3aa6
parenta642909c79f7fd9cce7b92e417506d2d9a3b7b77 (diff)
- Remove the novfs patches, it should be packaged as a KMP, or
ideally, reimplemented as a fuse filesystem (which is the reason why the current implementation it is never going to be accepted upstream). - Delete patches.fixes/novfs-copy_user-fixes.diff. - Delete patches.fixes/novfs-minsize-fixes. - Delete patches.fixes/novfs-nwcapi.patch. - Delete patches.suse/novfs-client-module. - Delete patches.suse/novfs-remove-bkl.
-rw-r--r--patches.fixes/novfs-copy_user-fixes.diff1830
-rw-r--r--patches.fixes/novfs-minsize-fixes92
-rw-r--r--patches.fixes/novfs-nwcapi.patch39
-rw-r--r--patches.suse/novfs-client-module14736
-rw-r--r--patches.suse/novfs-remove-bkl59
-rw-r--r--series.conf9
6 files changed, 0 insertions, 16765 deletions
diff --git a/patches.fixes/novfs-copy_user-fixes.diff b/patches.fixes/novfs-copy_user-fixes.diff
deleted file mode 100644
index c37f3fa8f2..0000000000
--- a/patches.fixes/novfs-copy_user-fixes.diff
+++ /dev/null
@@ -1,1830 +0,0 @@
-Return-Path: <psankar@novell.com>
-Received: from imap.suse.de [195.135.221.39]
- by pobox.suse.cz with IMAP (fetchmail-6.3.9-rc2)
- for <jack@localhost> (single-drop); Wed, 01 Jun 2011 10:31:42 +0200 (CEST)
-Received: from imap.suse.de ([unix socket])
- by imap-int (Cyrus v2.2.12) with LMTPA;
- Wed, 01 Jun 2011 10:30:35 +0200
-X-Sieve: CMU Sieve 2.2
-Received: from relay2.suse.de (relay2.suse.de [149.44.160.134])
- (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
- (Client CN "relay.suse.de", Issuer "CAcert Class 3 Root" (verified OK))
- by imap.suse.de (Postfix) with ESMTPS id 7A9363C539B7
- for <jack@imap.suse.de>; Wed, 1 Jun 2011 10:30:35 +0200 (CEST)
-Received: by relay2.suse.de (Postfix)
- id 718E01855308; Wed, 1 Jun 2011 10:30:35 +0200 (CEST)
-Received: from localhost (localhost [127.0.0.1])
- by relay2.suse.de (Postfix) with ESMTP id 64E4C18552AC;
- Wed, 1 Jun 2011 10:30:35 +0200 (CEST)
-Received: from relay2.suse.de ([127.0.0.1])
- by localhost (localhost [127.0.0.1]) (amavisd-new, port 10026) with ESMTP
- id 01564-02; Wed, 1 Jun 2011 10:30:34 +0200 (CEST)
-Received: from mx1.suse.de (cantor.suse.de [195.135.220.2])
- (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
- (No client certificate requested)
- by relay2.suse.de (Postfix) with ESMTPS id 073451855308;
- Wed, 1 Jun 2011 10:30:34 +0200 (CEST)
-Received: from victor.provo.novell.com (victor.provo.novell.com [137.65.250.26])
- (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
- (No client certificate requested)
- by mx1.suse.de (Postfix) with ESMTP id 4FFA98FEA2;
- Wed, 1 Jun 2011 10:30:31 +0200 (CEST)
-Received: from sanrise.blr.novell.com (prv-ext-foundry1int.gns.novell.com [137.65.251.240])
- by victor.provo.novell.com with ESMTP (NOT encrypted); Wed, 01 Jun 2011 02:30:04 -0600
-From: Sankar <psankar@novell.com>
-To: jack@suse.cz
-Cc: kernel@suse.de, jankit@novell.com,
- ncl-dev@forge.provo.novell.com, rravi@novell.com, dsterba@suse.cz,
- Sankar <psankar@novell.com>
-Subject: [PATCH] fs: novfs: Limit check for datacopy between user and kernel space
-Date: Wed, 1 Jun 2011 14:00:24 +0530
-Message-Id: <1306917024-6681-1-git-send-email-psankar@novell.com>
-X-Mailer: git-send-email 1.7.3.4
-X-Virus-Scanned: by amavisd-new at localhost
-X-Spam-Status: No, score=-6.11 tagged_above=-20 required=5
- tests=[BAYES_05=-1.11, MY_SUSE=-1, RCVD_IN_DNSWL_MED=-4]
-X-Spam-Score: -6.11
-X-Spam-Level:
-Content-Length: 65846
-
-This patch is to check if the copy_to_user and copy_from_user calls
-have successfully transferred data between the kernel and the user
-space. -EFAULT is returned in case of errors.
-
-Signed-off-by: Sankar P <psankar@novell.com>
-Reported-by: David Sterba <dsterba@suse.cz>
-Patch-mainline: No
----
-
-Please review and commit for SLE11SP1, SLE11SP2, Master branches.
-
-Review comments by Jan Kara and Ankit Jain have been incorporated. Re-Review and commit.
-
-
- fs/novfs/daemon.c | 96 ++++++---
- fs/novfs/nwcapi.c | 642 ++++++++++++++++++++++++++++++++++++++---------------
- 2 files changed, 533 insertions(+), 205 deletions(-)
-
-Index: linux-3.0-rc3-master/fs/novfs/daemon.c
-===================================================================
---- linux-3.0-rc3-master.orig/fs/novfs/daemon.c
-+++ linux-3.0-rc3-master/fs/novfs/daemon.c
-@@ -399,9 +399,8 @@ ssize_t novfs_daemon_cmd_send(struct fil
- size_t retValue = 0;
- int Finished = 0;
- struct novfs_data_list *dlist;
-- int i, dcnt, bcnt, ccnt, error;
-+ int i, dcnt, bcnt, error;
- char *vadr;
-- unsigned long cpylen;
-
- DbgPrint("%u %lld", len, *off);
- if (len > novfs_max_iosize) {
-@@ -421,7 +420,10 @@ ssize_t novfs_daemon_cmd_send(struct fil
- else
- novfs_dump(retValue, que->request);
-
-- cpylen = copy_to_user(buf, que->request, retValue);
-+ if(copy_to_user(buf, que->request, retValue)) {
-+ Queue_put(que);
-+ return -EFAULT;
-+ }
- if (que->datalen && (retValue < len)) {
- buf += retValue;
- dlist = que->data;
-@@ -443,7 +445,12 @@ ssize_t novfs_daemon_cmd_send(struct fil
- vadr = dlist->offset;
- }
-
-- ccnt = copy_to_user(buf, vadr, bcnt);
-+ if (copy_to_user(buf, vadr, bcnt)) {
-+ if (km_adr)
-+ kunmap(dlist->page);
-+ Queue_put(que);
-+ return -EFAULT;
-+ }
-
- DbgPrint("Copy %d from 0x%p to 0x%p.", bcnt, vadr, buf);
- if (bcnt > 0x80)
-@@ -492,7 +499,7 @@ ssize_t novfs_daemon_recv_reply(struct f
- struct daemon_cmd *que;
- size_t retValue = 0;
- void *reply;
-- unsigned long sequence, cpylen;
-+ unsigned long sequence;
-
- struct novfs_data_list *dlist;
- char *vadr;
-@@ -504,7 +511,8 @@ ssize_t novfs_daemon_recv_reply(struct f
- * Get sequence number from reply buffer
- */
-
-- cpylen = copy_from_user(&sequence, buf, sizeof(sequence));
-+ if(copy_from_user(&sequence, buf, sizeof(sequence)))
-+ return -EFAULT;
-
- /*
- * Find item based on sequence number
-@@ -553,7 +561,14 @@ ssize_t novfs_daemon_recv_reply(struct f
- thiscopy = left;
- dlist->len = left;
- }
-- cpylen = copy_from_user(vadr, buf, thiscopy);
-+
-+ if(copy_from_user(vadr, buf, thiscopy)) {
-+ if (km_adr)
-+ kunmap(dlist->page);
-+ retValue = -EFAULT;
-+ que->status = QUEUE_DONE;
-+ break;
-+ }
-
- if (thiscopy > 0x80)
- novfs_dump(0x80, vadr);
-@@ -791,16 +806,20 @@ static int daemon_login(struct novfs_log
- novfs_add_to_root(username);
- }
- }
-- }
-+ } else
-+ retCode = -EFAULT;
- kfree(password.buffer);
- }
-- }
-+ } else
-+ retCode = -EFAULT;
- kfree(username.buffer);
- }
-- }
-+ } else
-+ retCode = -EFAULT;
- kfree(server.buffer);
- }
-- }
-+ } else
-+ retCode = -EFAULT;
-
- return (retCode);
- }
-@@ -819,8 +838,10 @@ static int daemon_logout(struct novfs_lo
- if (!server.name)
- return -ENOMEM;
- server.len = lLogout.Server.length;
-- if (copy_from_user((void *)server.name, lLogout.Server.data, server.len))
-+ if (copy_from_user((void *)server.name, lLogout.Server.data, server.len)) {
-+ retCode = -EFAULT;
- goto exit;
-+ }
- retCode = novfs_daemon_logout(&server, Session);
- exit:
- kfree(server.name);
-@@ -1025,7 +1046,6 @@ int novfs_daemon_debug_cmd_send(char *Co
- long novfs_daemon_ioctl(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);
-@@ -1046,14 +1066,18 @@ long novfs_daemon_ioctl(struct file *fil
- } io;
- char *buf;
- io.length = 0;
-- cpylen = copy_from_user(&io, (char *)arg, sizeof(io));
-+ if(copy_from_user(&io, (char *)arg, sizeof(io)))
-+ return -EFAULT;
- if (io.length <= 0 || io.length > 1024)
- return -EINVAL;
- if (io.length) {
- buf = kmalloc(io.length + 1, GFP_KERNEL);
- if (buf) {
- buf[0] = 0;
-- cpylen = copy_from_user(buf, io.data, io.length);
-+ if(copy_from_user(buf, io.data, io.length)) {
-+ kfree(buf);
-+ return -EFAULT;
-+ }
- buf[io.length] = '\0';
- DbgPrint("%s", buf);
- kfree(buf);
-@@ -1067,7 +1091,8 @@ long novfs_daemon_ioctl(struct file *fil
- {
- struct novfs_xplat data;
-
-- cpylen = copy_from_user(&data, (void *)arg, sizeof(data));
-+ if(copy_from_user(&data, (void *)arg, sizeof(data)))
-+ return -EFAULT;
- retCode = ((data.xfunction & 0x0000FFFF) | 0xCC000000);
-
- switch (data.xfunction) {
-@@ -1343,7 +1368,6 @@ long novfs_daemon_lib_ioctl(struct file
- int retCode = -ENOSYS;
- struct daemon_handle *dh;
- void *handle = NULL;
-- unsigned long cpylen;
-
- dh = file->private_data;
-
-@@ -1368,14 +1392,18 @@ long novfs_daemon_lib_ioctl(struct file
- } io;
- char *buf;
- io.length = 0;
-- cpylen = copy_from_user(&io, (void *)arg, sizeof(io));
-+ if(copy_from_user(&io, (void *)arg, sizeof(io)))
-+ return -EFAULT;
- if (io.length <= 0 || io.length > 1024)
- return -EINVAL;
- if (io.length) {
- buf = kmalloc(io.length + 1, GFP_KERNEL);
- if (buf) {
- buf[0] = 0;
-- cpylen = copy_from_user(buf, io.data, io.length);
-+ if(copy_from_user(buf, io.data, io.length)) {
-+ kfree(buf);
-+ return -EFAULT;
-+ }
- buf[io.length] = '\0';
- __DbgPrint("%s", buf);
- kfree(buf);
-@@ -1389,7 +1417,8 @@ long novfs_daemon_lib_ioctl(struct file
- {
- struct novfs_xplat data;
-
-- cpylen = copy_from_user(&data, (void *)arg, sizeof(data));
-+ if(copy_from_user(&data, (void *)arg, sizeof(data)))
-+ return -EFAULT;
- retCode = ((data.xfunction & 0x0000FFFF) | 0xCC000000);
-
- switch (data.xfunction) {
-@@ -1615,11 +1644,11 @@ static int NwdConvertNetwareHandle(struc
- {
- 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));
-+ if(copy_from_user(&nh, pdata->reqData, sizeof(struct nwc_convert_netware_handle)))
-+ return -EFAULT;
-
- retVal =
- daemon_added_resource(DHandle, DH_TYPE_STREAM,
-@@ -1634,7 +1663,6 @@ static int NwdConvertLocalHandle(struct
- struct daemon_resource *resource;
- struct nwc_convert_local_handle lh;
- struct list_head *l;
-- unsigned long cpylen;
-
- DbgPrint("DHandle=0x%p", DHandle);
-
-@@ -1649,8 +1677,10 @@ static int NwdConvertLocalHandle(struct
- //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;
-+ if(copy_to_user(pdata->repData, &lh, sizeof(struct nwc_convert_local_handle)))
-+ retVal = -EFAULT;
-+ else
-+ retVal = 0;
- } else {
- retVal = NWE_BUFFER_OVERFLOW;
- }
-@@ -1667,12 +1697,12 @@ static int NwdGetMountPath(struct novfs_
- {
- int retVal = NWE_REQUESTER_FAILURE;
- int len;
-- unsigned long cpylen;
- struct nwc_get_mount_path mp;
-
- if (pdata->reqLen != sizeof(mp))
- return -EINVAL;
-- cpylen = copy_from_user(&mp, pdata->reqData, pdata->reqLen);
-+ if(copy_from_user(&mp, pdata->reqData, pdata->reqLen))
-+ return -EFAULT;
-
- if (novfs_current_mnt) {
-
-@@ -1681,7 +1711,8 @@ static int NwdGetMountPath(struct novfs_
- retVal = NWE_BUFFER_OVERFLOW;
- } else {
- if (mp.pMountPath) {
-- cpylen = copy_to_user(mp.pMountPath, novfs_current_mnt, len);
-+ if(copy_to_user(mp.pMountPath, novfs_current_mnt, len))
-+ return -EFAULT;
- }
- retVal = 0;
- }
-@@ -1689,7 +1720,8 @@ static int NwdGetMountPath(struct novfs_
- mp.MountPathLen = len;
-
- if (pdata->repData && (pdata->repLen >= sizeof(mp))) {
-- cpylen = copy_to_user(pdata->repData, &mp, sizeof(mp));
-+ if(copy_to_user(pdata->repData, &mp, sizeof(mp)))
-+ return -EFAULT;
- }
- }
-
-@@ -1699,7 +1731,6 @@ static int NwdGetMountPath(struct novfs_
- 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;
-@@ -1718,7 +1749,10 @@ static int set_map_drive(struct novfs_xp
-
- path = (char *)pdata->reqData;
- path += symInfo.linkOffset;
-- cpylen = copy_from_user(drivemap->name, path, symInfo.linkOffsetLength);
-+ if(copy_from_user(drivemap->name, path, symInfo.linkOffsetLength)) {
-+ kfree(drivemap);
-+ return -EFAULT;
-+ }
-
- drivemap->session = Session;
- drivemap->hash = full_name_hash(drivemap->name, symInfo.linkOffsetLength - 1);
-Index: linux-3.0-rc3-master/fs/novfs/nwcapi.c
-===================================================================
---- linux-3.0-rc3-master.orig/fs/novfs/nwcapi.c
-+++ linux-3.0-rc3-master/fs/novfs/nwcapi.c
-@@ -44,10 +44,11 @@ int novfs_open_conn_by_name(struct novfs
- struct nwd_open_conn_by_name *openConn = NULL, *connReply = NULL;
- struct nwc_open_conn_by_name ocbn;
- int retCode = 0;
-- unsigned long cmdlen, datalen, replylen, cpylen, pnamelen, stypelen;
-+ unsigned long cmdlen, datalen, replylen, pnamelen, stypelen;
- char *data = NULL;
-
-- cpylen = copy_from_user(&ocbn, pdata->reqData, sizeof(ocbn));
-+ if(copy_from_user(&ocbn, pdata->reqData, sizeof(ocbn)))
-+ return -EFAULT;
- pnamelen = strlen_user(ocbn.pName->pString);
- stypelen = strlen_user(ocbn.pServiceType);
- if (pnamelen > MAX_NAME_LEN || stypelen > NW_MAX_SERVICE_TYPE_LEN)
-@@ -76,9 +77,15 @@ int novfs_open_conn_by_name(struct novfs
- openConn->oName = sizeof(*openConn);
-
- openConn->oServiceType = openConn->oName + openConn->nameLen;
-- cpylen = copy_from_user(data, ocbn.pName->pString, openConn->nameLen);
-+ if(copy_from_user(data, ocbn.pName->pString, openConn->nameLen)) {
-+ retCode = -EFAULT;
-+ goto exit;
-+ }
- data += openConn->nameLen;
-- cpylen = copy_from_user(data, ocbn.pServiceType, openConn->serviceLen);
-+ if(copy_from_user(data, ocbn.pServiceType, openConn->serviceLen)) {
-+ retCode = -EFAULT;
-+ goto exit;
-+ }
-
- retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
- if (reply) {
-@@ -95,15 +102,17 @@ int novfs_open_conn_by_name(struct novfs
- ocbn.RetConnHandle = HandletoUint32(connReply->newConnHandle);
- *Handle = connReply->newConnHandle;
-
-- cpylen = copy_to_user(pdata->reqData, &ocbn, sizeof(ocbn));
-- DbgPrint("New Conn Handle = %X", connReply->newConnHandle);
-+ if(copy_to_user(pdata->reqData, &ocbn, sizeof(ocbn)))
-+ retCode = -EFAULT;
-+ else
-+ DbgPrint("New Conn Handle = %X", connReply->newConnHandle);
- }
- kfree(reply);
- }
-
-+exit:
- kfree(cmd);
- return ((int)retCode);
--
- }
-
- int novfs_open_conn_by_addr(struct novfs_xplat *pdata, void **Handle, struct novfs_schandle Session)
-@@ -114,10 +123,11 @@ int novfs_open_conn_by_addr(struct novfs
- struct nwc_open_conn_by_addr ocba;
- struct nwc_tran_addr tranAddr;
- int retCode = 0;
-- unsigned long cmdlen, datalen, replylen, cpylen;
-+ unsigned long cmdlen, datalen, replylen;
- char addr[MAX_ADDRESS_LENGTH];
-
-- cpylen = copy_from_user(&ocba, pdata->reqData, sizeof(ocba));
-+ if(copy_from_user(&ocba, pdata->reqData, sizeof(ocba)))
-+ return -EFAULT;
- datalen = sizeof(*openConn);
- cmdlen = datalen + sizeof(*cmd);
- cmd = kmalloc(cmdlen, GFP_KERNEL);
-@@ -132,7 +142,10 @@ int novfs_open_conn_by_addr(struct novfs
- cmd->dataLen = datalen;
- openConn = (struct nwd_open_conn_by_addr *)cmd->data;
-
-- cpylen = copy_from_user(&tranAddr, ocba.pTranAddr, sizeof(tranAddr));
-+ if(copy_from_user(&tranAddr, ocba.pTranAddr, sizeof(tranAddr))) {
-+ retCode = -EFAULT;
-+ goto out;
-+ }
- if (tranAddr.uAddressLength > sizeof(addr)) {
- retCode = -EINVAL;
- goto out;
-@@ -145,7 +158,10 @@ int novfs_open_conn_by_addr(struct novfs
- openConn->TranAddr.uAddressLength = tranAddr.uAddressLength;
- memset(addr, 0xcc, sizeof(addr) - 1);
-
-- cpylen = copy_from_user(addr, tranAddr.puAddress, tranAddr.uAddressLength);
-+ if(copy_from_user(addr, tranAddr.puAddress, tranAddr.uAddressLength)) {
-+ retCode = -EFAULT;
-+ goto out;
-+ }
-
- DbgPrint("addr");
- novfs_dump(sizeof(addr), addr);
-@@ -166,8 +182,10 @@ int novfs_open_conn_by_addr(struct novfs
- 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);
-+ if(copy_to_user(pdata->reqData, &ocba, sizeof(ocba)))
-+ retCode = -EFAULT;
-+ else
-+ DbgPrint("New Conn Handle = %X", connReply->ConnHandle);
- }
- kfree(reply);
- }
-@@ -175,7 +193,6 @@ int novfs_open_conn_by_addr(struct novfs
- out:
- kfree(cmd);
- return (retCode);
--
- }
-
- int novfs_open_conn_by_ref(struct novfs_xplat *pdata, void **Handle, struct novfs_schandle Session)
-@@ -185,9 +202,10 @@ int novfs_open_conn_by_ref(struct novfs_
- struct nwd_open_conn_by_ref *openConn = NULL;
- struct nwc_open_conn_by_ref ocbr;
- int retCode = -ENOMEM;
-- unsigned long cmdlen, datalen, replylen, cpylen;
-+ unsigned long cmdlen, datalen, replylen;
-
-- cpylen = copy_from_user(&ocbr, pdata->reqData, sizeof(ocbr));
-+ if(copy_from_user(&ocbr, pdata->reqData, sizeof(ocbr)))
-+ return -EFAULT;
- datalen = sizeof(*openConn);
- cmdlen = datalen + sizeof(*cmd);
- cmd = kmalloc(cmdlen, GFP_KERNEL);
-@@ -218,8 +236,10 @@ int novfs_open_conn_by_ref(struct novfs_
- ocbr.ConnHandle = HandletoUint32(openConn->ConnHandle);
- *Handle = openConn->ConnHandle;
-
-- cpylen = copy_to_user(pdata->reqData, &ocbr, sizeof(ocbr));
-- DbgPrint("New Conn Handle = %X", openConn->ConnHandle);
-+ if(copy_to_user(pdata->reqData, &ocbr, sizeof(ocbr)))
-+ retCode = -EFAULT;
-+ else
-+ DbgPrint("New Conn Handle = %X", openConn->ConnHandle);
- }
- kfree(reply);
- }
-@@ -236,7 +256,7 @@ int novfs_raw_send(struct novfs_xplat *p
- struct novfs_xplat_call_request *cmd = NULL;
- struct novfs_xplat_call_reply *reply = NULL;
- int retCode = 0;
-- unsigned long cmdlen, datalen, replylen, cpylen, totalLen;
-+ unsigned long cmdlen, datalen, replylen, totalLen;
- unsigned int x;
- struct nwd_ncp_req *ncpData = NULL;
- struct nwd_ncp_rep *ncpReply = NULL;
-@@ -244,7 +264,8 @@ int novfs_raw_send(struct novfs_xplat *p
- unsigned long actualReplyLength = 0;
-
- DbgPrint("[XPLAT] Process Raw NCP Send");
-- cpylen = copy_from_user(&xRequest, pdata->reqData, sizeof(xRequest));
-+ if(copy_from_user(&xRequest, pdata->reqData, sizeof(xRequest)))
-+ return -EFAULT;
-
- if (xRequest.uNumReplyFrags > MAX_NUM_REPLIES || xRequest.uNumReplyFrags < MIN_NUM_REPLIES ||
- xRequest.uNumRequestFrags > MAX_NUM_REQUESTS || xRequest.uNumRequestFrags < MIN_NUM_REQUESTS)
-@@ -260,7 +281,10 @@ int novfs_raw_send(struct novfs_xplat *p
- if (!frag)
- return -ENOMEM;
-
-- cpylen = copy_from_user(frag, xRequest.pReplyFrags, xRequest.uNumReplyFrags * sizeof(struct nwc_frag));
-+ if(copy_from_user(frag, xRequest.pReplyFrags, xRequest.uNumReplyFrags * sizeof(struct nwc_frag))) {
-+ retCode = -EFAULT;
-+ goto out_frag;
-+ }
- totalLen = 0;
-
- cFrag = frag;
-@@ -282,7 +306,10 @@ int novfs_raw_send(struct novfs_xplat *p
- goto out;
- }
-
-- cpylen = copy_from_user(reqFrag, xRequest.pRequestFrags, xRequest.uNumRequestFrags * sizeof(struct nwc_frag));
-+ if(copy_from_user(reqFrag, xRequest.pRequestFrags, xRequest.uNumRequestFrags * sizeof(struct nwc_frag))) {
-+ retCode = -EFAULT;
-+ goto out_reqfrag;
-+ }
- cFrag = reqFrag;
- for (x = 0; x < xRequest.uNumRequestFrags; x++) {
- if (cFrag->uLength > MAX_FRAG_SIZE || cFrag->uLength < MIN_FRAG_SIZE) {
-@@ -325,7 +352,10 @@ int novfs_raw_send(struct novfs_xplat *p
- cFrag = reqFrag;
-
- for (x = 0; x < xRequest.uNumRequestFrags; x++) {
-- cpylen = copy_from_user(reqData, cFrag->pData, cFrag->uLength);
-+ if(copy_from_user(reqData, cFrag->pData, cFrag->uLength)) {
-+ retCode = -EFAULT;
-+ goto out;
-+ }
- reqData += cFrag->uLength;
- cFrag++;
- }
-@@ -356,7 +386,11 @@ int novfs_raw_send(struct novfs_xplat *p
-
- datalen = min((unsigned long)cFrag->uLength, totalLen);
-
-- cpylen = copy_to_user(cFrag->pData, reqData, datalen);
-+ if(copy_to_user(cFrag->pData, reqData, datalen)) {
-+ kfree(reply);
-+ retCode = -EFAULT;
-+ goto out;
-+ }
- totalLen -= datalen;
- reqData += datalen;
- actualReplyLength += datalen;
-@@ -370,11 +404,14 @@ int novfs_raw_send(struct novfs_xplat *p
- }
-
- xRequest.uActualReplyLength = actualReplyLength;
-- cpylen = copy_to_user(pdata->reqData, &xRequest, sizeof(xRequest));
-+ if (copy_to_user(pdata->reqData, &xRequest, sizeof(xRequest)))
-+ retCode = -EFAULT;
-
- out:
- kfree(cmd);
-+out_reqfrag:
- kfree(reqFrag);
-+out_frag:
- kfree(frag);
-
- return (retCode);
-@@ -387,9 +424,10 @@ int novfs_conn_close(struct novfs_xplat
- struct nwc_close_conn cc;
- struct nwd_close_conn *nwdClose = NULL;
- int retCode = 0;
-- unsigned long cmdlen, datalen, replylen, cpylen;
-+ unsigned long cmdlen, datalen, replylen;
-
-- cpylen = copy_from_user(&cc, pdata->reqData, sizeof(cc));
-+ if(copy_from_user(&cc, pdata->reqData, sizeof(cc)))
-+ return -EFAULT;
-
- datalen = sizeof(*nwdClose);
- cmdlen = datalen + sizeof(*cmd);
-@@ -425,9 +463,10 @@ int novfs_sys_conn_close(struct novfs_xp
- struct nwc_close_conn cc;
- struct nwd_close_conn *nwdClose = NULL;
- unsigned int retCode = 0;
-- unsigned long cmdlen, datalen, replylen, cpylen;
-+ unsigned long cmdlen, datalen, replylen;
-
-- cpylen = copy_from_user(&cc, pdata->reqData, sizeof(cc));
-+ if(copy_from_user(&cc, pdata->reqData, sizeof(cc)))
-+ return -EFAULT;
-
- datalen = sizeof(*nwdClose);
- cmdlen = datalen + sizeof(*cmd);
-@@ -464,19 +503,20 @@ int novfs_login_id(struct novfs_xplat *p
- struct ncl_string server;
- struct ncl_string username;
- struct ncl_string password;
-- unsigned long cpylen;
- struct nwc_string nwcStr;
-
- memset(&server, 0, sizeof(server));
- memset(&username, 0, sizeof(username));
- memset(&password, 0, sizeof(password));
-
-- cpylen = copy_from_user(&lgn, pdata->reqData, sizeof(lgn));
-+ if(copy_from_user(&lgn, pdata->reqData, sizeof(lgn)))
-+ return -EFAULT;
-
- DbgPrint("");
- novfs_dump(sizeof(lgn), &lgn);
-
-- cpylen = copy_from_user(&nwcStr, lgn.pDomainName, sizeof(nwcStr));
-+ if(copy_from_user(&nwcStr, lgn.pDomainName, sizeof(nwcStr)))
-+ return -EFAULT;
- DbgPrint("DomainName\n");
- novfs_dump(sizeof(nwcStr), &nwcStr);
-
-@@ -490,7 +530,10 @@ int novfs_login_id(struct novfs_xplat *p
- DbgPrint("Server");
- novfs_dump(server.len, server.buffer);
-
-- cpylen = copy_from_user(&nwcStr, lgn.pObjectName, sizeof(nwcStr));
-+ if(copy_from_user(&nwcStr, lgn.pObjectName, sizeof(nwcStr))) {
-+ retCode = -EFAULT;
-+ goto out_server;
-+ }
- DbgPrint("ObjectName");
- if (nwcStr.DataLen > NW_MAX_DN_BYTES) {
- retCode = -EINVAL;
-@@ -504,11 +547,14 @@ int novfs_login_id(struct novfs_xplat *p
- DbgPrint("User");
- novfs_dump(username.len, username.buffer);
-
-- cpylen = copy_from_user(&nwcStr, lgn.pPassword, sizeof(nwcStr));
-+ if(copy_from_user(&nwcStr, lgn.pPassword, sizeof(nwcStr))) {
-+ retCode = -EFAULT;
-+ goto out_username;
-+ }
- DbgPrint("Password");
- if (nwcStr.DataLen > MAX_PASSWORD_LENGTH) {
- retCode = -EINVAL;
-- goto out;
-+ goto out_username;
- }
- novfs_dump(sizeof(nwcStr), &nwcStr);
-
-@@ -524,9 +570,8 @@ int novfs_login_id(struct novfs_xplat *p
- }
-
- plgn = (struct nwc_login_id *)pdata->reqData;
-- cpylen =
-- copy_to_user(&plgn->AuthenticationId, &lgn.AuthenticationId,
-- sizeof(plgn->AuthenticationId));
-+ if(copy_to_user(&plgn->AuthenticationId, &lgn.AuthenticationId, sizeof(plgn->AuthenticationId)))
-+ retCode = -EFAULT;
- }
- memset(password.buffer, 0, password.len);
-
-@@ -538,7 +583,9 @@ int novfs_login_id(struct novfs_xplat *p
- }
- out:
- kfree(password.buffer);
-+out_username:
- kfree(username.buffer);
-+out_server:
- kfree(server.buffer);
- return (retCode);
- }
-@@ -550,7 +597,7 @@ int novfs_auth_conn(struct novfs_xplat *
- struct novfs_xplat_call_request *cmd = NULL;
- struct novfs_xplat_call_reply *reply = NULL;
- int retCode = -ENOMEM;
-- unsigned long cmdlen, datalen, replylen, cpylen;
-+ unsigned long cmdlen, datalen, replylen;
-
- datalen = sizeof(*pDauth);
- cmdlen = datalen + sizeof(*cmd);
-@@ -563,7 +610,10 @@ int novfs_auth_conn(struct novfs_xplat *
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_AUTHENTICATE_CONN_WITH_ID;
-
-- cpylen = copy_from_user(&pauth, pdata->reqData, sizeof(pauth));
-+ if(copy_from_user(&pauth, pdata->reqData, sizeof(pauth))) {
-+ retCode = -EFAULT;
-+ goto out;
-+ }
-
- pDauth = (struct nwc_auth_wid *)cmd->data;
- cmd->dataLen = datalen;
-@@ -575,6 +625,9 @@ int novfs_auth_conn(struct novfs_xplat *
- retCode = reply->Reply.ErrorCode;
- kfree(reply);
- }
-+
-+out:
-+ kfree(cmd);
- return (retCode);
- }
-
-@@ -585,7 +638,7 @@ int novfs_license_conn(struct novfs_xpla
- struct nwc_license_conn lisc;
- struct nwc_lisc_id *pDLisc = NULL;
- int retCode = -ENOMEM;
-- unsigned long cmdlen, datalen, replylen, cpylen;
-+ unsigned long cmdlen, datalen, replylen;
-
- datalen = sizeof(*pDLisc);
- cmdlen = datalen + sizeof(*cmd);
-@@ -598,7 +651,10 @@ int novfs_license_conn(struct novfs_xpla
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_LICENSE_CONN;
-
-- cpylen = copy_from_user(&lisc, pdata->reqData, sizeof(lisc));
-+ if(copy_from_user(&lisc, pdata->reqData, sizeof(lisc))) {
-+ retCode = -EFAULT;
-+ goto out;
-+ }
-
- pDLisc = (struct nwc_lisc_id *)cmd->data;
- cmd->dataLen = datalen;
-@@ -609,6 +665,8 @@ int novfs_license_conn(struct novfs_xpla
- retCode = reply->Reply.ErrorCode;
- kfree(reply);
- }
-+
-+out:
- kfree(cmd);
- return (retCode);
- }
-@@ -619,7 +677,7 @@ int novfs_logout_id(struct novfs_xplat *
- struct novfs_xplat_call_reply *reply = NULL;
- struct nwc_lo_id logout, *pDLogout = NULL;
- int retCode = -ENOMEM;
-- unsigned long cmdlen, datalen, replylen, cpylen;
-+ unsigned long cmdlen, datalen, replylen;
-
- datalen = sizeof(*pDLogout);
- cmdlen = datalen + sizeof(*cmd);
-@@ -632,7 +690,10 @@ int novfs_logout_id(struct novfs_xplat *
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_LOGOUT_IDENTITY;
-
-- cpylen = copy_from_user(&logout, pdata->reqData, sizeof(logout));
-+ if(copy_from_user(&logout, pdata->reqData, sizeof(logout))) {
-+ retCode = -EFAULT;
-+ goto out;
-+ }
-
- pDLogout = (struct nwc_lo_id *)cmd->data;
- cmd->dataLen = datalen;
-@@ -643,6 +704,8 @@ int novfs_logout_id(struct novfs_xplat *
- retCode = reply->Reply.ErrorCode;
- kfree(reply);
- }
-+
-+out:
- kfree(cmd);
- return (retCode);
- }
-@@ -653,9 +716,10 @@ int novfs_unlicense_conn(struct novfs_xp
- struct novfs_xplat_call_reply *reply = NULL;
- struct nwc_unlic_conn *pUconn = NULL, ulc;
- int retCode = -ENOMEM;
-- unsigned long cmdlen, datalen, replylen, cpylen;
-+ unsigned long cmdlen, datalen, replylen;
-
-- cpylen = copy_from_user(&ulc, pdata->reqData, sizeof(ulc));
-+ if(copy_from_user(&ulc, pdata->reqData, sizeof(ulc)))
-+ return -EFAULT;
- datalen = sizeof(*pUconn);
- cmdlen = datalen + sizeof(*cmd);
- cmd = kmalloc(cmdlen, GFP_KERNEL);
-@@ -688,7 +752,7 @@ int novfs_unauthenticate(struct novfs_xp
- struct novfs_xplat_call_reply *reply = NULL;
- struct nwc_unauthenticate auth, *pDAuth = NULL;
- int retCode = -ENOMEM;
-- unsigned long cmdlen, datalen, replylen, cpylen;
-+ unsigned long cmdlen, datalen, replylen;
-
- datalen = sizeof(*pDAuth);
- cmdlen = datalen + sizeof(*cmd);
-@@ -701,7 +765,10 @@ int novfs_unauthenticate(struct novfs_xp
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_UNAUTHENTICATE_CONN;
-
-- cpylen = copy_from_user(&auth, pdata->reqData, sizeof(auth));
-+ if(copy_from_user(&auth, pdata->reqData, sizeof(auth))) {
-+ retCode = -EFAULT;
-+ goto out;
-+ }
-
- pDAuth = (struct nwc_unauthenticate *)cmd->data;
- cmd->dataLen = datalen;
-@@ -713,6 +780,8 @@ int novfs_unauthenticate(struct novfs_xp
- retCode = reply->Reply.ErrorCode;
- kfree(reply);
- }
-+
-+out:
- kfree(cmd);
- return (retCode);
-
-@@ -725,15 +794,18 @@ int novfs_get_conn_info(struct novfs_xpl
- struct nwc_get_conn_info connInfo;
- struct nwd_conn_info *pDConnInfo = NULL;
- int retCode = -ENOMEM;
-- unsigned long cmdlen, replylen, cpylen;
-+ unsigned long cmdlen, replylen;
-
- 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;
-
-+ if(copy_from_user(&connInfo, pdata->reqData, sizeof(struct nwc_get_conn_info))) {
-+ retCode = -EFAULT;
-+ goto out;
-+ }
-+
- if (connInfo.uInfoLength > MAX_INFO_LEN) {
- retCode = -EINVAL;
- goto out;
-@@ -773,14 +845,17 @@ int novfs_set_conn_info(struct novfs_xpl
- struct nwc_set_conn_info connInfo;
- struct nwd_set_conn_info *pDConnInfo = NULL;
- int retCode = -ENOMEM;
-- unsigned long cmdlen, replylen, cpylen;
-+ unsigned long cmdlen, replylen;
-
- 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;
-+ if(copy_from_user(&connInfo, pdata->reqData, sizeof(struct nwc_set_conn_info))) {
-+ retCode = -EFAULT;
-+ goto out;
-+ }
-+
- if (connInfo.uInfoLength > MAX_INFO_LEN) {
- retCode = -EINVAL;
- goto out;
-@@ -819,14 +894,16 @@ int novfs_get_id_info(struct novfs_xplat
- struct nwc_string xferStr;
- char *str = NULL;
- int retCode = -ENOMEM;
-- unsigned long cmdlen, replylen, cpylen;
-+ unsigned long cmdlen, replylen;
-
- cmdlen = sizeof(*cmd) + sizeof(*idInfo);
- cmd = kmalloc(cmdlen, GFP_KERNEL);
-- cpylen = copy_from_user(&qidInfo, pdata->reqData, sizeof(qidInfo));
--
- if (!cmd)
- return -ENOMEM;
-+ if(copy_from_user(&qidInfo, pdata->reqData, sizeof(qidInfo))) {
-+ retCode = -EFAULT;
-+ goto out_cmd;
-+ }
-
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
-@@ -847,13 +924,31 @@ int novfs_get_id_info(struct novfs_xplat
- */
- 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));
-+ if(copy_to_user(&gId->AuthenticationId, &idInfo->AuthenticationId, sizeof(idInfo->AuthenticationId))) {
-+ retCode = -EFAULT;
-+ goto out;
-+ }
-+ if(copy_to_user(&gId->AuthType, &idInfo->AuthType, sizeof(idInfo->AuthType))) {
-+ retCode = -EFAULT;
-+ goto out;
-+ }
-+ if(copy_to_user(&gId->IdentityFlags, &idInfo->IdentityFlags, sizeof(idInfo->IdentityFlags))) {
-+ retCode = -EFAULT;
-+ goto out;
-+ }
-+ if(copy_to_user(&gId->NameType, &idInfo->NameType, sizeof(idInfo->NameType))) {
-+ retCode = -EFAULT;
-+ goto out;
-+ }
-+ if(copy_to_user(&gId->ObjectType, &idInfo->ObjectType, sizeof(idInfo->ObjectType))) {
-+ retCode = -EFAULT;
-+ goto out;
-+ }
-
-- cpylen = copy_from_user(&xferStr, gId->pDomainName, sizeof(struct nwc_string));
-+ if(copy_from_user(&xferStr, gId->pDomainName, sizeof(struct nwc_string))) {
-+ retCode = -EFAULT;
-+ goto out;
-+ }
- if (idInfo->pDomainNameOffset >= reply->dataLen) {
- retCode = -EINVAL;
- goto out;
-@@ -864,11 +959,20 @@ int novfs_get_id_info(struct novfs_xplat
- goto out;
- }
-
-- cpylen = copy_to_user(xferStr.pBuffer, str, idInfo->domainLen);
-+ if(copy_to_user(xferStr.pBuffer, str, idInfo->domainLen)) {
-+ retCode = -EFAULT;
-+ goto out;
-+ }
- 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));
-+ if(copy_to_user(gId->pDomainName, &xferStr, sizeof(struct nwc_string))) {
-+ retCode = -EFAULT;
-+ goto out;
-+ }
-+ if(copy_from_user(&xferStr, gId->pObjectName, sizeof(struct nwc_string))) {
-+ retCode = -EFAULT;
-+ goto out;
-+ }
-
- if (idInfo->pObjectNameOffset >= reply->dataLen) {
- retCode = -EINVAL;
-@@ -879,15 +983,21 @@ int novfs_get_id_info(struct novfs_xplat
- retCode = -EINVAL;
- goto out;
- }
-- cpylen = copy_to_user(xferStr.pBuffer, str, idInfo->objectLen);
-+ if(copy_to_user(xferStr.pBuffer, str, idInfo->objectLen)) {
-+ retCode = -EFAULT;
-+ goto out;
-+ }
-+
- xferStr.DataLen = idInfo->objectLen - 1;
- xferStr.DataType = NWC_STRING_TYPE_ASCII;
-- cpylen = copy_to_user(gId->pObjectName, &xferStr, sizeof(struct nwc_string));
-+ if(copy_to_user(gId->pObjectName, &xferStr, sizeof(struct nwc_string)))
-+ retCode = -EFAULT;
- }
- }
-
- out:
- kfree(reply);
-+out_cmd:
- kfree(cmd);
- return (retCode);
- }
-@@ -899,10 +1009,11 @@ int novfs_scan_conn_info(struct novfs_xp
- struct nwc_scan_conn_info connInfo, *rInfo = NULL;
- struct nwd_scan_conn_info *pDConnInfo = NULL;
- int retCode = -ENOMEM;
-- unsigned long cmdlen, replylen, cpylen;
-+ unsigned long cmdlen, replylen;
- unsigned char *localData = NULL;
-
-- cpylen = copy_from_user(&connInfo, pdata->reqData, sizeof(struct nwc_scan_conn_info));
-+ if(copy_from_user(&connInfo, pdata->reqData, sizeof(struct nwc_scan_conn_info)))
-+ return -EFAULT;
-
- if (connInfo.uReturnInfoLength > MAX_INFO_LEN || connInfo.uScanInfoLen > MAX_INFO_LEN)
- return -EINVAL;
-@@ -940,7 +1051,10 @@ int novfs_scan_conn_info(struct novfs_xp
- localData = (unsigned char *)pDConnInfo;
- pDConnInfo->uScanConnInfoOffset = sizeof(*pDConnInfo);
- localData += pDConnInfo->uScanConnInfoOffset;
-- cpylen = copy_from_user(localData, connInfo.pScanConnInfo, connInfo.uScanInfoLen);
-+ if(copy_from_user(localData, connInfo.pScanConnInfo, connInfo.uScanInfoLen)) {
-+ retCode = -EFAULT;
-+ goto out;
-+ }
- } else {
- pDConnInfo->uScanConnInfoOffset = 0;
- }
-@@ -959,36 +1073,49 @@ int novfs_scan_conn_info(struct novfs_xp
- 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));
-+ if(copy_to_user(pdata->repData, &pDConnInfo->uScanIndex, sizeof(pDConnInfo->uScanIndex))) {
-+ kfree(reply);
-+ retCode = -EFAULT;
-+ goto out;
-+ }
-+ if(copy_to_user(&rInfo->uConnectionReference, &pDConnInfo->uConnectionReference, sizeof(pDConnInfo->uConnectionReference))) {
-+ kfree(reply);
-+ retCode = -EFAULT;
-+ goto out;
-+ }
- } else {
- unsigned long x;
-
- x = 0;
- rInfo = (struct nwc_scan_conn_info *)pdata->reqData;
-- cpylen = copy_to_user(&rInfo->uConnectionReference, &x, sizeof(rInfo->uConnectionReference));
-+ if(copy_to_user(&rInfo->uConnectionReference, &x, sizeof(rInfo->uConnectionReference)))
-+ retCode = -EFAULT;
- }
-
- kfree(reply);
- } else {
- retCode = -EIO;
- }
-+
-+out:
- kfree(cmd);
- return (retCode);
- }
-
- /*
-- * Copies the user data out of the scan conn info call.
-- */
-+ *
-+ * Copies the user data out of the scan conn info call.
-+ *
-+ * FIXME: This function is very badly designed. The return parameter should not be void
-+ * and should be an integer. Based on the return value, the OUT parameters should be
-+ * used. This function and the callers should be improved and written again. */
- 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 = NULL;
- unsigned char *srcData = NULL;
-- unsigned long dataLen = 0, cpylen;
-+ unsigned long dataLen = 0;
-
- pDConnInfo = (struct nwd_scan_conn_info *)reply->data;
- uLevel = pDConnInfo->uReturnInfoLevel;
-@@ -1030,7 +1157,8 @@ static void GetUserData(struct nwc_scan_
-
- DbgPrint("NWC_CONN_INFO_TRAN_ADDR 0x%p -> 0x%p :: 0x%X", srcData, connInfo->pReturnConnInfo, dataLen);
-
-- cpylen = copy_from_user(&tranAddr, dstData, sizeof(tranAddr));
-+ if(copy_from_user(&tranAddr, dstData, sizeof(tranAddr)))
-+ goto out_memerr;
- if (((struct nwd_scan_conn_info *)srcData)->uReturnConnInfoOffset >= reply->dataLen)
- goto out;
- srcData += ((struct nwd_scan_conn_info *)srcData)->uReturnConnInfoOffset;
-@@ -1038,9 +1166,11 @@ static void GetUserData(struct nwc_scan_
- tranAddr.uAddressLength = ((struct tagNwdTranAddrEx *)srcData)->uAddressLength;
- if (tranAddr.uAddressLength > MAX_ADDRESS_LENGTH)
- goto out;
-- cpylen = copy_to_user(dstData, &tranAddr, sizeof(tranAddr));
-- cpylen = copy_to_user(tranAddr.puAddress,
-- ((struct tagNwdTranAddrEx *)srcData)->Buffer, tranAddr.uAddressLength);
-+ if(copy_to_user(dstData, &tranAddr, sizeof(tranAddr)))
-+ goto out_memerr;
-+ if(copy_to_user(tranAddr.puAddress,
-+ ((struct tagNwdTranAddrEx *)srcData)->Buffer, tranAddr.uAddressLength))
-+ goto out_memerr;
- dataLen = 0;
- break;
- }
-@@ -1056,11 +1186,19 @@ static void GetUserData(struct nwc_scan_
-
- if (srcData && dataLen && dataLen <= reply->dataLen) {
- DbgPrint("Copy Data 0x%p -> 0x%p :: 0x%X", srcData, connInfo->pReturnConnInfo, dataLen);
-- cpylen = copy_to_user(connInfo->pReturnConnInfo, srcData, dataLen);
-+ if(copy_to_user(connInfo->pReturnConnInfo, srcData, dataLen))
-+ goto out_memerr;
- }
-
- out:
- return;
-+
-+out_memerr:
-+ /* Having this separate label for memory error handling,
-+ * helps in improving code readability. Ideally a -EFAULT
-+ * should be returned if the function would return an int. */
-+ DbgPrint("EFAULT while trying to copy memory between user and kernel space");
-+ return;
- }
-
- /*
-@@ -1073,7 +1211,7 @@ static void GetConnData(struct nwc_get_c
- struct nwd_conn_info *pDConnInfo = NULL;
-
- unsigned char *srcData = NULL;
-- unsigned long dataLen = 0, cpylen;
-+ unsigned long dataLen = 0;
-
- pDConnInfo = (struct nwd_conn_info *)cmd->data;
- uLevel = pDConnInfo->uInfoLevel;
-@@ -1095,14 +1233,17 @@ static void GetConnData(struct nwc_get_c
-
- srcData = (unsigned char *)reply->data;
-
-- cpylen = copy_from_user(&tranAddr, dstData, sizeof(tranAddr));
-+ if(copy_from_user(&tranAddr, dstData, sizeof(tranAddr)))
-+ goto out_memerr;
- tranAddr.uTransportType = ((struct tagNwdTranAddrEx *)srcData)->uTransportType;
- tranAddr.uAddressLength = ((struct tagNwdTranAddrEx *)srcData)->uAddressLength;
- if (tranAddr.uAddressLength > MAX_ADDRESS_LENGTH)
- goto out;
-- cpylen = copy_to_user(dstData, &tranAddr, sizeof(tranAddr));
-- cpylen = copy_to_user(tranAddr.puAddress,
-- ((struct tagNwdTranAddrEx *)srcData)->Buffer, tranAddr.uAddressLength);
-+ if(copy_to_user(dstData, &tranAddr, sizeof(tranAddr)))
-+ goto out_memerr;
-+ if(copy_to_user(tranAddr.puAddress,
-+ ((struct tagNwdTranAddrEx *)srcData)->Buffer, tranAddr.uAddressLength))
-+ goto out_memerr;
- dataLen = 0;
- break;
- }
-@@ -1147,11 +1288,19 @@ static void GetConnData(struct nwc_get_c
- }
-
- if (srcData && dataLen && dataLen <= reply->dataLen) {
-- cpylen = copy_to_user(connInfo->pConnInfo, srcData, connInfo->uInfoLength);
-+ if(copy_to_user(connInfo->pConnInfo, srcData, connInfo->uInfoLength))
-+ goto out_memerr;
- }
-
- out:
- return;
-+
-+out_memerr:
-+ /* Having this separate label for memory error handling,
-+ * helps in improving code readability. Ideally a -EFAULT
-+ * should be returned if the function would return an int. */
-+ DbgPrint("EFAULT while trying to copy memory between user and kernel space");
-+ return;
- }
-
- int novfs_get_daemon_ver(struct novfs_xplat *pdata, struct novfs_schandle Session)
-@@ -1160,7 +1309,7 @@ int novfs_get_daemon_ver(struct novfs_xp
- struct novfs_xplat_call_reply *reply = NULL;
- struct nwd_get_reqversion *pDVersion = NULL;
- int retCode = -ENOMEM;
-- unsigned long cmdlen, datalen, replylen, cpylen;
-+ unsigned long cmdlen, datalen, replylen;
-
- datalen = sizeof(*pDVersion);
- cmdlen = datalen + sizeof(*cmd);
-@@ -1177,12 +1326,12 @@ int novfs_get_daemon_ver(struct novfs_xp
- if (reply) {
- retCode = reply->Reply.ErrorCode;
- pDVersion = (struct nwd_get_reqversion *)reply->data;
-- cpylen = copy_to_user(pDVersion, pdata->reqData, sizeof(*pDVersion));
-+ if(copy_to_user(pDVersion, pdata->reqData, sizeof(*pDVersion)))
-+ retCode = -EFAULT;
- kfree(reply);
- }
- kfree(cmd);
- return (retCode);
--
- }
-
- int novfs_get_preferred_DS_tree(struct novfs_xplat *pdata, struct novfs_schandle Session)
-@@ -1192,10 +1341,11 @@ int novfs_get_preferred_DS_tree(struct n
- struct nwd_get_pref_ds_tree *pDGetTree = NULL;
- struct nwc_get_pref_ds_tree xplatCall, *p = NULL;
- int retCode = -ENOMEM;
-- unsigned long cmdlen, datalen, replylen, cpylen;
-+ unsigned long cmdlen, datalen, replylen;
- unsigned char *dPtr = NULL;
-
-- cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(struct nwc_get_pref_ds_tree));
-+ if(copy_from_user(&xplatCall, pdata->reqData, sizeof(struct nwc_get_pref_ds_tree)))
-+ return -EFAULT;
- if (xplatCall.uTreeLength > NW_MAX_TREE_NAME_LEN)
- return -EINVAL;
- datalen = sizeof(*pDGetTree) + xplatCall.uTreeLength;
-@@ -1231,8 +1381,10 @@ int novfs_get_preferred_DS_tree(struct n
- retCode = -EINVAL;
- goto out;
- }
-- cpylen = copy_to_user(p, &pDGetTree->uTreeLength, 4);
-- cpylen = copy_to_user(xplatCall.pDsTreeName, dPtr, pDGetTree->uTreeLength);
-+ if(copy_to_user(p, &pDGetTree->uTreeLength, 4))
-+ retCode = -EFAULT;
-+ else if(copy_to_user(xplatCall.pDsTreeName, dPtr, pDGetTree->uTreeLength))
-+ retCode = -EFAULT;
- }
- }
-
-@@ -1250,10 +1402,11 @@ int novfs_set_preferred_DS_tree(struct n
- struct nwd_set_pref_ds_tree *pDSetTree = NULL;
- struct nwc_set_pref_ds_tree xplatCall;
- int retCode = -ENOMEM;
-- unsigned long cmdlen, datalen, replylen, cpylen;
-+ unsigned long cmdlen, datalen, replylen;
- unsigned char *dPtr = NULL;
-
-- cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(struct nwc_set_pref_ds_tree));
-+ if(copy_from_user(&xplatCall, pdata->reqData, sizeof(struct nwc_set_pref_ds_tree)))
-+ return -EFAULT;
- if (xplatCall.uTreeLength > NW_MAX_TREE_NAME_LEN)
- return -EINVAL;
- datalen = sizeof(*pDSetTree) + xplatCall.uTreeLength;
-@@ -1273,16 +1426,17 @@ int novfs_set_preferred_DS_tree(struct n
- pDSetTree->uTreeLength = xplatCall.uTreeLength;
-
- dPtr = cmd->data + sizeof(*pDSetTree);
-- cpylen = copy_from_user(dPtr, xplatCall.pDsTreeName, xplatCall.uTreeLength);
-+ if(copy_from_user(dPtr, xplatCall.pDsTreeName, xplatCall.uTreeLength))
-+ goto out;
-
- retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
- if (reply) {
- retCode = reply->Reply.ErrorCode;
- kfree(reply);
- }
-+out:
- kfree(cmd);
- return (retCode);
--
- }
-
- int novfs_set_default_ctx(struct novfs_xplat *pdata, struct novfs_schandle Session)
-@@ -1292,10 +1446,11 @@ int novfs_set_default_ctx(struct novfs_x
- struct nwc_set_def_name_ctx xplatCall;
- struct nwd_set_def_name_ctx *pDSet = NULL;
- int retCode = -ENOMEM;
-- unsigned long cmdlen, datalen, replylen, cpylen;
-+ unsigned long cmdlen, datalen, replylen;
- unsigned char *dPtr = NULL;
-
-- cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(struct nwc_set_def_name_ctx));
-+ if(copy_from_user(&xplatCall, pdata->reqData, sizeof(struct nwc_set_def_name_ctx)))
-+ return -EFAULT;
- if (xplatCall.uNameLength > MAX_NAME_LEN || xplatCall.uTreeLength > NW_MAX_TREE_NAME_LEN)
- return -EINVAL;
- datalen = sizeof(*pDSet) + xplatCall.uTreeLength + xplatCall.uNameLength;
-@@ -1318,18 +1473,25 @@ int novfs_set_default_ctx(struct novfs_x
- 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);
-+ if(copy_from_user(dPtr + pDSet->TreeOffset, xplatCall.pDsTreeName, xplatCall.uTreeLength)) {
-+ retCode = -EFAULT;
-+ goto out;
-+ }
-+
-+ if(copy_from_user(dPtr + pDSet->NameContextOffset, xplatCall.pNameContext, xplatCall.uNameLength)) {
-+ retCode = -EFAULT;
-+ goto out;
-+ }
-
- retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
- if (reply) {
- retCode = reply->Reply.ErrorCode;
- kfree(reply);
- }
-+
-+out:
- kfree(cmd);
- return (retCode);
--
- }
-
- int novfs_get_default_ctx(struct novfs_xplat *pdata, struct novfs_schandle Session)
-@@ -1340,9 +1502,10 @@ int novfs_get_default_ctx(struct novfs_x
- struct nwd_get_def_name_ctx *pGet = NULL;
- char *dPtr = NULL;
- int retCode = -ENOMEM;
-- unsigned long cmdlen, replylen, cpylen;
-+ unsigned long cmdlen, replylen;
-
-- cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(struct nwc_get_def_name_ctx));
-+ if(copy_from_user(&xplatCall, pdata->reqData, sizeof(struct nwc_get_def_name_ctx)))
-+ return -EFAULT;
- if (xplatCall.uTreeLength > NW_MAX_TREE_NAME_LEN)
- return -EINVAL;
-
-@@ -1363,8 +1526,10 @@ int novfs_get_default_ctx(struct novfs_x
- 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
-+ if(copy_from_user(dPtr + pGet->TreeOffset, xplatCall.pDsTreeName, xplatCall.uTreeLength)) {
-+ retCode = -EFAULT;
-+ goto out;
-+ }
- dPtr[pGet->TreeOffset + pGet->uTreeLength] = 0;
-
- retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
-@@ -1379,23 +1544,25 @@ int novfs_get_default_ctx(struct novfs_x
- retCode = NWE_BUFFER_OVERFLOW;
- }
- dPtr = (char *)pGet + pGet->NameContextOffset;
-- cpylen = copy_to_user(xplatCall.pNameContext, dPtr, pGet->uNameLength);
-+ if(copy_to_user(xplatCall.pNameContext, dPtr, pGet->uNameLength))
-+ retCode = -EFAULT;
- }
-
- kfree(reply);
- }
-+
-+out:
- 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));
-+ if(copy_from_user(&xpCall, pdata->reqData, sizeof(struct nwc_query_feature)))
-+ return -EFAULT;
- switch (xpCall.Feature) {
- case NWC_FEAT_NDS:
- case NWC_FEAT_NDS_MTREE:
-@@ -1415,9 +1582,10 @@ int novfs_get_tree_monitored_conn(struct
- struct nwc_get_tree_monitored_conn_ref xplatCall, *p = NULL;
- struct nwd_get_tree_monitored_conn_ref *pDConnRef = NULL;
- char *dPtr = NULL;
-- unsigned long status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
-+ unsigned long status = -ENOMEM, cmdlen, datalen, replylen;
-
-- cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(struct nwc_get_tree_monitored_conn_ref));
-+ if(copy_from_user(&xplatCall, pdata->reqData, sizeof(struct nwc_get_tree_monitored_conn_ref)))
-+ return -EFAULT;
- if (!access_ok(VERIFY_READ, xplatCall.pTreeName, sizeof(struct nwc_string)))
- return -EINVAL;
- if (xplatCall.pTreeName->DataLen > NW_MAX_TREE_NAME_LEN)
-@@ -1440,17 +1608,23 @@ int novfs_get_tree_monitored_conn(struct
- pDConnRef->TreeName.type = xplatCall.pTreeName->DataType;
-
- dPtr = cmd->data + sizeof(*pDConnRef);
-- cpylen = copy_from_user(dPtr, xplatCall.pTreeName->pBuffer, pDConnRef->TreeName.len);
-+ if(copy_from_user(dPtr, xplatCall.pTreeName->pBuffer, pDConnRef->TreeName.len)) {
-+ status = -EFAULT;
-+ goto out;
-+ }
- 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;
-+ if(copy_to_user(&p->uConnReference, &pDConnRef->uConnReference, 4))
-+ status = -EFAULT;
-+ else
-+ status = reply->Reply.ErrorCode;
- kfree(reply);
- }
-+
-+out:
- kfree(cmd);
- return (status);
- }
-@@ -1463,9 +1637,10 @@ int novfs_enum_ids(struct novfs_xplat *p
- struct nwd_enum_ids *pEnum = NULL;
- struct nwc_string xferStr;
- char *str = NULL;
-- unsigned long status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
-+ unsigned long status = -ENOMEM, cmdlen, datalen, replylen;
-
-- cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(struct nwc_enum_ids));
-+ if(copy_from_user(&xplatCall, pdata->reqData, sizeof(struct nwc_enum_ids)))
-+ return -EFAULT;
- datalen = sizeof(*pEnum);
- cmdlen = datalen + sizeof(*cmd);
- cmd = kmalloc(cmdlen, GFP_KERNEL);
-@@ -1490,16 +1665,37 @@ int novfs_enum_ids(struct novfs_xplat *p
-
- eId = pdata->repData;
- pEnum = (struct nwd_enum_ids *)reply->data;
-- cpylen = copy_to_user(&eId->Iterator, &pEnum->Iterator, sizeof(pEnum->Iterator));
-+ if(copy_to_user(&eId->Iterator, &pEnum->Iterator, sizeof(pEnum->Iterator))) {
-+ status = -EFAULT;
-+ goto out;
-+ }
- 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(copy_to_user(&eId->AuthenticationId, &pEnum->AuthenticationId, sizeof(pEnum->AuthenticationId))) {
-+ status = -EFAULT;
-+ goto out;
-+ }
-+ if(copy_to_user(&eId->AuthType, &pEnum->AuthType, sizeof(pEnum->AuthType))) {
-+ status = -EFAULT;
-+ goto out;
-+ }
-+ if(copy_to_user(&eId->IdentityFlags, &pEnum->IdentityFlags, sizeof(pEnum->IdentityFlags))) {
-+ status = -EFAULT;
-+ goto out;
-+ }
-+ if(copy_to_user(&eId->NameType, &pEnum->NameType, sizeof(pEnum->NameType))) {
-+ status = -EFAULT;
-+ goto out;
-+ }
-+ if(copy_to_user(&eId->ObjectType, &pEnum->ObjectType, sizeof(pEnum->ObjectType))) {
-+ status = -EFAULT;
-+ goto out;
-+ }
-
- if (!status) {
-- cpylen = copy_from_user(&xferStr, eId->pDomainName, sizeof(struct nwc_string));
-+ if(copy_from_user(&xferStr, eId->pDomainName, sizeof(struct nwc_string))) {
-+ status = -EFAULT;
-+ goto out;
-+ }
- if (pEnum->domainNameOffset >= reply->dataLen) {
- status = -EINVAL;
- goto out;
-@@ -1510,12 +1706,21 @@ int novfs_enum_ids(struct novfs_xplat *p
- status = -EINVAL;
- goto out;
- }
-- cpylen = copy_to_user(xferStr.pBuffer, str, pEnum->domainNameLen);
-+ if(copy_to_user(xferStr.pBuffer, str, pEnum->domainNameLen)) {
-+ status = -EFAULT;
-+ goto out;
-+ }
- xferStr.DataType = NWC_STRING_TYPE_ASCII;
- xferStr.DataLen = pEnum->domainNameLen - 1;
-- cpylen = copy_to_user(eId->pDomainName, &xferStr, sizeof(struct nwc_string));
-+ if(copy_to_user(eId->pDomainName, &xferStr, sizeof(struct nwc_string))) {
-+ status = -EFAULT;
-+ goto out;
-+ }
-
-- cpylen = copy_from_user(&xferStr, eId->pObjectName, sizeof(struct nwc_string));
-+ if(copy_from_user(&xferStr, eId->pObjectName, sizeof(struct nwc_string))) {
-+ status = -EFAULT;
-+ goto out;
-+ }
- if (pEnum->objectNameOffset >= reply->dataLen) {
- status = -EINVAL;
- goto out;
-@@ -1526,10 +1731,14 @@ int novfs_enum_ids(struct novfs_xplat *p
- status = -EINVAL;
- goto out;
- }
-- cpylen = copy_to_user(xferStr.pBuffer, str, pEnum->objectNameLen);
-+ if(copy_to_user(xferStr.pBuffer, str, pEnum->objectNameLen)) {
-+ status = -EFAULT;
-+ goto out;
-+ }
- xferStr.DataType = NWC_STRING_TYPE_ASCII;
- xferStr.DataLen = pEnum->objectNameLen - 1;
-- cpylen = copy_to_user(eId->pObjectName, &xferStr, sizeof(struct nwc_string));
-+ if(copy_to_user(eId->pObjectName, &xferStr, sizeof(struct nwc_string)))
-+ status = -EFAULT;
- }
- }
- out:
-@@ -1546,9 +1755,10 @@ int novfs_change_auth_key(struct novfs_x
- struct nwd_change_key *pNewKey = NULL;
- struct nwc_string xferStr;
- char *str = NULL;
-- unsigned long status = -ENOMEM, cmdlen = 0, datalen, replylen, cpylen;
-+ unsigned long status = -ENOMEM, cmdlen = 0, datalen, replylen;
-
-- cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(struct nwc_change_key));
-+ if(copy_from_user(&xplatCall, pdata->reqData, sizeof(struct nwc_change_key)))
-+ return -EFAULT;
- if (!access_ok(VERIFY_READ, xplatCall.pDomainName, sizeof(struct nwc_string)) ||
- !access_ok(VERIFY_READ, xplatCall.pObjectName, sizeof(struct nwc_string)) ||
- !access_ok(VERIFY_READ, xplatCall.pNewPassword, sizeof(struct nwc_string)) ||
-@@ -1585,52 +1795,76 @@ int novfs_change_auth_key(struct novfs_x
- * Get the tree name
- */
- str += sizeof(*pNewKey);
-- cpylen = copy_from_user(&xferStr, xplatCall.pDomainName, sizeof(struct nwc_string));
-+ if(copy_from_user(&xferStr, xplatCall.pDomainName, sizeof(struct nwc_string))) {
-+ status = -EFAULT;
-+ goto out;
-+ }
- pNewKey->domainNameOffset = sizeof(*pNewKey);
- if (xferStr.DataLen > MAX_DOMAIN_LEN) {
- status = -EINVAL;
- goto out;
- }
-- cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
-+ if(copy_from_user(str, xferStr.pBuffer, xferStr.DataLen)) {
-+ status = -EFAULT;
-+ goto out;
-+ }
- pNewKey->domainNameLen = xferStr.DataLen;
-
- /*
- * Get the User Name
- */
- str += pNewKey->domainNameLen;
-- cpylen = copy_from_user(&xferStr, xplatCall.pObjectName, sizeof(struct nwc_string));
-+ if(copy_from_user(&xferStr, xplatCall.pObjectName, sizeof(struct nwc_string))) {
-+ status = -EFAULT;
-+ goto out;
-+ }
- pNewKey->objectNameOffset = pNewKey->domainNameOffset + pNewKey->domainNameLen;
- if (xferStr.DataLen > MAX_OBJECT_NAME_LENGTH) {
- status = -EINVAL;
- goto out;
- }
-- cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
-+ if(copy_from_user(str, xferStr.pBuffer, xferStr.DataLen)) {
-+ status = -EFAULT;
-+ goto out;
-+ }
- pNewKey->objectNameLen = xferStr.DataLen;
-
- /*
- * Get the New Password
- */
- str += pNewKey->objectNameLen;
-- cpylen = copy_from_user(&xferStr, xplatCall.pNewPassword, sizeof(struct nwc_string));
-+ if(copy_from_user(&xferStr, xplatCall.pNewPassword, sizeof(struct nwc_string))) {
-+ status = -EFAULT;
-+ goto out;
-+ }
- pNewKey->newPasswordOffset = pNewKey->objectNameOffset + pNewKey->objectNameLen;
- if (xferStr.DataLen > MAX_PASSWORD_LENGTH) {
- status = -EINVAL;
- goto out;
- }
-- cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
-+ if(copy_from_user(str, xferStr.pBuffer, xferStr.DataLen)) {
-+ status = -EFAULT;
-+ goto out;
-+ }
- pNewKey->newPasswordLen = xferStr.DataLen;
-
- /*
- * Get the Verify Password
- */
- str += pNewKey->newPasswordLen;
-- cpylen = copy_from_user(&xferStr, xplatCall.pVerifyPassword, sizeof(struct nwc_string));
-+ if(copy_from_user(&xferStr, xplatCall.pVerifyPassword, sizeof(struct nwc_string))) {
-+ status = -EFAULT;
-+ goto out;
-+ }
- pNewKey->verifyPasswordOffset = pNewKey->newPasswordOffset + pNewKey->newPasswordLen;
- if (xferStr.DataLen > MAX_PASSWORD_LENGTH) {
- status = -EINVAL;
- goto out;
- }
-- cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
-+ if(copy_from_user(str, xferStr.pBuffer, xferStr.DataLen)) {
-+ status = -EFAULT;
-+ goto out;
-+ }
- pNewKey->verifyPasswordLen = xferStr.DataLen;
-
- status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
-@@ -1651,9 +1885,10 @@ int novfs_set_pri_conn(struct novfs_xpla
- struct novfs_xplat_call_reply *reply = NULL;
- struct nwc_set_primary_conn xplatCall;
- struct nwd_set_primary_conn *pConn = NULL;
-- unsigned long status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
-+ unsigned long status = -ENOMEM, cmdlen, datalen, replylen;
-
-- cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(struct nwc_set_primary_conn));
-+ if(copy_from_user(&xplatCall, pdata->reqData, sizeof(struct nwc_set_primary_conn)))
-+ return -EFAULT;
-
- datalen = sizeof(struct nwd_set_primary_conn);
- cmdlen = sizeof(*cmd) + datalen;
-@@ -1682,7 +1917,7 @@ int novfs_get_pri_conn(struct novfs_xpla
- {
- struct novfs_xplat_call_request cmd;
- struct novfs_xplat_call_reply *reply = NULL;
-- unsigned long status = -ENOMEM, cmdlen, replylen, cpylen;
-+ unsigned long status = -ENOMEM, cmdlen, replylen;
-
- cmdlen = (unsigned long)(&((struct novfs_xplat_call_request *)0)->data);
-
-@@ -1697,7 +1932,8 @@ int novfs_get_pri_conn(struct novfs_xpla
- if (reply) {
- status = reply->Reply.ErrorCode;
- if (!status) {
-- cpylen = copy_to_user(pdata->repData, reply->data, sizeof(unsigned long));
-+ if(copy_to_user(pdata->repData, reply->data, sizeof(unsigned long)))
-+ status = -EFAULT;
- }
-
- kfree(reply);
-@@ -1761,12 +1997,13 @@ int novfs_unmap_drive(struct novfs_xplat
- {
- struct novfs_xplat_call_request *cmd = NULL;
- struct novfs_xplat_call_reply *reply = NULL;
-- unsigned long status = 0, datalen, cmdlen, replylen, cpylen;
-+ unsigned long status = 0, datalen, cmdlen, replylen;
- struct nwc_unmap_drive_ex symInfo;
-
- DbgPrint("");
-
-- cpylen = copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo));
-+ if(copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo)))
-+ return -EFAULT;
- if (symInfo.linkLen > MAX_NAME_LEN)
- return -EINVAL;
- cmdlen = sizeof(*cmd);
-@@ -1783,13 +2020,18 @@ int novfs_unmap_drive(struct novfs_xplat
- cmd->Command.SessionId = Session;
- cmd->NwcCommand = NWC_UNMAP_DRIVE;
-
-- cpylen = copy_from_user(cmd->data, pdata->reqData, datalen);
-+ if(copy_from_user(cmd->data, pdata->reqData, datalen)) {
-+ status = -EFAULT;
-+ goto out;
-+ }
- status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
-
- if (reply) {
- status = reply->Reply.ErrorCode;
- kfree(reply);
- }
-+
-+out:
- kfree(cmd);
- return (status);
- }
-@@ -1798,7 +2040,7 @@ int novfs_enum_drives(struct novfs_xplat
- {
- struct novfs_xplat_call_request *cmd = NULL;
- struct novfs_xplat_call_reply *reply = NULL;
-- unsigned long status = 0, cmdlen, replylen, cpylen;
-+ unsigned long status = 0, cmdlen, replylen;
- unsigned long offset;
- char *cp = NULL;
-
-@@ -1827,10 +2069,14 @@ int novfs_enum_drives(struct novfs_xplat
- status = -EINVAL;
- goto out;
- }
-- cpylen = copy_to_user(pdata->repData, cp, offset);
-+ if(copy_to_user(pdata->repData, cp, offset)) {
-+ status = -EFAULT;
-+ goto out;
-+ }
- cp += offset;
-- cpylen = copy_to_user(((struct nwc_get_mapped_drives *)pdata->repData)->MapBuffer, cp,
-- min(replylen - offset, reply->dataLen - offset));
-+ if(copy_to_user(((struct nwc_get_mapped_drives *)pdata->repData)->MapBuffer, cp,
-+ min(replylen - offset, reply->dataLen - offset)))
-+ status = -EFAULT;
- }
- }
- out:
-@@ -1853,7 +2099,10 @@ int novfs_get_bcast_msg(struct novfs_xpl
- if (!cmd)
- return -ENOMEM;
-
-- cpylen = copy_from_user(&msg, pdata->reqData, sizeof(msg));
-+ if(copy_from_user(&msg, pdata->reqData, sizeof(msg))) {
-+ status = -EFAULT;
-+ goto out;
-+ }
- cmd->dataLen = sizeof(*dmsg);
- cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL;
- cmd->Command.SequenceNumber = 0;
-@@ -1878,16 +2127,27 @@ int novfs_get_bcast_msg(struct novfs_xpl
- 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);
-+ if(copy_to_user(pdata->repData, &msg, cpylen)) {
-+ status = -EFAULT;
-+ kfree(reply);
-+ goto out;
-+ }
-+ if(copy_to_user(cp, dmsg->message, msg.messageLen)) {
-+ status = -EFAULT;
-+ kfree(reply);
-+ goto out;
-+ }
- } 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));
-+ if(copy_to_user(pdata->repData, &msg, sizeof(msg)))
-+ status = -EFAULT;
- }
- kfree(reply);
- }
-+
-+out:
- kfree(cmd);
- return (status);
- }
-@@ -1900,11 +2160,14 @@ int novfs_set_key_value(struct novfs_xpl
- struct nwd_set_key *pNewKey = NULL;
- struct nwc_string cstrObjectName, cstrPassword;
- char *str = NULL;
-- unsigned long status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
-+ unsigned long status = -ENOMEM, cmdlen, datalen, replylen;
-
-- 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));
-+ if(copy_from_user(&xplatCall, pdata->reqData, sizeof(struct nwc_set_key)))
-+ return -EFAULT;
-+ if(copy_from_user(&cstrObjectName, xplatCall.pObjectName, sizeof(struct nwc_string)))
-+ return -EFAULT;
-+ if(copy_from_user(&cstrPassword, xplatCall.pNewPassword, sizeof(struct nwc_string)))
-+ return -EFAULT;
-
- if (cstrObjectName.DataLen > MAX_OBJECT_NAME_LENGTH || cstrPassword.DataLen > MAX_PASSWORD_LENGTH)
- return -EINVAL;
-@@ -1932,7 +2195,10 @@ int novfs_set_key_value(struct novfs_xpl
- * Get the User Name
- */
- str += sizeof(struct nwd_set_key);
-- cpylen = copy_from_user(str, cstrObjectName.pBuffer, cstrObjectName.DataLen);
-+ if(copy_from_user(str, cstrObjectName.pBuffer, cstrObjectName.DataLen)) {
-+ status = -EFAULT;
-+ goto out;
-+ }
-
- str += pNewKey->objectNameLen = cstrObjectName.DataLen;
- pNewKey->objectNameOffset = sizeof(struct nwd_set_key);
-@@ -1940,7 +2206,10 @@ int novfs_set_key_value(struct novfs_xpl
- /*
- * Get the Verify Password
- */
-- cpylen = copy_from_user(str, cstrPassword.pBuffer, cstrPassword.DataLen);
-+ if(copy_from_user(str, cstrPassword.pBuffer, cstrPassword.DataLen)) {
-+ status = -EFAULT;
-+ goto out;
-+ }
-
- pNewKey->newPasswordLen = cstrPassword.DataLen;
- pNewKey->newPasswordOffset = pNewKey->objectNameOffset + pNewKey->objectNameLen;
-@@ -1950,6 +2219,8 @@ int novfs_set_key_value(struct novfs_xpl
- status = reply->Reply.ErrorCode;
- kfree(reply);
- }
-+
-+out:
- kfree(cmd);
- return (status);
- }
-@@ -1962,9 +2233,12 @@ int novfs_verify_key_value(struct novfs_
- struct nwd_verify_key *pNewKey = NULL;
- struct nwc_string xferStr;
- char *str = NULL;
-- unsigned long status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
-+ unsigned long status = -ENOMEM, cmdlen, datalen, replylen;
-
-- cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(struct nwc_verify_key));
-+ if(copy_from_user(&xplatCall, pdata->reqData, sizeof(struct nwc_verify_key))) {
-+ status = -EFAULT;
-+ goto out;
-+ }
-
- if (!access_ok(VERIFY_READ, xplatCall.pDomainName, sizeof(struct nwc_string)) ||
- !access_ok(VERIFY_READ, xplatCall.pVerifyPassword, sizeof(struct nwc_string)))
-@@ -1999,27 +2273,45 @@ int novfs_verify_key_value(struct novfs_
- * Get the tree name
- */
- str += sizeof(*pNewKey);
-- cpylen = copy_from_user(&xferStr, xplatCall.pDomainName, sizeof(struct nwc_string));
-+ if(copy_from_user(&xferStr, xplatCall.pDomainName, sizeof(struct nwc_string))) {
-+ status = -EFAULT;
-+ goto out;
-+ }
- pNewKey->domainNameOffset = sizeof(*pNewKey);
-- cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
-+ if(copy_from_user(str, xferStr.pBuffer, xferStr.DataLen)) {
-+ status = -EFAULT;
-+ goto out;
-+ }
- pNewKey->domainNameLen = xferStr.DataLen;
-
- /*
- * Get the User Name
- */
- str += pNewKey->domainNameLen;
-- cpylen = copy_from_user(&xferStr, xplatCall.pObjectName, sizeof(struct nwc_string));
-+ if(copy_from_user(&xferStr, xplatCall.pObjectName, sizeof(struct nwc_string))) {
-+ status = -EFAULT;
-+ goto out;
-+ }
- pNewKey->objectNameOffset = pNewKey->domainNameOffset + pNewKey->domainNameLen;
-- cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
-+ if(copy_from_user(str, xferStr.pBuffer, xferStr.DataLen)) {
-+ status = -EFAULT;
-+ goto out;
-+ }
- pNewKey->objectNameLen = xferStr.DataLen;
-
- /*
- * Get the Verify Password
- */
- str += pNewKey->objectNameLen;
-- cpylen = copy_from_user(&xferStr, xplatCall.pVerifyPassword, sizeof(struct nwc_string));
-+ if(copy_from_user(&xferStr, xplatCall.pVerifyPassword, sizeof(struct nwc_string))) {
-+ status = -EFAULT;
-+ goto out;
-+ }
- pNewKey->verifyPasswordOffset = pNewKey->objectNameOffset + pNewKey->objectNameLen;
-- cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen);
-+ if(copy_from_user(str, xferStr.pBuffer, xferStr.DataLen)) {
-+ status = -EFAULT;
-+ goto out;
-+ }
- pNewKey->verifyPasswordLen = xferStr.DataLen;
-
- status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE);
-@@ -2027,6 +2319,8 @@ int novfs_verify_key_value(struct novfs_
- status = reply->Reply.ErrorCode;
- kfree(reply);
- }
-+
-+out:
- kfree(cmd);
- return (status);
- }
diff --git a/patches.fixes/novfs-minsize-fixes b/patches.fixes/novfs-minsize-fixes
deleted file mode 100644
index 1d2d37f143..0000000000
--- a/patches.fixes/novfs-minsize-fixes
+++ /dev/null
@@ -1,92 +0,0 @@
-From: pankaj kumar biswas <bpankaj@novell.com>
-Subject: "Unable to save Login Script" appears when trying to save a user login script
-References: bnc#638985
-Patch-mainline: No
-
-Certain calls like SetFileSize do not have any payload associated with the
-request. All the needed information are passed along just as headers. So the
-minimum fragment size can be zero. Make code handle that.
-
-Signed-off-by: Sankar P <psankar@novell.com>
-Signed-off-by: Pankaj Biswas <bpankaj@novell.com>
-Reported-by: Jeremy Meldrum <jmeldrum@novell.com>
-
-Index: linux-3.0-rc3-master/fs/novfs/nwcapi.h
-===================================================================
---- linux-3.0-rc3-master.orig/fs/novfs/nwcapi.h
-+++ linux-3.0-rc3-master/fs/novfs/nwcapi.h
-@@ -298,11 +298,19 @@ N_EXTERN_LIBRARY(NWRCODE)
-
- #define MAX_NAME_LEN 1024
- #define MAX_NUM_REPLIES 4096
--#define MIN_NUM_REPLIES 1
-+/*
-+ * MIN_NUM_REPLIES should be zero,as some calls like ScanSalvagableFiles are asynchronous.
-+ * The server will not be sending responses to these requests.
-+ */
-+#define MIN_NUM_REPLIES 0
- #define MAX_NUM_REQUESTS 4096
- #define MIN_NUM_REQUESTS 1
- #define MAX_FRAG_SIZE 65536
--#define MIN_FRAG_SIZE 1
-+/*
-+ * Certain calls like SetFileSize do not have any payload associated with the request.
-+ * All the needed information are passed along just as headers.So the minimum fragment size can be zero.
-+ */
-+#define MIN_FRAG_SIZE 0
- #define MAX_INFO_LEN 4096
- #define MAX_DOMAIN_LEN MAX_NETWORK_NAME_LENGTH
- #define MAX_OFFSET_LEN 4096
-Index: linux-3.0-rc3-master/fs/novfs/nwcapi.c
-===================================================================
---- linux-3.0-rc3-master.orig/fs/novfs/nwcapi.c
-+++ linux-3.0-rc3-master/fs/novfs/nwcapi.c
-@@ -274,28 +274,30 @@ int novfs_raw_send(struct novfs_xplat *p
- /*
- * Figure out the length of the request
- */
-- frag = kmalloc(xRequest.uNumReplyFrags * sizeof(struct nwc_frag), GFP_KERNEL);
-+ totalLen = 0;
-+ if(xRequest.uNumReplyFrags) {
-+ frag = kmalloc(xRequest.uNumReplyFrags * sizeof(struct nwc_frag), GFP_KERNEL);
-
-- DbgPrint("[XPLAT RawNCP] - Reply Frag Count 0x%X", xRequest.uNumReplyFrags);
-+ DbgPrint("[XPLAT RawNCP] - Reply Frag Count 0x%X", xRequest.uNumReplyFrags);
-
-- if (!frag)
-- return -ENOMEM;
-+ if (!frag)
-+ return -ENOMEM;
-
-- if(copy_from_user(frag, xRequest.pReplyFrags, xRequest.uNumReplyFrags * sizeof(struct nwc_frag))) {
-- retCode = -EFAULT;
-- goto out_frag;
-- }
-- totalLen = 0;
--
-- cFrag = frag;
-- for (x = 0; x < xRequest.uNumReplyFrags; x++) {
-- DbgPrint("[XPLAT - RawNCP] - Frag Len = %d", cFrag->uLength);
-- if (cFrag->uLength > MAX_FRAG_SIZE || cFrag->uLength < MIN_FRAG_SIZE) {
-- retCode = -EINVAL;
-- goto out;
-+ if(copy_from_user(frag, xRequest.pReplyFrags, xRequest.uNumReplyFrags * sizeof(struct nwc_frag))) {
-+ retCode = -EFAULT;
-+ goto out_frag;
- }
-- totalLen += cFrag->uLength;
-- cFrag++;
-+
-+ cFrag = frag;
-+ for (x = 0; x < xRequest.uNumReplyFrags; x++) {
-+ DbgPrint("[XPLAT - RawNCP] - Frag Len = %d", cFrag->uLength);
-+ if (cFrag->uLength > MAX_FRAG_SIZE || cFrag->uLength < MIN_FRAG_SIZE) {
-+ retCode = -EINVAL;
-+ goto out;
-+ }
-+ totalLen += cFrag->uLength;
-+ cFrag++;
-+ }
- }
-
- DbgPrint("[XPLAT - RawNCP] - totalLen = %d", totalLen);
diff --git a/patches.fixes/novfs-nwcapi.patch b/patches.fixes/novfs-nwcapi.patch
deleted file mode 100644
index 55fa8a281c..0000000000
--- a/patches.fixes/novfs-nwcapi.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From: Pankaj Biswas <bpankaj@novell.com>
-Subject: Fix checking of login id
-References: bnc#626119
-Patch-mainline: No
-
-Signed-off-by: Pankaj Biswas <bpankaj@novell.com>
-Acked-by: Jan Kara <jack@suse.cz>
-
---- a/fs/novfs/vfs.h 2011-02-23 17:15:27.000000000 +0530
-+++ b/fs/novfs/vfs.h 2011-03-04 11:57:46.000000000 +0530
-@@ -54,6 +54,8 @@ struct novfs_schandle {
-
- #define PATH_LENGTH_BUFFER PATH_MAX
- #define NW_MAX_PATH_LENGTH 255
-+#define NW_MAX_DN_CHARS 256
-+#define NW_MAX_DN_BYTES (2*(NW_MAX_DN_CHARS+1))
-
- #define XA_BUFFER (8 * 1024)
-
---- a/fs/novfs/nwcapi.c 2011-03-02 12:00:46.000000000 +0530
-+++ b/fs/novfs/nwcapi.c 2011-03-04 11:57:42.000000000 +0530
-@@ -480,7 +480,7 @@ int novfs_login_id(struct novfs_xplat *p
- DbgPrint("DomainName\n");
- novfs_dump(sizeof(nwcStr), &nwcStr);
-
-- if (nwcStr.DataLen > MAX_NAME_LEN)
-+ if (nwcStr.DataLen > MAX_DOMAIN_LEN)
- return -EINVAL;
-
- if ((server.buffer = kmalloc(nwcStr.DataLen, GFP_KERNEL))) {
-@@ -492,7 +492,7 @@ int novfs_login_id(struct novfs_xplat *p
-
- cpylen = copy_from_user(&nwcStr, lgn.pObjectName, sizeof(nwcStr));
- DbgPrint("ObjectName");
-- if (nwcStr.DataLen > MAX_OBJECT_NAME_LENGTH) {
-+ if (nwcStr.DataLen > NW_MAX_DN_BYTES) {
- retCode = -EINVAL;
- goto out;
- }
diff --git a/patches.suse/novfs-client-module b/patches.suse/novfs-client-module
deleted file mode 100644
index 78b7b08762..0000000000
--- a/patches.suse/novfs-client-module
+++ /dev/null
@@ -1,14736 +0,0 @@
-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 | 952 ++++++++++++
- fs/novfs/daemon.c | 1900 ++++++++++++++++++++++++
- fs/novfs/file.c | 1760 ++++++++++++++++++++++
- fs/novfs/inode.c | 4104 ++++++++++++++++++++++++++++++++++++++++++++++++++++
- fs/novfs/nwcapi.c | 2032 +++++++++++++++++++++++++
- fs/novfs/nwcapi.h | 1418 +++++++++++++++++
- fs/novfs/nwerror.h | 657 ++++++++
- fs/novfs/proc.c | 140 +
- fs/novfs/profile.c | 640 ++++++++
- fs/novfs/scope.c | 624 +++++++
- fs/novfs/vfs.h | 372 ++++
- 15 files changed, 14628 insertions(+)
-
---- a/fs/Kconfig
-+++ b/fs/Kconfig
-@@ -239,6 +239,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
-@@ -122,5 +122,6 @@ 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/
- obj-$(CONFIG_PSTORE) += pstore/
---- /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,952 @@
-+/*
-+ * 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,1900 @@
-+/*
-+ * 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/semaphore.h>
-+#include <linux/sched.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 DEFINE_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);
-+ sema_init(&Daemon_Queue.semaphore, 0);
-+}
-+
-+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;
-+
-+ sema_init(&que->semaphore, 0);
-+
-+ 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))) {
-+ if (lLogin.Server.length > MAX_SERVER_NAME_LENGTH || lLogin.UserName.length > MAX_NAME_LEN ||
-+ lLogin.Password.length > MAX_PASSWORD_LENGTH)
-+ return -EINVAL;
-+ 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;
-+ if (lLogout.Server.length > MAX_SERVER_NAME_LENGTH)
-+ return -EINVAL;
-+ 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.
-+ */
-+ mutex_lock(&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);
-+ }
-+
-+ }
-+ mutex_unlock(&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);
-+}
-+
-+long novfs_daemon_ioctl(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 <= 0 || io.length > 1024)
-+ return -EINVAL;
-+ 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")
-+
-+long novfs_daemon_lib_ioctl(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 <= 0 || io.length > 1024)
-+ return -EINVAL;
-+ 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("NwSetConnInfo");
-+ 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;
-+
-+ if (pdata->reqLen != sizeof(mp))
-+ return -EINVAL;
-+ 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;
-+ if (symInfo.linkOffsetLength > MAX_NAME_LEN)
-+ return -EINVAL;
-+ 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;
-+
-+ mutex_lock(&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);
-+ mutex_unlock(&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;
-+ if (symInfo.linkLen > MAX_NAME_LEN || symInfo.linkLen == 0)
-+ return -EINVAL;
-+ 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;
-+
-+ mutex_lock(&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);
-+ }
-+
-+ mutex_unlock(&DriveMapLock);
-+ return (retVal);
-+}
-+
-+static void RemoveDriveMaps(void)
-+{
-+ struct drive_map *dm;
-+ struct list_head *list;
-+
-+ mutex_lock(&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);
-+ }
-+ mutex_unlock(&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 = kern_path_parent(pathname, &nd);
-+ DbgPrint("kern_path_parent %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;
-+ else
-+ c++;
-+ }
-+ dentry = lookup_one_len(name, nd.path.dentry, strlen(name));
-+ error = PTR_ERR(dentry);
-+
-+ if (!IS_ERR(dentry)) {
-+ DbgPrint("dentry %p", dentry);
-+ if (!(dentry->d_inode) || !(dentry->d_inode->i_mode & S_IFLNK)) {
-+ DbgPrint("%s not a link", name);
-+ error = -ENOENT;
-+ goto exit1;
-+ }
-+ /* 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,1760 @@
-+/*
-+ * 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);
-+
-+ retCode = -ENOATTR;
-+ } 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 (len > novfs_max_iosize - cmdlen) {
-+ 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;
-+ if (len > novfs_max_iosize)
-+ len = novfs_max_iosize;
-+ 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) {
-+
-+ /* Refer to the file ncp.c, in xtier's
-+ * NCP89_08 Function for various error codes */
-+
-+ if ((reply->Reply.ErrorCode & 0xFFFF) == 0x0006)
-+ retCode = -EACCES;
-+ else if ((reply->Reply.ErrorCode & 0xFFFF) == 0x0513)
-+ retCode = -ENOTEMPTY;
-+ 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,4104 @@
-+/*
-+ * 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/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 mutex 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 void novfs_kill_sb(struct super_block *SB);
-+
-+/*
-+ * Declared dentry_operations
-+ */
-+int novfs_d_revalidate(struct dentry *, struct nameidata *);
-+int novfs_d_hash(const struct dentry *, const struct inode *, struct qstr *);
-+int novfs_d_compare(const struct dentry *, const struct inode *,
-+ const struct dentry *, const struct inode *,
-+ unsigned int, const char *, const 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, 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_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 *, 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_evict_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 __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,
-+ .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,
-+};
-+
-+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,
-+ .evict_inode = novfs_evict_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,
-+};
-+*/
-+
-+static atomic_t novfs_Inode_Number = ATOMIC_INIT(0);
-+
-+struct dentry *novfs_root = NULL;
-+char *novfs_current_mnt = NULL;
-+
-+DEFINE_MUTEX(InodeList_lock);
-+
-+LIST_HEAD(InodeList);
-+
-+DEFINE_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_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, novfs_root->d_inode, &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, novfs_root->d_inode, &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, novfs_root->d_inode, &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(const struct dentry *dentry, const struct inode *inode,
-+ struct qstr *name)
-+{
-+ DbgPrint("%.*s", name->len, name->name);
-+
-+ name->hash = novfs_internal_hash(name);
-+
-+ return (0);
-+}
-+
-+static int novfs_d_strcmp(const char *str1, unsigned int len,
-+ const struct qstr *s2)
-+{
-+ int retCode = 1;
-+ const unsigned char *str2 = s2->name;
-+
-+ DbgPrint("s1=%.*s s2=%.*s", len, str1, s2->len, s2->name);
-+
-+ if (len && (len == s2->len)) {
-+ 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(const struct dentry *parent,
-+ const struct inode *parent_inode,
-+ const struct dentry *dentry, const struct inode *inode,
-+ unsigned int len, const char *s1, const struct qstr *s2)
-+{
-+ int retCode;
-+
-+ retCode = novfs_d_strcmp(s1, len, 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
-+ mutex_lock(&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;
-+ }
-+ }
-+ }
-+
-+ mutex_unlock(&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, int datasync)
-+{
-+ DbgPrint("Name %.*s", file->f_dentry->d_name.len,
-+ file->f_dentry->d_name.name);
-+ return generic_file_fsync(file, 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_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, 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) {
-+
-+ /*
-+ * Filling number of blocks as in NSS filesystem.
-+ * The s_blocksize is initialized to PAGE_CACHE_SIZE in
-+ * the super block initialization.
-+ *
-+ * Update i_blocks to have the number of 512 blocks
-+ */
-+ Inode->i_blocks = (((loff_t) Info->size) + Inode->i_sb->s_blocksize - 1)
-+ >> (loff_t) Inode->i_blkbits;
-+ Inode->i_blocks = Inode->i_blocks << (PAGE_CACHE_SHIFT - 9);
-+ 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) {
-+ if (id && id->Scope) {
-+ uid = novfs_scope_get_uid(id->Scope);
-+ } else {
-+ uid = novfs_scope_get_uid(novfs_get_scope(dentry));
-+ }
-+ 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 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))) {
-+ oldname.name = oldpath;
-+ oldname.len = (int)(oldcon - oldpath);
-+ oldname.hash = 0;
-+ if (!novfs_d_strcmp(newpath,
-+ newcon - newpath,
-+ &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;
-+
-+ 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 (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;
-+ }
-+ }
-+ }
-+ 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_evict_inode(struct inode *inode)
-+{
-+ truncate_inode_pages(&inode->i_data, 0);
-+ end_writeback(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);
-+
-+ mutex_lock(&InodeList_lock);
-+ list_del(&id->IList);
-+ mutex_unlock(&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);
-+ mutex_init(&id->DirCacheLock);
-+
-+ id->FileHandle = 0;
-+ id->CacheFlag = 0;
-+
-+ mutex_lock(&InodeList_lock);
-+
-+ list_add_tail(&id->IList, &InodeList);
-+ mutex_unlock(&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 = MAX_LFS_FILESIZE; /* 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 | 01777, 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 | 01777, 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 | 01777, 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 struct dentry *novfs_mount(struct file_system_type *fs_type, int flags,
-+ const char *dev_name, void *data)
-+{
-+ DbgPrint("Fstype=0x%x Dev_name=%s", fs_type, dev_name);
-+ return mount_nodev(fs_type, flags, data, novfs_fill_super);
-+}
-+
-+static void novfs_kill_sb(struct super_block *super)
-+{
-+ shrink_dcache_sb(super);
-+ kill_litter_super(super);
-+}
-+
-+/* This should be removed */
-+#ifndef kernel_locked
-+#define kernel_locked() (current->lock_depth >= 0)
-+#endif
-+
-+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);
-+}
-+
-+static struct file_system_type novfs_fs_type = {
-+ .name = "novfs",
-+ .mount = novfs_mount,
-+ .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 = bdi_init(&novfs_backing_dev_info);
-+
-+ if (!retCode)
-+ retCode = bdi_register(&novfs_backing_dev_info, NULL, "novfs-map");
-+ if (retCode) {
-+ bdi_destroy(&novfs_backing_dev_info);
-+ goto bdi_fail;
-+ }
-+
-+ 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();
-+ }
-+ }
-+
-+bdi_fail:
-+ 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;
-+ }
-+
-+ bdi_destroy(&novfs_backing_dev_info);
-+}
-+
-+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) {
-+ mutex_lock(&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) {
-+ mutex_unlock(&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;
-+
-+ //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);
-+ }
-+ }
-+ 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;
-+
-+ mutex_lock(&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);
-+ }
-+ }
-+ }
-+ mutex_unlock(&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,2032 @@
-+/*
-+ * 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 = NULL;
-+ struct novfs_xplat_call_reply *reply = NULL;
-+ struct nwd_open_conn_by_name *openConn = NULL, *connReply = NULL;
-+ struct nwc_open_conn_by_name ocbn;
-+ int retCode = 0;
-+ unsigned long cmdlen, datalen, replylen, cpylen, pnamelen, stypelen;
-+ char *data = NULL;
-+
-+ cpylen = copy_from_user(&ocbn, pdata->reqData, sizeof(ocbn));
-+ pnamelen = strlen_user(ocbn.pName->pString);
-+ stypelen = strlen_user(ocbn.pServiceType);
-+ if (pnamelen > MAX_NAME_LEN || stypelen > NW_MAX_SERVICE_TYPE_LEN)
-+ return -EINVAL;
-+ datalen = sizeof(*openConn) + pnamelen + stypelen;
-+ 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 = pnamelen;
-+ openConn->serviceLen = stypelen;
-+ 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 = NULL;
-+ struct novfs_xplat_call_reply *reply = NULL;
-+ struct nwd_open_conn_by_addr *openConn = NULL, *connReply = NULL;
-+ 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));
-+ if (tranAddr.uAddressLength > sizeof(addr)) {
-+ retCode = -EINVAL;
-+ goto out;
-+ }
-+
-+ 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);
-+ }
-+
-+out:
-+ 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 = NULL;
-+ struct novfs_xplat_call_reply *reply = NULL;
-+ struct nwd_open_conn_by_ref *openConn = NULL;
-+ 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 = NULL, *cFrag = NULL, *reqFrag = NULL;
-+ struct novfs_xplat_call_request *cmd = NULL;
-+ struct novfs_xplat_call_reply *reply = NULL;
-+ int retCode = 0;
-+ unsigned long cmdlen, datalen, replylen, cpylen, totalLen;
-+ unsigned int x;
-+ struct nwd_ncp_req *ncpData = NULL;
-+ struct nwd_ncp_rep *ncpReply = NULL;
-+ unsigned char *reqData = NULL;
-+ unsigned long actualReplyLength = 0;
-+
-+ DbgPrint("[XPLAT] Process Raw NCP Send");
-+ cpylen = copy_from_user(&xRequest, pdata->reqData, sizeof(xRequest));
-+
-+ if (xRequest.uNumReplyFrags > MAX_NUM_REPLIES || xRequest.uNumReplyFrags < MIN_NUM_REPLIES ||
-+ xRequest.uNumRequestFrags > MAX_NUM_REQUESTS || xRequest.uNumRequestFrags < MIN_NUM_REQUESTS)
-+ return -EINVAL;
-+
-+ /*
-+ * 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 -ENOMEM;
-+
-+ 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);
-+ if (cFrag->uLength > MAX_FRAG_SIZE || cFrag->uLength < MIN_FRAG_SIZE) {
-+ retCode = -EINVAL;
-+ goto out;
-+ }
-+ totalLen += cFrag->uLength;
-+ cFrag++;
-+ }
-+
-+ DbgPrint("[XPLAT - RawNCP] - totalLen = %d", totalLen);
-+ datalen = 0;
-+ reqFrag = kmalloc(xRequest.uNumRequestFrags * sizeof(struct nwc_frag), GFP_KERNEL);
-+ if (!reqFrag) {
-+ retCode = -ENOMEM;
-+ goto out;
-+ }
-+
-+ cpylen = copy_from_user(reqFrag, xRequest.pRequestFrags, xRequest.uNumRequestFrags * sizeof(struct nwc_frag));
-+ cFrag = reqFrag;
-+ for (x = 0; x < xRequest.uNumRequestFrags; x++) {
-+ if (cFrag->uLength > MAX_FRAG_SIZE || cFrag->uLength < MIN_FRAG_SIZE) {
-+ retCode = -EINVAL;
-+ goto out;
-+ }
-+ 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) {
-+ retCode = -ENOMEM;
-+ goto out;
-+ }
-+
-+ 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;
-+ }
-+
-+ xRequest.uActualReplyLength = actualReplyLength;
-+ cpylen = copy_to_user(pdata->reqData, &xRequest, sizeof(xRequest));
-+
-+out:
-+ kfree(cmd);
-+ 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 = NULL;
-+ struct novfs_xplat_call_reply *reply = NULL;
-+ struct nwc_close_conn cc;
-+ struct nwd_close_conn *nwdClose = NULL;
-+ 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 = NULL;
-+ struct novfs_xplat_call_reply *reply = NULL;
-+ struct nwc_close_conn cc;
-+ struct nwd_close_conn *nwdClose = NULL;
-+ 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 = NULL;
-+ int retCode = -ENOMEM;
-+ struct ncl_string server;
-+ struct ncl_string username;
-+ struct ncl_string password;
-+ unsigned long cpylen;
-+ struct nwc_string nwcStr;
-+
-+ memset(&server, 0, sizeof(server));
-+ memset(&username, 0, sizeof(username));
-+ memset(&password, 0, sizeof(password));
-+
-+ 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 (nwcStr.DataLen > MAX_NAME_LEN)
-+ return -EINVAL;
-+
-+ 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");
-+ if (nwcStr.DataLen > MAX_OBJECT_NAME_LENGTH) {
-+ retCode = -EINVAL;
-+ goto out;
-+ }
-+ 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");
-+ if (nwcStr.DataLen > MAX_PASSWORD_LENGTH) {
-+ retCode = -EINVAL;
-+ goto out;
-+ }
-+ 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);
-+
-+ }
-+ }
-+ memset(username.buffer, 0, username.len);
-+ }
-+ }
-+ }
-+out:
-+ kfree(password.buffer);
-+ 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 = NULL;
-+ struct novfs_xplat_call_request *cmd = NULL;
-+ struct novfs_xplat_call_reply *reply = NULL;
-+ 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 = NULL;
-+ struct novfs_xplat_call_reply *reply = NULL;
-+ struct nwc_license_conn lisc;
-+ struct nwc_lisc_id *pDLisc = NULL;
-+ 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 = NULL;
-+ struct novfs_xplat_call_reply *reply = NULL;
-+ struct nwc_lo_id logout, *pDLogout = NULL;
-+ 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 = NULL;
-+ struct novfs_xplat_call_reply *reply = NULL;
-+ struct nwc_unlic_conn *pUconn = NULL, 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 = NULL;
-+ struct novfs_xplat_call_reply *reply = NULL;
-+ struct nwc_unauthenticate auth, *pDAuth = NULL;
-+ 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 = NULL;
-+ struct novfs_xplat_call_reply *reply = NULL;
-+ struct nwc_get_conn_info connInfo;
-+ struct nwd_conn_info *pDConnInfo = NULL;
-+ 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;
-+
-+ if (connInfo.uInfoLength > MAX_INFO_LEN) {
-+ retCode = -EINVAL;
-+ goto out;
-+ }
-+
-+ 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);
-+ }
-+out:
-+ kfree(cmd);
-+ return (retCode);
-+
-+}
-+
-+int novfs_set_conn_info(struct novfs_xplat *pdata, struct novfs_schandle Session)
-+{
-+ struct novfs_xplat_call_request *cmd = NULL;
-+ struct novfs_xplat_call_reply *reply = NULL;
-+ struct nwc_set_conn_info connInfo;
-+ struct nwd_set_conn_info *pDConnInfo = NULL;
-+ 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;
-+ if (connInfo.uInfoLength > MAX_INFO_LEN) {
-+ retCode = -EINVAL;
-+ goto out;
-+ }
-+
-+ 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);
-+ }
-+
-+out:
-+ kfree(cmd);
-+ return (retCode);
-+
-+}
-+
-+int novfs_get_id_info(struct novfs_xplat *pdata, struct novfs_schandle Session)
-+{
-+ struct novfs_xplat_call_request *cmd = NULL;
-+ struct novfs_xplat_call_reply *reply = NULL;
-+ struct nwc_get_id_info qidInfo, *gId = NULL;
-+ struct nwd_get_id_info *idInfo = NULL;
-+ struct nwc_string xferStr;
-+ char *str = NULL;
-+ 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));
-+ if (idInfo->pDomainNameOffset >= reply->dataLen) {
-+ retCode = -EINVAL;
-+ goto out;
-+ }
-+ str = (char *)((char *)reply->data + idInfo->pDomainNameOffset);
-+ if (idInfo->domainLen > reply->dataLen - idInfo->pDomainNameOffset) {
-+ retCode = -EINVAL;
-+ goto out;
-+ }
-+
-+ 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));
-+
-+ if (idInfo->pObjectNameOffset >= reply->dataLen) {
-+ retCode = -EINVAL;
-+ goto out;
-+ }
-+ str = (char *)((char *)reply->data + idInfo->pObjectNameOffset);
-+ if (idInfo->objectLen > reply->dataLen - idInfo->pObjectNameOffset) {
-+ retCode = -EINVAL;
-+ goto out;
-+ }
-+ 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));
-+ }
-+ }
-+
-+out:
-+ 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 = NULL;
-+ struct novfs_xplat_call_reply *reply = NULL;
-+ struct nwc_scan_conn_info connInfo, *rInfo = NULL;
-+ struct nwd_scan_conn_info *pDConnInfo = NULL;
-+ int retCode = -ENOMEM;
-+ unsigned long cmdlen, replylen, cpylen;
-+ unsigned char *localData = NULL;
-+
-+ cpylen = copy_from_user(&connInfo, pdata->reqData, sizeof(struct nwc_scan_conn_info));
-+
-+ if (connInfo.uReturnInfoLength > MAX_INFO_LEN || connInfo.uScanInfoLen > MAX_INFO_LEN)
-+ return -EINVAL;
-+
-+ 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 = NULL;
-+ 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));
-+ if (((struct nwd_scan_conn_info *)srcData)->uReturnConnInfoOffset >= reply->dataLen)
-+ goto out;
-+ srcData += ((struct nwd_scan_conn_info *)srcData)->uReturnConnInfoOffset;
-+ tranAddr.uTransportType = ((struct nwd_tran_addr *)srcData)->uTransportType;
-+ tranAddr.uAddressLength = ((struct tagNwdTranAddrEx *)srcData)->uAddressLength;
-+ if (tranAddr.uAddressLength > MAX_ADDRESS_LENGTH)
-+ goto out;
-+ cpylen = copy_to_user(dstData, &tranAddr, sizeof(tranAddr));
-+ cpylen = copy_to_user(tranAddr.puAddress,
-+ ((struct tagNwdTranAddrEx *)srcData)->Buffer, tranAddr.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 && dataLen <= reply->dataLen) {
-+ DbgPrint("Copy Data 0x%p -> 0x%p :: 0x%X", srcData, connInfo->pReturnConnInfo, dataLen);
-+ cpylen = copy_to_user(connInfo->pReturnConnInfo, srcData, dataLen);
-+ }
-+
-+out:
-+ 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 = NULL;
-+
-+ 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;
-+ if (tranAddr.uAddressLength > MAX_ADDRESS_LENGTH)
-+ goto out;
-+ cpylen = copy_to_user(dstData, &tranAddr, sizeof(tranAddr));
-+ cpylen = copy_to_user(tranAddr.puAddress,
-+ ((struct tagNwdTranAddrEx *)srcData)->Buffer, tranAddr.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 && dataLen <= reply->dataLen) {
-+ cpylen = copy_to_user(connInfo->pConnInfo, srcData, connInfo->uInfoLength);
-+ }
-+
-+out:
-+ return;
-+}
-+
-+int novfs_get_daemon_ver(struct novfs_xplat *pdata, struct novfs_schandle Session)
-+{
-+ struct novfs_xplat_call_request *cmd = NULL;
-+ struct novfs_xplat_call_reply *reply = NULL;
-+ struct nwd_get_reqversion *pDVersion = NULL;
-+ 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 = NULL;
-+ struct novfs_xplat_call_reply *reply = NULL;
-+ struct nwd_get_pref_ds_tree *pDGetTree = NULL;
-+ struct nwc_get_pref_ds_tree xplatCall, *p = NULL;
-+ int retCode = -ENOMEM;
-+ unsigned long cmdlen, datalen, replylen, cpylen;
-+ unsigned char *dPtr = NULL;
-+
-+ cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(struct nwc_get_pref_ds_tree));
-+ if (xplatCall.uTreeLength > NW_MAX_TREE_NAME_LEN)
-+ return -EINVAL;
-+ 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;
-+ if (pDGetTree->DsTreeNameOffset >= reply->dataLen) {
-+ retCode = -EINVAL;
-+ goto out;
-+ }
-+ 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);
-+
-+ if (pDGetTree->uTreeLength > reply->dataLen - pDGetTree->DsTreeNameOffset) {
-+ retCode = -EINVAL;
-+ goto out;
-+ }
-+ cpylen = copy_to_user(p, &pDGetTree->uTreeLength, 4);
-+ cpylen = copy_to_user(xplatCall.pDsTreeName, dPtr, pDGetTree->uTreeLength);
-+ }
-+ }
-+
-+out:
-+ 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 = NULL;
-+ struct novfs_xplat_call_reply *reply = NULL;
-+ struct nwd_set_pref_ds_tree *pDSetTree = NULL;
-+ struct nwc_set_pref_ds_tree xplatCall;
-+ int retCode = -ENOMEM;
-+ unsigned long cmdlen, datalen, replylen, cpylen;
-+ unsigned char *dPtr = NULL;
-+
-+ cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(struct nwc_set_pref_ds_tree));
-+ if (xplatCall.uTreeLength > NW_MAX_TREE_NAME_LEN)
-+ return -EINVAL;
-+ 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 = NULL;
-+ struct novfs_xplat_call_reply *reply = NULL;
-+ struct nwc_set_def_name_ctx xplatCall;
-+ struct nwd_set_def_name_ctx *pDSet = NULL;
-+ int retCode = -ENOMEM;
-+ unsigned long cmdlen, datalen, replylen, cpylen;
-+ unsigned char *dPtr = NULL;
-+
-+ cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(struct nwc_set_def_name_ctx));
-+ if (xplatCall.uNameLength > MAX_NAME_LEN || xplatCall.uTreeLength > NW_MAX_TREE_NAME_LEN)
-+ return -EINVAL;
-+ 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 = NULL;
-+ struct novfs_xplat_call_reply *reply = NULL;
-+ struct nwc_get_def_name_ctx xplatCall;
-+ struct nwd_get_def_name_ctx *pGet = NULL;
-+ char *dPtr = NULL;
-+ int retCode = -ENOMEM;
-+ unsigned long cmdlen, replylen, cpylen;
-+
-+ cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(struct nwc_get_def_name_ctx));
-+ if (xplatCall.uTreeLength > NW_MAX_TREE_NAME_LEN)
-+ return -EINVAL;
-+
-+ 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 = NULL;
-+ struct novfs_xplat_call_reply *reply = NULL;
-+ struct nwc_get_tree_monitored_conn_ref xplatCall, *p = NULL;
-+ struct nwd_get_tree_monitored_conn_ref *pDConnRef = NULL;
-+ char *dPtr = NULL;
-+ unsigned long status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
-+
-+ cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(struct nwc_get_tree_monitored_conn_ref));
-+ if (!access_ok(VERIFY_READ, xplatCall.pTreeName, sizeof(struct nwc_string)))
-+ return -EINVAL;
-+ if (xplatCall.pTreeName->DataLen > NW_MAX_TREE_NAME_LEN)
-+ return -EINVAL;
-+ 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 = NULL;
-+ struct novfs_xplat_call_reply *reply = NULL;
-+ struct nwc_enum_ids xplatCall, *eId = NULL;
-+ struct nwd_enum_ids *pEnum = NULL;
-+ struct nwc_string xferStr;
-+ char *str = NULL;
-+ 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));
-+ if (pEnum->domainNameOffset >= reply->dataLen) {
-+ status = -EINVAL;
-+ goto out;
-+ }
-+ str = (char *)((char *)reply->data + pEnum->domainNameOffset);
-+ DbgPrint("[XPLAT NWCAPI] Found Domain %s", str);
-+ if (pEnum->domainNameLen > reply->dataLen - pEnum->domainNameOffset) {
-+ status = -EINVAL;
-+ goto out;
-+ }
-+ 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));
-+ if (pEnum->objectNameOffset >= reply->dataLen) {
-+ status = -EINVAL;
-+ goto out;
-+ }
-+ str = (char *)((char *)reply->data + pEnum->objectNameOffset);
-+ DbgPrint("[XPLAT NWCAPI] Found User %s", str);
-+ if (pEnum->objectNameLen > reply->dataLen - pEnum->objectNameOffset) {
-+ status = -EINVAL;
-+ goto out;
-+ }
-+ 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));
-+ }
-+ }
-+out:
-+ 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 = NULL;
-+ struct novfs_xplat_call_reply *reply = NULL;
-+ struct nwc_change_key xplatCall;
-+ struct nwd_change_key *pNewKey = NULL;
-+ struct nwc_string xferStr;
-+ char *str = NULL;
-+ unsigned long status = -ENOMEM, cmdlen = 0, datalen, replylen, cpylen;
-+
-+ cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(struct nwc_change_key));
-+ if (!access_ok(VERIFY_READ, xplatCall.pDomainName, sizeof(struct nwc_string)) ||
-+ !access_ok(VERIFY_READ, xplatCall.pObjectName, sizeof(struct nwc_string)) ||
-+ !access_ok(VERIFY_READ, xplatCall.pNewPassword, sizeof(struct nwc_string)) ||
-+ !access_ok(VERIFY_READ, xplatCall.pVerifyPassword, sizeof(struct nwc_string)))
-+ return -EINVAL;
-+ if (xplatCall.pDomainName->DataLen > MAX_DOMAIN_LEN ||
-+ xplatCall.pObjectName->DataLen > MAX_OBJECT_NAME_LENGTH ||
-+ xplatCall.pNewPassword->DataLen > MAX_PASSWORD_LENGTH || xplatCall.pVerifyPassword->DataLen > MAX_PASSWORD_LENGTH)
-+ return -EINVAL;
-+
-+ 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);
-+ if (xferStr.DataLen > MAX_DOMAIN_LEN) {
-+ status = -EINVAL;
-+ goto out;
-+ }
-+ 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;
-+ if (xferStr.DataLen > MAX_OBJECT_NAME_LENGTH) {
-+ status = -EINVAL;
-+ goto out;
-+ }
-+ 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;
-+ if (xferStr.DataLen > MAX_PASSWORD_LENGTH) {
-+ status = -EINVAL;
-+ goto out;
-+ }
-+ 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;
-+ if (xferStr.DataLen > MAX_PASSWORD_LENGTH) {
-+ status = -EINVAL;
-+ goto out;
-+ }
-+ 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;
-+
-+ }
-+out:
-+ memset(cmd, 0, cmdlen);
-+ kfree(reply);
-+ kfree(cmd);
-+ return (status);
-+}
-+
-+int novfs_set_pri_conn(struct novfs_xplat *pdata, struct novfs_schandle Session)
-+{
-+ struct novfs_xplat_call_request *cmd = NULL;
-+ struct novfs_xplat_call_reply *reply = NULL;
-+ struct nwc_set_primary_conn xplatCall;
-+ struct nwd_set_primary_conn *pConn = NULL;
-+ 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 = NULL;
-+ 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 = NULL;
-+ struct novfs_xplat_call_reply *reply = NULL;
-+ 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;
-+ if (symInfo.dirPathOffsetLength > MAX_OFFSET_LEN || symInfo.linkOffsetLength > MAX_OFFSET_LEN)
-+ return -EINVAL;
-+ 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 = NULL;
-+ struct novfs_xplat_call_reply *reply = NULL;
-+ unsigned long status = 0, datalen, cmdlen, replylen, cpylen;
-+ struct nwc_unmap_drive_ex symInfo;
-+
-+ DbgPrint("");
-+
-+ cpylen = copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo));
-+ if (symInfo.linkLen > MAX_NAME_LEN)
-+ return -EINVAL;
-+ 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 = NULL;
-+ struct novfs_xplat_call_reply *reply = NULL;
-+ unsigned long status = 0, cmdlen, replylen, cpylen;
-+ unsigned long offset;
-+ char *cp = NULL;
-+
-+ 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;
-+ if (offset > reply->dataLen) {
-+ status = -EINVAL;
-+ goto out;
-+ }
-+ 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));
-+ }
-+ }
-+out:
-+ 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 = NULL;
-+ struct novfs_xplat_call_reply *reply = NULL;
-+ unsigned long cmdlen, replylen;
-+ int status = 0x8866, cpylen;
-+ struct nwc_get_bcast_notification msg;
-+ struct nwd_get_bcast_notification *dmsg = NULL;
-+
-+ 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 = NULL;
-+ struct novfs_xplat_call_reply *reply = NULL;
-+ struct nwc_set_key xplatCall;
-+ struct nwd_set_key *pNewKey = NULL;
-+ struct nwc_string cstrObjectName, cstrPassword;
-+ char *str = NULL;
-+ 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));
-+
-+ if (cstrObjectName.DataLen > MAX_OBJECT_NAME_LENGTH || cstrPassword.DataLen > MAX_PASSWORD_LENGTH)
-+ return -EINVAL;
-+ 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 = NULL;
-+ struct novfs_xplat_call_reply *reply = NULL;
-+ struct nwc_verify_key xplatCall;
-+ struct nwd_verify_key *pNewKey = NULL;
-+ struct nwc_string xferStr;
-+ char *str = NULL;
-+ unsigned long status = -ENOMEM, cmdlen, datalen, replylen, cpylen;
-+
-+ cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(struct nwc_verify_key));
-+
-+ if (!access_ok(VERIFY_READ, xplatCall.pDomainName, sizeof(struct nwc_string)) ||
-+ !access_ok(VERIFY_READ, xplatCall.pVerifyPassword, sizeof(struct nwc_string)))
-+ return -EINVAL;
-+ if (xplatCall.pDomainName->DataLen > MAX_NAME_LEN || xplatCall.pObjectName->DataLen > MAX_OBJECT_NAME_LENGTH ||
-+ xplatCall.pVerifyPassword->DataLen > MAX_PASSWORD_LENGTH)
-+ return -EINVAL;
-+
-+ 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,1418 @@
-+/*
-+ * 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
-+
-+#define MAX_NAME_LEN 1024
-+#define MAX_NUM_REPLIES 4096
-+#define MIN_NUM_REPLIES 1
-+#define MAX_NUM_REQUESTS 4096
-+#define MIN_NUM_REQUESTS 1
-+#define MAX_FRAG_SIZE 65536
-+#define MIN_FRAG_SIZE 1
-+#define MAX_INFO_LEN 4096
-+#define MAX_DOMAIN_LEN MAX_NETWORK_NAME_LENGTH
-+#define MAX_OFFSET_LEN 4096
-+
-+//
-+// 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,657 @@
-+/*
-+ * 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,140 @@
-+/*
-+ * 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 "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.unlocked_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.unlocked_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,640 @@
-+/*
-+ * 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 DEFINE_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,
-+ 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,
-+ 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) {
-+ mutex_lock(&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;
-+
-+ mutex_unlock(&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) {
-+ mutex_lock(&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;
-+
-+ mutex_unlock(&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,624 @@
-+/*
-+ * 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/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 (scope && 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);
-+ sema_init(&Scope_Lock, 1);
-+ sema_init(&Scope_Thread_Delay, 0);
-+ 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,372 @@
-+/*
-+ * 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 long novfs_daemon_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
-+extern int novfs_daemon_lib_close(struct inode *inode, struct file *file);
-+extern long novfs_daemon_lib_ioctl(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 */
diff --git a/patches.suse/novfs-remove-bkl b/patches.suse/novfs-remove-bkl
deleted file mode 100644
index 44466c6956..0000000000
--- a/patches.suse/novfs-remove-bkl
+++ /dev/null
@@ -1,59 +0,0 @@
-From: Jeff Mahoney <jeffm@suse.com>
-Subject: novfs: Remove BKL
-Patch-mainline: Whenever it's upstream
-
- The BKL has been removed. Reporting its status is obsolete.
-
-Signed-off-by: Jeff Mahoney <jeffm@suse.com>
----
- fs/novfs/inode.c | 32 --------------------------------
- 1 file changed, 32 deletions(-)
-
---- a/fs/novfs/inode.c
-+++ b/fs/novfs/inode.c
-@@ -254,13 +254,6 @@ static struct super_operations novfs_ops
-
- };
-
--/* Not currently used
--static struct file_operations novfs_Control_operations = {
-- .read = novfs_Control_read,
-- .write = novfs_Control_write,
--};
--*/
--
- static atomic_t novfs_Inode_Number = ATOMIC_INIT(0);
-
- struct dentry *novfs_root = NULL;
-@@ -3440,31 +3433,6 @@ static void novfs_kill_sb(struct super_b
- kill_litter_super(super);
- }
-
--/* This should be removed */
--#ifndef kernel_locked
--#define kernel_locked() (current->lock_depth >= 0)
--#endif
--
--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);
--}
--
- static struct file_system_type novfs_fs_type = {
- .name = "novfs",
- .mount = novfs_mount,
diff --git a/series.conf b/series.conf
index 9cd24775ac..23461e72d1 100644
--- a/series.conf
+++ b/series.conf
@@ -292,15 +292,6 @@
########################################################
########################################################
- # novfs
- ########################################################
- patches.suse/novfs-client-module
- patches.fixes/novfs-nwcapi.patch
- patches.suse/novfs-remove-bkl
- patches.fixes/novfs-copy_user-fixes.diff
- patches.fixes/novfs-minsize-fixes
-
- ########################################################
# other filesystem stuff: richacls
########################################################
patches.suse/0001-vfs-Hooks-for-more-fine-grained-directory-permission.patch