diff -uNr src.old/LICENSE src/LICENSE --- src.old/LICENSE 1970-01-01 01:00:00.000000000 +0100 +++ src/LICENSE 2006-10-16 15:08:22.000000000 +0200 @@ -0,0 +1,343 @@ +"Use of the novfs source code is governed by the terms of the GPL:" + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + diff -uNr src.old/include/commands.h src/include/commands.h --- src.old/include/commands.h 2006-07-11 21:24:18.000000000 +0200 +++ src/include/commands.h 2006-10-16 15:08:23.000000000 +0200 @@ -73,6 +73,7 @@ #define VFS_COMMAND_SET_MOUNT_PATH 31 #define VFS_COMMAND_GET_USER_SPACE 32 #define VFS_COMMAND_DBG 33 +#define VFS_COMMAND_GET_CACHE_FLAG 34 #define NWD_ACCESS_QUERY 0x00000001 @@ -1167,6 +1168,21 @@ } NwdCVerifyKey, *PNwdCVerifyKey; +typedef struct _GET_CACHE_FLAG +{ + COMMAND_REQUEST_HEADER Command; + int pathLen; + unsigned char path[0]; + +} GET_CACHE_FLAG_REQUEST, *PGET_CACHE_FLAG_REQUEST; + +typedef struct _GET_CACHE_FLAG_REPLY +{ + COMMAND_REPLY_HEADER Reply; + int CacheFlag; + +} GET_CACHE_FLAG_REPLY, *PGET_CACHE_FLAG_REPLY; + #pragma pack(pop) diff -uNr src.old/novfs/Makefile src/novfs/Makefile --- src.old/novfs/Makefile 2006-07-11 21:24:18.000000000 +0200 +++ src/novfs/Makefile 1970-01-01 01:00:00.000000000 +0100 @@ -1,52 +0,0 @@ -##*++====================================================================== -## Program Name: Novell NCP Redirector for Linux -## File Name: Makefile -## Version: v1.01 -## Author: James Turner -## -## Abstract: This is used to generate the novfs module -## Notes: -## Revision History: -## 6/10/2005 - Added lines for SuSE -## -## Copyright (C) 2005 Novell, Inc. -## -## This program is free software; you can redistribute it and/or -## modify it under the terms of the GNU General Public License -## as published by the Free Software Foundation; either version 2 -## of the License, or (at your option) any later version. -## -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -##=====================================================================--*/ - -# -# Makefile for the Novell NetWare Client for Linux filesystem. -# -NOVFS_VFS_MAJOR = 1 -NOVFS_VFS_MINOR = 2 -NOVFS_VFS_SUB = 0 -NOVFS_VFS_RELEASE = 17 - -# Remove # from the following line for debug version -EXTRA_CFLAGS += -finstrument-functions -EXTRA_CFLAGS += -g -EXTRA_CFLAGS += -I. -EXTRA_CFLAGS += -I$(obj)/../include -#EXTRA_CFLAGS += -I$(obj)/../../include -EXTRA_CFLAGS += -DNOVFS_VFS_MAJOR=$(NOVFS_VFS_MAJOR) -EXTRA_CFLAGS += -DNOVFS_VFS_MINOR=$(NOVFS_VFS_MINOR) -EXTRA_CFLAGS += -DNOVFS_VFS_SUB=$(NOVFS_VFS_SUB) -EXTRA_CFLAGS += -DNOVFS_VFS_PATCH=$(NOVFS_VFS_PATCH) -EXTRA_CFLAGS += -DNOVFS_VFS_RELEASE=$(NOVFS_VFS_RELEASE) - - -obj-m := novfs.o - -novfs-y := inode.o proc.o profile.o daemon.o file.o scope.o nwcapi.o diff -uNr src.old/novfs/blank.c src/novfs/blank.c --- src.old/novfs/blank.c 2006-07-11 21:24:18.000000000 +0200 +++ src/novfs/blank.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,61 +0,0 @@ -/*++======================================================================== - * Program Name: Novell NCP Redirector for Linux - * File Name: .c - * Version: v1.00 - * Author: James Turner - * - * Abstract: This module - * - * Notes: - * Revision History: - * - * - * Copyright (C) 2005 Novell, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - *======================================================================--*/ - -/*===[ Include files specific to Linux ]==================================*/ - -/*===[ Include files specific to this module ]============================*/ - -/*===[ External data ]====================================================*/ - -/*===[ External prototypes ]==============================================*/ - -/*===[ Manifest constants ]===============================================*/ - -/*===[ Type definitions ]=================================================*/ - -/*===[ Function prototypes ]==============================================*/ - -/*===[ Global variables ]=================================================*/ - -/*===[ Code ]=============================================================*/ - -/*++======================================================================*/ -Function -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ diff -uNr src.old/novfs/daemon.c src/novfs/daemon.c --- src.old/novfs/daemon.c 2006-07-11 21:24:18.000000000 +0200 +++ src/novfs/daemon.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,2877 +0,0 @@ -/*++======================================================================== - * Program Name: Novell NCP Redirector for Linux - * File Name: daemon.c - * Version: v1.00 - * Author: James Turner - * - * Abstract: This module contains all the functions necessary - * for sending commands to our daemon module. - * Notes: - * Revision History: - * - * - * Copyright (C) 2005 Novell, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - *======================================================================--*/ - -/*===[ Include files specific to Linux ]==================================*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/*===[ Include files specific to this module ]============================*/ -#include "vfs.h" -#include "nwcapi.h" -#include "commands.h" -#include "nwerror.h" - -/*===[ External data ]====================================================*/ -extern char *Novfs_CurrentMount; -extern char DbgDaemonLogOn; - - -/*===[ External prototypes ]==============================================*/ -extern int DbgPrint( char *Fmt, ... ); -extern void mydump(int size, void *dumpptr); - -extern char *Scope_Get_UserName( void *Scope ); -extern void *Scope_Lookup( void ); -extern session_t Scope_Get_SessionId( void *Scope ); -extern void Scope_Cleanup( void ); - -extern int Novfs_Read_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, int User, session_t SessionId); -extern int Novfs_Write_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId); -extern int Novfs_Close_Stream( u_long ConnHandle, u_char *Handle, session_t SessionId ); - -extern int Novfs_Add_to_Root(char *); - -/* - * nwcapi.c functions - */ -extern int NwAuthConnWithId(PXPLAT pdata, session_t Session); -extern int NwConnClose(PXPLAT pdata, u_long *Handle, session_t Session); -extern int NwGetConnInfo(PXPLAT pdata, session_t Session); -extern int NwSetConnInfo(PXPLAT pdata, session_t Session); -extern int NwGetDaemonVersion(PXPLAT pdata, session_t Session); -extern int NwGetIdentityInfo(PXPLAT pdata, session_t Session); -extern int NwLicenseConn(PXPLAT pdata, session_t Session); -extern int NwLoginIdentity(PXPLAT pdata, session_t Session); -extern int NwLogoutIdentity(PXPLAT pdata, session_t Session); -extern int NwOpenConnByAddr(PXPLAT pdata, u_long *Handle, session_t Session); -extern int NwOpenConnByName(PXPLAT pdata, u_long *Handle, session_t Session); -extern int NwOpenConnByRef(PXPLAT pdata, u_long *Handle, session_t Session); -extern int NwQueryFeature(PXPLAT pdata, session_t Session); -extern int NwRawSend(PXPLAT pdata, session_t Session); -extern int NwScanConnInfo(PXPLAT pdata, session_t Session); -extern int NwSysConnClose(PXPLAT pdata, u_long *Handle, session_t Session); -extern int NwUnAuthenticate(PXPLAT pdata, session_t Session); -extern int NwUnlicenseConn(PXPLAT pdata, session_t Session); -extern int NwcChangeAuthKey(PXPLAT pdata, session_t Session); -extern int NwcEnumIdentities(PXPLAT pdata, session_t Session); -extern int NwcGetDefaultNameCtx(PXPLAT pdata, session_t Session); -extern int NwcGetPreferredDSTree(PXPLAT pdata, session_t Session); -extern int NwcGetTreeMonitoredConn(PXPLAT pdata, session_t Session); -extern int NwcSetDefaultNameCtx(PXPLAT pdata, session_t Session); -extern int NwcSetPreferredDSTree(PXPLAT pdata, session_t Session); -extern int NwcSetPrimaryConn(PXPLAT pdata, session_t Session); -extern int NwcGetPrimaryConn(PXPLAT pdata, session_t Session); -extern int NwcSetMapDrive(PXPLAT pdata, session_t Session); -extern int NwcUnMapDrive(PXPLAT pdata, session_t Session); -extern int NwcEnumerateDrives(PXPLAT pdata, session_t Session); -extern int NwcGetBroadcastMessage(PXPLAT pdata, session_t Session); -extern int NwdSetKeyValue(PXPLAT pdata, session_t Session); -extern int NwdVerifyKeyValue(PXPLAT pdata, session_t Session); - -/*===[ Manifest constants ]===============================================*/ -#define QUEUE_SENDING 0 -#define QUEUE_WAITING 1 -#define QUEUE_TIMEOUT 2 -#define QUEUE_ACKED 3 -#define QUEUE_DONE 4 - -#define TIMEOUT_VALUE 10 - -#define DH_TYPE_UNDEFINED 0 -#define DH_TYPE_STREAM 1 -#define DH_TYPE_CONNECTION 2 - -/*===[ Type definitions ]=================================================*/ -typedef struct _DAEMON_QUEUE -{ - struct list_head list; /* Must be first entry */ - spinlock_t lock; /* Used to control access to list */ - struct semaphore semaphore; /* Used to signal when data is available */ -} daemon_queue_t; - -typedef struct _DAEMON_COMMAND -{ - struct list_head list; /* Must be first entry */ - atomic_t reference; - u_long status; - u_long flags; - struct semaphore semaphore; - u_long sequence; - struct timer_list timer; - void *request; - u_long reqlen; - void *data; - int datalen; - void *reply; - u_long replen; -} daemon_command_t; - - -typedef struct _DAEMON_HANDLE_ -{ - struct list_head list; - rwlock_t lock; - session_t session; -} daemon_handle_t; - -typedef struct _DAEMON_RESOURCE_ -{ - struct list_head list; - int type; - u_long connection; - u_char handle[6]; - mode_t mode; - loff_t size; -} daemon_resource_t; - -typedef struct _DRIVE_MAP_ -{ - struct list_head list; /* Must be first item */ - session_t session; - u_long hash; - int namelen; - char name[1]; -} drive_map_t; - -/*===[ Function prototypes ]==============================================*/ -int Daemon_Added_Resource(daemon_handle_t *DHandle, int Type, u_long CHandle, u_char *FHandle, u_long Mode, u_long Size); -int Daemon_Close_Control(struct inode *Inode, struct file *File); -int Daemon_CreateSessionId( uint64_t *SessionId ); -int Daemon_DestroySessionId( uint64_t SessionId ); -void Daemon_Dumpque( void ); -int Daemon_Get_UserSpace( uint64_t SessionId, uint64_t *TotalSize, uint64_t *TotalFree, uint64_t *TotalDirectoryEnties, uint64_t *FreeDirectoryEnties); -int Daemon_Library_close(struct inode *inode, struct file *file); -int Daemon_Library_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u_long arg); -int Daemon_Library_open(struct inode *inode, struct file *file); -ssize_t Daemon_Library_read(struct file *file, char *buf, size_t len, loff_t *off); -ssize_t Daemon_Library_write(struct file *file, const char *buf, size_t len, loff_t *off); -loff_t Daemon_Library_llseek(struct file *file, loff_t offset, int origin); -int Daemon_Login(PLOGIN Login, session_t Session); -int Daemon_Logout(PLOGOUT Logout, session_t Session); -int Daemon_Open_Control(struct inode *Inode, struct file *File); -uint Daemon_Poll(struct file *file, struct poll_table_struct *poll_table); -ssize_t Daemon_Receive_Reply(struct file * file, char * buf, size_t nbytes, loff_t *ppos); -int Daemon_Remove_Resource(daemon_handle_t *DHandle, int Type, u_long CHandle, u_long FHandle); - -ssize_t Daemon_Send_Command(struct file *file, char *buf, size_t len, loff_t *off); -int Daemon_SetMountPoint( char *Path ); -void Daemon_Timer(u_long data); -int Daemon_getpwuid( uid_t uid, int unamelen, char *uname ); -int Daemon_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u_long arg); -void Init_Daemon_Queue( void ); -int Queue_Daemon_Command(void *request, u_long reqlen, void *data, int dlen, void **reply, u_long *replen, int interruptible); -void Queue_get(daemon_command_t *que); -void Queue_put(daemon_command_t *que); -void Uninit_Daemon_Queue( void ); -int do_login(NclString *Server, NclString *Username, NclString *Password, u_long *lgnId, session_t Session); -int do_logout( struct qstr *Server, session_t Session ); -daemon_command_t *find_queue(u_long sequence); -daemon_command_t *get_next_queue(int Set_Queue_Waiting); -int NwdConvertNetwareHandle(PXPLAT pdata, daemon_handle_t *DHandle); -int NwdConvertLocalHandle(PXPLAT pdata, daemon_handle_t *DHandle); -int NwdGetMountPath(PXPLAT pdata); -int NwdSetMapDrive(PXPLAT pdata, session_t Session); -int NwdUnMapDrive(PXPLAT pdata, session_t Session); -void RemoveDriveMaps( void ); -int local_unlink(const char *pathname); - -/*===[ Global variables ]=================================================*/ -daemon_queue_t Daemon_Queue; - -static DECLARE_WAIT_QUEUE_HEAD(Read_waitqueue); - -u_long Sequence = 0; -atomic_t Daemon_Open_Count=ATOMIC_INIT(0); - -u_long Daemon_Command_Timeout = TIMEOUT_VALUE; - -DECLARE_MUTEX ( DriveMapLock ); -LIST_HEAD( DriveMapList ); - -int MaxIoSize=PAGE_SIZE; - -/*===[ Code ]=============================================================*/ - -/*++======================================================================*/ -void Init_Daemon_Queue() -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - INIT_LIST_HEAD(&Daemon_Queue.list); - spin_lock_init(&Daemon_Queue.lock); - init_MUTEX_LOCKED(&Daemon_Queue.semaphore); -} - -/*++======================================================================*/ -void Uninit_Daemon_Queue( void ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - /* Does nothing for now but we maybe should clear the queue. */ -} - -/*++======================================================================*/ -void -NO_TRACE -Daemon_Timer(u_long data) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - daemon_command_t *que = (daemon_command_t *)data; - - if ( QUEUE_ACKED != que->status ) - { - que->status = QUEUE_TIMEOUT; - } - up(&que->semaphore); -} - -/*++======================================================================*/ -int Queue_Daemon_Command( - void *request, - u_long reqlen, - void *data, - int dlen, - void **reply, - u_long *replen, - int interruptible) -/* - * - * Arguments: void *request - pointer to the request that is to be sent. Needs to be kernel memory. - * int reqlen - length of the request. - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - daemon_command_t *que; - int retCode = 0; - struct timespec ts1, ts2; - - ts1 = current_kernel_time(); - - DbgPrint( "Queue_Daemon_Command: 0x%x %d\n", request, reqlen); - - if (atomic_read(&Daemon_Open_Count)) - { - - que = (daemon_command_t *)Novfs_Malloc(sizeof(*que), GFP_KERNEL); - - DbgPrint( "Queue_Daemon_Command: que=0x%x\n", que); - if (que) - { - atomic_set( &que->reference, 0 ); - que->status = QUEUE_SENDING; - que->flags = 0; - - init_MUTEX_LOCKED(&que->semaphore); - - DbgPrint( "Queue_Daemon_Command: semaphore inited que=0x%x\n", que); - - que->sequence = InterlockedIncrement(&Sequence); - - DbgPrint( "Queue_Daemon_Command: sequence=0x%x\n", que->sequence); - - ((PCOMMAND_REQUEST_HEADER)request)->SequenceNumber = que->sequence; - - /* - * Setup and start que timer - */ - init_timer(&que->timer); - que->timer.expires = jiffies + (HZ * Daemon_Command_Timeout); - que->timer.data = (u_long)que; - que->timer.function = Daemon_Timer; - add_timer(&que->timer); - - DbgPrint( "Queue_Daemon_Command: timer started que=0x%x\n", que); - - /* - * Setup request - */ - que->request = request; - que->reqlen = reqlen; - que->data = data; - que->datalen = dlen; - que->reply = NULL; - que->replen = 0; - - DbgPrint( "Queue_Daemon_Command: setting up que=0x%x\n", que); - - /* - * Added entry to queue. - */ - DbgPrint( "Queue_Daemon_Command: Daemon_Queue locked\n"); - - /* - * Check to see if interruptible and set flags. - */ - if (interruptible) - { - que->flags |= INTERRUPTIBLE; - } - - spin_lock(&Daemon_Queue.lock); - Queue_get( que ); - list_add_tail(&que->list, &Daemon_Queue.list); - spin_unlock(&Daemon_Queue.lock); - - DbgPrint( "Queue_Daemon_Command: 0x%x added to Daemon_Queue\n", que); - /* - * Signal that there is data to be read - */ - up(&Daemon_Queue.semaphore); - - /* - * Give a change to the other processes. - */ - yield(); - - DbgPrint( "Queue_Daemon_Command: calling down 0x%x\n", CURRENT_TIME); - - /* - * Block waiting for reply or timeout - */ - down(&que->semaphore); - - DbgPrint( "Queue_Daemon_Command: after down 0x%x\n", CURRENT_TIME); - - if ( QUEUE_ACKED == que->status ) - { - que->status = QUEUE_WAITING; - mod_timer(&que->timer, jiffies + (HZ * 2 * Daemon_Command_Timeout)); - DbgPrint( "Queue_Daemon_Command: mod_timer 0x%x\n", CURRENT_TIME); - if (interruptible) - { - retCode = down_interruptible(&que->semaphore); - } - else - { - down(&que->semaphore); - } - DbgPrint( "Queue_Daemon_Command: after down2 0x%x\n", CURRENT_TIME); - } - - DbgPrint( "Queue_Daemon_Command: after down 0x%d 0x%x\n", retCode, CURRENT_TIME); - /* - * Delete timer - */ - del_timer(&que->timer); - - /* - * Check for timeout - */ - if ((QUEUE_TIMEOUT == que->status) && (NULL == que->reply) ) - { - DbgPrint( "Queue_Daemon_Command: Timeout\n"); - retCode = -ETIME; - } - *reply = que->reply; - *replen = que->replen; - - /* - * Remove item from queue - */ - Queue_put( que ); - - } - else /* Error case with no memory */ - { - retCode = -ENOMEM; - *reply = NULL; - *replen = 0; - } - } - else - { - retCode = -EIO; - *reply = NULL; - *replen = 0; - - } - ts2 = current_kernel_time(); - if (ts2.tv_nsec < ts1.tv_nsec) - { - ts2.tv_sec--; - ts2.tv_nsec += NSEC_PER_SEC; - } - ts2.tv_sec = ts2.tv_sec-ts1.tv_sec; - ts2.tv_nsec = ts2.tv_nsec-ts1.tv_nsec; - - DbgPrint( "Queue_Daemon_Command: %ld:%lu retCode=%d \n", ts2.tv_sec, ts2.tv_nsec, retCode); - return(retCode); -} - -/*++======================================================================*/ -void Queue_get(daemon_command_t *Que) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - DbgPrint("Queue_get: que=0x%p %d\n", Que, atomic_read(&Que->reference)); - atomic_inc( &Que->reference ); -} - -/*++======================================================================*/ -void Queue_put(daemon_command_t *Que) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - spin_lock(&Daemon_Queue.lock); - - DbgPrint("Queue_put: que=0x%p %d\n", Que, atomic_read(&Que->reference)); - if ( atomic_dec_and_test( &Que->reference )) - { - /* - * Remove item from queue - */ - list_del(&Que->list); - - spin_unlock(&Daemon_Queue.lock); - - /* - * Free item memory - */ - Novfs_Free(Que); - } - else - { - spin_unlock(&Daemon_Queue.lock); - } -} - -/*++======================================================================*/ -daemon_command_t *get_next_queue(int Set_Queue_Waiting) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - daemon_command_t *que; - - spin_lock(&Daemon_Queue.lock); - que = (daemon_command_t *)Daemon_Queue.list.next; - - DbgPrint( "get_next_queue: que=0x%x\n", que); - - while (que && (que != (daemon_command_t *)&Daemon_Queue.list.next) && ( que->status != QUEUE_SENDING ) ) - { - que = (daemon_command_t *)que->list.next; - DbgPrint( "get_next_queue: que1=0x%x\n", que); - } - - if ((NULL == que) || (que == (daemon_command_t *)&Daemon_Queue.list) || (que->status != QUEUE_SENDING)) - { - que = NULL; - } - else if (Set_Queue_Waiting) - { - que->status = QUEUE_WAITING; - } - - if (que) - { - atomic_inc( &que->reference ); - } - - spin_unlock(&Daemon_Queue.lock); - - DbgPrint( "get_next_queue: return=0x%x\n", que); - return(que); -} - -/*++======================================================================*/ -daemon_command_t *find_queue(u_long sequence) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - daemon_command_t *que; - - DbgPrint( "find_queue: 0x%x\n", sequence); - - spin_lock(&Daemon_Queue.lock); - que = (daemon_command_t *)Daemon_Queue.list.next; - - DbgPrint( "find_queue: que=0x%x\n", que); - - while (que && (que != (daemon_command_t *)&Daemon_Queue.list.next) && (que->sequence != sequence)) - { - DbgPrint( "find_queue: que1=0x%x\n", que); - que = (daemon_command_t *)que->list.next; - } - - if ((NULL == que) || (que == (daemon_command_t *)&Daemon_Queue.list.next) || (que->sequence != sequence)) - { - que = NULL; - } - - if (que) - { - atomic_inc( &que->reference ); - } - - spin_unlock(&Daemon_Queue.lock); - - DbgPrint( "find_queue: return 0x%x\n", que); - return(que); -} -/*++======================================================================*/ -int Daemon_Open_Control(struct inode *Inode, struct file *File) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - DbgPrint("Daemon_Open_Control: pid=%d Count=%d\n", current->pid, atomic_read(&Daemon_Open_Count)); - atomic_inc(&Daemon_Open_Count); - - return(0); -} - -/*++======================================================================*/ -int Daemon_Close_Control(struct inode *Inode, struct file *File) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - daemon_command_t *que; - - DbgPrint("Daemon_Close_Control: pid=%d Count=%d\n", current->pid, atomic_read(&Daemon_Open_Count)); - - if (atomic_dec_and_test(&Daemon_Open_Count)) - { - /* - * Signal any pending que itmes. - */ - - spin_lock(&Daemon_Queue.lock); - que = (daemon_command_t *)Daemon_Queue.list.next; - - DbgPrint( "Daemon_Close_Control: que=0x%x\n", que); - - while (que && (que != (daemon_command_t *)&Daemon_Queue.list.next) && (que->status != QUEUE_DONE)) - { - que->status = QUEUE_TIMEOUT; - up(&que->semaphore); - - que = (daemon_command_t *)que->list.next; - DbgPrint( "Daemon_Close_Control: que1=0x%x\n", que); - } - spin_unlock(&Daemon_Queue.lock); - - RemoveDriveMaps(); - - Scope_Cleanup(); - } - - return(0); -} - -/*++======================================================================*/ -ssize_t -Daemon_Send_Command(struct file *file, char *buf, size_t len, loff_t *off) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - daemon_command_t *que; - size_t retValue = 0; - int Finished=0; - PDATA_LIST dlist; - int i, dcnt, bcnt, ccnt, error; - char *vadr; - u_long cpylen; - - DbgPrint( "Daemon_Send_Command: %u %lld\n", len, *off); - if (len > MaxIoSize) - { - MaxIoSize = len; - } - - while ( !Finished ) - { - que = get_next_queue(1); - DbgPrint( "Daemon_Send_Command: 0x%x\n", que); - if (que) - { - retValue = que->reqlen; - if (retValue > len) - { - retValue = len; - } - if (retValue > 0x80) - mydump(0x80, que->request); - else - mydump(retValue, que->request); - - cpylen = copy_to_user(buf, que->request, retValue); - if (que->datalen && (retValue < len)) - { - buf += retValue; - dlist = que->data; - dcnt = que->datalen; - for (i=0; irwflag ) - { - bcnt = dlist->len; - DbgPrint("Daemon_Send_Command%d: page=0x%x offset=0x%x len=%d\n", i, dlist->page, dlist->offset, dlist->len); - if ((bcnt + retValue) <= len) - { - void *km_adr=NULL; - - if (dlist->page) - { - //vadr = kmap(dlist->page); - km_adr = kmap_atomic(dlist->page, KM_USER1); - vadr = km_adr; - vadr += (u_int)dlist->offset; - } - else - { - vadr = dlist->offset; - } - - ccnt = copy_to_user(buf, vadr, bcnt); - - if ( km_adr ) - { - //kunmap(dlist->page); - kunmap_atomic(km_adr, KM_USER1); - } - - DbgPrint("Daemon_Send_Command: Copy %d from 0x%x to 0x%x.\n", bcnt, vadr, buf); - if (bcnt > 0x80) - mydump(0x80, vadr); - else - mydump(bcnt, vadr); - - retValue += bcnt; - buf += bcnt; - } - else - { - break; - } - } - } - } - Queue_put( que ); - break; - } - - if (O_NONBLOCK & file->f_flags) - { - retValue = -EAGAIN; - break; - } - else - { - if ((error = down_interruptible(&Daemon_Queue.semaphore))) - { - DbgPrint( "Daemon_Send_Command: after down_interruptible error...%d\n", error); - retValue = -EINTR; - break; - } - DbgPrint( "Daemon_Send_Command: after down_interruptible\n"); - } - } - - *off = *off; - - DbgPrint( "Daemon_Send_Command: return 0x%x\n", retValue); - - return(retValue); -} - -/*++======================================================================*/ -ssize_t -Daemon_Receive_Reply(struct file * file, char * buf, size_t nbytes, loff_t *ppos) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - daemon_command_t *que; - size_t retValue = 0; - void *reply; - u_long sequence, cpylen; - - PDATA_LIST dlist; - char *vadr; - int i; - - DbgPrint( "Daemon_Receive_Reply: buf=0x%x nbytes=%d ppos=%llx\n", buf, nbytes, *ppos); - - /* - * Get sequence number from reply buffer - */ - - cpylen = copy_from_user(&sequence, buf, sizeof(sequence)); - - /* - * Find item based on sequence number - */ - que = find_queue(sequence); - - DbgPrint( "Daemon_Receive_Reply: 0x%x 0x%x %d\n", sequence, que, nbytes); - if (que) - { - do - { - retValue = nbytes; - /* - * Ack packet from novfsd. Remove timer and - * return - */ - if (nbytes == sizeof(sequence)) - { - que->status = QUEUE_ACKED; - break; - } - - /* - * Set status that packet is done. - */ - que->status = QUEUE_DONE; - - if ( NULL != (dlist = que->data) ) - { - int thiscopy, left=nbytes; - retValue = 0; - - - DbgPrint( "Daemon_Receive_Reply: dlist=0x%x count=%d\n", dlist, que->datalen); - for (i=0; i < que->datalen; i++, dlist++) - { - DbgPrint( "Daemon_Receive_Reply:\n" \ - " dlist[%d].page: 0x%x\n" \ - " dlist[%d].offset: 0x%x\n" \ - " dlist[%d].len: 0x%x\n" \ - " dlist[%d].rwflag: 0x%x\n", - i, dlist->page, - i, dlist->offset, - i, dlist->len, - i, dlist->rwflag); - - if (DLWRITE == dlist->rwflag) - { - void *km_adr=NULL; - - if (dlist->page) - { - //vadr = kmap(dlist->page); - km_adr = kmap_atomic(dlist->page, KM_USER1); - vadr = km_adr; - vadr += (u_int)dlist->offset; - } - else - { - vadr = dlist->offset; - } - - thiscopy = dlist->len; - if (thiscopy > left) - { - thiscopy = left; - dlist->len = left; - } - cpylen = copy_from_user(vadr, buf, thiscopy); - - if ( km_adr ) - { - //kunmap(dlist->page); - kunmap_atomic(km_adr, KM_USER1); - } - - left -= thiscopy; - retValue += thiscopy; - buf += thiscopy; - } - } - } - else - { - reply = Novfs_Malloc(nbytes, GFP_KERNEL); - DbgPrint( "Daemon_Receive_Reply: reply=0x%x\n", reply); - if (reply) - { - retValue = nbytes; - que->reply = reply; - que->replen = nbytes; - - retValue -= copy_from_user(reply, buf, retValue); - if (retValue > 0x80) - mydump(0x80, reply); - else - mydump(retValue, reply); - - - } - else - { - retValue = -ENOMEM; - } - } - } while (0); - up(&que->semaphore); - Queue_put( que ); - } - - DbgPrint( "Daemon_Receive_Reply: return 0x%x\n", retValue); - - return(retValue); -} - -/*++======================================================================*/ -int do_login(NclString *Server, NclString *Username, NclString *Password, u_long *lgnId, session_t Session) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - PLOGIN_USER_REQUEST cmd; - PLOGIN_USER_REPLY reply; - u_long replylen=0; - int retCode, cmdlen, datalen; - u_char *data; - - datalen = Server->len+Username->len+Password->len; - cmdlen = sizeof(*cmd) + datalen; - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - if (cmd) - { - data = (u_char *)cmd + sizeof(*cmd); - cmd->Command.CommandType = VFS_COMMAND_LOGIN_USER; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - - cmd->srvNameType = Server->type; - cmd->serverLength = Server->len; - cmd->serverOffset = (u_long)(data-(u_char *)cmd); - memcpy(data, Server->buffer, Server->len); - data += Server->len; - - cmd->usrNameType = Username->type; - cmd->userNameLength = Username->len; - cmd->userNameOffset = (u_long)(data-(u_char *)cmd); - memcpy(data, Username->buffer, Username->len); - data += Username->len; - - cmd->pwdNameType = Password->type; - cmd->passwordLength = Password->len; - cmd->passwordOffset = (u_long)(data-(u_char *)cmd); - memcpy(data, Password->buffer, Password->len); - data += Password->len; - - retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - if (reply->Reply.ErrorCode) - { - retCode = reply->Reply.ErrorCode; - } - else - { - retCode = 0; - if (lgnId) - { - *lgnId = reply->loginIdentity; - } - } - Novfs_Free(reply); - } - memset(cmd, 0, cmdlen); - Novfs_Free(cmd); - } - else - { - retCode = -ENOMEM; - } - return( retCode ); - -} - -/*++======================================================================*/ -int do_logout( struct qstr *Server, session_t Session ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - PLOGOUT_REQUEST cmd; - PLOGOUT_REPLY reply; - u_long replylen=0; - int retCode, cmdlen; - - cmdlen = (int)(&((PLOGOUT_REQUEST)0)->Name) + Server->len; - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_LOGOUT_USER; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - - cmd->Length = Server->len; - memcpy(cmd->Name, Server->name, Server->len); - - retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - if (reply->Reply.ErrorCode) - { - retCode = -EIO; - } - Novfs_Free(reply); - } - Novfs_Free(cmd); - } - else - { - retCode = -ENOMEM; - } - return( retCode ); - -} - -/*++======================================================================*/ -int Daemon_getpwuid( uid_t uid, int unamelen, char *uname ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - GETPWUID_REQUEST cmd; - PGETPWUID_REPLY reply; - u_long replylen=0; - int retCode; - - cmd.Command.CommandType = VFS_COMMAND_GETPWUD; - cmd.Command.SequenceNumber = 0; - cmd.Command.SessionId = 0; - cmd.uid = uid; - - retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - if (reply->Reply.ErrorCode) - { - retCode = -EIO; - } - else - { - retCode = 0; - memset(uname, 0, unamelen); - replylen = replylen - (int)(&((PGETPWUID_REPLY)0)->UserName); - if (replylen) - { - if (replylen > unamelen) - { - retCode = -EINVAL; - replylen = unamelen-1; - } - memcpy(uname, reply->UserName, replylen); - } - } - Novfs_Free(reply); - } - return( retCode ); - -} - -/*++======================================================================*/ -int Daemon_getversion( char *Buf, int Length ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - GET_VERSION_REQUEST cmd; - PGET_VERSION_REPLY reply; - u_long replylen=0; - int retVal=0; - - cmd.Command.CommandType = VFS_COMMAND_GET_VERSION; - cmd.Command.SequenceNumber = 0; - cmd.Command.SessionId = 0; - - Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - if (reply->Reply.ErrorCode) - { - retVal = -EIO; - } - else - { - retVal = replylen - (int)(&((PGET_VERSION_REPLY)0)->Version); - if (retVal < Length) - { - memcpy(Buf, reply->Version, retVal); - Buf[retVal] = '\0'; - } - } - Novfs_Free(reply); - } - return( retVal ); - -} - -/*++======================================================================*/ -int Daemon_Login(PLOGIN Login, session_t Session) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - int retCode = -ENOMEM; - LOGIN lLogin; - NclString server; - NclString username; - NclString password; - - if ( !copy_from_user(&lLogin, Login, sizeof(lLogin))) - { - if ( (server.buffer = Novfs_Malloc(lLogin.Server.Length, GFP_KERNEL)) ) - { - server.len = lLogin.Server.Length; - server.type = NWC_STRING_TYPE_ASCII; - if ( !copy_from_user((void *)server.buffer, lLogin.Server.Data, server.len) ) - { - if ( (username.buffer = Novfs_Malloc(lLogin.UserName.Length, GFP_KERNEL)) ) - { - username.len = lLogin.UserName.Length; - username.type = NWC_STRING_TYPE_ASCII; - if ( !copy_from_user((void *)username.buffer, lLogin.UserName.Data, username.len) ) - { - if ( (password.buffer = Novfs_Malloc(lLogin.Password.Length, GFP_KERNEL)) ) - { - password.len = lLogin.Password.Length; - password.type = NWC_STRING_TYPE_ASCII; - if ( !copy_from_user((void *)password.buffer, lLogin.Password.Data, password.len) ) - { - retCode = do_login(&server, &username, &password, NULL, Session); - if ( !retCode ) - { - char *username; - username = Scope_Get_UserName( NULL ); - if (username) - { - Novfs_Add_to_Root( username ); - } - } - } - memset(password.buffer, 0, password.len); - Novfs_Free(password.buffer); - } - } - memset(username.buffer, 0, username.len); - Novfs_Free(username.buffer); - } - } - Novfs_Free(server.buffer); - } - } - - return( retCode ); -} - -/*++======================================================================*/ -int Daemon_Logout(PLOGOUT Logout, session_t Session) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - LOGOUT lLogout; - struct qstr server; - int retCode=0; - - if ( !copy_from_user(&lLogout, Logout, sizeof(lLogout))) - { - if ( (server.name = Novfs_Malloc(lLogout.Server.Length, GFP_KERNEL)) ) - { - server.len = lLogout.Server.Length; - if ( !copy_from_user((void *)server.name, lLogout.Server.Data, server.len) ) - { - retCode = do_logout( &server, Session ); - } - Novfs_Free(server.name); - } - } - return( retCode ); -} - -/*++======================================================================*/ -int Daemon_CreateSessionId( uint64_t *SessionId ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - CREATE_CONTEXT_REQUEST cmd; - PCREATE_CONTEXT_REPLY reply; - u_long replylen=0; - int retCode=0; - - DbgPrint("Daemon_CreateSessionId: %d\n", current->pid); - - cmd.Command.CommandType = VFS_COMMAND_CREATE_CONTEXT; - cmd.Command.SequenceNumber = 0; - cmd.Command.SessionId = 0; - - retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); - if ( reply ) - { - if ( !reply->Reply.ErrorCode && replylen > sizeof(COMMAND_REPLY_HEADER)) - { - *SessionId = reply->SessionId; - retCode = 0; - } - else - { - *SessionId = 0; - retCode = -EIO; - } - Novfs_Free(reply); - } - DbgPrint("Daemon_CreateSessionId: SessionId=0x%llx\n", *SessionId); - return(retCode); -} - -/*++======================================================================*/ -int Daemon_DestroySessionId( uint64_t SessionId ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - DESTROY_CONTEXT_REQUEST cmd; - PDESTROY_CONTEXT_REPLY reply; - u_long replylen=0; - int retCode=0; - - DbgPrint("Daemon_DestroySessionId: 0x%llx\n", SessionId); - - cmd.Command.CommandType = VFS_COMMAND_DESTROY_CONTEXT; - cmd.Command.SequenceNumber = 0; - cmd.Command.SessionId = SessionId; - - retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); - if ( reply ) - { - if ( !reply->Reply.ErrorCode ) - { - drive_map_t *dm; - struct list_head *list; - - retCode = 0; - - /* - * When destroying the session check to see if there are any - * mapped drives. If there are then remove them. - */ - down( &DriveMapLock ); - list_for_each( list, &DriveMapList ) - { - dm = list_entry( list, drive_map_t, list ); - if ( SessionId == dm->session) - { - local_unlink( dm->name ); - list = list->prev; - list_del( &dm->list ); - Novfs_Free( dm ); - } - - } - up( &DriveMapLock ); - - } - else - { - retCode = -EIO; - } - Novfs_Free(reply); - } - return(retCode); -} - -/*++======================================================================*/ -int Daemon_Get_UserSpace( uint64_t SessionId, uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - GET_USER_SPACE_REQUEST cmd; - PGET_USER_SPACE_REPLY reply; - u_long replylen=0; - int retCode=0; - - DbgPrint("Daemon_Get_UserSpace: 0x%llx\n", SessionId); - - cmd.Command.CommandType = VFS_COMMAND_GET_USER_SPACE; - cmd.Command.SequenceNumber = 0; - cmd.Command.SessionId = SessionId; - - retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); - if ( reply ) - { - if ( !reply->Reply.ErrorCode ) - { - - DbgPrint("TotalSpace: %llu\n", reply->TotalSpace); - DbgPrint("FreeSpace: %llu\n", reply->FreeSpace); - DbgPrint("TotalEnties: %llu\n", reply->TotalEnties); - DbgPrint("FreeEnties: %llu\n", reply->FreeEnties); - - if (TotalSize) *TotalSize = reply->TotalSpace; - if (Free) *Free = reply->FreeSpace; - if (TotalEnties) *TotalEnties = reply->TotalEnties; - if (FreeEnties) *FreeEnties = reply->FreeEnties; - retCode = 0; - } - else - { - retCode = -EIO; - } - Novfs_Free(reply); - } - return(retCode); -} - -/*++======================================================================*/ -int Daemon_SetMountPoint ( char *Path ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - PSET_MOUNT_PATH_REQUEST cmd; - PSET_MOUNT_PATH_REPLY reply; - u_long replylen, cmdlen; - int retCode = -ENOMEM; - - DbgPrint("Daemon_SetMountPoint: %s\n", Path); - - replylen = strlen(Path); - - cmdlen = sizeof(SET_MOUNT_PATH_REQUEST) + replylen; - - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - if ( cmd ) - { - cmd->Command.CommandType = VFS_COMMAND_SET_MOUNT_PATH; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = 0; - cmd->PathLength = replylen; - - strcpy(cmd->Path, Path); - - replylen = 0; - - retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); - if ( reply ) - { - if ( !reply->Reply.ErrorCode ) - { - retCode = 0; - } - else - { - retCode = -EIO; - } - Novfs_Free(reply); - } - Novfs_Free(cmd); - } - return(retCode); -} - -/*++======================================================================*/ -int Daemon_SendDebugCmd ( char *Command ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - DEBUG_REQUEST cmd; - PDEBUG_REPLY reply; - DEBUG_REPLY lreply; - u_long replylen, cmdlen; - DATA_LIST dlist[2]; - - int retCode = -ENOMEM; - - DbgPrint("Daemon_SendDebugCmd: %s\n", Command); - - dlist[0].page = NULL; - dlist[0].offset = (char *)Command; - dlist[0].len = strlen(Command); - dlist[0].rwflag = DLREAD; - - dlist[1].page = NULL; - dlist[1].offset = (char *)&lreply; - dlist[1].len = sizeof(lreply); - dlist[1].rwflag = DLWRITE; - - cmdlen = (int)(&((PDEBUG_REQUEST)0)->dbgcmd); - - cmd.Command.CommandType = VFS_COMMAND_DBG; - cmd.Command.SequenceNumber = 0; - cmd.Command.SessionId = 0; - cmd.cmdlen = strlen(Command); - - replylen = 0; - - retCode = Queue_Daemon_Command(&cmd, cmdlen, dlist, 2, (void *)&reply, &replylen, INTERRUPTIBLE); - if ( reply ) - { - Novfs_Free(reply); - } - if (0 == retCode) - { - retCode = lreply.Reply.ErrorCode; - } - - return(retCode); -} - -/*++======================================================================*/ -int -NO_TRACE -Daemon_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u_long arg) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - int retCode = -ENOSYS; - u_long cpylen; - - - switch (cmd) - { - case IOC_LOGIN: - { - retCode = Daemon_Login((PLOGIN)arg, Scope_Get_SessionId( NULL )); - break; - } - - case IOC_LOGOUT: - { - retCode = Daemon_Logout((PLOGOUT)arg, Scope_Get_SessionId( NULL )); - break; - } - case IOC_DEBUGPRINT: - { - struct Ioctl_Debug { - int length; - char *data; - } io; - char *buf; - io.length = 0; - cpylen = copy_from_user(&io, (char *)arg, sizeof(io)); - if (io.length) - { - buf = Novfs_Malloc(io.length+1, GFP_KERNEL); - if (buf) - { - buf[0] = 0; - cpylen = copy_from_user(buf, io.data, io.length); - buf[io.length] = '\0'; - if( DbgDaemonLogOn ) - printk("%s", buf); - else - DbgPrint("%s", buf); - Novfs_Free(buf); - retCode = 0; - } - } - break; - } - - case IOC_XPLAT: - { - XPLAT data; - - cpylen = copy_from_user(&data, (void *)arg, sizeof(data)); - retCode = ((data.xfunction & 0x0000FFFF) | 0xCC000000); - - switch(data.xfunction) - { - case NWC_GET_MOUNT_PATH: - DbgPrint("[Daemon_ioctl] Call NwdGetMountPath\n"); - retCode = NwdGetMountPath( &data ); - break; - } - - DbgPrint("[NOVFS XPLAT] status Code = %X\n", retCode); - break; - } - - } - return (retCode); -} - -/*++======================================================================*/ -int Daemon_Added_Resource(daemon_handle_t *DHandle, int Type, u_long CHandle, u_char *FHandle, u_long Mode, u_long Size) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - daemon_resource_t *resource; - int retVal = NWE_OUT_OF_HEAP_SPACE; - - if (FHandle) - DbgPrint("Daemon_Added_Resource: DHandle=0x%p Type=%d CHandle=0x%x FHandle=0x%x Mode=0x%x Size=%d\n", DHandle, Type, CHandle, *(u_long *)&FHandle[2], Mode, Size); - else - DbgPrint("Daemon_Added_Resource: DHandle=0x%p Type=%d CHandle=0x%x\n", DHandle, Type, CHandle); - - resource = Novfs_Malloc(sizeof(daemon_resource_t), GFP_KERNEL); - if (resource) - { - resource->type = Type; - resource->connection = CHandle; - if (FHandle) - { - memcpy( resource->handle, FHandle, sizeof(resource->handle) ); - } - else - { - memset( resource->handle, 0, sizeof(resource->handle) ); - } - resource->mode = Mode; - resource->size = Size; - write_lock( &DHandle->lock ); - list_add( &resource->list, &DHandle->list ); - write_unlock( &DHandle->lock ); - DbgPrint("Daemon_Added_Resource: Adding resource=0x%p\n", resource); - retVal = 0; - } - - return(retVal); -} - -/*++======================================================================*/ -int Daemon_Remove_Resource(daemon_handle_t *DHandle, int Type, u_long CHandle, u_long FHandle) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - daemon_resource_t *resource; - struct list_head *l; - int retVal = -ENOMEM; - - DbgPrint("Daemon_Remove_Resource: DHandle=0x%p Type=%d CHandle=0x%x FHandle=0x%x\n", DHandle, Type, CHandle, FHandle); - - write_lock( &DHandle->lock ); - - list_for_each( l, &DHandle->list ) - { - resource = list_entry( l, daemon_resource_t, list ); - - if ( (Type == resource->type) && - (resource->connection == CHandle) ) - { - DbgPrint("Daemon_Remove_Resource: Found resource=0x%p\n", resource); - l = l->prev; - list_del( &resource->list ); - Novfs_Free( resource ); - break; - } - } - - write_unlock( &DHandle->lock ); - - return(retVal); -} - -/*++======================================================================*/ -int Daemon_Library_open(struct inode *inode, struct file *file) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - int retVal = -ENOMEM; - daemon_handle_t *dh; - - DbgPrint("Daemon_Library_open: inode=0x%p file=0x%p\n", inode, file); - - if ((dh = Novfs_Malloc(sizeof(daemon_handle_t), GFP_KERNEL))) - { - file->private_data = dh; - INIT_LIST_HEAD( &dh->list); - rwlock_init( &dh->lock ); - dh->session = Scope_Get_SessionId( NULL ); - retVal = 0; - } - return(retVal); -} - -/*++======================================================================*/ -int Daemon_Library_close(struct inode *inode, struct file *file) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - daemon_handle_t *dh; - daemon_resource_t *resource; - struct list_head *l; - - char commanddata[sizeof(XPLAT_CALL_REQUEST)+sizeof(NwdCCloseConn)]; - PXPLAT_CALL_REQUEST cmd; - PXPLAT_CALL_REPLY reply; - PNwdCCloseConn nwdClose; - u_long cmdlen, replylen; - - DbgPrint("Daemon_Library_close: inode=0x%p file=0x%p\n", inode, file); - if (file->private_data) - { - dh = (daemon_handle_t *)file->private_data; - - list_for_each( l, &dh->list ) - { - resource = list_entry( l, daemon_resource_t, list ); - - if (DH_TYPE_STREAM == resource->type) - { - Novfs_Close_Stream( resource->connection, resource->handle, dh->session ); - } - else if (DH_TYPE_CONNECTION == resource->type) - { - cmd = (PXPLAT_CALL_REQUEST)commanddata; - cmdlen = offsetof(XPLAT_CALL_REQUEST, data) + sizeof(NwdCCloseConn); - cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = dh->session; - cmd->NwcCommand = NWC_CLOSE_CONN; - - cmd->dataLen = sizeof(NwdCCloseConn); - nwdClose = (PNwdCCloseConn)cmd->data; - nwdClose->ConnHandle = resource->connection; - - Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, 0); - if (reply) - { - Novfs_Free(reply); - } - } - l = l->prev; - list_del( &resource->list ); - Novfs_Free( resource ); - } - Novfs_Free(dh); - file->private_data = NULL; - } - - return(0); -} - -/*++======================================================================*/ -ssize_t Daemon_Library_read(struct file *file, char *buf, size_t len, loff_t *off) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - daemon_handle_t *dh; - daemon_resource_t *resource; - - size_t thisread, totalread=0; - loff_t offset = *off; - - DbgPrint("Daemon_Library_read: file=0x%p len=%d off=%lld\n", file, len, *off); - - if (file->private_data) - { - dh = file->private_data; - read_lock( &dh->lock ); - if (&dh->list != dh->list.next) - { - resource = list_entry( dh->list.next, daemon_resource_t, list ); - - if (DH_TYPE_STREAM == resource->type) - { - while( len > 0 && (offset < resource->size) ) - { - thisread = len; - if (Novfs_Read_Stream(resource->connection, - resource->handle, - buf, &thisread, - &offset, 1, - dh->session) || !thisread) - { - break; - } - len -= thisread; - buf += thisread; - offset += thisread; - totalread += thisread; - } - } - } - read_unlock( &dh->lock ); - } - *off = offset; - DbgPrint("Daemon_Library_read return = 0x%x\n", totalread); - return(totalread); -} - -/*++======================================================================*/ -ssize_t Daemon_Library_write(struct file *file, const char *buf, size_t len, loff_t *off) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - daemon_handle_t *dh; - daemon_resource_t *resource; - - size_t thiswrite, totalwrite=-EINVAL; - loff_t offset = *off; - int status; - - DbgPrint("Daemon_Library_write: file=0x%p len=%d off=%lld\n", file, len, *off); - - if (file->private_data) - { - dh = file->private_data; - write_lock( &dh->lock ); - if (&dh->list != dh->list.next) - { - resource = list_entry( dh->list.next, daemon_resource_t, list ); - - if ( (DH_TYPE_STREAM == resource->type) && (len >= 0) ) - { - totalwrite = 0; - do - { - thiswrite = len; - status = Novfs_Write_Stream(resource->connection, - resource->handle, - (PVOID)buf, - &thiswrite, - &offset, - dh->session); - if ( status || !thiswrite ) - { - /* - * If len is zero then the file will have just been - * truncated to offset. Update size. - */ - if ( !status && !len ) - { - resource->size = offset; - } - totalwrite = status; - break; - } - len -= thiswrite; - buf += thiswrite; - offset += thiswrite; - totalwrite += thiswrite; - if (offset > resource->size) - { - resource->size = offset; - } - } while(len > 0); - } - } - write_unlock( &dh->lock ); - } - *off = offset; - DbgPrint("Daemon_Library_write return = 0x%x\n", totalwrite); - - return(totalwrite); -} - -/*++======================================================================*/ -loff_t Daemon_Library_llseek(struct file *file, loff_t offset, int origin) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - daemon_handle_t *dh; - daemon_resource_t *resource; - - loff_t retVal = -EINVAL; - - DbgPrint("Daemon_Library_llseek: file=0x%p offset=%lld origin=%d\n", file, offset, origin); - - if (file->private_data) - { - dh = file->private_data; - read_lock( &dh->lock ); - if (&dh->list != dh->list.next) - { - resource = list_entry( dh->list.next, daemon_resource_t, list ); - - if (DH_TYPE_STREAM == resource->type) - { - switch (origin) { - case 2: - offset += resource->size; - break; - case 1: - offset += file->f_pos; - } - if (offset >= 0) { - if (offset != file->f_pos) { - file->f_pos = offset; - file->f_version = 0; - } - retVal = offset; - } - } - } - read_unlock( &dh->lock ); - } - - DbgPrint("Daemon_Library_llseek: ret %lld\n", retVal); - - return retVal; -} - -/*++======================================================================*/ -int -NO_TRACE -Daemon_Library_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u_long arg) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - int retCode = -ENOSYS; - daemon_handle_t *dh; - u_long handle=0, cpylen; - - - dh = file->private_data; - - DbgPrint("Daemon_Library_ioctl: file=0x%p 0x%x 0x%x dh=0x%p\n", file, cmd, arg, dh); - - if (dh) - { - - switch (cmd) - { - case IOC_LOGIN: - { - retCode = Daemon_Login((PLOGIN)arg, dh->session); - break; - } - - case IOC_LOGOUT: - { - retCode = Daemon_Logout((PLOGOUT)arg, dh->session); - break; - } - - case IOC_DEBUGPRINT: - { - struct Ioctl_Debug { - int length; - char *data; - } io; - char *buf; - io.length = 0; - cpylen = copy_from_user(&io, (char *)arg, sizeof(io)); - if (io.length) - { - buf = Novfs_Malloc(io.length+1, GFP_KERNEL); - if (buf) - { - buf[0] = 0; - cpylen = copy_from_user(buf, io.data, io.length); - buf[io.length] = '\0'; - DbgPrint("%s", buf); - Novfs_Free(buf); - retCode = 0; - } - } - break; - } - - case IOC_XPLAT: - { - XPLAT data; - - cpylen = copy_from_user(&data, (void *)arg, sizeof(data)); - retCode = ((data.xfunction & 0x0000FFFF) | 0xCC000000); - - switch(data.xfunction) - { - case NWC_OPEN_CONN_BY_NAME: - DbgPrint("[VFS XPLAT] Call NwOpenConnByName\n"); - retCode = NwOpenConnByName(&data, &handle, dh->session); - if ( !retCode ) - { - Daemon_Added_Resource(dh, DH_TYPE_CONNECTION, handle, 0, 0, 0); - } - break; - - case NWC_OPEN_CONN_BY_ADDRESS: - DbgPrint("[VFS XPLAT] Call NwOpenConnByAddress\n"); - retCode = NwOpenConnByAddr(&data, &handle, dh->session); - if ( !retCode ) - { - Daemon_Added_Resource(dh, DH_TYPE_CONNECTION, handle, 0, 0, 0); - } - break; - - case NWC_OPEN_CONN_BY_REFERENCE: - - DbgPrint("[VFS XPLAT] Call NwOpenConnByReference\n"); - retCode = NwOpenConnByRef(&data, &handle, dh->session); - if ( !retCode ) - { - Daemon_Added_Resource(dh, DH_TYPE_CONNECTION, handle, 0, 0, 0); - } - break; - - case NWC_SYS_CLOSE_CONN: - DbgPrint("[VFS XPLAT] Call NwSysCloseConn\n"); - retCode = NwSysConnClose(&data, &handle, dh->session); - Daemon_Remove_Resource(dh, DH_TYPE_CONNECTION, handle, 0); - break; - - case NWC_CLOSE_CONN: - DbgPrint("[VFS XPLAT] Call NwCloseConn\n"); - retCode = NwConnClose(&data, &handle, dh->session); - Daemon_Remove_Resource(dh, DH_TYPE_CONNECTION, handle, 0); - break; - - case NWC_LOGIN_IDENTITY: - DbgPrint("[VFS XPLAT] Call NwLoginIdentity\n"); - retCode = NwLoginIdentity(&data, dh->session); - break; - - case NWC_RAW_NCP_REQUEST: - DbgPrint("[VFS XPLAT] Send Raw NCP Request\n"); - retCode = NwRawSend(&data, dh->session); - break; - - case NWC_AUTHENTICATE_CONN_WITH_ID: - DbgPrint("[VFS XPLAT] Authenticate Conn With ID\n"); - retCode = NwAuthConnWithId(&data, dh->session); - break; - - case NWC_UNAUTHENTICATE_CONN: - DbgPrint("[VFS XPLAT] UnAuthenticate Conn With ID\n"); - retCode = NwUnAuthenticate(&data, dh->session); - break; - - case NWC_LICENSE_CONN: - DbgPrint("Call NwLicenseConn\n"); - retCode = NwLicenseConn(&data, dh->session); - break; - - case NWC_LOGOUT_IDENTITY: - DbgPrint("[VFS XPLAT] Call NwLogoutIdentity\n"); - retCode = NwLogoutIdentity(&data, dh->session); - break; - - case NWC_UNLICENSE_CONN: - DbgPrint("[VFS XPLAT] Call NwUnlicense\n"); - retCode = NwUnlicenseConn(&data, dh->session); - break; - - case NWC_GET_CONN_INFO: - DbgPrint("[VFS XPLAT] Call NwGetConnInfo\n"); - retCode = NwGetConnInfo(&data, dh->session); - break; - - case NWC_SET_CONN_INFO: - DbgPrint("[VFS XPLAT] Call NwGetConnInfo\n"); - retCode = NwSetConnInfo(&data, dh->session); - break; - - case NWC_SCAN_CONN_INFO: - DbgPrint("[VFS XPLAT] Call NwScanConnInfo\n"); - retCode = NwScanConnInfo(&data, dh->session); - break; - - - case NWC_GET_IDENTITY_INFO: - DbgPrint("[VFS XPLAT] Call NwGetIdentityInfo\n"); - retCode = NwGetIdentityInfo(&data, dh->session); - break; - - case NWC_GET_REQUESTER_VERSION: - DbgPrint("[VFS XPLAT] Call NwGetDaemonVersion\n"); - retCode = NwGetDaemonVersion(&data, dh->session); - break; - - case NWC_GET_PREFERRED_DS_TREE: - DbgPrint("[VFS XPLAT] Call NwcGetPreferredDsTree\n"); - retCode = NwcGetPreferredDSTree(&data, dh->session); - break; - - case NWC_SET_PREFERRED_DS_TREE: - DbgPrint("[VFS XPLAT] Call NwcSetPreferredDsTree\n"); - retCode = NwcSetPreferredDSTree(&data, dh->session); - break; - - case NWC_GET_DEFAULT_NAME_CONTEXT: - DbgPrint("[VFS XPLAT] Call NwcGetDefaultNameContext\n"); - retCode = NwcGetDefaultNameCtx(&data, dh->session); - break; - - case NWC_SET_DEFAULT_NAME_CONTEXT: - DbgPrint("[VFS XPLAT] Call NwcSetDefaultNameContext\n"); - retCode = NwcSetDefaultNameCtx(&data, dh->session); - break; - - case NWC_QUERY_FEATURE: - DbgPrint("[VFS XPLAT] Call NwQueryFeature\n"); - retCode = NwQueryFeature(&data, dh->session); - break; - - - case NWC_GET_TREE_MONITORED_CONN_REF: - DbgPrint("[VFS XPLAT] Call NwcGetTreeMonitoredConn\n"); - retCode = NwcGetTreeMonitoredConn(&data, dh->session); - break; - - case NWC_ENUMERATE_IDENTITIES: - DbgPrint("[VFS XPLAT] Call NwcEnumerateIdentities\n"); - retCode = NwcEnumIdentities(&data, dh->session); - break; - - case NWC_CHANGE_KEY: - DbgPrint("[VFS XPLAT] Call NwcChangeAuthKey\n"); - retCode = NwcChangeAuthKey(&data, dh->session); - break; - - case NWC_CONVERT_LOCAL_HANDLE: - DbgPrint("[VFS XPLAT] Call NwdConvertLocalHandle\n"); - retCode = NwdConvertLocalHandle(&data, dh); - break; - - case NWC_CONVERT_NETWARE_HANDLE: - DbgPrint("[VFS XPLAT] Call NwdConvertNetwareHandle\n"); - retCode = NwdConvertNetwareHandle(&data, dh); - break; - - case NWC_SET_PRIMARY_CONN: - DbgPrint("[VFS XPLAT] Call NwcSetPrimaryConn\n"); - retCode = NwcSetPrimaryConn(&data, dh->session); - break; - - case NWC_GET_PRIMARY_CONN: - DbgPrint("[VFS XPLAT] Call NwcGetPrimaryConn\n"); - retCode = NwcGetPrimaryConn(&data, dh->session); - break; - - case NWC_MAP_DRIVE: - DbgPrint("[VFS XPLAT] Call NwcMapDrive\n"); - retCode = NwdSetMapDrive(&data, dh->session); - break; - - case NWC_UNMAP_DRIVE: - DbgPrint("[VFS XPLAT] Call NwcUnMapDrive\n"); - retCode = NwdUnMapDrive(&data, dh->session); - break; - - case NWC_ENUMERATE_DRIVES: - DbgPrint("[VFS XPLAT] Call NwcEnumerateDrives\n"); - retCode = NwcEnumerateDrives(&data, dh->session); - break; - - case NWC_GET_MOUNT_PATH: - DbgPrint("[VFS XPLAT] Call NwdGetMountPath\n"); - retCode = NwdGetMountPath( &data ); - break; - - case NWC_GET_BROADCAST_MESSAGE: - DbgPrint("[VSF XPLAT Call NwdGetBroadcastMessage\n"); - retCode = NwcGetBroadcastMessage(&data, dh->session); - break; - - case NWC_SET_KEY: - DbgPrint("[VSF XPLAT Call NwdSetKey\n"); - retCode = NwdSetKeyValue(&data, dh->session); - break; - - case NWC_VERIFY_KEY: - DbgPrint("[VSF XPLAT Call NwdVerifyKey\n"); - retCode = NwdVerifyKeyValue(&data, dh->session); - break; - - case NWC_RAW_NCP_REQUEST_ALL: - case NWC_NDS_RESOLVE_NAME_TO_ID: - case NWC_FRAGMENT_REQUEST: - case NWC_GET_CONFIGURED_NSPS: - default: - break; - - } - - DbgPrint("[NOVFS XPLAT] status Code = %X\n", retCode); - break; - } - } - } - - return( retCode ); -} - -/*++======================================================================*/ -unsigned int Daemon_Poll(struct file *file, struct poll_table_struct *poll_table) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - daemon_command_t *que; - unsigned int mask = POLLOUT | POLLWRNORM; - - que = get_next_queue(0); - if (que) - { - mask |= (POLLIN | POLLRDNORM); - } - else - { - - } - return(mask); -} - - -void Daemon_Dumpque( void ) -{ -#ifdef CONFIG_KDB - daemon_command_t *que; - - que = (daemon_command_t *)Daemon_Queue.list.next; - - while (que && (que != (daemon_command_t *)&Daemon_Queue.list.next)) - { - kdb_printf("DaemonQue:\n" \ - " Que: 0x%p\n" \ - " status: 0x%lx\n" \ - " flags: 0x%lx\n" \ - " semaphore: 0x%x\n" \ - " sequence: 0x%lx\n" \ - " timer: 0x%lx\n" \ - " request: 0x%p\n" \ - " reqlen: %ld\n" \ - " data: 0x%p\n" \ - " datalen: %d\n" \ - " reply: 0x%p\n" \ - " replen: %ld\n", - que, - que->status, - que->flags, - atomic_read(&que->semaphore.count), - que->sequence, - que->timer.expires, - que->request, - que->reqlen, - que->data, - que->datalen, - que->reply, - que->replen); - que = (daemon_command_t *)que->list.next; - } -#endif -} - -/*++======================================================================*/ -int NwdConvertNetwareHandle(PXPLAT pdata, daemon_handle_t *DHandle) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - int retVal; - NwcConvertNetWareHandle nh; - u_long cpylen; - - DbgPrint("NwdConvertNetwareHandle: DHandle=0x%p\n", DHandle); - - cpylen = copy_from_user(&nh, pdata->reqData, sizeof(NwcConvertNetWareHandle)); - - retVal = Daemon_Added_Resource(DHandle, DH_TYPE_STREAM, nh.ConnHandle, nh.NetWareHandle, nh.uAccessMode, nh.uFileSize); - - return(retVal); -} - -/*++======================================================================*/ -int NwdConvertLocalHandle(PXPLAT pdata, daemon_handle_t *DHandle) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - int retVal = NWE_REQUESTER_FAILURE; - daemon_resource_t *resource; - NwcConvertLocalHandle lh; - struct list_head *l; - u_long cpylen; - - DbgPrint("NwdConvertLocalHandle: DHandle=0x%p\n", DHandle); - - read_lock( &DHandle->lock ); - - list_for_each( l, &DHandle->list ) - { - resource = list_entry( l, daemon_resource_t, list ); - - if ( DH_TYPE_STREAM == resource->type ) - { - lh.uConnReference = resource->connection; - - memcpy(lh.NwFileHandle, resource->handle, sizeof(resource->handle)); - if (pdata->repLen >= sizeof(NwcConvertLocalHandle)) - { - cpylen = copy_to_user(pdata->repData, &lh, sizeof(NwcConvertLocalHandle)); - retVal = 0; - } - else - { - retVal = NWE_BUFFER_OVERFLOW; - } - break; - } - } - - read_unlock( &DHandle->lock ); - - return(retVal); -} - -/*++======================================================================*/ -int NwdGetMountPath(PXPLAT pdata) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - int retVal = NWE_REQUESTER_FAILURE; - int len; - u_long cpylen; - NwcGetMountPath mp; - - cpylen = copy_from_user(&mp, pdata->reqData, pdata->reqLen); - - if ( Novfs_CurrentMount ) - { - - len = strlen(Novfs_CurrentMount)+1; - if ( (len > mp.MountPathLen) && mp.pMountPath) - { - retVal = NWE_BUFFER_OVERFLOW; - } - else - { - if (mp.pMountPath) - { - cpylen = copy_to_user(mp.pMountPath, Novfs_CurrentMount, len); - } - retVal = 0; - } - - mp.MountPathLen = len; - - if (pdata->repData && (pdata->repLen >= sizeof(mp)) ) - { - cpylen = copy_to_user(pdata->repData, &mp, sizeof(mp)); - } - } - - return(retVal); -} - -/*++======================================================================*/ -int NwdSetMapDrive(PXPLAT pdata, session_t Session) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - int retVal; - u_long cpylen; - - retVal = NwcSetMapDrive(pdata, Session); - if ( !retVal ) - { - NwcMapDriveEx symInfo; - char *path; - drive_map_t *drivemap, *dm; - struct list_head *list; - - cpylen = copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo)); - drivemap = Novfs_Malloc( sizeof(drive_map_t)+symInfo.linkOffsetLength, GFP_KERNEL ); - if (drivemap) - { - path = (char *)pdata->reqData; - path += symInfo.linkOffset; - cpylen = copy_from_user(drivemap->name, path, symInfo.linkOffsetLength); - - drivemap->session = Session; - drivemap->hash = full_name_hash(drivemap->name, symInfo.linkOffsetLength-1); - drivemap->namelen = symInfo.linkOffsetLength-1; - DbgPrint( "NwdSetMapDrive: hash=0x%x path=%s\n", drivemap->hash, drivemap->name); - - dm = (drive_map_t *)&DriveMapList.next; - - down( &DriveMapLock ); - - list_for_each( list, &DriveMapList ) - { - dm = list_entry( list, drive_map_t, list ); - DbgPrint( "NwdSetMapDrive: dm=0x%p\n" \ - " hash: 0x%x\n" \ - " namelen: %d\n" \ - " name: %s\n", - dm, dm->hash, dm->namelen, dm->name); - - if (drivemap->hash == dm->hash) - { - if ( 0 == strcmp(dm->name, drivemap->name)) - { - dm = NULL; - break; - } - } - else if (drivemap->hash < dm->hash) - { - break; - } - } - - if (dm) - { - if ( (dm == (drive_map_t *)&DriveMapList) || - (dm->hash < drivemap->hash) ) - { - list_add( &drivemap->list, &dm->list); - } - else - { - list_add_tail( &drivemap->list, &dm->list); - } - } - else - { - Novfs_Free( drivemap ); - } - up( &DriveMapLock ); - } - } - - return(retVal); -} - -/*++======================================================================*/ -int NwdUnMapDrive(PXPLAT pdata, session_t Session) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - int retVal = NWE_REQUESTER_FAILURE; - u_long cpylen; - - retVal = NwcUnMapDrive(pdata, Session); - if ( !retVal ) - { - NwcUnmapDriveEx symInfo; - char *path; - drive_map_t *dm; - struct list_head *list; - u_long hash; - - - cpylen = copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo)); - path = Novfs_Malloc( symInfo.linkLen, GFP_KERNEL ); - if (path) - { - cpylen = copy_from_user(path, ((NwcUnmapDriveEx *)pdata->reqData)->linkData, symInfo.linkLen); - - hash = full_name_hash(path, symInfo.linkLen-1); - DbgPrint( "NwdUnMapDrive: hash=0x%x path=%s\n", hash, path); - - dm = NULL; - - down( &DriveMapLock ); - - list_for_each( list, &DriveMapList ) - { - dm = list_entry( list, drive_map_t, list ); - DbgPrint( "NwdUnMapDrive: dm=0x%p %s\n" \ - " hash: 0x%x\n" \ - " namelen: %d\n", - dm, dm->name, dm->hash, dm->namelen); - - if (hash == dm->hash) - { - if ( 0 == strcmp(dm->name, path)) - { - break; - } - } - else if (hash < dm->hash) - { - dm = NULL; - break; - } - } - - if (dm) - { - DbgPrint( "NwdUnMapDrive: Remove dm=0x%p %s\n" \ - " hash: 0x%x\n" \ - " namelen: %d\n", - dm, dm->name, dm->hash, dm->namelen); - list_del( &dm->list ); - Novfs_Free( dm ); - } - - up( &DriveMapLock ); - } - } - - return(retVal); -} - -/*++======================================================================*/ -void RemoveDriveMaps( void ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - drive_map_t *dm; - struct list_head *list; - - down( &DriveMapLock ); - list_for_each( list, &DriveMapList ) - { - dm = list_entry( list, drive_map_t, list ); - - DbgPrint( "RemoveDriveMap: dm=0x%p\n" \ - " hash: 0x%x\n" \ - " namelen: %d\n" \ - " name: %s\n", - dm, dm->hash, dm->namelen, dm->name); - local_unlink( dm->name ); - list = list->prev; - list_del( &dm->list ); - Novfs_Free( dm ); - } - up( &DriveMapLock ); -} - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) -/*++======================================================================*/ -int local_unlink(const char *pathname) -{ - int error; - struct dentry *dentry; - struct nameidata nd; - struct inode *inode = NULL; - - DbgPrint("local_unlink: %s\n", pathname); - error = path_lookup(pathname, LOOKUP_PARENT, &nd); - DbgPrint("local_unlink: path_lookup %d\n", error); - if ( !error ) - { - error = -EISDIR; - if (nd.last_type == LAST_NORM) - { - mutex_lock(&nd.dentry->d_inode->i_mutex); - dentry = lookup_hash( &nd ); - DbgPrint("local_unlink: lookup_hash 0x%p\n", dentry); - - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) - { - if (nd.last.name[nd.last.len]) - { - error = !dentry->d_inode ? -ENOENT : S_ISDIR(dentry->d_inode->i_mode) ? -EISDIR : -ENOTDIR; - } - else - { - inode = dentry->d_inode; - if (inode) - { - atomic_inc(&inode->i_count); - } - error = vfs_unlink(nd.dentry->d_inode, dentry); - DbgPrint("local_unlink: vfs_unlink %d\n", error); - } - dput(dentry); - } - mutex_unlock(&nd.dentry->d_inode->i_mutex); - - } - path_release(&nd); - } - - if (inode) - { - iput(inode); /* truncate the inode here */ - } - - DbgPrint("local_unlink: error=%d\n", error); - return error; -} - -#else -/*++======================================================================*/ -int local_unlink(const char *pathname) -{ - int error; - struct dentry *dentry; - struct nameidata nd; - struct inode *inode = NULL; - - DbgPrint("local_unlink: %s\n", pathname); - error = path_lookup(pathname, LOOKUP_PARENT, &nd); - DbgPrint("local_unlink: path_lookup %d\n", error); - if ( !error ) - { - error = -EISDIR; - if (nd.last_type == LAST_NORM) - { - down(&nd.dentry->d_inode->i_sem); - dentry = lookup_hash(&nd.last, nd.dentry); - DbgPrint("local_unlink: lookup_hash 0x%p\n", dentry); - - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) - { - if (nd.last.name[nd.last.len]) - { - error = !dentry->d_inode ? -ENOENT : S_ISDIR(dentry->d_inode->i_mode) ? -EISDIR : -ENOTDIR; - } - else - { - inode = dentry->d_inode; - if (inode) - { - atomic_inc(&inode->i_count); - } - error = vfs_unlink(nd.dentry->d_inode, dentry); - DbgPrint("local_unlink: vfs_unlink %d\n", error); - } - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); - } - path_release(&nd); - } - - if (inode) - { - iput(inode); /* truncate the inode here */ - } - - DbgPrint("local_unlink: error=%d\n", error); - return error; -} -#endif diff -uNr src.old/novfs/file.c src/novfs/file.c --- src.old/novfs/file.c 2006-07-11 21:24:18.000000000 +0200 +++ src/novfs/file.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,2188 +0,0 @@ -/*++======================================================================== - * Program Name: Novell NCP Redirector for Linux - * File Name: file.c - * Version: v1.00 - * Author: James Turner - * - * Abstract: This module contains functions for accessing - * files through the daemon. - * Notes: - * Revision History: - * - * - * Copyright (C) 2005 Novell, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - *======================================================================--*/ - -/*===[ Include files specific to Linux ]==================================*/ -#include -#include -#include -#include -#include -#include -#include - -/*===[ Include files specific to this module ]============================*/ -#include "commands.h" -#include "nwerror.h" -#include "vfs.h" - -/*===[ External data ]====================================================*/ -extern struct dentry_operations Novfs_dentry_operations; - -/*===[ External prototypes ]==============================================*/ -extern int DbgPrint( char *Fmt, ... ); -extern void mydump(int size, void *dumpptr); -extern int Queue_Daemon_Command(void *request, u_long reqlen, void *data, int dlen, void **reply, u_long *replen, int interruptible); -extern struct inode *Novfs_get_inode(struct super_block *sb, int mode, int dev, uid_t uid); - -extern void *Scope_Lookup( void ); - -/*===[ Manifest constants ]===============================================*/ - -/*===[ Type definitions ]=================================================*/ - -/*===[ Function prototypes ]==============================================*/ - -int Novfs_verify_file( struct qstr *Path, session_t SessionId ); -int Novfs_get_alltrees(struct dentry *parent); -ssize_t Novfs_tree_read(struct file *file, char *buf, size_t len, loff_t *off); - -int Novfs_Get_Connected_Server_List( u_char **ServerList, session_t SessionId ); -int Novfs_Get_Server_Volume_List( struct qstr *Server, u_char **VolumeList, session_t SessionId ); -int Novfs_Find_Name_In_List( struct qstr *Name, u_char *List ); -int Novfs_Verify_Server_Name( struct qstr *Server, session_t SessionId ); -int Novfs_Verify_Volume_Name( struct qstr *Server, struct qstr *Volume, session_t SessionId ); -int Novfs_Get_File_Info( u_char *Path, PENTRY_INFO Info, session_t SessionId ); -int Novfs_Get_Directory_List( u_char *Path, u_long *EnumHandle, PENTRY_INFO Info, session_t SessionId ); -int Novfs_Get_Directory_ListEx( u_char *Path, u_long *EnumHandle, int *Count, PENTRY_INFO *Info, session_t SessionId ); -int Novfs_Open_File( u_char *Path, int Flags, PENTRY_INFO Info, u_long *Handle, session_t SessionId ); -int Novfs_Create( u_char *Path, int DirectoryFlag, session_t SessionId ); -int Novfs_Close_File( u_long Handle, session_t SessionId ); -int Novfs_Read_File( u_long Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, int User, session_t SessionId); -int Novfs_Write_File( u_long Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId); -int Novfs_Read_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, int User, session_t SessionId); -int Novfs_Write_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId); -int Novfs_Close_Stream( u_long ConnHandle, u_char *Handle, session_t SessionId ); -int Novfs_Delete( u_char *Path, int DirectoryFlag, session_t SessionId ); -int Novfs_Truncate_File( u_char *Path, int PathLen, session_t SessionId ); -int Novfs_Rename_File( int DirectoryFlag, u_char *OldName, int OldLen, u_char *NewName, int NewLen, session_t SessionId ); -int Novfs_Set_Attr( u_char *Path, struct iattr *Attr, session_t SessionId ); - -/*===[ Global variables ]=================================================*/ -static struct file_operations Novfs_tree_operations = { - read: Novfs_tree_read, -}; - -/* - * StripTrailingDots was added because some apps will - * try and create a file name with a trailing dot. NetWare - * doesn't like this and will return an error. - */ -u_char StripTrailingDots=1; - -/*===[ Code ]=============================================================*/ - -/*++======================================================================*/ -int Novfs_verify_file( struct qstr *Path, scope_t SessionId ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - PVERIFY_FILE_REPLY reply=NULL; - u_long replylen=0; - PVERIFY_FILE_REQUEST cmd; - int cmdlen; - int retCode=0; - - cmdlen = (int)(&((PVERIFY_FILE_REQUEST)0)->path) + Path->len; - cmd = (PVERIFY_FILE_REQUEST)Novfs_Malloc(cmdlen, GFP_KERNEL); - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_VERIFY_FILE; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = SessionId; - cmd->pathLen = Path->len; - memcpy(cmd->path, Path->name, Path->len); - - retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); - if ( reply ) - { - DbgPrint("Novfs_verify_file: reply\n"); - mydump(replylen, reply); - if (reply->Reply.ErrorCode) - { - retCode = -ENOENT; - } - else - { - retCode = 0; - } - Novfs_Free(reply); - } - Novfs_Free(cmd); - } - else - { - retCode = -ENOMEM; - } - return(retCode); -} - -/*++======================================================================*/ -int Novfs_get_alltrees(struct dentry *parent) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - u_char *p; - PCOMMAND_REPLY_HEADER reply=NULL; - u_long replylen=0; - COMMAND_REQUEST_HEADER cmd; - int retCode; - struct dentry *entry; - struct qstr name; - struct inode *inode; - - cmd.CommandType = 0; - cmd.SequenceNumber = 0; - cmd.SessionId = 0x1234; - - DbgPrint( "Novfs_get_alltrees:\n"); - - retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); - DbgPrint( "Novfs_get_alltrees: relpy=0x%x replylen=%d\n", reply, replylen); - if (reply) - { - mydump(replylen, reply); - if ( !reply->ErrorCode && (replylen > sizeof(COMMAND_REPLY_HEADER))) - { - p = (char *)reply+8; - while (*p) - { - DbgPrint( "Novfs_get_alltrees: %s\n",p); - name.len = strlen(p); - name.name = p; - name.hash = full_name_hash(name.name, name.len); - entry = d_lookup(parent, &name); - if ( NULL == entry ) - { - DbgPrint( "Novfs_get_alltrees: adding %s\n",p); - entry = d_alloc(parent, &name); - if (entry) - { - entry->d_op = &Novfs_dentry_operations; - inode = Novfs_get_inode(parent->d_sb, S_IFREG | 0400, 0, 0); - if (inode) - { - inode->i_fop = &Novfs_tree_operations; - d_add(entry, inode); - } - } - } - p += (name.len+1); - } - } - Novfs_Free(reply); - } - return(retCode); -} - -/*++======================================================================*/ -ssize_t Novfs_tree_read(struct file *file, char *buf, size_t len, loff_t *off) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - if (file->f_pos != 0) - { - return(0); - } - if (copy_to_user(buf, "Tree\n", 5)) - { - return(0); - } - return(5); -} - -/*++======================================================================*/ -int Novfs_Get_Connected_Server_List( u_char **ServerList, session_t SessionId ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - GET_CONNECTED_SERVER_LIST_REQUEST req; - PGET_CONNECTED_SERVER_LIST_REPLY reply=NULL; - u_long replylen=0; - int retCode=0; - - *ServerList = NULL; - - req.Command.CommandType = VFS_COMMAND_GET_CONNECTED_SERVER_LIST; - req.Command.SessionId = SessionId; - - retCode = Queue_Daemon_Command(&req, sizeof(req), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); - if ( reply ) - { - DbgPrint("Novfs_Get_Connected_Server_List: reply\n"); - replylen -= sizeof(COMMAND_REPLY_HEADER); - if ( !reply->Reply.ErrorCode && replylen ) - { - memcpy(reply, reply->List, replylen); - *ServerList = (u_char *)reply; - retCode = 0; - } - else - { - Novfs_Free(reply); - retCode = -ENOENT; - } - } - return(retCode); -} - -/*++======================================================================*/ -int Novfs_Get_Server_Volume_List( struct qstr *Server, u_char **VolumeList, scope_t SessionId ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - PGET_SERVER_VOLUME_LIST_REQUEST req; - PGET_SERVER_VOLUME_LIST_REPLY reply=NULL; - u_long replylen=0, reqlen; - int retCode; - - *VolumeList = NULL; - reqlen = sizeof(GET_SERVER_VOLUME_LIST_REQUEST)+Server->len; - req = Novfs_Malloc(reqlen, GFP_KERNEL); - if (req) - { - req->Command.CommandType = VFS_COMMAND_GET_SERVER_VOLUME_LIST; - req->Length = Server->len; - memcpy(req->Name, Server->name, Server->len); - req->Command.SessionId = SessionId; - - retCode = Queue_Daemon_Command(req, reqlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); - if ( reply ) - { - DbgPrint("Novfs_Get_Server_Volume_List: reply\n"); - mydump(replylen, reply); - replylen -= sizeof(COMMAND_REPLY_HEADER); - - if ( !reply->Reply.ErrorCode && replylen ) - { - memcpy(reply, reply->List, replylen); - *VolumeList = (u_char *)reply; - retCode = 0; - } - else - { - Novfs_Free(reply); - retCode = -ENOENT; - } - } - Novfs_Free(req); - } - else - { - retCode = -ENOMEM; - } - return(retCode); -} - -/*++======================================================================*/ -int Novfs_Find_Name_In_List( struct qstr *Name, u_char *List ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - int len; - int retCode = 0; - - while (*List) - { - len = strlen(List); - if ((len == Name->len) && !strncmp(Name->name, List, len)) - { - retCode = 1; - break; - } - List += (len+1); - } - return( retCode ); -} - -/*++======================================================================*/ -int Novfs_Verify_Server_Name( struct qstr *Server, session_t SessionId ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - u_char *list; - int retCode = 0; - - DbgPrint("Novfs_Verify_Server_Name: %.*s\n", Server->len, Server->name); - - list = NULL; - Novfs_Get_Connected_Server_List( &list, SessionId ); - - if (list) - { - retCode = Novfs_Find_Name_In_List( Server, list ); - Novfs_Free(list); - } - DbgPrint("Novfs_Verify_Server_Name: %d\n", retCode); - return(retCode); -} - -/*++======================================================================*/ -int Novfs_Verify_Volume_Name( struct qstr *Server, struct qstr *Volume, session_t SessionId ) -/* - * - * Arguments: Server - Server name. - * Volume - Volume name to check for. - * - * Returns: zero - not found. - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - u_char *list; - int retCode = 0; - u_char *name; - int namelen; - struct qstr path; - - list = NULL; - namelen = Server->len+Volume->len+2; - name = Novfs_Malloc(namelen, GFP_KERNEL); - - if (name) - { - name[0] = '\\'; - memcpy(&name[1], Server->name, Server->len); - name[1+Server->len] = '\\'; - memcpy(&name[2+Server->len], Volume->name, Volume->len); - path.len = namelen; - path.name = name; - - if (Novfs_verify_file(&path, SessionId)) - { - retCode = 0; - } - else - { - retCode = 1; - } - - Novfs_Free(name); - } - else - { - - Novfs_Get_Server_Volume_List( Server, &list, SessionId ); - - if (list) - { - retCode = Novfs_Find_Name_In_List( Volume, list ); - Novfs_Free(list); - } - } - return(retCode); -} - -/*++======================================================================*/ -int Novfs_Get_File_Info( u_char *Path, PENTRY_INFO Info, session_t SessionId ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - PVERIFY_FILE_REPLY reply=NULL; - u_long replylen=0; - PVERIFY_FILE_REQUEST cmd; - int cmdlen; - int retCode=-ENOENT; - int pathlen; - - DbgPrint("Novfs_Get_File_Info: Path = %s\n", Path); - - Info->mode = S_IFDIR | 0700; - Info->uid = current->uid; - Info->gid = current->gid; - Info->size = 0; - Info->atime = Info->mtime = Info->ctime = CURRENT_TIME; - - if (Path && *Path) - { - pathlen = strlen(Path); - if (StripTrailingDots) - { - if ('.' == Path[pathlen-1]) pathlen--; - } - cmdlen = (int)(&((PVERIFY_FILE_REQUEST)0)->path) + pathlen; - cmd = (PVERIFY_FILE_REQUEST)Novfs_Malloc(cmdlen, GFP_KERNEL); - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_VERIFY_FILE; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = SessionId; - cmd->pathLen = pathlen; - memcpy(cmd->path, Path, cmd->pathLen); - - retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); -/* - * retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, 0); - */ - if (reply) - { - - if ( reply->Reply.ErrorCode ) - { - retCode = -ENOENT; - } - else - { - Info->type = 3; - Info->mode = S_IRWXU; - - if (reply->fileMode & NW_ATTRIBUTE_DIRECTORY) - { - Info->mode |= S_IFDIR; - } - else - { - Info->mode |= S_IFREG; - } - - if (reply->fileMode & NW_ATTRIBUTE_READ_ONLY) - { - Info->mode &= ~(S_IWUSR); - } - - Info->uid = current->euid; - Info->gid = current->egid; - Info->size = reply->fileSize; - Info->atime.tv_sec = reply->lastAccessTime; - Info->atime.tv_nsec = 0; - Info->mtime.tv_sec = reply->modifyTime; - Info->mtime.tv_nsec = 0; - Info->ctime.tv_sec = reply->createTime; - Info->ctime.tv_nsec = 0; - retCode = 0; - } - - Novfs_Free(reply); - } - Novfs_Free(cmd); - } - } - - DbgPrint("Novfs_Get_File_Info: return 0x%x\n", retCode); - return(retCode); -} - -/*++======================================================================*/ -int Novfs_Get_File_Info2( u_char *Path, PENTRY_INFO Info, session_t SessionId ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - PVERIFY_FILE_REPLY reply=NULL; - u_long replylen=0; - PVERIFY_FILE_REQUEST cmd; - int cmdlen; - struct qstr server = {0}, volume = {0}; - u_char *p; - int i; - int retCode=-ENOENT; - p = Path; - - DbgPrint("Novfs_Get_File_Info: Path = %s\n", Path); - - Info->mode = S_IFDIR | 0700; - Info->uid = current->uid; - Info->gid = current->gid; - Info->size = 0; - Info->atime = Info->mtime = Info->ctime = CURRENT_TIME; - - if ('\\' == *p) - { - p++; - } - server.name = p; - - for(i=0; *p && ('\\' != *p); i++, p++); - server.len = i; - if (*p) - { - if ('\\' == *p) - { - p++; - } - volume.name = p; - for(i=0; *p && ('\\' != *p); i++, p++); - if (i) - { - volume.len = i; - if (*p) - { - if ('\\' == *p) - { - p++; - } - if (*p) - { - cmdlen = (int)(&((PVERIFY_FILE_REQUEST)0)->path) + strlen(Path); - cmd = (PVERIFY_FILE_REQUEST)Novfs_Malloc(cmdlen, GFP_KERNEL); - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_VERIFY_FILE; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = SessionId; - cmd->pathLen = strlen(Path); - memcpy(cmd->path, Path, cmd->pathLen); - - retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - - if ( reply->Reply.ErrorCode ) - { - retCode = -ENOENT; - } - else - { - Info->type = 3; - Info->mode = S_IRWXU; - - if (reply->fileMode & NW_ATTRIBUTE_DIRECTORY) - { - Info->mode |= S_IFDIR; - } - else - { - Info->mode |= S_IFREG; - } - - if (reply->fileMode & NW_ATTRIBUTE_READ_ONLY) - { - Info->mode &= ~(S_IWUSR); - } - - Info->uid = current->euid; - Info->gid = current->egid; - Info->size = reply->fileSize; - Info->atime.tv_sec = reply->lastAccessTime; - Info->atime.tv_nsec = 0; - Info->mtime.tv_sec = reply->modifyTime; - Info->mtime.tv_nsec = 0; - Info->ctime.tv_sec = reply->createTime; - Info->ctime.tv_nsec = 0; - retCode = 0; - } - - Novfs_Free(reply); - } - Novfs_Free(cmd); - } - } - } - } - if (('\0' == *p) && volume.len) - { - if ( Novfs_Verify_Volume_Name( &server, &volume, SessionId ) ) - { - retCode = 0; - Info->type = 2; - } - } - } - if (server.len && !volume.len) - { - if ( Novfs_Verify_Server_Name( &server, SessionId ) ) - { - retCode = 0; - Info->type = 1; - } - } - DbgPrint("Novfs_Get_File_Info: return 0x%x\n", retCode); - return(retCode); -} - -/*++======================================================================*/ -int begin_directory_enumerate( u_char *Path, int PathLen, u_long *EnumHandle, session_t SessionId) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - PBEGIN_ENUMERATE_DIRECTORY_REQUEST cmd; - PBEGIN_ENUMERATE_DIRECTORY_REPLY reply=NULL; - u_long replylen=0; - int retCode, cmdlen; - - *EnumHandle = 0; - - cmdlen = (int)(&((PBEGIN_ENUMERATE_DIRECTORY_REQUEST)0)->path) + PathLen; - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_START_ENUMERATE; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = SessionId; - - cmd->pathLen = PathLen; - memcpy(cmd->path, Path, PathLen); - - retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); -/* - * retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, 0); - */ - if (reply) - { - if (reply->Reply.ErrorCode) - { - retCode = -EIO; - } - else - { - *EnumHandle = reply->enumerateHandle; - retCode = 0; - } - Novfs_Free(reply); - } - Novfs_Free(cmd); - } - else - { - retCode = -ENOMEM; - } - return( retCode ); -} - -/*++======================================================================*/ -int end_directory_enumerate( u_long EnumHandle, session_t SessionId ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - END_ENUMERATE_DIRECTORY_REQUEST cmd; - PEND_ENUMERATE_DIRECTORY_REPLY reply=NULL; - u_long replylen=0; - int retCode; - - - cmd.Command.CommandType = VFS_COMMAND_END_ENUMERATE; - cmd.Command.SequenceNumber = 0; - cmd.Command.SessionId = SessionId; - - cmd.enumerateHandle = EnumHandle; - - retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, 0); - if (reply) - { - retCode = 0; - if (reply->Reply.ErrorCode) - { - retCode = -EIO; - } - Novfs_Free(reply); - } - - return( retCode ); -} - -/*++======================================================================*/ -int directory_enumerate( u_long *EnumHandle, PENTRY_INFO Info, session_t SessionId ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - ENUMERATE_DIRECTORY_REQUEST cmd; - PENUMERATE_DIRECTORY_REPLY reply=NULL; - u_long replylen=0; - int retCode; - - - cmd.Command.CommandType = VFS_COMMAND_ENUMERATE_DIRECTORY; - cmd.Command.SequenceNumber = 0; - cmd.Command.SessionId = SessionId; - - cmd.enumerateHandle = *EnumHandle; - cmd.pathLen = 0; - cmd.path[0] = '\0'; - - retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); - - if (reply) - { - /* - * The VFS_COMMAND_ENUMERATE_DIRECTORY call can return an - * error but there could still be valid data. - */ - if ( !reply->Reply.ErrorCode || - ( (replylen > sizeof(COMMAND_REPLY_HEADER)) && - (reply->nameLen > 0)) ) - { - Info->type = 3; - Info->mode = S_IRWXU; - - if (reply->mode & NW_ATTRIBUTE_DIRECTORY) - { - Info->mode |= S_IFDIR; - Info->mode |= S_IXUSR; - } - else - { - Info->mode |= S_IFREG; - } - - if (reply->mode & NW_ATTRIBUTE_READ_ONLY) - { - Info->mode &= ~(S_IWUSR); - } - - if (reply->mode & NW_ATTRIBUTE_EXECUTE) - { - Info->mode |= S_IXUSR; - } - - Info->uid = current->uid; - Info->gid = current->gid; - Info->size = reply->size; - Info->atime.tv_sec = reply->lastAccessTime; - Info->atime.tv_nsec = 0; - Info->mtime.tv_sec = reply->modifyTime; - Info->mtime.tv_nsec = 0; - Info->ctime.tv_sec = reply->createTime; - Info->ctime.tv_nsec = 0; - Info->namelength = reply->nameLen; - memcpy(Info->name, reply->name, reply->nameLen); - retCode = 0; - if (reply->Reply.ErrorCode) - { - retCode = -1; /* Eof of data */ - } - *EnumHandle = reply->enumerateHandle; - } - else - { - retCode = -ENODATA; - } - Novfs_Free(reply); - } - - return( retCode ); -} - -/*++======================================================================*/ -int directory_enumerate_ex( u_long *EnumHandle, session_t SessionId, int *Count, PENTRY_INFO *PInfo, int Interrupt) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - ENUMERATE_DIRECTORY_EX_REQUEST cmd; - PENUMERATE_DIRECTORY_EX_REPLY reply=NULL; - u_long replylen=0; - int retCode=0; - PENTRY_INFO info; - PENUMERATE_DIRECTORY_EX_DATA data; - int isize; - - if (PInfo) - { - *PInfo = NULL; - } - *Count = 0; - - cmd.Command.CommandType = VFS_COMMAND_ENUMERATE_DIRECTORY_EX; - cmd.Command.SequenceNumber = 0; - cmd.Command.SessionId = SessionId; - - cmd.enumerateHandle = *EnumHandle; - cmd.pathLen = 0; - cmd.path[0] = '\0'; - - retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, Interrupt); - - if (reply) - { - retCode = 0; - /* - * The VFS_COMMAND_ENUMERATE_DIRECTORY call can return an - * error but there could still be valid data. - */ - - if ( !reply->Reply.ErrorCode || - ( (replylen > sizeof(COMMAND_REPLY_HEADER)) && - (reply->enumCount > 0)) ) - { - DbgPrint("directory_enumerate_ex: isize=%d\n", replylen); - data = (PENUMERATE_DIRECTORY_EX_DATA)((char *)reply + sizeof(ENUMERATE_DIRECTORY_EX_REPLY)); - isize = replylen - - sizeof(PENUMERATE_DIRECTORY_EX_REPLY) - - reply->enumCount * (int)(&((PENUMERATE_DIRECTORY_EX_DATA)0)->name); - isize += (reply->enumCount * (int)(&((PENTRY_INFO)0)->name)); - - if (PInfo) - { - *PInfo = info = Novfs_Malloc(isize, GFP_KERNEL); - if ( *PInfo ) - { - DbgPrint("directory_enumerate_ex1: data=0x%p info=0x%p\n", data, info); - *Count = reply->enumCount; - do - { - DbgPrint("directory_enumerate_ex2: data=0x%p length=%d\n", data); - - info->type = 3; - info->mode = S_IRWXU; - - if (data->mode & NW_ATTRIBUTE_DIRECTORY) - { - info->mode |= S_IFDIR; - info->mode |= S_IXUSR; - } - else - { - info->mode |= S_IFREG; - } - - if (data->mode & NW_ATTRIBUTE_READ_ONLY) - { - info->mode &= ~(S_IWUSR); - } - - if (data->mode & NW_ATTRIBUTE_EXECUTE) - { - info->mode |= S_IXUSR; - } - - info->uid = current->euid; - info->gid = current->egid; - info->size = data->size; - info->atime.tv_sec = data->lastAccessTime; - info->atime.tv_nsec = 0; - info->mtime.tv_sec = data->modifyTime; - info->mtime.tv_nsec = 0; - info->ctime.tv_sec = data->createTime; - info->ctime.tv_nsec = 0; - info->namelength = data->nameLen; - memcpy(info->name, data->name, data->nameLen); - data = (PENUMERATE_DIRECTORY_EX_DATA)&data->name[data->nameLen]; - replylen = (int)((char *)&info->name[info->namelength] - (char *)info); - DbgPrint("directory_enumerate_ex3: info=0x%p\n", info); - mydump(replylen, info); - - info = (PENTRY_INFO)&info->name[info->namelength]; - - } while (--reply->enumCount); - } - } - - if (reply->Reply.ErrorCode) - { - retCode = -1; /* Eof of data */ - } - *EnumHandle = reply->enumerateHandle; - } - else - { - retCode = -ENODATA; - } - Novfs_Free(reply); - } - - return( retCode ); -} - -/*++======================================================================*/ -int Novfs_Get_Directory_List( u_char *Path, u_long *EnumHandle, PENTRY_INFO Info, session_t SessionId ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - int retCode = -ENOENT; - - if ( -1 == *EnumHandle) - { - return( -ENODATA ); - } - - if ( 0 == *EnumHandle ) - { - retCode = begin_directory_enumerate(Path, strlen(Path), EnumHandle, SessionId); - } - - if ( *EnumHandle ) - { - retCode = directory_enumerate( EnumHandle, Info, SessionId ); - if (retCode) - { - end_directory_enumerate( *EnumHandle, SessionId ); - if ( -1 == retCode ) - { - retCode = 0; - *EnumHandle = -1; - } - } - } - return(retCode); -} - -/*++======================================================================*/ -int Novfs_Get_Directory_ListEx( u_char *Path, u_long *EnumHandle, int *Count, PENTRY_INFO *Info, session_t SessionId ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - int retCode = -ENOENT; - - if (Count) *Count = 0; - if (Info) *Info = NULL; - - if ( -1 == *EnumHandle) - { - return( -ENODATA ); - } - - if ( 0 == *EnumHandle ) - { - retCode = begin_directory_enumerate(Path, strlen(Path), EnumHandle, SessionId); - } - - if ( *EnumHandle ) - { - retCode = directory_enumerate_ex( EnumHandle, SessionId, Count, Info, INTERRUPTIBLE ); - if (retCode) - { - end_directory_enumerate( *EnumHandle, SessionId ); - if ( -1 == retCode ) - { - retCode = 0; - *EnumHandle = -1; - } - } - } - return(retCode); -} - -/*++======================================================================*/ -int Novfs_Open_File( u_char *Path, int Flags, PENTRY_INFO Info, u_long *Handle, session_t SessionId ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - POPEN_FILE_REQUEST cmd; - POPEN_FILE_REPLY reply; - u_long replylen=0; - int retCode, cmdlen, pathlen; - - pathlen = strlen(Path); - - if (StripTrailingDots) - { - if ('.' == Path[pathlen-1]) pathlen--; - } - - cmdlen = (int)(&((POPEN_FILE_REQUEST)0)->path) + pathlen; - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_OPEN_FILE; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = SessionId; - - cmd->access = 0; - - if ( !(Flags & O_WRONLY) || (Flags & O_RDWR)) - { - cmd->access |= NWD_ACCESS_READ; - } - - if ((Flags & O_WRONLY) || (Flags & O_RDWR)) - { - cmd->access |= NWD_ACCESS_WRITE; - } - - switch (Flags & (O_CREAT | O_EXCL | O_TRUNC)) - { - case O_CREAT: - cmd->disp = NWD_DISP_OPEN_ALWAYS; - break; - - case O_CREAT | O_EXCL: - cmd->disp = NWD_DISP_CREATE_NEW; - break; - - case O_TRUNC: - cmd->disp = NWD_DISP_CREATE_ALWAYS; - break; - - case O_CREAT | O_TRUNC: - cmd->disp = NWD_DISP_CREATE_ALWAYS; - break; - - case O_CREAT | O_EXCL | O_TRUNC: - cmd->disp = NWD_DISP_CREATE_NEW; - break; - - default: - cmd->disp = NWD_DISP_OPEN_EXISTING; - break; - } - - cmd->mode = NWD_SHARE_READ | NWD_SHARE_WRITE | NWD_SHARE_DELETE; - - cmd->pathLen = pathlen; - memcpy(cmd->path, Path, pathlen); - - retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); - - if (reply) - { - if (reply->Reply.ErrorCode) - { - if( NWE_OBJECT_EXISTS == reply->Reply.ErrorCode) - { - retCode = -EEXIST; - } - else if( NWE_ACCESS_DENIED == reply->Reply.ErrorCode) - { - retCode = -EACCES; - } - else - { - retCode = -ENOENT; - } - } - else - { - *Handle = reply->handle; - retCode = 0; - } - Novfs_Free(reply); - } - Novfs_Free(cmd); - } - else - { - retCode = -ENOMEM; - } - return( retCode ); -} - -/*++======================================================================*/ -int Novfs_Create( u_char *Path, int DirectoryFlag, session_t SessionId ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - PCREATE_FILE_REQUEST cmd; - PCREATE_FILE_REPLY reply; - u_long replylen=0; - int retCode, cmdlen, pathlen; - - pathlen = strlen(Path); - - if (StripTrailingDots) - { - if ('.' == Path[pathlen-1]) pathlen--; - } - - cmdlen = (int)(&((PCREATE_FILE_REQUEST)0)->path) + pathlen; - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_CREATE_FILE; - if (DirectoryFlag) - { - cmd->Command.CommandType = VFS_COMMAND_CREATE_DIRECOTRY; - } - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = SessionId; - - cmd->pathlength = pathlen; - memcpy(cmd->path, Path, pathlen); - - retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); - - if (reply) - { - retCode = 0; - if (reply->Reply.ErrorCode) - { - retCode = -EIO; - } - Novfs_Free(reply); - } - Novfs_Free(cmd); - } - else - { - retCode = -ENOMEM; - } - return( retCode ); -} - -/*++======================================================================*/ -int Novfs_Close_File( u_long Handle, session_t SessionId ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - CLOSE_FILE_REQUEST cmd; - PCLOSE_FILE_REPLY reply; - u_long replylen=0; - int retCode; - - cmd.Command.CommandType = VFS_COMMAND_CLOSE_FILE; - cmd.Command.SequenceNumber = 0; - cmd.Command.SessionId = SessionId; - - cmd.handle = Handle; - - retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, 0); - if (reply) - { - retCode = 0; - if (reply->Reply.ErrorCode) - { - retCode = -EIO; - } - Novfs_Free(reply); - } - return( retCode ); -} - -/*++======================================================================*/ -int Novfs_Read_File( u_long Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, int User, session_t SessionId) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - READ_FILE_REQUEST cmd; - PREAD_FILE_REPLY reply=NULL; - u_long replylen=0; - int retCode = 0; - size_t len; - - len = *Bytes; - *Bytes = 0; - - if ( ((int)(&((PREAD_FILE_REPLY)0)->data) + len) > MAX_IO_SIZE) - { - len = MAX_IO_SIZE - (int)(&((PREAD_FILE_REPLY)0)->data); - len = (len/PAGE_SIZE)*PAGE_SIZE; - } - - cmd.Command.CommandType = VFS_COMMAND_READ_FILE; - cmd.Command.SequenceNumber = 0; - cmd.Command.SessionId = SessionId; - - cmd.handle = Handle; - cmd.len = len; - cmd.offset = *Offset; - - retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); - - DbgPrint("Novfs_Read_File: Queue_Daemon_Command 0x%x replylen=%d\n", retCode, replylen); - - if (!retCode) - { - if (reply->Reply.ErrorCode) - { - retCode = -EIO; - } - else - { - replylen -= (int)(&((PREAD_FILE_REPLY)0)->data); - if (replylen > 0) - { - if (User) - { - replylen -= copy_to_user(Buffer, reply->data, replylen); - } - else - { - memcpy(Buffer, reply->data, replylen); - } - - *Bytes = replylen; - } - } - } - - if ( reply ) - { - Novfs_Free(reply); - } - - DbgPrint("Novfs_Read_File *Bytes=0x%x retCode=0x%x\n", *Bytes, retCode); - - return( retCode ); -} - -/*++======================================================================*/ -int Novfs_Write_File( u_long Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - WRITE_FILE_REQUEST cmd; - PWRITE_FILE_REPLY reply=NULL; - unsigned long replylen=0; - int retCode=0, cmdlen; - size_t len; - - unsigned long boff; - struct page **pages; - DATA_LIST *dlist; - int res=0, npage, i; - WRITE_FILE_REPLY lreply; - - - len = *Bytes; - cmdlen = (int)(&((PWRITE_FILE_REQUEST)0)->data); - - *Bytes = 0; - - memset(&lreply, 0, sizeof(lreply)); - - DbgPrint("Novfs_Write_File cmdlen=%ld len=%ld\n", cmdlen, len); - - if ( (cmdlen+len) > MAX_IO_SIZE) - { - len = MAX_IO_SIZE-cmdlen; - len = (len/PAGE_SIZE)*PAGE_SIZE; - } - cmd.Command.CommandType = VFS_COMMAND_WRITE_FILE; - cmd.Command.SequenceNumber = 0; - cmd.Command.SessionId = SessionId; - cmd.handle = Handle; - cmd.len = len; - cmd.offset = *Offset; - - DbgPrint("Novfs_Write_File cmdlen=%ld len=%ld\n", cmdlen, len); - - npage = (((unsigned long)Buffer & ~PAGE_MASK) + len + (PAGE_SIZE-1)) >> PAGE_SHIFT; - - dlist = Novfs_Malloc(sizeof(DATA_LIST)*(npage+1), GFP_KERNEL); - if (NULL == dlist) - { - return(-ENOMEM); - } - - pages = Novfs_Malloc(sizeof(struct page *)*npage, GFP_KERNEL); - - if (NULL == pages) - { - Novfs_Free(dlist); - return(-ENOMEM); - } - - down_read(¤t->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(¤t->mm->mmap_sem); - - DbgPrint("Novfs_Write_File res=%d\n", res); - - if ( res > 0 ) - { - boff = (unsigned long)Buffer & ~PAGE_MASK; - - flush_dcache_page(pages[0]); - dlist[0].page = pages[0]; - dlist[0].offset = (char *)boff; - dlist[0].len = PAGE_SIZE - boff; - dlist[0].rwflag = DLREAD; - - if (dlist[0].len > len) - { - dlist[0].len = len; - } - - DbgPrint("Novfs_Write_File0: page=0x%x offset=0x%p len=%d\n", dlist[0].page, dlist[0].offset, dlist[0].len); - - boff = dlist[0].len; - - DbgPrint("Novfs_Write_File len=%d boff=%d\n", len, boff); - - for (i=1; (i < res) && (boff < len); i++) - { - flush_dcache_page(pages[i]); - - dlist[i].page = pages[i]; - dlist[i].offset = NULL; - dlist[i].len = len-boff; - if (dlist[i].len > PAGE_SIZE) - { - dlist[i].len = PAGE_SIZE; - } - dlist[i].rwflag = DLREAD; - - boff += dlist[i].len; - DbgPrint("Novfs_Write_File%d: page=0x%x offset=0x%p len=%d\n", i, dlist[i].page, dlist[i].offset, dlist[i].len); - } - - dlist[i].page = NULL; - dlist[i].offset = &lreply; - dlist[i].len = sizeof(lreply); - dlist[i].rwflag = DLWRITE; - res++; - - DbgPrint("Novfs_Write_File Buffer=0x%x boff=0x%x len=%d\n", Buffer, boff, len); - - retCode = Queue_Daemon_Command(&cmd, cmdlen, dlist, res, (void *)&reply, &replylen, INTERRUPTIBLE); - - } - else - { - char *kdata; - - res = 0; - - kdata = Novfs_Malloc(len, GFP_KERNEL); - if (kdata) - { - len -= copy_from_user(kdata, Buffer, len); - dlist[0].page = NULL; - dlist[0].offset = kdata; - dlist[0].len = len; - dlist[0].rwflag = DLREAD; - - dlist[1].page = NULL; - dlist[1].offset = &lreply; - dlist[1].len = sizeof(lreply); - dlist[1].rwflag = DLWRITE; - - retCode = Queue_Daemon_Command(&cmd, cmdlen, dlist, 2, (void *)&reply, &replylen, INTERRUPTIBLE); - - Novfs_Free(kdata); - } - } - - DbgPrint("Novfs_Write_File retCode=0x%x reply=0x%x\n", retCode, reply); - - if ( !retCode ) - { - switch (lreply.Reply.ErrorCode) - { - case 0: - *Bytes = (size_t)lreply.bytesWritten; - retCode = 0; - break; - - case NWE_INSUFFICIENT_SPACE: - retCode = -ENOSPC; - break; - - case NWE_ACCESS_DENIED: - retCode = -EACCES; - break; - - default: - retCode = -EIO; - break; - } - } - - if ( res ) - { - for (i=0; idata); - *Bytes = 0; - - if (cmdlen > MAX_IO_SIZE) - { - cmdlen = MAX_IO_SIZE; - len = cmdlen - (int)(&((PWRITE_FILE_REQUEST)0)->data); - } - - DbgPrint("Novfs_Write_File cmdlen=%d len=%d\n", cmdlen, len); - - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - - if (cmd) - { - len -= copy_from_user(cmd->data, Buffer, len); - DbgPrint("Novfs_Write_File len=%d\n", len); - if (len) - { - cmd->Command.CommandType = VFS_COMMAND_WRITE_FILE; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = SessionId; - - cmd->handle = Handle; - cmd->len = len; - cmd->offset = *Offset; - - retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); - if (!retCode) - { - if (reply) - { - switch (reply->Reply.ErrorCode) - { - case 0: - *Bytes = (size_t)reply->bytesWritten; - retCode = 0; - break; - - case NWE_INSUFFICIENT_SPACE: - retCode = -ENOSPC; - break; - - case NWE_ACCESS_DENIED: - retCode = -EACCES; - break; - - default: - retCode = -EIO; - break; - } - } - } - if ( reply ) - { - Novfs_Free(reply); - } - - } - Novfs_Free(cmd); - } - DbgPrint("Novfs_Write_File *Bytes=0x%x retCode=0x%x\n", *Bytes, retCode); - - return( retCode ); -} - -/*++======================================================================*/ -int Novfs_Read_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, int User, session_t SessionId) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - READ_STREAM_REQUEST cmd; - PREAD_STREAM_REPLY reply=NULL; - u_long replylen=0; - int retCode = 0; - size_t len; - - len = *Bytes; - *Bytes = 0; - - if ( ((int)(&((PREAD_FILE_REPLY)0)->data) + len) > MAX_IO_SIZE) - { - len = MAX_IO_SIZE - (int)(&((PREAD_FILE_REPLY)0)->data); - len = (len/PAGE_SIZE)*PAGE_SIZE; - } - - cmd.Command.CommandType = VFS_COMMAND_READ_STREAM; - cmd.Command.SequenceNumber = 0; - cmd.Command.SessionId = SessionId; - - cmd.connection = ConnHandle; - memcpy( cmd.handle, Handle, sizeof(cmd.handle)); - cmd.len = len; - cmd.offset = *Offset; - - retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); - - DbgPrint("Novfs_Read_Stream: Queue_Daemon_Command 0x%x replylen=%d\n", retCode, replylen); - - if ( reply ) - { - retCode = 0; - if (reply->Reply.ErrorCode) - { - retCode = -EIO; - } - else - { - replylen -= (int)(&((PREAD_STREAM_REPLY)0)->data); - if (replylen > 0) - { - if (User) - { - replylen -= copy_to_user(Buffer, reply->data, replylen); - } - else - { - memcpy(Buffer, reply->data, replylen); - } - - *Bytes = replylen; - } - } - Novfs_Free(reply); - } - - DbgPrint("Novfs_Read_Stream *Bytes=0x%x retCode=0x%x\n", *Bytes, retCode); - - return( retCode ); -} - -/*++======================================================================*/ -int Novfs_Write_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - PWRITE_STREAM_REQUEST cmd; - PWRITE_STREAM_REPLY reply=NULL; - u_long replylen=0; - int retCode=0, cmdlen; - size_t len; - - len = *Bytes; - cmdlen = len+(int)(&((PWRITE_STREAM_REQUEST)0)->data); - *Bytes = 0; - - if (cmdlen > MAX_IO_SIZE) - { - cmdlen = MAX_IO_SIZE; - len = cmdlen - (int)(&((PWRITE_STREAM_REQUEST)0)->data); - } - - DbgPrint("Novfs_Write_Stream cmdlen=%d len=%d\n", cmdlen, len); - - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - - if (cmd) - { - if (Buffer && len) - { - len -= copy_from_user(cmd->data, Buffer, len); - } - - DbgPrint("Novfs_Write_Stream len=%d\n", len); - - cmd->Command.CommandType = VFS_COMMAND_WRITE_STREAM; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = SessionId; - - cmd->connection = ConnHandle; - memcpy(cmd->handle, Handle, sizeof(cmd->handle)); - cmd->len = len; - cmd->offset = *Offset; - - retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - switch (reply->Reply.ErrorCode) - { - case 0: - retCode = 0; - break; - - case NWE_INSUFFICIENT_SPACE: - retCode = -ENOSPC; - break; - - case NWE_ACCESS_DENIED: - retCode = -EACCES; - break; - - default: - retCode = -EIO; - break; - } - DbgPrint("Novfs_Write_Stream reply->bytesWritten=0x%lx\n", reply->bytesWritten); - *Bytes = reply->bytesWritten; - Novfs_Free(reply); - } - Novfs_Free(cmd); - } - DbgPrint("Novfs_Write_Stream *Bytes=0x%x retCode=0x%x\n", *Bytes, retCode); - - return( retCode ); -} - -/*++======================================================================*/ -int Novfs_Close_Stream( u_long ConnHandle, u_char *Handle, session_t SessionId ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - CLOSE_STREAM_REQUEST cmd; - PCLOSE_STREAM_REPLY reply; - u_long replylen=0; - int retCode; - - cmd.Command.CommandType = VFS_COMMAND_CLOSE_STREAM; - cmd.Command.SequenceNumber = 0; - cmd.Command.SessionId = SessionId; - - cmd.connection = ConnHandle; - memcpy(cmd.handle, Handle, sizeof(cmd.handle)); - - retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, 0); - if (reply) - { - retCode = 0; - if (reply->Reply.ErrorCode) - { - retCode = -EIO; - } - Novfs_Free(reply); - } - return( retCode ); -} - -/*++======================================================================*/ -int Novfs_Delete( u_char *Path, int DirectoryFlag, session_t SessionId ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - PDELETE_FILE_REQUEST cmd; - PDELETE_FILE_REPLY reply; - u_long replylen=0; - int retCode, cmdlen, pathlen; - - pathlen = strlen(Path); - - if (StripTrailingDots) - { - if ('.' == Path[pathlen-1]) pathlen--; - } - - cmdlen = (int)(&((PDELETE_FILE_REQUEST)0)->path) + pathlen; - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_DELETE_FILE; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = SessionId; - - cmd->isDirectory = DirectoryFlag; - cmd->pathlength = pathlen; - memcpy(cmd->path, Path, pathlen); - - retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - retCode = 0; - if (reply->Reply.ErrorCode) - { - if ((reply->Reply.ErrorCode & 0xFFFF) == 0x0006) /* Access Denied Error */ - { - retCode = -EACCES; - } - else - { - retCode = -EIO; - } - } - Novfs_Free(reply); - } - Novfs_Free(cmd); - } - else - { - retCode = -ENOMEM; - } - return( retCode ); -} - -/*++======================================================================*/ -int Novfs_Truncate_File( u_char *Path, int PathLen, session_t SessionId ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - PTRUNCATE_FILE_REQUEST cmd; - PTRUNCATE_FILE_REPLY reply; - u_long replylen=0; - int retCode, cmdlen; - - if (StripTrailingDots) - { - if ('.' == Path[PathLen-1]) PathLen--; - } - cmdlen = (int)(&((PTRUNCATE_FILE_REQUEST)0)->path) + PathLen; - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_TRUNCATE_FILE; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = SessionId; - - cmd->pathLen = PathLen; - memcpy(cmd->path, Path, PathLen); - - retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - if (reply->Reply.ErrorCode) - { - retCode = -EIO; - } - Novfs_Free(reply); - } - Novfs_Free(cmd); - } - else - { - retCode = -ENOMEM; - } - return( retCode ); -} - -/*++======================================================================*/ -int Novfs_Rename_File( int DirectoryFlag, u_char *OldName, int OldLen, u_char *NewName, int NewLen, session_t SessionId ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - RENAME_FILE_REQUEST cmd; - PRENAME_FILE_REPLY reply; - u_long replylen=0; - int retCode; - - DbgPrint("Novfs_Rename_File:\n" \ - " DirectoryFlag: %d\n" \ - " OldName: %.*s\n" \ - " NewName: %.*s\n" \ - " SessionId: 0x%llx\n", - DirectoryFlag, - OldLen, OldName, - NewLen, NewName, - SessionId ); - - cmd.Command.CommandType = VFS_COMMAND_RENAME_FILE; - cmd.Command.SequenceNumber = 0; - cmd.Command.SessionId = SessionId; - - cmd.directoryFlag = DirectoryFlag; - - if (StripTrailingDots) - { - if ('.' == OldName[OldLen-1]) OldLen--; - if ('.' == NewName[NewLen-1]) NewLen--; - } - - cmd.newnameLen = NewLen; - memcpy(cmd.newname, NewName, NewLen); - - cmd.oldnameLen = OldLen; - memcpy(cmd.oldname, OldName, OldLen); - - retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - retCode = 0; - if (reply->Reply.ErrorCode) - { - retCode = -ENOENT; - } - Novfs_Free(reply); - } - return( retCode ); -} - -/*++======================================================================*/ -int Novfs_Set_Attr( u_char *Path, struct iattr *Attr, session_t SessionId ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - PSET_FILE_INFO_REQUEST cmd; - PSET_FILE_INFO_REPLY reply; - u_long replylen=0; - int retCode, cmdlen, pathlen; - - pathlen = strlen(Path); - - if (StripTrailingDots) - { - if ('.' == Path[pathlen-1]) pathlen--; - } - - cmdlen = (int)(&((PSET_FILE_INFO_REQUEST)0)->path) + pathlen; - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_SET_FILE_INFO; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = SessionId; - cmd->fileInfo.ia_valid = Attr->ia_valid; - cmd->fileInfo.ia_mode = Attr->ia_mode; - cmd->fileInfo.ia_uid = Attr->ia_uid; - cmd->fileInfo.ia_gid = Attr->ia_uid; - cmd->fileInfo.ia_size = Attr->ia_size; - cmd->fileInfo.ia_atime = Attr->ia_atime.tv_sec; - cmd->fileInfo.ia_mtime = Attr->ia_mtime.tv_sec;; - cmd->fileInfo.ia_ctime = Attr->ia_ctime.tv_sec;; -/* - cmd->fileInfo.ia_attr_flags = Attr->ia_attr_flags; -*/ - cmd->fileInfo.ia_attr_flags = 0; - - cmd->pathlength = pathlen; - memcpy(cmd->path, Path, pathlen); - - retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - switch( reply->Reply.ErrorCode ) - { - case 0: - retCode = 0; - break; - - case NWE_PARAM_INVALID: - retCode = -EINVAL; - break; - - default: - retCode = -EIO; - break; - } - Novfs_Free(reply); - } - Novfs_Free(cmd); - } - else - { - retCode = -ENOMEM; - } - return( retCode ); -} diff -uNr src.old/novfs/inode.c src/novfs/inode.c --- src.old/novfs/inode.c 2006-07-11 21:24:18.000000000 +0200 +++ src/novfs/inode.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,4584 +0,0 @@ -/*++======================================================================== - * Program Name: Novell NCP Redirector for Linux - * File Name: inode.c - * Version: v1.00 - * Author: James Turner - * - * Abstract: This module contains functions used to control - * access to the Linux file system. - * Notes: - * Revision History: - * - * - * Copyright (C) 2005 Novell, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - *======================================================================--*/ - -/*===[ Include files specific to Linux ]==================================*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/*===[ Include files specific to this module ]============================*/ -#include "vfs.h" - -/*===[ External data ]====================================================*/ - -/*===[ External prototypes ]==============================================*/ -extern int DbgPrint( char *Fmt, ... ); -extern int LocalPrint( char *Fmt, ... ); - -extern int Init_Procfs_Interface( void ); -extern void Uninit_Procfs_Interface( void ); -extern void mydump(int size, void *dumpptr); - -/* - * Daemon.c functions - */ -extern void Init_Daemon_Queue( void ); -extern void Uninit_Daemon_Queue( void ); -extern int do_logout( struct qstr *Server ); -extern int Daemon_SetMountPoint( char *Path ); - -/* - * file.c functions - */ -extern int Novfs_verify_file( struct qstr *Path, session_t SessionId ); -extern int Novfs_get_alltrees(struct dentry *parent); -extern int Novfs_Get_Connected_Server_List( unsigned char **ServerList, session_t SessionId ); -extern int Novfs_Get_Server_Volume_List( struct qstr *Server, unsigned char **VolumeList, session_t SessionId ); -extern int Novfs_Verify_Server_Name( struct qstr *Server, session_t SessionId ); -extern int Novfs_Verify_Volume_Name( struct qstr *Server, struct qstr *Volume, session_t SessionId ); -extern int Novfs_Get_File_Info( unsigned char *Path, PENTRY_INFO Info, session_t SessionId ); -extern int Novfs_Get_Directory_List( unsigned char *Path, unsigned long *EnumHandle, PENTRY_INFO Info, session_t SessionId ); -extern int Novfs_Get_Directory_ListEx( unsigned char *Path, unsigned long *EnumHandle, int *Count, PENTRY_INFO *Info, session_t SessionId ); -extern int Novfs_Open_File( unsigned char *Path, int Flags, PENTRY_INFO Info, unsigned long *Handle, session_t SessionId ); -extern int Novfs_Create( unsigned char *Path, int DirectoryFlag, session_t SessionId ); -extern int Novfs_Close_File( unsigned long Handle, session_t SessionId ); -extern int Novfs_Read_File( unsigned long Handle, unsigned char *Buffer, size_t *Bytes, loff_t *Offset, int User, session_t SessionId); -extern int Novfs_Write_File( unsigned long Handle, unsigned char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId); -extern int Novfs_Delete( unsigned char *Path, int DirectoryFlag, session_t SessionId ); -extern int Novfs_Truncate_File( unsigned char *Path, int PathLen, session_t SessionId ); -extern int Novfs_Rename_File( int DirectoryFlag, unsigned char *OldName, int OldLen, unsigned char *NewName, int NewLen, session_t SessionId ); -extern int Novfs_Set_Attr( unsigned char *Path, struct iattr *Attr, session_t SessionId ); - -/* - * scope.c functions - */ -extern void Scope_Init( void ); -extern void Scope_Uninit( void ); -extern void *Scope_Lookup( void ); -extern unsigned long Scope_Get_Hash( void *); -extern uid_t Scope_Get_Uid( void *); -extern session_t Scope_Get_SessionId( void *Scope ); -extern void *Scope_Get_ScopefromName( struct qstr *Name ); -extern void *Scope_Get_ScopefromPath( struct dentry *Dentry ); -extern char *Scope_Get_ScopeUsers( void ); -extern int Scope_Set_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties ); -extern int Scope_Get_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties ); -extern char *Scope_dget_path( struct dentry *Dentry, char *Buf, unsigned int Buflen, int Flags); - -/* - * profile.c functions - */ -extern int init_profile( void ); - -/*===[ Manifest constants ]===============================================*/ -#define FILE_UPDATE_TIMEOUT 2 - -/*===[ Type definitions ]=================================================*/ - -/*===[ Function prototypes ]==============================================*/ -int Novfs_Remove_from_Root(char *RemoveName); -int Novfs_Add_to_Root(char *); -char *Novfs_dget_path( struct dentry *d, char *path, unsigned int pathlen ); -int verify_dentry(struct dentry *dentry, int Flags); -int invalidate_dentry(struct dentry *parent); -struct dentry *Novfs_d_lookup(struct dentry *Parent, struct qstr *Name); -int Novfs_d_add(struct dentry *p, struct dentry *d, struct inode *i, int add); -int Novfs_d_strcmp (struct qstr *s1, struct qstr *s2); -struct inode *Novfs_get_inode(struct super_block *sb, int mode, int dev, uid_t uid, ino_t ino, struct qstr *name); -unsigned long Novfs_internal_hash (struct qstr *name); - -struct super_block *Novfs_get_sb (struct file_system_type *Fstype, int Flags, const char *Dev_name, void *Data); -void Novfs_kill_sb(struct super_block *SB); -int Novfs_fill_super (struct super_block *SB, void *Data, int Silent); - -/* - * Declared dentry_operations - */ -int Novfs_d_revalidate(struct dentry *, struct nameidata *); -int Novfs_d_hash (struct dentry *, struct qstr *); -int Novfs_d_compare (struct dentry *, struct qstr *, struct qstr *); -int Novfs_d_delete(struct dentry *dentry); -void Novfs_d_release(struct dentry *dentry); -void Novfs_d_iput(struct dentry *dentry, struct inode *inode); - -/* - * Declared directory operations - */ -int Novfs_dir_open(struct inode *inode, struct file *file); -int Novfs_dir_release(struct inode *inode, struct file *file); -loff_t Novfs_dir_lseek(struct file *file, loff_t offset, int origin); -int Novfs_dir_read(struct file *file, char *buf, size_t len, loff_t *off); -void addtodentry( struct dentry *Parent, unsigned char *List, int Level ); -int Novfs_filldir(void *data, const char *name, int namelen, loff_t off, ino_t ino, unsigned ftype); -int Novfs_dir_readdir(struct file * filp, void * dirent, filldir_t filldir); -int Novfs_dir_fsync(struct file * file, struct dentry *dentry, int datasync); - -/* - * Declared address space operations - */ -int Novfs_a_readpage(struct file *file, struct page *page); - -/* - * Declared file_operations - */ -ssize_t Novfs_f_read(struct file *, char *, size_t, loff_t *); -ssize_t Novfs_f_write(struct file *, const char *, size_t, loff_t *); -int Novfs_f_readdir(struct file *, void *, filldir_t); -int Novfs_f_ioctl(struct inode *, struct file *, unsigned int, unsigned long); -int Novfs_f_mmap(struct file * file, struct vm_area_struct * vma); -int Novfs_f_open(struct inode *, struct file *); -int Novfs_f_flush(struct file *); -int Novfs_f_release(struct inode *, struct file *); -int Novfs_f_fsync(struct file *, struct dentry *, int datasync); -int Novfs_f_lock(struct file *, int, struct file_lock *); - -/* - * Declared inode_operations - */ -int Novfs_i_create(struct inode *,struct dentry *,int, struct nameidata *); -struct dentry * Novfs_i_lookup(struct inode *,struct dentry *, struct nameidata *); -int Novfs_i_mkdir(struct inode *,struct dentry *,int); -int Novfs_i_unlink(struct inode *dir, struct dentry *dentry); -int Novfs_i_rmdir(struct inode *,struct dentry *); -int Novfs_i_mknod(struct inode *,struct dentry *,int,dev_t); -int Novfs_i_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); -int Novfs_i_permission(struct inode *inode, int mask); -int Novfs_i_setattr(struct dentry *, struct iattr *); -int Novfs_i_getattr(struct vfsmount *mnt, struct dentry *, struct kstat *); -int Novfs_i_revalidate(struct dentry *dentry); - -void update_inode(struct inode *Inode, PENTRY_INFO Info); - -/* - * Declared super_operations - */ -void Novfs_read_inode(struct inode *inode); -void Novfs_write_inode(struct inode *inode); -int Novfs_notify_change(struct dentry *dentry, struct iattr *attr); -void Novfs_clear_inode(struct inode *inode); -int Novfs_show_options( struct seq_file *s, struct vfsmount *m ); -int Novfs_statfs(struct super_block *sb, struct kstatfs *buf); - -/* - * Declared control interface functions - */ -ssize_t -Novfs_Control_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos); - -ssize_t -Novfs_Control_write(struct file * file, const char * buf, size_t nbytes, loff_t *ppos); - -int Novfs_Control_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); - -int __init init_novfs(void); -void __exit exit_novfs(void); - -int Novfs_lock_inode_cache( struct inode *i ); -void Novfs_unlock_inode_cache( struct inode *i ); -int Novfs_enumerate_inode_cache( struct inode *i, struct list_head **iteration, ino_t *ino, PENTRY_INFO info); -int Novfs_get_entry( struct inode *i, struct qstr *name, ino_t *ino, PENTRY_INFO info); -int Novfs_get_entry_time( struct inode *i, struct qstr *name, ino_t *ino, PENTRY_INFO info, u64 *EntryTime); -int Novfs_get_remove_entry( struct inode *i, ino_t *ino, PENTRY_INFO info); -void Novfs_invalidate_inode_cache( struct inode *i ); -PDIR_CACHE Novfs_lookup_inode_cache( struct inode *i, struct qstr *name, ino_t ino ); -int Novfs_lookup_validate( struct inode *i, struct qstr *name, ino_t ino ); -int Novfs_add_inode_entry( struct inode *i, struct qstr *name, ino_t ino, PENTRY_INFO info); -int Novfs_update_entry( struct inode *i, struct qstr *name, ino_t ino, PENTRY_INFO info); -void Novfs_remove_inode_entry( struct inode *i, struct qstr *name, ino_t ino); -void Novfs_free_invalid_entries( struct inode *i ); -void Novfs_free_inode_cache( struct inode *i ); - -/*===[ Global variables ]=================================================*/ -struct dentry_operations Novfs_dentry_operations = { - .d_revalidate = Novfs_d_revalidate, - .d_hash = Novfs_d_hash, - .d_compare = Novfs_d_compare, - .d_delete = Novfs_d_delete, - .d_release = Novfs_d_release, - .d_iput = Novfs_d_iput, -}; - -struct file_operations Novfs_dir_operations = { - .open = Novfs_dir_open, - .release = Novfs_dir_release, - .llseek = Novfs_dir_lseek, - .read = Novfs_dir_read, - .readdir = Novfs_dir_readdir, - .fsync = Novfs_dir_fsync, -}; - -static struct file_operations Novfs_file_operations = { - .read = Novfs_f_read, - .write = Novfs_f_write, - .readdir = Novfs_f_readdir, - .ioctl = Novfs_f_ioctl, - .mmap = Novfs_f_mmap, - .open = Novfs_f_open, - .release = Novfs_f_release, - .fsync = Novfs_f_fsync, - .llseek = generic_file_llseek, -}; - -static struct address_space_operations Novfs_aops = { - .readpage = Novfs_a_readpage, -}; - -static struct inode_operations Novfs_inode_operations = { - .create = Novfs_i_create, - .lookup = Novfs_i_lookup, - .unlink = Novfs_i_unlink, - .mkdir = Novfs_i_mkdir, - .rmdir = Novfs_i_rmdir, - .mknod = Novfs_i_mknod, - .rename = Novfs_i_rename, - .setattr = Novfs_i_setattr, - .getattr = Novfs_i_getattr, -}; - -static struct inode_operations Novfs_file_inode_operations = { - .setattr = Novfs_i_setattr, - .getattr = Novfs_i_getattr, -}; - -static struct super_operations Novfs_ops = { - .read_inode = Novfs_read_inode, - .statfs = Novfs_statfs, - .clear_inode = Novfs_clear_inode, - .drop_inode = generic_delete_inode, - .show_options = Novfs_show_options, - -}; - -/* Not currently used -static struct file_operations Novfs_Control_operations = { - .read = Novfs_Control_read, - .write = Novfs_Control_write, - .ioctl = Novfs_Control_ioctl, -}; -*/ - -ino_t Novfs_Inode_Number=1; - -static struct file_system_type Novfs_fs_type = { - .name = "novfs", - .get_sb = Novfs_get_sb, - .kill_sb = Novfs_kill_sb, - .owner = THIS_MODULE, -}; - -struct dentry *Novfs_root=NULL; - -int Novfs_Version_Major=NOVFS_VFS_MAJOR; -int Novfs_Version_Minor=NOVFS_VFS_MINOR; -int Novfs_Version_Sub=NOVFS_VFS_SUB; -int Novfs_Version_Release=NOVFS_VFS_RELEASE; - -char *Novfs_CurrentMount=NULL; - -DECLARE_MUTEX(InodeList_lock); - -LIST_HEAD(InodeList); - -unsigned long InodeCount=0, DCCount=0; -unsigned long File_update_timeout=FILE_UPDATE_TIMEOUT; -/*===[ Code ]=============================================================*/ -static __inline__ void PRINT_DENTRY(const char *s, struct dentry *d) -{ - DbgPrint("%s: 0x%x\n", s, d); - DbgPrint(" d_count: 0x%x\n", d->d_count); - DbgPrint(" d_lock: 0x%x\n", d->d_lock); - DbgPrint(" d_inode: 0x%x\n", d->d_inode); - DbgPrint(" d_lru: 0x%x\n" \ - " next: 0x%x\n" \ - " prev: 0x%x\n", &d->d_lru, d->d_lru.next, d->d_lru.prev); - DbgPrint(" d_child: 0x%x\n" \ - " next: 0x%x\n" \ - " prev: 0x%x\n", &d->D_CHILD, d->D_CHILD.next, d->D_CHILD.prev); - DbgPrint(" d_subdirs: 0x%x\n" \ - " next: 0x%x\n" \ - " prev: 0x%x\n", &d->d_subdirs, d->d_subdirs.next, d->d_subdirs.prev); - DbgPrint(" d_alias: 0x%x\n" \ - " next: 0x%x\n" \ - " prev: 0x%x\n", &d->d_alias, d->d_alias.next, d->d_alias.prev); - DbgPrint(" d_time: 0x%x\n", d->d_time); - DbgPrint(" d_op: 0x%x\n", d->d_op); - DbgPrint(" d_sb: 0x%x\n", d->d_sb); - DbgPrint(" d_flags: 0x%x\n", d->d_flags); - DbgPrint(" d_mounted: 0x%x\n", d->d_mounted); - DbgPrint(" d_fsdata: 0x%x\n", d->d_fsdata); -/* DbgPrint(" d_cookie: 0x%x\n", d->d_cookie); */ - DbgPrint(" d_parent: 0x%x\n", d->d_parent); - DbgPrint(" d_name: 0x%x %.*s\n", &d->d_name, d->d_name.len, d->d_name.name); - DbgPrint(" name: 0x%x\n" \ - " len: %d\n" \ - " hash: 0x%x\n", d->d_name.name, d->d_name.len, d->d_name.hash); - DbgPrint(" d_hash: 0x%x\n" \ - " next: 0x%x\n" \ - " pprev: 0x%x\n", d->d_hash, d->d_hash.next, d->d_hash.pprev); -} - -/*++======================================================================*/ -int Novfs_Remove_from_Root(char *RemoveName) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - struct qstr name; - struct dentry *dentry; - struct inode *dir; - - DbgPrint( "Novfs_Remove_from_Root: %s\n", RemoveName); - name.len = strlen(RemoveName); - name.name = RemoveName; - Novfs_d_hash(Novfs_root, &name); - - dentry = d_lookup( Novfs_root, &name); - if (dentry) - { - if (dentry->d_inode && dentry->d_inode->u.generic_ip) - { - ((PINODE_DATA)(dentry->d_inode->u.generic_ip))->Scope = NULL; - } - dput(dentry); - } - - - dir = Novfs_root->d_inode; - - Novfs_lock_inode_cache( dir ); - Novfs_remove_inode_entry( dir, &name, 0); - Novfs_unlock_inode_cache( dir ); - - return(0); -} - -/*++======================================================================*/ -int Novfs_Add_to_Root(char *AddName) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - struct qstr name; - struct inode *dir; - ENTRY_INFO info; - ino_t ino; - - DbgPrint( "Novfs_Add_to_Root: %s\n", AddName); - name.len = strlen(AddName); - name.name = AddName; - Novfs_d_hash(Novfs_root, &name); - - dir = Novfs_root->d_inode; - - Novfs_lock_inode_cache( dir ); - - ino = 0; - - if ( !Novfs_lookup_inode_cache(dir, &name, 0)) - { - info.mode = S_IFDIR | 0700; - info.size = 0; - info.atime = info.ctime = info.mtime = CURRENT_TIME; - - ino = (ino_t)InterlockedIncrement(&Novfs_Inode_Number); - Novfs_add_inode_entry( dir, &name, ino, &info); - } - - Novfs_unlock_inode_cache( dir ); - - return(0); -} - -/*++======================================================================*/ -int Novfs_Add_to_Root2(char *AddName) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - struct dentry *entry; - struct qstr name; - struct inode *inode; - void *scope; - - DbgPrint( "Novfs_Add_to_Root: %s\n", AddName); - name.len = strlen(AddName); - name.name = AddName; - - Novfs_d_hash(Novfs_root, &name); - - entry = Novfs_d_lookup(Novfs_root, &name); - DbgPrint( "Novfs_Add_to_Root: Novfs_d_lookup 0x%x\n", entry); - if ( NULL == entry ) - { - scope = Scope_Lookup(); - - entry = d_alloc(Novfs_root, &name); - DbgPrint( "Novfs_Add_to_Root: d_alloc 0x%x\n", entry ); - if (entry) - { - entry->d_op = &Novfs_dentry_operations; - entry->d_time = jiffies+(File_update_timeout*HZ); - /* - * done in Novfs_d_add now... entry->d_fsdata = (void *)Novfs_internal_hash( &name ); - */ - inode = Novfs_get_inode(Novfs_root->d_sb, S_IFDIR | 0700, 0, Scope_Get_Uid(scope), 0, &name); - DbgPrint( "Novfs_Add_to_Root: Inode=0x%x\n", inode); - if (inode) - { - inode->i_atime = - inode->i_ctime = - inode->i_mtime = CURRENT_TIME; - if ( !Novfs_d_add(Novfs_root, entry, inode, 1)) - { - if (inode->u.generic_ip) - { - ((PINODE_DATA)inode->u.generic_ip)->Flags = USER_INODE; - } - PRINT_DENTRY("After Novfs_d_add", entry); - } - else - { - dput(entry); - iput(inode); - } - } - } - } - else - { - dput(entry); - PRINT_DENTRY("Novfs_Add_to_Root: After dput Dentry", entry); - } - return(0); -} - -/*++======================================================================*/ -char *Novfs_dget_path( struct dentry *Dentry, char *Buf, unsigned int Buflen) -/* - * Arguments: struct dentry *Dentry - starting entry - * char *Buf - pointer to memory buffer - * unsigned int Buflen - size of memory buffer - * - * Returns: pointer to path. - * - * Abstract: Walks the dentry chain building a path. - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - char *retval=&Buf[Buflen]; - struct dentry *p=Dentry; - - *(--retval) = '\0'; - Buflen--; - - if (!IS_ROOT(p) && !IS_ROOT(p->d_parent)) - { - while (Buflen && !IS_ROOT(p) && !IS_ROOT(p->d_parent)) - { - if (Buflen > p->d_name.len) - { - retval -= p->d_name.len; - Buflen -= p->d_name.len; - memcpy(retval, p->d_name.name, p->d_name.len); - *(--retval) = '\\'; - Buflen--; - p = p->d_parent; - } - else - { - retval = NULL; - break; - } - } - } - else - { - *(--retval) = '\\'; - } - - - -if (retval) DbgPrint("Novfs_dget_path: %s\n", retval); - return(retval); -} - -/*++======================================================================*/ -int verify_dentry( struct dentry *dentry, int Flags ) -/* - * Arguments: struct dentry *dentry - entry to verify - * - * Returns: zero - Inode cache has been updated. If not in the cache - * then file doesn't exist. - * !zero - Error - * - * Abstract: This routine will verify if the file that dentry is pointing - * at exist and if it does it will put it in the inode cache of - * the parent. - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - int retVal = -ENOENT; - struct inode *dir; - PENTRY_INFO info=NULL; - PINODE_DATA id; - session_t session; - char *path, *list=NULL, *cp; - ino_t ino; - struct qstr name; - int iLock=0; - struct dentry *parent=NULL; - u64 ctime; - struct inode *inode; - - if ( IS_ROOT(dentry) ) - { - DbgPrint("verify_dentry: Root entry\n"); - return( 0 ); - } - - if ( dentry && dentry->d_parent && - (dir = dentry->d_parent->d_inode) && - (id = dir->u.generic_ip) ) - { - parent = dget_parent(dentry); - - info = Novfs_Malloc(sizeof(ENTRY_INFO)+PATH_LENGTH_BUFFER, GFP_KERNEL); - - if (info) - { - if (Novfs_lock_inode_cache( dir )) - { - name.len = dentry->d_name.len; - name.name = dentry->d_name.name; - name.hash = Novfs_internal_hash( &name ); - if ( !Novfs_get_entry_time(dir, &name, &ino, info, &ctime)) - { - inode = dentry->d_inode; - if ( inode && - ( (inode->i_size != info->size) || - (inode->i_mtime.tv_sec != info->mtime.tv_sec) )) - { - ((PINODE_DATA)inode->u.generic_ip)->Flags |= UPDATE_INODE; - } - - ctime = get_jiffies_64() - ctime; - if ( Flags || ctime < (u64)(File_update_timeout*HZ) ) - { - retVal = 0; - Novfs_unlock_inode_cache(dir); - dput(parent); - Novfs_Free(info); - return(0); - } - } - Novfs_unlock_inode_cache(dir); - } - - if ( IS_ROOT(dentry->d_parent) ) - { - session = Scope_Get_SessionId(Scope_Get_ScopefromName(&dentry->d_name)); - } - else - { - session = Scope_Get_SessionId( id->Scope ); - } - - if ( !session ) - { - id->Scope = Scope_Get_ScopefromPath(dentry); - session = Scope_Get_SessionId( id->Scope ); - } - - ino = 0; - retVal = 0; - - if ( IS_ROOT(dentry->d_parent) ) - { - DbgPrint("verify_dentry: parent is Root directory\n"); - list = Scope_Get_ScopeUsers(); - - iLock = Novfs_lock_inode_cache( dir ); - Novfs_invalidate_inode_cache( dir ); - - if ( list ) - { - cp = list; - while (*cp) - { - name.name = cp; - name.len = strlen(cp); - name.hash = Novfs_internal_hash( &name ); - cp += (name.len+1); - ino = 0; - if ( Novfs_get_entry( dir, &name, &ino, info ) ) - { - info->mode = S_IFDIR | 0700; - info->size = 0; - info->atime = info->ctime = info->mtime = CURRENT_TIME; - ino = (ino_t)InterlockedIncrement(&Novfs_Inode_Number); - Novfs_add_inode_entry(dir, &name, ino, info); - } - } - } - Novfs_free_invalid_entries( dir ); - } - else - { - - path = Novfs_dget_path(dentry, info->name, PATH_LENGTH_BUFFER); - if (path) - { - if (dentry->d_name.len <= NW_MAX_PATH_LENGTH) - { - name.hash = Novfs_internal_hash(&dentry->d_name); - name.len = dentry->d_name.len; - name.name = dentry->d_name.name; - - - - retVal = Novfs_Get_File_Info( path, info, session ); - if ( 0 == retVal) - { - dentry->d_time = jiffies+(File_update_timeout*HZ); - iLock = Novfs_lock_inode_cache( dir ); - if ( Novfs_update_entry( dir, &name, 0, info ) ) - { - if (dentry->d_inode) - { - ino = dentry->d_inode->i_ino; - } - else - { - ino = (ino_t)InterlockedIncrement(&Novfs_Inode_Number); - } - Novfs_add_inode_entry( dir, &name, ino, info); - } - if ( dentry->d_inode ) - { - update_inode(dentry->d_inode, info); - id->Flags &= ~UPDATE_INODE; - - dentry->d_inode->i_flags &= ~S_DEAD; - if (dentry->d_inode->u.generic_ip) - { - ((PINODE_DATA)dentry->d_inode->u.generic_ip)->Scope = id->Scope; - } - } - } - else if (-EINTR != retVal) - { - retVal = 0; - iLock = Novfs_lock_inode_cache( dir ); - Novfs_remove_inode_entry( dir, &name, 0 ); - if ( dentry->d_inode && !(dentry->d_inode->i_flags & S_DEAD) ) - { - dentry->d_inode->i_flags |= S_DEAD; - dentry->d_inode->i_size = 0; - dentry->d_inode->i_atime.tv_sec = - dentry->d_inode->i_atime.tv_nsec = - dentry->d_inode->i_ctime.tv_sec = - dentry->d_inode->i_ctime.tv_nsec = - dentry->d_inode->i_mtime.tv_sec = - dentry->d_inode->i_mtime.tv_nsec = 0; - dentry->d_inode->i_blocks = 0; - d_delete(dentry); /* Remove from cache */ - } - } - } - else - { - retVal = -ENAMETOOLONG; - } - } - } - } - else - { - retVal = -ENOMEM; - } - if (iLock) - { - Novfs_unlock_inode_cache( dir ); - } - dput(parent); - } - - if (list) Novfs_Free(list); - if (info) Novfs_Free(info); - - DbgPrint("verify_dentry: return=0x%x\n", retVal); - - return(retVal); -} - -/*++======================================================================*/ -struct dentry *Novfs_d_lookup(struct dentry *Parent, struct qstr *Name) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - return( d_lookup( Parent, Name)); -} - -/*++======================================================================*/ -int Novfs_d_add(struct dentry *Parent, struct dentry *d, struct inode *i, int a) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - void *scope; - PINODE_DATA id=NULL; - - char *path, *buf; - - buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); - if (buf) - { - path = Novfs_dget_path(d, buf, PATH_LENGTH_BUFFER); - if (path) - { - DbgPrint("Novfs_d_add: inode=0x%p ino=%d path %s\n", i, i->i_ino, path); - } - Novfs_Free(buf); - } - - if ( Parent && Parent->d_inode && Parent->d_inode->u.generic_ip) - { - id = (PINODE_DATA)Parent->d_inode->u.generic_ip; - } - - if (id && id->Scope) - { - scope = id->Scope; - } - else - { - scope = Scope_Get_ScopefromPath( d ); - } - - ((PINODE_DATA)i->u.generic_ip)->Scope = scope; - - d->d_time = jiffies+(File_update_timeout*HZ); - if (a) - { - d_add(d, i); - } - else - { - d_instantiate(d, i); - } - - return(0); -} - -/*++======================================================================*/ -int Novfs_d_revalidate(struct dentry *dentry, struct nameidata *nd) -/* - * Arguments: struct dentry *dentry - pointer to dentry to revalidate. - * struct nameidata *nd - pointer to nameidata. - * - * Returns: zero - dentry is not valid. - * !zero - valid entry - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - int retCode = 0; - struct inode *dir; - PINODE_DATA id; - struct qstr name; - - UNUSED_VARIABLE( nd ); - - DbgPrint("Novfs_d_revalidate: 0x%p %.*s\n" \ - " d_count: %d\n" \ - " d_inode: 0x%p\n", - dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_count, dentry->d_inode); - - if (IS_ROOT( dentry )) - { - retCode = 1; - } - else - { - if ( dentry->d_inode && - dentry->d_parent && - (dir = dentry->d_parent->d_inode) && - (id = dir->u.generic_ip) ) - { - /* - * Check timer to see if in valid time limit - */ - if (jiffies > dentry->d_time) - { - /* - * Revalidate entry - */ - name.len = dentry->d_name.len; - name.name = dentry->d_name.name; - name.hash = Novfs_internal_hash(&dentry->d_name); - dentry->d_time = 0; - - if ( 0 == verify_dentry( dentry, 0 )) - { - if (Novfs_lock_inode_cache( dir )) - { - if (Novfs_lookup_inode_cache( dir, &name, 0)) - { - dentry->d_time = jiffies + (File_update_timeout*HZ); - retCode = 1; - } - Novfs_unlock_inode_cache( dir ); - } - } - } - else - { - retCode = 1; - } - } - } - - - if ( ( 0 == retCode ) && dentry->d_inode ) - { - /* - * Entry has become invalid - */ -/* dput(dentry); -*/ - } - - DbgPrint("Novfs_d_revalidate: return 0x%x\n", retCode); - - return(retCode); -} - -/*++======================================================================*/ -unsigned long Novfs_internal_hash (struct qstr *name) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - unsigned long hash = 0; - unsigned int len = name->len; - unsigned char *c = (unsigned char *)name->name; - - while(len--) - { - /* - * Lower case values for the hash. - */ - hash = partial_name_hash(tolower(*c++), hash); - } - - return(hash); -} - -/*++======================================================================*/ -int Novfs_d_hash (struct dentry *dentry, struct qstr *name) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - UNUSED_VARIABLE( dentry ); - - DbgPrint("Novfs_d_hash: %.*s\n", name->len, name->name); - - name->hash = Novfs_internal_hash( name ); - - return(0); -} - -/*++======================================================================*/ -int Novfs_d_strcmp (struct qstr *s1, struct qstr *s2) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - int retCode = 1; - unsigned char *str1, *str2; - unsigned int len; - - DbgPrint("Novfs_d_strcmp: s1=%.*s s2=%.*s\n", s1->len, s1->name, s2->len, s2->name); - - if (s1->len && (s1->len == s2->len) && (s1->hash == s2->hash) ) - { - len = s1->len; - str1 = (unsigned char *)s1->name; - str2 = (unsigned char *)s2->name; - for ( retCode = 0; len-- ; str1++, str2++ ) - { - if (*str1 != *str2) - { - if (tolower(*str1) != tolower(*str2)) - { - retCode = 1; - break; - } - } - } - } - - DbgPrint("Novfs_d_strcmp: retCode=0x%x\n", retCode); - return(retCode); -} - -/*++======================================================================*/ -int Novfs_d_compare (struct dentry *parent, struct qstr *s1, struct qstr *s2) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - int retCode; - - retCode = Novfs_d_strcmp(s1, s2); - - DbgPrint("Novfs_d_compare: retCode=0x%x\n", retCode); - return(retCode); -} - -/*++======================================================================*/ -int Novfs_d_delete(struct dentry *dentry) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - int retVal = 0; - - DbgPrint("Novfs_d_delete: 0x%p %.*s\n" \ - " d_count: %d\n" \ - " d_inode: 0x%p\n", - dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_count, dentry->d_inode); - - if (dentry->d_inode && (dentry->d_inode->i_flags & S_DEAD)) - { - retVal = 1; - } - - dentry->d_time = 0; - - return( retVal ); -} - -/*++======================================================================*/ -void Novfs_d_release(struct dentry *dentry) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - DbgPrint("Novfs_d_release: 0x%x %.*s\n", dentry, dentry->d_name.len, dentry->d_name.name); -} - -/*++======================================================================*/ -void Novfs_d_iput(struct dentry *dentry, struct inode *inode) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - DbgPrint("Novfs_d_iput: Inode=0x%x Ino=%d Dentry=0x%x Name=%.*s\n", - inode, inode->i_ino, dentry, dentry->d_name.len, dentry->d_name.name); - - iput(inode); - -} -/*++======================================================================*/ -int Novfs_dir_open(struct inode *dir, struct file *file) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - char *path, *buf; - - - DbgPrint("Novfs_dir_open: Inode 0x%x %d Name %.*s\n", dir, dir->i_ino, file->f_dentry->d_name.len, file->f_dentry->d_name.name); - - buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); - if (buf) - { - path = Novfs_dget_path(file->f_dentry, buf, PATH_LENGTH_BUFFER); - if (path) - { - DbgPrint("Novfs_dir_open: path %s\n", path); - } - Novfs_Free(buf); - } - file->private_data = NULL; - return(0); -} - -/*++======================================================================*/ -int Novfs_dir_release(struct inode *dir, struct file *file) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - struct inode *inode; - - DbgPrint("Novfs_dir_release: Inode 0x%x %d Name %.*s\n", dir, dir->i_ino, file->f_dentry->d_name.len, file->f_dentry->d_name.name); - if (file->private_data) - { - inode = file->private_data; - Novfs_free_inode_cache( inode ); - Novfs_Free(file->private_data); - } - - return(0); -} - -/*++======================================================================*/ -loff_t Novfs_dir_lseek(struct file *file, loff_t offset, int origin) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - return(dcache_dir_lseek(file, offset, origin)); -} - -/*++======================================================================*/ -int Novfs_dir_read(struct file *file, char *buf, size_t len, loff_t *off) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ -/* - int rlen = 0; - - DbgPrint("Novfs_dir_readdir: dentry path %.*s buf=0x%p len=%d off=%lld\n", file->f_dentry->d_name.len, file->f_dentry->d_name.name, buf, len, *off); - - if (0 == *off) - { - rlen = 8; - rlen -= copy_to_user(buf, "Testing\n", 8); - *off += rlen; - } - return(rlen); -*/ - return(generic_read_dir(file, buf, len, off)); -} - -/*++======================================================================*/ -void process_list(struct file *File, char *List, int Type, PENTRY_INFO Info, session_t SessionId) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - unsigned char *path, *buf=NULL, *cp; - struct inode *dir = File->f_dentry->d_inode; - struct qstr name; - ino_t ino=0; - - buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); - path = buf; - if (buf) - { - path = Novfs_dget_path(File->f_dentry, buf, PATH_LENGTH_BUFFER); - if (path) - { - strcpy(buf, path); - } - path = buf+strlen(buf); - *path++ = '\\'; - } - - if ( List ) - { - cp = List; - while (*cp) - { - name.name = cp; - name.len = strlen(cp); - name.hash = Novfs_internal_hash( &name ); - cp += (name.len+1); - - Info->mode = S_IFDIR | 0700; - Info->size = 0; - Info->atime = Info->ctime = Info->mtime = CURRENT_TIME; - - if ( (USER_LIST != Type) && buf && ((int)(path-buf)+name.len < PATH_LENGTH_BUFFER) ) - { - strcpy(path, name.name); - Novfs_Get_File_Info(buf, Info, SessionId); - } - - if ( Novfs_update_entry( dir, &name, ino, Info ) ) - { - Novfs_add_inode_entry(dir, &name, (ino_t)InterlockedIncrement(&Novfs_Inode_Number), Info); - } - } - } - - if (buf) Novfs_Free(buf); - -} - -/*++======================================================================*/ -int Novfs_dir_readdir(struct file * file, void * dirent, filldir_t filldir) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - unsigned char *path, *buf=NULL; - unsigned char *list=NULL; - PENTRY_INFO info=NULL, pinfo, iinfo; - int count; - - int status = -ENOMEM; - struct inode *inode; - session_t sessionId; - uid_t uid; - struct qstr name; - struct list_head *inter; - ino_t ino; - int iLock=0; - int type = 0; - - DbgPrint("Novfs_dir_readdir(%s): dentry path %.*s 0x%x\n", current->comm, file->f_dentry->d_name.len, file->f_dentry->d_name.name, file->f_dentry->d_fsdata); - - inode = file->f_dentry->d_inode; - - info = Novfs_Malloc(sizeof(ENTRY_INFO)+PATH_LENGTH_BUFFER, GFP_KERNEL); - if (info) - { - if (file->f_pos) - { - if (file->private_data) - { - inode = file->private_data; - while( !Novfs_get_remove_entry(inode, &ino, info) ) - { - DbgPrint("Calling filedir-2 %llu with ino %d mode 0%o name %s\n", file->f_pos, ino, info->mode, info->name); - if ( filldir(dirent, info->name, info->namelength, file->f_pos, ino, info->mode >> 12) < 0 ) - { - /* - * put entry back on the list. - */ - name.len = info->namelength; - name.name = info->name; - name.hash = Novfs_internal_hash( &name ); - Novfs_add_inode_entry(inode, &name, ino, info); - - break; - } - file->f_pos++; - } - } - Novfs_Free(info); - return(0); - } - - if ( inode && inode->u.generic_ip ) - { - sessionId = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope); - if (0 == sessionId) - { - ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath(file->f_dentry); - sessionId = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope); - } - uid = Scope_Get_Uid(((PINODE_DATA)inode->u.generic_ip)->Scope); - } - else - { - sessionId = 0; - uid = current->euid; - } - - if ( IS_ROOT(file->f_dentry) || /* Root */ - IS_ROOT(file->f_dentry->d_parent) || /* User */ - IS_ROOT(file->f_dentry->d_parent->d_parent) ) /* Server */ - { - if ( IS_ROOT(file->f_dentry) ) - { - DbgPrint("Novfs_dir_readdir: Root directory\n"); - list = Scope_Get_ScopeUsers(); - type = USER_LIST; - - } else if ( IS_ROOT(file->f_dentry->d_parent) ) - { - DbgPrint("Novfs_dir_readdir: Parent is Root directory\n"); - Novfs_Get_Connected_Server_List( &list, sessionId ); - type = SERVER_LIST; - } - else - { - DbgPrint("Novfs_dir_readdir: Parent-Parent is Root directory\n"); - Novfs_Get_Server_Volume_List(&file->f_dentry->d_name, &list, sessionId); - type = VOLUME_LIST; - } - - iLock = Novfs_lock_inode_cache( inode ); - Novfs_invalidate_inode_cache( inode ); - - process_list(file, list, type, info, sessionId); - } - else - { - DbgPrint("Novfs_dir_readdir: Default directory\n"); - buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); - if (buf) - { - path = Novfs_dget_path(file->f_dentry, buf, PATH_LENGTH_BUFFER); - if (path) - { - unsigned long enumHandle=0; - - iLock = Novfs_lock_inode_cache( inode ); - Novfs_invalidate_inode_cache(inode); - - do - { - /* - * Novfs_Get_Directory_List will return 0 when no error or -1 when - * the last entry is returned. Otherwise it will return an error. - */ - info->namelength = 0; - status = Novfs_Get_Directory_ListEx(path, &enumHandle, &count, &pinfo, sessionId); - DbgPrint("Novfs_dir_readdir: Novfs_Get_Directory_List return 0x%x count=%d pinfo=0x%p\n", status, count, pinfo); - iinfo = pinfo; - while ( (0 == status) && pinfo && count-- ) - { - memcpy(info, pinfo, (int)((char *)&pinfo->name[pinfo->namelength]-(char *)pinfo)); - pinfo = (PENTRY_INFO)&pinfo->name[pinfo->namelength]; - name.len = info->namelength; - name.name = info->name; - name.hash = Novfs_internal_hash(&name); - info->name[name.len] = '\0'; - - DbgPrint("Novfs_dir_readdir: Got %s\n", name.name); - - if ( Novfs_update_entry( inode, &name, 0, info )) - { - Novfs_add_inode_entry(inode, &name, (ino_t)InterlockedIncrement(&Novfs_Inode_Number), info); - } - } - - if (iinfo) - { - Novfs_Free(iinfo); - } - - } while ( !status ); - } - } - } - - if ( iLock ) - { - Novfs_free_invalid_entries( inode ); - } - - switch ((int) file->f_pos) - { - case 0: - DbgPrint("Calling filedir %llu with ino %d name .\n", file->f_pos, inode->i_ino); - if (filldir(dirent, ".", 1, file->f_pos, inode->i_ino, DT_DIR) < 0) - { - break; - } - file->f_pos++; - /* fallthrough */ - case 1: - DbgPrint("Calling filedir %llu with ino %d name ..\n", file->f_pos, parent_ino(file->f_dentry)); - if (filldir(dirent, "..", 2, file->f_pos, parent_ino(file->f_dentry), DT_DIR) < 0) - { - break; - } - file->f_pos++; - /* fallthrough */ - - default: - status = 0; - inter = NULL; - - if ( iLock ) - { - while( !Novfs_enumerate_inode_cache(inode, &inter, &ino, info) ) - { - DbgPrint("Calling filedir %llu with ino %d mode 0%o name %s\n", file->f_pos, ino, info->mode, info->name); - if ( filldir(dirent, info->name, info->namelength, file->f_pos, ino, info->mode >> 12) < 0 ) - { - /* - * Get the rest of the entries and put them in a fake - * inode cache. - */ - file->private_data = (PDIR_CACHE)Novfs_Malloc(sizeof(struct inode) + sizeof(DIR_CACHE), GFP_KERNEL); - if (file->private_data) - { - struct inode *dinode = file->private_data; - PINODE_DATA id = (PINODE_DATA)((char *)file->private_data+sizeof(struct inode)); - - dinode->u.generic_ip = id; - - id->Scope = ((PINODE_DATA)inode->u.generic_ip)->Scope; - id->Flags = 0; - INIT_LIST_HEAD( &id->DirCache ); - init_MUTEX( &id->DirCacheLock ); - - /* - * Copy rest of the files. - */ - do - { - name.len = info->namelength; - name.name = info->name; - name.hash = Novfs_internal_hash( &name ); - Novfs_add_inode_entry(dinode, &name, ino, info); - } while( !Novfs_enumerate_inode_cache(inode, &inter, &ino, info) ); - } - - break; - } - file->f_pos++; - } - } - - } - - if (iLock) - { - Novfs_unlock_inode_cache(inode); - } - } - - if (info) Novfs_Free( info ); - if (buf) Novfs_Free( buf ); - if (list) Novfs_Free( list ); - - return(status); -} - - -/*++======================================================================*/ -int Novfs_dir_fsync(struct file * file, struct dentry *dentry, int datasync) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - return(simple_sync_file(file, dentry, datasync)); -} - -/*++======================================================================*/ -int do_open(struct file *file) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - PENTRY_INFO info=NULL; - int retCode = -ENOENT; - session_t session; - char *path; - struct dentry *parent; - struct inode *inode; - PINODE_DATA id; - - inode = file->f_dentry->d_inode; - - if (inode && inode->u.generic_ip) - { - id = (PINODE_DATA)file->f_dentry->d_inode->u.generic_ip; - session = Scope_Get_SessionId(id->Scope); - if (0 == session) - { - id->Scope = Scope_Get_ScopefromPath( file->f_dentry ); - session = Scope_Get_SessionId(id->Scope); - } - - retCode = -ENOMEM; - info = (PENTRY_INFO)Novfs_Malloc(sizeof(ENTRY_INFO) + PATH_LENGTH_BUFFER, GFP_KERNEL); - if (info) - { - path = Novfs_dget_path(file->f_dentry, info->name, PATH_LENGTH_BUFFER); - if (path) - { - DbgPrint("do_open: %s\n", path); - - retCode = Novfs_Open_File( - path, - file->f_flags & ~O_EXCL, info, - (unsigned long *)&file->private_data, - session); - DbgPrint("do_open: 0x%x 0x%x\n", retCode, file->private_data); - if ( !retCode ) - { - if( !Novfs_Get_File_Info(path, info, session)) - { - update_inode(inode, info); - } - - parent = dget_parent(file->f_dentry); - - if (parent && parent->d_inode) - { - struct inode *dir = parent->d_inode; - Novfs_lock_inode_cache(dir); - if (Novfs_update_entry(dir, &file->f_dentry->d_name, 0, info)) - { - Novfs_add_inode_entry(dir, &file->f_dentry->d_name, inode->i_ino, info); - } - - Novfs_unlock_inode_cache(dir); - } - dput(parent); - } - } - Novfs_Free(info); - } - } - - return(retCode); -} - -/*++======================================================================*/ -ssize_t Novfs_f_read(struct file *file, char *buf, size_t len, loff_t *off) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - size_t thisread, totalread=0; - loff_t offset = *off; - struct inode *inode; - session_t session; - - if (file->f_dentry && file->f_dentry->d_inode && file->f_dentry->d_inode->u.generic_ip) - { - DbgPrint("Novfs_f_read(0x%x 0x%p %d %lld %.*s)\n", (unsigned long)file->private_data, buf, len, offset, file->f_dentry->d_name.len, file->f_dentry->d_name.name); - - if ( !file->private_data ) - { - totalread = (size_t)do_open( file ); - if (totalread) - { - return(totalread); - } - } - - inode = file->f_dentry->d_inode; - - session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope); - if (0 == session) - { - ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( file->f_dentry ); - session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope); - } - - while(len > 0 && (offset < inode->i_size) ) - { - thisread = len; - if (Novfs_Read_File((unsigned long)file->private_data, buf, &thisread, &offset, 1, session) || !thisread) - { - break; - } - DbgPrint("Novfs_f_read thisread = 0x%x\n", thisread); - len -= thisread; - buf += thisread; - offset += thisread; - totalread += thisread; - } - } - *off = offset; - DbgPrint("Novfs_f_read return = 0x%x\n", totalread); - - return(totalread); -} - -/*++======================================================================*/ -ssize_t Novfs_f_write(struct file *file, const char *buf, size_t len, loff_t *off) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - size_t thiswrite, totalwrite=0; - loff_t offset = *off; - session_t session; - struct inode *inode; - int status; - - if (file->f_dentry && file->f_dentry->d_inode && file->f_dentry->d_inode->u.generic_ip) - { - inode = file->f_dentry->d_inode; - - if ( !file->private_data ) - { - totalwrite = (size_t)do_open( file ); - if (totalwrite) - { - return(totalwrite); - } - } - - DbgPrint("Novfs_f_write(0x%x %d %lld %.*s)\n", (unsigned long)file->private_data, len, offset, file->f_dentry->d_name.len, file->f_dentry->d_name.name); - - if (file->f_flags & O_APPEND) { - offset = inode->i_size; - DbgPrint("Novfs_f_write appending to end %lld %.*s\n", offset, file->f_dentry->d_name.len, file->f_dentry->d_name.name); - } - - - session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope); - if (0 == session) - { - ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( file->f_dentry ); - session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope); - } - - while(len > 0) - { - thiswrite = len; - if ((status = Novfs_Write_File( - (unsigned long)file->private_data, - (unsigned char *)buf, - &thiswrite, - &offset, - session)) || !thiswrite) - { - totalwrite = status; - break; - } - DbgPrint("Novfs_f_write thiswrite = 0x%x\n", thiswrite); - len -= thiswrite; - buf += thiswrite; - offset += thiswrite; - totalwrite += thiswrite; - if (offset > inode->i_size) - { - inode->i_size = offset; - inode->i_blocks = (offset + inode->i_blksize - 1) >> inode->i_blkbits; - } - inode->i_mtime = inode->i_atime = CURRENT_TIME; - ((PINODE_DATA)inode->u.generic_ip)->Flags |= UPDATE_INODE; - - } - } - *off = offset; - DbgPrint("Novfs_f_write return = 0x%x\n", totalwrite); - - return(totalwrite); -} - -/*++======================================================================*/ -int Novfs_f_readdir(struct file *file, void *data, filldir_t fill) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - UNUSED_VARIABLE(file); - UNUSED_VARIABLE(data); - UNUSED_VARIABLE(fill); - return(-EISDIR); -} - -/*++======================================================================*/ -int Novfs_f_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - UNUSED_VARIABLE(inode); - UNUSED_VARIABLE(file); - UNUSED_VARIABLE(cmd); - UNUSED_VARIABLE(arg); - DbgPrint("Novfs_f_ioctl: file=0x%x cmd=0x%x arg=0x%x", file, cmd, arg); - - return(-ENOSYS); -} - -/*++======================================================================*/ -int Novfs_f_mmap(struct file * file, struct vm_area_struct * vma) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - int retCode = -EINVAL; - - DbgPrint("Novfs_f_mmap: file=0x%x", file); - - retCode = generic_file_mmap(file, vma); - - DbgPrint("Novfs_f_mmap: retCode=0x%x\n", retCode); - return( retCode ); -} - -/*++======================================================================*/ -int Novfs_f_open2(struct inode *inode, struct file *file) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - int retCode; - - DbgPrint("Novfs_f_open: inode=0x%p file=0x%p dentry=0x%p dentry->d_inode=0x%p\n", inode, file, file->f_dentry, file->f_dentry->d_inode); - if (file->f_dentry) - { - DbgPrint("Novfs_f_open: %.*s f_flags=0%o f_mode=0%o i_mode=0%o\n", file->f_dentry->d_name.len, file->f_dentry->d_name.name, file->f_flags, file->f_mode, inode->i_mode); - } - retCode = do_open(file); - - DbgPrint("Novfs_f_open: retCode=0x%x\n", retCode); - - return( retCode ); -} - -/*++======================================================================*/ -int Novfs_f_open(struct inode *inode, struct file *file) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - PENTRY_INFO info=NULL; - int retCode = -ENOENT; - session_t session; - char *path; - struct dentry *parent; - PINODE_DATA id; - - DbgPrint("Novfs_f_open: inode=0x%p file=0x%p dentry=0x%p dentry->d_inode=0x%p\n", inode, file, file->f_dentry, file->f_dentry->d_inode); - if (file->f_dentry) - { - DbgPrint("Novfs_f_open: %.*s f_flags=0%o f_mode=0%o i_mode=0%o\n", file->f_dentry->d_name.len, file->f_dentry->d_name.name, file->f_flags, file->f_mode, inode->i_mode); - } - - if (inode && inode->u.generic_ip) - { - id = (PINODE_DATA)file->f_dentry->d_inode->u.generic_ip; - session = Scope_Get_SessionId(id->Scope); - if (0 == session) - { - id->Scope = Scope_Get_ScopefromPath( file->f_dentry ); - session = Scope_Get_SessionId(id->Scope); - } - - info = (PENTRY_INFO)Novfs_Malloc(sizeof(ENTRY_INFO) + PATH_LENGTH_BUFFER, GFP_KERNEL); - if (info) - { - path = Novfs_dget_path(file->f_dentry, info->name, PATH_LENGTH_BUFFER); - if (path) - { - DbgPrint("Novfs_f_open: %s\n", path); - - - retCode = Novfs_Get_File_Info(path, info, session); - if ( !retCode ) - { - if ( (O_TRUNC & file->f_flags) && S_ISREG(info->mode) && info->size ) - { - if (!Novfs_Truncate_File(path, strlen(path), session)) - { - info->size = 0; - } - } - - /* - * Update inode info. - */ - update_inode(inode, info); - - file->private_data = NULL; - - parent = dget_parent(file->f_dentry); - - if (parent && parent->d_inode) - { - struct inode *dir = parent->d_inode; - Novfs_lock_inode_cache(dir); - if (Novfs_update_entry(dir, &file->f_dentry->d_name, 0, info)) - { - Novfs_add_inode_entry(dir, &file->f_dentry->d_name, inode->i_ino, info); - } - - Novfs_unlock_inode_cache(dir); - } - dput(parent); - - if ( S_ISDIR(info->mode) ) - { - retCode = -EISDIR; - } - } - else - { - if ( O_CREAT & file->f_flags ) - { - retCode = do_open(file); - if (file->private_data) - { - Novfs_f_release(file->f_dentry->d_inode, file); - file->private_data = NULL; - } - } - } - } - Novfs_Free(info); - } - } - DbgPrint("Novfs_f_open: retCode=0x%x\n", retCode); - return( retCode ); -} - -/*++======================================================================*/ -int Novfs_f_flush(struct file *file) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - struct inode *inode; - - UNUSED_VARIABLE(file); - if (file->f_dentry) - { - inode = file->f_dentry->d_inode; - DbgPrint("Novfs_f_flush: %.*s f_flags=0x%x f_mode=0%o i_mode=0%o\n", file->f_dentry->d_name.len, file->f_dentry->d_name.name, file->f_flags, file->f_mode, inode->i_mode); - } - return(0); -} - -/*++======================================================================*/ -int Novfs_f_release(struct inode *inode, struct file *file) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - int retCode = -EACCES; - session_t session; - PINODE_DATA id; - - DbgPrint("Novfs_f_release: path=%.*s handle=0x%x inode=0x%p\n", - file->f_dentry->d_name.len, - file->f_dentry->d_name.name, - (unsigned long)file->private_data, file->f_dentry->d_inode); - - if ( file->f_dentry->d_inode && (id = file->f_dentry->d_inode->u.generic_ip)) - { - if (file->private_data) - { - session = Scope_Get_SessionId(id->Scope); - if (0 == session) - { - id->Scope = Scope_Get_ScopefromPath( file->f_dentry ); - session = Scope_Get_SessionId(id->Scope); - } - - //invalidate_remote_inode(file->f_dentry->d_inode); - - retCode = Novfs_Close_File((unsigned long)file->private_data, session); - file->private_data = NULL; - } - else - { - retCode = 0; - } - } - return(retCode); -} - -/*++======================================================================*/ -int Novfs_f_fsync(struct file *file, struct dentry *dentry, int datasync) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - UNUSED_VARIABLE(file); - UNUSED_VARIABLE(dentry); - UNUSED_VARIABLE(datasync); - return(0); -} - -/*++======================================================================*/ -int Novfs_f_llseek(struct file *file, loff_t offset, int origin) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - DbgPrint("Novfs_f_llseek: File=0x%x Name=%.*s offset=%lld origin=%d\n", file, file->f_dentry->d_name.len, file->f_dentry->d_name.name, offset, origin); - return(generic_file_llseek(file, offset, origin)); -} - -/*++======================================================================*/ -int Novfs_f_lock(struct file *file, int cmd, struct file_lock *lock) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - UNUSED_VARIABLE(file); - UNUSED_VARIABLE(cmd); - UNUSED_VARIABLE(lock); - return(-ENOSYS); -} - -/*++======================================================================*/ -int Novfs_a_readpage(struct file *file, struct page *page) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - int retCode = 0; - void *pbuf; - struct inode *inode=NULL; - struct dentry *dentry=NULL; - loff_t offset; - size_t len; - session_t session=0; - - DbgPrint("Novfs_a_readpage: File=0x%x Name=%.*s Page=0x%x", file, file->f_dentry->d_name.len, file->f_dentry->d_name.name, page); - - dentry = file->f_dentry; - - if (dentry) - { - DbgPrint(" Dentry=0x%x Name=%.*s", dentry, dentry->d_name.len, dentry->d_name.name); - if (dentry->d_inode) - { - inode = dentry->d_inode; - } - } - - - - if (inode) - { - DbgPrint(" Inode=0x%x Ino=%d", inode, inode->i_ino); - - if (inode->u.generic_ip) - { - session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope); - if (0 == session) - { - ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( file->f_dentry ); - session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope); - } - } - } - - DbgPrint("\n"); - - if ( !file->private_data ) - { - retCode = (size_t)do_open( file ); - } - - if (file->private_data && !PageUptodate(page)) - { - pbuf = kmap(page); - - offset = page->index << PAGE_CACHE_SHIFT; - len = PAGE_CACHE_SIZE; - - retCode = Novfs_Read_File((unsigned long)file->private_data, pbuf, &len, &offset, 0, session); - if ( len && (len < PAGE_CACHE_SIZE) ) - { - memset(&((char *)pbuf)[len], 0, PAGE_CACHE_SIZE-len); - } - - kunmap(page); - flush_dcache_page(page); - SetPageUptodate(page); - } - unlock_page(page); - - DbgPrint("Novfs_a_readpage: retCode=%d\n", retCode); - return (retCode); - -} - -/*++======================================================================*/ -int Novfs_i_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - char *path, *buf; - ENTRY_INFO info; - unsigned long handle; - session_t session; - int retCode = -EACCES; - - - DbgPrint("Novfs_i_create: mode=0%o flags=0%o %.*s\n", mode, nd->NDOPENFLAGS, dentry->d_name.len, dentry->d_name.name); - - if ( IS_ROOT(dentry) || /* Root */ - IS_ROOT(dentry->d_parent) || /* User */ - IS_ROOT(dentry->d_parent->d_parent) || /* Server */ - IS_ROOT(dentry->d_parent->d_parent->d_parent) ) /* Volume */ - { - return(-EACCES); - } - - if (mode | S_IFREG) - { - if (dir->u.generic_ip) - { - session = Scope_Get_SessionId( ((PINODE_DATA)dir->u.generic_ip)->Scope); - if (0 == session) - { - ((PINODE_DATA)dir->u.generic_ip)->Scope = Scope_Get_ScopefromPath( dentry ); - session = Scope_Get_SessionId(((PINODE_DATA)dir->u.generic_ip)->Scope); - } - - buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); - if (buf) - { - path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER); - if (path) - { - retCode = Novfs_Open_File(path, nd->NDOPENFLAGS|O_RDWR, &info, &handle, session); - if ( !retCode && handle ) - { - Novfs_Close_File(handle, session); - if (!Novfs_i_mknod(dir, dentry, mode | S_IFREG, 0)) - { - if (dentry->d_inode) - { - ((PINODE_DATA)dentry->d_inode->u.generic_ip)->Flags |= UPDATE_INODE; - } - } - } - } - Novfs_Free(buf); - } - } - } - return( retCode ); -} - -/*++======================================================================*/ -void update_inode(struct inode *Inode, PENTRY_INFO Info) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - static char dbuf[128]; - - DbgPrint("update_inode: Inode=0x%x I_ino=%d\n", Inode, Inode->i_ino); - - DbgPrint("update_inode: atime=%s\n", ctime_r(&Info->atime.tv_sec, dbuf)); - DbgPrint("update_inode: ctime=%s\n", ctime_r(&Info->ctime.tv_sec, dbuf)); - DbgPrint("update_inode: mtime=%s\n", ctime_r(&Info->mtime.tv_sec, dbuf)); - DbgPrint("update_inode: size=%lld\n", Info->size); - DbgPrint("update_inode: mode=0%o\n", Info->mode); - - Inode->i_mode = Info->mode; - Inode->i_size = Info->size; - Inode->i_atime = Info->atime; - Inode->i_ctime = Info->ctime; - Inode->i_mtime = Info->mtime; - Inode->i_blocks = (u_long)(Info->size >> (loff_t)Inode->i_blkbits); - Inode->i_bytes = Info->size & (Inode->i_blksize - 1); - - DbgPrint("update_inode: i_blksize=%d\n", Inode->i_blksize); - DbgPrint("update_inode: i_blkbits=%d\n", Inode->i_blkbits); - DbgPrint("update_inode: i_blocks=%d\n", Inode->i_blocks); - DbgPrint("update_inode: i_bytes=%d\n", Inode->i_bytes); -} - -/*++======================================================================*/ -struct dentry * Novfs_i_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - struct dentry *retVal = ERR_PTR(-ENOENT); - struct dentry *parent; - PENTRY_INFO info=NULL; - PINODE_DATA id; - struct inode *inode=NULL; - uid_t uid=current->euid; - ino_t ino=0; - struct qstr name; - - DbgPrint("Novfs_i_lookup: dir 0x%x %d name %.*s hash %d inode 0x%0p\n", dir, dir->i_ino, dentry->d_name.len, dentry->d_name.name, dentry->d_name.hash, dentry->d_inode); - - if (dir && (id = dir->u.generic_ip) ) - { - retVal = 0; - if ( IS_ROOT( dentry )) - { - DbgPrint("Novfs_i_lookup: Root entry=0x%x\n", Novfs_root); - inode = Novfs_root->d_inode; - return(0); - } - else - { - info = Novfs_Malloc(sizeof(ENTRY_INFO)+PATH_LENGTH_BUFFER, GFP_KERNEL); - if (info) - { - if ( NULL == (retVal = ERR_PTR(verify_dentry( dentry, 1 )))) - { - name.name = dentry->d_name.name; - name.len = dentry->d_name.len; - name.hash = Novfs_internal_hash(&name); - - if (Novfs_lock_inode_cache( dir )) - { - if ( !Novfs_get_entry(dir, &name, &ino, info) ) - { - inode = ilookup(dentry->d_sb, ino); - if ( inode ) - { - update_inode(inode, info); - } - } - Novfs_unlock_inode_cache( dir ); - } - - if ( !inode && ino ) - { - uid = Scope_Get_Uid( id->Scope ); - if (Novfs_lock_inode_cache( dir )) - { - inode = Novfs_get_inode(dentry->d_sb, info->mode, 0, uid, ino, &name); - if ( inode ) - { - if ( !Novfs_get_entry(dir, &dentry->d_name, &ino, info) ) - { - update_inode(inode, info); - } - } - Novfs_unlock_inode_cache( dir ); - } - } - } - } - } - } - - if ( !retVal ) - { - dentry->d_op = &Novfs_dentry_operations; - if (inode) - { - parent = dget_parent(dentry); - Novfs_d_add(dentry->d_parent, dentry, inode, 1); - dput(parent); - } - else - { - d_add( dentry, inode); - } - } - - if (info) Novfs_Free(info); - - DbgPrint("Novfs_i_lookup: inode=0x%x dentry->d_inode=0x%x return=0x%x\n", dir, dentry->d_inode, retVal); - - return(retVal); -} - -/*++======================================================================*/ -int Novfs_i_unlink(struct inode *dir, struct dentry *dentry) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - int retCode = -ENOENT; - struct inode *inode; - session_t session; - char *path, *buf; - uint64_t t64; - - DbgPrint("Novfs_i_unlink: dir=0x%x dir->i_ino=%d %.*s\n", dir, dir->i_ino, dentry->d_name.len, dentry->d_name.name); - DbgPrint("Novfs_i_unlink: IS_ROOT(dentry)=%d\n", IS_ROOT(dentry)); - DbgPrint("Novfs_i_unlink: IS_ROOT(dentry->d_parent)=%d\n", IS_ROOT(dentry->d_parent)); - DbgPrint("Novfs_i_unlink: IS_ROOT(dentry->d_parent->d_parent)=%d\n", IS_ROOT(dentry->d_parent->d_parent)); - DbgPrint("Novfs_i_unlink: IS_ROOT(dentry->d_parent->d_parent->d_parent)=%d\n", IS_ROOT(dentry->d_parent->d_parent->d_parent) ); - - if ( IS_ROOT(dentry) || /* Root */ - IS_ROOT(dentry->d_parent) || /* User */ - (!IS_ROOT(dentry->d_parent->d_parent) && /* Server */ - IS_ROOT(dentry->d_parent->d_parent->d_parent)) ) /* Volume */ - { - return(-EACCES); - } - - inode = dentry->d_inode; - if ( inode ) - { - DbgPrint("Novfs_i_unlink: dir=0x%x dir->i_ino=%d inode=0x%x ino=%d\n", dir, dir->i_ino, inode, inode->i_ino); - if (inode->u.generic_ip) - { - session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope); - if (0 == session) - { - ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( dentry ); - session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope); - } - - buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); - if (buf) - { - path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER); - if (path) - { - DbgPrint("Novfs_i_unlink: path %s mode 0%o\n", path, inode->i_mode); - if (IS_ROOT(dentry->d_parent->d_parent)) - { - retCode = do_logout(&dentry->d_name); - } - else - { - retCode = Novfs_Delete(path, S_ISDIR(inode->i_mode), session); - } - if ( !retCode || IS_DEADDIR(inode)) - { - Novfs_remove_inode_entry(dir, &dentry->d_name, 0); - dentry->d_time = 0; - t64 = 0; - Scope_Set_UserSpace(&t64, &t64, &t64, &t64); - retCode = 0; - } - } - Novfs_Free(buf); - } - } - } - - DbgPrint("Novfs_i_unlink: retCode 0x%x\n", retCode); - return (retCode); -} - -/*++======================================================================*/ -int Novfs_i_mkdir(struct inode *dir, struct dentry *dentry, int mode) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - char *path, *buf; - session_t session; - int retCode=0; - struct inode *inode; - ENTRY_INFO info; - uid_t uid; - - DbgPrint("Novfs_i_mkdir: dir=0x%p ino=%d dentry=0x%p %.*s mode=0%o\n", dir, dir->i_ino, dentry, dentry->d_name.len, dentry->d_name.name, mode); - - if ( IS_ROOT(dentry) || /* Root */ - IS_ROOT(dentry->d_parent) || /* User */ - IS_ROOT(dentry->d_parent->d_parent) || /* Server */ - IS_ROOT(dentry->d_parent->d_parent->d_parent) ) /* Volume */ - { - return(-EACCES); - } - - mode |= S_IFDIR; - mode &= (S_IFMT | S_IRWXU); - if ( dir->u.generic_ip ) - { - session = Scope_Get_SessionId( ((PINODE_DATA)dir->u.generic_ip)->Scope); - if (0 == session) - { - ((PINODE_DATA)dir->u.generic_ip)->Scope = Scope_Get_ScopefromPath( dentry ); - session = Scope_Get_SessionId(((PINODE_DATA)dir->u.generic_ip)->Scope); - } - - uid = Scope_Get_Uid( ((PINODE_DATA)dir->u.generic_ip)->Scope); - buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); - if (buf) - { - path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER); - if (path) - { - DbgPrint("Novfs_i_mkdir: path %s\n", path); - retCode = Novfs_Create(path, S_ISDIR(mode), session); - if ( !retCode ) - { - retCode = Novfs_Get_File_Info(path, &info, session ); - if ( !retCode ) - { - retCode = Novfs_i_mknod(dir, dentry, mode, 0); - inode = dentry->d_inode; - if (inode) - { - update_inode(inode, &info); - ((PINODE_DATA)inode->u.generic_ip)->Flags &= ~UPDATE_INODE; - - dentry->d_time = jiffies+(File_update_timeout*HZ); - - Novfs_lock_inode_cache(dir); - if (Novfs_update_entry( dir, &dentry->d_name, 0, &info )) - { - Novfs_add_inode_entry(dir, &dentry->d_name, inode->i_ino, &info); - } - Novfs_unlock_inode_cache(dir); - } - - } - } - } - Novfs_Free(buf); - } - } - - return( retCode ); -} - -/*++======================================================================*/ -int Novfs_i_rmdir(struct inode *inode, struct dentry *dentry) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - return(Novfs_i_unlink(inode, dentry)); -} - -/*++======================================================================*/ -int Novfs_i_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - struct inode *inode=NULL; - int retCode = -EACCES; - uid_t uid; - struct dentry *parent; - - if ( IS_ROOT(dentry) || /* Root */ - IS_ROOT(dentry->d_parent) || /* User */ - IS_ROOT(dentry->d_parent->d_parent) || /* Server */ - IS_ROOT(dentry->d_parent->d_parent->d_parent) ) /* Volume */ - { - return(-EACCES); - } - - if ( ((PINODE_DATA)dir->u.generic_ip) ) - { - uid = Scope_Get_Uid( ((PINODE_DATA)dir->u.generic_ip)->Scope); - if (mode & (S_IFREG | S_IFDIR)) - { - inode = Novfs_get_inode(dir->i_sb, mode, dev, uid, 0, &dentry->d_name); - } - } - - if (inode) - { - ENTRY_INFO info; - - dentry->d_op = &Novfs_dentry_operations; - parent = dget_parent(dentry); - Novfs_d_add(parent, dentry, inode, 0); - memset(&info, 0, sizeof(info)); - info.mode = inode->i_mode; - Novfs_lock_inode_cache( dir ); - Novfs_add_inode_entry( dir, &dentry->d_name, inode->i_ino, &info); - Novfs_unlock_inode_cache( dir ); - - dput(parent); - - retCode = 0; - } - DbgPrint("Novfs_i_mknod: return 0x%x\n", retCode); - return retCode; -} - -/*++======================================================================*/ -int Novfs_i_rename(struct inode *odir, struct dentry *od, struct inode *ndir, struct dentry *nd) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - int retCode = -ENOTEMPTY; - char *newpath, *newbuf, *newcon; - char *oldpath, *oldbuf, *oldcon; - struct qstr newname, oldname; - PENTRY_INFO info=NULL; - int oldlen, newlen; - session_t session; - ino_t ino; - - - if ( IS_ROOT(od) || /* Root */ - IS_ROOT(od->d_parent) || /* User */ - IS_ROOT(od->d_parent->d_parent) || /* Server */ - IS_ROOT(od->d_parent->d_parent->d_parent) ) /* Volume */ - { - return(-EACCES); - } - - DbgPrint("Novfs_i_rename: odir=0x%p ino=%d ndir=0x%p ino=%d\n", odir, odir->i_ino, ndir, ndir->i_ino); - - oldbuf = Novfs_Malloc(PATH_LENGTH_BUFFER*2, GFP_KERNEL); - newbuf = oldbuf+PATH_LENGTH_BUFFER; - if ( oldbuf && newbuf ) - { - oldpath = Novfs_dget_path(od, oldbuf, PATH_LENGTH_BUFFER); - newpath = Novfs_dget_path(nd, newbuf, PATH_LENGTH_BUFFER); - if (oldpath && newpath) - { - oldlen = PATH_LENGTH_BUFFER-(int)(oldpath-oldbuf); - newlen = PATH_LENGTH_BUFFER-(int)(newpath-newbuf); - - DbgPrint("Novfs_i_rename: odir=0x%x od->inode=0x%x\n", odir, od->d_inode); - DbgPrint("Novfs_i_rename: old path %s\n", oldpath); - DbgPrint("Novfs_i_rename: new path %s\n", newpath); - - /* - * Check to see if two different servers or different volumes - */ - newcon = strchr(newpath+1, '\\'); - oldcon = strchr(oldpath+1, '\\'); - DbgPrint("Novfs_i_rename: newcon=0x%x newpath=0x%x\n", newcon, newpath); - DbgPrint("Novfs_i_rename: oldcon=0x%x oldpath=0x%x\n", oldcon, oldpath); - retCode = -EXDEV; - if ( newcon && oldcon && ((int)(newcon-newpath) == (int)(oldcon-oldpath)) ) - { - newcon = strchr(newcon+1, '\\'); - oldcon = strchr(oldcon+1, '\\'); - DbgPrint("Novfs_i_rename2: newcon=0x%x newpath=0x%x\n", newcon, newpath); - DbgPrint("Novfs_i_rename2: oldcon=0x%x oldpath=0x%x\n", oldcon, oldpath); - if ( newcon && oldcon && ((int)(newcon-newpath) == (int)(oldcon-oldpath)) ) - { - newname.name = newpath; - newname.len = (int)(newcon-newpath); - newname.hash = 0; - - oldname.name = oldpath; - oldname.len = (int)(oldcon-oldpath); - oldname.hash = 0; - if ( !Novfs_d_strcmp(&newname, &oldname)) - { - - if ( od->d_inode && od->d_inode->u.generic_ip ) - { - - if (nd->d_inode && nd->d_inode->u.generic_ip) - { - session = Scope_Get_SessionId(((PINODE_DATA)ndir->u.generic_ip)->Scope); - if (0 == session) - { - ((PINODE_DATA)ndir->u.generic_ip)->Scope = Scope_Get_ScopefromPath( nd ); - session = Scope_Get_SessionId(((PINODE_DATA)ndir->u.generic_ip)->Scope); - } - - retCode = Novfs_Delete(newpath, S_ISDIR(nd->d_inode->i_mode), session); - } - - - session = Scope_Get_SessionId(((PINODE_DATA)ndir->u.generic_ip)->Scope); - if (0 == session) - { - ((PINODE_DATA)ndir->u.generic_ip)->Scope = Scope_Get_ScopefromPath( nd ); - session = Scope_Get_SessionId(((PINODE_DATA)ndir->u.generic_ip)->Scope); - } - retCode = Novfs_Rename_File( - S_ISDIR(od->d_inode->i_mode), - oldpath, - oldlen-1, - newpath, - newlen-1, - session); - - if ( !retCode ) - { - info = (PENTRY_INFO)oldbuf; - od->d_time = 0; - Novfs_remove_inode_entry(odir, &od->d_name, 0); - Novfs_Get_File_Info(newpath, info, session); - nd->d_time = jiffies+(File_update_timeout*HZ); - if (Novfs_update_entry(ndir, &nd->d_name, 0, info)) - { - if (nd->d_inode && nd->d_inode->i_ino) - { - ino = nd->d_inode->i_ino; - } - else - { - ino = (ino_t)InterlockedIncrement(&Novfs_Inode_Number); - } - Novfs_add_inode_entry(ndir, &nd->d_name, ino, info); - } - } - } - } - } - } - } - } - - if (oldbuf) Novfs_Free(oldbuf); - - return( retCode ); -} - -/*++======================================================================*/ -int Novfs_i_permission(struct inode *inode, int mask) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - int retCode=0; - - return(retCode); -} - -/*++======================================================================*/ -int Novfs_i_setattr(struct dentry *dentry, struct iattr *attr) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - char *path, *buf; - struct inode *inode=dentry->d_inode; - char atime_buf[32]; - char mtime_buf[32]; - char ctime_buf[32]; - unsigned int ia_valid = attr->ia_valid; - session_t session; - int retVal = 0; - - if ( IS_ROOT(dentry) || /* Root */ - IS_ROOT(dentry->d_parent) || /* User */ - IS_ROOT(dentry->d_parent->d_parent) || /* Server */ - IS_ROOT(dentry->d_parent->d_parent->d_parent) ) /* Volume */ - { - return(-EACCES); - } - - if (inode && inode->u.generic_ip) - { - session = Scope_Get_SessionId( ((PINODE_DATA)inode->u.generic_ip)->Scope); - if (0 == session) - { - ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( dentry ); - session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope); - } - - buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); - if (buf) - { - path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER); - if (path) - { - strcpy(atime_buf, "Unspecified"); - strcpy(mtime_buf, "Unspecified"); - strcpy(ctime_buf, "Unspecified"); - if (attr->ia_valid & ATTR_ATIME) - { - ctime_r(&attr->ia_atime.tv_sec, atime_buf); - } - if (attr->ia_valid & ATTR_MTIME) - { - ctime_r(&attr->ia_mtime.tv_sec, mtime_buf); - } - if (attr->ia_valid & ATTR_CTIME) - { - ctime_r(&attr->ia_ctime.tv_sec, ctime_buf); - } - DbgPrint("Novfs_i_setattr: %s\n" \ - " ia_valid: 0x%x\n" \ - " ia_mode: 0%o\n" \ - " ia_uid: %d\n" \ - " ia_gid: %d\n" \ - " ia_size: %lld\n" \ - " ia_atime: %s\n" \ - " ia_mtime: %s\n" \ - " ia_ctime: %s\n", - path, - attr->ia_valid, - attr->ia_mode, - attr->ia_uid, - attr->ia_gid, - attr->ia_size, - atime_buf, - mtime_buf, - ctime_buf); - - if ( !(retVal = Novfs_Set_Attr(path, attr, session) ) ) - { - ((PINODE_DATA)inode->u.generic_ip)->Flags |= UPDATE_INODE; - - if (ia_valid & ATTR_SIZE) - { - inode->i_size = attr->ia_size; - inode->i_blocks = (u_long)(inode->i_size >> (loff_t)inode->i_blkbits); - inode->i_bytes = inode->i_size & (inode->i_blksize - 1); - - } - if (ia_valid & ATTR_ATIME) - inode->i_atime = attr->ia_atime; - if (ia_valid & ATTR_MTIME) - inode->i_mtime = attr->ia_mtime; - if (ia_valid & ATTR_CTIME) - inode->i_ctime = attr->ia_ctime; - if (ia_valid & ATTR_MODE) { - inode->i_mode = attr->ia_mode & (S_IFMT | S_IRWXU); - } - } - } - } - Novfs_Free(buf); - } - - return(retVal); -} - -/*++======================================================================*/ -int Novfs_i_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *kstat) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - int retCode = 0; - char atime_buf[32]; - char mtime_buf[32]; - char ctime_buf[32]; - struct inode *inode = dentry->d_inode; - - ENTRY_INFO info; - char *path, *buf; - session_t session; - PINODE_DATA id; - - if ( !IS_ROOT(dentry) && - !IS_ROOT(dentry->d_parent) ) - { - session = 0; - id = dentry->d_inode->u.generic_ip; - - if (id && (id->Flags & UPDATE_INODE) ) - { - session = Scope_Get_SessionId( id->Scope ); - - if (0 == session) - { - id->Scope = Scope_Get_ScopefromPath( dentry ); - session = Scope_Get_SessionId(id->Scope); - } - - buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); - if (buf) - { - path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER); - if (path) - { - retCode = Novfs_Get_File_Info(path, &info, session ); - if ( !retCode ) - { - update_inode(inode, &info); - id->Flags &= ~UPDATE_INODE; - } - } - Novfs_Free(buf); - } - } - } - - kstat->ino = inode->i_ino; - kstat->dev = inode->i_sb->s_dev; - kstat->mode = inode->i_mode; - kstat->nlink = inode->i_nlink; - kstat->uid = inode->i_uid; - kstat->gid = inode->i_gid; - kstat->rdev = inode->i_rdev; - kstat->size = i_size_read(inode); - kstat->atime = inode->i_atime; - kstat->mtime = inode->i_mtime; - kstat->ctime = inode->i_ctime; - kstat->blksize = inode->i_blksize; - kstat->blocks = inode->i_blocks; - if (inode->i_bytes) - { - kstat->blocks++; - } - ctime_r(&kstat->atime.tv_sec, atime_buf); - ctime_r(&kstat->mtime.tv_sec, mtime_buf); - ctime_r(&kstat->ctime.tv_sec, ctime_buf); - - - DbgPrint("Novfs_i_getattr: 0x%x <%.*s>\n" \ - " ino: %d\n" \ - " dev: 0x%x\n" \ - " mode: 0%o\n" \ - " nlink: 0x%x\n" \ - " uid: 0x%x\n" \ - " gid: 0x%x\n" \ - " rdev: 0x%x\n" \ - " size: 0x%llx\n" \ - " atime: %s\n" \ - " mtime: %s\n" \ - " ctime: %s\n" \ - " blksize: 0x%x\n" \ - " blocks: 0x%x\n", - retCode, dentry->d_name.len, dentry->d_name.name, - kstat->ino, - kstat->dev, - kstat->mode, - kstat->nlink, - kstat->uid, - kstat->gid, - kstat->rdev, - kstat->size, - atime_buf, - mtime_buf, - ctime_buf, - kstat->blksize, - kstat->blocks); - return( retCode ); -} - - -/*++======================================================================*/ -int Novfs_i_revalidate(struct dentry *dentry) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - - DbgPrint("Novfs_i_revalidate: name %.*s\n", dentry->d_name.len, dentry->d_name.name); - - return(0); -} - -/*++======================================================================*/ -void Novfs_read_inode(struct inode *inode) -/* - * Arguments: - * - * Returns: nothing - * - * Abstract: - * - * Notes: - * - * Environment: Superblock operation - * - *=======================================================================-*/ -{ - DbgPrint( "Novfs_read_inode: 0x%x %d\n", inode, inode->i_ino); -} - -/*++======================================================================*/ -void Novfs_write_inode(struct inode *inode) -/* - * Arguments: - * - * Returns: nothing - * - * Abstract: - * - * Notes: - * - * Environment: Superblock operation - * - *=======================================================================-*/ -{ - DbgPrint( "Novfs_write_inode: Inode=0x%x Ino=%d\n", inode, inode->i_ino); -} - -/*++======================================================================*/ -int Novfs_notify_change(struct dentry *dentry, struct iattr *attr) -/* - * Arguments: - * - * Returns: error code - * - * Abstract: - * - * Notes: - * - * Environment: Superblock operation - * - *=======================================================================-*/ -{ - struct inode *inode = dentry->d_inode; - - DbgPrint( "Novfs_notify_change: Dentry=0x%x Name=%.*s Inode=0x%x Ino=%d ia_valid=0x%x\n", - dentry, dentry->d_name.len, dentry->d_name.name,inode, inode->i_ino, attr->ia_valid); - return(0); -} - -/*++======================================================================*/ -void Novfs_clear_inode(struct inode *inode) -/* - * Arguments: sb - pointer to the super_block - * buf - pointer to the statfs buffer - * - * Returns: 0 - * - * Abstract: Called when statfs(2) system called. - * - * Notes: - * - * Environment: Superblock operation - * - *========================================================================*/ -{ - InodeCount--; - - if ( inode->u.generic_ip ) - { - PINODE_DATA id=inode->u.generic_ip; - - DbgPrint("Novfs_clear_inode: inode=0x%x ino=%d Scope=0x%p Name=%s\n", inode, inode->i_ino, id->Scope, id->Name); - - Novfs_free_inode_cache(inode); - - down( &InodeList_lock ); - list_del( &id->IList ); - up( &InodeList_lock ); - - - Novfs_Free(inode->u.generic_ip); - inode->u.generic_ip = NULL; - - remove_inode_hash( inode ); - - } - else - { - DbgPrint("Novfs_clear_inode: inode=0x%x ino=%d\n", inode, inode->i_ino); - } -} - -/*++======================================================================*/ -int -NO_TRACE -Novfs_show_options( struct seq_file *s, struct vfsmount *m ) -/* - * Arguments: - * - * Returns: 0 - * - * Abstract: Called when /proc/mounts is read - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - char *buf, *path, *tmp; - - buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); - if (buf) - { - path = d_path(m->mnt_root, m, buf, PATH_LENGTH_BUFFER); - if (path) - { - if ( !Novfs_CurrentMount || (Novfs_CurrentMount && strcmp(Novfs_CurrentMount, path))) - { - DbgPrint("Novfs_show_options: %.*s %.*s %s\n", m->mnt_root->d_name.len, m->mnt_root->d_name.name, - m->mnt_mountpoint->d_name.len, m->mnt_mountpoint->d_name.name, path); - tmp = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER - (int)(path-buf), GFP_KERNEL); - if (tmp) - { - strcpy(tmp, path); - path = Novfs_CurrentMount; - Novfs_CurrentMount = tmp; - Daemon_SetMountPoint( Novfs_CurrentMount ); - - if (path) - { - Novfs_Free(path); - } - } - } - } - Novfs_Free( buf ); - } - return(0); -} - -/*++======================================================================*/ -int Novfs_statfs(struct super_block *sb, struct kstatfs *buf) -/* - * Arguments: sb - pointer to the super_block - * buf - pointer to the statfs buffer - * - * Returns: 0 - * - * Abstract: Called when statfs(2) system called. - * - * Notes: - * - * Environment: Superblock operation - * - *========================================================================*/ -{ - uint64_t td, fd, te, fe; - - UNUSED_VARIABLE(sb); - - DbgPrint("Novfs_statfs:\n"); - - td = fd = te = fe = 0; - - Scope_Get_UserSpace( &td, &fd, &te, &fe ); - - DbgPrint("td=%llu\n", td); - DbgPrint("fd=%llu\n", fd); - DbgPrint("te=%llu\n", te); - DbgPrint("fe=%llu\n", fd); - - buf->f_type = sb->s_magic; - buf->f_bsize = sb->s_blocksize; - buf->f_namelen = NW_MAX_PATH_LENGTH; - buf->f_blocks = (sector_t)(td + (uint64_t)(sb->s_blocksize-1)) >> (uint64_t)sb->s_blocksize_bits; - buf->f_bfree = (sector_t)fd >> (uint64_t)sb->s_blocksize_bits; - buf->f_bavail = (sector_t)buf->f_bfree; - buf->f_files = (sector_t)te; - buf->f_ffree = (sector_t)fe; - buf->f_frsize = sb->s_blocksize; - if (te > 0xffffffff) - buf->f_files = 0xffffffff; - - if (fe > 0xffffffff) - buf->f_ffree = 0xffffffff; - - - DbgPrint("f_type: 0x%x\n", buf->f_type); - DbgPrint("f_bsize: %u\n", buf->f_bsize); - DbgPrint("f_namelen: %d\n", buf->f_namelen); - DbgPrint("f_blocks: %llu\n", buf->f_blocks); - DbgPrint("f_bfree: %llu\n", buf->f_bfree); - DbgPrint("f_bavail: %llu\n", buf->f_bavail); - DbgPrint("f_files: %llu\n", buf->f_files); - DbgPrint("f_ffree: %llu\n", buf->f_ffree); - DbgPrint("f_frsize: %u\n", buf->f_frsize); - - return 0; -} - -/*++======================================================================*/ -struct inode *Novfs_get_inode(struct super_block *sb, int mode, int dev, uid_t Uid, ino_t ino, struct qstr *name) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *=======================================================================-*/ -{ - struct inode * inode = new_inode(sb); - - if (inode) - { - InodeCount++; - inode->i_mode = mode; - inode->i_uid = Uid; - inode->i_gid = 0; - inode->i_blksize = sb->s_blocksize; - inode->i_blkbits = sb->s_blocksize_bits; - inode->i_size = 0; - inode->i_blocks = 0; - inode->i_rdev = 0; - inode->i_ino = (ino) ? ino: (ino_t)InterlockedIncrement(&Novfs_Inode_Number); - inode->i_mapping->a_ops = &Novfs_aops; - inode->i_atime.tv_sec = 0; - inode->i_atime.tv_nsec = 0; - inode->i_mtime = inode->i_ctime = inode->i_atime; - - DbgPrint("Novfs_get_inode: Inode=0x%p I_ino=%d len=%d\n", inode, inode->i_ino, name->len); - - if (NULL != (inode->u.generic_ip = Novfs_Malloc(sizeof(INODE_DATA)+name->len, GFP_KERNEL))) - { - PINODE_DATA id; - id = inode->u.generic_ip; - - DbgPrint("Novfs_get_inode: u.generic_ip 0x%p\n", id); - - id->Scope = NULL; - id->Flags = 0; - id->Inode = inode; - INIT_LIST_HEAD( &id->DirCache ); - init_MUTEX( &id->DirCacheLock ); - down( &InodeList_lock ); - - list_add_tail(&id->IList, &InodeList); - up( &InodeList_lock ); - - id->Name[0] = '\0'; - - memcpy(id->Name, name->name, name->len); - id->Name[name->len] = '\0'; - - DbgPrint("Novfs_get_inode: name %s\n", id->Name); - } - - insert_inode_hash(inode); - - switch (mode & S_IFMT) { - - case S_IFREG: - inode->i_op = &Novfs_file_inode_operations; - inode->i_fop = &Novfs_file_operations; - break; - - case S_IFDIR: - inode->i_op = &Novfs_inode_operations; - inode->i_fop = &Novfs_dir_operations; - inode->i_blksize = 0; - inode->i_blkbits = 0; - break; - - default: - init_special_inode(inode, mode, dev); - break; - } - - DbgPrint("Novfs_get_inode: size=%lld\n", inode->i_size); - DbgPrint("Novfs_get_inode: mode=0%o\n", inode->i_mode); - DbgPrint("Novfs_get_inode: i_blksize=%d\n", inode->i_blksize); - DbgPrint("Novfs_get_inode: i_blkbits=%d\n", inode->i_blkbits); - DbgPrint("Novfs_get_inode: i_blocks=%d\n", inode->i_blocks); - DbgPrint("Novfs_get_inode: i_bytes=%d\n", inode->i_bytes); - } - - DbgPrint("Novfs_get_inode: 0x%p %d\n", inode, inode->i_ino); - return (inode); -} - -/*++======================================================================*/ -int Novfs_fill_super (struct super_block *SB, void *Data, int Silent) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - struct inode * inode; - struct dentry *server, *tree; - struct qstr name; -/* PINODE_DATA id; -*/ - ENTRY_INFO info; - - UNUSED_VARIABLE(Data); - UNUSED_VARIABLE(Silent); - - SB->s_blocksize = PAGE_CACHE_SIZE; - SB->s_blocksize_bits = PAGE_CACHE_SHIFT; - SB->s_maxbytes = 0xFFFFFFFFFFFFFFFFULL; /* Max file size */ - SB->s_op = &Novfs_ops; - SB->s_flags |= (MS_NODIRATIME | MS_NODEV | MS_POSIXACL); - SB->s_magic = NOVFS_MAGIC; - - - name.len = 1; - name.name = "/"; - - inode = Novfs_get_inode(SB, S_IFDIR | 0777, 0, 0, 0, &name); - if (!inode) - { - return( -ENOMEM ); - } - - Novfs_root = d_alloc_root(inode); - - if (!Novfs_root) - { - iput(inode); - return( -ENOMEM ); - } - Novfs_root->d_time = jiffies+(File_update_timeout*HZ); - - inode->i_atime = - inode->i_ctime = - inode->i_mtime = CURRENT_TIME; - - - SB->s_root = Novfs_root; - - DbgPrint( "Novfs_fill_super: root 0x%x\n", Novfs_root); - - if (Novfs_root) - { - Novfs_root->d_op = &Novfs_dentry_operations; - - name.name = SERVER_DIRECTORY_NAME; - name.len = strlen(SERVER_DIRECTORY_NAME); - name.hash = Novfs_internal_hash( &name ); - - inode = Novfs_get_inode(SB, S_IFDIR | 0777, 0, 0, 0, &name); - if (inode) - { - info.mode = inode->i_mode; - info.namelength = 0; - inode->i_size = info.size = 0; - inode->i_uid = info.uid = 0; - inode->i_gid = info.gid = 0; - inode->i_atime = info.atime = - inode->i_ctime = info.ctime = - inode->i_mtime = info.mtime = CURRENT_TIME; - - server = d_alloc(Novfs_root, &name); - if (server) - { - server->d_op = &Novfs_dentry_operations; - server->d_time = 0xffffffff; - d_add(server, inode); - DbgPrint( "Novfs_fill_super: d_add %s 0x%x\n", SERVER_DIRECTORY_NAME, server); - Novfs_add_inode_entry(Novfs_root->d_inode, &name, inode->i_ino, &info); - } - } - - name.name = TREE_DIRECTORY_NAME; - name.len = strlen(TREE_DIRECTORY_NAME); - name.hash = Novfs_internal_hash( &name ); - - inode = Novfs_get_inode(SB, S_IFDIR | 0777, 0, 0, 0, &name); - if (inode) - { - info.mode = inode->i_mode; - info.namelength = 0; - inode->i_size = info.size = 0; - inode->i_uid = info.uid = 0; - inode->i_gid = info.gid = 0; - inode->i_atime = info.atime = - inode->i_ctime = info.ctime = - inode->i_mtime = info.mtime = CURRENT_TIME; - tree = d_alloc(Novfs_root, &name); - if (tree) - { - tree->d_op = &Novfs_dentry_operations; - tree->d_time = 0xffffffff; - - d_add(tree, inode); - DbgPrint( "Novfs_fill_super: d_add %s 0x%x\n", TREE_DIRECTORY_NAME, tree); - Novfs_add_inode_entry(Novfs_root->d_inode, &name, inode->i_ino, &info); - } - } - } - - return( 0 ); -} - -/*++======================================================================*/ -struct super_block *Novfs_get_sb(struct file_system_type *Fstype, int Flags, const char *Dev_name, void *Data) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - struct super_block *sb; - UNUSED_VARIABLE(Dev_name); - - sb = get_sb_nodev(Fstype, Flags, Data, Novfs_fill_super); - - DbgPrint( "Novfs_get_sb: sb=0x%x Fstype=0x%x Dev_name=%s\n", sb, Fstype, Dev_name); - - return (sb ); -} - -/*++======================================================================*/ -void Novfs_kill_sb(struct super_block *SB) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - kill_litter_super(SB); -} - -/*++======================================================================*/ -ssize_t Novfs_Control_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - ssize_t retval=0; - - UNUSED_VARIABLE(file); - UNUSED_VARIABLE(buf); - UNUSED_VARIABLE(nbytes); - UNUSED_VARIABLE(ppos); - - DbgPrint( "Novfs_Control_read: kernel_locked 0x%x\n", kernel_locked()); - - return retval; -} - -/*++======================================================================*/ -ssize_t Novfs_Control_write(struct file * file, const char * buf, size_t nbytes, loff_t *ppos) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - ssize_t retval=0; - - UNUSED_VARIABLE(file); - UNUSED_VARIABLE(buf); - UNUSED_VARIABLE(nbytes); - UNUSED_VARIABLE(ppos); - - DbgPrint( "Novfs_Control_write: kernel_locked 0x%x\n", kernel_locked()); - if (buf && nbytes) - { - } - - return(retval); -} - -/*++======================================================================*/ -int Novfs_Control_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - int retval=0; - - UNUSED_VARIABLE(inode); - UNUSED_VARIABLE(file); - UNUSED_VARIABLE(cmd); - UNUSED_VARIABLE(arg); - - DbgPrint( "Novfs_Control_ioctl: kernel_locked 0x%x\n", kernel_locked()); - - return(retval); -} - -/*++======================================================================*/ -int __init init_novfs (void) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - int retCode; - - - retCode = Init_Procfs_Interface(); - - init_profile(); - - if ( !retCode ) - { - DbgPrint("init_novfs: %s %s %s\n", __DATE__, __TIME__, NOVFS_VERSION_STRING); - Init_Daemon_Queue(); - Scope_Init(); - retCode = register_filesystem(&Novfs_fs_type); - if ( retCode ) - { - Uninit_Procfs_Interface(); - Uninit_Daemon_Queue(); - Scope_Uninit(); - } - } - return(retCode); -} - -/*++======================================================================*/ -void __exit exit_novfs(void) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - printk( KERN_INFO "exit_novfs\n"); - Scope_Uninit(); - printk( KERN_INFO "exit_novfs after Scope_Uninit\n"); - Uninit_Daemon_Queue(); - printk( KERN_INFO "exit_novfs after Uninit_Daemon_Queue\n"); - Uninit_Procfs_Interface(); - printk( KERN_INFO "exit_novfs Uninit_Procfs_Interface\n"); - unregister_filesystem(&Novfs_fs_type); - printk( KERN_INFO "exit_novfs: Exit\n"); - if (Novfs_CurrentMount) - { - Novfs_Free(Novfs_CurrentMount); - Novfs_CurrentMount = NULL; - } -} - -/*++======================================================================*/ -int Novfs_lock_inode_cache( struct inode *i ) -/* - * - * Arguments: struct inode *i - pointer to directory inode - * - * Returns: 0 - locked - * -1 - not locked - * - * Abstract: Locks the inode cache. - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - PINODE_DATA id; - int retVal = 0; - - DbgPrint("Novfs_lock_inode_cache: 0x%p\n", i); - if ( i && (id = i->u.generic_ip) && id->DirCache.next ) - { - down( &id->DirCacheLock ); - retVal = 1; - } - DbgPrint("Novfs_lock_inode_cache: return %d\n", retVal); - return( retVal ); -} - -/*++======================================================================*/ -void Novfs_unlock_inode_cache( struct inode *i ) -/* - * Arguments: struct inode *i - pointer to directory inode - * - * Returns: nothing - * - * Abstract: Unlocks inode cache. - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - PINODE_DATA id; - - if ( i && (id = i->u.generic_ip) && id->DirCache.next ) - { - up( &id->DirCacheLock ); - } -} - -/*++======================================================================*/ -int Novfs_enumerate_inode_cache( struct inode *i, struct list_head **iteration, ino_t *ino, PENTRY_INFO info) -/* - * Arguments: struct inode *i - pointer to directory inode - * - * Returns: 0 - item found - * -1 - done - * - * Abstract: Unlocks inode cache. - * - * Notes: DirCacheLock should be held before calling this routine. - * - * Environment: - * - *========================================================================*/ -{ - PINODE_DATA id; - PDIR_CACHE dc; - struct list_head *l=NULL; - int retVal = -1; - - - if ( i && (id = i->u.generic_ip) && id->DirCache.next ) - { - if ( (NULL == iteration) || (NULL == *iteration) ) - { - l = id->DirCache.next; - } - else - { - l = *iteration; - } - - if (l == &id->DirCache) - { - l = NULL; - } - else - { - dc = list_entry(l, DIR_CACHE, list); - - *ino = dc->ino; - info->type = 0; - info->mode = dc->mode; - info->size = dc->size; - info->atime = dc->atime; - info->mtime = dc->mtime; - info->ctime = dc->ctime; - info->namelength = dc->nameLen; - memcpy(info->name, dc->name, dc->nameLen); - info->name[dc->nameLen] = '\0'; - retVal = 0; - - l = l->next; - } - } - *iteration = l; - return( retVal ); -} - -/*++======================================================================*/ -int Novfs_get_entry( struct inode *i, struct qstr *name, ino_t *ino, PENTRY_INFO info) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: DirCacheLock should be held before calling this routine. - * - * Environment: - * - *========================================================================*/ -{ - PINODE_DATA id; - PDIR_CACHE dc; - int retVal = -1; - char *n=""; - int nl=6; - - if ( i && (id = i->u.generic_ip) && id->DirCache.next ) - { - if (name && name->len) - { - n = (char *)name->name; - nl = name->len; - } - DbgPrint("Novfs_get_entry:\n" \ - " inode: 0x%p\n" \ - " name: %.*s\n" \ - " ino: %d\n", - i, nl, n, *ino); - - dc = Novfs_lookup_inode_cache(i, name, *ino); - if (dc) - { - dc->flags |= ENTRY_VALID; - retVal = 0; - *ino = dc->ino; - info->type = 0; - info->mode = dc->mode; - info->size = dc->size; - info->atime = dc->atime; - info->mtime = dc->mtime; - info->ctime = dc->ctime; - info->namelength = dc->nameLen; - memcpy(info->name, dc->name, dc->nameLen); - info->name[dc->nameLen] = '\0'; - retVal = 0; - } - } - DbgPrint("Novfs_get_entry: return %d\n", retVal); - return( retVal ); -} - -/*++======================================================================*/ -int Novfs_get_entry_time( struct inode *i, struct qstr *name, ino_t *ino, PENTRY_INFO info, u64 *EntryTime) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: DirCacheLock should be held before calling this routine. - * - * Environment: - * - *========================================================================*/ -{ - PINODE_DATA id; - PDIR_CACHE dc; - int retVal = -1; - char *n=""; - int nl=6; - - if ( i && (id = i->u.generic_ip) && id->DirCache.next ) - { - if (name && name->len) - { - n = (char *)name->name; - nl = name->len; - } - DbgPrint("Novfs_get_entry:\n" \ - " inode: 0x%p\n" \ - " name: %.*s\n" \ - " ino: %d\n", - i, nl, n, *ino); - - dc = Novfs_lookup_inode_cache(i, name, *ino); - if (dc) - { - retVal = 0; - *ino = dc->ino; - info->type = 0; - info->mode = dc->mode; - info->size = dc->size; - info->atime = dc->atime; - info->mtime = dc->mtime; - info->ctime = dc->ctime; - info->namelength = dc->nameLen; - memcpy(info->name, dc->name, dc->nameLen); - info->name[dc->nameLen] = '\0'; - if (EntryTime) - { - *EntryTime = dc->jiffies; - } - retVal = 0; - } - } - DbgPrint("Novfs_get_entry: return %d\n", retVal); - return( retVal ); -} - -/*++======================================================================*/ -int Novfs_get_remove_entry( struct inode *i, ino_t *ino, PENTRY_INFO info) -/* - * Arguments: - * - * Returns: - * - * Abstract: This routine will return the first entry on the list - * and then remove it. - * - * Notes: DirCacheLock should be held before calling this routine. - * - * Environment: - * - *========================================================================*/ -{ - PINODE_DATA id; - PDIR_CACHE dc; - struct list_head *l=NULL; - int retVal = -1; - - - if ( i && (id = i->u.generic_ip) && id->DirCache.next ) - { - l = id->DirCache.next; - - if (l != &id->DirCache) - { - dc = list_entry(l, DIR_CACHE, list); - - *ino = dc->ino; - info->type = 0; - info->mode = dc->mode; - info->size = dc->size; - info->atime = dc->atime; - info->mtime = dc->mtime; - info->ctime = dc->ctime; - info->namelength = dc->nameLen; - memcpy(info->name, dc->name, dc->nameLen); - info->name[dc->nameLen] = '\0'; - retVal = 0; - - list_del( &dc->list ); - Novfs_Free( dc ); - DCCount--; - - } - } - return( retVal ); -} - -/*++======================================================================*/ -void Novfs_invalidate_inode_cache( struct inode *i ) -/* - * Arguments: struct inode *i - pointer to directory inode - * - * Returns: nothing - * - * Abstract: Marks all entries in the directory cache as invalid. - * - * Notes: DirCacheLock should be held before calling this routine. - * - * Environment: - * - *========================================================================*/ -{ - PINODE_DATA id; - PDIR_CACHE dc; - struct list_head *l; - - if ( i && (id = i->u.generic_ip) && id->DirCache.next ) - { - list_for_each(l, &id->DirCache) - { - dc = list_entry(l, DIR_CACHE, list); - dc->flags &= ~ENTRY_VALID; - } - } -} - -/*++======================================================================*/ -PDIR_CACHE Novfs_lookup_inode_cache( struct inode *i, struct qstr *name, ino_t ino ) -/* - * Arguments: struct inode *i - pointer to directory inode - * struct qstr *name - pointer to name - * ino_t - inode number - * - * Returns: DIR_CACHE entry if match - * NULL - if there is no match. - * - * Abstract: Checks a inode directory to see if there are any enties - * matching name or ino. If name is specified then ino is - * not used. ino is use if name is not specified. - * - * Notes: DirCacheLock should be held before calling this routine. - * - * Environment: - * - *========================================================================*/ -{ - PINODE_DATA id; - PDIR_CACHE dc, retVal=NULL; - struct list_head *l; - char *n=""; - int nl=6; - int hash=0; - - if ( i && (id = i->u.generic_ip) && id->DirCache.next ) - { - if (name && name->name) - { - nl = name->len; - n = (char *)name->name; - hash = name->hash; - } - DbgPrint("Novfs_lookup_inode_cache:\n" \ - " inode: 0x%p\n" \ - " name: %.*s\n" \ - " hash: 0x%x\n" \ - " len: %d\n" \ - " ino: %d\n", - i, nl, n, hash, nl, ino); - - list_for_each(l, &id->DirCache) - { - dc = list_entry(l, DIR_CACHE, list); - if (name) - { - -/* DbgPrint("Novfs_lookup_inode_cache: 0x%p\n" \ - " ino: %d\n" \ - " hash: 0x%x\n" \ - " len: %d\n" \ - " name: %.*s\n", - dc, dc->ino, dc->hash, dc->nameLen, dc->nameLen, dc->name); -*/ - if ( (name->hash == dc->hash) && - (name->len == dc->nameLen) && - (0 == memcmp(name->name, dc->name, name->len)) ) - { - retVal = dc; - break; - } - } - else - { - if (ino == dc->ino) - { - retVal = dc; - break; - } - } - } - } - - DbgPrint("Novfs_lookup_inode_cache: return 0x%p\n", retVal); - return( retVal ); -} - -/*++======================================================================*/ -int Novfs_lookup_validate( struct inode *i, struct qstr *name, ino_t ino ) -/* - * Arguments: struct inode *i - pointer to directory inode - * struct qstr *name - pointer to name - * ino_t - inode number - * - * Returns: 0 if found - * !0 if not found - * - * Abstract: Checks a inode directory to see if there are any enties - * matching name or ino. If entry is found the valid bit - * is set. - * - * Notes: DirCacheLock should be held before calling this routine. - * - * Environment: - * - *========================================================================*/ -{ - PINODE_DATA id; - PDIR_CACHE dc; - int retVal = -1; - char *n=""; - int nl=6; - - if ( i && (id = i->u.generic_ip) && id->DirCache.next ) - { - if (name && name->len) - { - n = (char *)name->name; - nl = name->len; - } - DbgPrint("Novfs_update_entry:\n" \ - " inode: 0x%p\n" \ - " name: %.*s\n" \ - " ino: %d\n", - i, nl, n, ino); - - dc = Novfs_lookup_inode_cache( i, name, ino ); - if (dc) - { - dc->flags |= ENTRY_VALID; - retVal = 0; - } - } - return( retVal ); -} - -/*++======================================================================*/ -int Novfs_add_inode_entry( - struct inode *i, - struct qstr *name, - ino_t ino, - PENTRY_INFO info) -/* - * Arguments: - * - * Returns: -ENOMEM - alloc error. - * 0 - success. - * - * Abstract: Added entry to directory cache. - * - * Notes: DirCacheLock should be held before calling this routine. - * - * Environment: - * - *========================================================================*/ -{ - PINODE_DATA id; - PDIR_CACHE new; - int retVal = -ENOMEM; - - if ( i && (id = i->u.generic_ip) && id->DirCache.next ) - { - new = Novfs_Malloc(sizeof(DIR_CACHE)+name->len, GFP_KERNEL); - if (new) - { - DCCount++; - DbgPrint("Novfs_add_inode_entry:\n" \ - " inode: 0x%p\n" \ - " id: 0x%p\n" \ - " DC: 0x%p\n" \ - " new: 0x%p\n" \ - " name: %.*s\n" \ - " ino: %d\n" \ - " size: %lld\n" \ - " mode: 0x%x\n", - i, id, &id->DirCache, new, name->len, name->name, ino, info->size, info->mode); - - retVal = 0; - new->flags = ENTRY_VALID; - new->jiffies = get_jiffies_64(); - new->size = info->size; - new->mode = info->mode; - new->atime = info->atime; - new->mtime = info->mtime; - new->ctime = info->ctime; - new->ino = ino; - new->hash = name->hash; - new->nameLen = name->len; - memcpy(new->name, name->name, name->len); - new->name[new->nameLen] = '\0'; - list_add(&new->list, &id->DirCache); - -/* list_for_each(l, &id->DirCache) - { - dc = list_entry(l, DIR_CACHE, list); - if ( dc->hash > new->hash ) - { - break; - } - } - - DbgPrint("Novfs_add_inode_entry: adding 0x%p to 0x%p\n", new, l); - list_add(&new->list, l); -*/ - } - } - return( retVal ); -} - -/*++======================================================================*/ -int Novfs_update_entry( struct inode *i, struct qstr *name, ino_t ino, PENTRY_INFO info) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: DirCacheLock should be held before calling this routine. - * - * Environment: - * - *========================================================================*/ -{ - PINODE_DATA id; - PDIR_CACHE dc; - int retVal = -1; - char *n=""; - int nl=6; - char atime_buf[32]; - char mtime_buf[32]; - char ctime_buf[32]; - - if ( i && (id = i->u.generic_ip) && id->DirCache.next ) - { - - if (name && name->len) - { - n = (char *)name->name; - nl = name->len; - } - ctime_r(&info->atime.tv_sec, atime_buf); - ctime_r(&info->mtime.tv_sec, mtime_buf); - ctime_r(&info->ctime.tv_sec, ctime_buf); - DbgPrint("Novfs_update_entry:\n" \ - " inode: 0x%p\n" \ - " name: %.*s\n" \ - " ino: %d\n" \ - " size: %lld\n" \ - " atime: %s\n" \ - " mtime: %s\n" \ - " ctime: %s\n", - i, nl, n, ino, info->size, atime_buf, mtime_buf, ctime_buf); - - - dc = Novfs_lookup_inode_cache(i, name, ino); - if (dc) - { - retVal = 0; - dc->flags = ENTRY_VALID; - dc->jiffies = get_jiffies_64(); - dc->size = info->size; - dc->mode = info->mode; - dc->atime = info->atime; - dc->mtime = info->mtime; - dc->ctime = info->ctime; - - ctime_r(&dc->atime.tv_sec, atime_buf); - ctime_r(&dc->mtime.tv_sec, mtime_buf); - ctime_r(&dc->ctime.tv_sec, ctime_buf); - DbgPrint("Novfs_update_entry entry: 0x%x\n" \ - " flags: 0x%x\n" \ - " jiffies: %lld\n" \ - " ino: %d\n" \ - " size: %lld\n" \ - " mode: 0%o\n" \ - " atime: %s\n" \ - " mtime: %s\n" \ - " ctime: %s\n" \ - " hash: 0x%x\n" \ - " nameLen: %d\n" \ - " name: %s\n", - dc, dc->flags, dc->jiffies, dc->ino, dc->size, dc->mode, - atime_buf, mtime_buf, ctime_buf, dc->hash, dc->nameLen, dc->name); - } - } - DbgPrint("Novfs_update_entry: return %d\n", retVal); - return( retVal ); -} - -/*++======================================================================*/ -void Novfs_remove_inode_entry( struct inode *i, struct qstr *name, ino_t ino) -/* - * Arguments: - * - * Returns: nothing - * - * Abstract: Removes entry from directory cache. You can specify a name - * or an inode number. - * - * Notes: DirCacheLock should be held before calling this routine. - * - * Environment: - * - *========================================================================*/ -{ - PINODE_DATA id; - PDIR_CACHE dc; - char *n=""; - int nl=6; - - if ( i && (id = i->u.generic_ip) && id->DirCache.next ) - { - dc = Novfs_lookup_inode_cache( i, name, ino ); - if (dc) - { - if (name && name->name) - { - nl = name->len; - n = (char *)name->name; - } - DbgPrint("Novfs_remove_inode_entry:\n" \ - " inode: 0x%p\n" \ - " id: 0x%p\n" \ - " DC: 0x%p\n" \ - " name: %.*s\n" \ - " ino: %d\n" \ - " entry: 0x%p\n" \ - " name: %.*s\n"\ - " ino: %d\n" \ - " next: 0x%p\n" \ - " prev: 0x%p\n", - i, id, &id->DirCache, nl, n, ino, dc, dc->nameLen, dc->name, dc->ino, dc->list.next, dc->list.prev); - list_del( &dc->list ); - Novfs_Free( dc ); - DCCount--; - - } - } -} - -/*++======================================================================*/ -void Novfs_free_invalid_entries( struct inode *i ) -/* - * Arguments: struct inode *i - pointer to directory inode. - * - * Returns: nothing - * - * Abstract: Frees all invalid entries in the directory cache. - * - * Notes: DirCacheLock should be held before calling this routine. - * - * Environment: - * - *========================================================================*/ -{ - PINODE_DATA id; - PDIR_CACHE dc; - struct list_head *l; - - if ( i && (id = i->u.generic_ip) && id->DirCache.next ) - { - list_for_each( l, &id->DirCache ) - { - dc = list_entry( l, DIR_CACHE, list ); - if ( 0 == (dc->flags & ENTRY_VALID) ) - { - DbgPrint("Novfs_free_invalid_entries:\n" \ - " inode: 0x%p\n" \ - " id: 0x%p\n" \ - " entry: 0x%p\n" \ - " name: %.*s\n" \ - " ino: %d\n", - i, id, dc, dc->nameLen, dc->name, dc->ino); - l = l->prev; - list_del( &dc->list ); - Novfs_Free( dc ); - DCCount--; - } - } - } -} - -/*++======================================================================*/ -void Novfs_free_inode_cache( struct inode *i ) -/* - * Arguments: struct inode *i - pointer to directory inode. - * - * Returns: nothing - * - * Abstract: Frees all entries in the inode cache. - * - * Notes: DirCacheLock should be held before calling this routine. - * - * Environment: - * - *========================================================================*/ -{ - PINODE_DATA id; - PDIR_CACHE dc; - struct list_head *l; - - if ( i && (id = i->u.generic_ip) && id->DirCache.next ) - { - list_for_each( l, &id->DirCache ) - { - dc = list_entry( l, DIR_CACHE, list ); - l = l->prev; - list_del( &dc->list ); - Novfs_Free( dc ); - DCCount--; - } - } -} - -/*++======================================================================*/ -int -NO_TRACE -Novfs_dump_inode_cache(int argc, const char **argv, const char **envp, struct pt_regs *regs) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ -#ifdef CONFIG_KDB - struct inode *inode=NULL; - PINODE_DATA id; - PDIR_CACHE dc; - struct list_head *l; - char atime_buf[32]; - char mtime_buf[32]; - char ctime_buf[32]; - - if (Novfs_root) - { - inode = Novfs_root->d_inode; - } - - if (argc > 0) - { - inode = (void *)simple_strtoul(argv[1], NULL, 0); - } - - kdb_printf("Inode: 0x%p\n", inode); - if (inode) - { - id = inode->u.generic_ip; - kdb_printf("INODE_DATA: 0x%p\n", id); - - if ( id && id->DirCache.next ) - { - list_for_each(l, &id->DirCache) - { - dc = list_entry(l, DIR_CACHE, list); - ctime_r(&dc->atime.tv_sec, atime_buf); - ctime_r(&dc->mtime.tv_sec, mtime_buf); - ctime_r(&dc->ctime.tv_sec, ctime_buf); - - DbgPrint("Cache Entry: 0x%p\n" \ - " flags: 0x%x\n" \ - " jiffies: %llu\n" \ - " ino: %u\n" \ - " size: %llu\n" \ - " mode: 0%o\n" \ - " atime: %s\n" \ - " mtime: %s\n" \ - " ctime: %s\n" \ - " hash: 0x%x\n" \ - " len: %d\n" \ - " name: %s\n", - dc, dc->flags, dc->jiffies, - dc->ino, dc->size, dc->mode, - atime_buf, mtime_buf, ctime_buf, - dc->hash, dc->nameLen, dc->name); - } - } - } -#endif - return(0); -} - -/*++======================================================================*/ -void -NO_TRACE -Novfs_dump_inode( void *pf ) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - struct inode *inode; - void (*pfunc)(char *Fmt, ...) = pf; - PINODE_DATA id; - PDIR_CACHE dc; - struct list_head *il, *l; - char atime_buf[32]; - char mtime_buf[32]; - char ctime_buf[32]; - unsigned long icnt=0, dccnt=0; - - down( &InodeList_lock ); - list_for_each(il, &InodeList) - { - id = list_entry(il, INODE_DATA, IList); - inode = id->Inode; - if (inode) - { - icnt++; - - pfunc("Inode=0x%x I_ino=%d\n", inode, inode->i_ino); - - pfunc(" atime=%s\n", ctime_r(&inode->i_atime.tv_sec, atime_buf)); - pfunc(" ctime=%s\n", ctime_r(&inode->i_mtime.tv_sec, atime_buf)); - pfunc(" mtime=%s\n", ctime_r(&inode->i_ctime.tv_sec, atime_buf)); - pfunc(" size=%lld\n", inode->i_size); - pfunc(" mode=0%o\n", inode->i_mode); - } - - pfunc(" INODE_DATA: 0x%p Name=%s Scope=0x%p\n", id, id->Name, id->Scope); - - if (id->DirCache.next ) - { - list_for_each(l, &id->DirCache) - { - dccnt++; - dc = list_entry(l, DIR_CACHE, list); - ctime_r(&dc->atime.tv_sec, atime_buf); - ctime_r(&dc->mtime.tv_sec, mtime_buf); - ctime_r(&dc->ctime.tv_sec, ctime_buf); - - pfunc(" Cache Entry: 0x%p\n" \ - " flags: 0x%x\n" \ - " jiffies: %llu\n" \ - " ino: %u\n" \ - " size: %llu\n" \ - " mode: 0%o\n" \ - " atime: %s\n" \ - " mtime: %s\n" \ - " ctime: %s\n" \ - " hash: 0x%x\n" \ - " len: %d\n" \ - " name: %s\n", - dc, dc->flags, dc->jiffies, - dc->ino, dc->size, dc->mode, - atime_buf, mtime_buf, ctime_buf, - dc->hash, dc->nameLen, dc->name); - } - } - } - up( &InodeList_lock ); - - pfunc("Inodes: %d(%d) DirCache: %d(%d)\n", InodeCount, icnt, DCCount, dccnt ); - -} - -module_init(init_novfs) -module_exit(exit_novfs) - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Novell Inc."); -MODULE_DESCRIPTION("Novell NetWare Client for Linux"); -MODULE_VERSION( NOVFS_VERSION_STRING ); diff -uNr src.old/novfs/m src/novfs/m --- src.old/novfs/m 2006-07-11 21:24:18.000000000 +0200 +++ src/novfs/m 1970-01-01 01:00:00.000000000 +0100 @@ -1,12 +0,0 @@ -#!/bin/sh - -VERSION=`uname -r` - -make -C /usr/src/linux SUBDIRS=$PWD modules - -if [ -e novfs.ko ] -then - mkdir -p -m 755 /lib/modules/$VERSION/kernel/fs/novfs - echo "copying novfs.ko to /lib/modules/$VERSION/kernel/fs/novfs" - cp novfs.ko /lib/modules/$VERSION/kernel/fs/novfs -fi diff -uNr src.old/novfs/mk_novfs src/novfs/mk_novfs --- src.old/novfs/mk_novfs 2006-07-11 21:24:18.000000000 +0200 +++ src/novfs/mk_novfs 1970-01-01 01:00:00.000000000 +0100 @@ -1,113 +0,0 @@ -#!/bin/sh - -RVAL=1 -TO_BUILD=1 - -BUILD_TYPE=modules - -if [ $1 ] -then - if [ "$1" = "force" ] - then - FORCE=1 - else - BUILD_TYPE=$1 - FORCE=0 - fi -else - FORCE=0 -fi - - -if [ -d /usr/src/linux-obj/i386 ] -then - for i in $(ls /usr/src/linux-obj/i386) - do - TO_BUILD=1 - VERSION=`cat /usr/src/linux-obj/i386/$i/include/linux/version.h |grep UTS_RELEASE |awk '{printf("%s\n", substr($3, 2,length($3)-2))}'` - NOVFS_PATH=/lib/modules/$VERSION/kernel/fs/novfs - - if [ -e /lib/modules/$VERSION/extra/novfs.ko ] - then - NOVFS_PATH=/lib/modules/$VERSION/extra - - else - if [ -e /lib/modules/$VERSION/updates/novfs.ko ] - then - NOVFS_PATH=/lib/modules/$VERSION/updates - - fi - fi - - if [ -d /lib/modules/$VERSION ] - then - - if [ -e $NOVFS_PATH/novfs.ko ] - then - CUR_NOVFS_VERSION=`od --strings=8 $NOVFS_PATH/novfs.ko |grep version= |awk '{split($2,a,"="); if("version"==a[1]) printf("%s", a[2])}'` - CUR_NOVFS_VFS_MAJOR=`echo $CUR_NOVFS_VERSION |awk '{split($0,a,"."); printf("%d", a[1])}'` - CUR_NOVFS_VFS_MINOR=`echo $CUR_NOVFS_VERSION |awk '{split($0,a,"."); printf("%d", a[2])}'` - CUR_NOVFS_VFS_SUB=`echo $CUR_NOVFS_VERSION |awk '{split($0,a,"."); printf("%d", a[3])}'` - CUR_NOVFS_VFS_RELEASE=`echo $CUR_NOVFS_VERSION |awk '{split($0,a,"-"); printf("%d", a[2])}'` - - NOVFS_VFS_MAJOR=`cat Makefile |grep 'NOVFS_VFS_MAJOR =' |awk '{printf("%d", $3)}'` - NOVFS_VFS_MINOR=`cat Makefile |grep 'NOVFS_VFS_MINOR =' |awk '{printf("%d", $3)}'` - NOVFS_VFS_SUB=`cat Makefile |grep 'NOVFS_VFS_SUB =' |awk '{printf("%d", $3)}'` - NOVFS_VFS_RELEASE=`cat Makefile |grep 'NOVFS_VFS_RELEASE =' |awk '{printf("%d", $3)}'` - NOVFS_VFS_VERSION="$NOVFS_VFS_MAJOR.$NOVFS_VFS_MINOR.$NOVFS_VFS_SUB-$NOVFS_VFS_RELEASE" - - TO_BUILD=0 - - if [ $NOVFS_VFS_MAJOR -gt $CUR_NOVFS_VFS_MAJOR ] - then - TO_BUILD=1 - else - if [ $NOVFS_VFS_MAJOR -eq $CUR_NOVFS_VFS_MAJOR ] - then - if [ $NOVFS_VFS_MINOR -gt $CUR_NOVFS_VFS_MINOR ] - then - TO_BUILD=1 - else - if [ $NOVFS_VFS_MINOR -eq $CUR_NOVFS_VFS_MINOR ] - then - if [ $NOVFS_VFS_SUB -gt $CUR_NOVFS_VFS_SUB ] - then - TO_BUILD=1 - else - if [ $NOVFS_VFS_SUB -eq $CUR_NOVFS_VFS_SUB ] - then - if [ $NOVFS_VFS_RELEASE -gt $CUR_NOVFS_VFS_RELEASE ] - then - TO_BUILD=1 - fi - fi - fi - fi - fi - fi - fi - fi - - if [ $FORCE -eq 1 ] - then - TO_BUILD=1; - fi - - if [ $TO_BUILD -eq 1 ] - then - echo Building novfs.ko for $VERSION - make -C /usr/src/linux-obj/i386/$i SUBDIRS=$PWD $BUILD_TYPE - RVAL=$? - if [ -e novfs.ko ] - then - mkdir -p -m 755 $NOVFS_PATH - echo "copying novfs.ko to $NOVFS_PATH" - cp novfs.ko $NOVFS_PATH - RVAL=$? - fi - fi - fi - done -fi -exit $RVAL - diff -uNr src.old/novfs/nwcapi.c src/novfs/nwcapi.c --- src.old/novfs/nwcapi.c 2006-07-11 21:24:18.000000000 +0200 +++ src/novfs/nwcapi.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,2410 +0,0 @@ -/*++======================================================================== - * Program Name: Novell NCP Redirector for Linux - * File Name: nwcapi.c - * Version: v1.00 - * Author: James Turner/Richard Williams - * - * Abstract: This module contains functions used to interface to - * the library interface of the daemon. - * Notes: - * Revision History: - * - * - * Copyright (C) 2005 Novell, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - *======================================================================--*/ - -/*===[ Include files specific to Linux ]==================================*/ - -/*===[ Include files specific to this module ]============================*/ -#include -#include -#include -#include -#include -#include -#include -#include - -#include "nwcapi.h" -#include "nwerror.h" -#include "commands.h" - -#include "vfs.h" - -/*===[ External data ]====================================================*/ - -/*===[ External prototypes ]==============================================*/ - -extern int DbgPrint( char *Fmt, ... ); -extern void mydump(int size, void *dumpptr); - -extern session_t Scope_Get_SessionId( void *Scope ); -extern int Queue_Daemon_Command(void *request, u_long reqlen, void *data, int dlen, void **reply, u_long *replen, int interruptible); - -extern int do_login(NclString *Server, NclString *Username, NclString *Password, u_long *lgnId, session_t Session); - -void GetUserData(NwcScanConnInfo *connInfo, PXPLAT_CALL_REQUEST cmd, PXPLAT_CALL_REPLY reply); -void GetConnData(NwcGetConnInfo *connInfo, PXPLAT_CALL_REQUEST cmd, PXPLAT_CALL_REPLY reply); - -/*===[ Manifest constants ]===============================================*/ - -/*===[ Type definitions ]=================================================*/ - -/*===[ Function prototypes ]==============================================*/ - -/*===[ Global variables ]=================================================*/ - -/*===[ Code ]=============================================================*/ - -/*++======================================================================*/ - -/*++======================================================================*/ -int NwOpenConnByName(PXPLAT pdata, u_long *Handle, session_t Session) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ -PXPLAT_CALL_REQUEST cmd; -PXPLAT_CALL_REPLY reply; -PNwdCOpenConnByName openConn, connReply; -NwcOpenConnByName ocbn; -u_long retCode = 0, cmdlen, datalen, replylen, cpylen; -char *data; - - cpylen = copy_from_user(&ocbn, pdata->reqData, sizeof(ocbn)); - datalen = sizeof(*openConn) + strlen_user(ocbn.pName->pString) + strlen_user(ocbn.pServiceType); - cmdlen = datalen + sizeof(*cmd); - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - cmd->NwcCommand = NWC_OPEN_CONN_BY_NAME; - - cmd->dataLen = datalen; - openConn = (PNwdCOpenConnByName)cmd->data; - - openConn->nameLen = strlen_user(ocbn.pName->pString); - openConn->serviceLen = strlen_user(ocbn.pServiceType); - openConn->uConnFlags = ocbn.uConnFlags; - openConn->ConnHandle = ocbn.ConnHandle; - data = (char *)openConn; - data += sizeof(*openConn); - openConn->oName = sizeof(*openConn); - - openConn->oServiceType = openConn->oName + openConn->nameLen; - cpylen = copy_from_user(data, ocbn.pName->pString, openConn->nameLen); - data += openConn->nameLen; - cpylen = copy_from_user(data, ocbn.pServiceType, openConn->serviceLen); - - retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - /* - * we got reply data from the daemon - */ - connReply = (PNwdCOpenConnByName)reply->data; - retCode = reply->Reply.ErrorCode; - if (!retCode) - { - /* - * we got valid data. - */ - connReply = (PNwdCOpenConnByName)reply->data; - ocbn.RetConnHandle = connReply->newConnHandle; - *Handle = connReply->newConnHandle; - cpylen = copy_to_user(pdata->reqData, &ocbn, sizeof(ocbn)); - DbgPrint("New Conn Handle = %X\n", connReply->newConnHandle); - } - Novfs_Free(reply); - } - - Novfs_Free(cmd); - } - - return((int)retCode); - -} - -/*++======================================================================*/ -int NwOpenConnByAddr(PXPLAT pdata, u_long *Handle, session_t Session) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ -PXPLAT_CALL_REQUEST cmd; -PXPLAT_CALL_REPLY reply; -PNwdCOpenConnByAddr openConn, connReply; -NwcOpenConnByAddr ocba; -NwcTranAddr tranAddr; -u_long retCode = 0, cmdlen, datalen, replylen, cpylen; -char addr[MAX_ADDRESS_LENGTH]; - - cpylen = copy_from_user(&ocba, pdata->reqData, sizeof(ocba)); - datalen = sizeof(*openConn); - cmdlen = datalen + sizeof(*cmd); - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - cmd->NwcCommand = NWC_OPEN_CONN_BY_ADDRESS; - cmd->dataLen = datalen; - openConn = (PNwdCOpenConnByAddr)cmd->data; - - cpylen = copy_from_user(&tranAddr, ocba.pTranAddr, sizeof(tranAddr)); - - DbgPrint("NwOpenConnByAddr: tranAddr\n"); - mydump(sizeof(tranAddr), &tranAddr); - - openConn->TranAddr.uTransportType = tranAddr.uTransportType; - openConn->TranAddr.uAddressLength = tranAddr.uAddressLength; - memset(addr, 0xcc, sizeof(addr)-1); - - cpylen = copy_from_user(addr, tranAddr.puAddress, tranAddr.uAddressLength); - - DbgPrint("NwOpenConnByAddr: addr\n"); - mydump(sizeof(addr), addr); - - openConn->TranAddr.oAddress = *(u_long *)(&addr[2]); - - retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - /* - * we got reply data from the daemon - */ - connReply = (PNwdCOpenConnByAddr)reply->data; - retCode = reply->Reply.ErrorCode; - if (!retCode) - { - /* - * we got valid data. - */ - connReply = (PNwdCOpenConnByAddr)reply->data; - ocba.ConnHandle = connReply->ConnHandle; - *Handle = connReply->ConnHandle; - cpylen = copy_to_user(pdata->reqData, &ocba, sizeof(ocba)); - DbgPrint("New Conn Handle = %X\n", connReply->ConnHandle); - } - Novfs_Free(reply); - } - - Novfs_Free(cmd); - } - - return(retCode); - -} - -/*++======================================================================*/ -int NwOpenConnByRef(PXPLAT pdata, u_long *Handle, session_t Session) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ -PXPLAT_CALL_REQUEST cmd; -PXPLAT_CALL_REPLY reply; -PNwdCOpenConnByRef openConn; -NwcOpenConnByReference ocbr; -u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen; - - - cpylen = copy_from_user(&ocbr, pdata->reqData, sizeof(ocbr)); - datalen = sizeof(*openConn); - cmdlen = datalen + sizeof(*cmd); - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - cmd->NwcCommand = NWC_OPEN_CONN_BY_REFERENCE; - cmd->dataLen = datalen; - openConn = (PNwdCOpenConnByRef)cmd->data; - - memcpy(openConn, &ocbr, sizeof(ocbr)); - retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - /* - * we got reply data from the daemon - */ - openConn = (PNwdCOpenConnByRef)reply->data; - retCode = reply->Reply.ErrorCode; - if (!retCode) - { - /* - * we got valid data. - */ - ocbr.ConnHandle = openConn->ConnHandle; - *Handle = openConn->ConnHandle; - - cpylen = copy_to_user(pdata->reqData, &ocbr, sizeof(ocbr)); - DbgPrint("New Conn Handle = %X\n", openConn->ConnHandle); - } - Novfs_Free(reply); - } - - Novfs_Free(cmd); - } - return(retCode); - -} - -/*++======================================================================*/ -int NwRawSend(PXPLAT pdata, session_t Session) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ -NwcRequest xRequest; -PNwcFrag frag, cFrag, reqFrag; -PXPLAT_CALL_REQUEST cmd; -PXPLAT_CALL_REPLY reply; -u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen; -u_long x, totalLen; -PNwdCNCPReq ncpData; -PNwdCNCPRep ncpReply; -u_char *reqData; -unsigned long actualReplyLength=0; - - DbgPrint("[XPLAT] Process Raw NCP Send\n"); - cpylen = copy_from_user(&xRequest, pdata->reqData, sizeof(xRequest)); - - /* - * Figure out the length of the request - */ - frag = Novfs_Malloc(xRequest.uNumReplyFrags * sizeof(NwcFrag), GFP_KERNEL); - - DbgPrint("[XPLAT RawNCP] - Reply Frag Count 0x%X\n", xRequest.uNumReplyFrags); - - if (!frag) - return(retCode); - - cpylen = copy_from_user(frag, xRequest.pReplyFrags, xRequest.uNumReplyFrags * sizeof(NwcFrag)); - totalLen = 0; - - cFrag = frag; - for (x = 0; x < xRequest.uNumReplyFrags; x ++) - { - DbgPrint("[XPLAT - RawNCP] - Frag Len = %d\n", cFrag->uLength); - totalLen += cFrag->uLength; - cFrag++; - } - - - DbgPrint("[XPLAT - RawNCP] - totalLen = %d\n", totalLen); - datalen = 0; - reqFrag = Novfs_Malloc(xRequest.uNumRequestFrags * sizeof(NwcFrag), GFP_KERNEL); - if (!reqFrag) - { - Novfs_Free(frag); - return(retCode); - } - - cpylen = copy_from_user(reqFrag, xRequest.pRequestFrags, xRequest.uNumRequestFrags * sizeof(NwcFrag)); - cFrag = reqFrag; - for (x = 0; x < xRequest.uNumRequestFrags; x ++) - { - datalen += cFrag->uLength; - cFrag++; - } - - /* - * Allocate the cmd Request - */ - cmdlen = datalen + sizeof(*cmd) + sizeof(*ncpData); - DbgPrint("[XPLAT RawNCP] - Frag Count 0x%X\n", xRequest.uNumRequestFrags); - DbgPrint("[XPLAT RawNCP] - Total Command Data Len = %x\n", cmdlen); - - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - cmd->NwcCommand = NWC_RAW_NCP_REQUEST; - - /* - * build the NCP Request - */ - cmd->dataLen = cmdlen - sizeof(*cmd); - ncpData = (PNwdCNCPReq)cmd->data; - ncpData->replyLen = totalLen; - ncpData->requestLen = datalen; - ncpData->ConnHandle = xRequest.ConnHandle; - ncpData->function = xRequest.uFunction; - - - reqData = ncpData->data; - cFrag = reqFrag; - - for (x = 0; x < xRequest.uNumRequestFrags; x ++) - { - cpylen = copy_from_user(reqData, cFrag->pData, cFrag->uLength); - reqData += cFrag->uLength; - cFrag++; - } - - retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); - DbgPrint("RawNCP - reply = %x\n", reply); - DbgPrint("RawNCP - retCode = %x\n", retCode); - - if (reply) - { - /* - * we got reply data from the daemon - */ - ncpReply = (PNwdCNCPRep)reply->data; - retCode = reply->Reply.ErrorCode; - - DbgPrint("RawNCP - Reply Frag Count 0x%X\n", xRequest.uNumReplyFrags); - - /* - * We need to copy the reply frags to the packet. - */ - reqData = ncpReply->data; - cFrag = frag; - - totalLen = ncpReply->replyLen; - for (x = 0; x < xRequest.uNumReplyFrags; x ++) - { - - DbgPrint("RawNCP - Copy Frag %d: 0x%X\n", x, cFrag->uLength); - - datalen = min(cFrag->uLength, totalLen); - - cpylen = copy_to_user(cFrag->pData, reqData, datalen); - totalLen -= datalen; - reqData += datalen; - actualReplyLength += datalen; - - cFrag++; - } - - Novfs_Free(reply); - } - else - { - retCode = -EIO; - } - - Novfs_Free(cmd); - } - xRequest.uActualReplyLength = actualReplyLength; - cpylen = copy_to_user(pdata->reqData, &xRequest, sizeof(xRequest)); - - Novfs_Free(reqFrag); - Novfs_Free(frag); - - return(retCode); -} - -/*++======================================================================*/ -int NwConnClose(PXPLAT pdata, u_long *Handle, session_t Session) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ -PXPLAT_CALL_REQUEST cmd; -PXPLAT_CALL_REPLY reply; -NwcCloseConn cc; -PNwdCCloseConn nwdClose; -u_long retCode = 0, cmdlen, datalen, replylen, cpylen; - - cpylen = copy_from_user(&cc, pdata->reqData, sizeof(cc)); - - datalen = sizeof(*nwdClose); - cmdlen = datalen + sizeof(*cmd); - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - cmd->NwcCommand = NWC_CLOSE_CONN; - - nwdClose = (PNwdCCloseConn)cmd->data; - cmd->dataLen = sizeof(*nwdClose); - nwdClose->ConnHandle = cc.ConnHandle; - *Handle = cc.ConnHandle; - - /* - * send the request - */ - retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, 0); - if (reply) - { - retCode = reply->Reply.ErrorCode; - Novfs_Free(reply); - } - Novfs_Free(cmd); - - } - - return(retCode); - -} - -/*++======================================================================*/ -int NwSysConnClose(PXPLAT pdata, u_long *Handle, session_t Session) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ -PXPLAT_CALL_REQUEST cmd; -PXPLAT_CALL_REPLY reply; -NwcCloseConn cc; -PNwdCCloseConn nwdClose; -u_long retCode = 0, cmdlen, datalen, replylen, cpylen; - - cpylen = copy_from_user(&cc, pdata->reqData, sizeof(cc)); - - datalen = sizeof(*nwdClose); - cmdlen = datalen + sizeof(*cmd); - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - cmd->NwcCommand = NWC_SYS_CLOSE_CONN; - - nwdClose = (PNwdCCloseConn)cmd->data; - cmd->dataLen = sizeof(*nwdClose); - nwdClose->ConnHandle = cc.ConnHandle; - *Handle = cc.ConnHandle; - - /* - * send the request - */ - retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, 0); - if (reply) - { - retCode = reply->Reply.ErrorCode; - Novfs_Free(reply); - } - Novfs_Free(cmd); - - } - - return(retCode); - -} - -/*++======================================================================*/ -int NwLoginIdentity(PXPLAT pdata, session_t Session) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ -NwcLoginIdentity lgn, *plgn; -int retCode = -ENOMEM; -NclString server; -NclString username; -NclString password; -u_long cpylen; -NwcString nwcStr; - - cpylen = copy_from_user(&lgn, pdata->reqData, sizeof(lgn)); - - DbgPrint("NwLoginIdentity:\n"); - mydump(sizeof(lgn), &lgn); - - - - cpylen = copy_from_user(&nwcStr, lgn.pDomainName, sizeof(nwcStr)); - DbgPrint("NwLoginIdentity: DomainName\n"); - mydump(sizeof(nwcStr), &nwcStr); - - if ( (server.buffer = Novfs_Malloc(nwcStr.DataLen, GFP_KERNEL)) ) - { - server.type = nwcStr.DataType; - server.len = nwcStr.DataLen; - if ( !copy_from_user((void *)server.buffer, nwcStr.pBuffer, server.len) ) - { - DbgPrint("NwLoginIdentity: Server\n"); - mydump(server.len, server.buffer); - - cpylen = copy_from_user(&nwcStr, lgn.pObjectName, sizeof(nwcStr)); - DbgPrint("NwLoginIdentity: ObjectName\n"); - mydump(sizeof(nwcStr), &nwcStr); - - if ( (username.buffer = Novfs_Malloc(nwcStr.DataLen, GFP_KERNEL)) ) - { - username.type = nwcStr.DataType; - username.len = nwcStr.DataLen; - if ( !copy_from_user((void *)username.buffer, nwcStr.pBuffer, username.len) ) - { - DbgPrint("NwLoginIdentity: User\n"); - mydump(username.len, username.buffer); - - cpylen = copy_from_user(&nwcStr, lgn.pPassword, sizeof(nwcStr)); - DbgPrint("NwLoginIdentity: Password\n"); - mydump(sizeof(nwcStr), &nwcStr); - - if ( (password.buffer = Novfs_Malloc(nwcStr.DataLen, GFP_KERNEL)) ) - { - password.type = nwcStr.DataType; - password.len = nwcStr.DataLen; - if ( !copy_from_user((void *)password.buffer, nwcStr.pBuffer, password.len) ) - { - retCode = do_login(&server, &username, &password, (u_long *)&lgn.AuthenticationId, Session); - if (retCode) - { - lgn.AuthenticationId = 0; - } - - plgn = (NwcLoginIdentity *)pdata->reqData; - cpylen = copy_to_user(&plgn->AuthenticationId, &lgn.AuthenticationId, sizeof(plgn->AuthenticationId)); - - } - memset(password.buffer, 0, password.len); - Novfs_Free(password.buffer); - } - } - memset(username.buffer, 0, username.len); - Novfs_Free(username.buffer); - } - } - Novfs_Free(server.buffer); - } - return(retCode); -} - -/*++======================================================================*/ -int NwAuthConnWithId(PXPLAT pdata, session_t Session) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ -NwcAuthenticateWithId pauth; -PNwdCAuthenticateWithId pDauth; -PXPLAT_CALL_REQUEST cmd; -PXPLAT_CALL_REPLY reply; -u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen; - - datalen = sizeof(*pDauth); - cmdlen = datalen + sizeof(*cmd); - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - cmd->NwcCommand = NWC_AUTHENTICATE_CONN_WITH_ID; - - - cpylen = copy_from_user(&pauth, pdata->reqData, sizeof(pauth)); - - pDauth = (PNwdCAuthenticateWithId)cmd->data; - cmd->dataLen = datalen; - pDauth->AuthenticationId = pauth.AuthenticationId; - pDauth->ConnHandle = pauth.ConnHandle; - - retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - retCode = reply->Reply.ErrorCode; - Novfs_Free(reply); - } - Novfs_Free(cmd); - } - return(retCode); -} - -/*++======================================================================*/ -int NwLicenseConn(PXPLAT pdata, session_t Session) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ -PXPLAT_CALL_REQUEST cmd; -PXPLAT_CALL_REPLY reply; -NwcLicenseConn lisc; -PNwdCLicenseConn pDLisc; -u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen; - - datalen = sizeof(*pDLisc); - cmdlen = datalen + sizeof(*cmd); - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - cmd->NwcCommand = NWC_LICENSE_CONN; - - - cpylen = copy_from_user(&lisc, pdata->reqData, sizeof(lisc)); - - pDLisc = (PNwdCLicenseConn)cmd->data; - cmd->dataLen = datalen; - pDLisc->ConnHandle = lisc.ConnHandle; - - retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - retCode = reply->Reply.ErrorCode; - Novfs_Free(reply); - } - Novfs_Free(cmd); - } - return(retCode); -} - - -/*++======================================================================*/ -int NwLogoutIdentity(PXPLAT pdata, session_t Session) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ -PXPLAT_CALL_REQUEST cmd; -PXPLAT_CALL_REPLY reply; -NwcLogoutIdentity logout; -PNwdCLogoutIdentity pDLogout; -u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen; - - datalen = sizeof(*pDLogout); - cmdlen = datalen + sizeof(*cmd); - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - cmd->NwcCommand = NWC_LOGOUT_IDENTITY; - - cpylen = copy_from_user(&logout, pdata->reqData, sizeof(logout)); - - pDLogout = (PNwdCLogoutIdentity)cmd->data; - cmd->dataLen = datalen; - pDLogout->AuthenticationId = logout.AuthenticationId; - - retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - retCode = reply->Reply.ErrorCode; - Novfs_Free(reply); - } - Novfs_Free(cmd); - } - return(retCode); -} - -/*++======================================================================*/ -int NwUnlicenseConn(PXPLAT pdata, session_t Session) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ -PXPLAT_CALL_REQUEST cmd; -PXPLAT_CALL_REPLY reply; -PNwdCUnlicenseConn pUconn; -NwcUnlicenseConn ulc; -u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen; - - - cpylen = copy_from_user(&ulc, pdata->reqData, sizeof(ulc)); - datalen = sizeof(*pUconn); - cmdlen = datalen + sizeof(*cmd); - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - cmd->NwcCommand = NWC_UNLICENSE_CONN; - cmd->dataLen = datalen; - pUconn = (PNwdCUnlicenseConn)cmd->data; - - pUconn->ConnHandle = ulc.ConnHandle; - retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - /* - * we got reply data from the daemon - */ - retCode = reply->Reply.ErrorCode; - Novfs_Free(reply); - } - - Novfs_Free(cmd); - } - return(retCode); - -} - - -/*++======================================================================*/ -int NwUnAuthenticate(PXPLAT pdata, session_t Session) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ -PXPLAT_CALL_REQUEST cmd; -PXPLAT_CALL_REPLY reply; -NwcUnauthenticate auth; -PNwdCUnauthenticate pDAuth; -u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen; - - datalen = sizeof(*pDAuth); - cmdlen = datalen + sizeof(*cmd); - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - cmd->NwcCommand = NWC_UNAUTHENTICATE_CONN; - - cpylen = copy_from_user(&auth, pdata->reqData, sizeof(auth)); - - pDAuth = (PNwdCUnauthenticate)cmd->data; - cmd->dataLen = datalen; - pDAuth->AuthenticationId = auth.AuthenticationId; - pDAuth->ConnHandle = auth.ConnHandle; - - retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - retCode = reply->Reply.ErrorCode; - Novfs_Free(reply); - } - Novfs_Free(cmd); - } - return(retCode); - -} - - -/*++======================================================================*/ -int NwGetConnInfo(PXPLAT pdata, session_t Session) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ -PXPLAT_CALL_REQUEST cmd; -PXPLAT_CALL_REPLY reply; -NwcGetConnInfo connInfo; -PNwdCGetConnInfo pDConnInfo; -u_long retCode = -ENOMEM, cmdlen, replylen, cpylen; - - cmdlen = sizeof(*cmd) + sizeof(*pDConnInfo); - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - cpylen = copy_from_user(&connInfo, pdata->reqData, sizeof(NwcGetConnInfo)); - - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - cmd->NwcCommand = NWC_GET_CONN_INFO; - - pDConnInfo = (PNwdCGetConnInfo)cmd->data; - - pDConnInfo->ConnHandle = connInfo.ConnHandle; - pDConnInfo->uInfoLevel = connInfo.uInfoLevel; - pDConnInfo->uInfoLength = connInfo.uInfoLength; - cmd->dataLen = sizeof(*pDConnInfo); - - retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - retCode = reply->Reply.ErrorCode; - GetConnData(&connInfo, cmd, reply); - - Novfs_Free(reply); - } - Novfs_Free(cmd); - - } - - return(retCode); - -} - - -/*++======================================================================*/ -int NwSetConnInfo(PXPLAT pdata, session_t Session) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ -PXPLAT_CALL_REQUEST cmd; -PXPLAT_CALL_REPLY reply; -NwcSetConnInfo connInfo; -PNwdCSetConnInfo pDConnInfo; -u_long retCode = -ENOMEM, cmdlen, replylen, cpylen; - - cmdlen = sizeof(*cmd) + sizeof(*pDConnInfo); - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - cpylen = copy_from_user(&connInfo, pdata->reqData, sizeof(NwcSetConnInfo)); - - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - cmd->NwcCommand = NWC_SET_CONN_INFO; - - pDConnInfo = (PNwdCSetConnInfo)cmd->data; - - pDConnInfo->ConnHandle = connInfo.ConnHandle; - pDConnInfo->uInfoLevel = connInfo.uInfoLevel; - pDConnInfo->uInfoLength = connInfo.uInfoLength; - cmd->dataLen = sizeof(*pDConnInfo); - - retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - retCode = reply->Reply.ErrorCode; - Novfs_Free(reply); - } - Novfs_Free(cmd); - - } - - return(retCode); - -} - -/*++======================================================================*/ -int NwGetIdentityInfo(PXPLAT pdata, session_t Session) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ -PXPLAT_CALL_REQUEST cmd; -PXPLAT_CALL_REPLY reply; -NwcGetIdentityInfo qidInfo, *gId; -PNwdCGetIdentityInfo idInfo; -NwcString xferStr; -char *str; -u_long retCode = -ENOMEM, cmdlen, replylen, cpylen; - - cmdlen = sizeof(*cmd) + sizeof(*idInfo); - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - cpylen = copy_from_user(&qidInfo, pdata->reqData, sizeof(qidInfo)); - - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - cmd->NwcCommand = NWC_GET_IDENTITY_INFO; - - idInfo = (PNwdCGetIdentityInfo)cmd->data; - - idInfo->AuthenticationId = qidInfo.AuthenticationId; - cmd->dataLen = sizeof(*idInfo); - - retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - retCode = reply->Reply.ErrorCode; - - if (!reply->Reply.ErrorCode) - { - /* - * Save the return info to the user structure. - */ - gId = pdata->reqData; - idInfo = (PNwdCGetIdentityInfo)reply->data; - cpylen = copy_to_user(&gId->AuthenticationId, &idInfo->AuthenticationId, sizeof(idInfo->AuthenticationId)); - cpylen = copy_to_user(&gId->AuthType, &idInfo->AuthType, sizeof(idInfo->AuthType)); - cpylen = copy_to_user(&gId->IdentityFlags, &idInfo->IdentityFlags, sizeof(idInfo->IdentityFlags)); - cpylen = copy_to_user(&gId->NameType, &idInfo->NameType, sizeof(idInfo->NameType)); - cpylen = copy_to_user(&gId->ObjectType, &idInfo->ObjectType, sizeof(idInfo->ObjectType)); - - cpylen = copy_from_user(&xferStr, gId->pDomainName, sizeof(NwcString)); - str = (char *)((char *)reply->data + idInfo->pDomainNameOffset); - cpylen = copy_to_user(xferStr.pBuffer, str, idInfo->domainLen); - xferStr.DataType = NWC_STRING_TYPE_ASCII; - xferStr.DataLen = idInfo->domainLen; - cpylen = copy_to_user(gId->pDomainName, &xferStr, sizeof(NwcString)); - - - cpylen = copy_from_user(&xferStr, gId->pObjectName, sizeof(NwcString)); - str = (char *)((char *)reply->data + idInfo->pObjectNameOffset); - cpylen = copy_to_user(xferStr.pBuffer, str, idInfo->objectLen); - xferStr.DataLen = idInfo->objectLen - 1; - xferStr.DataType = NWC_STRING_TYPE_ASCII; - cpylen = copy_to_user(gId->pObjectName, &xferStr, sizeof(NwcString)); - } - - Novfs_Free(reply); - } - Novfs_Free(cmd); - - } - - return(retCode); -} - -/*++======================================================================*/ -int NwScanConnInfo(PXPLAT pdata, session_t Session) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ -PXPLAT_CALL_REQUEST cmd; -PXPLAT_CALL_REPLY reply; -NwcScanConnInfo connInfo, *rInfo; -PNwdCScanConnInfo pDConnInfo; -u_long retCode = -ENOMEM, cmdlen, replylen, cpylen; -u_char *localData; - - cpylen = copy_from_user(&connInfo, pdata->reqData, sizeof(NwcScanConnInfo)); - - cmdlen = sizeof(*cmd) + sizeof(*pDConnInfo) + connInfo.uScanInfoLen; - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - cmd->NwcCommand = NWC_SCAN_CONN_INFO; - - pDConnInfo = (PNwdCScanConnInfo)cmd->data; - - DbgPrint("NwScanConnInfo: Input Data\n"); - DbgPrint("connInfo.uScanIndex = 0x%X\n", connInfo.uScanIndex); - DbgPrint("connInfo.uConnectionReference = 0x%X\n", connInfo.uConnectionReference); - DbgPrint("connInfo.uScanInfoLevel = 0x%X\n", connInfo.uScanInfoLevel); - DbgPrint("connInfo.uScanInfoLen = 0x%X\n", connInfo.uScanInfoLen); - DbgPrint("connInfo.uReturnInfoLength = 0x%X\n", connInfo.uReturnInfoLength); - DbgPrint("connInfo.uReturnInfoLevel = 0x%X\n", connInfo.uReturnInfoLevel); - DbgPrint("connInfo.uScanFlags = 0x%X\n", connInfo.uScanFlags); - - - pDConnInfo->uScanIndex = connInfo.uScanIndex; - pDConnInfo->uConnectionReference = connInfo.uConnectionReference; - pDConnInfo->uScanInfoLevel = connInfo.uScanInfoLevel; - pDConnInfo->uScanInfoLen = connInfo.uScanInfoLen; - pDConnInfo->uReturnInfoLength = connInfo.uReturnInfoLength; - pDConnInfo->uReturnInfoLevel = connInfo.uReturnInfoLevel; - pDConnInfo->uScanFlags = connInfo.uScanFlags; - - if (pDConnInfo->uScanInfoLen) - { - localData = (u_char *)pDConnInfo; - pDConnInfo->uScanConnInfoOffset = sizeof(*pDConnInfo); - localData += pDConnInfo->uScanConnInfoOffset; - cpylen = copy_from_user(localData, connInfo.pScanConnInfo, connInfo.uScanInfoLen); - } - else - { - pDConnInfo->uScanConnInfoOffset = 0; - } - - - cmd->dataLen = sizeof(*pDConnInfo); - - retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - DbgPrint("NwScanConnInfo: Reply recieved\n"); - DbgPrint(" NextIndex = %x\n", connInfo.uScanIndex); - DbgPrint(" ErrorCode = %x\n", reply->Reply.ErrorCode); - DbgPrint(" data = %x\n", reply->data); - - pDConnInfo = (PNwdCScanConnInfo)reply->data; - retCode = (u_long)reply->Reply.ErrorCode; - if (!retCode) - { - GetUserData(&connInfo, cmd, reply); - rInfo = (NwcScanConnInfo *)pdata->repData; - cpylen = copy_to_user(pdata->repData, &pDConnInfo->uScanIndex, sizeof(pDConnInfo->uScanIndex)); - cpylen = copy_to_user(&rInfo->uConnectionReference, &pDConnInfo->uConnectionReference, sizeof(pDConnInfo->uConnectionReference)); - } - else - { - u_long x; - - x = 0; - rInfo = (NwcScanConnInfo *)pdata->reqData; - cpylen = copy_to_user(&rInfo->uConnectionReference, &x, sizeof(rInfo->uConnectionReference)); - } - - Novfs_Free(reply); - } - else - { - retCode = -EIO; - } - Novfs_Free(cmd); - - } - - return(retCode); -} - -/*++======================================================================*/ -void GetUserData(NwcScanConnInfo *connInfo, PXPLAT_CALL_REQUEST cmd, PXPLAT_CALL_REPLY reply) -/* - * Abstract: Copies the user data out of the scan conn info call. - * - *========================================================================*/ - -{ -u_long uLevel; -PNwdCScanConnInfo pDConnInfo; - -u_char *srcData = NULL; -u_long dataLen = 0, cpylen; - - - pDConnInfo = (PNwdCScanConnInfo)reply->data; - uLevel = pDConnInfo->uReturnInfoLevel; - DbgPrint("[GetUserData] uLevel = %d, reply = 0x%X, reply->data = 0x%X\n", uLevel, reply, reply->data); - - switch(uLevel) - { - case NWC_CONN_INFO_RETURN_ALL: - case NWC_CONN_INFO_TRAN_ADDR: - case NWC_CONN_INFO_NDS_STATE: - case NWC_CONN_INFO_MAX_PACKET_SIZE: - case NWC_CONN_INFO_LICENSE_STATE: - case NWC_CONN_INFO_PUBLIC_STATE: - case NWC_CONN_INFO_SERVICE_TYPE: - case NWC_CONN_INFO_DISTANCE: - case NWC_CONN_INFO_SERVER_VERSION: - case NWC_CONN_INFO_AUTH_ID: - case NWC_CONN_INFO_SUSPENDED: - case NWC_CONN_INFO_WORKGROUP_ID: - case NWC_CONN_INFO_SECURITY_STATE: - case NWC_CONN_INFO_CONN_NUMBER: - case NWC_CONN_INFO_USER_ID: - case NWC_CONN_INFO_BCAST_STATE: - case NWC_CONN_INFO_CONN_REF: - case NWC_CONN_INFO_AUTH_STATE: - case NWC_CONN_INFO_TREE_NAME: - case NWC_CONN_INFO_SERVER_NAME: - case NWC_CONN_INFO_VERSION: - srcData = (u_char *)pDConnInfo; - srcData += pDConnInfo->uReturnConnInfoOffset; - dataLen = pDConnInfo->uReturnInfoLength; - break; - - case NWC_CONN_INFO_RETURN_NONE: - case NWC_CONN_INFO_TREE_NAME_UNICODE: - case NWC_CONN_INFO_SERVER_NAME_UNICODE: - case NWC_CONN_INFO_LOCAL_TRAN_ADDR: - case NWC_CONN_INFO_ALTERNATE_ADDR: - case NWC_CONN_INFO_SERVER_GUID: - default: - break; - } - - if (srcData && dataLen) - { - DbgPrint("Copy Data in GetUserData 0x%X -> 0x%X :: 0x%X\n", - srcData, connInfo->pReturnConnInfo, dataLen); - cpylen = copy_to_user(connInfo->pReturnConnInfo, srcData, dataLen); - } - - return; -} - -/*++======================================================================*/ -void GetConnData(NwcGetConnInfo *connInfo, PXPLAT_CALL_REQUEST cmd, PXPLAT_CALL_REPLY reply) -/* - * Abstract: Copies the user data out of the scan conn info call. - * - *========================================================================*/ - -{ -u_long uLevel; -PNwdCGetConnInfo pDConnInfo; - -u_char *srcData = NULL; -u_long dataLen = 0, cpylen; - - - pDConnInfo = (PNwdCGetConnInfo)cmd->data; - uLevel = pDConnInfo->uInfoLevel; - - switch(uLevel) - { - case NWC_CONN_INFO_RETURN_ALL: - srcData = (u_char *)reply->data; - dataLen = reply->dataLen; - break; - - case NWC_CONN_INFO_RETURN_NONE: - dataLen = 0; - break; - - case NWC_CONN_INFO_TRAN_ADDR: - { - u_char *dstData = connInfo->pConnInfo; - NwcTranAddr tranAddr; - - srcData = (u_char *)reply->data; - - cpylen = copy_from_user(&tranAddr, dstData, sizeof(tranAddr)); - tranAddr.uTransportType = ((PNwdTranAddr)srcData)->uTransportType; - tranAddr.uAddressLength = ((PNwdTranAddr)srcData)->uAddressLength; - cpylen = copy_to_user(dstData, &tranAddr, sizeof(tranAddr)); - cpylen = copy_to_user(tranAddr.puAddress, ((PNwdTranAddr)srcData)->Buffer, ((PNwdTranAddr)srcData)->uAddressLength); - dataLen=0; - break; - } - case NWC_CONN_INFO_NDS_STATE: - case NWC_CONN_INFO_MAX_PACKET_SIZE: - case NWC_CONN_INFO_LICENSE_STATE: - case NWC_CONN_INFO_PUBLIC_STATE: - case NWC_CONN_INFO_SERVICE_TYPE: - case NWC_CONN_INFO_DISTANCE: - case NWC_CONN_INFO_SERVER_VERSION: - case NWC_CONN_INFO_AUTH_ID: - case NWC_CONN_INFO_SUSPENDED: - case NWC_CONN_INFO_WORKGROUP_ID: - case NWC_CONN_INFO_SECURITY_STATE: - case NWC_CONN_INFO_CONN_NUMBER: - case NWC_CONN_INFO_USER_ID: - case NWC_CONN_INFO_BCAST_STATE: - case NWC_CONN_INFO_CONN_REF: - case NWC_CONN_INFO_AUTH_STATE: - case NWC_CONN_INFO_VERSION: - case NWC_CONN_INFO_SERVER_NAME: - case NWC_CONN_INFO_TREE_NAME: - srcData = (u_char *)reply->data; - dataLen = reply->dataLen; - break; - - case NWC_CONN_INFO_TREE_NAME_UNICODE: - case NWC_CONN_INFO_SERVER_NAME_UNICODE: - break; - - case NWC_CONN_INFO_LOCAL_TRAN_ADDR: - break; - - case NWC_CONN_INFO_ALTERNATE_ADDR: - break; - - case NWC_CONN_INFO_SERVER_GUID: - break; - - default: - break; - } - - if (srcData && dataLen) - { - cpylen = copy_to_user(connInfo->pConnInfo, srcData, connInfo->uInfoLength); - } - - return; -} - -/*++======================================================================*/ -int NwGetDaemonVersion(PXPLAT pdata, session_t Session) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ - -{ -PXPLAT_CALL_REQUEST cmd; -PXPLAT_CALL_REPLY reply; -PNwdCGetRequesterVersion pDVersion; -u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen; - - datalen = sizeof(*pDVersion); - cmdlen = datalen + sizeof(*cmd); - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - cmd->NwcCommand = NWC_GET_REQUESTER_VERSION; - cmdlen = sizeof(*cmd); - retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - retCode = reply->Reply.ErrorCode; - pDVersion = (PNwdCGetRequesterVersion)reply->data; - cpylen = copy_to_user(pDVersion, pdata->reqData, sizeof(*pDVersion)); - Novfs_Free(reply); - } - Novfs_Free(cmd); - } - return(retCode); - -} - - -/*++======================================================================*/ -int NwcGetPreferredDSTree(PXPLAT pdata, session_t Session) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ - -{ -PXPLAT_CALL_REQUEST cmd; -PXPLAT_CALL_REPLY reply; -PNwdCGetPreferredDsTree pDGetTree; -NwcGetPreferredDsTree xplatCall, *p; -u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen; -u_char *dPtr; - - cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcGetPreferredDsTree)); - datalen = sizeof(*pDGetTree) + xplatCall.uTreeLength; - cmdlen = datalen + sizeof(*cmd); - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - cmd->NwcCommand = NWC_GET_PREFERRED_DS_TREE; - cmdlen = sizeof(*cmd); - - retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - retCode = reply->Reply.ErrorCode; - if (!retCode) - { - pDGetTree = (PNwdCGetPreferredDsTree)reply->data; - dPtr = reply->data + pDGetTree->DsTreeNameOffset; - p = (NwcGetPreferredDsTree *)pdata->reqData; - - DbgPrint("NwcGetPreferredDSTree: Reply recieved\n"); - DbgPrint(" TreeLen = %x\n", pDGetTree->uTreeLength); - DbgPrint(" TreeName = %s\n", dPtr); - - cpylen = copy_to_user(p, &pDGetTree->uTreeLength, 4); - cpylen = copy_to_user(xplatCall.pDsTreeName, dPtr, pDGetTree->uTreeLength); - } - Novfs_Free(reply); - } - Novfs_Free(cmd); - } - return(retCode); - -} - -/*++======================================================================*/ -int NwcSetPreferredDSTree(PXPLAT pdata, session_t Session) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ - -{ -PXPLAT_CALL_REQUEST cmd; -PXPLAT_CALL_REPLY reply; -PNwdCSetPreferredDsTree pDSetTree; -NwcSetPreferredDsTree xplatCall; -u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen; -u_char *dPtr; - - cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcSetPreferredDsTree)); - datalen = sizeof(*pDSetTree) + xplatCall.uTreeLength; - cmdlen = datalen + sizeof(*cmd); - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - cmd->NwcCommand = NWC_SET_PREFERRED_DS_TREE; - - pDSetTree = (PNwdCSetPreferredDsTree)cmd->data; - pDSetTree->DsTreeNameOffset = sizeof(*pDSetTree); - pDSetTree->uTreeLength = xplatCall.uTreeLength; - - dPtr = cmd->data + sizeof(*pDSetTree); - cpylen = copy_from_user(dPtr, xplatCall.pDsTreeName, xplatCall.uTreeLength); - - - retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - retCode = reply->Reply.ErrorCode; - Novfs_Free(reply); - } - Novfs_Free(cmd); - } - return(retCode); - -} - - -/*++======================================================================*/ -int NwcSetDefaultNameCtx(PXPLAT pdata, session_t Session) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ - -{ -PXPLAT_CALL_REQUEST cmd; -PXPLAT_CALL_REPLY reply; -NwcSetDefaultNameContext xplatCall; -PNwdCSetDefaultNameContext pDSet; -u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen; -u_char *dPtr; - - cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcSetDefaultNameContext)); - datalen = sizeof(*pDSet) + xplatCall.uTreeLength + xplatCall.uNameLength; - cmdlen = datalen + sizeof(*cmd); - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - cmd->NwcCommand = NWC_SET_DEFAULT_NAME_CONTEXT; - cmd->dataLen = sizeof(NwdCSetDefaultNameContext) + xplatCall.uTreeLength + xplatCall.uNameLength; - - pDSet = (PNwdCSetDefaultNameContext)cmd->data; - dPtr = cmd->data; - - pDSet->TreeOffset = sizeof(NwdCSetDefaultNameContext); - pDSet->uTreeLength = xplatCall.uTreeLength; - pDSet->NameContextOffset = pDSet->TreeOffset+xplatCall.uTreeLength; - pDSet->uNameLength = xplatCall.uNameLength; - - cpylen = copy_from_user(dPtr+pDSet->TreeOffset, xplatCall.pTreeName, xplatCall.uTreeLength); - cpylen = copy_from_user(dPtr+pDSet->NameContextOffset, xplatCall.pNameContext, xplatCall.uNameLength); - - retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - retCode = reply->Reply.ErrorCode; - Novfs_Free(reply); - } - Novfs_Free(cmd); - } - return(retCode); - -} - -/*++======================================================================*/ -int NwcGetDefaultNameCtx(PXPLAT pdata, session_t Session) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ - -{ -PXPLAT_CALL_REQUEST cmd; -PXPLAT_CALL_REPLY reply; -NwcGetDefaultNameContext xplatCall; -PNwdCGetDefaultNameContext pGet; -char *dPtr; -int retCode = -ENOMEM; -u_long cmdlen, replylen, cpylen; - - cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcGetDefaultNameContext)); - cmdlen = sizeof(*cmd) + sizeof(NwdCGetDefaultNameContext) + xplatCall.uTreeLength; - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - cmd->NwcCommand = NWC_GET_DEFAULT_NAME_CONTEXT; - cmd->dataLen = sizeof(NwdCGetDefaultNameContext)+xplatCall.uTreeLength; - - pGet = (PNwdCGetDefaultNameContext)cmd->data; - dPtr = cmd->data; - - pGet->TreeOffset = sizeof(NwdCGetDefaultNameContext); - pGet->uTreeLength = xplatCall.uTreeLength; - - cpylen = copy_from_user( dPtr + pGet->TreeOffset, xplatCall.pTreeName, xplatCall.uTreeLength); - dPtr[pGet->TreeOffset+pGet->uTreeLength] = 0; - - retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - retCode = reply->Reply.ErrorCode; - if (!retCode) - { - pGet = (PNwdCGetDefaultNameContext)reply->data; - - DbgPrint("NwcGetDefaultNameCtx: retCode=0x%x uNameLength1=%d uNameLength2=%d\n", retCode, pGet->uNameLength, xplatCall.uNameLength); - if (xplatCall.uNameLength < pGet->uNameLength) - { - pGet->uNameLength = xplatCall.uNameLength; - retCode = NWE_BUFFER_OVERFLOW; - } - dPtr = (char *)pGet + pGet->NameContextOffset; - cpylen = copy_to_user(xplatCall.pNameContext, dPtr, pGet->uNameLength); - } - - Novfs_Free(reply); - } - Novfs_Free(cmd); - } - return(retCode); - -} - -/*++======================================================================*/ -int NwQueryFeature(PXPLAT pdata, session_t Session) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - NwcQueryFeature xpCall; - int status = SUCCESS; - u_long cpylen; - - cpylen = copy_from_user(&xpCall, pdata->reqData, sizeof(NwcQueryFeature)); - switch (xpCall.Feature) - { - case NWC_FEAT_NDS: - case NWC_FEAT_NDS_MTREE: - case NWC_FEAT_PRN_CAPTURE: - case NWC_FEAT_NDS_RESOLVE: - - status = NWE_REQUESTER_FAILURE; - - } - return( status ); -} - -/*++======================================================================*/ -int NwcGetTreeMonitoredConn(PXPLAT pdata, session_t Session) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ -PXPLAT_CALL_REQUEST cmd; -PXPLAT_CALL_REPLY reply; -NwcGetTreeMonitoredConnRef xplatCall, *p; -PNwdCGetTreeMonitoredConnRef pDConnRef; -char *dPtr; -u_long status = -ENOMEM, cmdlen, datalen, replylen, cpylen; - - cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcGetTreeMonitoredConnRef)); - datalen = sizeof(*pDConnRef) + xplatCall.pTreeName->DataLen; - cmdlen = datalen + sizeof(*cmd); - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - cmd->NwcCommand = NWC_GET_TREE_MONITORED_CONN_REF; - - pDConnRef = (PNwdCGetTreeMonitoredConnRef)cmd->data; - pDConnRef->TreeName.boffset = sizeof(*pDConnRef); - pDConnRef->TreeName.len = xplatCall.pTreeName->DataLen; - pDConnRef->TreeName.type = xplatCall.pTreeName->DataType; - - dPtr = cmd->data + sizeof(*pDConnRef); - cpylen = copy_from_user(dPtr, xplatCall.pTreeName->pBuffer, pDConnRef->TreeName.len); - status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - pDConnRef = (PNwdCGetTreeMonitoredConnRef)reply->data; - dPtr = reply->data + pDConnRef->TreeName.boffset; - p = (NwcGetTreeMonitoredConnRef *)pdata->reqData; - cpylen = copy_to_user(&p->uConnReference, &pDConnRef->uConnReference, 4); - - status = reply->Reply.ErrorCode; - Novfs_Free(reply); - } - Novfs_Free(cmd); - - } - - return(status); -} - -/*++======================================================================*/ -int NwcEnumIdentities(PXPLAT pdata, session_t Session) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ -PXPLAT_CALL_REQUEST cmd; -PXPLAT_CALL_REPLY reply; -NwcEnumerateIdentities xplatCall, *eId; -PNwdCEnumerateIdentities pEnum; -NwcString xferStr; -char *str; -u_long status = -ENOMEM, cmdlen, datalen, replylen, cpylen; - - cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcEnumerateIdentities)); - datalen = sizeof(*pEnum); - cmdlen = datalen + sizeof(*cmd); - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - - if (cmd) - { - cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - cmd->NwcCommand = NWC_ENUMERATE_IDENTITIES; - - DbgPrint("NwcEnumIdentities: Send Request\n"); - DbgPrint(" iterator = %x\n", xplatCall.Iterator); - DbgPrint(" cmdlen = %d\n", cmdlen); - - pEnum = (PNwdCEnumerateIdentities)cmd->data; - pEnum->Iterator = xplatCall.Iterator; - status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - status = reply->Reply.ErrorCode; - - eId = pdata->repData; - pEnum = (PNwdCEnumerateIdentities)reply->data; - cpylen = copy_to_user(&eId->Iterator, &pEnum->Iterator, sizeof(pEnum->Iterator)); - DbgPrint("[XPLAT NWCAPI] Found AuthId 0x%X\n", pEnum->AuthenticationId); - cpylen = copy_to_user(&eId->AuthenticationId, &pEnum->AuthenticationId, sizeof(pEnum->AuthenticationId)); - cpylen = copy_to_user(&eId->AuthType, &pEnum->AuthType, sizeof(pEnum->AuthType)); - cpylen = copy_to_user(&eId->IdentityFlags, &pEnum->IdentityFlags, sizeof(pEnum->IdentityFlags)); - cpylen = copy_to_user(&eId->NameType, &pEnum->NameType, sizeof(pEnum->NameType)); - cpylen = copy_to_user(&eId->ObjectType, &pEnum->ObjectType, sizeof(pEnum->ObjectType)); - - if (!status) - { - cpylen = copy_from_user(&xferStr, eId->pDomainName, sizeof(NwcString)); - str = (char *)((char *)reply->data + pEnum->domainNameOffset); - DbgPrint("[XPLAT NWCAPI] Found Domain %s\n", str); - cpylen = copy_to_user(xferStr.pBuffer, str, pEnum->domainNameLen); - xferStr.DataType = NWC_STRING_TYPE_ASCII; - xferStr.DataLen = pEnum->domainNameLen - 1; - cpylen = copy_to_user(eId->pDomainName, &xferStr, sizeof(NwcString)); - - - cpylen = copy_from_user(&xferStr, eId->pObjectName, sizeof(NwcString)); - str = (char *)((char *)reply->data + pEnum->objectNameOffset); - DbgPrint("[XPLAT NWCAPI] Found User %s\n", str); - cpylen = copy_to_user(xferStr.pBuffer, str, pEnum->objectNameLen); - xferStr.DataType = NWC_STRING_TYPE_ASCII; - xferStr.DataLen = pEnum->objectNameLen - 1; - cpylen = copy_to_user(eId->pObjectName, &xferStr, sizeof(NwcString)); - } - - Novfs_Free(reply); - - } - Novfs_Free(cmd); - - } - return(status); -} - -/*++======================================================================*/ -int NwcChangeAuthKey(PXPLAT pdata, session_t Session) -/* - * Arguments: - * - * Returns: - * - * Abstract: Change the password on the server - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ -PXPLAT_CALL_REQUEST cmd; -PXPLAT_CALL_REPLY reply; -NwcChangeKey xplatCall; -PNwdCChangeKey pNewKey; -NwcString xferStr; -char *str; -u_long status = -ENOMEM, cmdlen, datalen, replylen, cpylen; - - cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcChangeKey)); - - datalen = sizeof(NwdCChangeKey) + xplatCall.pDomainName->DataLen + xplatCall.pObjectName->DataLen - + xplatCall.pNewPassword->DataLen + xplatCall.pVerifyPassword->DataLen; - - cmdlen = sizeof(*cmd) + datalen; - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - - if (cmd) - { - pNewKey = (PNwdCChangeKey)cmd->data; - cmd->dataLen = datalen; - cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - cmd->NwcCommand = NWC_CHANGE_KEY; - - pNewKey->NameType = xplatCall.NameType; - pNewKey->ObjectType = xplatCall.ObjectType; - pNewKey->AuthType = xplatCall.AuthType; - str = (char *)pNewKey; - - /* - * Get the tree name - */ - str += sizeof(*pNewKey); - cpylen = copy_from_user(&xferStr, xplatCall.pDomainName, sizeof(NwcString)); - pNewKey->domainNameOffset = sizeof(*pNewKey); - cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen); - pNewKey->domainNameLen = xferStr.DataLen; - - /* - * Get the User Name - */ - str += pNewKey->domainNameLen; - cpylen = copy_from_user(&xferStr, xplatCall.pObjectName, sizeof(NwcString)); - pNewKey->objectNameOffset = pNewKey->domainNameOffset + pNewKey->domainNameLen; - cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen); - pNewKey->objectNameLen = xferStr.DataLen; - - /* - * Get the New Password - */ - str += pNewKey->objectNameLen; - cpylen = copy_from_user(&xferStr, xplatCall.pNewPassword, sizeof(NwcString)); - pNewKey->newPasswordOffset = pNewKey->objectNameOffset + pNewKey->objectNameLen; - cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen); - pNewKey->newPasswordLen = xferStr.DataLen; - - /* - * Get the Verify Password - */ - str += pNewKey->newPasswordLen; - cpylen = copy_from_user(&xferStr, xplatCall.pVerifyPassword, sizeof(NwcString)); - pNewKey->verifyPasswordOffset = pNewKey->newPasswordOffset + pNewKey->newPasswordLen; - cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen); - pNewKey->verifyPasswordLen = xferStr.DataLen; - - status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - status = reply->Reply.ErrorCode; - Novfs_Free(reply); - } - memset(cmd, 0, cmdlen); - - Novfs_Free(cmd); - } - - return(status); -} - -/*++======================================================================*/ -int NwcSetPrimaryConn(PXPLAT pdata, session_t Session) -/* - * Arguments: - * - * Returns: - * - * Abstract: Set the primary connection Id - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ -PXPLAT_CALL_REQUEST cmd; -PXPLAT_CALL_REPLY reply; -NwcSetPrimaryConnection xplatCall; -PNwdCSetPrimaryConnection pConn; -u_long status = -ENOMEM, cmdlen, datalen, replylen, cpylen; - - cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcSetPrimaryConnection)); - - datalen = sizeof(NwdCSetPrimaryConnection); - cmdlen = sizeof(*cmd) + datalen; - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - if (cmd) - { - pConn = (PNwdCSetPrimaryConnection)cmd->data; - cmd->dataLen = datalen; - cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - cmd->NwcCommand = NWC_SET_PRIMARY_CONN; - pConn->ConnHandle = xplatCall.ConnHandle; - status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); - - if (reply) - { - status = reply->Reply.ErrorCode; - Novfs_Free(reply); - } - - Novfs_Free(cmd); - } - - return(status); -} - -/*++======================================================================*/ -int NwcGetPrimaryConn(PXPLAT pdata, session_t Session) -/* - * Arguments: - * - * Returns: - * - * Abstract: Get the Primary connection - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ -XPLAT_CALL_REQUEST cmd; -PXPLAT_CALL_REPLY reply; -u_long status = -ENOMEM, cmdlen, replylen, cpylen; - - - cmdlen = (u_long)(&((PXPLAT_CALL_REQUEST)0)->data); - - cmd.dataLen = 0; - cmd.Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd.Command.SequenceNumber = 0; - cmd.Command.SessionId = Session; - cmd.NwcCommand = NWC_GET_PRIMARY_CONN; - - status = Queue_Daemon_Command((void *)&cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); - - if (reply) - { - status = reply->Reply.ErrorCode; - if (!status) - { - cpylen = copy_to_user(pdata->repData, reply->data, sizeof(u_long)); - } - - Novfs_Free(reply); - } - - return(status); -} - - -/*++======================================================================*/ -int NwcSetMapDrive(PXPLAT pdata, session_t Session) -/* - * Arguments: - * - * Returns: - * - * Abstract: Get the Primary connection - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - -PXPLAT_CALL_REQUEST cmd; -PXPLAT_CALL_REPLY reply; -u_long status = 0, datalen, cmdlen, replylen, cpylen; -NwcMapDriveEx symInfo; - - DbgPrint("Call to NwcSetMapDrive\n"); - cpylen = copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo)); - cmdlen = sizeof(*cmd); - datalen = sizeof(symInfo) + symInfo.dirPathOffsetLength + symInfo.linkOffsetLength; - - DbgPrint(" cmdlen = %d\n", cmdlen); - DbgPrint(" dataLen = %d\n", datalen); - DbgPrint(" symInfo.dirPathOffsetLength = %d\n", symInfo.dirPathOffsetLength); - DbgPrint(" symInfo.linkOffsetLength = %d\n", symInfo.linkOffsetLength); - DbgPrint(" pdata->datalen = %d\n", pdata->reqLen); - - mydump(sizeof(symInfo), &symInfo); - - cmdlen += datalen; - - - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - if (cmd) - { - cmd->dataLen = datalen; - cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - cmd->NwcCommand = NWC_MAP_DRIVE; - - cpylen = copy_from_user(cmd->data, pdata->reqData, datalen); - status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); - - if (reply) - { - status = reply->Reply.ErrorCode; - Novfs_Free(reply); - } - Novfs_Free(cmd); - } - return(status); - -} - -/*++======================================================================*/ -int NwcUnMapDrive(PXPLAT pdata, session_t Session) -/* - * Arguments: - * - * Returns: - * - * Abstract: Get the Primary connection - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ -PXPLAT_CALL_REQUEST cmd; -PXPLAT_CALL_REPLY reply; -u_long status = 0, datalen, cmdlen, replylen, cpylen; -NwcUnmapDriveEx symInfo; - - DbgPrint("Call to NwcUnMapDrive\n"); - - cpylen = copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo)); - cmdlen = sizeof(*cmd); - datalen = sizeof(symInfo) + symInfo.linkLen; - - cmdlen += datalen; - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - if (cmd) - { - cmd->dataLen = datalen; - cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - cmd->NwcCommand = NWC_UNMAP_DRIVE; - - cpylen = copy_from_user(cmd->data, pdata->reqData, datalen); - status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); - - if (reply) - { - status = reply->Reply.ErrorCode; - Novfs_Free(reply); - } - Novfs_Free(cmd); - } - - return(status); -} - - -/*++======================================================================*/ -int NwcEnumerateDrives(PXPLAT pdata, session_t Session) -/* - * Arguments: - * - * Returns: - * - * Abstract: Get the Primary connection - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ -PXPLAT_CALL_REQUEST cmd; -PXPLAT_CALL_REPLY reply; -u_long status = 0, cmdlen, replylen, cpylen; -u_long offset; -char *cp; - - DbgPrint("Call to NwcEnumerateDrives\n"); - - cmdlen = sizeof(*cmd); - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - if (cmd) - { - cmd->dataLen = 0; - cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - cmd->NwcCommand = NWC_ENUMERATE_DRIVES; - status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); - - if (reply) - { - status = reply->Reply.ErrorCode; - DbgPrint("Status Code = 0x%X\n", status); - if (!status) - { - offset = sizeof(u_long); - cp = reply->data; - replylen = ((PNwcGetMappedDrives)pdata->repData)->MapBuffLen; - cpylen = copy_to_user(pdata->repData, cp, offset); - cp += offset; - cpylen = copy_to_user(((PNwcGetMappedDrives)pdata->repData)->MapBuffer, cp, min(replylen - offset, reply->dataLen - offset)); - } - - Novfs_Free(reply); - } - Novfs_Free(cmd); - } - - return(status); -} - - -/*++======================================================================*/ -int NwcGetBroadcastMessage(PXPLAT pdata, session_t Session) -/* - * Arguments: - * - * Returns: - * - * Abstract: Get the Primary connection - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ -PXPLAT_CALL_REQUEST cmd; -PXPLAT_CALL_REPLY reply; -u_long status = 0x8866, cmdlen, replylen, cpylen; -NwcGetBroadcastNotification msg; -PNwdCGetBroadcastNotification dmsg; - - cmdlen = sizeof(*cmd) + sizeof(*dmsg); - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - if (cmd) - { - - cpylen = copy_from_user(&msg, pdata->reqData, sizeof(msg)); - cmd->dataLen = sizeof(*dmsg); - cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - - cmd->NwcCommand = NWC_GET_BROADCAST_MESSAGE; - dmsg = (PNwdCGetBroadcastNotification)cmd->data; - dmsg->uConnReference = msg.uConnReference; - - status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); - - if (reply) - { - status = reply->Reply.ErrorCode; - DbgPrint("Status Code = 0x%X\n", status); - if (!status) - { - /* we have a message so copy it to the user buffer */ - cpylen = copy_to_user(pdata->repData, reply->data, min(pdata->repLen, reply->dataLen)); - } - else - { - msg.messageLen = 0; - msg.message[0] = 0; - cpylen = copy_to_user(pdata->repData, &msg, sizeof(msg)); - } - - Novfs_Free(reply); - } - Novfs_Free(cmd); - } - return(status); - -} - - -int NwdSetKeyValue(PXPLAT pdata, session_t Session) -{ -PXPLAT_CALL_REQUEST cmd; -PXPLAT_CALL_REPLY reply; -NwcSetKey xplatCall; -PNwdCSetKey pNewKey; -NwcString cstrObjectName, cstrPassword; -char *str; -u_long status = -ENOMEM, cmdlen, datalen, replylen, cpylen; - - cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcSetKey)); - cpylen = copy_from_user(&cstrObjectName, xplatCall.pObjectName, sizeof(NwcString)); - cpylen = copy_from_user(&cstrPassword, xplatCall.pNewPassword, sizeof(NwcString)); - - datalen = sizeof(NwdCSetKey) + cstrObjectName.DataLen + cstrPassword.DataLen; - - cmdlen = sizeof(*cmd) + datalen; - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - - if (cmd) - { - pNewKey = (PNwdCSetKey)cmd->data; - cmd->dataLen = datalen; - cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - cmd->NwcCommand = NWC_SET_KEY; - - pNewKey->ObjectType = xplatCall.ObjectType; - pNewKey->AuthenticationId = xplatCall.AuthenticationId; - pNewKey->ConnHandle = xplatCall.ConnHandle; - str = (char *)pNewKey; - - /* - * Get the User Name - */ - str += sizeof(NwdCSetKey); - cpylen = copy_from_user(str, cstrObjectName.pBuffer, cstrObjectName.DataLen); - - str += - pNewKey->objectNameLen = cstrObjectName.DataLen; - pNewKey->objectNameOffset = sizeof(NwdCSetKey); - - /* - * Get the Verify Password - */ - cpylen = copy_from_user(str, cstrPassword.pBuffer, cstrPassword.DataLen); - - pNewKey->newPasswordLen = cstrPassword.DataLen; - pNewKey->newPasswordOffset = pNewKey->objectNameOffset+pNewKey->objectNameLen; - - status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - status = reply->Reply.ErrorCode; - Novfs_Free(reply); - } - memset(cmd, 0, cmdlen); - Novfs_Free(cmd); - } - - return(status); -} - -/*++======================================================================*/ -int NwdVerifyKeyValue(PXPLAT pdata, session_t Session) -/* - * Arguments: - * - * Returns: - * - * Abstract: Change the password on the server - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ -PXPLAT_CALL_REQUEST cmd; -PXPLAT_CALL_REPLY reply; -NwcVerifyKey xplatCall; -PNwdCVerifyKey pNewKey; -NwcString xferStr; -char *str; -u_long status = -ENOMEM, cmdlen, datalen, replylen, cpylen; - - cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcVerifyKey)); - - datalen = sizeof(NwdCVerifyKey) + xplatCall.pDomainName->DataLen + xplatCall.pObjectName->DataLen - + xplatCall.pVerifyPassword->DataLen; - - cmdlen = sizeof(*cmd) + datalen; - cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); - - if (cmd) - { - pNewKey = (PNwdCVerifyKey)cmd->data; - cmd->dataLen = datalen; - cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; - cmd->Command.SequenceNumber = 0; - cmd->Command.SessionId = Session; - cmd->NwcCommand = NWC_VERIFY_KEY; - - pNewKey->NameType = xplatCall.NameType; - pNewKey->ObjectType = xplatCall.ObjectType; - pNewKey->AuthType = xplatCall.AuthType; - str = (char *)pNewKey; - - /* - * Get the tree name - */ - str += sizeof(*pNewKey); - cpylen = copy_from_user(&xferStr, xplatCall.pDomainName, sizeof(NwcString)); - pNewKey->domainNameOffset = sizeof(*pNewKey); - cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen); - pNewKey->domainNameLen = xferStr.DataLen; - - /* - * Get the User Name - */ - str += pNewKey->domainNameLen; - cpylen = copy_from_user(&xferStr, xplatCall.pObjectName, sizeof(NwcString)); - pNewKey->objectNameOffset = pNewKey->domainNameOffset + pNewKey->domainNameLen; - cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen); - pNewKey->objectNameLen = xferStr.DataLen; - - /* - * Get the Verify Password - */ - str += pNewKey->objectNameLen; - cpylen = copy_from_user(&xferStr, xplatCall.pVerifyPassword, sizeof(NwcString)); - pNewKey->verifyPasswordOffset = pNewKey->objectNameOffset + pNewKey->objectNameLen; - cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen); - pNewKey->verifyPasswordLen = xferStr.DataLen; - - status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); - if (reply) - { - status = reply->Reply.ErrorCode; - Novfs_Free(reply); - } - memset(cmd, 0, cmdlen); - Novfs_Free(cmd); - } - - return(status); -} diff -uNr src.old/novfs/proc.c src/novfs/proc.c --- src.old/novfs/proc.c 2006-07-11 21:24:18.000000000 +0200 +++ src/novfs/proc.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,339 +0,0 @@ -/*++======================================================================== - * Program Name: Novell NCP Redirector for Linux - * File Name: proc.c - * Version: v1.00 - * Author: James Turner - * - * Abstract: This module contains functions that create the - * interface to the proc filesystem. - * Notes: - * Revision History: - * - * - * Copyright (C) 2005 Novell, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - *======================================================================--*/ - -/*===[ Include files specific to Linux ]==================================*/ -#include -#include -#include -#include - -/*===[ Include files specific to this module ]============================*/ -#include "vfs.h" - -/*===[ External data ]====================================================*/ -extern char *Novfs_CurrentMount; - -/*===[ External prototypes ]==============================================*/ -extern int DbgPrint( char *Fmt, ... ); - -extern ssize_t -Daemon_Receive_Reply(struct file *file, const char *buf, size_t nbytes, loff_t *ppos); - -extern ssize_t -Daemon_Send_Command(struct file *file, char *buf, size_t len, loff_t *off); - -extern int Daemon_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); - -extern int Daemon_Library_close(struct inode *inode, struct file *file); -extern int Daemon_Library_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); -extern int Daemon_Library_open(struct inode *inode, struct file *file); -extern ssize_t Daemon_Library_read(struct file *file, char *buf, size_t len, loff_t *off); -extern ssize_t Daemon_Library_write(struct file *file, const char *buf, size_t len, loff_t *off); -extern loff_t Daemon_Library_llseek(struct file *file, loff_t offset, int origin); - -extern int Daemon_Open_Control(struct inode *Inode, struct file *File); -extern int Daemon_Close_Control(struct inode *Inode, struct file *File); - -extern int Daemon_getversion( char *Buf, int Length ); - -/*===[ Manifest constants ]===============================================*/ - -/*===[ Type definitions ]=================================================*/ - -/*===[ Function prototypes ]==============================================*/ -ssize_t -Novfs_User_proc_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos); - -ssize_t -Novfs_User_proc_write(struct file * file, char * buf, size_t nbytes, loff_t *ppos); - -int Novfs_User_proc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); - -int Init_Procfs_Interface( void ); -void Uninit_Procfs_Interface( void ); - -/*===[ Global variables ]=================================================*/ -struct proc_dir_entry *Novfs_Procfs_dir, *Novfs_Control, *Novfs_Library, *Novfs_Version; -static struct file_operations Daemon_proc_fops; -static struct file_operations Library_proc_fops; - -/*===[ Code ]=============================================================*/ - -/*++======================================================================*/ -int Novfs_Get_Version(char *page, char **start, off_t off, int count, int *eof, void *data) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - char *buf, tbuf[48]; - int len=0, i; - - if ( !off ) - { - buf = page+off; - *start = buf; - len = sprintf(buf, "Novfs Version=%s\n", NOVFS_VERSION_STRING); - i = Daemon_getversion(tbuf, sizeof(tbuf)); - if ((i > 0) && i < (count-len)) - { - len += sprintf(buf+len, "Novfsd Version=%s\n", tbuf); - } - - if (Novfs_CurrentMount) - { - i = strlen(Novfs_CurrentMount); - if ((i > 0) && i < (count-len)) - { - len += sprintf(buf+len, "Novfs mount=%s\n", Novfs_CurrentMount); - } - } - DbgPrint("Novfs_Get_Version:\n%s\n", buf); - } - *eof = 1; - return(len); -} - -/*++======================================================================*/ -ssize_t -Novfs_User_proc_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - ssize_t retval=0; - - UNUSED_VARIABLE(file); - UNUSED_VARIABLE(buf); - UNUSED_VARIABLE(nbytes); - UNUSED_VARIABLE(ppos); - - DbgPrint( "Novfs_User_proc_read: kernel_locked 0x%x\n", kernel_locked()); - - return retval; -} -/*++======================================================================*/ -ssize_t -Novfs_User_proc_write(struct file * file, char * buf, size_t nbytes, loff_t *ppos) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - ssize_t retval=0; - - UNUSED_VARIABLE(file); - UNUSED_VARIABLE(ppos); - - DbgPrint( "Novfs_User_proc_write: kernel_locked 0x%x\n", kernel_locked()); - if (buf && nbytes) - { - } - - return(retval); -} - -/*++======================================================================*/ -int Novfs_User_proc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - int retval=-ENOSYS; - - UNUSED_VARIABLE(inode); - UNUSED_VARIABLE(file); - UNUSED_VARIABLE(cmd); - UNUSED_VARIABLE(arg); - - DbgPrint( "Novfs_User_proc_ioctl: kernel_locked 0x%x\n", kernel_locked()); - - return(retval); -} - -/*++======================================================================*/ -int Init_Procfs_Interface( void ) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - int retCode=0; - - Novfs_Procfs_dir = proc_mkdir(MODULE_NAME, NULL); - if ( Novfs_Procfs_dir ) - { - Novfs_Procfs_dir->owner = THIS_MODULE; - - Novfs_Control = create_proc_entry("Control", 0600, Novfs_Procfs_dir); - - if ( Novfs_Control ) - { - Novfs_Control->owner = THIS_MODULE; - Novfs_Control->size = 0; - memcpy(&Daemon_proc_fops, Novfs_Control->proc_fops, sizeof(struct file_operations)); - - /* - * Setup our functions - */ - Daemon_proc_fops.owner = THIS_MODULE; - Daemon_proc_fops.open = Daemon_Open_Control; - Daemon_proc_fops.release = Daemon_Close_Control; - Daemon_proc_fops.read = Daemon_Send_Command; - Daemon_proc_fops.write = Daemon_Receive_Reply; - Daemon_proc_fops.ioctl = Daemon_ioctl; - - Novfs_Control->proc_fops = &Daemon_proc_fops; - } - else - { - remove_proc_entry(MODULE_NAME, NULL); - return(-ENOENT); - } - - Novfs_Library = create_proc_entry("Library", 0666, Novfs_Procfs_dir); - if ( Novfs_Library ) - { - Novfs_Library->owner = THIS_MODULE; - Novfs_Library->size = 0; - - /* - * Setup our file functions - */ - memcpy(&Library_proc_fops, Novfs_Library->proc_fops, sizeof(struct file_operations)); - Library_proc_fops.owner = THIS_MODULE; - Library_proc_fops.open = Daemon_Library_open; - Library_proc_fops.release = Daemon_Library_close; - Library_proc_fops.read = Daemon_Library_read; - Library_proc_fops.write = Daemon_Library_write; - Library_proc_fops.llseek = Daemon_Library_llseek; - Library_proc_fops.ioctl = Daemon_Library_ioctl; - Novfs_Library->proc_fops = &Library_proc_fops; - } - else - { - remove_proc_entry("Control", Novfs_Procfs_dir); - remove_proc_entry(MODULE_NAME, NULL); - return(-ENOENT); - } - - Novfs_Version = create_proc_read_entry("Version", 0444, Novfs_Procfs_dir, Novfs_Get_Version, NULL); - if ( Novfs_Version ) - { - Novfs_Version->owner = THIS_MODULE; - Novfs_Version->size = 0; - } - else - { - remove_proc_entry("Library", Novfs_Procfs_dir); - remove_proc_entry("Control", Novfs_Procfs_dir); - remove_proc_entry(MODULE_NAME, NULL); - retCode = -ENOENT; - } - } - else - { - retCode = -ENOENT; - } - return(retCode); -} - -/*++======================================================================*/ -void Uninit_Procfs_Interface( void ) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - - DbgPrint("Uninit_Procfs_Interface remove_proc_entry(Version, NULL)\n"); - remove_proc_entry("Version", Novfs_Procfs_dir); - - DbgPrint("Uninit_Procfs_Interface remove_proc_entry(Control, NULL)\n"); - remove_proc_entry("Control", Novfs_Procfs_dir); - - DbgPrint("Uninit_Procfs_Interface remove_proc_entry(Library, NULL)\n"); - remove_proc_entry("Library", Novfs_Procfs_dir); - - DbgPrint("Uninit_Procfs_Interface remove_proc_entry(%s, NULL)\n", MODULE_NAME); - remove_proc_entry(MODULE_NAME, NULL); - - DbgPrint("Uninit_Procfs_Interface done\n"); -} diff -uNr src.old/novfs/profile.c src/novfs/profile.c --- src.old/novfs/profile.c 2006-07-11 21:24:18.000000000 +0200 +++ src/novfs/profile.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,1201 +0,0 @@ -/*++======================================================================== - * Program Name: Novell NCP Redirector for Linux - * File Name: profile.c - * Version: v1.00 - * Author: James Turner - * - * Abstract: This module contains a debugging code for - * the novfs VFS. - * Notes: - * Revision History: - * - * - * Copyright (C) 2005 Novell, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - *======================================================================--*/ - -/*===[ Include files specific to Linux ]==================================*/ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -/*===[ Include files specific to this module ]============================*/ -#include "vfs.h" - -/*===[ External data ]====================================================*/ -extern struct dentry *Novfs_root; -extern struct proc_dir_entry *Novfs_Procfs_dir; -extern unsigned long File_update_timeout; - -/*===[ External prototypes ]==============================================*/ -extern void Scope_Dump_Tasklist( void ); -extern void Scope_Dump_Scopetable( void ); -extern void Daemon_Dumpque( void ); -extern char *Scope_dget_path( struct dentry *Dentry, char *Buf, unsigned int Buflen, int Flags); -extern int Novfs_dump_inode_cache(int argc, const char **argv, const char **envp, struct pt_regs *regs); -extern void Novfs_dump_inode( void *pf ); -extern int Daemon_SendDebugCmd ( char *Command ); - - -/*===[ Manifest constants ]===============================================*/ -#define DBGBUFFERSIZE (1024*1024*32) - -/*===[ Type definitions ]=================================================*/ -typedef void daemon_command_t; - -typedef struct _SYMBOL_TABLE { - void *address; - char *name; -} SYMBOL_TABLE, *PSYMBOL_TABLE; - -struct local_rtc_time { - int tm_sec; - int tm_min; - int tm_hour; - int tm_mday; - int tm_mon; - int tm_year; - int tm_wday; - int tm_yday; - int tm_isdst; -}; - -/*===[ Function prototypes ]==============================================*/ -int profile_task_exit_callback(struct notifier_block *self, unsigned long val, void *data) __attribute__((__no_instrument_function__)); -int init_profile( void ); - -char *ctime_r(time_t *clock, char *buf); -int LocalPrint( char *Fmt, ... ) __attribute__((__no_instrument_function__)); -int DbgPrint( char *Fmt, ... ) __attribute__((__no_instrument_function__)); - -void __cyg_profile_func_enter (void *this_fn, void *call_site) __attribute__((__no_instrument_function__)) ; -void __cyg_profile_func_exit (void *this_fn, void *call_site) __attribute__((__no_instrument_function__)); -void doline(unsigned char *b, unsigned char *p, unsigned char *l) __attribute__((__no_instrument_function__)); -void mydump(int size, void *dumpptr) __attribute__((__no_instrument_function__)); -void GregorianDay(struct local_rtc_time * tm) __attribute__((__no_instrument_function__)); -void to_tm(int tim, struct local_rtc_time * tm) __attribute__((__no_instrument_function__)); -char *ctime_r(time_t *clock, char *buf) __attribute__((__no_instrument_function__)); -int profile_dump_tasklist(int argc, const char **argv, const char **envp, struct pt_regs *regs); -int profile_dump_scopetable(int argc, const char **argv, const char **envp, struct pt_regs *regs); -int profile_dump_daemonque(int argc, const char **argv, const char **envp, struct pt_regs *regs); -int profile_dump_DbgBuffer(int argc, const char **argv, const char **envp, struct pt_regs *regs); -int profile_dump_DentryTree(int argc, const char **argv, const char **envp, struct pt_regs *regs); -int profile_dump_inode(int argc, const char **argv, const char **envp, struct pt_regs *regs); - -void *Novfs_Malloc( size_t size, int flags ) __attribute__((__no_instrument_function__)); -void Novfs_Free( const void *p ) __attribute__((__no_instrument_function__)); - -int profile_dump_memorylist_dbg(int argc, const char **argv, const char **envp, struct pt_regs *regs) __attribute__((__no_instrument_function__)); -void profile_dump_memorylist( void *pf ); - -static ssize_t User_proc_write_DbgBuffer(struct file * file, const char __user *buf, size_t nbytes, loff_t *ppos) __attribute__((__no_instrument_function__)); -static ssize_t User_proc_read_DbgBuffer(struct file * file, char * buf, size_t nbytes, loff_t *ppos) __attribute__((__no_instrument_function__)); -static int proc_read_DbgBuffer(char *page, char **start, - off_t off, int count, - int *eof, void *data) __attribute__((__no_instrument_function__)); - -void profile_dump_dt(struct dentry *parent, void *pf ); -ssize_t profile_inode_read(struct file *file, char *buf, size_t len, loff_t *off); -ssize_t profile_dentry_read(struct file *file, char *buf, size_t len, loff_t *off); -ssize_t profile_memory_read(struct file *file, char *buf, size_t len, loff_t *off); - -/*===[ Global variables ]=================================================*/ -char *DbgPrintBuffer=NULL; -char DbgPrintOn=0; -char DbgSyslogOn=0; -char DbgProfileOn=0; -char DbgDaemonLogOn=0; -unsigned long DbgPrintBufferOffset=0; -unsigned long DbgPrintBufferReadOffset=0; -unsigned long DbgPrintBufferSize = DBGBUFFERSIZE; - -int Indent = 0; -char IndentString[] = " "; - -static struct file_operations Dbg_proc_file_operations; -static struct file_operations dentry_proc_file_ops; -static struct file_operations inode_proc_file_ops; -static struct file_operations memory_proc_file_ops; - -static struct proc_dir_entry *dbg_dir, *dbg_file; -static struct proc_dir_entry *dentry_file; -static struct proc_dir_entry *inode_file; -static struct proc_dir_entry *memory_file; - -static struct notifier_block taskexit_nb; - - -DECLARE_MUTEX(LocalPrint_lock); -spinlock_t Syslog_lock = SPIN_LOCK_UNLOCKED; - -#include "profile_funcs.h" - - -/*===[ Code ]=============================================================*/ -int -profile_task_exit_callback(struct notifier_block *self, unsigned long val, void *data) -{ - struct task_struct *task = (struct task_struct *)data; - - DbgPrint("profile_task_exit_callback: task 0x%p %u exiting %s\n", task, task->pid, task->comm); - return(0); -} - -int init_profile( void ) -{ - int retCode = 0; - - if ( DbgPrintBuffer ) - { - if (Novfs_Procfs_dir) - { - dbg_dir = Novfs_Procfs_dir; - } - else - { - dbg_dir = proc_mkdir(MODULE_NAME, NULL); - } - - if( dbg_dir ) - { - dbg_dir->owner = THIS_MODULE; - dbg_file = create_proc_read_entry("Debug", - 0600, - dbg_dir, - proc_read_DbgBuffer, - NULL); - if ( dbg_file ) - { - dbg_file->owner = THIS_MODULE; - dbg_file->size = DBGBUFFERSIZE; - memcpy(&Dbg_proc_file_operations, dbg_file->proc_fops, sizeof(struct file_operations)); - Dbg_proc_file_operations.read = User_proc_read_DbgBuffer; - Dbg_proc_file_operations.write = User_proc_write_DbgBuffer; - dbg_file->proc_fops = &Dbg_proc_file_operations; - } - else - { - remove_proc_entry(MODULE_NAME, NULL); - vfree( DbgPrintBuffer ); - DbgPrintBuffer = NULL; - } - - inode_file = create_proc_entry("inode", - 0600, - dbg_dir); - if ( inode_file ) - { - inode_file->owner = THIS_MODULE; - inode_file->size = 0; - memcpy(&inode_proc_file_ops, inode_file->proc_fops, sizeof(struct file_operations)); - inode_proc_file_ops.owner = THIS_MODULE; - inode_proc_file_ops.read = profile_inode_read; - inode_file->proc_fops = &inode_proc_file_ops; - } - - dentry_file = create_proc_entry("dentry", - 0600, - dbg_dir); - if ( dentry_file ) - { - dentry_file->owner = THIS_MODULE; - dentry_file->size = 0; - memcpy(&dentry_proc_file_ops, dentry_file->proc_fops, sizeof(struct file_operations)); - dentry_proc_file_ops.owner = THIS_MODULE; - dentry_proc_file_ops.read = profile_dentry_read; - dentry_file->proc_fops = &dentry_proc_file_ops; - } - - memory_file = create_proc_entry("memory", - 0600, - dbg_dir); - if ( memory_file ) - { - memory_file->owner = THIS_MODULE; - memory_file->size = 0; - memcpy(&memory_proc_file_ops, memory_file->proc_fops, sizeof(struct file_operations)); - memory_proc_file_ops.owner = THIS_MODULE; - memory_proc_file_ops.read = profile_memory_read; - memory_file->proc_fops = &memory_proc_file_ops; - } - - } - else - { - vfree( DbgPrintBuffer ); - DbgPrintBuffer = NULL; - } - } - return( retCode ); -} - -/* -void uninit_profile() -{ - if (dbg_file) DbgPrint("Calling remove_proc_entry(Debug, NULL)\n"), remove_proc_entry( "Debug", dbg_dir ); - if (inode_file) DbgPrint("Calling remove_proc_entry(inode, NULL)\n"), remove_proc_entry( "inode", dbg_dir ); - if (dentry_file) DbgPrint("Calling remove_proc_entry(dentry, NULL)\n"), remove_proc_entry( "dentry", dbg_dir ); - if (memory_file) DbgPrint("Calling remove_proc_entry(memory, NULL)\n"), remove_proc_entry( "memory", dbg_dir ); - - if (dbg_dir && (dbg_dir != Novfs_Procfs_dir)) - { - DbgPrint("Calling remove_proc_entry(%s, NULL)\n", MODULE_NAME); - remove_proc_entry( MODULE_NAME, NULL ); - } -} -*/ - -static -ssize_t -User_proc_write_DbgBuffer(struct file * file, const char __user *buf, size_t nbytes, loff_t *ppos) -{ - ssize_t retval=nbytes; - u_char *lbuf, *p; - int i; - u_long cpylen; - - - UNUSED_VARIABLE( *ppos ); - - lbuf = Novfs_Malloc(nbytes+1, GFP_KERNEL); - if (lbuf) - { - cpylen = copy_from_user(lbuf, buf, nbytes); - - lbuf[nbytes] = 0; - DbgPrint("User_proc_write_DbgBuffer: %s\n", lbuf); - - for (i=0; lbuf[i] && lbuf[i] != '\n'; i++) ; - - if ( '\n' == lbuf[i] ) - { - lbuf[i] = '\0'; - } - - if ( !strcmp("on", lbuf)) - { - DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0; - DbgPrintOn = 1; - } - else if ( !strcmp("off", lbuf)) - { - DbgPrintOn = 0; - } - else if ( !strcmp("reset", lbuf)) - { - DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0; - } - else if ( NULL != (p = strchr(lbuf, ' '))) - { - *p++ = '\0'; - if ( !strcmp("syslog", lbuf)) - { - - if (!strcmp("on", p)) - { - DbgSyslogOn = 1; - } - else if (!strcmp("off", p)) - { - DbgSyslogOn = 0; - } - } - else if ( !strcmp("profile", lbuf)) - { - - if (!strcmp("on", p)) - { - DbgProfileOn = 1; - } - else if (!strcmp("off", p)) - { - DbgProfileOn = 0; - } - } - else if ( !strcmp("daemonlog", lbuf)) - { - - if (!strcmp("on", p)) - { - DbgDaemonLogOn = 1; - } - else if (!strcmp("off", p)) - { - DbgDaemonLogOn = 0; - } - } - else if ( !strcmp("novfsd", lbuf)) - { - Daemon_SendDebugCmd( p ); - } - else if ( !strcmp("file_update_timeout", lbuf)) - { - File_update_timeout = simple_strtoul(p, NULL, 0); - } - } - Novfs_Free(lbuf); - } - - return (retval); -} - -static -ssize_t -User_proc_read_DbgBuffer(struct file * file, char * buf, size_t nbytes, loff_t *ppos) - -{ - ssize_t retval=0; - size_t count; - - UNUSED_VARIABLE( *ppos ); - - if (0 != (count = DbgPrintBufferOffset - DbgPrintBufferReadOffset)) - { - - if (count > nbytes) - { - count = nbytes; - } - - count -= copy_to_user(buf, &DbgPrintBuffer[DbgPrintBufferReadOffset], count); - - if (count == 0) - { - if (retval == 0) - retval = -EFAULT; - } - else - { - DbgPrintBufferReadOffset += count; - if (DbgPrintBufferReadOffset >= DbgPrintBufferOffset) - { - DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0; - } - retval = count; - } - } - - return retval; -} - -static -int -proc_read_DbgBuffer(char *page, char **start, - off_t off, int count, - int *eof, void *data) -{ - int len; - static char bufd[512]; - - UNUSED_VARIABLE(start); - UNUSED_VARIABLE(eof); - UNUSED_VARIABLE(data); - - sprintf(bufd, KERN_ALERT "proc_read_DbgBuffer: off=%ld count=%d DbgPrintBufferOffset=%lu DbgPrintBufferReadOffset=%lu\n", - off, count, DbgPrintBufferOffset, DbgPrintBufferReadOffset); - printk(bufd); - - len = DbgPrintBufferOffset - DbgPrintBufferReadOffset; - - if ((int)(DbgPrintBufferOffset-DbgPrintBufferReadOffset) > count) - { - len = count; - } - - if (len) - { - memcpy(page, &DbgPrintBuffer[DbgPrintBufferReadOffset], len); - DbgPrintBufferReadOffset += len; - } - - - if (DbgPrintBufferReadOffset >= DbgPrintBufferOffset) - { - DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0; - } - - sprintf(bufd, KERN_ALERT "proc_read_DbgBuffer: return %d\n", len); - printk(bufd); - - return len; -} - -#define DBG_BUFFER_SIZE (2*1024) - -int -LocalPrint( char *Fmt, ... ) -{ - int len=0; - va_list args; - - if (DbgPrintBuffer) - { - va_start(args, Fmt); - len += vsnprintf(DbgPrintBuffer+DbgPrintBufferOffset, DbgPrintBufferSize-DbgPrintBufferOffset, Fmt, args); - DbgPrintBufferOffset += len; - } - - return(len); -} - - -int -DbgPrint( char *Fmt, ... ) -{ - char *buf; - int len=0; - unsigned long offset; - va_list args; - - if ( (DbgPrintBuffer && DbgPrintOn) || DbgSyslogOn ) - { - buf = kmalloc( DBG_BUFFER_SIZE, GFP_KERNEL ); - - if (buf) - { - va_start(args, Fmt); - len = sprintf(buf, "[%d] ", current->pid); - - len += vsnprintf(buf+len, DBG_BUFFER_SIZE-len, Fmt, args); - if ( -1 == len ) - { - len = DBG_BUFFER_SIZE-1; - buf[len] = '\0'; - } - /* - len = sprintf(&DbgPrintBuffer[offset], "[%llu] ", ts); - len += vsprintf(&DbgPrintBuffer[offset+len], Fmt, args); - */ - - if (len) - { - if (DbgSyslogOn) - { - spin_lock( &Syslog_lock ); - printk("<6>%s", buf); - spin_unlock( &Syslog_lock ); - } - - if ( DbgPrintBuffer && DbgPrintOn ) - { - if ((DbgPrintBufferOffset+len) > DbgPrintBufferSize) - { - offset = DbgPrintBufferOffset; - DbgPrintBufferOffset = 0; - memset(&DbgPrintBuffer[offset], 0, DbgPrintBufferSize-offset); - } - - mb(); - - if ((DbgPrintBufferOffset+len) < DbgPrintBufferSize) - { - DbgPrintBufferOffset += len; - offset = DbgPrintBufferOffset-len; - memcpy(&DbgPrintBuffer[offset], buf, len+1); - } - } - } - kfree(buf); - } - } - - return(len); -} - -void -__cyg_profile_func_enter (void *this_fn, void *call_site) -{ - PSYMBOL_TABLE sym; - struct timespec ts; - - - if ((void *)init_novfs == this_fn) - { - DbgPrintBuffer = vmalloc(DBGBUFFERSIZE); - taskexit_nb.notifier_call = profile_task_exit_callback; - -#ifdef CONFIG_KDB - kdb_register("novfs_tl", profile_dump_tasklist, "", "Dumps task list", 0); - kdb_register("novfs_st", profile_dump_scopetable, "", "Dumps the novfs scope table", 0); - kdb_register("novfs_dque", profile_dump_daemonque, "", "Dumps the novfs daemon que", 0); - kdb_register("novfs_db", profile_dump_DbgBuffer, "[-r] [-e size] [-i]", "Dumps the novfs DbgBuffer", 0); - kdb_register("novfs_den", profile_dump_DentryTree, "[dentry]", "Dumps a Dentry tree", 0); - kdb_register("novfs_ic", Novfs_dump_inode_cache, "[inode]", "Dumps a Inode Cache", 0); - kdb_register("novfs_inode", profile_dump_inode, "", "Dump allocated Inodes", 0); - kdb_register("novfs_mem", profile_dump_memorylist_dbg, "", "Dumps allocated memory", 0); -#endif - } - else if (exit_novfs == this_fn) - { - if (dbg_file) DbgPrint("Calling remove_proc_entry(Debug, NULL)\n"), remove_proc_entry( "Debug", dbg_dir ); - if (inode_file) DbgPrint("Calling remove_proc_entry(inode, NULL)\n"), remove_proc_entry( "inode", dbg_dir ); - if (dentry_file) DbgPrint("Calling remove_proc_entry(dentry, NULL)\n"), remove_proc_entry( "dentry", dbg_dir ); - if (memory_file) DbgPrint("Calling remove_proc_entry(memory, NULL)\n"), remove_proc_entry( "memory", dbg_dir ); - - if (dbg_dir && (dbg_dir != Novfs_Procfs_dir)) - { - printk( KERN_INFO "Calling remove_proc_entry(%s, NULL)\n", MODULE_NAME); - remove_proc_entry( MODULE_NAME, NULL ); - } - } - - if (DbgProfileOn) - { - sym = SymbolTable; - while (sym->address) - { - if (this_fn == sym->address ) - { - ts = current_kernel_time(); - DbgPrint("[%ld:lu]%sS %s (0x%p 0x%p)\n", ts.tv_sec, ts.tv_nsec, &IndentString[sizeof(IndentString)-Indent-1], sym->name, this_fn, call_site); - - Indent++; - if (Indent > (int)(sizeof(IndentString)-1)) - Indent--; - - break; - } - sym++; - } - } -} - -void -__cyg_profile_func_exit (void *this_fn, void *call_site) -{ - PSYMBOL_TABLE sym; - struct timespec ts; - - if (exit_novfs == this_fn) - { - if (DbgPrintBuffer) vfree( DbgPrintBuffer ); - DbgPrintBuffer = NULL; - -#ifdef CONFIG_KDB - kdb_unregister("novfs_tl"); - kdb_unregister("novfs_st"); - kdb_unregister("novfs_dque"); - kdb_unregister("novfs_db"); - kdb_unregister("novfs_den"); - kdb_unregister("novfs_ic"); - kdb_unregister("novfs_inode"); - kdb_unregister("novfs_mem"); -#endif - return; - } - - if (DbgProfileOn) - { - sym = SymbolTable; - while (sym->address) - { - if (this_fn == sym->address ) - { - Indent--; - if (Indent < 0) - Indent = 0; - - ts = current_kernel_time(); - DbgPrint("[%ld:lu]%sR %s (0x%p)\n", ts.tv_sec, ts.tv_nsec, &IndentString[sizeof(IndentString)-Indent-1], sym->name, call_site); - break; - } - sym++; - } - } -} - -void -doline(unsigned char *b, unsigned char *e, unsigned char *l) -{ - *b++ = ' '; - while (l < e) { - if ((*l < ' ') || (*l > '~')) - { - *b++ = '.'; - *b = '\0'; - } - else - { - b += sprintf(b, "%c", *l); - } - l++; - } -} - -void -mydump(int size, void *dumpptr) -{ - unsigned char *ptr = (unsigned char *)dumpptr; - unsigned char *line=0, buf[80], *bptr=buf; - int i; - - if ( DbgPrintBuffer ) - { - if (size) - { - for (i=0; i < size; i++) - { - if (0 == (i % 16)) - { - if (line) - { - doline(bptr, ptr, line); - DbgPrint("%s\n", buf); - bptr = buf; - } - bptr += sprintf(bptr, "0x%p: ", ptr); - line = ptr; - } - bptr += sprintf(bptr, "%02x ", *ptr++); - } - doline(bptr, ptr, line); - DbgPrint("%s\n", buf); - } - } -} - -#define FEBRUARY 2 -#define STARTOFTIME 1970 -#define SECDAY 86400L -#define SECYR (SECDAY * 365) -#define leapyear(year) ((year) % 4 == 0) -#define days_in_year(a) (leapyear(a) ? 366 : 365) -#define days_in_month(a) (month_days[(a) - 1]) - -static int month_days[12] = { - 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 -}; - -/* - * This only works for the Gregorian calendar - i.e. after 1752 (in the UK) - */ -void -GregorianDay(struct local_rtc_time * tm) -{ - int leapsToDate; - int lastYear; - int day; - int MonthOffset[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; - - lastYear=tm->tm_year-1; - - /* - * Number of leap corrections to apply up to end of last year - */ - leapsToDate = lastYear/4 - lastYear/100 + lastYear/400; - - /* - * This year is a leap year if it is divisible by 4 except when it is - * divisible by 100 unless it is divisible by 400 - * - * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 will be - */ - if((tm->tm_year%4==0) && - ((tm->tm_year%100!=0) || (tm->tm_year%400==0)) && - (tm->tm_mon>2)) - { - /* - * We are past Feb. 29 in a leap year - */ - day=1; - } - else - { - day=0; - } - - day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] + - tm->tm_mday; - - tm->tm_wday=day%7; -} - -void -to_tm(int tim, struct local_rtc_time * tm) -{ - register int i; - register long hms, day; - - day = tim / SECDAY; - hms = tim % SECDAY; - - /* Hours, minutes, seconds are easy */ - tm->tm_hour = hms / 3600; - tm->tm_min = (hms % 3600) / 60; - tm->tm_sec = (hms % 3600) % 60; - - /* Number of years in days */ - for (i = STARTOFTIME; day >= days_in_year(i); i++) - day -= days_in_year(i); - tm->tm_year = i; - - /* Number of months in days left */ - if (leapyear(tm->tm_year)) - days_in_month(FEBRUARY) = 29; - for (i = 1; day >= days_in_month(i); i++) - day -= days_in_month(i); - days_in_month(FEBRUARY) = 28; - tm->tm_mon = i; - - /* Days are what is left over (+1) from all that. */ - tm->tm_mday = day + 1; - - /* - * Determine the day of week - */ - GregorianDay(tm); -} - -char * -ctime_r(time_t *clock, char *buf) -{ - struct local_rtc_time tm; - static char *DAYOFWEEK[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; - static char *MONTHOFYEAR[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; - - to_tm(*clock, &tm); - - sprintf(buf, "%s %s %d %d:%02d:%02d %d", DAYOFWEEK[tm.tm_wday], MONTHOFYEAR[tm.tm_mon-1], tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_year); - return(buf); -} - - -#ifdef CONFIG_KDB - -int -NO_TRACE -profile_dump_tasklist(int argc, const char **argv, const char **envp, struct pt_regs *regs) -{ - Scope_Dump_Tasklist(); - return( 0 ); -} - -int -NO_TRACE -profile_dump_scopetable(int argc, const char **argv, const char **envp, struct pt_regs *regs) -{ - Scope_Dump_Scopetable(); - return( 0 ); -} - -int -NO_TRACE -profile_dump_daemonque(int argc, const char **argv, const char **envp, struct pt_regs *regs) -{ - Daemon_Dumpque(); - return( 0 ); -} - -int -NO_TRACE -profile_dump_DbgBuffer(int argc, const char **argv, const char **envp, struct pt_regs *regs) -{ - unsigned long offset = DbgPrintBufferReadOffset; - if (argc > 0) - { - if (!strcmp("-r", argv[1])) - { - DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0; - } - else if (!strcmp("-e", argv[1]) && (argc > 1)) - { - offset = simple_strtoul(argv[2], NULL, 0); - if (offset && offset < DbgPrintBufferOffset) - { - offset = DbgPrintBufferOffset - offset; - } - else - { - offset = DbgPrintBufferOffset; - } - } - else if (!strcmp("-i", argv[1])) - { - kdb_printf("DbgPrintBuffer =0x%p\n", DbgPrintBuffer); - kdb_printf("DbgPrintBufferOffset =0x%lx\n", DbgPrintBufferOffset); - kdb_printf("DbgPrintBufferSize =0x%lx\n", DbgPrintBufferSize); - offset = DbgPrintBufferOffset; - - } - } - while (DbgPrintBufferOffset > offset) - { - kdb_printf("%c", DbgPrintBuffer[offset++]); - } - return( 0 ); -} - -int -NO_TRACE -profile_dump_DentryTree(int argc, const char **argv, const char **envp, struct pt_regs *regs) -{ - struct dentry *parent=Novfs_root; - - if (argc > 0) - { - parent = (void *)simple_strtoul(argv[1], NULL, 0); - } - - if (parent) - { - profile_dump_dt(parent, kdb_printf ); - } - - return(0); -} - - -int -NO_TRACE -profile_dump_inode(int argc, const char **argv, const char **envp, struct pt_regs *regs) -{ - Novfs_dump_inode( kdb_printf ); - return( 0 ); -} - -#endif /* CONFIG_KDB */ - -typedef struct memory_header -{ - struct list_head list; - void *caller; - size_t size; -} MEMORY_LIST, *PMEMORY_LIST; - -spinlock_t Malloc_Lock = SPIN_LOCK_UNLOCKED; -LIST_HEAD( Memory_List ); - -void *Novfs_Malloc( size_t size, int flags ) -{ - void *p=NULL; - PMEMORY_LIST mh; - - mh = kmalloc(size + sizeof(MEMORY_LIST), flags); - if (mh) - { - mh->caller = __builtin_return_address(0); - mh->size = size; - spin_lock(&Malloc_Lock); - list_add(&mh->list, &Memory_List); - spin_unlock(&Malloc_Lock); - p = (char *)mh+sizeof(MEMORY_LIST); - /*DbgPrint("Novfs_Malloc: 0x%p 0x%p %d\n", p, mh->caller, size); - */ - } - return(p); -} - -void Novfs_Free( const void *p ) -{ - PMEMORY_LIST mh; - - if (p) - { - /*DbgPrint("Novfs_Free: 0x%p 0x%p\n", p, __builtin_return_address(0)); - */ - mh = (PMEMORY_LIST)((char *)p-sizeof(MEMORY_LIST)); - - spin_lock(&Malloc_Lock); - list_del(&mh->list); - spin_unlock(&Malloc_Lock); - kfree(mh); - } -} - - -int -NO_TRACE -profile_dump_memorylist_dbg(int argc, const char **argv, const char **envp, struct pt_regs *regs) -{ -#ifdef CONFIG_KDB - profile_dump_memorylist(kdb_printf); -#endif /* CONFIG_KDB */ - - return( 0 ); -} - -void -NO_TRACE -profile_dump_memorylist( void *pf ) -{ - void (*pfunc)(char *Fmt, ...) = pf; - - PMEMORY_LIST mh; - struct list_head *l; - - size_t total=0; - int count=0; - - spin_lock( &Malloc_Lock ); - - list_for_each( l, &Memory_List ) - { - mh = list_entry(l, MEMORY_LIST, list); - pfunc("0x%p 0x%p 0x%p %d\n", mh, (char *)mh+sizeof(MEMORY_LIST), mh->caller, mh->size); - count++; - total += mh->size; - } - spin_unlock( &Malloc_Lock ); - - pfunc("Blocks=%d Total=%d\n", count, total); -} - -void -NO_TRACE -profile_dump_dt(struct dentry *parent, void *pf ) -{ - void (*pfunc)(char *Fmt, ...) = pf; - struct l { - struct l *next; - struct dentry *dentry; - } *l, *n, *start; - struct list_head *p; - struct dentry *d; - char *buf, *path, *sd; - char inode_number[16]; - - buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); - - if( NULL == buf ) - { - return; - } - - if (parent) - { - pfunc("starting 0x%p %.*s\n", parent, parent->d_name.len, parent->d_name.name); - if (parent->d_subdirs.next == &parent->d_subdirs) - { - pfunc("No children...\n"); - } - else - { - start = Novfs_Malloc(sizeof(*start), GFP_KERNEL); - if (start) - { - start->next = NULL; - start->dentry = parent; - l = start; - while(l) - { - p = l->dentry->d_subdirs.next; - while(p != &l->dentry->d_subdirs) - { - d = list_entry(p, struct dentry, D_CHILD); - p = p->next; - - if (d->d_subdirs.next != &d->d_subdirs) - { - n = Novfs_Malloc(sizeof(*n), GFP_KERNEL); - if (n) - { - n->next = l->next; - l->next = n; - n->dentry = d; - } - } - else - { - path = Scope_dget_path(d, buf, PATH_LENGTH_BUFFER, 1); - if (path) - { - pfunc("1-0x%p %s\n" \ - " d_name: %.*s\n" \ - " d_parent: 0x%p\n" \ - " d_count: %d\n" \ - " d_flags: 0x%x\n" \ - " d_subdirs: 0x%p\n" \ - " d_inode: 0x%p\n", - d, path, d->d_name.len, d->d_name.name, d->d_parent, - atomic_read(&d->d_count), d->d_flags, d->d_subdirs.next, d->d_inode); - } - } - } - l = l->next; - } - l = start; - while(l) - { - d=l->dentry; - path = Scope_dget_path(d, buf, PATH_LENGTH_BUFFER, 1); - if (path) - { - sd = " (None)"; - if (&d->d_subdirs != d->d_subdirs.next) - { - sd = ""; - } - inode_number[0] = '\0'; - if (d->d_inode) - { - sprintf(inode_number, " (%lu)", d->d_inode->i_ino); - } - pfunc("0x%p %s\n" \ - " d_parent: 0x%p\n" \ - " d_count: %d\n" \ - " d_flags: 0x%x\n" \ - " d_subdirs: 0x%p%s\n" \ - " d_inode: 0x%p%s\n", - d, path, d->d_parent, - atomic_read(&d->d_count), d->d_flags, d->d_subdirs.next, sd, d->d_inode, inode_number); - } - - n = l; - l = l->next; - Novfs_Free(n); - } - } - } - } - - Novfs_Free(buf); - -} - -/*int profile_inode_open(struct inode *inode, struct file *file) -{ - -} - -int profile_inode_close(struct inode *inode, struct file *file) -{ -} -*/ -ssize_t profile_common_read( char *buf, size_t len, loff_t *off ) -{ - ssize_t retval=0; - size_t count; - unsigned long offset = *off; - - if (0 != (count = DbgPrintBufferOffset - offset)) - { - if (count > len) - { - count = len; - } - - count -= copy_to_user(buf, &DbgPrintBuffer[offset], count); - - if (count == 0) - { - retval = -EFAULT; - } - else - { - *off += (loff_t)count; - retval = count; - } - } - return retval; - -} - -//ssize_t NO_TRACE profile_inode_read(struct file *file, char *buf, size_t len, loff_t *off) -ssize_t profile_inode_read(struct file *file, char *buf, size_t len, loff_t *off) -{ - ssize_t retval=0; - unsigned long offset = *off; - static char save_DbgPrintOn; - - if (offset == 0) - { - down(&LocalPrint_lock); - save_DbgPrintOn = DbgPrintOn; - DbgPrintOn = 0; - - DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0; - Novfs_dump_inode( LocalPrint ); - } - - retval = profile_common_read(buf, len, off); - - if ( 0 == retval) - { - DbgPrintOn = save_DbgPrintOn; - DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0; - - up(&LocalPrint_lock); - } - - return retval; - -} - -ssize_t NO_TRACE profile_dentry_read(struct file *file, char *buf, size_t len, loff_t *off) -{ - ssize_t retval=0; - unsigned long offset = *off; - static char save_DbgPrintOn; - - if (offset == 0) - { - down(&LocalPrint_lock); - save_DbgPrintOn = DbgPrintOn; - DbgPrintOn = 0; - DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0; - profile_dump_dt(Novfs_root, LocalPrint); - } - - retval = profile_common_read(buf, len, off); - - if ( 0 == retval) - { - DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0; - DbgPrintOn = save_DbgPrintOn; - - up(&LocalPrint_lock); - } - - return retval; - -} - -ssize_t NO_TRACE profile_memory_read(struct file *file, char *buf, size_t len, loff_t *off) -{ - ssize_t retval=0; - unsigned long offset = *off; - static char save_DbgPrintOn; - - if (offset == 0) - { - down(&LocalPrint_lock); - save_DbgPrintOn = DbgPrintOn; - DbgPrintOn = 0; - DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0; - profile_dump_memorylist( LocalPrint ); - } - - retval = profile_common_read(buf, len, off); - - if ( 0 == retval) - { - DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0; - DbgPrintOn = save_DbgPrintOn; - - up(&LocalPrint_lock); - } - - return retval; - -} diff -uNr src.old/novfs/profile_funcs.h src/novfs/profile_funcs.h --- src.old/novfs/profile_funcs.h 2006-07-11 21:24:18.000000000 +0200 +++ src/novfs/profile_funcs.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,419 +0,0 @@ -extern void Daemon_Added_Resource( void ); -extern void Daemon_Close_Control( void ); -extern void Daemon_CreateSessionId( void ); -extern void Daemon_DestroySessionId( void ); -extern void Daemon_Dumpque( void ); -extern void Daemon_Get_UserSpace( void ); -extern void Daemon_Library_close( void ); -extern void Daemon_Library_ioctl( void ); -extern void Daemon_Library_open( void ); -extern void Daemon_Library_read( void ); -extern void Daemon_Library_write( void ); -extern void Daemon_Login( void ); -extern void Daemon_Logout( void ); -extern void Daemon_Open_Control( void ); -extern void Daemon_Poll( void ); -extern void Daemon_Receive_Reply( void ); -extern void Daemon_Remove_Resource( void ); -extern void Daemon_Send_Command( void ); -extern void Daemon_SetMountPoint( void ); -extern void Daemon_Timer( void ); -extern void Daemon_getpwuid( void ); -extern void Daemon_getversion( void ); -extern void Daemon_ioctl( void ); -extern void GetConnData( void ); -extern void GetUserData( void ); -extern void Init_Daemon_Queue( void ); -extern void Init_Procfs_Interface( void ); -extern void Novfs_Add_to_Root( void ); -extern void Novfs_Add_to_Root2( void ); -extern void Novfs_Close_File( void ); -extern void Novfs_Close_Stream( void ); -extern void Novfs_Control_ioctl( void ); -extern void Novfs_Control_read( void ); -extern void Novfs_Control_write( void ); -extern void Novfs_Create( void ); -extern void Novfs_Delete( void ); -extern void Novfs_Find_Name_In_List( void ); -extern void Novfs_Get_Connected_Server_List( void ); -extern void Novfs_Get_Directory_List( void ); -extern void Novfs_Get_Directory_ListEx( void ); -extern void Novfs_Get_File_Info( void ); -extern void Novfs_Get_File_Info2( void ); -extern void Novfs_Get_Server_Volume_List( void ); -extern void Novfs_Get_Version( void ); -extern void Novfs_Open_File( void ); -extern void Novfs_Read_File( void ); -extern void Novfs_Read_Stream( void ); -extern void Novfs_Remove_from_Root( void ); -extern void Novfs_Rename_File( void ); -extern void Novfs_Set_Attr( void ); -extern void Novfs_Truncate_File( void ); -extern void Novfs_User_proc_ioctl( void ); -extern void Novfs_User_proc_read( void ); -extern void Novfs_User_proc_write( void ); -extern void Novfs_Verify_Server_Name( void ); -extern void Novfs_Verify_Volume_Name( void ); -extern void Novfs_Write_File( void ); -extern void Novfs_Write_File2( void ); -extern void Novfs_Write_Stream( void ); -extern void Novfs_a_readpage( void ); -extern void Novfs_add_inode_entry( void ); -extern void Novfs_clear_inode( void ); -extern void Novfs_d_add( void ); -extern void Novfs_d_compare( void ); -extern void Novfs_d_delete( void ); -extern void Novfs_d_hash( void ); -extern void Novfs_d_iput( void ); -extern void Novfs_d_lookup( void ); -extern void Novfs_d_release( void ); -extern void Novfs_d_revalidate( void ); -extern void Novfs_d_strcmp( void ); -extern void Novfs_dget_path( void ); -extern void Novfs_dir_fsync( void ); -extern void Novfs_dir_lseek( void ); -extern void Novfs_dir_open( void ); -extern void Novfs_dir_read( void ); -extern void Novfs_dir_readdir( void ); -extern void Novfs_dir_release( void ); -extern void Novfs_enumerate_inode_cache( void ); -extern void Novfs_f_flush( void ); -extern void Novfs_f_fsync( void ); -extern void Novfs_f_ioctl( void ); -extern void Novfs_f_llseek( void ); -extern void Novfs_f_lock( void ); -extern void Novfs_f_mmap( void ); -extern void Novfs_f_open( void ); -extern void Novfs_f_read( void ); -extern void Novfs_f_readdir( void ); -extern void Novfs_f_release( void ); -extern void Novfs_f_write( void ); -extern void Novfs_fill_super( void ); -extern void Novfs_free_inode_cache( void ); -extern void Novfs_free_invalid_entries( void ); -extern void Novfs_get_alltrees( void ); -extern void Novfs_get_entry( void ); -extern void Novfs_get_entry_time( void ); -extern void Novfs_get_inode( void ); -extern void Novfs_get_remove_entry( void ); -extern void Novfs_get_sb( void ); -extern void Novfs_i_create( void ); -extern void Novfs_i_getattr( void ); -extern void Novfs_i_lookup( void ); -extern void Novfs_i_mkdir( void ); -extern void Novfs_i_mknod( void ); -extern void Novfs_i_permission( void ); -extern void Novfs_i_rename( void ); -extern void Novfs_i_revalidate( void ); -extern void Novfs_i_rmdir( void ); -extern void Novfs_i_setattr( void ); -extern void Novfs_i_unlink( void ); -extern void Novfs_internal_hash( void ); -extern void Novfs_invalidate_inode_cache( void ); -extern void Novfs_kill_sb( void ); -extern void Novfs_lock_inode_cache( void ); -extern void Novfs_lookup_inode_cache( void ); -extern void Novfs_lookup_validate( void ); -extern void Novfs_notify_change( void ); -extern void Novfs_read_inode( void ); -extern void Novfs_remove_inode_entry( void ); -extern void Novfs_show_options( void ); -extern void Novfs_statfs( void ); -extern void Novfs_tree_read( void ); -extern void Novfs_unlock_inode_cache( void ); -extern void Novfs_update_entry( void ); -extern void Novfs_verify_file( void ); -extern void Novfs_write_inode( void ); -extern void NwAuthConnWithId( void ); -extern void NwConnClose( void ); -extern void NwGetConnInfo( void ); -extern void NwGetDaemonVersion( void ); -extern void NwGetIdentityInfo( void ); -extern void NwLicenseConn( void ); -extern void NwLoginIdentity( void ); -extern void NwLogoutIdentity( void ); -extern void NwOpenConnByAddr( void ); -extern void NwOpenConnByName( void ); -extern void NwOpenConnByRef( void ); -extern void NwQueryFeature( void ); -extern void NwRawSend( void ); -extern void NwScanConnInfo( void ); -extern void NwSetConnInfo( void ); -extern void NwSysConnClose( void ); -extern void NwUnAuthenticate( void ); -extern void NwUnlicenseConn( void ); -extern void NwcChangeAuthKey( void ); -extern void NwcEnumIdentities( void ); -extern void NwcEnumerateDrives( void ); -extern void NwcGetBroadcastMessage( void ); -extern void NwcGetDefaultNameCtx( void ); -extern void NwcGetPreferredDSTree( void ); -extern void NwcGetPrimaryConn( void ); -extern void NwcGetTreeMonitoredConn( void ); -extern void NwcSetDefaultNameCtx( void ); -extern void NwcSetMapDrive( void ); -extern void NwcSetPreferredDSTree( void ); -extern void NwcSetPrimaryConn( void ); -extern void NwcUnMapDrive( void ); -extern void NwdConvertLocalHandle( void ); -extern void NwdConvertNetwareHandle( void ); -extern void NwdGetMountPath( void ); -extern void NwdSetKeyValue( void ); -extern void NwdSetMapDrive( void ); -extern void NwdUnMapDrive( void ); -extern void NwdVerifyKeyValue( void ); -extern void Queue_Daemon_Command( void ); -extern void Queue_get( void ); -extern void Queue_put( void ); -extern void RemoveDriveMaps( void ); -extern void Scope_Cleanup( void ); -extern void Scope_Cleanup_Thread( void ); -extern void Scope_Dump_Scopetable( void ); -extern void Scope_Dump_Tasklist( void ); -extern void Scope_Find_Scope( void ); -extern void Scope_Get_Hash( void ); -extern void Scope_Get_ScopeUsers( void ); -extern void Scope_Get_ScopefromName( void ); -extern void Scope_Get_ScopefromPath( void ); -extern void Scope_Get_SessionId( void ); -extern void Scope_Get_Uid( void ); -extern void Scope_Get_UserName( void ); -extern void Scope_Get_UserSpace( void ); -extern void Scope_Init( void ); -extern void Scope_Lookup( void ); -extern void Scope_Search4Scope( void ); -extern void Scope_Set_UserSpace( void ); -extern void Scope_Timer_Function( void ); -extern void Scope_Uninit( void ); -extern void Scope_Validate_Scope( void ); -extern void Uninit_Daemon_Queue( void ); -extern void Uninit_Procfs_Interface( void ); -extern void add_to_list( void ); -extern void begin_directory_enumerate( void ); -extern void directory_enumerate( void ); -extern void directory_enumerate_ex( void ); -extern void do_login( void ); -extern void do_logout( void ); -extern void end_directory_enumerate( void ); -extern void exit_novfs( void ); -extern void find_queue( void ); -extern void get_next_queue( void ); -extern void init_novfs( void ); -extern void local_unlink( void ); -extern void process_list( void ); -extern void update_inode( void ); -extern void verify_dentry( void ); - -SYMBOL_TABLE SymbolTable[] = { - {Scope_Get_UserSpace, "Scope_Get_UserSpace"}, - {NwLoginIdentity, "NwLoginIdentity"}, - {Novfs_d_revalidate, "Novfs_d_revalidate"}, - {Daemon_SetMountPoint, "Daemon_SetMountPoint"}, - {Scope_Get_Hash, "Scope_Get_Hash"}, - {Queue_get, "Queue_get"}, - {Queue_Daemon_Command, "Queue_Daemon_Command"}, - {Novfs_dir_fsync, "Novfs_dir_fsync"}, - {Novfs_Read_File, "Novfs_Read_File"}, - {Daemon_Library_close, "Daemon_Library_close"}, - {NwRawSend, "NwRawSend"}, - {Novfs_get_inode, "Novfs_get_inode"}, - {Novfs_Remove_from_Root, "Novfs_Remove_from_Root"}, - {Novfs_Find_Name_In_List, "Novfs_Find_Name_In_List"}, - {Scope_Get_SessionId, "Scope_Get_SessionId"}, - {NwOpenConnByAddr, "NwOpenConnByAddr"}, - {Novfs_read_inode, "Novfs_read_inode"}, - {Novfs_Truncate_File, "Novfs_Truncate_File"}, - {Daemon_Login, "Daemon_Login"}, - {Scope_Get_ScopefromPath, "Scope_Get_ScopefromPath"}, - {NwcGetTreeMonitoredConn, "NwcGetTreeMonitoredConn"}, - {Novfs_write_inode, "Novfs_write_inode"}, - {Scope_Lookup, "Scope_Lookup"}, - {NwQueryFeature, "NwQueryFeature"}, - {Novfs_get_entry_time, "Novfs_get_entry_time"}, - {Novfs_Control_write, "Novfs_Control_write"}, - {Scope_Get_Uid, "Scope_Get_Uid"}, - {NwSysConnClose, "NwSysConnClose"}, - {NwConnClose, "NwConnClose"}, - {Novfs_get_entry, "Novfs_get_entry"}, - {Novfs_Rename_File, "Novfs_Rename_File"}, - {NwdConvertLocalHandle, "NwdConvertLocalHandle"}, - {Novfs_dir_lseek, "Novfs_dir_lseek"}, - {Scope_Get_ScopefromName, "Scope_Get_ScopefromName"}, - {NwcGetPrimaryConn, "NwcGetPrimaryConn"}, - {Novfs_d_strcmp, "Novfs_d_strcmp"}, - {Daemon_Library_ioctl, "Daemon_Library_ioctl"}, - {end_directory_enumerate, "end_directory_enumerate"}, - {directory_enumerate, "directory_enumerate"}, - {begin_directory_enumerate, "begin_directory_enumerate"}, - {NwdGetMountPath, "NwdGetMountPath"}, - {NwAuthConnWithId, "NwAuthConnWithId"}, - {Novfs_Set_Attr, "Novfs_Set_Attr"}, - {Daemon_getversion, "Daemon_getversion"}, - {Scope_Dump_Scopetable, "Scope_Dump_Scopetable"}, - {NwcSetMapDrive, "NwcSetMapDrive"}, - {Novfs_lookup_inode_cache, "Novfs_lookup_inode_cache"}, - {Novfs_i_mkdir, "Novfs_i_mkdir"}, - {Novfs_free_invalid_entries, "Novfs_free_invalid_entries"}, - {Novfs_dump_inode_cache, "Novfs_dump_inode_cache"}, - {Novfs_Write_Stream, "Novfs_Write_Stream"}, - {Novfs_Verify_Server_Name, "Novfs_Verify_Server_Name"}, - {GetConnData, "GetConnData"}, - {Uninit_Procfs_Interface, "Uninit_Procfs_Interface"}, - {Scope_Validate_Scope, "Scope_Validate_Scope"}, - {Scope_Timer_Function, "Scope_Timer_Function"}, - {Novfs_i_setattr, "Novfs_i_setattr"}, - {Novfs_i_mknod, "Novfs_i_mknod"}, - {Novfs_Verify_Volume_Name, "Novfs_Verify_Volume_Name"}, - {Novfs_Close_Stream, "Novfs_Close_Stream"}, - {Novfs_Add_to_Root, "Novfs_Add_to_Root"}, - {Init_Procfs_Interface, "Init_Procfs_Interface"}, - {Novfs_dump_inode, "Novfs_dump_inode"}, - {Novfs_Get_Directory_List, "Novfs_Get_Directory_List"}, - {Novfs_Get_Connected_Server_List, "Novfs_Get_Connected_Server_List"}, - {Daemon_Logout, "Daemon_Logout"}, - {do_logout, "do_logout"}, - {Scope_Search4Scope, "Scope_Search4Scope"}, - {NwdUnMapDrive, "NwdUnMapDrive"}, - {Novfs_Control_read, "Novfs_Control_read"}, - {Scope_Cleanup_Thread, "Scope_Cleanup_Thread"}, - {Novfs_invalidate_inode_cache, "Novfs_invalidate_inode_cache"}, - {Novfs_f_flush, "Novfs_f_flush"}, - {Novfs_enumerate_inode_cache, "Novfs_enumerate_inode_cache"}, - {Novfs_d_compare, "Novfs_d_compare"}, - {Daemon_Library_write, "Daemon_Library_write"}, - {GetUserData, "GetUserData"}, - {Daemon_Remove_Resource, "Daemon_Remove_Resource"}, - {Scope_Set_UserSpace, "Scope_Set_UserSpace"}, - {Novfs_get_alltrees, "Novfs_get_alltrees"}, - {Daemon_Get_UserSpace, "Daemon_Get_UserSpace"}, - {Uninit_Daemon_Queue, "Uninit_Daemon_Queue"}, - {NwcChangeAuthKey, "NwcChangeAuthKey"}, - {NwLicenseConn, "NwLicenseConn"}, - {Init_Daemon_Queue, "Init_Daemon_Queue"}, - {Novfs_tree_read, "Novfs_tree_read"}, - {Novfs_f_llseek, "Novfs_f_llseek"}, - {find_queue, "find_queue"}, - {Scope_Find_Scope, "Scope_Find_Scope"}, - {Novfs_lookup_validate, "Novfs_lookup_validate"}, - {Novfs_d_hash, "Novfs_d_hash"}, - {Novfs_a_readpage, "Novfs_a_readpage"}, - {Novfs_Create, "Novfs_Create"}, - {Novfs_Close_File, "Novfs_Close_File"}, - {Daemon_getpwuid, "Daemon_getpwuid"}, - {Daemon_CreateSessionId, "Daemon_CreateSessionId"}, - {Scope_dget_path, "Scope_dget_path"}, - {NwcSetDefaultNameCtx, "NwcSetDefaultNameCtx"}, - {NwcGetDefaultNameCtx, "NwcGetDefaultNameCtx"}, - {NwUnAuthenticate, "NwUnAuthenticate"}, - {Novfs_i_getattr, "Novfs_i_getattr"}, - {Novfs_get_remove_entry, "Novfs_get_remove_entry"}, - {Novfs_f_ioctl, "Novfs_f_ioctl"}, - {Scope_Get_ScopeUsers, "Scope_Get_ScopeUsers"}, - {Scope_Dump_Tasklist, "Scope_Dump_Tasklist"}, - {NwOpenConnByRef, "NwOpenConnByRef"}, - {Novfs_unlock_inode_cache, "Novfs_unlock_inode_cache"}, - {Novfs_lock_inode_cache, "Novfs_lock_inode_cache"}, - {Daemon_DestroySessionId, "Daemon_DestroySessionId"}, - {do_login, "do_login"}, - {Novfs_free_inode_cache, "Novfs_free_inode_cache"}, - {Novfs_Read_Stream, "Novfs_Read_Stream"}, - {Daemon_Library_read, "Daemon_Library_read"}, - {NwdSetMapDrive, "NwdSetMapDrive"}, - {Novfs_internal_hash, "Novfs_internal_hash"}, - {Daemon_Receive_Reply, "Daemon_Receive_Reply"}, - {Daemon_Library_open, "Daemon_Library_open"}, - {get_next_queue, "get_next_queue"}, - {exit_novfs, "exit_novfs"}, - {NwcGetBroadcastMessage, "NwcGetBroadcastMessage"}, - {Novfs_d_lookup, "Novfs_d_lookup"}, - {Novfs_clear_inode, "Novfs_clear_inode"}, - {Daemon_Open_Control, "Daemon_Open_Control"}, - {NwdConvertNetwareHandle, "NwdConvertNetwareHandle"}, - {NwcUnMapDrive, "NwcUnMapDrive"}, - {Novfs_notify_change, "Novfs_notify_change"}, - {Novfs_dir_release, "Novfs_dir_release"}, - {directory_enumerate_ex, "directory_enumerate_ex"}, - {RemoveDriveMaps, "RemoveDriveMaps"}, - {NwOpenConnByName, "NwOpenConnByName"}, - {Novfs_verify_file, "Novfs_verify_file"}, - {Novfs_statfs, "Novfs_statfs"}, - {Novfs_f_write, "Novfs_f_write"}, - {Novfs_Get_File_Info, "Novfs_Get_File_Info"}, - {Novfs_Delete, "Novfs_Delete"}, - {update_inode, "update_inode"}, - {NwcSetPreferredDSTree, "NwcSetPreferredDSTree"}, - {NwcGetPreferredDSTree, "NwcGetPreferredDSTree"}, - {Novfs_update_entry, "Novfs_update_entry"}, - {Novfs_kill_sb, "Novfs_kill_sb"}, - {Daemon_ioctl, "Daemon_ioctl"}, - {Scope_Get_UserName, "Scope_Get_UserName"}, - {NwcEnumerateDrives, "NwcEnumerateDrives"}, - {Novfs_i_revalidate, "Novfs_i_revalidate"}, - {Novfs_f_release, "Novfs_f_release"}, - {Novfs_f_read, "Novfs_f_read"}, - {Novfs_d_delete, "Novfs_d_delete"}, - {Novfs_Write_File, "Novfs_Write_File"}, - {Novfs_User_proc_ioctl, "Novfs_User_proc_ioctl"}, - {Novfs_Get_File_Info2, "Novfs_Get_File_Info2"}, - {NwdSetKeyValue, "NwdSetKeyValue"}, - {Novfs_remove_inode_entry, "Novfs_remove_inode_entry"}, - {Novfs_i_rename, "Novfs_i_rename"}, - {Novfs_f_open, "Novfs_f_open"}, - {Novfs_d_iput, "Novfs_d_iput"}, - {Novfs_Get_Directory_ListEx, "Novfs_Get_Directory_ListEx"}, - {Daemon_Timer, "Daemon_Timer"}, - {Daemon_Close_Control, "Daemon_Close_Control"}, - {verify_dentry, "verify_dentry"}, - {process_list, "process_list"}, - {local_unlink, "local_unlink"}, - {init_novfs, "init_novfs"}, - {NwUnlicenseConn, "NwUnlicenseConn"}, - {NwGetConnInfo, "NwGetConnInfo"}, - {Novfs_i_permission, "Novfs_i_permission"}, - {Novfs_dir_read, "Novfs_dir_read"}, - {NwcSetPrimaryConn, "NwcSetPrimaryConn"}, - {Novfs_f_lock, "Novfs_f_lock"}, - {Novfs_dir_readdir, "Novfs_dir_readdir"}, - {Novfs_dir_open, "Novfs_dir_open"}, - {Queue_put, "Queue_put"}, - {NwLogoutIdentity, "NwLogoutIdentity"}, - {NwGetIdentityInfo, "NwGetIdentityInfo"}, - {Novfs_i_rmdir, "Novfs_i_rmdir"}, - {Novfs_i_create, "Novfs_i_create"}, - {Novfs_f_mmap, "Novfs_f_mmap"}, - {Novfs_Write_File2, "Novfs_Write_File2"}, - {Novfs_User_proc_read, "Novfs_User_proc_read"}, - {Novfs_show_options, "Novfs_show_options"}, - {Novfs_add_inode_entry, "Novfs_add_inode_entry"}, - {Novfs_Open_File, "Novfs_Open_File"}, - {Novfs_Get_Version, "Novfs_Get_Version"}, - {Daemon_Poll, "Daemon_Poll"}, - {add_to_list, "add_to_list"}, - {Scope_Init, "Scope_Init"}, - {Scope_Cleanup, "Scope_Cleanup"}, - {NwSetConnInfo, "NwSetConnInfo"}, - {Novfs_i_unlink, "Novfs_i_unlink"}, - {Novfs_get_sb, "Novfs_get_sb"}, - {Novfs_f_readdir, "Novfs_f_readdir"}, - {Novfs_f_fsync, "Novfs_f_fsync"}, - {Novfs_d_release, "Novfs_d_release"}, - {Novfs_User_proc_write, "Novfs_User_proc_write"}, - {Daemon_Send_Command, "Daemon_Send_Command"}, - {Daemon_Dumpque, "Daemon_Dumpque"}, - {NwcEnumIdentities, "NwcEnumIdentities"}, - {NwGetDaemonVersion, "NwGetDaemonVersion"}, - {Novfs_i_lookup, "Novfs_i_lookup"}, - {Novfs_fill_super, "Novfs_fill_super"}, - {Novfs_Get_Server_Volume_List, "Novfs_Get_Server_Volume_List"}, - {Novfs_Add_to_Root2, "Novfs_Add_to_Root2"}, - {Daemon_SendDebugCmd, "Daemon_SendDebugCmd"}, - {Daemon_Added_Resource, "Daemon_Added_Resource"}, - {Scope_Uninit, "Scope_Uninit"}, - {NwdVerifyKeyValue, "NwdVerifyKeyValue"}, - {NwScanConnInfo, "NwScanConnInfo"}, - {Novfs_dget_path, "Novfs_dget_path"}, - {Novfs_d_add, "Novfs_d_add"}, - {Novfs_Control_ioctl, "Novfs_Control_ioctl"}, - // Terminate the table - {NULL, NULL} -}; diff -uNr src.old/novfs/scope.c src/novfs/scope.c --- src.old/novfs/scope.c 2006-07-11 21:24:18.000000000 +0200 +++ src/novfs/scope.c 1970-01-01 01:00:00.000000000 +0100 @@ -1,1210 +0,0 @@ -/*++======================================================================== - * Program Name: Novell NCP Redirector for Linux - * File Name: scope.c - * Version: v1.00 - * Author: James Turner - * - * Abstract: This module contains functions used to scope - * users. - * Notes: - * Revision History: - * - * - * Copyright (C) 2005 Novell, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - *======================================================================--*/ - -/*===[ Include files specific to Linux ]==================================*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/*===[ Include files specific to this module ]============================*/ -#include "vfs.h" -#define LEADER signal->leader - -/*===[ External data ]====================================================*/ - -/*===[ External prototypes ]==============================================*/ -extern int DbgPrint( char *Fmt, ... ); -extern int Daemon_CreateSessionId( uint64_t *SessionId ); -extern int Daemon_DestroySessionId( uint64_t SessionId ); -extern int Daemon_getpwuid( uid_t uid, int unamelen, char *uname ); -extern int Daemon_Get_UserSpace( uint64_t SessionId, uint64_t *TotalSize, uint64_t *TotalFree, uint64_t *TotalDirectoryEnties, uint64_t *FreeDirectoryEnties); - -extern int Novfs_Remove_from_Root(char *); -extern int Novfs_Add_to_Root(char *); - -/*===[ Manifest constants ]===============================================*/ -#define CLEANUP_INTERVAL 10 -#define MAX_USERNAME_LENGTH 32 - -/*===[ Type definitions ]=================================================*/ -typedef struct _SCOPE_LIST_ -{ - struct list_head ScopeList; - scope_t ScopeId; - session_t SessionId; - pid_t ScopePid; - task_t *ScopeTask; - unsigned long ScopeHash; - uid_t ScopeUid; - uint64_t ScopeUSize; - uint64_t ScopeUFree; - uint64_t ScopeUTEnties; - uint64_t ScopeUAEnties; - int ScopeUserNameLength; - unsigned char ScopeUserName[MAX_USERNAME_LENGTH]; -} SCOPE_LIST, *PSCOPE_LIST; - -/*===[ Function prototypes ]==============================================*/ -void Scope_Init( void ); -void Scope_Uninit( void ); - -PSCOPE_LIST Scope_Search4Scope( session_t Id, BOOLEAN Session, BOOLEAN Locked ); -PSCOPE_LIST Scope_Find_Scope( BOOLEAN Create ); -unsigned long Scope_Get_Hash( PSCOPE_LIST Scope ); -uid_t Scope_Get_Uid( PSCOPE_LIST Scope ); -int Scope_Validate_Scope( PSCOPE_LIST Scope ); -char *Scope_Get_UserName( PSCOPE_LIST Scope ); -session_t Scope_Get_SessionId( PSCOPE_LIST Scope ); -PSCOPE_LIST Scope_Get_ScopefromName( struct qstr *Name ); -int Scope_Set_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties ); -int Scope_Get_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties ); - -char *Scope_Get_ScopeUsers( void ); -void *Scope_Lookup( void ); - -void Scope_Timer_Function(unsigned long Context); -int Scope_Cleanup_Thread(void *Args); -void Scope_Cleanup( void ); -char *Scope_dget_path( struct dentry *Dentry, char *Buf, unsigned int Buflen, int Flags); -void Scope_Dump_Tasklist( void ); -void Scope_Dump_Scopetable( void ); - -/*===[ Global variables ]=================================================*/ -struct list_head Scope_List; -struct semaphore Scope_Lock; -struct semaphore Scope_Thread_Delay; -int Scope_Thread_Terminate=0; -struct semaphore Scope_Delay_Event; -struct timer_list Scope_Timer; -unsigned long Scope_Hash_Val=1; - -/*===[ Code ]=============================================================*/ - -/*++======================================================================*/ -void Scope_Init( void ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - INIT_LIST_HEAD( &Scope_List ); - init_MUTEX( &Scope_Lock ); - init_MUTEX_LOCKED( &Scope_Thread_Delay ); - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) - kernel_thread( Scope_Cleanup_Thread, NULL, 0 ); -#else - kthread_run(Scope_Cleanup_Thread, NULL, "novfs_ST"); -#endif -} - -/*++======================================================================*/ -void Scope_Uninit( void ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - Scope_Thread_Terminate = 1; - - up(&Scope_Thread_Delay); - - mb(); - while( Scope_Thread_Terminate ) - { - yield(); - } - printk( KERN_INFO "Scope_Uninit: Exit\n"); - -} - -/*++======================================================================*/ -PSCOPE_LIST Scope_Search4Scope( session_t Id, BOOLEAN Session, BOOLEAN Locked ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - PSCOPE_LIST scope, rscope=NULL; - struct list_head *sl; - int offset; - - DbgPrint("Scope_Search4Scope: 0x%llx 0x%x 0x%x\n", Id, Session, Locked); - - if ( Session ) - { - offset = (int)(&((PSCOPE_LIST)0)->SessionId); - } - else - { - offset = (int)(&((PSCOPE_LIST)0)->ScopeId); - } - - if ( !Locked ) - { - down( &Scope_Lock ); - } - - sl = Scope_List.next; - DbgPrint("Scope_Search4Scope: 0x%x\n", sl); - while (sl != &Scope_List) - { - scope = list_entry(sl, SCOPE_LIST, ScopeList); - - if ( Id == *(session_t *)((char *)scope+offset) ) - { - rscope = scope; - break; - } - - sl = sl->next; - } - - if ( !Locked ) - { - up( &Scope_Lock ); - } - - DbgPrint("Scope_Search4Scope: return 0x%x\n", rscope); - return( rscope ); -} - -/*++======================================================================*/ -PSCOPE_LIST Scope_Find_Scope( BOOLEAN Create ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - PSCOPE_LIST scope=NULL, pscope=NULL; - task_t *task; - scope_t scopeId; - int addscope=0; - - task = current; - - DbgPrint("Scope_Find_Scope: %d %d %d %d\n", task->uid, task->euid, task->suid, task->fsuid); - - scopeId = task->euid; - - scope = Scope_Search4Scope( scopeId, FALSE, FALSE ); - - if ( !scope && Create ) - { - scope = Novfs_Malloc( sizeof(*pscope), GFP_KERNEL ); - if ( scope ) - { - scope->ScopeId = scopeId; - scope->SessionId = 0; - scope->ScopePid = task->pid; - scope->ScopeTask = task; - scope->ScopeHash = 0; - scope->ScopeUid = task->euid; - scope->ScopeUserName[0] = '\0'; - - if ( !Daemon_CreateSessionId( &scope->SessionId ) ) - { - DbgPrint("Scope_Find_Scope2: %d %d %d %d\n", task->uid, task->euid, task->suid, task->fsuid); - memset(scope->ScopeUserName, 0, sizeof(scope->ScopeUserName)); - scope->ScopeUserNameLength = 0; - Daemon_getpwuid(task->euid, sizeof(scope->ScopeUserName), scope->ScopeUserName); - scope->ScopeUserNameLength = strlen(scope->ScopeUserName); - addscope = 1; - } - - scope->ScopeHash = Scope_Hash_Val++; - DbgPrint("Scope_Find_Scope: Adding 0x%x\n" \ - " ScopeId: 0x%llx\n" \ - " SessionId: 0x%llx\n" \ - " ScopePid: %d\n" \ - " ScopeTask: 0x%x\n" \ - " ScopeHash: %d\n" \ - " ScopeUid: %d\n" \ - " ScopeUserNameLength: %d\n" \ - " ScopeUserName: %s\n", - scope, - scope->ScopeId, - scope->SessionId, - scope->ScopePid, - scope->ScopeTask, - scope->ScopeHash, - scope->ScopeUid, - scope->ScopeUserNameLength, - scope->ScopeUserName); - - if ( scope->SessionId ) - { - down( &Scope_Lock ); - list_add(&scope->ScopeList, &Scope_List); - up( &Scope_Lock ); - } - else - { - Novfs_Free(scope); - scope = NULL; - } - } - - if (addscope) - { - Novfs_Add_to_Root( scope->ScopeUserName ); - } - } - - return(scope); -} - -/*++======================================================================*/ -unsigned long Scope_Get_Hash( PSCOPE_LIST Scope ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - unsigned long hash=0; - - if ( NULL == Scope) - { - Scope = Scope_Find_Scope( TRUE ); - } - - if ( Scope && Scope_Validate_Scope( Scope )) - { - hash = Scope->ScopeHash; - } - return( hash ); -} - -/*++======================================================================*/ -uid_t Scope_Get_Uid( PSCOPE_LIST Scope ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - uid_t uid=0; - - if ( NULL == Scope) - { - Scope = Scope_Find_Scope( TRUE ); - } - - if ( Scope && Scope_Validate_Scope( Scope )) - { - uid = Scope->ScopeUid; - } - return( uid ); -} - -/*++======================================================================*/ -int Scope_Validate_Scope( PSCOPE_LIST Scope ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - PSCOPE_LIST s; - struct list_head *sl; - int retVal = 0; - - DbgPrint("Scope_Validate_Scope: 0x%x\n", Scope); - - down( &Scope_Lock ); - - sl = Scope_List.next; - while (sl != &Scope_List) - { - s = list_entry(sl, SCOPE_LIST, ScopeList); - - if ( s == Scope ) - { - retVal = 1; - break; - } - - sl = sl->next; - } - - up( &Scope_Lock ); - - return( retVal ); -} - -/*++======================================================================*/ -char *Scope_Get_UserName( PSCOPE_LIST Scope ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - char *name=NULL; - - if ( !Scope ) - { - Scope = Scope_Find_Scope( TRUE ); - } - - if ( Scope && Scope_Validate_Scope( Scope )) - { - name = Scope->ScopeUserName; - } - return( name ); -} - -/*++======================================================================*/ -session_t Scope_Get_SessionId( PSCOPE_LIST Scope ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - session_t sessionId=0; - - DbgPrint("Scope_Get_SessionId: 0x%p\n", Scope); - if ( !Scope ) - { - Scope = Scope_Find_Scope( TRUE ); - } - - if ( Scope && Scope_Validate_Scope( Scope )) - { - sessionId = Scope->SessionId; - } - DbgPrint("Scope_Get_SessionId: return 0x%llx\n", sessionId); - return( sessionId ); -} - -/*++======================================================================*/ -PSCOPE_LIST Scope_Get_ScopefromName( struct qstr *Name ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - PSCOPE_LIST scope, rscope=NULL; - struct list_head *sl; - - DbgPrint("Scope_Get_ScopefromName: %.*s\n", Name->len, Name->name); - - down( &Scope_Lock ); - - sl = Scope_List.next; - while (sl != &Scope_List) - { - scope = list_entry(sl, SCOPE_LIST, ScopeList); - - if ( (Name->len == scope->ScopeUserNameLength) && - (0 == strncmp(scope->ScopeUserName, Name->name, Name->len)) ) - { - rscope = scope; - break; - } - - sl = sl->next; - } - - up( &Scope_Lock ); - - return( rscope ); -} - -/*++======================================================================*/ -int Scope_Set_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - PSCOPE_LIST scope; - int retVal=0; - - scope = Scope_Find_Scope( TRUE ); - - if ( scope ) - { - if (TotalSize) scope->ScopeUSize = *TotalSize; - if (Free) scope->ScopeUFree = *Free; - if (TotalEnties) scope->ScopeUTEnties = *TotalEnties; - if (FreeEnties) scope->ScopeUAEnties = *FreeEnties; - } - - - return( retVal ); -} - -/*++======================================================================*/ -int Scope_Get_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - PSCOPE_LIST scope; - int retVal=0; - - uint64_t td, fd, te, fe; - - scope = Scope_Find_Scope( TRUE ); - - td = fd = te = fe = 0; - if ( scope ) - { - - retVal = Daemon_Get_UserSpace(scope->SessionId, &td, &fd, &te, &fe); - - scope->ScopeUSize = td; - scope->ScopeUFree = fd; - scope->ScopeUTEnties = te; - scope->ScopeUAEnties = fe; - } - - if (TotalSize) *TotalSize = td; - if (Free) *Free = fd; - if (TotalEnties) *TotalEnties = te; - if (FreeEnties) *FreeEnties = fe; - - return( retVal ); -} - -/*++======================================================================*/ -PSCOPE_LIST Scope_Get_ScopefromPath( struct dentry *Dentry ) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - PSCOPE_LIST scope=NULL; - char *buf, *path, *cp; - struct qstr name; - - buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); - if (buf) - { - path = Scope_dget_path( Dentry, buf, PATH_LENGTH_BUFFER, 0 ); - if (path) - { - DbgPrint("Scope_Get_ScopefromPath: %s\n", path ); - - if (*path == '/') path++; - - cp = path; - if ( *cp ) - { - while ( *cp && (*cp != '/') ) cp++; - - *cp = '\0'; - name.hash = 0; - name.len = (int)(cp-path); - name.name = path; - scope = Scope_Get_ScopefromName( &name ); - } - } - Novfs_Free(buf); - } - - return( scope ); -} - -/*++======================================================================*/ -char *add_to_list(char *Name, char *List, char *EndOfList) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - while (*Name && (List < EndOfList) ) - { - *List++ = *Name++; - } - - if (List < EndOfList) - { - *List++ = '\0'; - } - return(List); -} - -/*++======================================================================*/ -char *Scope_Get_ScopeUsers() -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - PSCOPE_LIST scope; - struct list_head *sl; - int asize=8*MAX_USERNAME_LENGTH; - char *list, *cp, *ep; - - DbgPrint("Scope_Get_ScopeUsers\n"); - - do /* Copy list until done or out of memory */ - { - list = Novfs_Malloc(asize, GFP_KERNEL); - - DbgPrint("Scope_Get_ScopeUsers list=0x%p\n", list); - if (list) - { - cp = list; - ep = cp+asize; - - /* - * Add the tree and server entries - */ - cp = add_to_list(TREE_DIRECTORY_NAME, cp, ep); - cp = add_to_list(SERVER_DIRECTORY_NAME, cp, ep); - - down( &Scope_Lock ); - - sl = Scope_List.next; - while ( (sl != &Scope_List) && (cp < ep) ) - { - scope = list_entry(sl, SCOPE_LIST, ScopeList); - - DbgPrint("Scope_Get_ScopeUsers found 0x%p %s\n", scope, scope->ScopeUserName); - - cp = add_to_list(scope->ScopeUserName, cp, ep); - - sl = sl->next; - } - - up( &Scope_Lock ); - - if (cp < ep) - { - *cp++ = '\0'; - asize = 0; - } - else /* Allocation was to small, up size */ - { - asize *= 4; - Novfs_Free(list); - list=NULL; - } - } - else /* if allocation fails return an empty list */ - { - break; - } - } while ( !list ); /* List was to small try again */ - - return( list ); -} - -/*++======================================================================*/ -void *Scope_Lookup() -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - PSCOPE_LIST scope; - - scope = Scope_Find_Scope( TRUE ); - return( scope ); -} - -/*++======================================================================*/ -void -NO_TRACE -Scope_Timer_Function(unsigned long Context) -/* - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - up(&Scope_Thread_Delay); -} - -/*++======================================================================*/ -int Scope_Cleanup_Thread(void *Args) -/* - * - * Arguments: - * - * Returns: - * - * Abstract: - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - PSCOPE_LIST scope, rscope; - struct list_head *sl, cleanup; - task_t *task; - - DbgPrint( "Scope_Cleanup_Thread: %d\n", current->pid); - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) - lock_kernel(); - snprintf(current->comm, 16, "novfs_ST"); - unlock_kernel(); - sys_close(0); - sys_close(1); - sys_close(2); -#endif - - /* - * Setup and start que timer - */ - init_timer( &Scope_Timer ); - - for ( ;; ) - { - DbgPrint( "Scope_Cleanup_Thread: looping\n"); - if ( Scope_Thread_Terminate ) - { - break; - } - - /* - * Check scope list for any terminated processes - */ - down( &Scope_Lock ); - - sl = Scope_List.next; - INIT_LIST_HEAD( &cleanup ); - - while (sl != &Scope_List) - { - scope = list_entry(sl, SCOPE_LIST, ScopeList); - sl = sl->next; - - rscope = NULL; - read_lock(&tasklist_lock); - for_each_process(task) - { - if ( (task->uid == scope->ScopeUid) || (task->euid == scope->ScopeUid) ) - { - rscope = scope; - break; - } - } - read_unlock(&tasklist_lock); - if ( !rscope ) - { - list_move( &scope->ScopeList, &cleanup ); - DbgPrint("Scope_Cleanup_Thread: Scope=0x%x\n", rscope); - } - } - - up(&Scope_Lock); - - sl = cleanup.next; - while ( sl != &cleanup ) - { - scope = list_entry(sl, SCOPE_LIST, ScopeList); - sl = sl->next; - - DbgPrint("Scope_Cleanup_Thread: Removing 0x%x\n" \ - " ScopeId: 0x%llx\n" \ - " SessionId: 0x%llx\n" \ - " ScopePid: %d\n" \ - " ScopeTask: 0x%x\n" \ - " ScopeHash: %d\n" \ - " ScopeUid: %d\n" \ - " ScopeUserName: %s\n", - scope, - scope->ScopeId, - scope->SessionId, - scope->ScopePid, - scope->ScopeTask, - scope->ScopeHash, - scope->ScopeUid, - scope->ScopeUserName); - if ( !Scope_Search4Scope(scope->SessionId, TRUE, FALSE) ) - { - Novfs_Remove_from_Root( scope->ScopeUserName ); - Daemon_DestroySessionId( scope->SessionId ); - } - Novfs_Free( scope ); - } - - Scope_Timer.expires = jiffies + HZ*CLEANUP_INTERVAL; - Scope_Timer.data = (unsigned long)0; - Scope_Timer.function = Scope_Timer_Function; - add_timer(&Scope_Timer); - DbgPrint( "Scope_Cleanup_Thread: sleeping\n"); - - if (down_interruptible( &Scope_Thread_Delay )) - { - break; - } - del_timer(&Scope_Timer); - } - Scope_Thread_Terminate = 0; - - printk( KERN_INFO "Scope_Cleanup_Thread: Exit\n"); - DbgPrint( "Scope_Cleanup_Thread: Exit\n"); - return(0); -} - -/*++======================================================================*/ -void Scope_Cleanup( void ) -/* - * - * Arguments: None - * - * Returns: Nothing - * - * Abstract: Removes all knows scopes. - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - PSCOPE_LIST scope; - struct list_head *sl; - - DbgPrint( "Scope_Cleanup:\n"); - - /* - * Check scope list for any terminated processes - */ - down( &Scope_Lock ); - - sl = Scope_List.next; - - while (sl != &Scope_List) - { - scope = list_entry( sl, SCOPE_LIST, ScopeList ); - sl = sl->next; - - list_del( &scope->ScopeList ); - - DbgPrint("Scope_Cleanup: Removing 0x%x\n" \ - " ScopeId: 0x%llx\n" \ - " SessionId: 0x%llx\n" \ - " ScopePid: %d\n" \ - " ScopeTask: 0x%x\n" \ - " ScopeHash: %d\n" \ - " ScopeUid: %d\n" \ - " ScopeUserName: %s\n", - scope, - scope->ScopeId, - scope->SessionId, - scope->ScopePid, - scope->ScopeTask, - scope->ScopeHash, - scope->ScopeUid, - scope->ScopeUserName); - if ( !Scope_Search4Scope( scope->SessionId, TRUE, TRUE ) ) - { - Novfs_Remove_from_Root( scope->ScopeUserName ); - Daemon_DestroySessionId( scope->SessionId ); - } - Novfs_Free( scope ); - } - - up(&Scope_Lock); - -} - -/*++======================================================================*/ -char * -NO_TRACE -Scope_dget_path( struct dentry *Dentry, char *Buf, unsigned int Buflen, int Flags) -/* - * Arguments: struct dentry *Dentry - starting entry - * char *Buf - pointer to memory buffer - * unsigned int Buflen - size of memory buffer - * - * Returns: pointer to path. - * - * Abstract: Walks the dentry chain building a path. - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - char *retval=&Buf[Buflen]; - struct dentry *p=Dentry; - int len; - - *(--retval) = '\0'; - Buflen--; - -/* - if (!IS_ROOT(p)) - { - while (Buflen && !IS_ROOT(p)) - { - if (Buflen > p->d_name.len) - { - retval -= p->d_name.len; - Buflen -= p->d_name.len; - memcpy(retval, p->d_name.name, p->d_name.len); - *(--retval) = '/'; - Buflen--; - p = p->d_parent; - } - else - { - retval = NULL; - break; - } - } - } - if (Flags) - { - len = strlen(p->d_sb->s_type->name); - if (Buflen-len > 0) - { - retval -= len; - Buflen -= len; - memcpy(retval, p->d_sb->s_type->name, len); - *(--retval) = '/'; - Buflen--; - } - } - else - { - *(--retval) = '/'; - Buflen--; - } -*/ - do - { - if (Buflen > p->d_name.len) - { - retval -= p->d_name.len; - Buflen -= p->d_name.len; - memcpy(retval, p->d_name.name, p->d_name.len); - *(--retval) = '/'; - Buflen--; - p = p->d_parent; - } - else - { - retval = NULL; - break; - } - } while (!IS_ROOT(p)); - - if (IS_ROOT(Dentry)) - { - retval++; - } - - if (Flags) - { - len = strlen(p->d_sb->s_type->name); - if (Buflen-len > 0) - { - retval -= len; - Buflen -= len; - memcpy(retval, p->d_sb->s_type->name, len); - *(--retval) = '/'; - Buflen--; - } - } - - return(retval); -} - -void Scope_Dump_Tasklist( void ) -{ -#ifdef OLD_DEBUG_KERNEL - task_t *task; - struct files_struct *fs; - int i, open_files=0; - static char buf[1024]; - char *path; - - - for_each_process(task) - { - kdb_printf("Task List:\n" \ - " Task: 0x%p\n" \ - " pid: %d\n" \ - " tgid: %d\n" \ - " uid: %d %d %d %d\n" \ - " gid: %d\n" \ - " parent: 0x%p\n" \ - " comm: %s\n" \ - " user: 0x%p\n" \ - " real_parent: 0x%p\n" \ - " parent_exec_id: 0x%x\n" \ - " self_exec_id: 0x%x\n" \ - " did_exec: 0x%x\n" \ - " signal: 0x%p\n" \ - " thread_info: 0x%p\n" \ - " security: 0x%p\n", - task, - task->pid, - task->tgid, - task->uid,task->euid,task->suid,task->fsuid, - task->gid, - task->parent, - task->comm, - task->user, - task->real_parent, - task->parent_exec_id, - task->self_exec_id, - task->did_exec, - task->signal, - task->thread_info, - task->security); - - fs = task->files; - kdb_printf(" File List: 0x%p\n", fs); - if (fs) - { - open_files = fs->max_fds; - kdb_printf(" Max fds: %d\n", open_files); - for (i = 0; ifd[i]; - if (f && (f->f_dentry)) - { - path = Scope_dget_path(f->f_dentry, buf, sizeof(buf), 1); - if ( !path ) - { - path = buf; - memcpy(path, f->f_dentry->d_name.name, f->f_dentry->d_name.len); - path[f->f_dentry->d_name.len] = '\0'; - } - kdb_printf(" file(%d): 0x%p\n" \ - " f_dentry: 0x%p\n" \ - " d_name: %s\n" \ - " d_count: %d\n" \ - " d_inode: 0x%p\n", - i, f, f->f_dentry, path, - atomic_read(&f->f_dentry->d_count), - f->f_dentry->d_inode); - } - } - } - } -#endif -} - -void Scope_Dump_Scopetable( void ) -{ -#ifdef CONFIG_KDB - PSCOPE_LIST scope; - struct list_head *sl; - - sl = Scope_List.next; - while (sl != &Scope_List) - { - scope = list_entry(sl, SCOPE_LIST, ScopeList); - sl = sl->next; - kdb_printf("Scope List:\n" \ - " Scope: 0x%p\n" \ - " ScopeId: 0x%llx\n" \ - " SessionId: 0x%llx\n" \ - " ScopePid: %u\n" \ - " ScopeTask: 0x%p\n" \ - " ScopeHash: 0x%lx\n" \ - " ScopeUid: %ld\n" \ - " ScopeUserName: %s\n", - scope, - scope->ScopeId, - scope->SessionId, - scope->ScopePid, - scope->ScopeTask, - scope->ScopeHash, - (long)scope->ScopeUid, - scope->ScopeUserName); - - } - -#endif -} diff -uNr src.old/novfs/vfs.h src/novfs/vfs.h --- src.old/novfs/vfs.h 2006-07-11 21:24:18.000000000 +0200 +++ src/novfs/vfs.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,276 +0,0 @@ -/*++======================================================================== - * Program Name: Novell NCP Redirector for Linux - * File Name: vfs.h - * Version: v1.00 - * Author: James Turner - * - * Abstract: Include module for novfs. - * Notes: - * Revision History: - * - * - * Copyright (C) 2005 Novell, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - *======================================================================--*/ -#ifndef __STDC_VERSION__ -#define __STDC_VERSION__ 0L -#endif - -/*===[ Include files specific to Linux ]==================================*/ -#ifdef CONFIG_KDB -#include -#include - -#endif /* CONFIG_KDB */ - -#include -#include - -/*===[ Include files specific to this module ]============================*/ - -/*===[ External data ]====================================================*/ -extern int Novfs_Version_Major; -extern int Novfs_Version_Minor; -extern int Novfs_Version_Sub; -extern int Novfs_Version_Release; - -/*===[ External prototypes ]==============================================*/ -extern void *Novfs_Malloc( size_t, int ); -extern void Novfs_Free( const void * ); - - -/*===[ Manifest constants ]===============================================*/ -#define NOVFS_MAGIC 0x4e574653 -#define MODULE_NAME "novfs" - -#define UNUSED_VARIABLE(a) (a) = (a) - -#define TREE_DIRECTORY_NAME ".Trees" -#define SERVER_DIRECTORY_NAME ".Servers" - -#define PATH_LENGTH_BUFFER PATH_MAX -#define NW_MAX_PATH_LENGTH 255 - -#define IOC_LOGIN 0x4a540000 -#define IOC_LOGOUT 0x4a540001 -#define IOC_XPLAT 0x4a540002 -#define IOC_SESSION 0x4a540003 -#define IOC_DEBUGPRINT 0x4a540004 - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) -#define D_CHILD d_u.d_child -#else -#define D_CHILD d_child -#endif - -/* - * NetWare file attributes - */ - -#define NW_ATTRIBUTE_NORMAL 0x00 -#define NW_ATTRIBUTE_READ_ONLY 0x01 -#define NW_ATTRIBUTE_HIDDEN 0x02 -#define NW_ATTRIBUTE_SYSTEM 0x04 -#define NW_ATTRIBUTE_EXECUTE_ONLY 0x08 -#define NW_ATTRIBUTE_DIRECTORY 0x10 -#define NW_ATTRIBUTE_ARCHIVE 0x20 -#define NW_ATTRIBUTE_EXECUTE 0x40 -#define NW_ATTRIBUTE_SHAREABLE 0x80 - -/* - * Define READ/WRITE flag for DATA_LIST - */ -#define DLREAD 0 -#define DLWRITE 1 - -/* - * Define list type - */ -#define USER_LIST 1 -#define SERVER_LIST 2 -#define VOLUME_LIST 3 - -/* - * Define flags used in for inodes - */ -#define USER_INODE 1 -#define UPDATE_INODE 2 - -/* - * Define flags for directory cache flags - */ -#define ENTRY_VALID 0x00000001 - -#ifdef INTENT_MAGIC -#define NDOPENFLAGS intent.it_flags -#else -#define NDOPENFLAGS intent.open.flags -#endif - -/* - * daemon_command_t flags values - */ -#define INTERRUPTIBLE 1 - -#define NO_TRACE __attribute__((__no_instrument_function__)) - -#ifndef NOVFS_VFS_MAJOR -#define NOVFS_VFS_MAJOR 0 -#endif - -#ifndef NOVFS_VFS_MINOR -#define NOVFS_VFS_MINOR 0 -#endif - -#ifndef NOVFS_VFS_SUB -#define NOVFS_VFS_SUB 0 -#endif - -#ifndef NOVFS_VFS_RELEASE -#define NOVFS_VFS_RELEASE 0 -#endif - -#define VALUE_TO_STR( value ) #value -#define DEFINE_TO_STR(value) VALUE_TO_STR(value) - - -#define NOVFS_VERSION_STRING \ - DEFINE_TO_STR(NOVFS_VFS_MAJOR)"." \ - DEFINE_TO_STR(NOVFS_VFS_MINOR)"." \ - DEFINE_TO_STR(NOVFS_VFS_SUB)"-" \ - DEFINE_TO_STR(NOVFS_VFS_RELEASE) - -/*===[ Type definitions ]=================================================*/ -typedef struct _ENTRY_INFO -{ - int type; - umode_t mode; - uid_t uid; - gid_t gid; - loff_t size; - struct timespec atime; - struct timespec mtime; - struct timespec ctime; - int namelength; - unsigned char name[1]; -} ENTRY_INFO, *PENTRY_INFO; - -typedef struct _STRING_ -{ - int Length; - unsigned char *Data; -} STRING, *PSTRING; - -typedef struct _LOGIN_ -{ - STRING Server; - STRING UserName; - STRING Password; -} LOGIN, *PLOGIN; - -typedef struct _LOGOUT_ -{ - STRING Server; -} LOGOUT, *PLOGOUT; - -typedef uint64_t scope_t; -typedef uint64_t session_t; - -typedef struct _DIR_CACHE_ -{ - struct list_head list; - int flags; - u64 jiffies; - ino_t ino; - loff_t size; - umode_t mode; - struct timespec atime; - struct timespec mtime; - struct timespec ctime; - unsigned long hash; - int nameLen; - char name[1]; -} DIR_CACHE, *PDIR_CACHE; - -typedef struct _INODE_DATA_ -{ - void *Scope; - unsigned long Flags; - struct list_head IList; - struct inode *Inode; - struct list_head DirCache; - struct semaphore DirCacheLock; - char Name[1]; /* Needs to be last entry */ -} INODE_DATA, *PINODE_DATA; - -typedef struct _DATA_LIST_ -{ - void *page; - void *offset; - int len; - int rwflag; -} DATA_LIST, *PDATA_LIST; - -typedef struct _XPLAT_ -{ - int xfunction; - unsigned long reqLen; - void *reqData; - unsigned long repLen; - void *repData; - -} XPLAT, *PXPLAT; - - -/*===[ Function prototypes ]==============================================*/ - -extern int DbgPrint( char *Fmt, ... ); -extern char *ctime_r(time_t *clock, char *buf); - - -/*++======================================================================*/ -static inline unsigned long InterlockedIncrement( unsigned long *p ) -/* - * - * Arguments: unsigned long *p - pointer to value. - * - * Returns: unsigned long - value prior to increment. - * - * Abstract: The value of *p is incremented and the value of *p before - * it was incremented is returned. This is an atomic operation. - * - * Notes: - * - * Environment: - * - *========================================================================*/ -{ - unsigned long x = 1; - - mb(); - -#if defined(__i386) || defined(__i386__) - __asm__ __volatile__( - " lock xadd %0,(%2)" - : "+r"(x), "=m"(p) - : "r"(p), "m"(p) - : "memory"); - -#else - x = *p++; -#endif - return( x ); -} diff -uNr src.old/src/Makefile src/src/Makefile --- src.old/src/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ src/src/Makefile 2006-10-16 15:08:22.000000000 +0200 @@ -0,0 +1,58 @@ +##*++====================================================================== +## Program Name: Novell NCP Redirector for Linux +## File Name: Makefile +## Version: v1.01 +## Author: James Turner +## +## Abstract: This is used to generate the novfs module +## Notes: +## Revision History: +## 6/10/2005 - Added lines for SuSE +## +## Copyright (C) 2005 Novell, Inc. +## +## This program is free software; you can redistribute it and/or +## modify it under the terms of the GNU General Public License +## as published by the Free Software Foundation; either version 2 +## of the License, or (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +##=====================================================================--*/ + +# +# Makefile for the Novell NetWare Client for Linux filesystem. +# +NOVFS_VFS_MAJOR = 2 +NOVFS_VFS_MINOR = 0 +NOVFS_VFS_SUB = 0 +NOVFS_VFS_RELEASE = 0 + +# Remove # from the following line for debug version +EXTRA_CFLAGS += -finstrument-functions +EXTRA_CFLAGS += -g +EXTRA_CFLAGS += -I. +EXTRA_CFLAGS += -I$(obj)/../include +EXTRA_CFLAGS += -I$(obj)/../../include +EXTRA_CFLAGS += -DNOVFS_VFS_MAJOR=$(NOVFS_VFS_MAJOR) +EXTRA_CFLAGS += -DNOVFS_VFS_MINOR=$(NOVFS_VFS_MINOR) +EXTRA_CFLAGS += -DNOVFS_VFS_SUB=$(NOVFS_VFS_SUB) +EXTRA_CFLAGS += -DNOVFS_VFS_PATCH=$(NOVFS_VFS_PATCH) +EXTRA_CFLAGS += -DNOVFS_VFS_RELEASE=$(NOVFS_VFS_RELEASE) + + +obj-m := novfs.o + +novfs-y := inode.o proc.o profile.o daemon.o file.o scope.o nwcapi.o + +all: + make -C /usr/src/linux SUBDIRS=`pwd` modules + +clean: + make -C /usr/src/linux SUBDIRS=`pwd` modules clean diff -uNr src.old/src/blank.c src/src/blank.c --- src.old/src/blank.c 1970-01-01 01:00:00.000000000 +0100 +++ src/src/blank.c 2006-10-16 15:08:22.000000000 +0200 @@ -0,0 +1,61 @@ +/*++======================================================================== + * Program Name: Novell NCP Redirector for Linux + * File Name: .c + * Version: v1.00 + * Author: James Turner + * + * Abstract: This module + * + * Notes: + * Revision History: + * + * + * Copyright (C) 2005 Novell, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *======================================================================--*/ + +/*===[ Include files specific to Linux ]==================================*/ + +/*===[ Include files specific to this module ]============================*/ + +/*===[ External data ]====================================================*/ + +/*===[ External prototypes ]==============================================*/ + +/*===[ Manifest constants ]===============================================*/ + +/*===[ Type definitions ]=================================================*/ + +/*===[ Function prototypes ]==============================================*/ + +/*===[ Global variables ]=================================================*/ + +/*===[ Code ]=============================================================*/ + +/*++======================================================================*/ +Function +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ diff -uNr src.old/src/daemon.c src/src/daemon.c --- src.old/src/daemon.c 1970-01-01 01:00:00.000000000 +0100 +++ src/src/daemon.c 2006-10-16 15:08:23.000000000 +0200 @@ -0,0 +1,2863 @@ +/*++======================================================================== + * Program Name: Novell NCP Redirector for Linux + * File Name: daemon.c + * Version: v1.00 + * Author: James Turner + * + * Abstract: This module contains all the functions necessary + * for sending commands to our daemon module. + * Notes: + * Revision History: + * + * + * Copyright (C) 2005 Novell, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *======================================================================--*/ + +/*===[ Include files specific to Linux ]==================================*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/*===[ Include files specific to this module ]============================*/ +#include "vfs.h" +#include "nwcapi.h" +#include "commands.h" +#include "nwerror.h" + +/*===[ External data ]====================================================*/ +extern char *Novfs_CurrentMount; + +/*===[ External prototypes ]==============================================*/ +extern int DbgPrint( char *Fmt, ... ); +extern void mydump(int size, void *dumpptr); + +extern char *Scope_Get_UserName( void *Scope ); +extern void *Scope_Lookup( void ); +extern session_t Scope_Get_SessionId( void *Scope ); +extern void Scope_Cleanup( void ); + +extern int Novfs_Read_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, int User, session_t SessionId); +extern int Novfs_Write_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId); +extern int Novfs_Close_Stream( u_long ConnHandle, u_char *Handle, session_t SessionId ); + +extern int Novfs_Add_to_Root(char *); + +/* + * profile.c functions + */ +extern uint64_t get_nanosecond_time( void ); + +/* + * nwcapi.c functions + */ +extern int NwAuthConnWithId(PXPLAT pdata, session_t Session); +extern int NwConnClose(PXPLAT pdata, u_long *Handle, session_t Session); +extern int NwGetConnInfo(PXPLAT pdata, session_t Session); +extern int NwSetConnInfo(PXPLAT pdata, session_t Session); +extern int NwGetDaemonVersion(PXPLAT pdata, session_t Session); +extern int NwGetIdentityInfo(PXPLAT pdata, session_t Session); +extern int NwLicenseConn(PXPLAT pdata, session_t Session); +extern int NwLoginIdentity(PXPLAT pdata, session_t Session); +extern int NwLogoutIdentity(PXPLAT pdata, session_t Session); +extern int NwOpenConnByAddr(PXPLAT pdata, u_long *Handle, session_t Session); +extern int NwOpenConnByName(PXPLAT pdata, u_long *Handle, session_t Session); +extern int NwOpenConnByRef(PXPLAT pdata, u_long *Handle, session_t Session); +extern int NwQueryFeature(PXPLAT pdata, session_t Session); +extern int NwRawSend(PXPLAT pdata, session_t Session); +extern int NwScanConnInfo(PXPLAT pdata, session_t Session); +extern int NwSysConnClose(PXPLAT pdata, u_long *Handle, session_t Session); +extern int NwUnAuthenticate(PXPLAT pdata, session_t Session); +extern int NwUnlicenseConn(PXPLAT pdata, session_t Session); +extern int NwcChangeAuthKey(PXPLAT pdata, session_t Session); +extern int NwcEnumIdentities(PXPLAT pdata, session_t Session); +extern int NwcGetDefaultNameCtx(PXPLAT pdata, session_t Session); +extern int NwcGetPreferredDSTree(PXPLAT pdata, session_t Session); +extern int NwcGetTreeMonitoredConn(PXPLAT pdata, session_t Session); +extern int NwcSetDefaultNameCtx(PXPLAT pdata, session_t Session); +extern int NwcSetPreferredDSTree(PXPLAT pdata, session_t Session); +extern int NwcSetPrimaryConn(PXPLAT pdata, session_t Session); +extern int NwcGetPrimaryConn(PXPLAT pdata, session_t Session); +extern int NwcSetMapDrive(PXPLAT pdata, session_t Session); +extern int NwcUnMapDrive(PXPLAT pdata, session_t Session); +extern int NwcEnumerateDrives(PXPLAT pdata, session_t Session); +extern int NwcGetBroadcastMessage(PXPLAT pdata, session_t Session); +extern int NwdSetKeyValue(PXPLAT pdata, session_t Session); +extern int NwdVerifyKeyValue(PXPLAT pdata, session_t Session); + +/*===[ Manifest constants ]===============================================*/ +#define QUEUE_SENDING 0 +#define QUEUE_WAITING 1 +#define QUEUE_TIMEOUT 2 +#define QUEUE_ACKED 3 +#define QUEUE_DONE 4 + +#define TIMEOUT_VALUE 10 + +#define DH_TYPE_UNDEFINED 0 +#define DH_TYPE_STREAM 1 +#define DH_TYPE_CONNECTION 2 + +/*===[ Type definitions ]=================================================*/ +typedef struct _DAEMON_QUEUE +{ + struct list_head list; /* Must be first entry */ + spinlock_t lock; /* Used to control access to list */ + struct semaphore semaphore; /* Used to signal when data is available */ +} daemon_queue_t; + +typedef struct _DAEMON_COMMAND +{ + struct list_head list; /* Must be first entry */ + atomic_t reference; + u_long status; + u_long flags; + struct semaphore semaphore; + u_long sequence; + struct timer_list timer; + void *request; + u_long reqlen; + void *data; + int datalen; + void *reply; + u_long replen; +} daemon_command_t; + + +typedef struct _DAEMON_HANDLE_ +{ + struct list_head list; + rwlock_t lock; + session_t session; +} daemon_handle_t; + +typedef struct _DAEMON_RESOURCE_ +{ + struct list_head list; + int type; + u_long connection; + u_char handle[6]; + mode_t mode; + loff_t size; +} daemon_resource_t; + +typedef struct _DRIVE_MAP_ +{ + struct list_head list; /* Must be first item */ + session_t session; + u_long hash; + int namelen; + char name[1]; +} drive_map_t; + +/*===[ Function prototypes ]==============================================*/ +int Daemon_Added_Resource(daemon_handle_t *DHandle, int Type, u_long CHandle, u_char *FHandle, u_long Mode, u_long Size); +int Daemon_Close_Control(struct inode *Inode, struct file *File); +int Daemon_CreateSessionId( uint64_t *SessionId ); +int Daemon_DestroySessionId( uint64_t SessionId ); +void Daemon_Dumpque( void ); +int Daemon_Get_UserSpace( uint64_t SessionId, uint64_t *TotalSize, uint64_t *TotalFree, uint64_t *TotalDirectoryEnties, uint64_t *FreeDirectoryEnties); +int Daemon_Library_close(struct inode *inode, struct file *file); +int Daemon_Library_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u_long arg); +int Daemon_Library_open(struct inode *inode, struct file *file); +ssize_t Daemon_Library_read(struct file *file, char *buf, size_t len, loff_t *off); +ssize_t Daemon_Library_write(struct file *file, const char *buf, size_t len, loff_t *off); +loff_t Daemon_Library_llseek(struct file *file, loff_t offset, int origin); +int Daemon_Login(PLOGIN Login, session_t Session); +int Daemon_Logout(PLOGOUT Logout, session_t Session); +int Daemon_Open_Control(struct inode *Inode, struct file *File); +uint Daemon_Poll(struct file *file, struct poll_table_struct *poll_table); +ssize_t Daemon_Receive_Reply(struct file * file, char * buf, size_t nbytes, loff_t *ppos); +int Daemon_Remove_Resource(daemon_handle_t *DHandle, int Type, u_long CHandle, u_long FHandle); + +ssize_t Daemon_Send_Command(struct file *file, char *buf, size_t len, loff_t *off); +int Daemon_SetMountPoint( char *Path ); +void Daemon_Timer(u_long data); +int Daemon_getpwuid( uid_t uid, int unamelen, char *uname ); +int Daemon_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u_long arg); +void Init_Daemon_Queue( void ); +int Queue_Daemon_Command(void *request, u_long reqlen, void *data, int dlen, void **reply, u_long *replen, int interruptible); +void Queue_get(daemon_command_t *que); +void Queue_put(daemon_command_t *que); +void Uninit_Daemon_Queue( void ); +int do_login(NclString *Server, NclString *Username, NclString *Password, u_long *lgnId, session_t Session); +int do_logout( struct qstr *Server, session_t Session ); +daemon_command_t *find_queue(u_long sequence); +daemon_command_t *get_next_queue(int Set_Queue_Waiting); +int NwdConvertNetwareHandle(PXPLAT pdata, daemon_handle_t *DHandle); +int NwdConvertLocalHandle(PXPLAT pdata, daemon_handle_t *DHandle); +int NwdGetMountPath(PXPLAT pdata); +int NwdSetMapDrive(PXPLAT pdata, session_t Session); +int NwdUnMapDrive(PXPLAT pdata, session_t Session); +void RemoveDriveMaps( void ); +int local_unlink(const char *pathname); + +/*===[ Global variables ]=================================================*/ +daemon_queue_t Daemon_Queue; + +static DECLARE_WAIT_QUEUE_HEAD(Read_waitqueue); + +u_long Sequence = 0; +atomic_t Daemon_Open_Count=ATOMIC_INIT(0); + +u_long Daemon_Command_Timeout = TIMEOUT_VALUE; + +DECLARE_MUTEX ( DriveMapLock ); +LIST_HEAD( DriveMapList ); + +int MaxIoSize=PAGE_SIZE; + +/*===[ Code ]=============================================================*/ + +/*++======================================================================*/ +void Init_Daemon_Queue() +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + INIT_LIST_HEAD(&Daemon_Queue.list); + spin_lock_init(&Daemon_Queue.lock); + init_MUTEX_LOCKED(&Daemon_Queue.semaphore); +} + +/*++======================================================================*/ +void Uninit_Daemon_Queue( void ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + /* Does nothing for now but we maybe should clear the queue. */ +} + +/*++======================================================================*/ +void +NO_TRACE +Daemon_Timer(u_long data) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + daemon_command_t *que = (daemon_command_t *)data; + + if ( QUEUE_ACKED != que->status ) + { + que->status = QUEUE_TIMEOUT; + } + up(&que->semaphore); +} + +/*++======================================================================*/ +int Queue_Daemon_Command( + void *request, + u_long reqlen, + void *data, + int dlen, + void **reply, + u_long *replen, + int interruptible) +/* + * + * Arguments: void *request - pointer to the request that is to be sent. Needs to be kernel memory. + * int reqlen - length of the request. + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + daemon_command_t *que; + int retCode = 0; + uint64_t ts1, ts2; + + ts1 = get_nanosecond_time(); + + DbgPrint( "Queue_Daemon_Command: 0x%x %d\n", request, reqlen); + + if (atomic_read(&Daemon_Open_Count)) + { + + que = (daemon_command_t *)Novfs_Malloc(sizeof(*que), GFP_KERNEL); + + DbgPrint( "Queue_Daemon_Command: que=0x%x\n", que); + if (que) + { + atomic_set( &que->reference, 0 ); + que->status = QUEUE_SENDING; + que->flags = 0; + + init_MUTEX_LOCKED(&que->semaphore); + + DbgPrint( "Queue_Daemon_Command: semaphore inited que=0x%x\n", que); + + que->sequence = InterlockedIncrement(&Sequence); + + DbgPrint( "Queue_Daemon_Command: sequence=0x%x\n", que->sequence); + + ((PCOMMAND_REQUEST_HEADER)request)->SequenceNumber = que->sequence; + + /* + * Setup and start que timer + */ + init_timer(&que->timer); + que->timer.expires = jiffies + (HZ * Daemon_Command_Timeout); + que->timer.data = (u_long)que; + que->timer.function = Daemon_Timer; + add_timer(&que->timer); + + DbgPrint( "Queue_Daemon_Command: timer started que=0x%x\n", que); + + /* + * Setup request + */ + que->request = request; + que->reqlen = reqlen; + que->data = data; + que->datalen = dlen; + que->reply = NULL; + que->replen = 0; + + DbgPrint( "Queue_Daemon_Command: setting up que=0x%x\n", que); + + /* + * Added entry to queue. + */ + DbgPrint( "Queue_Daemon_Command: Daemon_Queue locked\n"); + + /* + * Check to see if interruptible and set flags. + */ + if (interruptible) + { + que->flags |= INTERRUPTIBLE; + } + + Queue_get( que ); + + spin_lock(&Daemon_Queue.lock); + list_add_tail(&que->list, &Daemon_Queue.list); + spin_unlock(&Daemon_Queue.lock); + + DbgPrint( "Queue_Daemon_Command: 0x%x added to Daemon_Queue\n", que); + /* + * Signal that there is data to be read + */ + up(&Daemon_Queue.semaphore); + + /* + * Give a change to the other processes. + */ + yield(); + + DbgPrint( "Queue_Daemon_Command: calling down 0x%x\n", CURRENT_TIME); + + /* + * Block waiting for reply or timeout + */ + down(&que->semaphore); + + DbgPrint( "Queue_Daemon_Command: after down 0x%x\n", CURRENT_TIME); + + if ( QUEUE_ACKED == que->status ) + { + que->status = QUEUE_WAITING; + mod_timer(&que->timer, jiffies + (HZ * 2 * Daemon_Command_Timeout)); + DbgPrint( "Queue_Daemon_Command: mod_timer 0x%x\n", CURRENT_TIME); + if (interruptible) + { + retCode = down_interruptible(&que->semaphore); + } + else + { + down(&que->semaphore); + } + DbgPrint( "Queue_Daemon_Command: after down2 0x%x\n", CURRENT_TIME); + } + + DbgPrint( "Queue_Daemon_Command: after down 0x%d 0x%x\n", retCode, CURRENT_TIME); + /* + * Delete timer + */ + del_timer(&que->timer); + + /* + * Check for timeout + */ + if ((QUEUE_TIMEOUT == que->status) && (NULL == que->reply) ) + { + DbgPrint( "Queue_Daemon_Command: Timeout\n"); + retCode = -ETIME; + } + *reply = que->reply; + *replen = que->replen; + + /* + * Remove item from queue + */ + Queue_put( que ); + + } + else /* Error case with no memory */ + { + retCode = -ENOMEM; + *reply = NULL; + *replen = 0; + } + } + else + { + retCode = -EIO; + *reply = NULL; + *replen = 0; + + } + ts2 = get_nanosecond_time(); + ts2 = ts2-ts1; + + DbgPrint( "Queue_Daemon_Command: %llu retCode=%d \n", ts2, retCode); + return(retCode); +} + +/*++======================================================================*/ +void Queue_get(daemon_command_t *Que) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + DbgPrint("Queue_get: que=0x%p %d\n", Que, atomic_read(&Que->reference)); + atomic_inc( &Que->reference ); +} + +/*++======================================================================*/ +void Queue_put(daemon_command_t *Que) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + + DbgPrint("Queue_put: que=0x%p %d\n", Que, atomic_read(&Que->reference)); + spin_lock(&Daemon_Queue.lock); + + if ( atomic_dec_and_test( &Que->reference )) + { + /* + * Remove item from queue + */ + list_del(&Que->list); + spin_unlock(&Daemon_Queue.lock); + + /* + * Free item memory + */ + Novfs_Free(Que); + } + else + { + spin_unlock(&Daemon_Queue.lock); + } +} + +/*++======================================================================*/ +daemon_command_t *get_next_queue(int Set_Queue_Waiting) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + daemon_command_t *que; + + DbgPrint( "get_next_queue: que=0x%p\n", Daemon_Queue.list.next); + + spin_lock(&Daemon_Queue.lock); + que = (daemon_command_t *)Daemon_Queue.list.next; + + while (que && (que != (daemon_command_t *)&Daemon_Queue.list.next) && ( que->status != QUEUE_SENDING ) ) + { + que = (daemon_command_t *)que->list.next; + } + + if ((NULL == que) || (que == (daemon_command_t *)&Daemon_Queue.list) || (que->status != QUEUE_SENDING)) + { + que = NULL; + } + else if (Set_Queue_Waiting) + { + que->status = QUEUE_WAITING; + } + + if (que) + { + atomic_inc( &que->reference ); + } + + spin_unlock(&Daemon_Queue.lock); + + DbgPrint( "get_next_queue: return=0x%x\n", que); + return(que); +} + +/*++======================================================================*/ +daemon_command_t *find_queue(u_long sequence) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + daemon_command_t *que; + + DbgPrint( "find_queue: 0x%x\n", sequence); + + spin_lock(&Daemon_Queue.lock); + que = (daemon_command_t *)Daemon_Queue.list.next; + + + while (que && (que != (daemon_command_t *)&Daemon_Queue.list.next) && (que->sequence != sequence)) + { + que = (daemon_command_t *)que->list.next; + } + + if ((NULL == que) || (que == (daemon_command_t *)&Daemon_Queue.list.next) || (que->sequence != sequence)) + { + que = NULL; + } + + if (que) + { + atomic_inc( &que->reference ); + } + + spin_unlock(&Daemon_Queue.lock); + + DbgPrint( "find_queue: return 0x%p\n", que); + return(que); +} +/*++======================================================================*/ +int Daemon_Open_Control(struct inode *Inode, struct file *File) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + DbgPrint("Daemon_Open_Control: pid=%d Count=%d\n", current->pid, atomic_read(&Daemon_Open_Count)); + atomic_inc(&Daemon_Open_Count); + + return(0); +} + +/*++======================================================================*/ +int Daemon_Close_Control(struct inode *Inode, struct file *File) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + daemon_command_t *que; + + DbgPrint("Daemon_Close_Control: pid=%d Count=%d\n", current->pid, atomic_read(&Daemon_Open_Count)); + + if (atomic_dec_and_test(&Daemon_Open_Count)) + { + /* + * Signal any pending que itmes. + */ + + spin_lock(&Daemon_Queue.lock); + que = (daemon_command_t *)Daemon_Queue.list.next; + + while (que && (que != (daemon_command_t *)&Daemon_Queue.list.next) && (que->status != QUEUE_DONE)) + { + que->status = QUEUE_TIMEOUT; + up(&que->semaphore); + + que = (daemon_command_t *)que->list.next; + } + spin_unlock(&Daemon_Queue.lock); + + RemoveDriveMaps(); + + Scope_Cleanup(); + } + + return(0); +} + +/*++======================================================================*/ +ssize_t +Daemon_Send_Command(struct file *file, char *buf, size_t len, loff_t *off) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + daemon_command_t *que; + size_t retValue = 0; + int Finished=0; + PDATA_LIST dlist; + int i, dcnt, bcnt, ccnt, error; + char *vadr; + u_long cpylen; + + DbgPrint( "Daemon_Send_Command: %u %lld\n", len, *off); + if (len > MaxIoSize) + { + MaxIoSize = len; + } + + while ( !Finished ) + { + que = get_next_queue(1); + DbgPrint( "Daemon_Send_Command: 0x%x\n", que); + if (que) + { + retValue = que->reqlen; + if (retValue > len) + { + retValue = len; + } + if (retValue > 0x80) + mydump(0x80, que->request); + else + mydump(retValue, que->request); + + cpylen = copy_to_user(buf, que->request, retValue); + if (que->datalen && (retValue < len)) + { + buf += retValue; + dlist = que->data; + dcnt = que->datalen; + for (i=0; irwflag ) + { + bcnt = dlist->len; + DbgPrint("Daemon_Send_Command%d: page=0x%x offset=0x%x len=%d\n", i, dlist->page, dlist->offset, dlist->len); + if ((bcnt + retValue) <= len) + { + void *km_adr=NULL; + + if (dlist->page) + { + km_adr = kmap(dlist->page); + vadr = km_adr; + vadr += (u_int)dlist->offset; + } + else + { + vadr = dlist->offset; + } + + ccnt = copy_to_user(buf, vadr, bcnt); + + if ( km_adr ) + { + kunmap(dlist->page); + } + + DbgPrint("Daemon_Send_Command: Copy %d from 0x%x to 0x%x.\n", bcnt, vadr, buf); + if (bcnt > 0x80) + mydump(0x80, vadr); + else + mydump(bcnt, vadr); + + retValue += bcnt; + buf += bcnt; + } + else + { + break; + } + } + } + } + Queue_put( que ); + break; + } + + if (O_NONBLOCK & file->f_flags) + { + retValue = -EAGAIN; + break; + } + else + { + if ((error = down_interruptible(&Daemon_Queue.semaphore))) + { + DbgPrint( "Daemon_Send_Command: after down_interruptible error...%d\n", error); + retValue = -EINTR; + break; + } + DbgPrint( "Daemon_Send_Command: after down_interruptible\n"); + } + } + + *off = *off; + + DbgPrint( "Daemon_Send_Command: return 0x%x\n", retValue); + + return(retValue); +} + +/*++======================================================================*/ +ssize_t +Daemon_Receive_Reply(struct file * file, char * buf, size_t nbytes, loff_t *ppos) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + daemon_command_t *que; + size_t retValue = 0; + void *reply; + u_long sequence, cpylen; + + PDATA_LIST dlist; + char *vadr; + int i; + + DbgPrint( "Daemon_Receive_Reply: buf=0x%x nbytes=%d ppos=%llx\n", buf, nbytes, *ppos); + + /* + * Get sequence number from reply buffer + */ + + cpylen = copy_from_user(&sequence, buf, sizeof(sequence)); + + /* + * Find item based on sequence number + */ + que = find_queue(sequence); + + DbgPrint( "Daemon_Receive_Reply: 0x%x 0x%x %d\n", sequence, que, nbytes); + if (que) + { + do + { + retValue = nbytes; + /* + * Ack packet from novfsd. Remove timer and + * return + */ + if (nbytes == sizeof(sequence)) + { + que->status = QUEUE_ACKED; + break; + } + + /* + * Set status that packet is done. + */ + que->status = QUEUE_DONE; + + if ( NULL != (dlist = que->data) ) + { + int thiscopy, left=nbytes; + retValue = 0; + + + DbgPrint( "Daemon_Receive_Reply: dlist=0x%x count=%d\n", dlist, que->datalen); + for (i=0; (i < que->datalen) && (retValue < nbytes); i++, dlist++) + { + DbgPrint( "Daemon_Receive_Reply:\n" \ + " dlist[%d].page: 0x%x\n" \ + " dlist[%d].offset: 0x%x\n" \ + " dlist[%d].len: 0x%x\n" \ + " dlist[%d].rwflag: 0x%x\n", + i, dlist->page, + i, dlist->offset, + i, dlist->len, + i, dlist->rwflag); + + if (DLWRITE == dlist->rwflag) + { + void *km_adr=NULL; + + if (dlist->page) + { + km_adr = kmap(dlist->page); + vadr = km_adr; + vadr += (u_int)dlist->offset; + } + else + { + vadr = dlist->offset; + } + + thiscopy = dlist->len; + if (thiscopy > left) + { + thiscopy = left; + dlist->len = left; + } + cpylen = copy_from_user(vadr, buf, thiscopy); + + if ( km_adr ) + { + kunmap(dlist->page); + } + + left -= thiscopy; + retValue += thiscopy; + buf += thiscopy; + } + } + que->replen = retValue; + } + else + { + reply = Novfs_Malloc(nbytes, GFP_KERNEL); + DbgPrint( "Daemon_Receive_Reply: reply=0x%x\n", reply); + if (reply) + { + retValue = nbytes; + que->reply = reply; + que->replen = nbytes; + + retValue -= copy_from_user(reply, buf, retValue); + if (retValue > 0x80) + mydump(0x80, reply); + else + mydump(retValue, reply); + + + } + else + { + retValue = -ENOMEM; + } + } + } while (0); + up(&que->semaphore); + Queue_put( que ); + } + + DbgPrint( "Daemon_Receive_Reply: return 0x%x\n", retValue); + + return(retValue); +} + +/*++======================================================================*/ +int do_login(NclString *Server, NclString *Username, NclString *Password, u_long *lgnId, session_t Session) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + PLOGIN_USER_REQUEST cmd; + PLOGIN_USER_REPLY reply; + u_long replylen=0; + int retCode, cmdlen, datalen; + u_char *data; + + datalen = Server->len+Username->len+Password->len; + cmdlen = sizeof(*cmd) + datalen; + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + if (cmd) + { + data = (u_char *)cmd + sizeof(*cmd); + cmd->Command.CommandType = VFS_COMMAND_LOGIN_USER; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + + cmd->srvNameType = Server->type; + cmd->serverLength = Server->len; + cmd->serverOffset = (u_long)(data-(u_char *)cmd); + memcpy(data, Server->buffer, Server->len); + data += Server->len; + + cmd->usrNameType = Username->type; + cmd->userNameLength = Username->len; + cmd->userNameOffset = (u_long)(data-(u_char *)cmd); + memcpy(data, Username->buffer, Username->len); + data += Username->len; + + cmd->pwdNameType = Password->type; + cmd->passwordLength = Password->len; + cmd->passwordOffset = (u_long)(data-(u_char *)cmd); + memcpy(data, Password->buffer, Password->len); + data += Password->len; + + retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + if (reply->Reply.ErrorCode) + { + retCode = reply->Reply.ErrorCode; + } + else + { + retCode = 0; + if (lgnId) + { + *lgnId = reply->loginIdentity; + } + } + Novfs_Free(reply); + } + memset(cmd, 0, cmdlen); + Novfs_Free(cmd); + } + else + { + retCode = -ENOMEM; + } + return( retCode ); + +} + +/*++======================================================================*/ +int do_logout( struct qstr *Server, session_t Session ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + PLOGOUT_REQUEST cmd; + PLOGOUT_REPLY reply; + u_long replylen=0; + int retCode, cmdlen; + + cmdlen = (int)(&((PLOGOUT_REQUEST)0)->Name) + Server->len; + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_LOGOUT_USER; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + + cmd->Length = Server->len; + memcpy(cmd->Name, Server->name, Server->len); + + retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + if (reply->Reply.ErrorCode) + { + retCode = -EIO; + } + Novfs_Free(reply); + } + Novfs_Free(cmd); + } + else + { + retCode = -ENOMEM; + } + return( retCode ); + +} + +/*++======================================================================*/ +int Daemon_getpwuid( uid_t uid, int unamelen, char *uname ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + GETPWUID_REQUEST cmd; + PGETPWUID_REPLY reply; + u_long replylen=0; + int retCode; + + cmd.Command.CommandType = VFS_COMMAND_GETPWUD; + cmd.Command.SequenceNumber = 0; + cmd.Command.SessionId = 0; + cmd.uid = uid; + + retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + if (reply->Reply.ErrorCode) + { + retCode = -EIO; + } + else + { + retCode = 0; + memset(uname, 0, unamelen); + replylen = replylen - (int)(&((PGETPWUID_REPLY)0)->UserName); + if (replylen) + { + if (replylen > unamelen) + { + retCode = -EINVAL; + replylen = unamelen-1; + } + memcpy(uname, reply->UserName, replylen); + } + } + Novfs_Free(reply); + } + return( retCode ); + +} + +/*++======================================================================*/ +int Daemon_getversion( char *Buf, int Length ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + GET_VERSION_REQUEST cmd; + PGET_VERSION_REPLY reply; + u_long replylen=0; + int retVal=0; + + cmd.Command.CommandType = VFS_COMMAND_GET_VERSION; + cmd.Command.SequenceNumber = 0; + cmd.Command.SessionId = 0; + + Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + if (reply->Reply.ErrorCode) + { + retVal = -EIO; + } + else + { + retVal = replylen - (int)(&((PGET_VERSION_REPLY)0)->Version); + if (retVal < Length) + { + memcpy(Buf, reply->Version, retVal); + Buf[retVal] = '\0'; + } + } + Novfs_Free(reply); + } + return( retVal ); + +} + +/*++======================================================================*/ +int Daemon_Login(PLOGIN Login, session_t Session) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int retCode = -ENOMEM; + LOGIN lLogin; + NclString server; + NclString username; + NclString password; + + if ( !copy_from_user(&lLogin, Login, sizeof(lLogin))) + { + if ( (server.buffer = Novfs_Malloc(lLogin.Server.Length, GFP_KERNEL)) ) + { + server.len = lLogin.Server.Length; + server.type = NWC_STRING_TYPE_ASCII; + if ( !copy_from_user((void *)server.buffer, lLogin.Server.Data, server.len) ) + { + if ( (username.buffer = Novfs_Malloc(lLogin.UserName.Length, GFP_KERNEL)) ) + { + username.len = lLogin.UserName.Length; + username.type = NWC_STRING_TYPE_ASCII; + if ( !copy_from_user((void *)username.buffer, lLogin.UserName.Data, username.len) ) + { + if ( (password.buffer = Novfs_Malloc(lLogin.Password.Length, GFP_KERNEL)) ) + { + password.len = lLogin.Password.Length; + password.type = NWC_STRING_TYPE_ASCII; + if ( !copy_from_user((void *)password.buffer, lLogin.Password.Data, password.len) ) + { + retCode = do_login(&server, &username, &password, NULL, Session); + if ( !retCode ) + { + char *username; + username = Scope_Get_UserName( NULL ); + if (username) + { + Novfs_Add_to_Root( username ); + } + } + } + memset(password.buffer, 0, password.len); + Novfs_Free(password.buffer); + } + } + memset(username.buffer, 0, username.len); + Novfs_Free(username.buffer); + } + } + Novfs_Free(server.buffer); + } + } + + return( retCode ); +} + +/*++======================================================================*/ +int Daemon_Logout(PLOGOUT Logout, session_t Session) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + LOGOUT lLogout; + struct qstr server; + int retCode=0; + + if ( !copy_from_user(&lLogout, Logout, sizeof(lLogout))) + { + if ( (server.name = Novfs_Malloc(lLogout.Server.Length, GFP_KERNEL)) ) + { + server.len = lLogout.Server.Length; + if ( !copy_from_user((void *)server.name, lLogout.Server.Data, server.len) ) + { + retCode = do_logout( &server, Session ); + } + Novfs_Free(server.name); + } + } + return( retCode ); +} + +/*++======================================================================*/ +int Daemon_CreateSessionId( uint64_t *SessionId ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + CREATE_CONTEXT_REQUEST cmd; + PCREATE_CONTEXT_REPLY reply; + u_long replylen=0; + int retCode=0; + + DbgPrint("Daemon_CreateSessionId: %d\n", current->pid); + + cmd.Command.CommandType = VFS_COMMAND_CREATE_CONTEXT; + cmd.Command.SequenceNumber = 0; + cmd.Command.SessionId = 0; + + retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); + if ( reply ) + { + if ( !reply->Reply.ErrorCode && replylen > sizeof(COMMAND_REPLY_HEADER)) + { + *SessionId = reply->SessionId; + retCode = 0; + } + else + { + *SessionId = 0; + retCode = -EIO; + } + Novfs_Free(reply); + } + DbgPrint("Daemon_CreateSessionId: SessionId=0x%llx\n", *SessionId); + return(retCode); +} + +/*++======================================================================*/ +int Daemon_DestroySessionId( uint64_t SessionId ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + DESTROY_CONTEXT_REQUEST cmd; + PDESTROY_CONTEXT_REPLY reply; + u_long replylen=0; + int retCode=0; + + DbgPrint("Daemon_DestroySessionId: 0x%llx\n", SessionId); + + cmd.Command.CommandType = VFS_COMMAND_DESTROY_CONTEXT; + cmd.Command.SequenceNumber = 0; + cmd.Command.SessionId = SessionId; + + retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); + if ( reply ) + { + if ( !reply->Reply.ErrorCode ) + { + drive_map_t *dm; + struct list_head *list; + + retCode = 0; + + /* + * When destroying the session check to see if there are any + * mapped drives. If there are then remove them. + */ + down( &DriveMapLock ); + list_for_each( list, &DriveMapList ) + { + dm = list_entry( list, drive_map_t, list ); + if ( SessionId == dm->session) + { + local_unlink( dm->name ); + list = list->prev; + list_del( &dm->list ); + Novfs_Free( dm ); + } + + } + up( &DriveMapLock ); + + } + else + { + retCode = -EIO; + } + Novfs_Free(reply); + } + return(retCode); +} + +/*++======================================================================*/ +int Daemon_Get_UserSpace( uint64_t SessionId, uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + GET_USER_SPACE_REQUEST cmd; + PGET_USER_SPACE_REPLY reply; + u_long replylen=0; + int retCode=0; + + DbgPrint("Daemon_Get_UserSpace: 0x%llx\n", SessionId); + + cmd.Command.CommandType = VFS_COMMAND_GET_USER_SPACE; + cmd.Command.SequenceNumber = 0; + cmd.Command.SessionId = SessionId; + + retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); + if ( reply ) + { + if ( !reply->Reply.ErrorCode ) + { + + DbgPrint("TotalSpace: %llu\n", reply->TotalSpace); + DbgPrint("FreeSpace: %llu\n", reply->FreeSpace); + DbgPrint("TotalEnties: %llu\n", reply->TotalEnties); + DbgPrint("FreeEnties: %llu\n", reply->FreeEnties); + + if (TotalSize) *TotalSize = reply->TotalSpace; + if (Free) *Free = reply->FreeSpace; + if (TotalEnties) *TotalEnties = reply->TotalEnties; + if (FreeEnties) *FreeEnties = reply->FreeEnties; + retCode = 0; + } + else + { + retCode = -EIO; + } + Novfs_Free(reply); + } + return(retCode); +} + +/*++======================================================================*/ +int Daemon_SetMountPoint ( char *Path ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + PSET_MOUNT_PATH_REQUEST cmd; + PSET_MOUNT_PATH_REPLY reply; + u_long replylen, cmdlen; + int retCode = -ENOMEM; + + DbgPrint("Daemon_SetMountPoint: %s\n", Path); + + replylen = strlen(Path); + + cmdlen = sizeof(SET_MOUNT_PATH_REQUEST) + replylen; + + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + if ( cmd ) + { + cmd->Command.CommandType = VFS_COMMAND_SET_MOUNT_PATH; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = 0; + cmd->PathLength = replylen; + + strcpy(cmd->Path, Path); + + replylen = 0; + + retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); + if ( reply ) + { + if ( !reply->Reply.ErrorCode ) + { + retCode = 0; + } + else + { + retCode = -EIO; + } + Novfs_Free(reply); + } + Novfs_Free(cmd); + } + return(retCode); +} + +/*++======================================================================*/ +int Daemon_SendDebugCmd ( char *Command ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + DEBUG_REQUEST cmd; + PDEBUG_REPLY reply; + DEBUG_REPLY lreply; + u_long replylen, cmdlen; + DATA_LIST dlist[2]; + + int retCode = -ENOMEM; + + DbgPrint("Daemon_SendDebugCmd: %s\n", Command); + + dlist[0].page = NULL; + dlist[0].offset = (char *)Command; + dlist[0].len = strlen(Command); + dlist[0].rwflag = DLREAD; + + dlist[1].page = NULL; + dlist[1].offset = (char *)&lreply; + dlist[1].len = sizeof(lreply); + dlist[1].rwflag = DLWRITE; + + cmdlen = (int)(&((PDEBUG_REQUEST)0)->dbgcmd); + + cmd.Command.CommandType = VFS_COMMAND_DBG; + cmd.Command.SequenceNumber = 0; + cmd.Command.SessionId = 0; + cmd.cmdlen = strlen(Command); + + replylen = 0; + + retCode = Queue_Daemon_Command(&cmd, cmdlen, dlist, 2, (void *)&reply, &replylen, INTERRUPTIBLE); + if ( reply ) + { + Novfs_Free(reply); + } + if (0 == retCode) + { + retCode = lreply.Reply.ErrorCode; + } + + return(retCode); +} + +/*++======================================================================*/ +int +NO_TRACE +Daemon_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u_long arg) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int retCode = -ENOSYS; + u_long cpylen; + + + switch (cmd) + { + case IOC_LOGIN: + { + retCode = Daemon_Login((PLOGIN)arg, Scope_Get_SessionId( NULL )); + break; + } + + case IOC_LOGOUT: + { + retCode = Daemon_Logout((PLOGOUT)arg, Scope_Get_SessionId( NULL )); + break; + } + case IOC_DEBUGPRINT: + { + struct Ioctl_Debug { + int length; + char *data; + } io; + char *buf; + io.length = 0; + cpylen = copy_from_user(&io, (char *)arg, sizeof(io)); + if (io.length) + { + buf = Novfs_Malloc(io.length+1, GFP_KERNEL); + if (buf) + { + buf[0] = 0; + cpylen = copy_from_user(buf, io.data, io.length); + buf[io.length] = '\0'; + DbgPrint("%s", buf); + Novfs_Free(buf); + retCode = 0; + } + } + break; + } + + case IOC_XPLAT: + { + XPLAT data; + + cpylen = copy_from_user(&data, (void *)arg, sizeof(data)); + retCode = ((data.xfunction & 0x0000FFFF) | 0xCC000000); + + switch(data.xfunction) + { + case NWC_GET_MOUNT_PATH: + DbgPrint("[Daemon_ioctl] Call NwdGetMountPath\n"); + retCode = NwdGetMountPath( &data ); + break; + } + + DbgPrint("[NOVFS XPLAT] status Code = %X\n", retCode); + break; + } + + } + return (retCode); +} + +/*++======================================================================*/ +int Daemon_Added_Resource(daemon_handle_t *DHandle, int Type, u_long CHandle, u_char *FHandle, u_long Mode, u_long Size) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + daemon_resource_t *resource; + int retVal = NWE_OUT_OF_HEAP_SPACE; + + if (FHandle) + DbgPrint("Daemon_Added_Resource: DHandle=0x%p Type=%d CHandle=0x%x FHandle=0x%x Mode=0x%x Size=%d\n", DHandle, Type, CHandle, *(u_long *)&FHandle[2], Mode, Size); + else + DbgPrint("Daemon_Added_Resource: DHandle=0x%p Type=%d CHandle=0x%x\n", DHandle, Type, CHandle); + + resource = Novfs_Malloc(sizeof(daemon_resource_t), GFP_KERNEL); + if (resource) + { + resource->type = Type; + resource->connection = CHandle; + if (FHandle) + { + memcpy( resource->handle, FHandle, sizeof(resource->handle) ); + } + else + { + memset( resource->handle, 0, sizeof(resource->handle) ); + } + resource->mode = Mode; + resource->size = Size; + write_lock( &DHandle->lock ); + list_add( &resource->list, &DHandle->list ); + write_unlock( &DHandle->lock ); + DbgPrint("Daemon_Added_Resource: Adding resource=0x%p\n", resource); + retVal = 0; + } + + return(retVal); +} + +/*++======================================================================*/ +int Daemon_Remove_Resource(daemon_handle_t *DHandle, int Type, u_long CHandle, u_long FHandle) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + daemon_resource_t *resource; + struct list_head *l; + int retVal = -ENOMEM; + + DbgPrint("Daemon_Remove_Resource: DHandle=0x%p Type=%d CHandle=0x%x FHandle=0x%x\n", DHandle, Type, CHandle, FHandle); + + write_lock( &DHandle->lock ); + + list_for_each( l, &DHandle->list ) + { + resource = list_entry( l, daemon_resource_t, list ); + + if ( (Type == resource->type) && + (resource->connection == CHandle) ) + { + DbgPrint("Daemon_Remove_Resource: Found resource=0x%p\n", resource); + l = l->prev; + list_del( &resource->list ); + Novfs_Free( resource ); + break; + } + } + + write_unlock( &DHandle->lock ); + + return(retVal); +} + +/*++======================================================================*/ +int Daemon_Library_open(struct inode *inode, struct file *file) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int retVal = -ENOMEM; + daemon_handle_t *dh; + + DbgPrint("Daemon_Library_open: inode=0x%p file=0x%p\n", inode, file); + + if ((dh = Novfs_Malloc(sizeof(daemon_handle_t), GFP_KERNEL))) + { + file->private_data = dh; + INIT_LIST_HEAD( &dh->list); + rwlock_init( &dh->lock ); + dh->session = Scope_Get_SessionId( NULL ); + retVal = 0; + } + return(retVal); +} + +/*++======================================================================*/ +int Daemon_Library_close(struct inode *inode, struct file *file) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + daemon_handle_t *dh; + daemon_resource_t *resource; + struct list_head *l; + + char commanddata[sizeof(XPLAT_CALL_REQUEST)+sizeof(NwdCCloseConn)]; + PXPLAT_CALL_REQUEST cmd; + PXPLAT_CALL_REPLY reply; + PNwdCCloseConn nwdClose; + u_long cmdlen, replylen; + + DbgPrint("Daemon_Library_close: inode=0x%p file=0x%p\n", inode, file); + if (file->private_data) + { + dh = (daemon_handle_t *)file->private_data; + + list_for_each( l, &dh->list ) + { + resource = list_entry( l, daemon_resource_t, list ); + + if (DH_TYPE_STREAM == resource->type) + { + Novfs_Close_Stream( resource->connection, resource->handle, dh->session ); + } + else if (DH_TYPE_CONNECTION == resource->type) + { + cmd = (PXPLAT_CALL_REQUEST)commanddata; + cmdlen = offsetof(XPLAT_CALL_REQUEST, data) + sizeof(NwdCCloseConn); + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = dh->session; + cmd->NwcCommand = NWC_CLOSE_CONN; + + cmd->dataLen = sizeof(NwdCCloseConn); + nwdClose = (PNwdCCloseConn)cmd->data; + nwdClose->ConnHandle = resource->connection; + + Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, 0); + if (reply) + { + Novfs_Free(reply); + } + } + l = l->prev; + list_del( &resource->list ); + Novfs_Free( resource ); + } + Novfs_Free(dh); + file->private_data = NULL; + } + + return(0); +} + +/*++======================================================================*/ +ssize_t Daemon_Library_read(struct file *file, char *buf, size_t len, loff_t *off) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + daemon_handle_t *dh; + daemon_resource_t *resource; + + size_t thisread, totalread=0; + loff_t offset = *off; + + DbgPrint("Daemon_Library_read: file=0x%p len=%d off=%lld\n", file, len, *off); + + if (file->private_data) + { + dh = file->private_data; + read_lock( &dh->lock ); + if (&dh->list != dh->list.next) + { + resource = list_entry( dh->list.next, daemon_resource_t, list ); + + if (DH_TYPE_STREAM == resource->type) + { + while( len > 0 && (offset < resource->size) ) + { + thisread = len; + if (Novfs_Read_Stream(resource->connection, + resource->handle, + buf, &thisread, + &offset, 1, + dh->session) || !thisread) + { + break; + } + len -= thisread; + buf += thisread; + offset += thisread; + totalread += thisread; + } + } + } + read_unlock( &dh->lock ); + } + *off = offset; + DbgPrint("Daemon_Library_read return = 0x%x\n", totalread); + return(totalread); +} + +/*++======================================================================*/ +ssize_t Daemon_Library_write(struct file *file, const char *buf, size_t len, loff_t *off) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + daemon_handle_t *dh; + daemon_resource_t *resource; + + size_t thiswrite, totalwrite=-EINVAL; + loff_t offset = *off; + int status; + + DbgPrint("Daemon_Library_write: file=0x%p len=%d off=%lld\n", file, len, *off); + + if (file->private_data) + { + dh = file->private_data; + write_lock( &dh->lock ); + if (&dh->list != dh->list.next) + { + resource = list_entry( dh->list.next, daemon_resource_t, list ); + + if ( (DH_TYPE_STREAM == resource->type) && (len >= 0) ) + { + totalwrite = 0; + do + { + thiswrite = len; + status = Novfs_Write_Stream(resource->connection, + resource->handle, + (PVOID)buf, + &thiswrite, + &offset, + dh->session); + if ( status || !thiswrite ) + { + /* + * If len is zero then the file will have just been + * truncated to offset. Update size. + */ + if ( !status && !len ) + { + resource->size = offset; + } + totalwrite = status; + break; + } + len -= thiswrite; + buf += thiswrite; + offset += thiswrite; + totalwrite += thiswrite; + if (offset > resource->size) + { + resource->size = offset; + } + } while(len > 0); + } + } + write_unlock( &dh->lock ); + } + *off = offset; + DbgPrint("Daemon_Library_write return = 0x%x\n", totalwrite); + + return(totalwrite); +} + +/*++======================================================================*/ +loff_t Daemon_Library_llseek(struct file *file, loff_t offset, int origin) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + daemon_handle_t *dh; + daemon_resource_t *resource; + + loff_t retVal = -EINVAL; + + DbgPrint("Daemon_Library_llseek: file=0x%p offset=%lld origin=%d\n", file, offset, origin); + + if (file->private_data) + { + dh = file->private_data; + read_lock( &dh->lock ); + if (&dh->list != dh->list.next) + { + resource = list_entry( dh->list.next, daemon_resource_t, list ); + + if (DH_TYPE_STREAM == resource->type) + { + switch (origin) { + case 2: + offset += resource->size; + break; + case 1: + offset += file->f_pos; + } + if (offset >= 0) { + if (offset != file->f_pos) { + file->f_pos = offset; + file->f_version = 0; + } + retVal = offset; + } + } + } + read_unlock( &dh->lock ); + } + + DbgPrint("Daemon_Library_llseek: ret %lld\n", retVal); + + return retVal; +} + +/*++======================================================================*/ +int +NO_TRACE +Daemon_Library_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u_long arg) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int retCode = -ENOSYS; + daemon_handle_t *dh; + u_long handle=0, cpylen; + + + dh = file->private_data; + + DbgPrint("Daemon_Library_ioctl: file=0x%p 0x%x 0x%x dh=0x%p\n", file, cmd, arg, dh); + + if (dh) + { + + switch (cmd) + { + case IOC_LOGIN: + { + retCode = Daemon_Login((PLOGIN)arg, dh->session); + break; + } + + case IOC_LOGOUT: + { + retCode = Daemon_Logout((PLOGOUT)arg, dh->session); + break; + } + + case IOC_DEBUGPRINT: + { + struct Ioctl_Debug { + int length; + char *data; + } io; + char *buf; + io.length = 0; + cpylen = copy_from_user(&io, (char *)arg, sizeof(io)); + if (io.length) + { + buf = Novfs_Malloc(io.length+1, GFP_KERNEL); + if (buf) + { + buf[0] = 0; + cpylen = copy_from_user(buf, io.data, io.length); + buf[io.length] = '\0'; + DbgPrint("%s", buf); + Novfs_Free(buf); + retCode = 0; + } + } + break; + } + + case IOC_XPLAT: + { + XPLAT data; + + cpylen = copy_from_user(&data, (void *)arg, sizeof(data)); + retCode = ((data.xfunction & 0x0000FFFF) | 0xCC000000); + + switch(data.xfunction) + { + case NWC_OPEN_CONN_BY_NAME: + DbgPrint("[VFS XPLAT] Call NwOpenConnByName\n"); + retCode = NwOpenConnByName(&data, &handle, dh->session); + if ( !retCode ) + { + Daemon_Added_Resource(dh, DH_TYPE_CONNECTION, handle, 0, 0, 0); + } + break; + + case NWC_OPEN_CONN_BY_ADDRESS: + DbgPrint("[VFS XPLAT] Call NwOpenConnByAddress\n"); + retCode = NwOpenConnByAddr(&data, &handle, dh->session); + if ( !retCode ) + { + Daemon_Added_Resource(dh, DH_TYPE_CONNECTION, handle, 0, 0, 0); + } + break; + + case NWC_OPEN_CONN_BY_REFERENCE: + + DbgPrint("[VFS XPLAT] Call NwOpenConnByReference\n"); + retCode = NwOpenConnByRef(&data, &handle, dh->session); + if ( !retCode ) + { + Daemon_Added_Resource(dh, DH_TYPE_CONNECTION, handle, 0, 0, 0); + } + break; + + case NWC_SYS_CLOSE_CONN: + DbgPrint("[VFS XPLAT] Call NwSysCloseConn\n"); + retCode = NwSysConnClose(&data, &handle, dh->session); + Daemon_Remove_Resource(dh, DH_TYPE_CONNECTION, handle, 0); + break; + + case NWC_CLOSE_CONN: + DbgPrint("[VFS XPLAT] Call NwCloseConn\n"); + retCode = NwConnClose(&data, &handle, dh->session); + Daemon_Remove_Resource(dh, DH_TYPE_CONNECTION, handle, 0); + break; + + case NWC_LOGIN_IDENTITY: + DbgPrint("[VFS XPLAT] Call NwLoginIdentity\n"); + retCode = NwLoginIdentity(&data, dh->session); + break; + + case NWC_RAW_NCP_REQUEST: + DbgPrint("[VFS XPLAT] Send Raw NCP Request\n"); + retCode = NwRawSend(&data, dh->session); + break; + + case NWC_AUTHENTICATE_CONN_WITH_ID: + DbgPrint("[VFS XPLAT] Authenticate Conn With ID\n"); + retCode = NwAuthConnWithId(&data, dh->session); + break; + + case NWC_UNAUTHENTICATE_CONN: + DbgPrint("[VFS XPLAT] UnAuthenticate Conn With ID\n"); + retCode = NwUnAuthenticate(&data, dh->session); + break; + + case NWC_LICENSE_CONN: + DbgPrint("Call NwLicenseConn\n"); + retCode = NwLicenseConn(&data, dh->session); + break; + + case NWC_LOGOUT_IDENTITY: + DbgPrint("[VFS XPLAT] Call NwLogoutIdentity\n"); + retCode = NwLogoutIdentity(&data, dh->session); + break; + + case NWC_UNLICENSE_CONN: + DbgPrint("[VFS XPLAT] Call NwUnlicense\n"); + retCode = NwUnlicenseConn(&data, dh->session); + break; + + case NWC_GET_CONN_INFO: + DbgPrint("[VFS XPLAT] Call NwGetConnInfo\n"); + retCode = NwGetConnInfo(&data, dh->session); + break; + + case NWC_SET_CONN_INFO: + DbgPrint("[VFS XPLAT] Call NwGetConnInfo\n"); + retCode = NwSetConnInfo(&data, dh->session); + break; + + case NWC_SCAN_CONN_INFO: + DbgPrint("[VFS XPLAT] Call NwScanConnInfo\n"); + retCode = NwScanConnInfo(&data, dh->session); + break; + + + case NWC_GET_IDENTITY_INFO: + DbgPrint("[VFS XPLAT] Call NwGetIdentityInfo\n"); + retCode = NwGetIdentityInfo(&data, dh->session); + break; + + case NWC_GET_REQUESTER_VERSION: + DbgPrint("[VFS XPLAT] Call NwGetDaemonVersion\n"); + retCode = NwGetDaemonVersion(&data, dh->session); + break; + + case NWC_GET_PREFERRED_DS_TREE: + DbgPrint("[VFS XPLAT] Call NwcGetPreferredDsTree\n"); + retCode = NwcGetPreferredDSTree(&data, dh->session); + break; + + case NWC_SET_PREFERRED_DS_TREE: + DbgPrint("[VFS XPLAT] Call NwcSetPreferredDsTree\n"); + retCode = NwcSetPreferredDSTree(&data, dh->session); + break; + + case NWC_GET_DEFAULT_NAME_CONTEXT: + DbgPrint("[VFS XPLAT] Call NwcGetDefaultNameContext\n"); + retCode = NwcGetDefaultNameCtx(&data, dh->session); + break; + + case NWC_SET_DEFAULT_NAME_CONTEXT: + DbgPrint("[VFS XPLAT] Call NwcSetDefaultNameContext\n"); + retCode = NwcSetDefaultNameCtx(&data, dh->session); + break; + + case NWC_QUERY_FEATURE: + DbgPrint("[VFS XPLAT] Call NwQueryFeature\n"); + retCode = NwQueryFeature(&data, dh->session); + break; + + + case NWC_GET_TREE_MONITORED_CONN_REF: + DbgPrint("[VFS XPLAT] Call NwcGetTreeMonitoredConn\n"); + retCode = NwcGetTreeMonitoredConn(&data, dh->session); + break; + + case NWC_ENUMERATE_IDENTITIES: + DbgPrint("[VFS XPLAT] Call NwcEnumerateIdentities\n"); + retCode = NwcEnumIdentities(&data, dh->session); + break; + + case NWC_CHANGE_KEY: + DbgPrint("[VFS XPLAT] Call NwcChangeAuthKey\n"); + retCode = NwcChangeAuthKey(&data, dh->session); + break; + + case NWC_CONVERT_LOCAL_HANDLE: + DbgPrint("[VFS XPLAT] Call NwdConvertLocalHandle\n"); + retCode = NwdConvertLocalHandle(&data, dh); + break; + + case NWC_CONVERT_NETWARE_HANDLE: + DbgPrint("[VFS XPLAT] Call NwdConvertNetwareHandle\n"); + retCode = NwdConvertNetwareHandle(&data, dh); + break; + + case NWC_SET_PRIMARY_CONN: + DbgPrint("[VFS XPLAT] Call NwcSetPrimaryConn\n"); + retCode = NwcSetPrimaryConn(&data, dh->session); + break; + + case NWC_GET_PRIMARY_CONN: + DbgPrint("[VFS XPLAT] Call NwcGetPrimaryConn\n"); + retCode = NwcGetPrimaryConn(&data, dh->session); + break; + + case NWC_MAP_DRIVE: + DbgPrint("[VFS XPLAT] Call NwcMapDrive\n"); + retCode = NwdSetMapDrive(&data, dh->session); + break; + + case NWC_UNMAP_DRIVE: + DbgPrint("[VFS XPLAT] Call NwcUnMapDrive\n"); + retCode = NwdUnMapDrive(&data, dh->session); + break; + + case NWC_ENUMERATE_DRIVES: + DbgPrint("[VFS XPLAT] Call NwcEnumerateDrives\n"); + retCode = NwcEnumerateDrives(&data, dh->session); + break; + + case NWC_GET_MOUNT_PATH: + DbgPrint("[VFS XPLAT] Call NwdGetMountPath\n"); + retCode = NwdGetMountPath( &data ); + break; + + case NWC_GET_BROADCAST_MESSAGE: + DbgPrint("[VSF XPLAT Call NwdGetBroadcastMessage\n"); + retCode = NwcGetBroadcastMessage(&data, dh->session); + break; + + case NWC_SET_KEY: + DbgPrint("[VSF XPLAT Call NwdSetKey\n"); + retCode = NwdSetKeyValue(&data, dh->session); + break; + + case NWC_VERIFY_KEY: + DbgPrint("[VSF XPLAT Call NwdVerifyKey\n"); + retCode = NwdVerifyKeyValue(&data, dh->session); + break; + + case NWC_RAW_NCP_REQUEST_ALL: + case NWC_NDS_RESOLVE_NAME_TO_ID: + case NWC_FRAGMENT_REQUEST: + case NWC_GET_CONFIGURED_NSPS: + default: + break; + + } + + DbgPrint("[NOVFS XPLAT] status Code = %X\n", retCode); + break; + } + } + } + + return( retCode ); +} + +/*++======================================================================*/ +unsigned int Daemon_Poll(struct file *file, struct poll_table_struct *poll_table) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + daemon_command_t *que; + unsigned int mask = POLLOUT | POLLWRNORM; + + que = get_next_queue(0); + if (que) + { + mask |= (POLLIN | POLLRDNORM); + } + else + { + + } + return(mask); +} + + +void Daemon_Dumpque( void ) +{ +#ifdef CONFIG_KDB + daemon_command_t *que; + + que = (daemon_command_t *)Daemon_Queue.list.next; + + while (que && (que != (daemon_command_t *)&Daemon_Queue.list.next)) + { + kdb_printf("DaemonQue:\n" \ + " Que: 0x%p\n" \ + " status: 0x%lx\n" \ + " flags: 0x%lx\n" \ + " semaphore: 0x%x\n" \ + " sequence: 0x%lx\n" \ + " timer: 0x%lx\n" \ + " request: 0x%p\n" \ + " reqlen: %ld\n" \ + " data: 0x%p\n" \ + " datalen: %d\n" \ + " reply: 0x%p\n" \ + " replen: %ld\n", + que, + que->status, + que->flags, + atomic_read(&que->semaphore.count), + que->sequence, + que->timer.expires, + que->request, + que->reqlen, + que->data, + que->datalen, + que->reply, + que->replen); + que = (daemon_command_t *)que->list.next; + } +#endif +} + +/*++======================================================================*/ +int NwdConvertNetwareHandle(PXPLAT pdata, daemon_handle_t *DHandle) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int retVal; + NwcConvertNetWareHandle nh; + u_long cpylen; + + DbgPrint("NwdConvertNetwareHandle: DHandle=0x%p\n", DHandle); + + cpylen = copy_from_user(&nh, pdata->reqData, sizeof(NwcConvertNetWareHandle)); + + retVal = Daemon_Added_Resource(DHandle, DH_TYPE_STREAM, nh.ConnHandle, nh.NetWareHandle, nh.uAccessMode, nh.uFileSize); + + return(retVal); +} + +/*++======================================================================*/ +int NwdConvertLocalHandle(PXPLAT pdata, daemon_handle_t *DHandle) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int retVal = NWE_REQUESTER_FAILURE; + daemon_resource_t *resource; + NwcConvertLocalHandle lh; + struct list_head *l; + u_long cpylen; + + DbgPrint("NwdConvertLocalHandle: DHandle=0x%p\n", DHandle); + + read_lock( &DHandle->lock ); + + list_for_each( l, &DHandle->list ) + { + resource = list_entry( l, daemon_resource_t, list ); + + if ( DH_TYPE_STREAM == resource->type ) + { + lh.uConnReference = resource->connection; + + memcpy(lh.NwFileHandle, resource->handle, sizeof(resource->handle)); + if (pdata->repLen >= sizeof(NwcConvertLocalHandle)) + { + cpylen = copy_to_user(pdata->repData, &lh, sizeof(NwcConvertLocalHandle)); + retVal = 0; + } + else + { + retVal = NWE_BUFFER_OVERFLOW; + } + break; + } + } + + read_unlock( &DHandle->lock ); + + return(retVal); +} + +/*++======================================================================*/ +int NwdGetMountPath(PXPLAT pdata) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int retVal = NWE_REQUESTER_FAILURE; + int len; + u_long cpylen; + NwcGetMountPath mp; + + cpylen = copy_from_user(&mp, pdata->reqData, pdata->reqLen); + + if ( Novfs_CurrentMount ) + { + + len = strlen(Novfs_CurrentMount)+1; + if ( (len > mp.MountPathLen) && mp.pMountPath) + { + retVal = NWE_BUFFER_OVERFLOW; + } + else + { + if (mp.pMountPath) + { + cpylen = copy_to_user(mp.pMountPath, Novfs_CurrentMount, len); + } + retVal = 0; + } + + mp.MountPathLen = len; + + if (pdata->repData && (pdata->repLen >= sizeof(mp)) ) + { + cpylen = copy_to_user(pdata->repData, &mp, sizeof(mp)); + } + } + + return(retVal); +} + +/*++======================================================================*/ +int NwdSetMapDrive(PXPLAT pdata, session_t Session) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int retVal; + u_long cpylen; + + retVal = NwcSetMapDrive(pdata, Session); + if ( !retVal ) + { + NwcMapDriveEx symInfo; + char *path; + drive_map_t *drivemap, *dm; + struct list_head *list; + + cpylen = copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo)); + drivemap = Novfs_Malloc( sizeof(drive_map_t)+symInfo.linkOffsetLength, GFP_KERNEL ); + if (drivemap) + { + path = (char *)pdata->reqData; + path += symInfo.linkOffset; + cpylen = copy_from_user(drivemap->name, path, symInfo.linkOffsetLength); + + drivemap->session = Session; + drivemap->hash = full_name_hash(drivemap->name, symInfo.linkOffsetLength-1); + drivemap->namelen = symInfo.linkOffsetLength-1; + DbgPrint( "NwdSetMapDrive: hash=0x%x path=%s\n", drivemap->hash, drivemap->name); + + dm = (drive_map_t *)&DriveMapList.next; + + down( &DriveMapLock ); + + list_for_each( list, &DriveMapList ) + { + dm = list_entry( list, drive_map_t, list ); + DbgPrint( "NwdSetMapDrive: dm=0x%p\n" \ + " hash: 0x%x\n" \ + " namelen: %d\n" \ + " name: %s\n", + dm, dm->hash, dm->namelen, dm->name); + + if (drivemap->hash == dm->hash) + { + if ( 0 == strcmp(dm->name, drivemap->name)) + { + dm = NULL; + break; + } + } + else if (drivemap->hash < dm->hash) + { + break; + } + } + + if (dm) + { + if ( (dm == (drive_map_t *)&DriveMapList) || + (dm->hash < drivemap->hash) ) + { + list_add( &drivemap->list, &dm->list); + } + else + { + list_add_tail( &drivemap->list, &dm->list); + } + } + else + { + Novfs_Free( drivemap ); + } + up( &DriveMapLock ); + } + } + + return(retVal); +} + +/*++======================================================================*/ +int NwdUnMapDrive(PXPLAT pdata, session_t Session) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int retVal = NWE_REQUESTER_FAILURE; + u_long cpylen; + + retVal = NwcUnMapDrive(pdata, Session); + if ( !retVal ) + { + NwcUnmapDriveEx symInfo; + char *path; + drive_map_t *dm; + struct list_head *list; + u_long hash; + + + cpylen = copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo)); + path = Novfs_Malloc( symInfo.linkLen, GFP_KERNEL ); + if (path) + { + cpylen = copy_from_user(path, ((NwcUnmapDriveEx *)pdata->reqData)->linkData, symInfo.linkLen); + + hash = full_name_hash(path, symInfo.linkLen-1); + DbgPrint( "NwdUnMapDrive: hash=0x%x path=%s\n", hash, path); + + dm = NULL; + + down( &DriveMapLock ); + + list_for_each( list, &DriveMapList ) + { + dm = list_entry( list, drive_map_t, list ); + DbgPrint( "NwdUnMapDrive: dm=0x%p %s\n" \ + " hash: 0x%x\n" \ + " namelen: %d\n", + dm, dm->name, dm->hash, dm->namelen); + + if (hash == dm->hash) + { + if ( 0 == strcmp(dm->name, path)) + { + break; + } + } + else if (hash < dm->hash) + { + dm = NULL; + break; + } + } + + if (dm) + { + DbgPrint( "NwdUnMapDrive: Remove dm=0x%p %s\n" \ + " hash: 0x%x\n" \ + " namelen: %d\n", + dm, dm->name, dm->hash, dm->namelen); + list_del( &dm->list ); + Novfs_Free( dm ); + } + + up( &DriveMapLock ); + } + } + + return(retVal); +} + +/*++======================================================================*/ +void RemoveDriveMaps( void ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + drive_map_t *dm; + struct list_head *list; + + down( &DriveMapLock ); + list_for_each( list, &DriveMapList ) + { + dm = list_entry( list, drive_map_t, list ); + + DbgPrint( "RemoveDriveMap: dm=0x%p\n" \ + " hash: 0x%x\n" \ + " namelen: %d\n" \ + " name: %s\n", + dm, dm->hash, dm->namelen, dm->name); + local_unlink( dm->name ); + list = list->prev; + list_del( &dm->list ); + Novfs_Free( dm ); + } + up( &DriveMapLock ); +} + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) +/*++======================================================================*/ +int local_unlink(const char *pathname) +{ + int error; + struct dentry *dentry; + struct nameidata nd; + struct inode *inode = NULL; + + DbgPrint("local_unlink: %s\n", pathname); + error = path_lookup(pathname, LOOKUP_PARENT, &nd); + DbgPrint("local_unlink: path_lookup %d\n", error); + if ( !error ) + { + error = -EISDIR; + if (nd.last_type == LAST_NORM) + { + mutex_lock(&nd.dentry->d_inode->i_mutex); + dentry = lookup_create( &nd, 1); + DbgPrint("local_unlink: lookup_hash 0x%p\n", dentry); + + error = PTR_ERR(dentry); + if (!IS_ERR(dentry)) + { + if (nd.last.name[nd.last.len]) + { + error = !dentry->d_inode ? -ENOENT : S_ISDIR(dentry->d_inode->i_mode) ? -EISDIR : -ENOTDIR; + } + else + { + inode = dentry->d_inode; + if (inode) + { + atomic_inc(&inode->i_count); + } + error = vfs_unlink(nd.dentry->d_inode, dentry); + DbgPrint("local_unlink: vfs_unlink %d\n", error); + } + dput(dentry); + } + mutex_unlock(&nd.dentry->d_inode->i_mutex); + + } + path_release(&nd); + } + + if (inode) + { + iput(inode); /* truncate the inode here */ + } + + DbgPrint("local_unlink: error=%d\n", error); + return error; +} + +#else +/*++======================================================================*/ +int local_unlink(const char *pathname) +{ + int error; + struct dentry *dentry; + struct nameidata nd; + struct inode *inode = NULL; + + DbgPrint("local_unlink: %s\n", pathname); + error = path_lookup(pathname, LOOKUP_PARENT, &nd); + DbgPrint("local_unlink: path_lookup %d\n", error); + if ( !error ) + { + error = -EISDIR; + if (nd.last_type == LAST_NORM) + { + down(&nd.dentry->d_inode->i_sem); + dentry = lookup_one_len(&nd.last, nd.dentry, sizeof(nd.last)); + DbgPrint("local_unlink: lookup_hash 0x%p\n", dentry); + + error = PTR_ERR(dentry); + if (!IS_ERR(dentry)) + { + if (nd.last.name[nd.last.len]) + { + error = !dentry->d_inode ? -ENOENT : S_ISDIR(dentry->d_inode->i_mode) ? -EISDIR : -ENOTDIR; + } + else + { + inode = dentry->d_inode; + if (inode) + { + atomic_inc(&inode->i_count); + } + error = vfs_unlink(nd.dentry->d_inode, dentry); + DbgPrint("local_unlink: vfs_unlink %d\n", error); + } + dput(dentry); + } + up(&nd.dentry->d_inode->i_sem); + } + path_release(&nd); + } + + if (inode) + { + iput(inode); /* truncate the inode here */ + } + + DbgPrint("local_unlink: error=%d\n", error); + return error; +} +#endif diff -uNr src.old/src/file.c src/src/file.c --- src.old/src/file.c 1970-01-01 01:00:00.000000000 +0100 +++ src/src/file.c 2006-10-16 15:08:22.000000000 +0200 @@ -0,0 +1,2318 @@ +/*++======================================================================== + * Program Name: Novell NCP Redirector for Linux + * File Name: file.c + * Version: v1.00 + * Author: James Turner + * + * Abstract: This module contains functions for accessing + * files through the daemon. + * Notes: + * Revision History: + * + * + * Copyright (C) 2005 Novell, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *======================================================================--*/ + +/*===[ Include files specific to Linux ]==================================*/ +#include +#include +#include +#include +#include +#include +#include + +/*===[ Include files specific to this module ]============================*/ +#include "commands.h" +#include "nwerror.h" +#include "vfs.h" + +/*===[ External data ]====================================================*/ +extern struct dentry_operations Novfs_dentry_operations; +extern int MaxIoSize; + + +/*===[ External prototypes ]==============================================*/ +extern int DbgPrint( char *Fmt, ... ); +extern void mydump(int size, void *dumpptr); +extern int Queue_Daemon_Command(void *request, u_long reqlen, void *data, int dlen, void **reply, u_long *replen, int interruptible); +extern struct inode *Novfs_get_inode(struct super_block *sb, int mode, int dev, uid_t uid); + +extern void *Scope_Lookup( void ); + +/*===[ Manifest constants ]===============================================*/ + +/*===[ Type definitions ]=================================================*/ + +/*===[ Function prototypes ]==============================================*/ + +int Novfs_verify_file( struct qstr *Path, session_t SessionId ); +int Novfs_get_alltrees(struct dentry *parent); +ssize_t Novfs_tree_read(struct file *file, char *buf, size_t len, loff_t *off); + +int Novfs_Get_Connected_Server_List( u_char **ServerList, session_t SessionId ); +int Novfs_Get_Server_Volume_List( struct qstr *Server, u_char **VolumeList, session_t SessionId ); +int Novfs_Find_Name_In_List( struct qstr *Name, u_char *List ); +int Novfs_Verify_Server_Name( struct qstr *Server, session_t SessionId ); +int Novfs_Verify_Volume_Name( struct qstr *Server, struct qstr *Volume, session_t SessionId ); +int Novfs_Get_File_Info( u_char *Path, PENTRY_INFO Info, session_t SessionId ); +int Novfs_Get_Directory_List( u_char *Path, u_long *EnumHandle, PENTRY_INFO Info, session_t SessionId ); +int Novfs_Get_Directory_ListEx( u_char *Path, u_long *EnumHandle, int *Count, PENTRY_INFO *Info, session_t SessionId ); +int Novfs_Open_File( u_char *Path, int Flags, PENTRY_INFO Info, u_long *Handle, session_t SessionId ); +int Novfs_Create( u_char *Path, int DirectoryFlag, session_t SessionId ); +int Novfs_Close_File( u_long Handle, session_t SessionId ); +int Novfs_Read_File( u_long Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId); +int Novfs_Read_Pages( u_long Handle, PDATA_LIST DList, int DList_Cnt, size_t *Bytes, loff_t *Offset, session_t SessionId); +int Novfs_Write_File( u_long Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId); +int Novfs_Write_Pages( u_long Handle, PDATA_LIST DList, int DList_Cnt, size_t Bytes, loff_t Offset, session_t SessionId); +int Novfs_Read_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, int User, session_t SessionId); +int Novfs_Write_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId); +int Novfs_Close_Stream( u_long ConnHandle, u_char *Handle, session_t SessionId ); +int Novfs_Delete( u_char *Path, int DirectoryFlag, session_t SessionId ); +int Novfs_Truncate_File( u_char *Path, int PathLen, session_t SessionId ); +int Novfs_Rename_File( int DirectoryFlag, u_char *OldName, int OldLen, u_char *NewName, int NewLen, session_t SessionId ); +int Novfs_Set_Attr( u_char *Path, struct iattr *Attr, session_t SessionId ); +int Novfs_Get_File_Cache_Flag( u_char *Path, session_t SessionId ); + +/*===[ Global variables ]=================================================*/ +static struct file_operations Novfs_tree_operations = { + read: Novfs_tree_read, +}; + +/* + * StripTrailingDots was added because some apps will + * try and create a file name with a trailing dot. NetWare + * doesn't like this and will return an error. + */ +u_char StripTrailingDots=1; + +/*===[ Code ]=============================================================*/ + +/*++======================================================================*/ +int Novfs_verify_file( struct qstr *Path, scope_t SessionId ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + PVERIFY_FILE_REPLY reply=NULL; + u_long replylen=0; + PVERIFY_FILE_REQUEST cmd; + int cmdlen; + int retCode=0; + + cmdlen = (int)(&((PVERIFY_FILE_REQUEST)0)->path) + Path->len; + cmd = (PVERIFY_FILE_REQUEST)Novfs_Malloc(cmdlen, GFP_KERNEL); + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_VERIFY_FILE; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = SessionId; + cmd->pathLen = Path->len; + memcpy(cmd->path, Path->name, Path->len); + + retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); + if ( reply ) + { + DbgPrint("Novfs_verify_file: reply\n"); + mydump(replylen, reply); + if (reply->Reply.ErrorCode) + { + retCode = -ENOENT; + } + else + { + retCode = 0; + } + Novfs_Free(reply); + } + Novfs_Free(cmd); + } + else + { + retCode = -ENOMEM; + } + return(retCode); +} + +/*++======================================================================*/ +int Novfs_get_alltrees(struct dentry *parent) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + u_char *p; + PCOMMAND_REPLY_HEADER reply=NULL; + u_long replylen=0; + COMMAND_REQUEST_HEADER cmd; + int retCode; + struct dentry *entry; + struct qstr name; + struct inode *inode; + + cmd.CommandType = 0; + cmd.SequenceNumber = 0; + cmd.SessionId = 0x1234; + + DbgPrint( "Novfs_get_alltrees:\n"); + + retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); + DbgPrint( "Novfs_get_alltrees: relpy=0x%x replylen=%d\n", reply, replylen); + if (reply) + { + mydump(replylen, reply); + if ( !reply->ErrorCode && (replylen > sizeof(COMMAND_REPLY_HEADER))) + { + p = (char *)reply+8; + while (*p) + { + DbgPrint( "Novfs_get_alltrees: %s\n",p); + name.len = strlen(p); + name.name = p; + name.hash = full_name_hash(name.name, name.len); + entry = d_lookup(parent, &name); + if ( NULL == entry ) + { + DbgPrint( "Novfs_get_alltrees: adding %s\n",p); + entry = d_alloc(parent, &name); + if (entry) + { + entry->d_op = &Novfs_dentry_operations; + inode = Novfs_get_inode(parent->d_sb, S_IFREG | 0400, 0, 0); + if (inode) + { + inode->i_fop = &Novfs_tree_operations; + d_add(entry, inode); + } + } + } + p += (name.len+1); + } + } + Novfs_Free(reply); + } + return(retCode); +} + +/*++======================================================================*/ +ssize_t Novfs_tree_read(struct file *file, char *buf, size_t len, loff_t *off) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + if (file->f_pos != 0) + { + return(0); + } + if (copy_to_user(buf, "Tree\n", 5)) + { + return(0); + } + return(5); +} + +/*++======================================================================*/ +int Novfs_Get_Connected_Server_List( u_char **ServerList, session_t SessionId ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + GET_CONNECTED_SERVER_LIST_REQUEST req; + PGET_CONNECTED_SERVER_LIST_REPLY reply=NULL; + u_long replylen=0; + int retCode=0; + + *ServerList = NULL; + + req.Command.CommandType = VFS_COMMAND_GET_CONNECTED_SERVER_LIST; + req.Command.SessionId = SessionId; + + retCode = Queue_Daemon_Command(&req, sizeof(req), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); + if ( reply ) + { + DbgPrint("Novfs_Get_Connected_Server_List: reply\n"); + replylen -= sizeof(COMMAND_REPLY_HEADER); + if ( !reply->Reply.ErrorCode && replylen ) + { + memcpy(reply, reply->List, replylen); + *ServerList = (u_char *)reply; + retCode = 0; + } + else + { + Novfs_Free(reply); + retCode = -ENOENT; + } + } + return(retCode); +} + +/*++======================================================================*/ +int Novfs_Get_Server_Volume_List( struct qstr *Server, u_char **VolumeList, scope_t SessionId ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + PGET_SERVER_VOLUME_LIST_REQUEST req; + PGET_SERVER_VOLUME_LIST_REPLY reply=NULL; + u_long replylen=0, reqlen; + int retCode; + + *VolumeList = NULL; + reqlen = sizeof(GET_SERVER_VOLUME_LIST_REQUEST)+Server->len; + req = Novfs_Malloc(reqlen, GFP_KERNEL); + if (req) + { + req->Command.CommandType = VFS_COMMAND_GET_SERVER_VOLUME_LIST; + req->Length = Server->len; + memcpy(req->Name, Server->name, Server->len); + req->Command.SessionId = SessionId; + + retCode = Queue_Daemon_Command(req, reqlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); + if ( reply ) + { + DbgPrint("Novfs_Get_Server_Volume_List: reply\n"); + mydump(replylen, reply); + replylen -= sizeof(COMMAND_REPLY_HEADER); + + if ( !reply->Reply.ErrorCode && replylen ) + { + memcpy(reply, reply->List, replylen); + *VolumeList = (u_char *)reply; + retCode = 0; + } + else + { + Novfs_Free(reply); + retCode = -ENOENT; + } + } + Novfs_Free(req); + } + else + { + retCode = -ENOMEM; + } + return(retCode); +} + +/*++======================================================================*/ +int Novfs_Find_Name_In_List( struct qstr *Name, u_char *List ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int len; + int retCode = 0; + + while (*List) + { + len = strlen(List); + if ((len == Name->len) && !strncmp(Name->name, List, len)) + { + retCode = 1; + break; + } + List += (len+1); + } + return( retCode ); +} + +/*++======================================================================*/ +int Novfs_Verify_Server_Name( struct qstr *Server, session_t SessionId ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + u_char *list; + int retCode = 0; + + DbgPrint("Novfs_Verify_Server_Name: %.*s\n", Server->len, Server->name); + + list = NULL; + Novfs_Get_Connected_Server_List( &list, SessionId ); + + if (list) + { + retCode = Novfs_Find_Name_In_List( Server, list ); + Novfs_Free(list); + } + DbgPrint("Novfs_Verify_Server_Name: %d\n", retCode); + return(retCode); +} + +/*++======================================================================*/ +int Novfs_Verify_Volume_Name( struct qstr *Server, struct qstr *Volume, session_t SessionId ) +/* + * + * Arguments: Server - Server name. + * Volume - Volume name to check for. + * + * Returns: zero - not found. + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + u_char *list; + int retCode = 0; + u_char *name; + int namelen; + struct qstr path; + + list = NULL; + namelen = Server->len+Volume->len+2; + name = Novfs_Malloc(namelen, GFP_KERNEL); + + if (name) + { + name[0] = '\\'; + memcpy(&name[1], Server->name, Server->len); + name[1+Server->len] = '\\'; + memcpy(&name[2+Server->len], Volume->name, Volume->len); + path.len = namelen; + path.name = name; + + if (Novfs_verify_file(&path, SessionId)) + { + retCode = 0; + } + else + { + retCode = 1; + } + + Novfs_Free(name); + } + else + { + + Novfs_Get_Server_Volume_List( Server, &list, SessionId ); + + if (list) + { + retCode = Novfs_Find_Name_In_List( Volume, list ); + Novfs_Free(list); + } + } + return(retCode); +} + +/*++======================================================================*/ +int Novfs_Get_File_Info( u_char *Path, PENTRY_INFO Info, session_t SessionId ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + PVERIFY_FILE_REPLY reply=NULL; + u_long replylen=0; + PVERIFY_FILE_REQUEST cmd; + int cmdlen; + int retCode=-ENOENT; + int pathlen; + + DbgPrint("Novfs_Get_File_Info: Path = %s\n", Path); + + Info->mode = S_IFDIR | 0700; + Info->uid = current->uid; + Info->gid = current->gid; + Info->size = 0; + Info->atime = Info->mtime = Info->ctime = CURRENT_TIME; + + if (Path && *Path) + { + pathlen = strlen(Path); + if (StripTrailingDots) + { + if ('.' == Path[pathlen-1]) pathlen--; + } + cmdlen = (int)(&((PVERIFY_FILE_REQUEST)0)->path) + pathlen; + cmd = (PVERIFY_FILE_REQUEST)Novfs_Malloc(cmdlen, GFP_KERNEL); + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_VERIFY_FILE; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = SessionId; + cmd->pathLen = pathlen; + memcpy(cmd->path, Path, cmd->pathLen); + + retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); + + if (reply) + { + + if ( reply->Reply.ErrorCode ) + { + retCode = -ENOENT; + } + else + { + Info->type = 3; + Info->mode = S_IRWXU; + + if (reply->fileMode & NW_ATTRIBUTE_DIRECTORY) + { + Info->mode |= S_IFDIR; + } + else + { + Info->mode |= S_IFREG; + } + + if (reply->fileMode & NW_ATTRIBUTE_READ_ONLY) + { + Info->mode &= ~(S_IWUSR); + } + + Info->uid = current->euid; + Info->gid = current->egid; + Info->size = reply->fileSize; + Info->atime.tv_sec = reply->lastAccessTime; + Info->atime.tv_nsec = 0; + Info->mtime.tv_sec = reply->modifyTime; + Info->mtime.tv_nsec = 0; + Info->ctime.tv_sec = reply->createTime; + Info->ctime.tv_nsec = 0; + DbgPrint("Novfs_Get_File_Info: replylen=%d sizeof(VERIFY_FILE_REPLY)=%d\n", replylen, sizeof(VERIFY_FILE_REPLY)); + if (replylen > sizeof(VERIFY_FILE_REPLY)) + { + long *lp = &reply->fileMode; + lp++; + DbgPrint("Novfs_Get_File_Info: extra data 0x%x\n", *lp); + Info->mtime.tv_nsec = *lp; + } + retCode = 0; + } + + Novfs_Free(reply); + } + Novfs_Free(cmd); + } + } + + DbgPrint("Novfs_Get_File_Info: return 0x%x\n", retCode); + return(retCode); +} + +/*++======================================================================*/ +int Novfs_Get_File_Info2( u_char *Path, PENTRY_INFO Info, session_t SessionId ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + PVERIFY_FILE_REPLY reply=NULL; + u_long replylen=0; + PVERIFY_FILE_REQUEST cmd; + int cmdlen; + struct qstr server = {0}, volume = {0}; + u_char *p; + int i; + int retCode=-ENOENT; + p = Path; + + DbgPrint("Novfs_Get_File_Info: Path = %s\n", Path); + + Info->mode = S_IFDIR | 0700; + Info->uid = current->uid; + Info->gid = current->gid; + Info->size = 0; + Info->atime = Info->mtime = Info->ctime = CURRENT_TIME; + + if ('\\' == *p) + { + p++; + } + server.name = p; + + for(i=0; *p && ('\\' != *p); i++, p++); + server.len = i; + if (*p) + { + if ('\\' == *p) + { + p++; + } + volume.name = p; + for(i=0; *p && ('\\' != *p); i++, p++); + if (i) + { + volume.len = i; + if (*p) + { + if ('\\' == *p) + { + p++; + } + if (*p) + { + cmdlen = (int)(&((PVERIFY_FILE_REQUEST)0)->path) + strlen(Path); + cmd = (PVERIFY_FILE_REQUEST)Novfs_Malloc(cmdlen, GFP_KERNEL); + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_VERIFY_FILE; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = SessionId; + cmd->pathLen = strlen(Path); + memcpy(cmd->path, Path, cmd->pathLen); + + retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + + if ( reply->Reply.ErrorCode ) + { + retCode = -ENOENT; + } + else + { + Info->type = 3; + Info->mode = S_IRWXU; + + if (reply->fileMode & NW_ATTRIBUTE_DIRECTORY) + { + Info->mode |= S_IFDIR; + } + else + { + Info->mode |= S_IFREG; + } + + if (reply->fileMode & NW_ATTRIBUTE_READ_ONLY) + { + Info->mode &= ~(S_IWUSR); + } + + Info->uid = current->euid; + Info->gid = current->egid; + Info->size = reply->fileSize; + Info->atime.tv_sec = reply->lastAccessTime; + Info->atime.tv_nsec = 0; + Info->mtime.tv_sec = reply->modifyTime; + Info->mtime.tv_nsec = 0; + Info->ctime.tv_sec = reply->createTime; + Info->ctime.tv_nsec = 0; + retCode = 0; + } + + Novfs_Free(reply); + } + Novfs_Free(cmd); + } + } + } + } + if (('\0' == *p) && volume.len) + { + if ( Novfs_Verify_Volume_Name( &server, &volume, SessionId ) ) + { + retCode = 0; + Info->type = 2; + } + } + } + if (server.len && !volume.len) + { + if ( Novfs_Verify_Server_Name( &server, SessionId ) ) + { + retCode = 0; + Info->type = 1; + } + } + DbgPrint("Novfs_Get_File_Info: return 0x%x\n", retCode); + return(retCode); +} + +/*++======================================================================*/ +int begin_directory_enumerate( u_char *Path, int PathLen, u_long *EnumHandle, session_t SessionId) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + PBEGIN_ENUMERATE_DIRECTORY_REQUEST cmd; + PBEGIN_ENUMERATE_DIRECTORY_REPLY reply=NULL; + u_long replylen=0; + int retCode, cmdlen; + + *EnumHandle = 0; + + cmdlen = (int)(&((PBEGIN_ENUMERATE_DIRECTORY_REQUEST)0)->path) + PathLen; + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_START_ENUMERATE; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = SessionId; + + cmd->pathLen = PathLen; + memcpy(cmd->path, Path, PathLen); + + retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); +/* + * retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, 0); + */ + if (reply) + { + if (reply->Reply.ErrorCode) + { + retCode = -EIO; + } + else + { + *EnumHandle = reply->enumerateHandle; + retCode = 0; + } + Novfs_Free(reply); + } + Novfs_Free(cmd); + } + else + { + retCode = -ENOMEM; + } + return( retCode ); +} + +/*++======================================================================*/ +int end_directory_enumerate( u_long EnumHandle, session_t SessionId ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + END_ENUMERATE_DIRECTORY_REQUEST cmd; + PEND_ENUMERATE_DIRECTORY_REPLY reply=NULL; + u_long replylen=0; + int retCode; + + + cmd.Command.CommandType = VFS_COMMAND_END_ENUMERATE; + cmd.Command.SequenceNumber = 0; + cmd.Command.SessionId = SessionId; + + cmd.enumerateHandle = EnumHandle; + + retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, 0); + if (reply) + { + retCode = 0; + if (reply->Reply.ErrorCode) + { + retCode = -EIO; + } + Novfs_Free(reply); + } + + return( retCode ); +} + +/*++======================================================================*/ +int directory_enumerate( u_long *EnumHandle, PENTRY_INFO Info, session_t SessionId ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + ENUMERATE_DIRECTORY_REQUEST cmd; + PENUMERATE_DIRECTORY_REPLY reply=NULL; + u_long replylen=0; + int retCode; + + + cmd.Command.CommandType = VFS_COMMAND_ENUMERATE_DIRECTORY; + cmd.Command.SequenceNumber = 0; + cmd.Command.SessionId = SessionId; + + cmd.enumerateHandle = *EnumHandle; + cmd.pathLen = 0; + cmd.path[0] = '\0'; + + retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); + + if (reply) + { + /* + * The VFS_COMMAND_ENUMERATE_DIRECTORY call can return an + * error but there could still be valid data. + */ + if ( !reply->Reply.ErrorCode || + ( (replylen > sizeof(COMMAND_REPLY_HEADER)) && + (reply->nameLen > 0)) ) + { + Info->type = 3; + Info->mode = S_IRWXU; + + if (reply->mode & NW_ATTRIBUTE_DIRECTORY) + { + Info->mode |= S_IFDIR; + Info->mode |= S_IXUSR; + } + else + { + Info->mode |= S_IFREG; + } + + if (reply->mode & NW_ATTRIBUTE_READ_ONLY) + { + Info->mode &= ~(S_IWUSR); + } + + if (reply->mode & NW_ATTRIBUTE_EXECUTE) + { + Info->mode |= S_IXUSR; + } + + Info->uid = current->uid; + Info->gid = current->gid; + Info->size = reply->size; + Info->atime.tv_sec = reply->lastAccessTime; + Info->atime.tv_nsec = 0; + Info->mtime.tv_sec = reply->modifyTime; + Info->mtime.tv_nsec = 0; + Info->ctime.tv_sec = reply->createTime; + Info->ctime.tv_nsec = 0; + Info->namelength = reply->nameLen; + memcpy(Info->name, reply->name, reply->nameLen); + retCode = 0; + if (reply->Reply.ErrorCode) + { + retCode = -1; /* Eof of data */ + } + *EnumHandle = reply->enumerateHandle; + } + else + { + retCode = -ENODATA; + } + Novfs_Free(reply); + } + + return( retCode ); +} + +/*++======================================================================*/ +int directory_enumerate_ex( u_long *EnumHandle, session_t SessionId, int *Count, PENTRY_INFO *PInfo, int Interrupt) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + ENUMERATE_DIRECTORY_EX_REQUEST cmd; + PENUMERATE_DIRECTORY_EX_REPLY reply=NULL; + u_long replylen=0; + int retCode=0; + PENTRY_INFO info; + PENUMERATE_DIRECTORY_EX_DATA data; + int isize; + + if (PInfo) + { + *PInfo = NULL; + } + *Count = 0; + + cmd.Command.CommandType = VFS_COMMAND_ENUMERATE_DIRECTORY_EX; + cmd.Command.SequenceNumber = 0; + cmd.Command.SessionId = SessionId; + + cmd.enumerateHandle = *EnumHandle; + cmd.pathLen = 0; + cmd.path[0] = '\0'; + + retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, Interrupt); + + if (reply) + { + retCode = 0; + /* + * The VFS_COMMAND_ENUMERATE_DIRECTORY call can return an + * error but there could still be valid data. + */ + + if ( !reply->Reply.ErrorCode || + ( (replylen > sizeof(COMMAND_REPLY_HEADER)) && + (reply->enumCount > 0)) ) + { + DbgPrint("directory_enumerate_ex: isize=%d\n", replylen); + data = (PENUMERATE_DIRECTORY_EX_DATA)((char *)reply + sizeof(ENUMERATE_DIRECTORY_EX_REPLY)); + isize = replylen - + sizeof(PENUMERATE_DIRECTORY_EX_REPLY) - + reply->enumCount * (int)(&((PENUMERATE_DIRECTORY_EX_DATA)0)->name); + isize += (reply->enumCount * (int)(&((PENTRY_INFO)0)->name)); + + if (PInfo) + { + *PInfo = info = Novfs_Malloc(isize, GFP_KERNEL); + if ( *PInfo ) + { + DbgPrint("directory_enumerate_ex1: data=0x%p info=0x%p\n", data, info); + *Count = reply->enumCount; + do + { + DbgPrint("directory_enumerate_ex2: data=0x%p length=%d\n", data); + + info->type = 3; + info->mode = S_IRWXU; + + if (data->mode & NW_ATTRIBUTE_DIRECTORY) + { + info->mode |= S_IFDIR; + info->mode |= S_IXUSR; + } + else + { + info->mode |= S_IFREG; + } + + if (data->mode & NW_ATTRIBUTE_READ_ONLY) + { + info->mode &= ~(S_IWUSR); + } + + if (data->mode & NW_ATTRIBUTE_EXECUTE) + { + info->mode |= S_IXUSR; + } + + info->uid = current->euid; + info->gid = current->egid; + info->size = data->size; + info->atime.tv_sec = data->lastAccessTime; + info->atime.tv_nsec = 0; + info->mtime.tv_sec = data->modifyTime; + info->mtime.tv_nsec = 0; + info->ctime.tv_sec = data->createTime; + info->ctime.tv_nsec = 0; + info->namelength = data->nameLen; + memcpy(info->name, data->name, data->nameLen); + data = (PENUMERATE_DIRECTORY_EX_DATA)&data->name[data->nameLen]; + replylen = (int)((char *)&info->name[info->namelength] - (char *)info); + DbgPrint("directory_enumerate_ex3: info=0x%p\n", info); + mydump(replylen, info); + + info = (PENTRY_INFO)&info->name[info->namelength]; + + } while (--reply->enumCount); + } + } + + if (reply->Reply.ErrorCode) + { + retCode = -1; /* Eof of data */ + } + *EnumHandle = reply->enumerateHandle; + } + else + { + retCode = -ENODATA; + } + Novfs_Free(reply); + } + + return( retCode ); +} + +/*++======================================================================*/ +int Novfs_Get_Directory_List( u_char *Path, u_long *EnumHandle, PENTRY_INFO Info, session_t SessionId ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int retCode = -ENOENT; + + if ( -1 == *EnumHandle) + { + return( -ENODATA ); + } + + if ( 0 == *EnumHandle ) + { + retCode = begin_directory_enumerate(Path, strlen(Path), EnumHandle, SessionId); + } + + if ( *EnumHandle ) + { + retCode = directory_enumerate( EnumHandle, Info, SessionId ); + if (retCode) + { + end_directory_enumerate( *EnumHandle, SessionId ); + if ( -1 == retCode ) + { + retCode = 0; + *EnumHandle = -1; + } + } + } + return(retCode); +} + +/*++======================================================================*/ +int Novfs_Get_Directory_ListEx( u_char *Path, u_long *EnumHandle, int *Count, PENTRY_INFO *Info, session_t SessionId ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int retCode = -ENOENT; + + if (Count) *Count = 0; + if (Info) *Info = NULL; + + if ( -1 == *EnumHandle) + { + return( -ENODATA ); + } + + if ( 0 == *EnumHandle ) + { + retCode = begin_directory_enumerate(Path, strlen(Path), EnumHandle, SessionId); + } + + if ( *EnumHandle ) + { + retCode = directory_enumerate_ex( EnumHandle, SessionId, Count, Info, INTERRUPTIBLE ); + if (retCode) + { + end_directory_enumerate( *EnumHandle, SessionId ); + if ( -1 == retCode ) + { + retCode = 0; + *EnumHandle = -1; + } + } + } + return(retCode); +} + +/*++======================================================================*/ +int Novfs_Open_File( u_char *Path, int Flags, PENTRY_INFO Info, u_long *Handle, session_t SessionId ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + POPEN_FILE_REQUEST cmd; + POPEN_FILE_REPLY reply; + u_long replylen=0; + int retCode, cmdlen, pathlen; + + pathlen = strlen(Path); + + if (StripTrailingDots) + { + if ('.' == Path[pathlen-1]) pathlen--; + } + + *Handle = 0; + + cmdlen = (int)(&((POPEN_FILE_REQUEST)0)->path) + pathlen; + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_OPEN_FILE; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = SessionId; + + cmd->access = 0; + + if ( !(Flags & O_WRONLY) || (Flags & O_RDWR)) + { + cmd->access |= NWD_ACCESS_READ; + } + + if ((Flags & O_WRONLY) || (Flags & O_RDWR)) + { + cmd->access |= NWD_ACCESS_WRITE; + } + + switch (Flags & (O_CREAT | O_EXCL | O_TRUNC)) + { + case O_CREAT: + cmd->disp = NWD_DISP_OPEN_ALWAYS; + break; + + case O_CREAT | O_EXCL: + cmd->disp = NWD_DISP_CREATE_NEW; + break; + + case O_TRUNC: + cmd->disp = NWD_DISP_CREATE_ALWAYS; + break; + + case O_CREAT | O_TRUNC: + cmd->disp = NWD_DISP_CREATE_ALWAYS; + break; + + case O_CREAT | O_EXCL | O_TRUNC: + cmd->disp = NWD_DISP_CREATE_NEW; + break; + + default: + cmd->disp = NWD_DISP_OPEN_EXISTING; + break; + } + + cmd->mode = NWD_SHARE_READ | NWD_SHARE_WRITE | NWD_SHARE_DELETE; + + cmd->pathLen = pathlen; + memcpy(cmd->path, Path, pathlen); + + retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); + + if (reply) + { + if (reply->Reply.ErrorCode) + { + if( NWE_OBJECT_EXISTS == reply->Reply.ErrorCode) + { + retCode = -EEXIST; + } + else if( NWE_ACCESS_DENIED == reply->Reply.ErrorCode) + { + retCode = -EACCES; + } + else + { + retCode = -ENOENT; + } + } + else + { + *Handle = reply->handle; + retCode = 0; + } + Novfs_Free(reply); + } + Novfs_Free(cmd); + } + else + { + retCode = -ENOMEM; + } + return( retCode ); +} + +/*++======================================================================*/ +int Novfs_Create( u_char *Path, int DirectoryFlag, session_t SessionId ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + PCREATE_FILE_REQUEST cmd; + PCREATE_FILE_REPLY reply; + u_long replylen=0; + int retCode, cmdlen, pathlen; + + pathlen = strlen(Path); + + if (StripTrailingDots) + { + if ('.' == Path[pathlen-1]) pathlen--; + } + + cmdlen = (int)(&((PCREATE_FILE_REQUEST)0)->path) + pathlen; + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_CREATE_FILE; + if (DirectoryFlag) + { + cmd->Command.CommandType = VFS_COMMAND_CREATE_DIRECOTRY; + } + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = SessionId; + + cmd->pathlength = pathlen; + memcpy(cmd->path, Path, pathlen); + + retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); + + if (reply) + { + retCode = 0; + if (reply->Reply.ErrorCode) + { + retCode = -EIO; + } + Novfs_Free(reply); + } + Novfs_Free(cmd); + } + else + { + retCode = -ENOMEM; + } + return( retCode ); +} + +/*++======================================================================*/ +int Novfs_Close_File( u_long Handle, session_t SessionId ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + CLOSE_FILE_REQUEST cmd; + PCLOSE_FILE_REPLY reply; + u_long replylen=0; + int retCode; + + cmd.Command.CommandType = VFS_COMMAND_CLOSE_FILE; + cmd.Command.SequenceNumber = 0; + cmd.Command.SessionId = SessionId; + + cmd.handle = Handle; + + retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, 0); + if (reply) + { + retCode = 0; + if (reply->Reply.ErrorCode) + { + retCode = -EIO; + } + Novfs_Free(reply); + } + return( retCode ); +} +/*++======================================================================*/ +int Novfs_Read_File( u_long Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + READ_FILE_REQUEST cmd; + PREAD_FILE_REPLY reply=NULL; + u_long replylen=0; + int retCode = 0; + size_t len; + + len = *Bytes; + *Bytes = 0; + + if ( ((int)(&((PREAD_FILE_REPLY)0)->data) + len) > MaxIoSize) + { + len = MaxIoSize - (int)(&((PREAD_FILE_REPLY)0)->data); + len = (len/PAGE_SIZE)*PAGE_SIZE; + } + + cmd.Command.CommandType = VFS_COMMAND_READ_FILE; + cmd.Command.SequenceNumber = 0; + cmd.Command.SessionId = SessionId; + + cmd.handle = Handle; + cmd.len = len; + cmd.offset = *Offset; + + retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); + + DbgPrint("Novfs_Read_File: Queue_Daemon_Command 0x%x replylen=%d\n", retCode, replylen); + + if (!retCode) + { + if (reply->Reply.ErrorCode) + { + retCode = -EIO; + } + else + { + replylen -= (int)(&((PREAD_FILE_REPLY)0)->data); + if (replylen > 0) + { + replylen -= copy_to_user(Buffer, reply->data, replylen); + *Bytes = replylen; + } + } + } + + if ( reply ) + { + Novfs_Free(reply); + } + + DbgPrint("Novfs_Read_File *Bytes=0x%x retCode=0x%x\n", *Bytes, retCode); + + return( retCode ); +} + +/*++======================================================================*/ +int Novfs_Read_Pages( u_long Handle, PDATA_LIST DList, int DList_Cnt, size_t *Bytes, loff_t *Offset, session_t SessionId) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + READ_FILE_REQUEST cmd; + PREAD_FILE_REPLY reply=NULL; + READ_FILE_REPLY lreply; + u_long replylen=0; + int retCode = 0; + size_t len; + + len = *Bytes; + *Bytes = 0; + + DbgPrint("Novfs_Read_File_Pages: Handle=0x%x Dlst=0x%p Dlcnt=%d Bytes=%d Offset=%lld SessionId=0x%llx\n", + Handle, DList, DList_Cnt, len, *Offset, SessionId); + + cmd.Command.CommandType = VFS_COMMAND_READ_FILE; + cmd.Command.SequenceNumber = 0; + cmd.Command.SessionId = SessionId; + + cmd.handle = Handle; + cmd.len = len; + cmd.offset = *Offset; + + /* + * Dlst first entry is reserved for reply header. + */ + DList[0].page = NULL; + DList[0].offset = &lreply; + DList[0].len = (int)(&((PREAD_FILE_REPLY)0)->data); + DList[0].rwflag = DLWRITE; + + retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), DList, DList_Cnt, (void *)&reply, &replylen, INTERRUPTIBLE); + + DbgPrint("Novfs_Read_File_Pages: Queue_Daemon_Command 0x%x\n", retCode); + + if (!retCode) + { + if (reply) + { + memcpy(&lreply, reply, sizeof(lreply)); + } + + if (lreply.Reply.ErrorCode) + { + retCode = -EIO; + } + *Bytes = replylen - (int)(&((PREAD_FILE_REPLY)0)->data); + } + + if ( reply ) + { + Novfs_Free(reply); + } + + DbgPrint("Novfs_Read_File: retCode=0x%x\n", retCode); + + return( retCode ); +} + +/*++======================================================================*/ +int Novfs_Write_File( u_long Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + WRITE_FILE_REQUEST cmd; + PWRITE_FILE_REPLY reply=NULL; + unsigned long replylen=0; + int retCode=0, cmdlen; + size_t len; + + unsigned long boff; + struct page **pages; + DATA_LIST *dlist; + int res=0, npage, i; + WRITE_FILE_REPLY lreply; + + + len = *Bytes; + cmdlen = (int)(&((PWRITE_FILE_REQUEST)0)->data); + + *Bytes = 0; + + memset(&lreply, 0, sizeof(lreply)); + + DbgPrint("Novfs_Write_File cmdlen=%ld len=%ld\n", cmdlen, len); + + if ( (cmdlen+len) > MaxIoSize) + { + len = MaxIoSize-cmdlen; + len = (len/PAGE_SIZE)*PAGE_SIZE; + } + cmd.Command.CommandType = VFS_COMMAND_WRITE_FILE; + cmd.Command.SequenceNumber = 0; + cmd.Command.SessionId = SessionId; + cmd.handle = Handle; + cmd.len = len; + cmd.offset = *Offset; + + DbgPrint("Novfs_Write_File cmdlen=%ld len=%ld\n", cmdlen, len); + + npage = (((unsigned long)Buffer & ~PAGE_MASK) + len + (PAGE_SIZE-1)) >> PAGE_SHIFT; + + dlist = Novfs_Malloc(sizeof(DATA_LIST)*(npage+1), GFP_KERNEL); + if (NULL == dlist) + { + return(-ENOMEM); + } + + pages = Novfs_Malloc(sizeof(struct page *)*npage, GFP_KERNEL); + + if (NULL == pages) + { + Novfs_Free(dlist); + return(-ENOMEM); + } + + down_read(¤t->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(¤t->mm->mmap_sem); + + DbgPrint("Novfs_Write_File res=%d\n", res); + + if ( res > 0 ) + { + boff = (unsigned long)Buffer & ~PAGE_MASK; + + flush_dcache_page(pages[0]); + dlist[0].page = pages[0]; + dlist[0].offset = (char *)boff; + dlist[0].len = PAGE_SIZE - boff; + dlist[0].rwflag = DLREAD; + + if (dlist[0].len > len) + { + dlist[0].len = len; + } + + DbgPrint("Novfs_Write_File0: page=0x%x offset=0x%p len=%d\n", dlist[0].page, dlist[0].offset, dlist[0].len); + + boff = dlist[0].len; + + DbgPrint("Novfs_Write_File len=%d boff=%d\n", len, boff); + + for (i=1; (i < res) && (boff < len); i++) + { + flush_dcache_page(pages[i]); + + dlist[i].page = pages[i]; + dlist[i].offset = NULL; + dlist[i].len = len-boff; + if (dlist[i].len > PAGE_SIZE) + { + dlist[i].len = PAGE_SIZE; + } + dlist[i].rwflag = DLREAD; + + boff += dlist[i].len; + DbgPrint("Novfs_Write_File%d: page=0x%x offset=0x%p len=%d\n", i, dlist[i].page, dlist[i].offset, dlist[i].len); + } + + dlist[i].page = NULL; + dlist[i].offset = &lreply; + dlist[i].len = sizeof(lreply); + dlist[i].rwflag = DLWRITE; + res++; + + DbgPrint("Novfs_Write_File Buffer=0x%x boff=0x%x len=%d\n", Buffer, boff, len); + + retCode = Queue_Daemon_Command(&cmd, cmdlen, dlist, res, (void *)&reply, &replylen, INTERRUPTIBLE); + + } + else + { + char *kdata; + + res = 0; + + kdata = Novfs_Malloc(len, GFP_KERNEL); + if (kdata) + { + len -= copy_from_user(kdata, Buffer, len); + dlist[0].page = NULL; + dlist[0].offset = kdata; + dlist[0].len = len; + dlist[0].rwflag = DLREAD; + + dlist[1].page = NULL; + dlist[1].offset = &lreply; + dlist[1].len = sizeof(lreply); + dlist[1].rwflag = DLWRITE; + + retCode = Queue_Daemon_Command(&cmd, cmdlen, dlist, 2, (void *)&reply, &replylen, INTERRUPTIBLE); + + Novfs_Free(kdata); + } + } + + DbgPrint("Novfs_Write_File retCode=0x%x reply=0x%x\n", retCode, reply); + + if ( !retCode ) + { + switch (lreply.Reply.ErrorCode) + { + case 0: + *Bytes = (size_t)lreply.bytesWritten; + retCode = 0; + break; + + case NWE_INSUFFICIENT_SPACE: + retCode = -ENOSPC; + break; + + case NWE_ACCESS_DENIED: + retCode = -EACCES; + break; + + default: + retCode = -EIO; + break; + } + } + + if ( res ) + { + for (i=0; idata); + + if (len) + { + cmd.Command.CommandType = VFS_COMMAND_WRITE_FILE; + cmd.Command.SequenceNumber = 0; + cmd.Command.SessionId = SessionId; + + cmd.handle = Handle; + cmd.len = len; + cmd.offset = Offset; + + retCode = Queue_Daemon_Command(&cmd, cmdlen, DList, DList_Cnt, (void *)&reply, &replylen, INTERRUPTIBLE); + if (!retCode) + { + if (reply) + { + memcpy(&lreply, reply, sizeof(lreply)); + } + switch (lreply.Reply.ErrorCode) + { + case 0: + retCode = 0; + break; + + case NWE_INSUFFICIENT_SPACE: + retCode = -ENOSPC; + break; + + case NWE_ACCESS_DENIED: + retCode = -EACCES; + break; + + default: + retCode = -EIO; + break; + } + } + if ( reply ) + { + Novfs_Free(reply); + } + } + DbgPrint("Novfs_Write_Pages retCode=0x%x\n", retCode); + + return( retCode ); +} + +/*++======================================================================*/ +int Novfs_Read_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, int User, session_t SessionId) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + READ_STREAM_REQUEST cmd; + PREAD_STREAM_REPLY reply=NULL; + u_long replylen=0; + int retCode = 0; + size_t len; + + len = *Bytes; + *Bytes = 0; + + if ( ((int)(&((PREAD_FILE_REPLY)0)->data) + len) > MaxIoSize) + { + len = MaxIoSize - (int)(&((PREAD_FILE_REPLY)0)->data); + len = (len/PAGE_SIZE)*PAGE_SIZE; + } + + cmd.Command.CommandType = VFS_COMMAND_READ_STREAM; + cmd.Command.SequenceNumber = 0; + cmd.Command.SessionId = SessionId; + + cmd.connection = ConnHandle; + memcpy( cmd.handle, Handle, sizeof(cmd.handle)); + cmd.len = len; + cmd.offset = *Offset; + + retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); + + DbgPrint("Novfs_Read_Stream: Queue_Daemon_Command 0x%x replylen=%d\n", retCode, replylen); + + if ( reply ) + { + retCode = 0; + if (reply->Reply.ErrorCode) + { + retCode = -EIO; + } + else + { + replylen -= (int)(&((PREAD_STREAM_REPLY)0)->data); + if (replylen > 0) + { + if (User) + { + replylen -= copy_to_user(Buffer, reply->data, replylen); + } + else + { + memcpy(Buffer, reply->data, replylen); + } + + *Bytes = replylen; + } + } + Novfs_Free(reply); + } + + DbgPrint("Novfs_Read_Stream *Bytes=0x%x retCode=0x%x\n", *Bytes, retCode); + + return( retCode ); +} + +/*++======================================================================*/ +int Novfs_Write_Stream( u_long ConnHandle, u_char *Handle, u_char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + PWRITE_STREAM_REQUEST cmd; + PWRITE_STREAM_REPLY reply=NULL; + u_long replylen=0; + int retCode=0, cmdlen; + size_t len; + + len = *Bytes; + cmdlen = len+(int)(&((PWRITE_STREAM_REQUEST)0)->data); + *Bytes = 0; + + if (cmdlen > MaxIoSize) + { + cmdlen = MaxIoSize; + len = cmdlen - (int)(&((PWRITE_STREAM_REQUEST)0)->data); + } + + DbgPrint("Novfs_Write_Stream cmdlen=%d len=%d\n", cmdlen, len); + + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + + if (cmd) + { + if (Buffer && len) + { + len -= copy_from_user(cmd->data, Buffer, len); + } + + DbgPrint("Novfs_Write_Stream len=%d\n", len); + + cmd->Command.CommandType = VFS_COMMAND_WRITE_STREAM; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = SessionId; + + cmd->connection = ConnHandle; + memcpy(cmd->handle, Handle, sizeof(cmd->handle)); + cmd->len = len; + cmd->offset = *Offset; + + retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + switch (reply->Reply.ErrorCode) + { + case 0: + retCode = 0; + break; + + case NWE_INSUFFICIENT_SPACE: + retCode = -ENOSPC; + break; + + case NWE_ACCESS_DENIED: + retCode = -EACCES; + break; + + default: + retCode = -EIO; + break; + } + DbgPrint("Novfs_Write_Stream reply->bytesWritten=0x%lx\n", reply->bytesWritten); + *Bytes = reply->bytesWritten; + Novfs_Free(reply); + } + Novfs_Free(cmd); + } + DbgPrint("Novfs_Write_Stream *Bytes=0x%x retCode=0x%x\n", *Bytes, retCode); + + return( retCode ); +} + +/*++======================================================================*/ +int Novfs_Close_Stream( u_long ConnHandle, u_char *Handle, session_t SessionId ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + CLOSE_STREAM_REQUEST cmd; + PCLOSE_STREAM_REPLY reply; + u_long replylen=0; + int retCode; + + cmd.Command.CommandType = VFS_COMMAND_CLOSE_STREAM; + cmd.Command.SequenceNumber = 0; + cmd.Command.SessionId = SessionId; + + cmd.connection = ConnHandle; + memcpy(cmd.handle, Handle, sizeof(cmd.handle)); + + retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, 0); + if (reply) + { + retCode = 0; + if (reply->Reply.ErrorCode) + { + retCode = -EIO; + } + Novfs_Free(reply); + } + return( retCode ); +} + +/*++======================================================================*/ +int Novfs_Delete( u_char *Path, int DirectoryFlag, session_t SessionId ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + PDELETE_FILE_REQUEST cmd; + PDELETE_FILE_REPLY reply; + u_long replylen=0; + int retCode, cmdlen, pathlen; + + pathlen = strlen(Path); + + if (StripTrailingDots) + { + if ('.' == Path[pathlen-1]) pathlen--; + } + + cmdlen = (int)(&((PDELETE_FILE_REQUEST)0)->path) + pathlen; + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_DELETE_FILE; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = SessionId; + + cmd->isDirectory = DirectoryFlag; + cmd->pathlength = pathlen; + memcpy(cmd->path, Path, pathlen); + + retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + retCode = 0; + if (reply->Reply.ErrorCode) + { + if ((reply->Reply.ErrorCode & 0xFFFF) == 0x0006) /* Access Denied Error */ + { + retCode = -EACCES; + } + else + { + retCode = -EIO; + } + } + Novfs_Free(reply); + } + Novfs_Free(cmd); + } + else + { + retCode = -ENOMEM; + } + return( retCode ); +} + +/*++======================================================================*/ +int Novfs_Truncate_File( u_char *Path, int PathLen, session_t SessionId ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + PTRUNCATE_FILE_REQUEST cmd; + PTRUNCATE_FILE_REPLY reply; + u_long replylen=0; + int retCode, cmdlen; + + if (StripTrailingDots) + { + if ('.' == Path[PathLen-1]) PathLen--; + } + cmdlen = (int)(&((PTRUNCATE_FILE_REQUEST)0)->path) + PathLen; + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_TRUNCATE_FILE; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = SessionId; + + cmd->pathLen = PathLen; + memcpy(cmd->path, Path, PathLen); + + retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + if (reply->Reply.ErrorCode) + { + retCode = -EIO; + } + Novfs_Free(reply); + } + Novfs_Free(cmd); + } + else + { + retCode = -ENOMEM; + } + return( retCode ); +} + +/*++======================================================================*/ +int Novfs_Rename_File( int DirectoryFlag, u_char *OldName, int OldLen, u_char *NewName, int NewLen, session_t SessionId ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + RENAME_FILE_REQUEST cmd; + PRENAME_FILE_REPLY reply; + u_long replylen=0; + int retCode; + + DbgPrint("Novfs_Rename_File:\n" \ + " DirectoryFlag: %d\n" \ + " OldName: %.*s\n" \ + " NewName: %.*s\n" \ + " SessionId: 0x%llx\n", + DirectoryFlag, + OldLen, OldName, + NewLen, NewName, + SessionId ); + + cmd.Command.CommandType = VFS_COMMAND_RENAME_FILE; + cmd.Command.SequenceNumber = 0; + cmd.Command.SessionId = SessionId; + + cmd.directoryFlag = DirectoryFlag; + + if (StripTrailingDots) + { + if ('.' == OldName[OldLen-1]) OldLen--; + if ('.' == NewName[NewLen-1]) NewLen--; + } + + cmd.newnameLen = NewLen; + memcpy(cmd.newname, NewName, NewLen); + + cmd.oldnameLen = OldLen; + memcpy(cmd.oldname, OldName, OldLen); + + retCode = Queue_Daemon_Command(&cmd, sizeof(cmd), NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + retCode = 0; + if (reply->Reply.ErrorCode) + { + retCode = -ENOENT; + } + Novfs_Free(reply); + } + return( retCode ); +} + +/*++======================================================================*/ +int Novfs_Set_Attr( u_char *Path, struct iattr *Attr, session_t SessionId ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + PSET_FILE_INFO_REQUEST cmd; + PSET_FILE_INFO_REPLY reply; + u_long replylen=0; + int retCode, cmdlen, pathlen; + + pathlen = strlen(Path); + + if (StripTrailingDots) + { + if ('.' == Path[pathlen-1]) pathlen--; + } + + cmdlen = (int)(&((PSET_FILE_INFO_REQUEST)0)->path) + pathlen; + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_SET_FILE_INFO; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = SessionId; + cmd->fileInfo.ia_valid = Attr->ia_valid; + cmd->fileInfo.ia_mode = Attr->ia_mode; + cmd->fileInfo.ia_uid = Attr->ia_uid; + cmd->fileInfo.ia_gid = Attr->ia_uid; + cmd->fileInfo.ia_size = Attr->ia_size; + cmd->fileInfo.ia_atime = Attr->ia_atime.tv_sec; + cmd->fileInfo.ia_mtime = Attr->ia_mtime.tv_sec;; + cmd->fileInfo.ia_ctime = Attr->ia_ctime.tv_sec;; +/* + cmd->fileInfo.ia_attr_flags = Attr->ia_attr_flags; +*/ + cmd->fileInfo.ia_attr_flags = 0; + + cmd->pathlength = pathlen; + memcpy(cmd->path, Path, pathlen); + + retCode = Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + switch( reply->Reply.ErrorCode ) + { + case 0: + retCode = 0; + break; + + case NWE_PARAM_INVALID: + retCode = -EINVAL; + break; + + default: + retCode = -EIO; + break; + } + Novfs_Free(reply); + } + Novfs_Free(cmd); + } + else + { + retCode = -ENOMEM; + } + return( retCode ); +} + +/*++======================================================================*/ +int Novfs_Get_File_Cache_Flag( u_char *Path, session_t SessionId ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + PGET_CACHE_FLAG_REQUEST cmd; + PGET_CACHE_FLAG_REPLY reply=NULL; + u_long replylen=0; + int cmdlen; + int retCode = 0; + int pathlen; + + DbgPrint("Novfs_Get_File_Cache_Flag: Path = %s\n", Path); + + if (Path && *Path) + { + pathlen = strlen(Path); + if (StripTrailingDots) + { + if ('.' == Path[pathlen-1]) pathlen--; + } + cmdlen = (int)(&((PGET_CACHE_FLAG_REQUEST)0)->path) + pathlen; + cmd = (PGET_CACHE_FLAG_REQUEST)Novfs_Malloc(cmdlen, GFP_KERNEL); + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_GET_CACHE_FLAG; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = SessionId; + cmd->pathLen = pathlen; + memcpy(cmd->path, Path, cmd->pathLen); + + Queue_Daemon_Command(cmd, cmdlen, NULL, 0, (void *)&reply, &replylen, INTERRUPTIBLE); + + if (reply) + { + + if ( !reply->Reply.ErrorCode ) + { + retCode = reply->CacheFlag; + } + + Novfs_Free(reply); + } + Novfs_Free(cmd); + } + } + + DbgPrint("Novfs_Get_File_Cache_Flag: return %d\n", retCode); + return(retCode); +} diff -uNr src.old/src/inode.c src/src/inode.c --- src.old/src/inode.c 1970-01-01 01:00:00.000000000 +0100 +++ src/src/inode.c 2006-10-16 15:08:22.000000000 +0200 @@ -0,0 +1,5236 @@ +/*++======================================================================== + * Program Name: Novell NCP Redirector for Linux + * File Name: inode.c + * Version: v1.00 + * Author: James Turner + * + * Abstract: This module contains functions used to control + * access to the Linux file system. + * Notes: + * Revision History: + * + * + * Copyright (C) 2005 Novell, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *======================================================================--*/ + +/*===[ Include files specific to Linux ]==================================*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*===[ Include files specific to this module ]============================*/ +#include "vfs.h" + +/*===[ External data ]====================================================*/ +extern int MaxIoSize; + +/*===[ External prototypes ]==============================================*/ +extern int DbgPrint( char *Fmt, ... ); +extern int LocalPrint( char *Fmt, ... ); + +extern int Init_Procfs_Interface( void ); +extern void Uninit_Procfs_Interface( void ); +extern void mydump(int size, void *dumpptr); + +/* + * Daemon.c functions + */ +extern void Init_Daemon_Queue( void ); +extern void Uninit_Daemon_Queue( void ); +extern int do_logout( struct qstr *Server ); +extern int Daemon_SetMountPoint( char *Path ); + +/* + * file.c functions + */ +extern int Novfs_verify_file( struct qstr *Path, session_t SessionId ); +extern int Novfs_get_alltrees(struct dentry *parent); +extern int Novfs_Get_Connected_Server_List( unsigned char **ServerList, session_t SessionId ); +extern int Novfs_Get_Server_Volume_List( struct qstr *Server, unsigned char **VolumeList, session_t SessionId ); +extern int Novfs_Verify_Server_Name( struct qstr *Server, session_t SessionId ); +extern int Novfs_Verify_Volume_Name( struct qstr *Server, struct qstr *Volume, session_t SessionId ); +extern int Novfs_Get_File_Info( unsigned char *Path, PENTRY_INFO Info, session_t SessionId ); +extern int Novfs_Get_Directory_List( unsigned char *Path, unsigned long *EnumHandle, PENTRY_INFO Info, session_t SessionId ); +extern int Novfs_Get_Directory_ListEx( unsigned char *Path, unsigned long *EnumHandle, int *Count, PENTRY_INFO *Info, session_t SessionId ); +extern int Novfs_Open_File( unsigned char *Path, int Flags, PENTRY_INFO Info, unsigned long *Handle, session_t SessionId ); +extern int Novfs_Create( unsigned char *Path, int DirectoryFlag, session_t SessionId ); +extern int Novfs_Close_File( unsigned long Handle, session_t SessionId ); +extern int Novfs_Read_File( unsigned long Handle, unsigned char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId); +extern int Novfs_Read_Pages( u_long Handle, PDATA_LIST DList, int DList_Cnt, size_t *Bytes, loff_t *Offset, session_t SessionId); +extern int Novfs_Write_File( unsigned long Handle, unsigned char *Buffer, size_t *Bytes, loff_t *Offset, session_t SessionId); +extern int Novfs_Write_Pages( unsigned long Handle, PDATA_LIST DList, int DList_Cnt, size_t Bytes, loff_t Offset, session_t SessionId); +extern int Novfs_Delete( unsigned char *Path, int DirectoryFlag, session_t SessionId ); +extern int Novfs_Truncate_File( unsigned char *Path, int PathLen, session_t SessionId ); +extern int Novfs_Rename_File( int DirectoryFlag, unsigned char *OldName, int OldLen, unsigned char *NewName, int NewLen, session_t SessionId ); +extern int Novfs_Set_Attr( unsigned char *Path, struct iattr *Attr, session_t SessionId ); +extern int Novfs_Get_File_Cache_Flag( u_char *Path, session_t SessionId ); + +/* + * scope.c functions + */ +extern void Scope_Init( void ); +extern void Scope_Uninit( void ); +extern void *Scope_Lookup( void ); +extern unsigned long Scope_Get_Hash( void *); +extern uid_t Scope_Get_Uid( void *); +extern session_t Scope_Get_SessionId( void *Scope ); +extern void *Scope_Get_ScopefromName( struct qstr *Name ); +extern void *Scope_Get_ScopefromPath( struct dentry *Dentry ); +extern char *Scope_Get_ScopeUsers( void ); +extern int Scope_Set_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties ); +extern int Scope_Get_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties ); +extern char *Scope_dget_path( struct dentry *Dentry, char *Buf, unsigned int Buflen, int Flags); + +/* + * profile.c functions + */ +extern int init_profile( void ); +extern void uninit_profile( void ); + +/*===[ Manifest constants ]===============================================*/ +#define FILE_UPDATE_TIMEOUT 2 + +/*===[ Type definitions ]=================================================*/ + +/*===[ Function prototypes ]==============================================*/ +int Novfs_Remove_from_Root(char *RemoveName); +int Novfs_Add_to_Root(char *); +char *Novfs_dget_path( struct dentry *d, char *path, unsigned int pathlen ); +int verify_dentry(struct dentry *dentry, int Flags); +int invalidate_dentry(struct dentry *parent); +struct dentry *Novfs_d_lookup(struct dentry *Parent, struct qstr *Name); +int Novfs_d_add(struct dentry *p, struct dentry *d, struct inode *i, int add); +int Novfs_d_strcmp (struct qstr *s1, struct qstr *s2); +struct inode *Novfs_get_inode(struct super_block *sb, int mode, int dev, uid_t uid, ino_t ino, struct qstr *name); +unsigned long Novfs_internal_hash (struct qstr *name); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) + int Novfs_get_sb(struct file_system_type *Fstype, int Flags, const char *Dev_name, void *Data, struct vfsmount *Mnt); +#else + struct super_block * Novfs_get_sb(struct file_system_type *Fstype, int Flags, const char *Dev_name, void *Data); +#endif + +void Novfs_kill_sb(struct super_block *SB); +int Novfs_fill_super (struct super_block *SB, void *Data, int Silent); + +/* + * Declared dentry_operations + */ +int Novfs_d_revalidate(struct dentry *, struct nameidata *); +int Novfs_d_hash (struct dentry *, struct qstr *); +int Novfs_d_compare (struct dentry *, struct qstr *, struct qstr *); +int Novfs_d_delete(struct dentry *dentry); +void Novfs_d_release(struct dentry *dentry); +void Novfs_d_iput(struct dentry *dentry, struct inode *inode); + +/* + * Declared directory operations + */ +int Novfs_dir_open(struct inode *inode, struct file *file); +int Novfs_dir_release(struct inode *inode, struct file *file); +loff_t Novfs_dir_lseek(struct file *file, loff_t offset, int origin); +int Novfs_dir_read(struct file *file, char *buf, size_t len, loff_t *off); +void addtodentry( struct dentry *Parent, unsigned char *List, int Level ); +int Novfs_filldir(void *data, const char *name, int namelen, loff_t off, ino_t ino, unsigned ftype); +int Novfs_dir_readdir(struct file * filp, void * dirent, filldir_t filldir); +int Novfs_dir_fsync(struct file * file, struct dentry *dentry, int datasync); + +/* + * Declared address space operations + */ +int Novfs_a_writepage(struct page* page, struct writeback_control *wbc); +int Novfs_a_writepages(struct address_space *mapping, struct writeback_control *wbc); +int Novfs_a_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to); +int Novfs_a_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to); +int Novfs_a_readpage(struct file *file, struct page *page); +int Novfs_a_readpages(struct file *file, struct address_space *mapping, struct list_head *page_lst, unsigned nr_pages); +ssize_t Novfs_a_direct_IO(int rw, struct kiocb *kiocb, + const struct iovec *iov, + loff_t offset, + unsigned long nr_segs); + +/* + * Declared file_operations + */ +ssize_t Novfs_f_read(struct file *, char *, size_t, loff_t *); +ssize_t Novfs_f_write(struct file *, const char *, size_t, loff_t *); +int Novfs_f_readdir(struct file *, void *, filldir_t); +int Novfs_f_ioctl(struct inode *, struct file *, unsigned int, unsigned long); +int Novfs_f_mmap(struct file * file, struct vm_area_struct * vma); +int Novfs_f_open(struct inode *, struct file *); +int Novfs_f_flush(struct file *); +int Novfs_f_release(struct inode *, struct file *); +int Novfs_f_fsync(struct file *, struct dentry *, int datasync); +int Novfs_f_lock(struct file *, int, struct file_lock *); + +/* + * Declared inode_operations + */ +int Novfs_i_create(struct inode *,struct dentry *,int, struct nameidata *); +struct dentry * Novfs_i_lookup(struct inode *,struct dentry *, struct nameidata *); +int Novfs_i_mkdir(struct inode *,struct dentry *,int); +int Novfs_i_unlink(struct inode *dir, struct dentry *dentry); +int Novfs_i_rmdir(struct inode *,struct dentry *); +int Novfs_i_mknod(struct inode *,struct dentry *,int,dev_t); +int Novfs_i_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); +int Novfs_i_permission(struct inode *inode, int mask); +int Novfs_i_setattr(struct dentry *, struct iattr *); +int Novfs_i_getattr(struct vfsmount *mnt, struct dentry *, struct kstat *); +int Novfs_i_revalidate(struct dentry *dentry); + +void update_inode(struct inode *Inode, PENTRY_INFO Info); + +/* + * Declared super_operations + */ +void Novfs_read_inode(struct inode *inode); +void Novfs_write_inode(struct inode *inode); +int Novfs_notify_change(struct dentry *dentry, struct iattr *attr); +void Novfs_clear_inode(struct inode *inode); +int Novfs_show_options( struct seq_file *s, struct vfsmount *m ); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) + int Novfs_statfs(struct dentry *de, struct kstatfs *buf); +#else + int Novfs_statfs(struct super_block *sb, struct kstatfs *buf); +#endif + +/* + * Declared control interface functions + */ +ssize_t +Novfs_Control_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos); + +ssize_t +Novfs_Control_write(struct file * file, const char * buf, size_t nbytes, loff_t *ppos); + +int Novfs_Control_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); + +int __init init_novfs(void); +void __exit exit_novfs(void); + +int Novfs_lock_inode_cache( struct inode *i ); +void Novfs_unlock_inode_cache( struct inode *i ); +int Novfs_enumerate_inode_cache( struct inode *i, struct list_head **iteration, ino_t *ino, PENTRY_INFO info); +int Novfs_get_entry( struct inode *i, struct qstr *name, ino_t *ino, PENTRY_INFO info); +int Novfs_get_entry_by_pos( struct inode *i, loff_t pos, ino_t *ino, PENTRY_INFO info); +int Novfs_get_entry_time( struct inode *i, struct qstr *name, ino_t *ino, PENTRY_INFO info, u64 *EntryTime); +int Novfs_get_remove_entry( struct inode *i, ino_t *ino, PENTRY_INFO info); +void Novfs_invalidate_inode_cache( struct inode *i ); +PDIR_CACHE Novfs_lookup_inode_cache( struct inode *i, struct qstr *name, ino_t ino ); +int Novfs_lookup_validate( struct inode *i, struct qstr *name, ino_t ino ); +int Novfs_add_inode_entry( struct inode *i, struct qstr *name, ino_t ino, PENTRY_INFO info); +int Novfs_update_entry( struct inode *i, struct qstr *name, ino_t ino, PENTRY_INFO info); +void Novfs_remove_inode_entry( struct inode *i, struct qstr *name, ino_t ino); +void Novfs_free_invalid_entries( struct inode *i ); +void Novfs_free_inode_cache( struct inode *i ); + +/*===[ Global variables ]=================================================*/ +struct dentry_operations Novfs_dentry_operations = { + .d_revalidate = Novfs_d_revalidate, + .d_hash = Novfs_d_hash, + .d_compare = Novfs_d_compare, + .d_delete = Novfs_d_delete, + .d_release = Novfs_d_release, + .d_iput = Novfs_d_iput, +}; + +struct file_operations Novfs_dir_operations = { + .owner = THIS_MODULE, + .open = Novfs_dir_open, + .release = Novfs_dir_release, + .llseek = Novfs_dir_lseek, + .read = Novfs_dir_read, + .readdir = Novfs_dir_readdir, + .fsync = Novfs_dir_fsync, +}; + +static struct file_operations Novfs_file_operations = { + .owner = THIS_MODULE, + .read = Novfs_f_read, + .write = Novfs_f_write, + .readdir = Novfs_f_readdir, + .ioctl = Novfs_f_ioctl, + .mmap = Novfs_f_mmap, + .open = Novfs_f_open, + .flush = Novfs_f_flush, + .release = Novfs_f_release, + .fsync = Novfs_f_fsync, + .llseek = generic_file_llseek, +}; + +static struct address_space_operations Novfs_aops = { + .readpage = Novfs_a_readpage, + .readpages = Novfs_a_readpages, + .writepage = Novfs_a_writepage, + .writepages = Novfs_a_writepages, + .prepare_write = Novfs_a_prepare_write, + .commit_write = Novfs_a_commit_write, + .set_page_dirty = __set_page_dirty_nobuffers, + .direct_IO = Novfs_a_direct_IO, +}; + +static struct inode_operations Novfs_inode_operations = { + .create = Novfs_i_create, + .lookup = Novfs_i_lookup, + .unlink = Novfs_i_unlink, + .mkdir = Novfs_i_mkdir, + .rmdir = Novfs_i_rmdir, + .mknod = Novfs_i_mknod, + .rename = Novfs_i_rename, + .setattr = Novfs_i_setattr, + .getattr = Novfs_i_getattr, +}; + +static struct inode_operations Novfs_file_inode_operations = { + .setattr = Novfs_i_setattr, + .getattr = Novfs_i_getattr, +}; + +static struct super_operations Novfs_ops = { + .read_inode = Novfs_read_inode, + .statfs = Novfs_statfs, + .clear_inode = Novfs_clear_inode, + .drop_inode = generic_delete_inode, + .show_options = Novfs_show_options, + +}; + +/* Not currently used +static struct file_operations Novfs_Control_operations = { + .read = Novfs_Control_read, + .write = Novfs_Control_write, + .ioctl = Novfs_Control_ioctl, +}; +*/ + +ino_t Novfs_Inode_Number=1; + +static struct file_system_type Novfs_fs_type = { + .name = "novfs", + .get_sb = Novfs_get_sb, + .kill_sb = Novfs_kill_sb, + .owner = THIS_MODULE, +}; + +struct dentry *Novfs_root=NULL; + +int Novfs_Version_Major=NOVFS_VFS_MAJOR; +int Novfs_Version_Minor=NOVFS_VFS_MINOR; +int Novfs_Version_Sub=NOVFS_VFS_SUB; +int Novfs_Version_Release=NOVFS_VFS_RELEASE; + +char *Novfs_CurrentMount=NULL; + +DECLARE_MUTEX(InodeList_lock); + +LIST_HEAD(InodeList); + +unsigned long InodeCount=0, DCCount=0; +unsigned long File_update_timeout=FILE_UPDATE_TIMEOUT; +int PageCache=1; + +/*===[ Code ]=============================================================*/ +static __inline__ void PRINT_DENTRY(const char *s, struct dentry *d) +{ + DbgPrint("%s: 0x%x\n", s, d); + DbgPrint(" d_count: 0x%x\n", d->d_count); + DbgPrint(" d_lock: 0x%x\n", d->d_lock); + DbgPrint(" d_inode: 0x%x\n", d->d_inode); + DbgPrint(" d_lru: 0x%x\n" \ + " next: 0x%x\n" \ + " prev: 0x%x\n", &d->d_lru, d->d_lru.next, d->d_lru.prev); + DbgPrint(" d_child: 0x%x\n" \ + " next: 0x%x\n" \ + " prev: 0x%x\n", &d->D_CHILD, d->D_CHILD.next, d->D_CHILD.prev); + DbgPrint(" d_subdirs: 0x%x\n" \ + " next: 0x%x\n" \ + " prev: 0x%x\n", &d->d_subdirs, d->d_subdirs.next, d->d_subdirs.prev); + DbgPrint(" d_alias: 0x%x\n" \ + " next: 0x%x\n" \ + " prev: 0x%x\n", &d->d_alias, d->d_alias.next, d->d_alias.prev); + DbgPrint(" d_time: 0x%x\n", d->d_time); + DbgPrint(" d_op: 0x%x\n", d->d_op); + DbgPrint(" d_sb: 0x%x\n", d->d_sb); + DbgPrint(" d_flags: 0x%x\n", d->d_flags); + DbgPrint(" d_mounted: 0x%x\n", d->d_mounted); + DbgPrint(" d_fsdata: 0x%x\n", d->d_fsdata); +/* DbgPrint(" d_cookie: 0x%x\n", d->d_cookie); */ + DbgPrint(" d_parent: 0x%x\n", d->d_parent); + DbgPrint(" d_name: 0x%x %.*s\n", &d->d_name, d->d_name.len, d->d_name.name); + DbgPrint(" name: 0x%x\n" \ + " len: %d\n" \ + " hash: 0x%x\n", d->d_name.name, d->d_name.len, d->d_name.hash); + DbgPrint(" d_hash: 0x%x\n" \ + " next: 0x%x\n" \ + " pprev: 0x%x\n", d->d_hash, d->d_hash.next, d->d_hash.pprev); +} + +/*++======================================================================*/ +int Novfs_Remove_from_Root(char *RemoveName) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + struct qstr name; + struct dentry *dentry; + struct inode *dir; + + DbgPrint( "Novfs_Remove_from_Root: %s\n", RemoveName); + name.len = strlen(RemoveName); + name.name = RemoveName; + Novfs_d_hash(Novfs_root, &name); + + dentry = d_lookup( Novfs_root, &name); + if (dentry) + { + if (dentry->d_inode && dentry->d_inode->u.generic_ip) + { + ((PINODE_DATA)(dentry->d_inode->u.generic_ip))->Scope = NULL; + } + dput(dentry); + } + + + dir = Novfs_root->d_inode; + + Novfs_lock_inode_cache( dir ); + Novfs_remove_inode_entry( dir, &name, 0); + Novfs_unlock_inode_cache( dir ); + + return(0); +} + +/*++======================================================================*/ +int Novfs_Add_to_Root(char *AddName) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + struct qstr name; + struct inode *dir; + ENTRY_INFO info; + ino_t ino; + + DbgPrint( "Novfs_Add_to_Root: %s\n", AddName); + name.len = strlen(AddName); + name.name = AddName; + Novfs_d_hash(Novfs_root, &name); + + dir = Novfs_root->d_inode; + + Novfs_lock_inode_cache( dir ); + + ino = 0; + + if ( !Novfs_lookup_inode_cache(dir, &name, 0)) + { + info.mode = S_IFDIR | 0700; + info.size = 0; + info.atime = info.ctime = info.mtime = CURRENT_TIME; + + ino = (ino_t)InterlockedIncrement(&Novfs_Inode_Number); + Novfs_add_inode_entry( dir, &name, ino, &info); + } + + Novfs_unlock_inode_cache( dir ); + + return(0); +} + +/*++======================================================================*/ +int Novfs_Add_to_Root2(char *AddName) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + struct dentry *entry; + struct qstr name; + struct inode *inode; + void *scope; + + DbgPrint( "Novfs_Add_to_Root: %s\n", AddName); + name.len = strlen(AddName); + name.name = AddName; + + Novfs_d_hash(Novfs_root, &name); + + entry = Novfs_d_lookup(Novfs_root, &name); + DbgPrint( "Novfs_Add_to_Root: Novfs_d_lookup 0x%x\n", entry); + if ( NULL == entry ) + { + scope = Scope_Lookup(); + + entry = d_alloc(Novfs_root, &name); + DbgPrint( "Novfs_Add_to_Root: d_alloc 0x%x\n", entry ); + if (entry) + { + entry->d_op = &Novfs_dentry_operations; + entry->d_time = jiffies+(File_update_timeout*HZ); + /* + * done in Novfs_d_add now... entry->d_fsdata = (void *)Novfs_internal_hash( &name ); + */ + inode = Novfs_get_inode(Novfs_root->d_sb, S_IFDIR | 0700, 0, Scope_Get_Uid(scope), 0, &name); + DbgPrint( "Novfs_Add_to_Root: Inode=0x%x\n", inode); + if (inode) + { + inode->i_atime = + inode->i_ctime = + inode->i_mtime = CURRENT_TIME; + if ( !Novfs_d_add(Novfs_root, entry, inode, 1)) + { + if (inode->u.generic_ip) + { + ((PINODE_DATA)inode->u.generic_ip)->Flags = USER_INODE; + } + PRINT_DENTRY("After Novfs_d_add", entry); + } + else + { + dput(entry); + iput(inode); + } + } + } + } + else + { + dput(entry); + PRINT_DENTRY("Novfs_Add_to_Root: After dput Dentry", entry); + } + return(0); +} + +/*++======================================================================*/ +char *Novfs_dget_path( struct dentry *Dentry, char *Buf, unsigned int Buflen) +/* + * Arguments: struct dentry *Dentry - starting entry + * char *Buf - pointer to memory buffer + * unsigned int Buflen - size of memory buffer + * + * Returns: pointer to path. + * + * Abstract: Walks the dentry chain building a path. + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + char *retval=&Buf[Buflen]; + struct dentry *p=Dentry; + + *(--retval) = '\0'; + Buflen--; + + if (!IS_ROOT(p) && !IS_ROOT(p->d_parent)) + { + while (Buflen && !IS_ROOT(p) && !IS_ROOT(p->d_parent)) + { + if (Buflen > p->d_name.len) + { + retval -= p->d_name.len; + Buflen -= p->d_name.len; + memcpy(retval, p->d_name.name, p->d_name.len); + *(--retval) = '\\'; + Buflen--; + p = p->d_parent; + } + else + { + retval = NULL; + break; + } + } + } + else + { + *(--retval) = '\\'; + } + + + +if (retval) DbgPrint("Novfs_dget_path: %s\n", retval); + return(retval); +} + +/*++======================================================================*/ +int verify_dentry( struct dentry *dentry, int Flags ) +/* + * Arguments: struct dentry *dentry - entry to verify + * + * Returns: zero - Inode cache has been updated. If not in the cache + * then file doesn't exist. + * !zero - Error + * + * Abstract: This routine will verify if the file that dentry is pointing + * at exist and if it does it will put it in the inode cache of + * the parent. + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int retVal = -ENOENT; + struct inode *dir; + PENTRY_INFO info=NULL; + PINODE_DATA id; + session_t session; + char *path, *list=NULL, *cp; + ino_t ino; + struct qstr name; + int iLock=0; + struct dentry *parent=NULL; + u64 ctime; + struct inode *inode; + + if ( IS_ROOT(dentry) ) + { + DbgPrint("verify_dentry: Root entry\n"); + return( 0 ); + } + + if ( dentry && dentry->d_parent && + (dir = dentry->d_parent->d_inode) && + (id = dir->u.generic_ip) ) + { + parent = dget_parent(dentry); + + info = Novfs_Malloc(sizeof(ENTRY_INFO)+PATH_LENGTH_BUFFER, GFP_KERNEL); + + if (info) + { + if (Novfs_lock_inode_cache( dir )) + { + name.len = dentry->d_name.len; + name.name = dentry->d_name.name; + name.hash = Novfs_internal_hash( &name ); + if ( !Novfs_get_entry_time(dir, &name, &ino, info, &ctime)) + { + inode = dentry->d_inode; + if ( inode && + ( (inode->i_size != info->size) || + (inode->i_mtime.tv_sec != info->mtime.tv_sec) || + (inode->i_mtime.tv_nsec != info->mtime.tv_nsec) )) + { + /* + * Values don't match so update. + */ + ((PINODE_DATA)inode->u.generic_ip)->Flags |= UPDATE_INODE; + } + + ctime = get_jiffies_64() - ctime; + if ( Flags || ctime < (u64)(File_update_timeout*HZ) ) + { + retVal = 0; + Novfs_unlock_inode_cache(dir); + dput(parent); + Novfs_Free(info); + return(0); + } + } + Novfs_unlock_inode_cache(dir); + } + + if ( IS_ROOT(dentry->d_parent) ) + { + session = Scope_Get_SessionId(Scope_Get_ScopefromName(&dentry->d_name)); + } + else + { + session = Scope_Get_SessionId( id->Scope ); + } + + if ( !session ) + { + id->Scope = Scope_Get_ScopefromPath(dentry); + session = Scope_Get_SessionId( id->Scope ); + } + + ino = 0; + retVal = 0; + + if ( IS_ROOT(dentry->d_parent) ) + { + DbgPrint("verify_dentry: parent is Root directory\n"); + list = Scope_Get_ScopeUsers(); + + iLock = Novfs_lock_inode_cache( dir ); + Novfs_invalidate_inode_cache( dir ); + + if ( list ) + { + cp = list; + while (*cp) + { + name.name = cp; + name.len = strlen(cp); + name.hash = Novfs_internal_hash( &name ); + cp += (name.len+1); + ino = 0; + if ( Novfs_get_entry( dir, &name, &ino, info ) ) + { + info->mode = S_IFDIR | 0700; + info->size = 0; + info->atime = info->ctime = info->mtime = CURRENT_TIME; + ino = (ino_t)InterlockedIncrement(&Novfs_Inode_Number); + Novfs_add_inode_entry(dir, &name, ino, info); + } + } + } + Novfs_free_invalid_entries( dir ); + } + else + { + + path = Novfs_dget_path(dentry, info->name, PATH_LENGTH_BUFFER); + if (path) + { + if (dentry->d_name.len <= NW_MAX_PATH_LENGTH) + { + name.hash = Novfs_internal_hash(&dentry->d_name); + name.len = dentry->d_name.len; + name.name = dentry->d_name.name; + + + + retVal = Novfs_Get_File_Info( path, info, session ); + if ( 0 == retVal) + { + dentry->d_time = jiffies+(File_update_timeout*HZ); + iLock = Novfs_lock_inode_cache( dir ); + if ( Novfs_update_entry( dir, &name, 0, info ) ) + { + if (dentry->d_inode) + { + ino = dentry->d_inode->i_ino; + } + else + { + ino = (ino_t)InterlockedIncrement(&Novfs_Inode_Number); + } + Novfs_add_inode_entry( dir, &name, ino, info); + } + if ( dentry->d_inode ) + { + update_inode(dentry->d_inode, info); + id->Flags &= ~UPDATE_INODE; + + dentry->d_inode->i_flags &= ~S_DEAD; + if (dentry->d_inode->u.generic_ip) + { + ((PINODE_DATA)dentry->d_inode->u.generic_ip)->Scope = id->Scope; + } + } + } + else if (-EINTR != retVal) + { + retVal = 0; + iLock = Novfs_lock_inode_cache( dir ); + Novfs_remove_inode_entry( dir, &name, 0 ); + if ( dentry->d_inode && !(dentry->d_inode->i_flags & S_DEAD) ) + { + dentry->d_inode->i_flags |= S_DEAD; + dentry->d_inode->i_size = 0; + dentry->d_inode->i_atime.tv_sec = + dentry->d_inode->i_atime.tv_nsec = + dentry->d_inode->i_ctime.tv_sec = + dentry->d_inode->i_ctime.tv_nsec = + dentry->d_inode->i_mtime.tv_sec = + dentry->d_inode->i_mtime.tv_nsec = 0; + dentry->d_inode->i_blocks = 0; + d_delete(dentry); /* Remove from cache */ + } + } + } + else + { + retVal = -ENAMETOOLONG; + } + } + } + } + else + { + retVal = -ENOMEM; + } + if (iLock) + { + Novfs_unlock_inode_cache( dir ); + } + dput(parent); + } + + if (list) Novfs_Free(list); + if (info) Novfs_Free(info); + + DbgPrint("verify_dentry: return=0x%x\n", retVal); + + return(retVal); +} + +/*++======================================================================*/ +struct dentry *Novfs_d_lookup(struct dentry *Parent, struct qstr *Name) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + return( d_lookup( Parent, Name)); +} + +/*++======================================================================*/ +int Novfs_d_add(struct dentry *Parent, struct dentry *d, struct inode *i, int a) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + void *scope; + PINODE_DATA id=NULL; + + char *path, *buf; + + buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); + if (buf) + { + path = Novfs_dget_path(d, buf, PATH_LENGTH_BUFFER); + if (path) + { + DbgPrint("Novfs_d_add: inode=0x%p ino=%d path %s\n", i, i->i_ino, path); + } + Novfs_Free(buf); + } + + if ( Parent && Parent->d_inode && Parent->d_inode->u.generic_ip) + { + id = (PINODE_DATA)Parent->d_inode->u.generic_ip; + } + + if (id && id->Scope) + { + scope = id->Scope; + } + else + { + scope = Scope_Get_ScopefromPath( d ); + } + + ((PINODE_DATA)i->u.generic_ip)->Scope = scope; + + d->d_time = jiffies+(File_update_timeout*HZ); + if (a) + { + d_add(d, i); + } + else + { + d_instantiate(d, i); + } + + return(0); +} + +/*++======================================================================*/ +int Novfs_d_revalidate(struct dentry *dentry, struct nameidata *nd) +/* + * Arguments: struct dentry *dentry - pointer to dentry to revalidate. + * struct nameidata *nd - pointer to nameidata. + * + * Returns: zero - dentry is not valid. + * !zero - valid entry + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int retCode = 0; + struct inode *dir; + PINODE_DATA id; + struct qstr name; + + UNUSED_VARIABLE( nd ); + + DbgPrint("Novfs_d_revalidate: 0x%p %.*s\n" \ + " d_count: %d\n" \ + " d_inode: 0x%p\n", + dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_count, dentry->d_inode); + + if (IS_ROOT( dentry )) + { + retCode = 1; + } + else + { + if ( dentry->d_inode && + dentry->d_parent && + (dir = dentry->d_parent->d_inode) && + (id = dir->u.generic_ip) ) + { + /* + * Check timer to see if in valid time limit + */ + if (jiffies > dentry->d_time) + { + /* + * Revalidate entry + */ + name.len = dentry->d_name.len; + name.name = dentry->d_name.name; + name.hash = Novfs_internal_hash(&dentry->d_name); + dentry->d_time = 0; + + if ( 0 == verify_dentry( dentry, 0 )) + { + if (Novfs_lock_inode_cache( dir )) + { + if (Novfs_lookup_inode_cache( dir, &name, 0)) + { + dentry->d_time = jiffies + (File_update_timeout*HZ); + retCode = 1; + } + Novfs_unlock_inode_cache( dir ); + } + } + } + else + { + retCode = 1; + } + } + } + + + if ( ( 0 == retCode ) && dentry->d_inode ) + { + /* + * Entry has become invalid + */ +/* dput(dentry); +*/ + } + + DbgPrint("Novfs_d_revalidate: return 0x%x\n", retCode); + + return(retCode); +} + +/*++======================================================================*/ +unsigned long Novfs_internal_hash (struct qstr *name) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + unsigned long hash = 0; + unsigned int len = name->len; + unsigned char *c = (unsigned char *)name->name; + + while(len--) + { + /* + * Lower case values for the hash. + */ + hash = partial_name_hash(tolower(*c++), hash); + } + + return(hash); +} + +/*++======================================================================*/ +int Novfs_d_hash (struct dentry *dentry, struct qstr *name) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + UNUSED_VARIABLE( dentry ); + + DbgPrint("Novfs_d_hash: %.*s\n", name->len, name->name); + + name->hash = Novfs_internal_hash( name ); + + return(0); +} + +/*++======================================================================*/ +int Novfs_d_strcmp (struct qstr *s1, struct qstr *s2) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int retCode = 1; + unsigned char *str1, *str2; + unsigned int len; + + DbgPrint("Novfs_d_strcmp: s1=%.*s s2=%.*s\n", s1->len, s1->name, s2->len, s2->name); + + if (s1->len && (s1->len == s2->len) && (s1->hash == s2->hash) ) + { + len = s1->len; + str1 = (unsigned char *)s1->name; + str2 = (unsigned char *)s2->name; + for ( retCode = 0; len-- ; str1++, str2++ ) + { + if (*str1 != *str2) + { + if (tolower(*str1) != tolower(*str2)) + { + retCode = 1; + break; + } + } + } + } + + DbgPrint("Novfs_d_strcmp: retCode=0x%x\n", retCode); + return(retCode); +} + +/*++======================================================================*/ +int Novfs_d_compare (struct dentry *parent, struct qstr *s1, struct qstr *s2) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int retCode; + + retCode = Novfs_d_strcmp(s1, s2); + + DbgPrint("Novfs_d_compare: retCode=0x%x\n", retCode); + return(retCode); +} + +/*++======================================================================*/ +int Novfs_d_delete(struct dentry *dentry) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int retVal = 0; + + DbgPrint("Novfs_d_delete: 0x%p %.*s\n" \ + " d_count: %d\n" \ + " d_inode: 0x%p\n", + dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_count, dentry->d_inode); + + if (dentry->d_inode && (dentry->d_inode->i_flags & S_DEAD)) + { + retVal = 1; + } + + dentry->d_time = 0; + + return( retVal ); +} + +/*++======================================================================*/ +void Novfs_d_release(struct dentry *dentry) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + DbgPrint("Novfs_d_release: 0x%x %.*s\n", dentry, dentry->d_name.len, dentry->d_name.name); +} + +/*++======================================================================*/ +void Novfs_d_iput(struct dentry *dentry, struct inode *inode) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + DbgPrint("Novfs_d_iput: Inode=0x%x Ino=%d Dentry=0x%x Name=%.*s\n", + inode, inode->i_ino, dentry, dentry->d_name.len, dentry->d_name.name); + + iput(inode); + +} +/*++======================================================================*/ +int Novfs_dir_open(struct inode *dir, struct file *file) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + char *path, *buf; + + + DbgPrint("Novfs_dir_open: Inode 0x%x %d Name %.*s\n", dir, dir->i_ino, file->f_dentry->d_name.len, file->f_dentry->d_name.name); + + buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); + if (buf) + { + path = Novfs_dget_path(file->f_dentry, buf, PATH_LENGTH_BUFFER); + if (path) + { + DbgPrint("Novfs_dir_open: path %s\n", path); + } + Novfs_Free(buf); + } + file->private_data = NULL; + return(0); +} + +/*++======================================================================*/ +int Novfs_dir_release(struct inode *dir, struct file *file) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + struct inode *inode; + + DbgPrint("Novfs_dir_release: Inode 0x%x %d Name %.*s\n", dir, dir->i_ino, file->f_dentry->d_name.len, file->f_dentry->d_name.name); + if (file->private_data) + { + inode = file->private_data; + Novfs_free_inode_cache( inode ); + Novfs_Free(file->private_data); + } + + return(0); +} + +/*++======================================================================*/ +loff_t Novfs_dir_lseek(struct file *file, loff_t offset, int origin) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + return(default_llseek(file, offset, origin)); +} + +/*++======================================================================*/ +int Novfs_dir_read(struct file *file, char *buf, size_t len, loff_t *off) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ +/* + int rlen = 0; + + DbgPrint("Novfs_dir_readdir: dentry path %.*s buf=0x%p len=%d off=%lld\n", file->f_dentry->d_name.len, file->f_dentry->d_name.name, buf, len, *off); + + if (0 == *off) + { + rlen = 8; + rlen -= copy_to_user(buf, "Testing\n", 8); + *off += rlen; + } + return(rlen); +*/ + return(generic_read_dir(file, buf, len, off)); +} + +/*++======================================================================*/ +void process_list(struct file *File, char *List, int Type, PENTRY_INFO Info, session_t SessionId) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + unsigned char *path, *buf=NULL, *cp; + struct inode *dir = File->f_dentry->d_inode; + struct qstr name; + ino_t ino=0; + + buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); + path = buf; + if (buf) + { + path = Novfs_dget_path(File->f_dentry, buf, PATH_LENGTH_BUFFER); + if (path) + { + strcpy(buf, path); + } + path = buf+strlen(buf); + *path++ = '\\'; + } + + if ( List ) + { + cp = List; + while (*cp) + { + name.name = cp; + name.len = strlen(cp); + name.hash = Novfs_internal_hash( &name ); + cp += (name.len+1); + + Info->mode = S_IFDIR | 0700; + Info->size = 0; + Info->atime = Info->ctime = Info->mtime = CURRENT_TIME; + + if ( (USER_LIST != Type) && buf && ((int)(path-buf)+name.len < PATH_LENGTH_BUFFER) ) + { + strcpy(path, name.name); + Novfs_Get_File_Info(buf, Info, SessionId); + } + + if ( Novfs_update_entry( dir, &name, ino, Info ) ) + { + Novfs_add_inode_entry(dir, &name, (ino_t)InterlockedIncrement(&Novfs_Inode_Number), Info); + } + } + } + + if (buf) Novfs_Free(buf); + +} + +/*++======================================================================*/ +int Novfs_dir_readdir(struct file * file, void * dirent, filldir_t filldir) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + unsigned char *path, *buf=NULL; + unsigned char *list=NULL; + PENTRY_INFO info=NULL, pinfo, iinfo; + int count; + + int status = -ENOMEM; + struct inode *inode; + session_t sessionId; + uid_t uid; + struct qstr name; + struct list_head *inter; + ino_t ino; + int iLock=0; + int type = 0; + + DbgPrint("Novfs_dir_readdir(%s): dentry path %.*s 0x%x\n", current->comm, file->f_dentry->d_name.len, file->f_dentry->d_name.name, file->f_dentry->d_fsdata); + + inode = file->f_dentry->d_inode; + + info = Novfs_Malloc(sizeof(ENTRY_INFO)+PATH_LENGTH_BUFFER, GFP_KERNEL); + if (info) + { + if (!file->private_data) + { + if ( inode && inode->u.generic_ip ) + { + sessionId = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope); + if (0 == sessionId) + { + ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath(file->f_dentry); + sessionId = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope); + } + uid = Scope_Get_Uid(((PINODE_DATA)inode->u.generic_ip)->Scope); + } + else + { + sessionId = 0; + uid = current->euid; + } + + if ( IS_ROOT(file->f_dentry) || /* Root */ + IS_ROOT(file->f_dentry->d_parent) || /* User */ + IS_ROOT(file->f_dentry->d_parent->d_parent) ) /* Server */ + { + if ( IS_ROOT(file->f_dentry) ) + { + DbgPrint("Novfs_dir_readdir: Root directory\n"); + list = Scope_Get_ScopeUsers(); + type = USER_LIST; + + } + else if ( IS_ROOT(file->f_dentry->d_parent) ) + { + DbgPrint("Novfs_dir_readdir: Parent is Root directory\n"); + Novfs_Get_Connected_Server_List( &list, sessionId ); + type = SERVER_LIST; + } + else + { + DbgPrint("Novfs_dir_readdir: Parent-Parent is Root directory\n"); + Novfs_Get_Server_Volume_List(&file->f_dentry->d_name, &list, sessionId); + type = VOLUME_LIST; + } + + iLock = Novfs_lock_inode_cache( inode ); + Novfs_invalidate_inode_cache( inode ); + + process_list(file, list, type, info, sessionId); + } + else + { + DbgPrint("Novfs_dir_readdir: Default directory\n"); + buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); + if (buf) + { + path = Novfs_dget_path(file->f_dentry, buf, PATH_LENGTH_BUFFER); + if (path) + { + unsigned long enumHandle=0; + + iLock = Novfs_lock_inode_cache( inode ); + Novfs_invalidate_inode_cache(inode); + do + { + /* + * Novfs_Get_Directory_List will return 0 when no error or -1 when + * the last entry is returned. Otherwise it will return an error. + */ + info->namelength = 0; + status = Novfs_Get_Directory_ListEx(path, &enumHandle, &count, &pinfo, sessionId); + DbgPrint("Novfs_dir_readdir: Novfs_Get_Directory_List return 0x%x count=%d pinfo=0x%p\n", status, count, pinfo); + iinfo = pinfo; + while ( (0 == status) && pinfo && count-- ) + { + memcpy(info, pinfo, (int)((char *)&pinfo->name[pinfo->namelength]-(char *)pinfo)); + pinfo = (PENTRY_INFO)&pinfo->name[pinfo->namelength]; + name.len = info->namelength; + name.name = info->name; + name.hash = Novfs_internal_hash(&name); + info->name[name.len] = '\0'; + + DbgPrint("Novfs_dir_readdir: Got %s\n", name.name); + + if ( Novfs_update_entry( inode, &name, 0, info )) + { + Novfs_add_inode_entry(inode, &name, (ino_t)InterlockedIncrement(&Novfs_Inode_Number), info); + } + } + + if (iinfo) + { + Novfs_Free(iinfo); + } + + } + while ( !status ); + } + } + } + + file->private_data = (PDIR_CACHE)Novfs_Malloc(sizeof(struct inode) + sizeof(DIR_CACHE), GFP_KERNEL); + if (file->private_data) + { + struct inode *dinode = file->private_data; + PINODE_DATA id = (PINODE_DATA)((char *)file->private_data+sizeof(struct inode)); + + dinode->u.generic_ip = id; + + id->Scope = ((PINODE_DATA)inode->u.generic_ip)->Scope; + id->Flags = 0; + INIT_LIST_HEAD( &id->DirCache ); + init_MUTEX( &id->DirCacheLock ); + + inter = NULL; + /* + * Copy rest of the files. + */ + while( !Novfs_enumerate_inode_cache(inode, &inter, &ino, info)) + { + DbgPrint("Novfs_dir_readdir : BEGIN Calling filedir %llu with ino %d mode 0%o name %s\n", file->f_pos, ino, info->mode, info->name); + name.len = info->namelength; + name.name = info->name; + name.hash = Novfs_internal_hash( &name ); + Novfs_add_inode_entry(dinode, &name, ino, info); + DbgPrint("Novfs_dir_readdir : END Calling filedir %llu with ino %d mode 0%o name %s\n", file->f_pos, ino, info->mode, info->name); + } + file->private_data = dinode; + } + + if ( iLock ) + { + Novfs_free_invalid_entries( inode ); + } + } + + switch ((int) file->f_pos) + { + case 0: + DbgPrint("Novfs_dir_readdir : Calling filedir %llu with ino %d name .\n", file->f_pos, inode->i_ino); + if (filldir(dirent, ".", 1, file->f_pos, inode->i_ino, DT_DIR) < 0) + { + break; + } + file->f_pos++; + /* fallthrough */ + case 1: + DbgPrint("Novfs_dir_readdir : Calling filedir %llu with ino %d name ..\n", file->f_pos, parent_ino(file->f_dentry)); + if (filldir(dirent, "..", 2, file->f_pos, parent_ino(file->f_dentry), DT_DIR) < 0) + { + break; + } + file->f_pos++; + /* fallthrough */ + } + + status = 0; + inter = NULL; + + if(!Novfs_get_entry_by_pos(file->private_data, file->f_pos, &ino, info)) + { + DbgPrint("Novfs_dir_readdir : Calling filedir %llu with ino %d mode 0%o name %s\n", file->f_pos, ino, info->mode, info->name); + filldir(dirent, info->name, info->namelength, file->f_pos, ino, info->mode >> 12); + } + file->f_pos++; + + if (iLock) + { + Novfs_unlock_inode_cache(inode); + } + } + + if (info) Novfs_Free( info ); + if (buf) Novfs_Free( buf ); + if (list) Novfs_Free( list ); + + return(status); +} + + +/*++======================================================================*/ +int Novfs_dir_fsync(struct file * file, struct dentry *dentry, int datasync) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + return(simple_sync_file(file, dentry, datasync)); +} + + +/*++======================================================================*/ +ssize_t Novfs_f_read(struct file *file, char *buf, size_t len, loff_t *off) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + size_t thisread, totalread=0; + loff_t offset = *off; + struct inode *inode; + session_t session; + PINODE_DATA id; + + if ( file->f_dentry && + (inode = file->f_dentry->d_inode) && + (id = (PINODE_DATA)inode->u.generic_ip)) + { + + DbgPrint("Novfs_f_read(0x%x 0x%p %d %lld %.*s)\n", + (unsigned long)file->private_data, + buf, len, offset, + file->f_dentry->d_name.len, + file->f_dentry->d_name.name); + + if ( PageCache && + !(file->f_flags & O_DIRECT) && + id->CacheFlag ) + { + totalread = generic_file_read(file, buf, len, off); + } + else + { + session = Scope_Get_SessionId(id->Scope); + if (0 == session) + { + id->Scope = Scope_Get_ScopefromPath( file->f_dentry ); + session = Scope_Get_SessionId(id->Scope); + } + + while(len > 0 && (offset < i_size_read(inode)) ) + { + thisread = len; + if (Novfs_Read_File((unsigned long)file->private_data, buf, &thisread, &offset, session) || !thisread) + { + break; + } + DbgPrint("Novfs_f_read thisread = 0x%x\n", thisread); + len -= thisread; + buf += thisread; + offset += thisread; + totalread += thisread; + } + *off = offset; + } + } + DbgPrint("Novfs_f_read return = 0x%x\n", totalread); + + return(totalread); +} + +/*++======================================================================*/ +ssize_t Novfs_f_write(struct file *file, const char *buf, size_t len, loff_t *off) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + ssize_t thiswrite, totalwrite=0; + loff_t offset = *off; + session_t session; + struct inode *inode; + int status; + PINODE_DATA id; + + if ( file->f_dentry && + (inode = file->f_dentry->d_inode) && + (id = file->f_dentry->d_inode->u.generic_ip) ) + { + DbgPrint("Novfs_f_write(0x%x %d %lld %.*s)\n", (unsigned long)file->private_data, len, offset, file->f_dentry->d_name.len, file->f_dentry->d_name.name); + + if ( PageCache && + !(file->f_flags & O_DIRECT) && + id->CacheFlag ) + { + totalwrite = generic_file_write(file, buf, len, off); + } + else + { + if (file->f_flags & O_APPEND) + { + offset = i_size_read(inode); + DbgPrint("Novfs_f_write appending to end %lld %.*s\n", offset, file->f_dentry->d_name.len, file->f_dentry->d_name.name); + } + + session = Scope_Get_SessionId(id->Scope); + if (0 == session) + { + id->Scope = Scope_Get_ScopefromPath( file->f_dentry ); + session = Scope_Get_SessionId(id->Scope); + } + + while(len > 0) + { + thiswrite = len; + if ((status = Novfs_Write_File( + (unsigned long)file->private_data, + (unsigned char *)buf, + &thiswrite, + &offset, + session)) || !thiswrite) + { + totalwrite = status; + break; + } + DbgPrint("Novfs_f_write thiswrite = 0x%x\n", thiswrite); + len -= thiswrite; + buf += thiswrite; + offset += thiswrite; + totalwrite += thiswrite; + if (offset > i_size_read(inode)) + { + i_size_write(inode, offset); + inode->i_blocks = (offset + inode->i_blksize - 1) >> inode->i_blkbits; + } + inode->i_mtime = inode->i_atime = CURRENT_TIME; + id->Flags |= UPDATE_INODE; + + } + *off = offset; + } + } + DbgPrint("Novfs_f_write return = 0x%x\n", totalwrite); + + return(totalwrite); +} + +/*++======================================================================*/ +int Novfs_f_readdir(struct file *file, void *data, filldir_t fill) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + UNUSED_VARIABLE(file); + UNUSED_VARIABLE(data); + UNUSED_VARIABLE(fill); + return(-EISDIR); +} + +/*++======================================================================*/ +int Novfs_f_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + UNUSED_VARIABLE(inode); + UNUSED_VARIABLE(file); + UNUSED_VARIABLE(cmd); + UNUSED_VARIABLE(arg); + DbgPrint("Novfs_f_ioctl: file=0x%x cmd=0x%x arg=0x%x", file, cmd, arg); + + return(-ENOSYS); +} + +/*++======================================================================*/ +int Novfs_f_mmap(struct file * file, struct vm_area_struct * vma) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int retCode = -EINVAL; + + DbgPrint("Novfs_f_mmap: file=0x%x", file); + + retCode = generic_file_mmap(file, vma); + + DbgPrint("Novfs_f_mmap: retCode=0x%x\n", retCode); + return( retCode ); +} + +/*++======================================================================*/ +int Novfs_f_open(struct inode *inode, struct file *file) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + PENTRY_INFO info=NULL; + int retCode = -ENOENT; + session_t session; + char *path; + struct dentry *parent; + ino_t ino; + PINODE_DATA id; + + DbgPrint("Novfs_f_open: inode=0x%p file=0x%p dentry=0x%p dentry->d_inode=0x%p\n", inode, file, file->f_dentry, file->f_dentry->d_inode); + if (file->f_dentry) + { + DbgPrint("Novfs_f_open: %.*s f_flags=0%o f_mode=0%o i_mode=0%o\n", file->f_dentry->d_name.len, file->f_dentry->d_name.name, file->f_flags, file->f_mode, inode->i_mode); + } + + if (inode && inode->u.generic_ip) + { + id = (PINODE_DATA)file->f_dentry->d_inode->u.generic_ip; + session = Scope_Get_SessionId(id->Scope); + if (0 == session) + { + id->Scope = Scope_Get_ScopefromPath( file->f_dentry ); + session = Scope_Get_SessionId(id->Scope); + } + + info = (PENTRY_INFO)Novfs_Malloc(sizeof(ENTRY_INFO) + PATH_LENGTH_BUFFER, GFP_KERNEL); + if (info) + { + path = Novfs_dget_path(file->f_dentry, info->name, PATH_LENGTH_BUFFER); + if (path) + { + DbgPrint("Novfs_f_open: %s\n", path); + retCode = Novfs_Open_File( + path, + file->f_flags & ~O_EXCL, info, + (unsigned long *)&file->private_data, + session); + if ( !retCode ) + { + /* + *update_inode(inode, &info); + */ + id->FileHandle = (unsigned long)file->private_data; + id->CacheFlag = Novfs_Get_File_Cache_Flag( path, session ); + + if( !Novfs_Get_File_Info(path, info, session)) + { + update_inode(inode, info); + } + + parent = dget_parent(file->f_dentry); + + if (parent && parent->d_inode) + { + struct inode *dir = parent->d_inode; + Novfs_lock_inode_cache(dir); + ino = 0; + if (Novfs_get_entry(dir, &file->f_dentry->d_name, &ino, info)) + { + ((PINODE_DATA)inode->u.generic_ip)->Flags |= UPDATE_INODE; + } + + Novfs_unlock_inode_cache(dir); + } + dput(parent); + } + } + Novfs_Free(info); + } + } + DbgPrint("Novfs_f_open: retCode=0x%x\n", retCode); + return( retCode ); +} + +/*++======================================================================*/ +int Novfs_f_flush(struct file *file) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + struct inode *inode; + + if (file->f_dentry) + { + if( (file->f_flags & O_ACCMODE) != O_RDONLY) + { + inode = file->f_dentry->d_inode; + DbgPrint("Novfs_f_flush: %.*s f_flags=0x%x f_mode=0%o i_mode=0%o\n", file->f_dentry->d_name.len, file->f_dentry->d_name.name, file->f_flags, file->f_mode, inode->i_mode); + filemap_fdatawrite( file->f_dentry->d_inode->i_mapping ); + } + } + return(0); +} + +/*++======================================================================*/ +int Novfs_f_release(struct inode *inode, struct file *file) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int retCode = -EACCES; + session_t session; + PINODE_DATA id; + + DbgPrint("Novfs_f_release: path=%.*s handle=%x\n", + file->f_dentry->d_name.len, + file->f_dentry->d_name.name, + (unsigned long)file->private_data); + + if ( file->f_dentry->d_inode && (id = file->f_dentry->d_inode->u.generic_ip)) + { + session = Scope_Get_SessionId(id->Scope); + if (0 == session) + { + id->Scope = Scope_Get_ScopefromPath( file->f_dentry ); + session = Scope_Get_SessionId(id->Scope); + } + + //invalidate_remote_inode(file->f_dentry->d_inode); + + retCode = Novfs_Close_File((unsigned long)file->private_data, session); + id->FileHandle = 0; + } + return(retCode); +} + +/*++======================================================================*/ +int Novfs_f_fsync(struct file *file, struct dentry *dentry, int datasync) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + UNUSED_VARIABLE(file); + UNUSED_VARIABLE(dentry); + UNUSED_VARIABLE(datasync); + return(0); +} + +/*++======================================================================*/ +int Novfs_f_llseek(struct file *file, loff_t offset, int origin) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + DbgPrint("Novfs_f_llseek: File=0x%x Name=%.*s offset=%lld origin=%d\n", file, file->f_dentry->d_name.len, file->f_dentry->d_name.name, offset, origin); + return(generic_file_llseek(file, offset, origin)); +} + +/*++======================================================================*/ +int Novfs_f_lock(struct file *file, int cmd, struct file_lock *lock) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + UNUSED_VARIABLE(file); + UNUSED_VARIABLE(cmd); + UNUSED_VARIABLE(lock); + return(-ENOSYS); +} +/*++======================================================================*/ +static void Novfs_copy_cache_pages(struct address_space *mapping, + struct list_head *pages, int bytes_read, char *data, + struct pagevec *plru_pvec) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + struct page *page; + char *target; + + while (bytes_read > 0) { + if (list_empty(pages)) + break; + + page = list_entry(pages->prev, struct page, lru); + list_del(&page->lru); + + if (add_to_page_cache(page, mapping, page->index, + GFP_KERNEL)) { + page_cache_release(page); + data += PAGE_CACHE_SIZE; + bytes_read -= PAGE_CACHE_SIZE; + continue; + } + + target = kmap_atomic(page,KM_USER0); + + if (PAGE_CACHE_SIZE > bytes_read) { + memcpy(target, data, bytes_read); + /* zero the tail end of this partial page */ + memset(target + bytes_read, 0, + PAGE_CACHE_SIZE - bytes_read); + bytes_read = 0; + } else { + memcpy(target, data, PAGE_CACHE_SIZE); + bytes_read -= PAGE_CACHE_SIZE; + } + kunmap_atomic(target, KM_USER0); + + flush_dcache_page(page); + SetPageUptodate(page); + unlock_page(page); + if (!pagevec_add(plru_pvec, page)) + __pagevec_lru_add(plru_pvec); + data += PAGE_CACHE_SIZE; + } + return; +} + +/*++======================================================================*/ +int Novfs_a_writepage(struct page* page, struct writeback_control *wbc) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int retCode = -EFAULT; + struct inode *inode = page->mapping->host; + PINODE_DATA id = inode->u.generic_ip; + loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT); + session_t session=0; + DATA_LIST dlst[2]; + size_t len = PAGE_CACHE_SIZE; + + session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope); + + page_cache_get(page); + + pos = ((loff_t)page->index << PAGE_CACHE_SHIFT); + + /* + * Leave first dlst entry for reply header. + */ + dlst[1].page = page; + dlst[1].offset = NULL; + dlst[1].len = len; + dlst[1].rwflag = DLREAD; + + /* + * Check size so we don't write pass end of file. + */ + if ((pos + (loff_t)len) > i_size_read(inode)) + { + len = (size_t)(i_size_read(inode) - pos); + } + + retCode = Novfs_Write_Pages( id->FileHandle, dlst, 2, len, pos, session); + if ( !retCode ) + { + SetPageUptodate(page); + } + + unlock_page(page); + page_cache_release(page); + + return( retCode ); +} + +/*++======================================================================*/ +int Novfs_a_writepages(struct address_space *mapping, struct writeback_control *wbc) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int retCode = 0; + struct inode *inode=mapping->host; + session_t session=0; + unsigned long fh=0; + + int max_page_lookup = MaxIoSize/PAGE_CACHE_SIZE; + + PDATA_LIST dlist, dlptr; + struct page **pages; + + int dlist_idx, i=0; + pgoff_t index, next_index=0; + loff_t pos=0; + size_t tsize; + + DbgPrint("Novfs_a_writepages: mapping=0x%p wbc=0x%p\n", mapping, wbc); + + if (inode) + { + DbgPrint(" Inode=0x%x Ino=%d\n", inode, inode->i_ino); + + if (inode->u.generic_ip) + { + session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope); + fh = ((PINODE_DATA)inode->u.generic_ip)->FileHandle; + } + } + + dlist = Novfs_Malloc( sizeof(DATA_LIST) * max_page_lookup, GFP_KERNEL); + pages = Novfs_Malloc( sizeof(struct page *) * max_page_lookup, GFP_KERNEL); + + if ( fh && dlist && pages ) + { + struct backing_dev_info *bdi = mapping->backing_dev_info; + int done = 0; + int nr_pages=0; + int scanned = 0; + + if (wbc->nonblocking && bdi_write_congested(bdi)) + { + wbc->encountered_congestion = 1; + return 0; + } + + if (wbc->sync_mode == WB_SYNC_NONE) + { + index = mapping->writeback_index; /* Start from prev offset */ + } + else + { + index = 0; /* whole-file sweep */ + scanned = 1; + } + + next_index = index; + + while (!done && (wbc->nr_to_write > 0)) + { + dlist_idx = 0; + dlptr = &dlist[1]; + + DbgPrint("Novfs_a_writepages1: nr_pages=%d\n", nr_pages); + if ( !nr_pages ) + { + memset(pages, 0, sizeof(struct page *)*max_page_lookup); + + AS_TREE_LOCK(&mapping->tree_lock); + + /* + * Need to ask for one less then max_page_lookup or we + * will overflow the request buffer. This also frees + * the first entry for the reply buffer. + */ + nr_pages = radix_tree_gang_lookup_tag(&mapping->page_tree, + (void **)pages, index, max_page_lookup-1, PAGECACHE_TAG_DIRTY); + + DbgPrint("Novfs_a_writepages2: nr_pages=%d\n", nr_pages); + + + for (i = 0; i < nr_pages; i++) + { + page_cache_get(pages[i]); + } + + AS_TREE_UNLOCK(&mapping->tree_lock); + + if (nr_pages) + { + index = pages[nr_pages - 1]->index + 1; + pos = (loff_t)pages[0]->index << PAGE_CACHE_SHIFT; + } + + if ( !nr_pages ) + { + if ( scanned ) + { + index = 0; + scanned = 0; + continue; + } + done = 1; + } + else + { + next_index = pages[0]->index; + i = 0; + } + } + else + { + if (pages[i]) + { + pos = (loff_t)pages[i]->index << PAGE_CACHE_SHIFT; + } + } + + + for ( ; i < nr_pages ; i++) + { + struct page *page = pages[i]; + + /* + * At this point we hold neither mapping->tree_lock nor + * lock on the page itself: the page may be truncated or + * invalidated (changing page->mapping to NULL), or even + * swizzled back from swapper_space to tmpfs file + * mapping + */ + + DbgPrint("Novfs_a_writepages: pos=0x%llx index=%d page->index=%d next_index=%d\n", pos, index, page->index, next_index); + + if (page->index != next_index) + { + next_index = page->index; + break; + } + next_index = page->index+1; + + lock_page(page); + + if (wbc->sync_mode != WB_SYNC_NONE) + wait_on_page_writeback(page); + + if (page->mapping != mapping || PageWriteback(page) || + !clear_page_dirty_for_io(page)) + { + unlock_page(page); + continue; + } + + dlptr[dlist_idx].page = page; + dlptr[dlist_idx].offset = NULL; + dlptr[dlist_idx].len = PAGE_CACHE_SIZE; + dlptr[dlist_idx].rwflag = DLREAD; + dlist_idx++; + DbgPrint("Novfs_a_writepages: Add page=0x%p index=0x%lx\n", page, page->index); + } + + DbgPrint("Novfs_a_writepages: dlist_idx=%d\n", dlist_idx); + if ( dlist_idx ) + { + tsize = dlist_idx * PAGE_CACHE_SIZE; + /* + * Check size so we don't write pass end of file. + */ + if ((pos + tsize) > i_size_read(inode)) + { + tsize = (size_t)(i_size_read(inode) - pos); + } + + retCode = Novfs_Write_Pages(fh, dlist, dlist_idx+1, tsize, pos, session); + switch (retCode) + { + case 0: + wbc->nr_to_write -= dlist_idx; + break; + + case -ENOSPC: + set_bit(AS_ENOSPC, &mapping->flags); + done = 1; + break; + + default: + set_bit(AS_EIO, &mapping->flags); + done = 1; + break; + } + + do + { + unlock_page((struct page *)dlptr[dlist_idx-1].page); + page_cache_release((struct page *)dlptr[dlist_idx-1].page); + DbgPrint("Novfs_a_writepages: release page=0x%p index=0x%lx\n", dlptr[dlist_idx-1].page, ((struct page *)dlptr[dlist_idx-1].page)->index); + if ( !retCode ) + { + wbc->nr_to_write--; + } + } while( --dlist_idx ); + } + + if ( i >= nr_pages ) + { + nr_pages = 0; + } + } + + mapping->writeback_index = index; + + } + else + { + set_bit(AS_EIO, &mapping->flags); + } + if (dlist) Novfs_Free(dlist); + if (pages) Novfs_Free(pages); + + DbgPrint("Novfs_a_writepage: retCode=%d\n", retCode); + return (0); + +} + +/*++======================================================================*/ +int Novfs_a_readpage(struct file *file, struct page *page) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int retCode = 0; + void *pbuf; + struct inode *inode=NULL; + struct dentry *dentry=NULL; + loff_t offset; + size_t len; + session_t session=0; + + DbgPrint("Novfs_a_readpage: File=0x%x Name=%.*s Page=0x%x", file, file->f_dentry->d_name.len, file->f_dentry->d_name.name, page); + + dentry = file->f_dentry; + + if (dentry) + { + DbgPrint(" Dentry=0x%x Name=%.*s", dentry, dentry->d_name.len, dentry->d_name.name); + if (dentry->d_inode) + { + inode = dentry->d_inode; + } + } + + + + if (inode) + { + DbgPrint(" Inode=0x%x Ino=%d", inode, inode->i_ino); + + if (inode->u.generic_ip) + { + session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope); + if (0 == session) + { + ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( file->f_dentry ); + session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope); + } + } + } + + DbgPrint("\n"); + + + if (!PageUptodate(page)) + { + DATA_LIST dlst[2]; + + offset = page->index << PAGE_CACHE_SHIFT; + len = PAGE_CACHE_SIZE; + + /* + * Save the first entry for the reply header. + */ + dlst[1].page = page; + dlst[1].offset = NULL; + dlst[1].len = PAGE_CACHE_SIZE; + dlst[1].rwflag = DLWRITE; + + retCode = Novfs_Read_Pages((unsigned long)file->private_data, dlst, 2, &len, &offset, session); + if ( len && (len < PAGE_CACHE_SIZE) ) + { + pbuf = kmap_atomic(page, KM_USER0); + memset(&((char *)pbuf)[len], 0, PAGE_CACHE_SIZE-len); + kunmap_atomic(pbuf, KM_USER0); + } + + flush_dcache_page(page); + SetPageUptodate(page); + } + unlock_page(page); + + DbgPrint("Novfs_a_readpage: retCode=%d\n", retCode); + return (retCode); + +} + +/*++======================================================================*/ +int Novfs_a_readpages(struct file *file, struct address_space *mapping, struct list_head *page_lst, unsigned nr_pages) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int retCode = 0; + struct inode *inode=NULL; + struct dentry *dentry=NULL; + session_t session=0; + loff_t offset; + size_t len; + + unsigned page_idx; + struct pagevec lru_pvec; + pgoff_t next_index; + + char *rbuf, done=0; + + DbgPrint("Novfs_a_readpages: File=0x%p Name=%.*s Pages=%d\n", file, file->f_dentry->d_name.len, file->f_dentry->d_name.name, nr_pages); + + dentry = file->f_dentry; + + if (dentry) + { + DbgPrint(" Dentry=0x%x Name=%.*s\n", dentry, dentry->d_name.len, dentry->d_name.name); + if (dentry->d_inode) + { + inode = dentry->d_inode; + } + } + + if (inode) + { + DbgPrint(" Inode=0x%x Ino=%d\n", inode, inode->i_ino); + + if (inode->u.generic_ip) + { + session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope); + if (0 == session) + { + ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( file->f_dentry ); + session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope); + } + } + } + + rbuf = (char *)Novfs_Malloc(MaxIoSize, GFP_KERNEL); + if (rbuf) + { + pagevec_init(&lru_pvec, 0); + for (page_idx = 0; page_idx < nr_pages && !done; ) + { + struct page *page, *tpage; + + if (list_empty(page_lst)) + break; + + page = list_entry(page_lst->prev, struct page, lru); + + next_index = page->index; + offset = (loff_t)page->index << PAGE_CACHE_SHIFT; + len = 0; + + /* + * Count number of contiguous pages. + */ + list_for_each_entry_reverse(tpage, page_lst, lru) + { + if ( (next_index != tpage->index) || + (len >= MaxIoSize-PAGE_SIZE) ) + { + break; + } + len += PAGE_SIZE; + next_index++; + } + + if ( len && !done ) + { + DATA_LIST dllst[2]; + + dllst[1].page = NULL; + dllst[1].offset = rbuf; + dllst[1].len = len; + dllst[1].rwflag = DLWRITE; + + if ( !Novfs_Read_Pages((unsigned long)file->private_data, dllst, 2, &len, &offset, session)) + { + Novfs_copy_cache_pages(mapping, page_lst, len, rbuf, &lru_pvec); + page_idx += len >> PAGE_CACHE_SHIFT; + if ((int)(len & PAGE_CACHE_MASK) != len) + { + page_idx++; + } + } + else + { + done = 1; + } + } + } + + /* + * Free any remaining pages. + */ + while ( !list_empty(page_lst) ) + { + struct page *page = list_entry(page_lst->prev, struct page, lru); + + list_del(&page->lru); + page_cache_release(page); + } + + pagevec_lru_add(&lru_pvec); + Novfs_Free( rbuf ); + } + else + { + retCode = -ENOMEM; + } + + DbgPrint("Novfs_a_readpages: retCode=%d\n", retCode); + return (retCode); + +} + +/*++======================================================================*/ +int Novfs_a_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int retVal = 0; + loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT; + size_t len=PAGE_CACHE_SIZE; + session_t session=0; + DATA_LIST dllst[2]; + struct inode *inode = file->f_dentry->d_inode; + + DbgPrint("Novfs_a_prepare_write: File=0x%x Page=0x%x offset=0x%llx From=%u To=%u filesize=%lld\n", file, page, offset, from, to, i_size_read(file->f_dentry->d_inode)); + if (!PageUptodate(page)) + { + /* + * Check to see if whole page + */ + if((to==PAGE_CACHE_SIZE) && (from == 0)) + { + SetPageUptodate(page); + } + + /* + * Check to see if we can read page. + */ + else if((file->f_flags & O_ACCMODE) != O_WRONLY) + { + /* + * Get session. + */ + if (file->f_dentry && file->f_dentry->d_inode) + { + if (file->f_dentry->d_inode->u.generic_ip) + { + session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope); + if (0 == session) + { + ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( file->f_dentry ); + session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope); + } + } + } + + page_cache_get(page); + + len = i_size_read(inode) - offset; + if (len > PAGE_CACHE_SIZE) + { + len = PAGE_CACHE_SIZE; + } + + if( len ) + { + /* + * Read page from server. + */ + + dllst[1].page = page; + dllst[1].offset = 0; + dllst[1].len = len; + dllst[1].rwflag = DLWRITE; + + Novfs_Read_Pages((unsigned long)file->private_data, dllst, 2, &len, &offset, session); + /* + * Zero unnsed page. + */ + } + + if (len < PAGE_CACHE_SIZE) + { + char *adr = kmap_atomic(page, KM_USER0); + memset(adr+len, 0, PAGE_CACHE_SIZE-len); + kunmap_atomic(adr, KM_USER0); + } + } + else + { + /* + * Zero section of memory that not going to be used. + */ + char *adr = kmap_atomic(page, KM_USER0); + memset(adr, 0, from); + memset(adr + to, 0, PAGE_CACHE_SIZE - to); + kunmap_atomic(adr, KM_USER0); + + DbgPrint("Novfs_a_prepare_write: memset 0x%p\n", adr); + } + flush_dcache_page(page); + SetPageUptodate(page); + } + +// DbgPrint("Novfs_a_prepare_write: return %d\n", retVal); + return( retVal ); +} + +/*++======================================================================*/ +int Novfs_a_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ + +{ + int retCode = 0; + struct inode *inode = page->mapping->host; + loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to; + session_t session=0; + PINODE_DATA id; + DATA_LIST dlst[1]; + size_t len = to - offset; + + DbgPrint("Novfs_a_commit_write: File=0x%p Page=0x%p offset=0x%x To=%u filesize=%lld\n", file, page, offset, to, i_size_read(file->f_dentry->d_inode)); + if (file->f_dentry->d_inode && (id = file->f_dentry->d_inode->u.generic_ip)) + { + session = Scope_Get_SessionId(id->Scope); + if (0 == session) + { + id->Scope = Scope_Get_ScopefromPath( file->f_dentry ); + session = Scope_Get_SessionId(id->Scope); + } + + if (pos > inode->i_size) + { + i_size_write(inode, pos); + } + + if (!PageUptodate(page)) + { + pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + offset; + + if (to < offset) + { + return( retCode ); + } + dlst[0].page = page; + dlst[0].offset = (void *)offset; + dlst[0].len = len; + dlst[0].rwflag = DLREAD; + + retCode = Novfs_Write_Pages( id->FileHandle, dlst, 1, len, pos, session); + + } else { + set_page_dirty(page); + } + } + + return( retCode ); +} + +/*++======================================================================*/ +ssize_t Novfs_a_direct_IO(int rw, struct kiocb *kiocb, + const struct iovec *iov, + loff_t offset, + unsigned long nr_segs) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: This is a dummy function so that we can allow a file + * to get the direct IO flag set. Novfs_f_read and + * Novfs_f_write will do the work. Maybe not the best + * way to do but it was the easiest to implement. + * + * Environment: + * + *========================================================================*/ +{ + return( -EIO ); +} + +/*++======================================================================*/ +int Novfs_i_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + char *path, *buf; + ENTRY_INFO info; + unsigned long handle; + session_t session; + int retCode = -EACCES; + + + DbgPrint("Novfs_i_create: mode=0%o flags=0%o %.*s\n", mode, nd->NDOPENFLAGS, dentry->d_name.len, dentry->d_name.name); + + if ( IS_ROOT(dentry) || /* Root */ + IS_ROOT(dentry->d_parent) || /* User */ + IS_ROOT(dentry->d_parent->d_parent) || /* Server */ + IS_ROOT(dentry->d_parent->d_parent->d_parent) ) /* Volume */ + { + return(-EACCES); + } + + if (mode | S_IFREG) + { + if (dir->u.generic_ip) + { + session = Scope_Get_SessionId( ((PINODE_DATA)dir->u.generic_ip)->Scope); + if (0 == session) + { + ((PINODE_DATA)dir->u.generic_ip)->Scope = Scope_Get_ScopefromPath( dentry ); + session = Scope_Get_SessionId(((PINODE_DATA)dir->u.generic_ip)->Scope); + } + + buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); + if (buf) + { + path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER); + if (path) + { + retCode = Novfs_Open_File(path, nd->NDOPENFLAGS|O_RDWR, &info, &handle, session); + if ( !retCode && handle ) + { + Novfs_Close_File(handle, session); + if (!Novfs_i_mknod(dir, dentry, mode | S_IFREG, 0)) + { + if (dentry->d_inode) + { + ((PINODE_DATA)dentry->d_inode->u.generic_ip)->Flags |= UPDATE_INODE; + } + } + } + } + Novfs_Free(buf); + } + } + } + return( retCode ); +} + +/*++======================================================================*/ +void update_inode(struct inode *Inode, PENTRY_INFO Info) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + static char dbuf[128]; + + DbgPrint("update_inode: Inode=0x%x I_ino=%d\n", Inode, Inode->i_ino); + + DbgPrint("update_inode: atime=%s\n", ctime_r(&Info->atime.tv_sec, dbuf)); + DbgPrint("update_inode: ctime=%s\n", ctime_r(&Info->ctime.tv_sec, dbuf)); + DbgPrint("update_inode: mtime=%s %d\n", ctime_r(&Info->mtime.tv_sec, dbuf), Info->mtime.tv_nsec); + DbgPrint("update_inode: size=%lld\n", Info->size); + DbgPrint("update_inode: mode=0%o\n", Info->mode); + + if ( Inode && + ( (Inode->i_size != Info->size) || + (Inode->i_mtime.tv_sec != Info->mtime.tv_sec) || + (Inode->i_mtime.tv_nsec != Info->mtime.tv_nsec) )) + { + DbgPrint("update_inode: calling invalidate_remote_inode sz %d %d\n", Inode->i_size, Info->size); + DbgPrint("update_inode: calling invalidate_remote_inode sec %d %d\n", Inode->i_mtime.tv_sec, Info->mtime.tv_sec); + DbgPrint("update_inode: calling invalidate_remote_inode ns %d %d\n", Inode->i_mtime.tv_nsec, Info->mtime.tv_nsec); + invalidate_remote_inode( Inode ); + } + + Inode->i_mode = Info->mode; + Inode->i_size = Info->size; + Inode->i_atime = Info->atime; + Inode->i_ctime = Info->ctime; + Inode->i_mtime = Info->mtime; + + if (Inode->i_size && Inode->i_blksize) + { + Inode->i_blocks = (u_long)(Info->size >> (loff_t)Inode->i_blkbits); + Inode->i_bytes = Info->size & (Inode->i_blksize - 1); + + DbgPrint("update_inode: i_blksize=%d\n", Inode->i_blksize); + DbgPrint("update_inode: i_blkbits=%d\n", Inode->i_blkbits); + DbgPrint("update_inode: i_blocks=%d\n", Inode->i_blocks); + DbgPrint("update_inode: i_bytes=%d\n", Inode->i_bytes); + } +} + +/*++======================================================================*/ +struct dentry * Novfs_i_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + struct dentry *retVal = ERR_PTR(-ENOENT); + struct dentry *parent; + PENTRY_INFO info=NULL; + PINODE_DATA id; + struct inode *inode=NULL; + uid_t uid=current->euid; + ino_t ino=0; + struct qstr name; + + DbgPrint("Novfs_i_lookup: dir 0x%x %d name %.*s hash %d inode 0x%0p\n", dir, dir->i_ino, dentry->d_name.len, dentry->d_name.name, dentry->d_name.hash, dentry->d_inode); + + if (dir && (id = dir->u.generic_ip) ) + { + retVal = 0; + if ( IS_ROOT( dentry )) + { + DbgPrint("Novfs_i_lookup: Root entry=0x%x\n", Novfs_root); + inode = Novfs_root->d_inode; + return(0); + } + else + { + info = Novfs_Malloc(sizeof(ENTRY_INFO)+PATH_LENGTH_BUFFER, GFP_KERNEL); + if (info) + { + if ( NULL == (retVal = ERR_PTR(verify_dentry( dentry, 1 )))) + { + name.name = dentry->d_name.name; + name.len = dentry->d_name.len; + name.hash = Novfs_internal_hash(&name); + + if (Novfs_lock_inode_cache( dir )) + { + if ( !Novfs_get_entry(dir, &name, &ino, info) ) + { + inode = ilookup(dentry->d_sb, ino); + if ( inode ) + { + update_inode(inode, info); + } + } + Novfs_unlock_inode_cache( dir ); + } + + if ( !inode && ino ) + { + uid = Scope_Get_Uid( id->Scope ); + if (Novfs_lock_inode_cache( dir )) + { + inode = Novfs_get_inode(dentry->d_sb, info->mode, 0, uid, ino, &name); + if ( inode ) + { + if ( !Novfs_get_entry(dir, &dentry->d_name, &ino, info) ) + { + update_inode(inode, info); + } + } + Novfs_unlock_inode_cache( dir ); + } + } + } + } + } + } + + if ( !retVal ) + { + dentry->d_op = &Novfs_dentry_operations; + if (inode) + { + parent = dget_parent(dentry); + Novfs_d_add(dentry->d_parent, dentry, inode, 1); + dput(parent); + } + else + { + d_add( dentry, inode); + } + } + + if (info) Novfs_Free(info); + + DbgPrint("Novfs_i_lookup: inode=0x%x dentry->d_inode=0x%x return=0x%x\n", dir, dentry->d_inode, retVal); + + return(retVal); +} + +/*++======================================================================*/ +int Novfs_i_unlink(struct inode *dir, struct dentry *dentry) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int retCode = -ENOENT; + struct inode *inode; + session_t session; + char *path, *buf; + uint64_t t64; + + DbgPrint("Novfs_i_unlink: dir=0x%x dir->i_ino=%d %.*s\n", dir, dir->i_ino, dentry->d_name.len, dentry->d_name.name); + DbgPrint("Novfs_i_unlink: IS_ROOT(dentry)=%d\n", IS_ROOT(dentry)); + DbgPrint("Novfs_i_unlink: IS_ROOT(dentry->d_parent)=%d\n", IS_ROOT(dentry->d_parent)); + DbgPrint("Novfs_i_unlink: IS_ROOT(dentry->d_parent->d_parent)=%d\n", IS_ROOT(dentry->d_parent->d_parent)); + DbgPrint("Novfs_i_unlink: IS_ROOT(dentry->d_parent->d_parent->d_parent)=%d\n", IS_ROOT(dentry->d_parent->d_parent->d_parent) ); + + if ( IS_ROOT(dentry) || /* Root */ + IS_ROOT(dentry->d_parent) || /* User */ + (!IS_ROOT(dentry->d_parent->d_parent) && /* Server */ + IS_ROOT(dentry->d_parent->d_parent->d_parent)) ) /* Volume */ + { + return(-EACCES); + } + + inode = dentry->d_inode; + if ( inode ) + { + DbgPrint("Novfs_i_unlink: dir=0x%x dir->i_ino=%d inode=0x%x ino=%d\n", dir, dir->i_ino, inode, inode->i_ino); + if (inode->u.generic_ip) + { + session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope); + if (0 == session) + { + ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( dentry ); + session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope); + } + + buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); + if (buf) + { + path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER); + if (path) + { + DbgPrint("Novfs_i_unlink: path %s mode 0%o\n", path, inode->i_mode); + if (IS_ROOT(dentry->d_parent->d_parent)) + { + retCode = do_logout(&dentry->d_name); + } + else + { + retCode = Novfs_Delete(path, S_ISDIR(inode->i_mode), session); + } + if ( !retCode || IS_DEADDIR(inode)) + { + Novfs_remove_inode_entry(dir, &dentry->d_name, 0); + dentry->d_time = 0; + t64 = 0; + Scope_Set_UserSpace(&t64, &t64, &t64, &t64); + retCode = 0; + } + } + Novfs_Free(buf); + } + } + } + + DbgPrint("Novfs_i_unlink: retCode 0x%x\n", retCode); + return (retCode); +} + +/*++======================================================================*/ +int Novfs_i_mkdir(struct inode *dir, struct dentry *dentry, int mode) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + char *path, *buf; + session_t session; + int retCode=0; + struct inode *inode; + ENTRY_INFO info; + uid_t uid; + + DbgPrint("Novfs_i_mkdir: dir=0x%p ino=%d dentry=0x%p %.*s mode=0%o\n", dir, dir->i_ino, dentry, dentry->d_name.len, dentry->d_name.name, mode); + + if ( IS_ROOT(dentry) || /* Root */ + IS_ROOT(dentry->d_parent) || /* User */ + IS_ROOT(dentry->d_parent->d_parent) || /* Server */ + IS_ROOT(dentry->d_parent->d_parent->d_parent) ) /* Volume */ + { + return(-EACCES); + } + + mode |= S_IFDIR; + mode &= (S_IFMT | S_IRWXU); + if ( dir->u.generic_ip ) + { + session = Scope_Get_SessionId( ((PINODE_DATA)dir->u.generic_ip)->Scope); + if (0 == session) + { + ((PINODE_DATA)dir->u.generic_ip)->Scope = Scope_Get_ScopefromPath( dentry ); + session = Scope_Get_SessionId(((PINODE_DATA)dir->u.generic_ip)->Scope); + } + + uid = Scope_Get_Uid( ((PINODE_DATA)dir->u.generic_ip)->Scope); + buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); + if (buf) + { + path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER); + if (path) + { + DbgPrint("Novfs_i_mkdir: path %s\n", path); + retCode = Novfs_Create(path, S_ISDIR(mode), session); + if ( !retCode ) + { + retCode = Novfs_Get_File_Info(path, &info, session ); + if ( !retCode ) + { + retCode = Novfs_i_mknod(dir, dentry, mode, 0); + inode = dentry->d_inode; + if (inode) + { + update_inode(inode, &info); + ((PINODE_DATA)inode->u.generic_ip)->Flags &= ~UPDATE_INODE; + + dentry->d_time = jiffies+(File_update_timeout*HZ); + + Novfs_lock_inode_cache(dir); + if (Novfs_update_entry( dir, &dentry->d_name, 0, &info )) + { + Novfs_add_inode_entry(dir, &dentry->d_name, inode->i_ino, &info); + } + Novfs_unlock_inode_cache(dir); + } + + } + } + } + Novfs_Free(buf); + } + } + + return( retCode ); +} + +/*++======================================================================*/ +int Novfs_i_rmdir(struct inode *inode, struct dentry *dentry) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + return(Novfs_i_unlink(inode, dentry)); +} + +/*++======================================================================*/ +int Novfs_i_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + struct inode *inode=NULL; + int retCode = -EACCES; + uid_t uid; + struct dentry *parent; + + if ( IS_ROOT(dentry) || /* Root */ + IS_ROOT(dentry->d_parent) || /* User */ + IS_ROOT(dentry->d_parent->d_parent) || /* Server */ + IS_ROOT(dentry->d_parent->d_parent->d_parent) ) /* Volume */ + { + return(-EACCES); + } + + if ( ((PINODE_DATA)dir->u.generic_ip) ) + { + uid = Scope_Get_Uid( ((PINODE_DATA)dir->u.generic_ip)->Scope); + if (mode & (S_IFREG | S_IFDIR)) + { + inode = Novfs_get_inode(dir->i_sb, mode, dev, uid, 0, &dentry->d_name); + } + } + + if (inode) + { + ENTRY_INFO info; + + dentry->d_op = &Novfs_dentry_operations; + parent = dget_parent(dentry); + Novfs_d_add(parent, dentry, inode, 0); + memset(&info, 0, sizeof(info)); + info.mode = inode->i_mode; + Novfs_lock_inode_cache( dir ); + Novfs_add_inode_entry( dir, &dentry->d_name, inode->i_ino, &info); + Novfs_unlock_inode_cache( dir ); + + dput(parent); + + retCode = 0; + } + DbgPrint("Novfs_i_mknod: return 0x%x\n", retCode); + return retCode; +} + +/*++======================================================================*/ +int Novfs_i_rename(struct inode *odir, struct dentry *od, struct inode *ndir, struct dentry *nd) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int retCode = -ENOTEMPTY; + char *newpath, *newbuf, *newcon; + char *oldpath, *oldbuf, *oldcon; + struct qstr newname, oldname; + PENTRY_INFO info=NULL; + int oldlen, newlen; + session_t session; + ino_t ino; + + + if ( IS_ROOT(od) || /* Root */ + IS_ROOT(od->d_parent) || /* User */ + IS_ROOT(od->d_parent->d_parent) || /* Server */ + IS_ROOT(od->d_parent->d_parent->d_parent) ) /* Volume */ + { + return(-EACCES); + } + + DbgPrint("Novfs_i_rename: odir=0x%p ino=%d ndir=0x%p ino=%d\n", odir, odir->i_ino, ndir, ndir->i_ino); + + oldbuf = Novfs_Malloc(PATH_LENGTH_BUFFER*2, GFP_KERNEL); + newbuf = oldbuf+PATH_LENGTH_BUFFER; + if ( oldbuf && newbuf ) + { + oldpath = Novfs_dget_path(od, oldbuf, PATH_LENGTH_BUFFER); + newpath = Novfs_dget_path(nd, newbuf, PATH_LENGTH_BUFFER); + if (oldpath && newpath) + { + oldlen = PATH_LENGTH_BUFFER-(int)(oldpath-oldbuf); + newlen = PATH_LENGTH_BUFFER-(int)(newpath-newbuf); + + DbgPrint("Novfs_i_rename: odir=0x%x od->inode=0x%x\n", odir, od->d_inode); + DbgPrint("Novfs_i_rename: old path %s\n", oldpath); + DbgPrint("Novfs_i_rename: new path %s\n", newpath); + + /* + * Check to see if two different servers or different volumes + */ + newcon = strchr(newpath+1, '\\'); + oldcon = strchr(oldpath+1, '\\'); + DbgPrint("Novfs_i_rename: newcon=0x%x newpath=0x%x\n", newcon, newpath); + DbgPrint("Novfs_i_rename: oldcon=0x%x oldpath=0x%x\n", oldcon, oldpath); + retCode = -EXDEV; + if ( newcon && oldcon && ((int)(newcon-newpath) == (int)(oldcon-oldpath)) ) + { + newcon = strchr(newcon+1, '\\'); + oldcon = strchr(oldcon+1, '\\'); + DbgPrint("Novfs_i_rename2: newcon=0x%x newpath=0x%x\n", newcon, newpath); + DbgPrint("Novfs_i_rename2: oldcon=0x%x oldpath=0x%x\n", oldcon, oldpath); + if ( newcon && oldcon && ((int)(newcon-newpath) == (int)(oldcon-oldpath)) ) + { + newname.name = newpath; + newname.len = (int)(newcon-newpath); + newname.hash = 0; + + oldname.name = oldpath; + oldname.len = (int)(oldcon-oldpath); + oldname.hash = 0; + if ( !Novfs_d_strcmp(&newname, &oldname)) + { + + if ( od->d_inode && od->d_inode->u.generic_ip ) + { + + if (nd->d_inode && nd->d_inode->u.generic_ip) + { + session = Scope_Get_SessionId(((PINODE_DATA)ndir->u.generic_ip)->Scope); + if (0 == session) + { + ((PINODE_DATA)ndir->u.generic_ip)->Scope = Scope_Get_ScopefromPath( nd ); + session = Scope_Get_SessionId(((PINODE_DATA)ndir->u.generic_ip)->Scope); + } + + retCode = Novfs_Delete(newpath, S_ISDIR(nd->d_inode->i_mode), session); + } + + + session = Scope_Get_SessionId(((PINODE_DATA)ndir->u.generic_ip)->Scope); + if (0 == session) + { + ((PINODE_DATA)ndir->u.generic_ip)->Scope = Scope_Get_ScopefromPath( nd ); + session = Scope_Get_SessionId(((PINODE_DATA)ndir->u.generic_ip)->Scope); + } + retCode = Novfs_Rename_File( + S_ISDIR(od->d_inode->i_mode), + oldpath, + oldlen-1, + newpath, + newlen-1, + session); + + if ( !retCode ) + { + info = (PENTRY_INFO)oldbuf; + od->d_time = 0; + Novfs_remove_inode_entry(odir, &od->d_name, 0); + Novfs_Get_File_Info(newpath, info, session); + nd->d_time = jiffies+(File_update_timeout*HZ); + if (Novfs_update_entry(ndir, &nd->d_name, 0, info)) + { + if (nd->d_inode && nd->d_inode->i_ino) + { + ino = nd->d_inode->i_ino; + } + else + { + ino = (ino_t)InterlockedIncrement(&Novfs_Inode_Number); + } + Novfs_add_inode_entry(ndir, &nd->d_name, ino, info); + } + } + } + } + } + } + } + } + + if (oldbuf) Novfs_Free(oldbuf); + + return( retCode ); +} + +/*++======================================================================*/ +int Novfs_i_permission(struct inode *inode, int mask) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int retCode=0; + + return(retCode); +} + +/*++======================================================================*/ +int Novfs_i_setattr(struct dentry *dentry, struct iattr *attr) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + char *path, *buf; + struct inode *inode=dentry->d_inode; + char atime_buf[32]; + char mtime_buf[32]; + char ctime_buf[32]; + unsigned int ia_valid = attr->ia_valid; + session_t session; + int retVal = 0; + + if ( IS_ROOT(dentry) || /* Root */ + IS_ROOT(dentry->d_parent) || /* User */ + IS_ROOT(dentry->d_parent->d_parent) || /* Server */ + IS_ROOT(dentry->d_parent->d_parent->d_parent) ) /* Volume */ + { + return(-EACCES); + } + + if (inode && inode->u.generic_ip) + { + session = Scope_Get_SessionId( ((PINODE_DATA)inode->u.generic_ip)->Scope); + if (0 == session) + { + ((PINODE_DATA)inode->u.generic_ip)->Scope = Scope_Get_ScopefromPath( dentry ); + session = Scope_Get_SessionId(((PINODE_DATA)inode->u.generic_ip)->Scope); + } + + buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); + if (buf) + { + path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER); + if (path) + { + strcpy(atime_buf, "Unspecified"); + strcpy(mtime_buf, "Unspecified"); + strcpy(ctime_buf, "Unspecified"); + if (attr->ia_valid & ATTR_ATIME) + { + ctime_r(&attr->ia_atime.tv_sec, atime_buf); + } + if (attr->ia_valid & ATTR_MTIME) + { + ctime_r(&attr->ia_mtime.tv_sec, mtime_buf); + } + if (attr->ia_valid & ATTR_CTIME) + { + ctime_r(&attr->ia_ctime.tv_sec, ctime_buf); + } + /* Removed for Bug 132374. jlt + DbgPrint("Novfs_i_setattr: %s\n" \ + " ia_valid: 0x%x\n" \ + " ia_mode: 0%o\n" \ + " ia_uid: %d\n" \ + " ia_gid: %d\n" \ + " ia_size: %lld\n" \ + " ia_atime: %s\n" \ + " ia_mtime: %s\n" \ + " ia_ctime: %s\n" \ + " ia_attr_flags: 0x%x\n", + path, + attr->ia_valid, + attr->ia_mode, + attr->ia_uid, + attr->ia_gid, + attr->ia_size, + atime_buf, + mtime_buf, + ctime_buf, + attr->ia_attr_flags); + */ + + if ( !(retVal = Novfs_Set_Attr(path, attr, session) ) ) + { + ((PINODE_DATA)inode->u.generic_ip)->Flags |= UPDATE_INODE; + + if (ia_valid & ATTR_ATIME) + inode->i_atime = attr->ia_atime; + if (ia_valid & ATTR_MTIME) + inode->i_mtime = attr->ia_mtime; + if (ia_valid & ATTR_CTIME) + inode->i_ctime = attr->ia_ctime; + if (ia_valid & ATTR_MODE) { + inode->i_mode = attr->ia_mode & (S_IFMT | S_IRWXU); + } + } + } + } + Novfs_Free(buf); + } + + return(retVal); +} + +/*++======================================================================*/ +int Novfs_i_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *kstat) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int retCode = 0; + char atime_buf[32]; + char mtime_buf[32]; + char ctime_buf[32]; + struct inode *inode = dentry->d_inode; + + ENTRY_INFO info; + char *path, *buf; + session_t session; + PINODE_DATA id; + + if ( !IS_ROOT(dentry) && + !IS_ROOT(dentry->d_parent) ) + { + session = 0; + id = dentry->d_inode->u.generic_ip; + + if (id && (id->Flags & UPDATE_INODE) ) + { + session = Scope_Get_SessionId( id->Scope ); + + if (0 == session) + { + id->Scope = Scope_Get_ScopefromPath( dentry ); + session = Scope_Get_SessionId(id->Scope); + } + + buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); + if (buf) + { + path = Novfs_dget_path(dentry, buf, PATH_LENGTH_BUFFER); + if (path) + { + retCode = Novfs_Get_File_Info(path, &info, session ); + if ( !retCode ) + { + update_inode(inode, &info); + id->Flags &= ~UPDATE_INODE; + } + } + Novfs_Free(buf); + } + } + } + + kstat->ino = inode->i_ino; + kstat->dev = inode->i_sb->s_dev; + kstat->mode = inode->i_mode; + kstat->nlink = inode->i_nlink; + kstat->uid = inode->i_uid; + kstat->gid = inode->i_gid; + kstat->rdev = inode->i_rdev; + kstat->size = i_size_read(inode); + kstat->atime = inode->i_atime; + kstat->mtime = inode->i_mtime; + kstat->ctime = inode->i_ctime; + kstat->blksize = inode->i_blksize; + kstat->blocks = inode->i_blocks; + if (inode->i_bytes) + { + kstat->blocks++; + } + ctime_r(&kstat->atime.tv_sec, atime_buf); + ctime_r(&kstat->mtime.tv_sec, mtime_buf); + ctime_r(&kstat->ctime.tv_sec, ctime_buf); + + + DbgPrint("Novfs_i_getattr: 0x%x <%.*s>\n" \ + " ino: %d\n" \ + " dev: 0x%x\n" \ + " mode: 0%o\n" \ + " nlink: 0x%x\n" \ + " uid: 0x%x\n" \ + " gid: 0x%x\n" \ + " rdev: 0x%x\n" \ + " size: 0x%llx\n" \ + " atime: %s\n" \ + " mtime: %s\n" \ + " ctime: %s\n" \ + " blksize: 0x%x\n" \ + " blocks: 0x%x\n", + retCode, dentry->d_name.len, dentry->d_name.name, + kstat->ino, + kstat->dev, + kstat->mode, + kstat->nlink, + kstat->uid, + kstat->gid, + kstat->rdev, + kstat->size, + atime_buf, + mtime_buf, + ctime_buf, + kstat->blksize, + kstat->blocks); + return( retCode ); +} + + +/*++======================================================================*/ +int Novfs_i_revalidate(struct dentry *dentry) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + + DbgPrint("Novfs_i_revalidate: name %.*s\n", dentry->d_name.len, dentry->d_name.name); + + return(0); +} + +/*++======================================================================*/ +void Novfs_read_inode(struct inode *inode) +/* + * Arguments: + * + * Returns: nothing + * + * Abstract: + * + * Notes: + * + * Environment: Superblock operation + * + *=======================================================================-*/ +{ + DbgPrint( "Novfs_read_inode: 0x%x %d\n", inode, inode->i_ino); +} + +/*++======================================================================*/ +void Novfs_write_inode(struct inode *inode) +/* + * Arguments: + * + * Returns: nothing + * + * Abstract: + * + * Notes: + * + * Environment: Superblock operation + * + *=======================================================================-*/ +{ + DbgPrint( "Novfs_write_inode: Inode=0x%x Ino=%d\n", inode, inode->i_ino); +} + +/*++======================================================================*/ +int Novfs_notify_change(struct dentry *dentry, struct iattr *attr) +/* + * Arguments: + * + * Returns: error code + * + * Abstract: + * + * Notes: + * + * Environment: Superblock operation + * + *=======================================================================-*/ +{ + struct inode *inode = dentry->d_inode; + + DbgPrint( "Novfs_notify_change: Dentry=0x%x Name=%.*s Inode=0x%x Ino=%d ia_valid=0x%x\n", + dentry, dentry->d_name.len, dentry->d_name.name,inode, inode->i_ino, attr->ia_valid); + return(0); +} + +/*++======================================================================*/ +void Novfs_clear_inode(struct inode *inode) +/* + * Arguments: sb - pointer to the super_block + * buf - pointer to the statfs buffer + * + * Returns: 0 + * + * Abstract: Called when statfs(2) system called. + * + * Notes: + * + * Environment: Superblock operation + * + *========================================================================*/ +{ + InodeCount--; + + if ( inode->u.generic_ip ) + { + PINODE_DATA id=inode->u.generic_ip; + + DbgPrint("Novfs_clear_inode: inode=0x%x ino=%d Scope=0x%p Name=%s\n", inode, inode->i_ino, id->Scope, id->Name); + + Novfs_free_inode_cache(inode); + + down( &InodeList_lock ); + list_del( &id->IList ); + up( &InodeList_lock ); + + + Novfs_Free(inode->u.generic_ip); + inode->u.generic_ip = NULL; + + remove_inode_hash( inode ); + + } + else + { + DbgPrint("Novfs_clear_inode: inode=0x%x ino=%d\n", inode, inode->i_ino); + } +} + +/*++======================================================================*/ +int +NO_TRACE +Novfs_show_options( struct seq_file *s, struct vfsmount *m ) +/* + * Arguments: + * + * Returns: 0 + * + * Abstract: Called when /proc/mounts is read + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + char *buf, *path, *tmp; + + buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); + if (buf) + { + path = d_path(m->mnt_root, m, buf, PATH_LENGTH_BUFFER); + if (path) + { + if ( !Novfs_CurrentMount || (Novfs_CurrentMount && strcmp(Novfs_CurrentMount, path))) + { + DbgPrint("Novfs_show_options: %.*s %.*s %s\n", m->mnt_root->d_name.len, m->mnt_root->d_name.name, + m->mnt_mountpoint->d_name.len, m->mnt_mountpoint->d_name.name, path); + tmp = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER - (int)(path-buf), GFP_KERNEL); + if (tmp) + { + strcpy(tmp, path); + path = Novfs_CurrentMount; + Novfs_CurrentMount = tmp; + Daemon_SetMountPoint( Novfs_CurrentMount ); + + if (path) + { + Novfs_Free(path); + } + } + } + } + Novfs_Free( buf ); + } + return(0); +} + +/*++======================================================================*/ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) +int Novfs_statfs(struct dentry *de, struct kstatfs *buf) +#else +int Novfs_statfs(struct super_block *sb, struct kstatfs *buf) +#endif +/* + * Arguments: sb - pointer to the super_block + * buf - pointer to the statfs buffer + * + * Returns: 0 + * + * Abstract: Called when statfs(2) system called. + * + * Notes: + * + * Environment: Superblock operation + * + *========================================================================*/ +{ + uint64_t td, fd, te, fe; + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) + struct super_block *sb = de->d_sb; +#endif + + UNUSED_VARIABLE(sb); + + DbgPrint("Novfs_statfs:\n"); + + td = fd = te = fe = 0; + + Scope_Get_UserSpace( &td, &fd, &te, &fe ); + + DbgPrint("td=%llu\n", td); + DbgPrint("fd=%llu\n", fd); + DbgPrint("te=%llu\n", te); + DbgPrint("fe=%llu\n", fd); + + buf->f_type = sb->s_magic; + buf->f_bsize = sb->s_blocksize; + buf->f_namelen = NW_MAX_PATH_LENGTH; + buf->f_blocks = (sector_t)(td + (uint64_t)(sb->s_blocksize-1)) >> (uint64_t)sb->s_blocksize_bits; + buf->f_bfree = (sector_t)fd >> (uint64_t)sb->s_blocksize_bits; + buf->f_bavail = (sector_t)buf->f_bfree; + buf->f_files = (sector_t)te; + buf->f_ffree = (sector_t)fe; + buf->f_frsize = sb->s_blocksize; + if (te > 0xffffffff) + buf->f_files = 0xffffffff; + + if (fe > 0xffffffff) + buf->f_ffree = 0xffffffff; + + + DbgPrint("f_type: 0x%x\n", buf->f_type); + DbgPrint("f_bsize: %u\n", buf->f_bsize); + DbgPrint("f_namelen: %d\n", buf->f_namelen); + DbgPrint("f_blocks: %llu\n", buf->f_blocks); + DbgPrint("f_bfree: %llu\n", buf->f_bfree); + DbgPrint("f_bavail: %llu\n", buf->f_bavail); + DbgPrint("f_files: %llu\n", buf->f_files); + DbgPrint("f_ffree: %llu\n", buf->f_ffree); + DbgPrint("f_frsize: %u\n", buf->f_frsize); + + return 0; +} + +/*++======================================================================*/ +struct inode *Novfs_get_inode(struct super_block *sb, int mode, int dev, uid_t Uid, ino_t ino, struct qstr *name) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *=======================================================================-*/ +{ + struct inode * inode = new_inode(sb); + + if (inode) + { + InodeCount++; + inode->i_mode = mode; + inode->i_uid = Uid; + inode->i_gid = 0; + inode->i_blksize = sb->s_blocksize; + inode->i_blkbits = sb->s_blocksize_bits; + inode->i_blocks = 0; + inode->i_rdev = 0; + inode->i_ino = (ino) ? ino: (ino_t)InterlockedIncrement(&Novfs_Inode_Number); + inode->i_mapping->a_ops = &Novfs_aops; + inode->i_atime.tv_sec = 0; + inode->i_atime.tv_nsec = 0; + inode->i_mtime = inode->i_ctime = inode->i_atime; + + DbgPrint("Novfs_get_inode: Inode=0x%p I_ino=%d len=%d\n", inode, inode->i_ino, name->len); + + if (NULL != (inode->u.generic_ip = Novfs_Malloc(sizeof(INODE_DATA)+name->len, GFP_KERNEL))) + { + PINODE_DATA id; + id = inode->u.generic_ip; + + DbgPrint("Novfs_get_inode: u.generic_ip 0x%p\n", id); + + id->Scope = NULL; + id->Flags = 0; + id->Inode = inode; + INIT_LIST_HEAD( &id->DirCache ); + init_MUTEX( &id->DirCacheLock ); + + id->FileHandle = 0; + id->CacheFlag = 0; + + down( &InodeList_lock ); + + list_add_tail(&id->IList, &InodeList); + up( &InodeList_lock ); + + id->Name[0] = '\0'; + + memcpy(id->Name, name->name, name->len); + id->Name[name->len] = '\0'; + + DbgPrint("Novfs_get_inode: name %s\n", id->Name); + } + + insert_inode_hash(inode); + + switch (mode & S_IFMT) { + + case S_IFREG: + inode->i_op = &Novfs_file_inode_operations; + inode->i_fop = &Novfs_file_operations; + break; + + case S_IFDIR: + inode->i_op = &Novfs_inode_operations; + inode->i_fop = &Novfs_dir_operations; + inode->i_blksize = 0; + inode->i_blkbits = 0; + break; + + default: + init_special_inode(inode, mode, dev); + break; + } + + DbgPrint("Novfs_get_inode: size=%lld\n", inode->i_size); + DbgPrint("Novfs_get_inode: mode=0%o\n", inode->i_mode); + DbgPrint("Novfs_get_inode: i_blksize=%d\n", inode->i_blksize); + DbgPrint("Novfs_get_inode: i_blkbits=%d\n", inode->i_blkbits); + DbgPrint("Novfs_get_inode: i_blocks=%d\n", inode->i_blocks); + DbgPrint("Novfs_get_inode: i_bytes=%d\n", inode->i_bytes); + } + + DbgPrint("Novfs_get_inode: 0x%p %d\n", inode, inode->i_ino); + return (inode); +} + +/*++======================================================================*/ +int Novfs_fill_super (struct super_block *SB, void *Data, int Silent) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + struct inode * inode; + struct dentry *server, *tree; + struct qstr name; +/* PINODE_DATA id; +*/ + ENTRY_INFO info; + + UNUSED_VARIABLE(Data); + UNUSED_VARIABLE(Silent); + + SB->s_blocksize = PAGE_CACHE_SIZE; + SB->s_blocksize_bits = PAGE_CACHE_SHIFT; + SB->s_maxbytes = 0xFFFFFFFFFFFFFFFFULL; /* Max file size */ + SB->s_op = &Novfs_ops; + SB->s_flags |= (MS_NODIRATIME | MS_NODEV | MS_POSIXACL); + SB->s_magic = NOVFS_MAGIC; + + + name.len = 1; + name.name = "/"; + + inode = Novfs_get_inode(SB, S_IFDIR | 0777, 0, 0, 0, &name); + if (!inode) + { + return( -ENOMEM ); + } + + Novfs_root = d_alloc_root(inode); + + if (!Novfs_root) + { + iput(inode); + return( -ENOMEM ); + } + Novfs_root->d_time = jiffies+(File_update_timeout*HZ); + + inode->i_atime = + inode->i_ctime = + inode->i_mtime = CURRENT_TIME; + + + SB->s_root = Novfs_root; + + DbgPrint( "Novfs_fill_super: root 0x%x\n", Novfs_root); + + if (Novfs_root) + { + Novfs_root->d_op = &Novfs_dentry_operations; + + name.name = SERVER_DIRECTORY_NAME; + name.len = strlen(SERVER_DIRECTORY_NAME); + name.hash = Novfs_internal_hash( &name ); + + inode = Novfs_get_inode(SB, S_IFDIR | 0777, 0, 0, 0, &name); + if (inode) + { + info.mode = inode->i_mode; + info.namelength = 0; + inode->i_size = info.size = 0; + inode->i_uid = info.uid = 0; + inode->i_gid = info.gid = 0; + inode->i_atime = info.atime = + inode->i_ctime = info.ctime = + inode->i_mtime = info.mtime = CURRENT_TIME; + + server = d_alloc(Novfs_root, &name); + if (server) + { + server->d_op = &Novfs_dentry_operations; + server->d_time = 0xffffffff; + d_add(server, inode); + DbgPrint( "Novfs_fill_super: d_add %s 0x%x\n", SERVER_DIRECTORY_NAME, server); + Novfs_add_inode_entry(Novfs_root->d_inode, &name, inode->i_ino, &info); + } + } + + name.name = TREE_DIRECTORY_NAME; + name.len = strlen(TREE_DIRECTORY_NAME); + name.hash = Novfs_internal_hash( &name ); + + inode = Novfs_get_inode(SB, S_IFDIR | 0777, 0, 0, 0, &name); + if (inode) + { + info.mode = inode->i_mode; + info.namelength = 0; + inode->i_size = info.size = 0; + inode->i_uid = info.uid = 0; + inode->i_gid = info.gid = 0; + inode->i_atime = info.atime = + inode->i_ctime = info.ctime = + inode->i_mtime = info.mtime = CURRENT_TIME; + tree = d_alloc(Novfs_root, &name); + if (tree) + { + tree->d_op = &Novfs_dentry_operations; + tree->d_time = 0xffffffff; + + d_add(tree, inode); + DbgPrint( "Novfs_fill_super: d_add %s 0x%x\n", TREE_DIRECTORY_NAME, tree); + Novfs_add_inode_entry(Novfs_root->d_inode, &name, inode->i_ino, &info); + } + } + } + + return( 0 ); +} + +/*++======================================================================*/ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) +int Novfs_get_sb(struct file_system_type *Fstype, int Flags, const char *Dev_name, void *Data, struct vfsmount *Mnt) +#else +struct super_block * Novfs_get_sb(struct file_system_type *Fstype, int Flags, const char *Dev_name, void *Data) +#endif +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) + int sb; +#else + struct super_block *sb; +#endif + + UNUSED_VARIABLE(Dev_name); + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) + sb = get_sb_nodev(Fstype, Flags, Data, Novfs_fill_super, Mnt); +#else + sb = get_sb_nodev(Fstype, Flags, Data, Novfs_fill_super); +#endif + + DbgPrint( "Novfs_get_sb: sb=0x%x Fstype=0x%x Dev_name=%s\n", sb, Fstype, Dev_name); + + return (sb ); +} + +/*++======================================================================*/ +void Novfs_kill_sb(struct super_block *SB) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + kill_litter_super(SB); +} + +/*++======================================================================*/ +ssize_t Novfs_Control_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + ssize_t retval=0; + + UNUSED_VARIABLE(file); + UNUSED_VARIABLE(buf); + UNUSED_VARIABLE(nbytes); + UNUSED_VARIABLE(ppos); + + DbgPrint( "Novfs_Control_read: kernel_locked 0x%x\n", kernel_locked()); + + return retval; +} + +/*++======================================================================*/ +ssize_t Novfs_Control_write(struct file * file, const char * buf, size_t nbytes, loff_t *ppos) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + ssize_t retval=0; + + UNUSED_VARIABLE(file); + UNUSED_VARIABLE(buf); + UNUSED_VARIABLE(nbytes); + UNUSED_VARIABLE(ppos); + + DbgPrint( "Novfs_Control_write: kernel_locked 0x%x\n", kernel_locked()); + if (buf && nbytes) + { + } + + return(retval); +} + +/*++======================================================================*/ +int Novfs_Control_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int retval=0; + + UNUSED_VARIABLE(inode); + UNUSED_VARIABLE(file); + UNUSED_VARIABLE(cmd); + UNUSED_VARIABLE(arg); + + DbgPrint( "Novfs_Control_ioctl: kernel_locked 0x%x\n", kernel_locked()); + + return(retval); +} + +/*++======================================================================*/ +int __init init_novfs (void) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int retCode; + + + retCode = Init_Procfs_Interface(); + + init_profile(); + + if ( !retCode ) + { + DbgPrint("init_novfs: %s %s %s\n", __DATE__, __TIME__, NOVFS_VERSION_STRING); + Init_Daemon_Queue(); + Scope_Init(); + retCode = register_filesystem(&Novfs_fs_type); + if ( retCode ) + { + Uninit_Procfs_Interface(); + Uninit_Daemon_Queue(); + Scope_Uninit(); + } + } + return(retCode); +} + +/*++======================================================================*/ +void __exit exit_novfs(void) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + printk( KERN_INFO "exit_novfs\n"); + + Scope_Uninit(); + printk( KERN_INFO "exit_novfs after Scope_Uninit\n"); + + Uninit_Daemon_Queue(); + printk( KERN_INFO "exit_novfs after Uninit_Daemon_Queue\n"); + + uninit_profile(); + printk( KERN_INFO "exit_novfs after uninit_profile\n"); + + Uninit_Procfs_Interface(); + printk( KERN_INFO "exit_novfs Uninit_Procfs_Interface\n"); + + unregister_filesystem(&Novfs_fs_type); + printk( KERN_INFO "exit_novfs: Exit\n"); + + if (Novfs_CurrentMount) + { + Novfs_Free(Novfs_CurrentMount); + Novfs_CurrentMount = NULL; + } +} + +/*++======================================================================*/ +int Novfs_lock_inode_cache( struct inode *i ) +/* + * + * Arguments: struct inode *i - pointer to directory inode + * + * Returns: 0 - locked + * -1 - not locked + * + * Abstract: Locks the inode cache. + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + PINODE_DATA id; + int retVal = 0; + + DbgPrint("Novfs_lock_inode_cache: 0x%p\n", i); + if ( i && (id = i->u.generic_ip) && id->DirCache.next ) + { + down( &id->DirCacheLock ); + retVal = 1; + } + DbgPrint("Novfs_lock_inode_cache: return %d\n", retVal); + return( retVal ); +} + +/*++======================================================================*/ +void Novfs_unlock_inode_cache( struct inode *i ) +/* + * Arguments: struct inode *i - pointer to directory inode + * + * Returns: nothing + * + * Abstract: Unlocks inode cache. + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + PINODE_DATA id; + + if ( i && (id = i->u.generic_ip) && id->DirCache.next ) + { + up( &id->DirCacheLock ); + } +} + +/*++======================================================================*/ +int Novfs_enumerate_inode_cache( struct inode *i, struct list_head **iteration, ino_t *ino, PENTRY_INFO info) +/* + * Arguments: struct inode *i - pointer to directory inode + * + * Returns: 0 - item found + * -1 - done + * + * Abstract: Unlocks inode cache. + * + * Notes: DirCacheLock should be held before calling this routine. + * + * Environment: + * + *========================================================================*/ +{ + PINODE_DATA id; + PDIR_CACHE dc; + struct list_head *l=NULL; + int retVal = -1; + + + if ( i && (id = i->u.generic_ip) && id->DirCache.next ) + { + if ( (NULL == iteration) || (NULL == *iteration) ) + { + l = id->DirCache.next; + } + else + { + l = *iteration; + } + + if (l == &id->DirCache) + { + l = NULL; + } + else + { + dc = list_entry(l, DIR_CACHE, list); + + *ino = dc->ino; + info->type = 0; + info->mode = dc->mode; + info->size = dc->size; + info->atime = dc->atime; + info->mtime = dc->mtime; + info->ctime = dc->ctime; + info->namelength = dc->nameLen; + memcpy(info->name, dc->name, dc->nameLen); + info->name[dc->nameLen] = '\0'; + retVal = 0; + + l = l->next; + } + } + *iteration = l; + return( retVal ); +} + +/*++======================================================================*/ +int Novfs_get_entry( struct inode *i, struct qstr *name, ino_t *ino, PENTRY_INFO info) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: DirCacheLock should be held before calling this routine. + * + * Environment: + * + *========================================================================*/ +{ + PINODE_DATA id; + PDIR_CACHE dc; + int retVal = -1; + char *n=""; + int nl=6; + + if ( i && (id = i->u.generic_ip) && id->DirCache.next ) + { + if (name && name->len) + { + n = (char *)name->name; + nl = name->len; + } + DbgPrint("Novfs_get_entry:\n" \ + " inode: 0x%p\n" \ + " name: %.*s\n" \ + " ino: %d\n", + i, nl, n, *ino); + + dc = Novfs_lookup_inode_cache(i, name, *ino); + if (dc) + { + dc->flags |= ENTRY_VALID; + retVal = 0; + *ino = dc->ino; + info->type = 0; + info->mode = dc->mode; + info->size = dc->size; + info->atime = dc->atime; + info->mtime = dc->mtime; + info->ctime = dc->ctime; + info->namelength = dc->nameLen; + memcpy(info->name, dc->name, dc->nameLen); + info->name[dc->nameLen] = '\0'; + retVal = 0; + } + } + DbgPrint("Novfs_get_entry: return %d\n", retVal); + return( retVal ); +} + +int Novfs_get_entry_by_pos( struct inode *i, loff_t pos, ino_t* ino, PENTRY_INFO info) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: DirCacheLock should be held before calling this routine. + * + * Environment: + * + *========================================================================*/ +{ + int retVal = -1; + loff_t count = 0; + loff_t i_pos = pos - 2; + struct list_head *inter = NULL; + while( !Novfs_enumerate_inode_cache(i, &inter, ino, info)) + { + DbgPrint("Novfs_dir_readdir : Novfs_get_entry_by_pos : info->name = %s\n", info->name); + if(count == i_pos) + { + retVal = 0; + break; + } + else + count++; + } + + return retVal; +} + +/*++======================================================================*/ +int Novfs_get_entry_time( struct inode *i, struct qstr *name, ino_t *ino, PENTRY_INFO info, u64 *EntryTime) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: DirCacheLock should be held before calling this routine. + * + * Environment: + * + *========================================================================*/ +{ + PINODE_DATA id; + PDIR_CACHE dc; + int retVal = -1; + char *n=""; + int nl=6; + + if ( i && (id = i->u.generic_ip) && id->DirCache.next ) + { + if (name && name->len) + { + n = (char *)name->name; + nl = name->len; + } + DbgPrint("Novfs_get_entry:\n" \ + " inode: 0x%p\n" \ + " name: %.*s\n" \ + " ino: %d\n", + i, nl, n, *ino); + + dc = Novfs_lookup_inode_cache(i, name, *ino); + if (dc) + { + retVal = 0; + *ino = dc->ino; + info->type = 0; + info->mode = dc->mode; + info->size = dc->size; + info->atime = dc->atime; + info->mtime = dc->mtime; + info->ctime = dc->ctime; + info->namelength = dc->nameLen; + memcpy(info->name, dc->name, dc->nameLen); + info->name[dc->nameLen] = '\0'; + if (EntryTime) + { + *EntryTime = dc->jiffies; + } + retVal = 0; + } + } + DbgPrint("Novfs_get_entry: return %d\n", retVal); + return( retVal ); +} + +/*++======================================================================*/ +int Novfs_get_remove_entry( struct inode *i, ino_t *ino, PENTRY_INFO info) +/* + * Arguments: + * + * Returns: + * + * Abstract: This routine will return the first entry on the list + * and then remove it. + * + * Notes: DirCacheLock should be held before calling this routine. + * + * Environment: + * + *========================================================================*/ +{ + PINODE_DATA id; + PDIR_CACHE dc; + struct list_head *l=NULL; + int retVal = -1; + + + if ( i && (id = i->u.generic_ip) && id->DirCache.next ) + { + l = id->DirCache.next; + + if (l != &id->DirCache) + { + dc = list_entry(l, DIR_CACHE, list); + + *ino = dc->ino; + info->type = 0; + info->mode = dc->mode; + info->size = dc->size; + info->atime = dc->atime; + info->mtime = dc->mtime; + info->ctime = dc->ctime; + info->namelength = dc->nameLen; + memcpy(info->name, dc->name, dc->nameLen); + info->name[dc->nameLen] = '\0'; + retVal = 0; + + list_del( &dc->list ); + Novfs_Free( dc ); + DCCount--; + + } + } + return( retVal ); +} + +/*++======================================================================*/ +void Novfs_invalidate_inode_cache( struct inode *i ) +/* + * Arguments: struct inode *i - pointer to directory inode + * + * Returns: nothing + * + * Abstract: Marks all entries in the directory cache as invalid. + * + * Notes: DirCacheLock should be held before calling this routine. + * + * Environment: + * + *========================================================================*/ +{ + PINODE_DATA id; + PDIR_CACHE dc; + struct list_head *l; + + if ( i && (id = i->u.generic_ip) && id->DirCache.next ) + { + list_for_each(l, &id->DirCache) + { + dc = list_entry(l, DIR_CACHE, list); + dc->flags &= ~ENTRY_VALID; + } + } +} + +/*++======================================================================*/ +PDIR_CACHE Novfs_lookup_inode_cache( struct inode *i, struct qstr *name, ino_t ino ) +/* + * Arguments: struct inode *i - pointer to directory inode + * struct qstr *name - pointer to name + * ino_t - inode number + * + * Returns: DIR_CACHE entry if match + * NULL - if there is no match. + * + * Abstract: Checks a inode directory to see if there are any enties + * matching name or ino. If name is specified then ino is + * not used. ino is use if name is not specified. + * + * Notes: DirCacheLock should be held before calling this routine. + * + * Environment: + * + *========================================================================*/ +{ + PINODE_DATA id; + PDIR_CACHE dc, retVal=NULL; + struct list_head *l; + char *n=""; + int nl=6; + int hash=0; + + if ( i && (id = i->u.generic_ip) && id->DirCache.next ) + { + if (name && name->name) + { + nl = name->len; + n = (char *)name->name; + hash = name->hash; + } + DbgPrint("Novfs_lookup_inode_cache:\n" \ + " inode: 0x%p\n" \ + " name: %.*s\n" \ + " hash: 0x%x\n" \ + " len: %d\n" \ + " ino: %d\n", + i, nl, n, hash, nl, ino); + + list_for_each(l, &id->DirCache) + { + dc = list_entry(l, DIR_CACHE, list); + if (name) + { + +/* DbgPrint("Novfs_lookup_inode_cache: 0x%p\n" \ + " ino: %d\n" \ + " hash: 0x%x\n" \ + " len: %d\n" \ + " name: %.*s\n", + dc, dc->ino, dc->hash, dc->nameLen, dc->nameLen, dc->name); +*/ + if ( (name->hash == dc->hash) && + (name->len == dc->nameLen) && + (0 == memcmp(name->name, dc->name, name->len)) ) + { + retVal = dc; + break; + } + } + else + { + if (ino == dc->ino) + { + retVal = dc; + break; + } + } + } + } + + DbgPrint("Novfs_lookup_inode_cache: return 0x%p\n", retVal); + return( retVal ); +} + +/*++======================================================================*/ +int Novfs_lookup_validate( struct inode *i, struct qstr *name, ino_t ino ) +/* + * Arguments: struct inode *i - pointer to directory inode + * struct qstr *name - pointer to name + * ino_t - inode number + * + * Returns: 0 if found + * !0 if not found + * + * Abstract: Checks a inode directory to see if there are any enties + * matching name or ino. If entry is found the valid bit + * is set. + * + * Notes: DirCacheLock should be held before calling this routine. + * + * Environment: + * + *========================================================================*/ +{ + PINODE_DATA id; + PDIR_CACHE dc; + int retVal = -1; + char *n=""; + int nl=6; + + if ( i && (id = i->u.generic_ip) && id->DirCache.next ) + { + if (name && name->len) + { + n = (char *)name->name; + nl = name->len; + } + DbgPrint("Novfs_update_entry:\n" \ + " inode: 0x%p\n" \ + " name: %.*s\n" \ + " ino: %d\n", + i, nl, n, ino); + + dc = Novfs_lookup_inode_cache( i, name, ino ); + if (dc) + { + dc->flags |= ENTRY_VALID; + retVal = 0; + } + } + return( retVal ); +} + +/*++======================================================================*/ +int Novfs_add_inode_entry( + struct inode *i, + struct qstr *name, + ino_t ino, + PENTRY_INFO info) +/* + * Arguments: + * + * Returns: -ENOMEM - alloc error. + * 0 - success. + * + * Abstract: Added entry to directory cache. + * + * Notes: DirCacheLock should be held before calling this routine. + * + * Environment: + * + *========================================================================*/ +{ + PINODE_DATA id; + PDIR_CACHE new; + int retVal = -ENOMEM; + + if ( i && (id = i->u.generic_ip) && id->DirCache.next ) + { + new = Novfs_Malloc(sizeof(DIR_CACHE)+name->len, GFP_KERNEL); + if (new) + { + DCCount++; + DbgPrint("Novfs_add_inode_entry:\n" \ + " inode: 0x%p\n" \ + " id: 0x%p\n" \ + " DC: 0x%p\n" \ + " new: 0x%p\n" \ + " name: %.*s\n" \ + " ino: %d\n" \ + " size: %lld\n" \ + " mode: 0x%x\n", + i, id, &id->DirCache, new, name->len, name->name, ino, info->size, info->mode); + + retVal = 0; + new->flags = ENTRY_VALID; + new->jiffies = get_jiffies_64(); + new->size = info->size; + new->mode = info->mode; + new->atime = info->atime; + new->mtime = info->mtime; + new->ctime = info->ctime; + new->ino = ino; + new->hash = name->hash; + new->nameLen = name->len; + memcpy(new->name, name->name, name->len); + new->name[new->nameLen] = '\0'; + list_add(&new->list, &id->DirCache); + +/* list_for_each(l, &id->DirCache) + { + dc = list_entry(l, DIR_CACHE, list); + if ( dc->hash > new->hash ) + { + break; + } + } + + DbgPrint("Novfs_add_inode_entry: adding 0x%p to 0x%p\n", new, l); + list_add(&new->list, l); +*/ + } + } + return( retVal ); +} + +/*++======================================================================*/ +int Novfs_update_entry( struct inode *i, struct qstr *name, ino_t ino, PENTRY_INFO info) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: DirCacheLock should be held before calling this routine. + * + * Environment: + * + *========================================================================*/ +{ + PINODE_DATA id; + PDIR_CACHE dc; + int retVal = -1; + char *n=""; + int nl=6; + char atime_buf[32]; + char mtime_buf[32]; + char ctime_buf[32]; + + if ( i && (id = i->u.generic_ip) && id->DirCache.next ) + { + + if (name && name->len) + { + n = (char *)name->name; + nl = name->len; + } + ctime_r(&info->atime.tv_sec, atime_buf); + ctime_r(&info->mtime.tv_sec, mtime_buf); + ctime_r(&info->ctime.tv_sec, ctime_buf); + DbgPrint("Novfs_update_entry:\n" \ + " inode: 0x%p\n" \ + " name: %.*s\n" \ + " ino: %d\n" \ + " size: %lld\n" \ + " atime: %s\n" \ + " mtime: %s\n" \ + " ctime: %s\n", + i, nl, n, ino, info->size, atime_buf, mtime_buf, ctime_buf); + + + dc = Novfs_lookup_inode_cache(i, name, ino); + if (dc) + { + retVal = 0; + dc->flags = ENTRY_VALID; + dc->jiffies = get_jiffies_64(); + dc->size = info->size; + dc->mode = info->mode; + dc->atime = info->atime; + dc->mtime = info->mtime; + dc->ctime = info->ctime; + + ctime_r(&dc->atime.tv_sec, atime_buf); + ctime_r(&dc->mtime.tv_sec, mtime_buf); + ctime_r(&dc->ctime.tv_sec, ctime_buf); + DbgPrint("Novfs_update_entry entry: 0x%x\n" \ + " flags: 0x%x\n" \ + " jiffies: %lld\n" \ + " ino: %d\n" \ + " size: %lld\n" \ + " mode: 0%o\n" \ + " atime: %s\n" \ + " mtime: %s %d\n" \ + " ctime: %s\n" \ + " hash: 0x%x\n" \ + " nameLen: %d\n" \ + " name: %s\n", + dc, dc->flags, dc->jiffies, dc->ino, dc->size, dc->mode, + atime_buf, mtime_buf, dc->mtime.tv_nsec, ctime_buf, dc->hash, dc->nameLen, dc->name); + } + } + DbgPrint("Novfs_update_entry: return %d\n", retVal); + return( retVal ); +} + +/*++======================================================================*/ +void Novfs_remove_inode_entry( struct inode *i, struct qstr *name, ino_t ino) +/* + * Arguments: + * + * Returns: nothing + * + * Abstract: Removes entry from directory cache. You can specify a name + * or an inode number. + * + * Notes: DirCacheLock should be held before calling this routine. + * + * Environment: + * + *========================================================================*/ +{ + PINODE_DATA id; + PDIR_CACHE dc; + char *n=""; + int nl=6; + + if ( i && (id = i->u.generic_ip) && id->DirCache.next ) + { + dc = Novfs_lookup_inode_cache( i, name, ino ); + if (dc) + { + if (name && name->name) + { + nl = name->len; + n = (char *)name->name; + } + DbgPrint("Novfs_remove_inode_entry:\n" \ + " inode: 0x%p\n" \ + " id: 0x%p\n" \ + " DC: 0x%p\n" \ + " name: %.*s\n" \ + " ino: %d\n" \ + " entry: 0x%p\n" \ + " name: %.*s\n"\ + " ino: %d\n" \ + " next: 0x%p\n" \ + " prev: 0x%p\n", + i, id, &id->DirCache, nl, n, ino, dc, dc->nameLen, dc->name, dc->ino, dc->list.next, dc->list.prev); + list_del( &dc->list ); + Novfs_Free( dc ); + DCCount--; + + } + } +} + +/*++======================================================================*/ +void Novfs_free_invalid_entries( struct inode *i ) +/* + * Arguments: struct inode *i - pointer to directory inode. + * + * Returns: nothing + * + * Abstract: Frees all invalid entries in the directory cache. + * + * Notes: DirCacheLock should be held before calling this routine. + * + * Environment: + * + *========================================================================*/ +{ + PINODE_DATA id; + PDIR_CACHE dc; + struct list_head *l; + + if ( i && (id = i->u.generic_ip) && id->DirCache.next ) + { + list_for_each( l, &id->DirCache ) + { + dc = list_entry( l, DIR_CACHE, list ); + if ( 0 == (dc->flags & ENTRY_VALID) ) + { + DbgPrint("Novfs_free_invalid_entries:\n" \ + " inode: 0x%p\n" \ + " id: 0x%p\n" \ + " entry: 0x%p\n" \ + " name: %.*s\n" \ + " ino: %d\n", + i, id, dc, dc->nameLen, dc->name, dc->ino); + l = l->prev; + list_del( &dc->list ); + Novfs_Free( dc ); + DCCount--; + } + } + } +} + +/*++======================================================================*/ +void Novfs_free_inode_cache( struct inode *i ) +/* + * Arguments: struct inode *i - pointer to directory inode. + * + * Returns: nothing + * + * Abstract: Frees all entries in the inode cache. + * + * Notes: DirCacheLock should be held before calling this routine. + * + * Environment: + * + *========================================================================*/ +{ + PINODE_DATA id; + PDIR_CACHE dc; + struct list_head *l; + + if ( i && (id = i->u.generic_ip) && id->DirCache.next ) + { + list_for_each( l, &id->DirCache ) + { + dc = list_entry( l, DIR_CACHE, list ); + l = l->prev; + list_del( &dc->list ); + Novfs_Free( dc ); + DCCount--; + } + } +} + +/*++======================================================================*/ +int +NO_TRACE +Novfs_dump_inode_cache(int argc, const char **argv, const char **envp, struct pt_regs *regs) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ +#ifdef CONFIG_KDB + struct inode *inode=NULL; + PINODE_DATA id; + PDIR_CACHE dc; + struct list_head *l; + char atime_buf[32]; + char mtime_buf[32]; + char ctime_buf[32]; + + if (Novfs_root) + { + inode = Novfs_root->d_inode; + } + + if (argc > 0) + { + inode = (void *)simple_strtoul(argv[1], NULL, 0); + } + + kdb_printf("Inode: 0x%p\n", inode); + if (inode) + { + id = inode->u.generic_ip; + kdb_printf("INODE_DATA: 0x%p\n", id); + + if ( id && id->DirCache.next ) + { + list_for_each(l, &id->DirCache) + { + dc = list_entry(l, DIR_CACHE, list); + ctime_r(&dc->atime.tv_sec, atime_buf); + ctime_r(&dc->mtime.tv_sec, mtime_buf); + ctime_r(&dc->ctime.tv_sec, ctime_buf); + + DbgPrint("Cache Entry: 0x%p\n" \ + " flags: 0x%x\n" \ + " jiffies: %llu\n" \ + " ino: %u\n" \ + " size: %llu\n" \ + " mode: 0%o\n" \ + " atime: %s\n" \ + " mtime: %s\n" \ + " ctime: %s\n" \ + " hash: 0x%x\n" \ + " len: %d\n" \ + " name: %s\n", + dc, dc->flags, dc->jiffies, + dc->ino, dc->size, dc->mode, + atime_buf, mtime_buf, ctime_buf, + dc->hash, dc->nameLen, dc->name); + } + } + } +#endif + return(0); +} + +/*++======================================================================*/ +void +NO_TRACE +Novfs_dump_inode( void *pf ) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + struct inode *inode; + void (*pfunc)(char *Fmt, ...) = pf; + PINODE_DATA id; + PDIR_CACHE dc; + struct list_head *il, *l; + char atime_buf[32]; + char mtime_buf[32]; + char ctime_buf[32]; + unsigned long icnt=0, dccnt=0; + + down( &InodeList_lock ); + list_for_each(il, &InodeList) + { + id = list_entry(il, INODE_DATA, IList); + inode = id->Inode; + if (inode) + { + icnt++; + + pfunc("Inode=0x%x I_ino=%d\n", inode, inode->i_ino); + + pfunc(" atime=%s\n", ctime_r(&inode->i_atime.tv_sec, atime_buf)); + pfunc(" ctime=%s\n", ctime_r(&inode->i_mtime.tv_sec, atime_buf)); + pfunc(" mtime=%s\n", ctime_r(&inode->i_ctime.tv_sec, atime_buf)); + pfunc(" size=%lld\n", inode->i_size); + pfunc(" mode=0%o\n", inode->i_mode); + } + + pfunc(" INODE_DATA: 0x%p Name=%s Scope=0x%p\n", id, id->Name, id->Scope); + + if (id->DirCache.next ) + { + list_for_each(l, &id->DirCache) + { + dccnt++; + dc = list_entry(l, DIR_CACHE, list); + ctime_r(&dc->atime.tv_sec, atime_buf); + ctime_r(&dc->mtime.tv_sec, mtime_buf); + ctime_r(&dc->ctime.tv_sec, ctime_buf); + + pfunc(" Cache Entry: 0x%p\n" \ + " flags: 0x%x\n" \ + " jiffies: %llu\n" \ + " ino: %u\n" \ + " size: %llu\n" \ + " mode: 0%o\n" \ + " atime: %s\n" \ + " mtime: %s\n" \ + " ctime: %s\n" \ + " hash: 0x%x\n" \ + " len: %d\n" \ + " name: %s\n", + dc, dc->flags, dc->jiffies, + dc->ino, dc->size, dc->mode, + atime_buf, mtime_buf, ctime_buf, + dc->hash, dc->nameLen, dc->name); + } + } + } + up( &InodeList_lock ); + + pfunc("Inodes: %d(%d) DirCache: %d(%d)\n", InodeCount, icnt, DCCount, dccnt ); + +} + +module_init(init_novfs) +module_exit(exit_novfs) + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Novell Inc."); +MODULE_DESCRIPTION("Novell NetWare Client for Linux"); +MODULE_VERSION( NOVFS_VERSION_STRING ); diff -uNr src.old/src/m src/src/m --- src.old/src/m 1970-01-01 01:00:00.000000000 +0100 +++ src/src/m 2006-10-16 15:08:22.000000000 +0200 @@ -0,0 +1,12 @@ +#!/bin/sh + +VERSION=`uname -r` + +make -C /usr/src/linux SUBDIRS=$PWD modules + +if [ -e novfs.ko ] +then + mkdir -p -m 755 /lib/modules/$VERSION/kernel/fs/novfs + echo "copying novfs.ko to /lib/modules/$VERSION/kernel/fs/novfs" + cp novfs.ko /lib/modules/$VERSION/kernel/fs/novfs +fi diff -uNr src.old/src/mk_novfs src/src/mk_novfs --- src.old/src/mk_novfs 1970-01-01 01:00:00.000000000 +0100 +++ src/src/mk_novfs 2006-10-16 15:08:22.000000000 +0200 @@ -0,0 +1,114 @@ +#!/bin/sh + +RVAL=1 +TO_BUILD=1 + +BUILD_TYPE=modules + +if [ $1 ] +then + if [ "$1" = "force" ] + then + FORCE=1 + else + BUILD_TYPE=$1 + FORCE=0 + fi +else + FORCE=0 +fi + +platform=`uname -i` + +if [ -d /usr/src/linux-obj/$platform ] +then + for i in $(ls /usr/src/linux-obj/$platform) + do + TO_BUILD=1 + VERSION=`cat /usr/src/linux-obj/$platform/$i/include/linux/version.h |grep UTS_RELEASE |awk '{printf("%s\n", substr($3, 2,length($3)-2))}'` + NOVFS_PATH=/lib/modules/$VERSION/kernel/fs/novfs + + if [ -e /lib/modules/$VERSION/extra/novfs.ko ] + then + NOVFS_PATH=/lib/modules/$VERSION/extra + + else + if [ -e /lib/modules/$VERSION/updates/novfs.ko ] + then + NOVFS_PATH=/lib/modules/$VERSION/updates + + fi + fi + + if [ -d /lib/modules/$VERSION ] + then + + if [ -e $NOVFS_PATH/novfs.ko ] + then + CUR_NOVFS_VERSION=`od --strings=8 $NOVFS_PATH/novfs.ko |grep version= |awk '{split($2,a,"="); if("version"==a[1]) printf("%s", a[2])}'` + CUR_NOVFS_VFS_MAJOR=`echo $CUR_NOVFS_VERSION |awk '{split($0,a,"."); printf("%d", a[1])}'` + CUR_NOVFS_VFS_MINOR=`echo $CUR_NOVFS_VERSION |awk '{split($0,a,"."); printf("%d", a[2])}'` + CUR_NOVFS_VFS_SUB=`echo $CUR_NOVFS_VERSION |awk '{split($0,a,"."); printf("%d", a[3])}'` + CUR_NOVFS_VFS_RELEASE=`echo $CUR_NOVFS_VERSION |awk '{split($0,a,"-"); printf("%d", a[2])}'` + + NOVFS_VFS_MAJOR=`cat Makefile |grep 'NOVFS_VFS_MAJOR =' |awk '{printf("%d", $3)}'` + NOVFS_VFS_MINOR=`cat Makefile |grep 'NOVFS_VFS_MINOR =' |awk '{printf("%d", $3)}'` + NOVFS_VFS_SUB=`cat Makefile |grep 'NOVFS_VFS_SUB =' |awk '{printf("%d", $3)}'` + NOVFS_VFS_RELEASE=`cat Makefile |grep 'NOVFS_VFS_RELEASE =' |awk '{printf("%d", $3)}'` + NOVFS_VFS_VERSION="$NOVFS_VFS_MAJOR.$NOVFS_VFS_MINOR.$NOVFS_VFS_SUB-$NOVFS_VFS_RELEASE" + + TO_BUILD=0 + + if [ $NOVFS_VFS_MAJOR -gt $CUR_NOVFS_VFS_MAJOR ] + then + TO_BUILD=1 + else + if [ $NOVFS_VFS_MAJOR -eq $CUR_NOVFS_VFS_MAJOR ] + then + if [ $NOVFS_VFS_MINOR -gt $CUR_NOVFS_VFS_MINOR ] + then + TO_BUILD=1 + else + if [ $NOVFS_VFS_MINOR -eq $CUR_NOVFS_VFS_MINOR ] + then + if [ $NOVFS_VFS_SUB -gt $CUR_NOVFS_VFS_SUB ] + then + TO_BUILD=1 + else + if [ $NOVFS_VFS_SUB -eq $CUR_NOVFS_VFS_SUB ] + then + if [ $NOVFS_VFS_RELEASE -gt $CUR_NOVFS_VFS_RELEASE ] + then + TO_BUILD=1 + fi + fi + fi + fi + fi + fi + fi + fi + + if [ $FORCE -eq 1 ] + then + TO_BUILD=1; + fi + + if [ $TO_BUILD -eq 1 ] + then + echo Building novfs.ko for $VERSION + make -C /usr/src/linux-obj/$platform/$i SUBDIRS=$PWD $BUILD_TYPE + RVAL=$? + if [ -e novfs.ko ] + then + mkdir -p -m 755 $NOVFS_PATH + echo "copying novfs.ko to $NOVFS_PATH" + cp novfs.ko $NOVFS_PATH + RVAL=$? + fi + fi + fi + done +fi +exit $RVAL + diff -uNr src.old/src/nwcapi.c src/src/nwcapi.c --- src.old/src/nwcapi.c 1970-01-01 01:00:00.000000000 +0100 +++ src/src/nwcapi.c 2006-10-16 15:08:22.000000000 +0200 @@ -0,0 +1,2410 @@ +/*++======================================================================== + * Program Name: Novell NCP Redirector for Linux + * File Name: nwcapi.c + * Version: v1.00 + * Author: James Turner/Richard Williams + * + * Abstract: This module contains functions used to interface to + * the library interface of the daemon. + * Notes: + * Revision History: + * + * + * Copyright (C) 2005 Novell, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *======================================================================--*/ + +/*===[ Include files specific to Linux ]==================================*/ + +/*===[ Include files specific to this module ]============================*/ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nwcapi.h" +#include "nwerror.h" +#include "commands.h" + +#include "vfs.h" + +/*===[ External data ]====================================================*/ + +/*===[ External prototypes ]==============================================*/ + +extern int DbgPrint( char *Fmt, ... ); +extern void mydump(int size, void *dumpptr); + +extern session_t Scope_Get_SessionId( void *Scope ); +extern int Queue_Daemon_Command(void *request, u_long reqlen, void *data, int dlen, void **reply, u_long *replen, int interruptible); + +extern int do_login(NclString *Server, NclString *Username, NclString *Password, u_long *lgnId, session_t Session); + +void GetUserData(NwcScanConnInfo *connInfo, PXPLAT_CALL_REQUEST cmd, PXPLAT_CALL_REPLY reply); +void GetConnData(NwcGetConnInfo *connInfo, PXPLAT_CALL_REQUEST cmd, PXPLAT_CALL_REPLY reply); + +/*===[ Manifest constants ]===============================================*/ + +/*===[ Type definitions ]=================================================*/ + +/*===[ Function prototypes ]==============================================*/ + +/*===[ Global variables ]=================================================*/ + +/*===[ Code ]=============================================================*/ + +/*++======================================================================*/ + +/*++======================================================================*/ +int NwOpenConnByName(PXPLAT pdata, u_long *Handle, session_t Session) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ +PXPLAT_CALL_REQUEST cmd; +PXPLAT_CALL_REPLY reply; +PNwdCOpenConnByName openConn, connReply; +NwcOpenConnByName ocbn; +u_long retCode = 0, cmdlen, datalen, replylen, cpylen; +char *data; + + cpylen = copy_from_user(&ocbn, pdata->reqData, sizeof(ocbn)); + datalen = sizeof(*openConn) + strlen_user(ocbn.pName->pString) + strlen_user(ocbn.pServiceType); + cmdlen = datalen + sizeof(*cmd); + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + cmd->NwcCommand = NWC_OPEN_CONN_BY_NAME; + + cmd->dataLen = datalen; + openConn = (PNwdCOpenConnByName)cmd->data; + + openConn->nameLen = strlen_user(ocbn.pName->pString); + openConn->serviceLen = strlen_user(ocbn.pServiceType); + openConn->uConnFlags = ocbn.uConnFlags; + openConn->ConnHandle = ocbn.ConnHandle; + data = (char *)openConn; + data += sizeof(*openConn); + openConn->oName = sizeof(*openConn); + + openConn->oServiceType = openConn->oName + openConn->nameLen; + cpylen = copy_from_user(data, ocbn.pName->pString, openConn->nameLen); + data += openConn->nameLen; + cpylen = copy_from_user(data, ocbn.pServiceType, openConn->serviceLen); + + retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + /* + * we got reply data from the daemon + */ + connReply = (PNwdCOpenConnByName)reply->data; + retCode = reply->Reply.ErrorCode; + if (!retCode) + { + /* + * we got valid data. + */ + connReply = (PNwdCOpenConnByName)reply->data; + ocbn.RetConnHandle = connReply->newConnHandle; + *Handle = connReply->newConnHandle; + cpylen = copy_to_user(pdata->reqData, &ocbn, sizeof(ocbn)); + DbgPrint("New Conn Handle = %X\n", connReply->newConnHandle); + } + Novfs_Free(reply); + } + + Novfs_Free(cmd); + } + + return((int)retCode); + +} + +/*++======================================================================*/ +int NwOpenConnByAddr(PXPLAT pdata, u_long *Handle, session_t Session) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ +PXPLAT_CALL_REQUEST cmd; +PXPLAT_CALL_REPLY reply; +PNwdCOpenConnByAddr openConn, connReply; +NwcOpenConnByAddr ocba; +NwcTranAddr tranAddr; +u_long retCode = 0, cmdlen, datalen, replylen, cpylen; +char addr[MAX_ADDRESS_LENGTH]; + + cpylen = copy_from_user(&ocba, pdata->reqData, sizeof(ocba)); + datalen = sizeof(*openConn); + cmdlen = datalen + sizeof(*cmd); + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + cmd->NwcCommand = NWC_OPEN_CONN_BY_ADDRESS; + cmd->dataLen = datalen; + openConn = (PNwdCOpenConnByAddr)cmd->data; + + cpylen = copy_from_user(&tranAddr, ocba.pTranAddr, sizeof(tranAddr)); + + DbgPrint("NwOpenConnByAddr: tranAddr\n"); + mydump(sizeof(tranAddr), &tranAddr); + + openConn->TranAddr.uTransportType = tranAddr.uTransportType; + openConn->TranAddr.uAddressLength = tranAddr.uAddressLength; + memset(addr, 0xcc, sizeof(addr)-1); + + cpylen = copy_from_user(addr, tranAddr.puAddress, tranAddr.uAddressLength); + + DbgPrint("NwOpenConnByAddr: addr\n"); + mydump(sizeof(addr), addr); + + openConn->TranAddr.oAddress = *(u_long *)(&addr[2]); + + retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + /* + * we got reply data from the daemon + */ + connReply = (PNwdCOpenConnByAddr)reply->data; + retCode = reply->Reply.ErrorCode; + if (!retCode) + { + /* + * we got valid data. + */ + connReply = (PNwdCOpenConnByAddr)reply->data; + ocba.ConnHandle = connReply->ConnHandle; + *Handle = connReply->ConnHandle; + cpylen = copy_to_user(pdata->reqData, &ocba, sizeof(ocba)); + DbgPrint("New Conn Handle = %X\n", connReply->ConnHandle); + } + Novfs_Free(reply); + } + + Novfs_Free(cmd); + } + + return(retCode); + +} + +/*++======================================================================*/ +int NwOpenConnByRef(PXPLAT pdata, u_long *Handle, session_t Session) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ +PXPLAT_CALL_REQUEST cmd; +PXPLAT_CALL_REPLY reply; +PNwdCOpenConnByRef openConn; +NwcOpenConnByReference ocbr; +u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen; + + + cpylen = copy_from_user(&ocbr, pdata->reqData, sizeof(ocbr)); + datalen = sizeof(*openConn); + cmdlen = datalen + sizeof(*cmd); + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + cmd->NwcCommand = NWC_OPEN_CONN_BY_REFERENCE; + cmd->dataLen = datalen; + openConn = (PNwdCOpenConnByRef)cmd->data; + + memcpy(openConn, &ocbr, sizeof(ocbr)); + retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + /* + * we got reply data from the daemon + */ + openConn = (PNwdCOpenConnByRef)reply->data; + retCode = reply->Reply.ErrorCode; + if (!retCode) + { + /* + * we got valid data. + */ + ocbr.ConnHandle = openConn->ConnHandle; + *Handle = openConn->ConnHandle; + + cpylen = copy_to_user(pdata->reqData, &ocbr, sizeof(ocbr)); + DbgPrint("New Conn Handle = %X\n", openConn->ConnHandle); + } + Novfs_Free(reply); + } + + Novfs_Free(cmd); + } + return(retCode); + +} + +/*++======================================================================*/ +int NwRawSend(PXPLAT pdata, session_t Session) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ +NwcRequest xRequest; +PNwcFrag frag, cFrag, reqFrag; +PXPLAT_CALL_REQUEST cmd; +PXPLAT_CALL_REPLY reply; +u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen; +u_long x, totalLen; +PNwdCNCPReq ncpData; +PNwdCNCPRep ncpReply; +u_char *reqData; +unsigned long actualReplyLength=0; + + DbgPrint("[XPLAT] Process Raw NCP Send\n"); + cpylen = copy_from_user(&xRequest, pdata->reqData, sizeof(xRequest)); + + /* + * Figure out the length of the request + */ + frag = Novfs_Malloc(xRequest.uNumReplyFrags * sizeof(NwcFrag), GFP_KERNEL); + + DbgPrint("[XPLAT RawNCP] - Reply Frag Count 0x%X\n", xRequest.uNumReplyFrags); + + if (!frag) + return(retCode); + + cpylen = copy_from_user(frag, xRequest.pReplyFrags, xRequest.uNumReplyFrags * sizeof(NwcFrag)); + totalLen = 0; + + cFrag = frag; + for (x = 0; x < xRequest.uNumReplyFrags; x ++) + { + DbgPrint("[XPLAT - RawNCP] - Frag Len = %d\n", cFrag->uLength); + totalLen += cFrag->uLength; + cFrag++; + } + + + DbgPrint("[XPLAT - RawNCP] - totalLen = %d\n", totalLen); + datalen = 0; + reqFrag = Novfs_Malloc(xRequest.uNumRequestFrags * sizeof(NwcFrag), GFP_KERNEL); + if (!reqFrag) + { + Novfs_Free(frag); + return(retCode); + } + + cpylen = copy_from_user(reqFrag, xRequest.pRequestFrags, xRequest.uNumRequestFrags * sizeof(NwcFrag)); + cFrag = reqFrag; + for (x = 0; x < xRequest.uNumRequestFrags; x ++) + { + datalen += cFrag->uLength; + cFrag++; + } + + /* + * Allocate the cmd Request + */ + cmdlen = datalen + sizeof(*cmd) + sizeof(*ncpData); + DbgPrint("[XPLAT RawNCP] - Frag Count 0x%X\n", xRequest.uNumRequestFrags); + DbgPrint("[XPLAT RawNCP] - Total Command Data Len = %x\n", cmdlen); + + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + cmd->NwcCommand = NWC_RAW_NCP_REQUEST; + + /* + * build the NCP Request + */ + cmd->dataLen = cmdlen - sizeof(*cmd); + ncpData = (PNwdCNCPReq)cmd->data; + ncpData->replyLen = totalLen; + ncpData->requestLen = datalen; + ncpData->ConnHandle = xRequest.ConnHandle; + ncpData->function = xRequest.uFunction; + + + reqData = ncpData->data; + cFrag = reqFrag; + + for (x = 0; x < xRequest.uNumRequestFrags; x ++) + { + cpylen = copy_from_user(reqData, cFrag->pData, cFrag->uLength); + reqData += cFrag->uLength; + cFrag++; + } + + retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); + DbgPrint("RawNCP - reply = %x\n", reply); + DbgPrint("RawNCP - retCode = %x\n", retCode); + + if (reply) + { + /* + * we got reply data from the daemon + */ + ncpReply = (PNwdCNCPRep)reply->data; + retCode = reply->Reply.ErrorCode; + + DbgPrint("RawNCP - Reply Frag Count 0x%X\n", xRequest.uNumReplyFrags); + + /* + * We need to copy the reply frags to the packet. + */ + reqData = ncpReply->data; + cFrag = frag; + + totalLen = ncpReply->replyLen; + for (x = 0; x < xRequest.uNumReplyFrags; x ++) + { + + DbgPrint("RawNCP - Copy Frag %d: 0x%X\n", x, cFrag->uLength); + + datalen = min(cFrag->uLength, totalLen); + + cpylen = copy_to_user(cFrag->pData, reqData, datalen); + totalLen -= datalen; + reqData += datalen; + actualReplyLength += datalen; + + cFrag++; + } + + Novfs_Free(reply); + } + else + { + retCode = -EIO; + } + + Novfs_Free(cmd); + } + xRequest.uActualReplyLength = actualReplyLength; + cpylen = copy_to_user(pdata->reqData, &xRequest, sizeof(xRequest)); + + Novfs_Free(reqFrag); + Novfs_Free(frag); + + return(retCode); +} + +/*++======================================================================*/ +int NwConnClose(PXPLAT pdata, u_long *Handle, session_t Session) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ +PXPLAT_CALL_REQUEST cmd; +PXPLAT_CALL_REPLY reply; +NwcCloseConn cc; +PNwdCCloseConn nwdClose; +u_long retCode = 0, cmdlen, datalen, replylen, cpylen; + + cpylen = copy_from_user(&cc, pdata->reqData, sizeof(cc)); + + datalen = sizeof(*nwdClose); + cmdlen = datalen + sizeof(*cmd); + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + cmd->NwcCommand = NWC_CLOSE_CONN; + + nwdClose = (PNwdCCloseConn)cmd->data; + cmd->dataLen = sizeof(*nwdClose); + nwdClose->ConnHandle = cc.ConnHandle; + *Handle = cc.ConnHandle; + + /* + * send the request + */ + retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, 0); + if (reply) + { + retCode = reply->Reply.ErrorCode; + Novfs_Free(reply); + } + Novfs_Free(cmd); + + } + + return(retCode); + +} + +/*++======================================================================*/ +int NwSysConnClose(PXPLAT pdata, u_long *Handle, session_t Session) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ +PXPLAT_CALL_REQUEST cmd; +PXPLAT_CALL_REPLY reply; +NwcCloseConn cc; +PNwdCCloseConn nwdClose; +u_long retCode = 0, cmdlen, datalen, replylen, cpylen; + + cpylen = copy_from_user(&cc, pdata->reqData, sizeof(cc)); + + datalen = sizeof(*nwdClose); + cmdlen = datalen + sizeof(*cmd); + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + cmd->NwcCommand = NWC_SYS_CLOSE_CONN; + + nwdClose = (PNwdCCloseConn)cmd->data; + cmd->dataLen = sizeof(*nwdClose); + nwdClose->ConnHandle = cc.ConnHandle; + *Handle = cc.ConnHandle; + + /* + * send the request + */ + retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, 0); + if (reply) + { + retCode = reply->Reply.ErrorCode; + Novfs_Free(reply); + } + Novfs_Free(cmd); + + } + + return(retCode); + +} + +/*++======================================================================*/ +int NwLoginIdentity(PXPLAT pdata, session_t Session) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ +NwcLoginIdentity lgn, *plgn; +int retCode = -ENOMEM; +NclString server; +NclString username; +NclString password; +u_long cpylen; +NwcString nwcStr; + + cpylen = copy_from_user(&lgn, pdata->reqData, sizeof(lgn)); + + DbgPrint("NwLoginIdentity:\n"); + mydump(sizeof(lgn), &lgn); + + + + cpylen = copy_from_user(&nwcStr, lgn.pDomainName, sizeof(nwcStr)); + DbgPrint("NwLoginIdentity: DomainName\n"); + mydump(sizeof(nwcStr), &nwcStr); + + if ( (server.buffer = Novfs_Malloc(nwcStr.DataLen, GFP_KERNEL)) ) + { + server.type = nwcStr.DataType; + server.len = nwcStr.DataLen; + if ( !copy_from_user((void *)server.buffer, nwcStr.pBuffer, server.len) ) + { + DbgPrint("NwLoginIdentity: Server\n"); + mydump(server.len, server.buffer); + + cpylen = copy_from_user(&nwcStr, lgn.pObjectName, sizeof(nwcStr)); + DbgPrint("NwLoginIdentity: ObjectName\n"); + mydump(sizeof(nwcStr), &nwcStr); + + if ( (username.buffer = Novfs_Malloc(nwcStr.DataLen, GFP_KERNEL)) ) + { + username.type = nwcStr.DataType; + username.len = nwcStr.DataLen; + if ( !copy_from_user((void *)username.buffer, nwcStr.pBuffer, username.len) ) + { + DbgPrint("NwLoginIdentity: User\n"); + mydump(username.len, username.buffer); + + cpylen = copy_from_user(&nwcStr, lgn.pPassword, sizeof(nwcStr)); + DbgPrint("NwLoginIdentity: Password\n"); + mydump(sizeof(nwcStr), &nwcStr); + + if ( (password.buffer = Novfs_Malloc(nwcStr.DataLen, GFP_KERNEL)) ) + { + password.type = nwcStr.DataType; + password.len = nwcStr.DataLen; + if ( !copy_from_user((void *)password.buffer, nwcStr.pBuffer, password.len) ) + { + retCode = do_login(&server, &username, &password, (u_long *)&lgn.AuthenticationId, Session); + if (retCode) + { + lgn.AuthenticationId = 0; + } + + plgn = (NwcLoginIdentity *)pdata->reqData; + cpylen = copy_to_user(&plgn->AuthenticationId, &lgn.AuthenticationId, sizeof(plgn->AuthenticationId)); + + } + memset(password.buffer, 0, password.len); + Novfs_Free(password.buffer); + } + } + memset(username.buffer, 0, username.len); + Novfs_Free(username.buffer); + } + } + Novfs_Free(server.buffer); + } + return(retCode); +} + +/*++======================================================================*/ +int NwAuthConnWithId(PXPLAT pdata, session_t Session) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ +NwcAuthenticateWithId pauth; +PNwdCAuthenticateWithId pDauth; +PXPLAT_CALL_REQUEST cmd; +PXPLAT_CALL_REPLY reply; +u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen; + + datalen = sizeof(*pDauth); + cmdlen = datalen + sizeof(*cmd); + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + cmd->NwcCommand = NWC_AUTHENTICATE_CONN_WITH_ID; + + + cpylen = copy_from_user(&pauth, pdata->reqData, sizeof(pauth)); + + pDauth = (PNwdCAuthenticateWithId)cmd->data; + cmd->dataLen = datalen; + pDauth->AuthenticationId = pauth.AuthenticationId; + pDauth->ConnHandle = pauth.ConnHandle; + + retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + retCode = reply->Reply.ErrorCode; + Novfs_Free(reply); + } + Novfs_Free(cmd); + } + return(retCode); +} + +/*++======================================================================*/ +int NwLicenseConn(PXPLAT pdata, session_t Session) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ +PXPLAT_CALL_REQUEST cmd; +PXPLAT_CALL_REPLY reply; +NwcLicenseConn lisc; +PNwdCLicenseConn pDLisc; +u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen; + + datalen = sizeof(*pDLisc); + cmdlen = datalen + sizeof(*cmd); + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + cmd->NwcCommand = NWC_LICENSE_CONN; + + + cpylen = copy_from_user(&lisc, pdata->reqData, sizeof(lisc)); + + pDLisc = (PNwdCLicenseConn)cmd->data; + cmd->dataLen = datalen; + pDLisc->ConnHandle = lisc.ConnHandle; + + retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + retCode = reply->Reply.ErrorCode; + Novfs_Free(reply); + } + Novfs_Free(cmd); + } + return(retCode); +} + + +/*++======================================================================*/ +int NwLogoutIdentity(PXPLAT pdata, session_t Session) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ +PXPLAT_CALL_REQUEST cmd; +PXPLAT_CALL_REPLY reply; +NwcLogoutIdentity logout; +PNwdCLogoutIdentity pDLogout; +u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen; + + datalen = sizeof(*pDLogout); + cmdlen = datalen + sizeof(*cmd); + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + cmd->NwcCommand = NWC_LOGOUT_IDENTITY; + + cpylen = copy_from_user(&logout, pdata->reqData, sizeof(logout)); + + pDLogout = (PNwdCLogoutIdentity)cmd->data; + cmd->dataLen = datalen; + pDLogout->AuthenticationId = logout.AuthenticationId; + + retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + retCode = reply->Reply.ErrorCode; + Novfs_Free(reply); + } + Novfs_Free(cmd); + } + return(retCode); +} + +/*++======================================================================*/ +int NwUnlicenseConn(PXPLAT pdata, session_t Session) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ +PXPLAT_CALL_REQUEST cmd; +PXPLAT_CALL_REPLY reply; +PNwdCUnlicenseConn pUconn; +NwcUnlicenseConn ulc; +u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen; + + + cpylen = copy_from_user(&ulc, pdata->reqData, sizeof(ulc)); + datalen = sizeof(*pUconn); + cmdlen = datalen + sizeof(*cmd); + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + cmd->NwcCommand = NWC_UNLICENSE_CONN; + cmd->dataLen = datalen; + pUconn = (PNwdCUnlicenseConn)cmd->data; + + pUconn->ConnHandle = ulc.ConnHandle; + retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + /* + * we got reply data from the daemon + */ + retCode = reply->Reply.ErrorCode; + Novfs_Free(reply); + } + + Novfs_Free(cmd); + } + return(retCode); + +} + + +/*++======================================================================*/ +int NwUnAuthenticate(PXPLAT pdata, session_t Session) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ +PXPLAT_CALL_REQUEST cmd; +PXPLAT_CALL_REPLY reply; +NwcUnauthenticate auth; +PNwdCUnauthenticate pDAuth; +u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen; + + datalen = sizeof(*pDAuth); + cmdlen = datalen + sizeof(*cmd); + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + cmd->NwcCommand = NWC_UNAUTHENTICATE_CONN; + + cpylen = copy_from_user(&auth, pdata->reqData, sizeof(auth)); + + pDAuth = (PNwdCUnauthenticate)cmd->data; + cmd->dataLen = datalen; + pDAuth->AuthenticationId = auth.AuthenticationId; + pDAuth->ConnHandle = auth.ConnHandle; + + retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + retCode = reply->Reply.ErrorCode; + Novfs_Free(reply); + } + Novfs_Free(cmd); + } + return(retCode); + +} + + +/*++======================================================================*/ +int NwGetConnInfo(PXPLAT pdata, session_t Session) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ +PXPLAT_CALL_REQUEST cmd; +PXPLAT_CALL_REPLY reply; +NwcGetConnInfo connInfo; +PNwdCGetConnInfo pDConnInfo; +u_long retCode = -ENOMEM, cmdlen, replylen, cpylen; + + cmdlen = sizeof(*cmd) + sizeof(*pDConnInfo); + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + cpylen = copy_from_user(&connInfo, pdata->reqData, sizeof(NwcGetConnInfo)); + + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + cmd->NwcCommand = NWC_GET_CONN_INFO; + + pDConnInfo = (PNwdCGetConnInfo)cmd->data; + + pDConnInfo->ConnHandle = connInfo.ConnHandle; + pDConnInfo->uInfoLevel = connInfo.uInfoLevel; + pDConnInfo->uInfoLength = connInfo.uInfoLength; + cmd->dataLen = sizeof(*pDConnInfo); + + retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + retCode = reply->Reply.ErrorCode; + GetConnData(&connInfo, cmd, reply); + + Novfs_Free(reply); + } + Novfs_Free(cmd); + + } + + return(retCode); + +} + + +/*++======================================================================*/ +int NwSetConnInfo(PXPLAT pdata, session_t Session) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ +PXPLAT_CALL_REQUEST cmd; +PXPLAT_CALL_REPLY reply; +NwcSetConnInfo connInfo; +PNwdCSetConnInfo pDConnInfo; +u_long retCode = -ENOMEM, cmdlen, replylen, cpylen; + + cmdlen = sizeof(*cmd) + sizeof(*pDConnInfo); + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + cpylen = copy_from_user(&connInfo, pdata->reqData, sizeof(NwcSetConnInfo)); + + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + cmd->NwcCommand = NWC_SET_CONN_INFO; + + pDConnInfo = (PNwdCSetConnInfo)cmd->data; + + pDConnInfo->ConnHandle = connInfo.ConnHandle; + pDConnInfo->uInfoLevel = connInfo.uInfoLevel; + pDConnInfo->uInfoLength = connInfo.uInfoLength; + cmd->dataLen = sizeof(*pDConnInfo); + + retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + retCode = reply->Reply.ErrorCode; + Novfs_Free(reply); + } + Novfs_Free(cmd); + + } + + return(retCode); + +} + +/*++======================================================================*/ +int NwGetIdentityInfo(PXPLAT pdata, session_t Session) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ +PXPLAT_CALL_REQUEST cmd; +PXPLAT_CALL_REPLY reply; +NwcGetIdentityInfo qidInfo, *gId; +PNwdCGetIdentityInfo idInfo; +NwcString xferStr; +char *str; +u_long retCode = -ENOMEM, cmdlen, replylen, cpylen; + + cmdlen = sizeof(*cmd) + sizeof(*idInfo); + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + cpylen = copy_from_user(&qidInfo, pdata->reqData, sizeof(qidInfo)); + + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + cmd->NwcCommand = NWC_GET_IDENTITY_INFO; + + idInfo = (PNwdCGetIdentityInfo)cmd->data; + + idInfo->AuthenticationId = qidInfo.AuthenticationId; + cmd->dataLen = sizeof(*idInfo); + + retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + retCode = reply->Reply.ErrorCode; + + if (!reply->Reply.ErrorCode) + { + /* + * Save the return info to the user structure. + */ + gId = pdata->reqData; + idInfo = (PNwdCGetIdentityInfo)reply->data; + cpylen = copy_to_user(&gId->AuthenticationId, &idInfo->AuthenticationId, sizeof(idInfo->AuthenticationId)); + cpylen = copy_to_user(&gId->AuthType, &idInfo->AuthType, sizeof(idInfo->AuthType)); + cpylen = copy_to_user(&gId->IdentityFlags, &idInfo->IdentityFlags, sizeof(idInfo->IdentityFlags)); + cpylen = copy_to_user(&gId->NameType, &idInfo->NameType, sizeof(idInfo->NameType)); + cpylen = copy_to_user(&gId->ObjectType, &idInfo->ObjectType, sizeof(idInfo->ObjectType)); + + cpylen = copy_from_user(&xferStr, gId->pDomainName, sizeof(NwcString)); + str = (char *)((char *)reply->data + idInfo->pDomainNameOffset); + cpylen = copy_to_user(xferStr.pBuffer, str, idInfo->domainLen); + xferStr.DataType = NWC_STRING_TYPE_ASCII; + xferStr.DataLen = idInfo->domainLen; + cpylen = copy_to_user(gId->pDomainName, &xferStr, sizeof(NwcString)); + + + cpylen = copy_from_user(&xferStr, gId->pObjectName, sizeof(NwcString)); + str = (char *)((char *)reply->data + idInfo->pObjectNameOffset); + cpylen = copy_to_user(xferStr.pBuffer, str, idInfo->objectLen); + xferStr.DataLen = idInfo->objectLen - 1; + xferStr.DataType = NWC_STRING_TYPE_ASCII; + cpylen = copy_to_user(gId->pObjectName, &xferStr, sizeof(NwcString)); + } + + Novfs_Free(reply); + } + Novfs_Free(cmd); + + } + + return(retCode); +} + +/*++======================================================================*/ +int NwScanConnInfo(PXPLAT pdata, session_t Session) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ +PXPLAT_CALL_REQUEST cmd; +PXPLAT_CALL_REPLY reply; +NwcScanConnInfo connInfo, *rInfo; +PNwdCScanConnInfo pDConnInfo; +u_long retCode = -ENOMEM, cmdlen, replylen, cpylen; +u_char *localData; + + cpylen = copy_from_user(&connInfo, pdata->reqData, sizeof(NwcScanConnInfo)); + + cmdlen = sizeof(*cmd) + sizeof(*pDConnInfo) + connInfo.uScanInfoLen; + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + cmd->NwcCommand = NWC_SCAN_CONN_INFO; + + pDConnInfo = (PNwdCScanConnInfo)cmd->data; + + DbgPrint("NwScanConnInfo: Input Data\n"); + DbgPrint("connInfo.uScanIndex = 0x%X\n", connInfo.uScanIndex); + DbgPrint("connInfo.uConnectionReference = 0x%X\n", connInfo.uConnectionReference); + DbgPrint("connInfo.uScanInfoLevel = 0x%X\n", connInfo.uScanInfoLevel); + DbgPrint("connInfo.uScanInfoLen = 0x%X\n", connInfo.uScanInfoLen); + DbgPrint("connInfo.uReturnInfoLength = 0x%X\n", connInfo.uReturnInfoLength); + DbgPrint("connInfo.uReturnInfoLevel = 0x%X\n", connInfo.uReturnInfoLevel); + DbgPrint("connInfo.uScanFlags = 0x%X\n", connInfo.uScanFlags); + + + pDConnInfo->uScanIndex = connInfo.uScanIndex; + pDConnInfo->uConnectionReference = connInfo.uConnectionReference; + pDConnInfo->uScanInfoLevel = connInfo.uScanInfoLevel; + pDConnInfo->uScanInfoLen = connInfo.uScanInfoLen; + pDConnInfo->uReturnInfoLength = connInfo.uReturnInfoLength; + pDConnInfo->uReturnInfoLevel = connInfo.uReturnInfoLevel; + pDConnInfo->uScanFlags = connInfo.uScanFlags; + + if (pDConnInfo->uScanInfoLen) + { + localData = (u_char *)pDConnInfo; + pDConnInfo->uScanConnInfoOffset = sizeof(*pDConnInfo); + localData += pDConnInfo->uScanConnInfoOffset; + cpylen = copy_from_user(localData, connInfo.pScanConnInfo, connInfo.uScanInfoLen); + } + else + { + pDConnInfo->uScanConnInfoOffset = 0; + } + + + cmd->dataLen = sizeof(*pDConnInfo); + + retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + DbgPrint("NwScanConnInfo: Reply recieved\n"); + DbgPrint(" NextIndex = %x\n", connInfo.uScanIndex); + DbgPrint(" ErrorCode = %x\n", reply->Reply.ErrorCode); + DbgPrint(" data = %x\n", reply->data); + + pDConnInfo = (PNwdCScanConnInfo)reply->data; + retCode = (u_long)reply->Reply.ErrorCode; + if (!retCode) + { + GetUserData(&connInfo, cmd, reply); + rInfo = (NwcScanConnInfo *)pdata->repData; + cpylen = copy_to_user(pdata->repData, &pDConnInfo->uScanIndex, sizeof(pDConnInfo->uScanIndex)); + cpylen = copy_to_user(&rInfo->uConnectionReference, &pDConnInfo->uConnectionReference, sizeof(pDConnInfo->uConnectionReference)); + } + else + { + u_long x; + + x = 0; + rInfo = (NwcScanConnInfo *)pdata->reqData; + cpylen = copy_to_user(&rInfo->uConnectionReference, &x, sizeof(rInfo->uConnectionReference)); + } + + Novfs_Free(reply); + } + else + { + retCode = -EIO; + } + Novfs_Free(cmd); + + } + + return(retCode); +} + +/*++======================================================================*/ +void GetUserData(NwcScanConnInfo *connInfo, PXPLAT_CALL_REQUEST cmd, PXPLAT_CALL_REPLY reply) +/* + * Abstract: Copies the user data out of the scan conn info call. + * + *========================================================================*/ + +{ +u_long uLevel; +PNwdCScanConnInfo pDConnInfo; + +u_char *srcData = NULL; +u_long dataLen = 0, cpylen; + + + pDConnInfo = (PNwdCScanConnInfo)reply->data; + uLevel = pDConnInfo->uReturnInfoLevel; + DbgPrint("[GetUserData] uLevel = %d, reply = 0x%X, reply->data = 0x%X\n", uLevel, reply, reply->data); + + switch(uLevel) + { + case NWC_CONN_INFO_RETURN_ALL: + case NWC_CONN_INFO_TRAN_ADDR: + case NWC_CONN_INFO_NDS_STATE: + case NWC_CONN_INFO_MAX_PACKET_SIZE: + case NWC_CONN_INFO_LICENSE_STATE: + case NWC_CONN_INFO_PUBLIC_STATE: + case NWC_CONN_INFO_SERVICE_TYPE: + case NWC_CONN_INFO_DISTANCE: + case NWC_CONN_INFO_SERVER_VERSION: + case NWC_CONN_INFO_AUTH_ID: + case NWC_CONN_INFO_SUSPENDED: + case NWC_CONN_INFO_WORKGROUP_ID: + case NWC_CONN_INFO_SECURITY_STATE: + case NWC_CONN_INFO_CONN_NUMBER: + case NWC_CONN_INFO_USER_ID: + case NWC_CONN_INFO_BCAST_STATE: + case NWC_CONN_INFO_CONN_REF: + case NWC_CONN_INFO_AUTH_STATE: + case NWC_CONN_INFO_TREE_NAME: + case NWC_CONN_INFO_SERVER_NAME: + case NWC_CONN_INFO_VERSION: + srcData = (u_char *)pDConnInfo; + srcData += pDConnInfo->uReturnConnInfoOffset; + dataLen = pDConnInfo->uReturnInfoLength; + break; + + case NWC_CONN_INFO_RETURN_NONE: + case NWC_CONN_INFO_TREE_NAME_UNICODE: + case NWC_CONN_INFO_SERVER_NAME_UNICODE: + case NWC_CONN_INFO_LOCAL_TRAN_ADDR: + case NWC_CONN_INFO_ALTERNATE_ADDR: + case NWC_CONN_INFO_SERVER_GUID: + default: + break; + } + + if (srcData && dataLen) + { + DbgPrint("Copy Data in GetUserData 0x%X -> 0x%X :: 0x%X\n", + srcData, connInfo->pReturnConnInfo, dataLen); + cpylen = copy_to_user(connInfo->pReturnConnInfo, srcData, dataLen); + } + + return; +} + +/*++======================================================================*/ +void GetConnData(NwcGetConnInfo *connInfo, PXPLAT_CALL_REQUEST cmd, PXPLAT_CALL_REPLY reply) +/* + * Abstract: Copies the user data out of the scan conn info call. + * + *========================================================================*/ + +{ +u_long uLevel; +PNwdCGetConnInfo pDConnInfo; + +u_char *srcData = NULL; +u_long dataLen = 0, cpylen; + + + pDConnInfo = (PNwdCGetConnInfo)cmd->data; + uLevel = pDConnInfo->uInfoLevel; + + switch(uLevel) + { + case NWC_CONN_INFO_RETURN_ALL: + srcData = (u_char *)reply->data; + dataLen = reply->dataLen; + break; + + case NWC_CONN_INFO_RETURN_NONE: + dataLen = 0; + break; + + case NWC_CONN_INFO_TRAN_ADDR: + { + u_char *dstData = connInfo->pConnInfo; + NwcTranAddr tranAddr; + + srcData = (u_char *)reply->data; + + cpylen = copy_from_user(&tranAddr, dstData, sizeof(tranAddr)); + tranAddr.uTransportType = ((PNwdTranAddr)srcData)->uTransportType; + tranAddr.uAddressLength = ((PNwdTranAddr)srcData)->uAddressLength; + cpylen = copy_to_user(dstData, &tranAddr, sizeof(tranAddr)); + cpylen = copy_to_user(tranAddr.puAddress, ((PNwdTranAddr)srcData)->Buffer, ((PNwdTranAddr)srcData)->uAddressLength); + dataLen=0; + break; + } + case NWC_CONN_INFO_NDS_STATE: + case NWC_CONN_INFO_MAX_PACKET_SIZE: + case NWC_CONN_INFO_LICENSE_STATE: + case NWC_CONN_INFO_PUBLIC_STATE: + case NWC_CONN_INFO_SERVICE_TYPE: + case NWC_CONN_INFO_DISTANCE: + case NWC_CONN_INFO_SERVER_VERSION: + case NWC_CONN_INFO_AUTH_ID: + case NWC_CONN_INFO_SUSPENDED: + case NWC_CONN_INFO_WORKGROUP_ID: + case NWC_CONN_INFO_SECURITY_STATE: + case NWC_CONN_INFO_CONN_NUMBER: + case NWC_CONN_INFO_USER_ID: + case NWC_CONN_INFO_BCAST_STATE: + case NWC_CONN_INFO_CONN_REF: + case NWC_CONN_INFO_AUTH_STATE: + case NWC_CONN_INFO_VERSION: + case NWC_CONN_INFO_SERVER_NAME: + case NWC_CONN_INFO_TREE_NAME: + srcData = (u_char *)reply->data; + dataLen = reply->dataLen; + break; + + case NWC_CONN_INFO_TREE_NAME_UNICODE: + case NWC_CONN_INFO_SERVER_NAME_UNICODE: + break; + + case NWC_CONN_INFO_LOCAL_TRAN_ADDR: + break; + + case NWC_CONN_INFO_ALTERNATE_ADDR: + break; + + case NWC_CONN_INFO_SERVER_GUID: + break; + + default: + break; + } + + if (srcData && dataLen) + { + cpylen = copy_to_user(connInfo->pConnInfo, srcData, connInfo->uInfoLength); + } + + return; +} + +/*++======================================================================*/ +int NwGetDaemonVersion(PXPLAT pdata, session_t Session) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ + +{ +PXPLAT_CALL_REQUEST cmd; +PXPLAT_CALL_REPLY reply; +PNwdCGetRequesterVersion pDVersion; +u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen; + + datalen = sizeof(*pDVersion); + cmdlen = datalen + sizeof(*cmd); + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + cmd->NwcCommand = NWC_GET_REQUESTER_VERSION; + cmdlen = sizeof(*cmd); + retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + retCode = reply->Reply.ErrorCode; + pDVersion = (PNwdCGetRequesterVersion)reply->data; + cpylen = copy_to_user(pDVersion, pdata->reqData, sizeof(*pDVersion)); + Novfs_Free(reply); + } + Novfs_Free(cmd); + } + return(retCode); + +} + + +/*++======================================================================*/ +int NwcGetPreferredDSTree(PXPLAT pdata, session_t Session) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ + +{ +PXPLAT_CALL_REQUEST cmd; +PXPLAT_CALL_REPLY reply; +PNwdCGetPreferredDsTree pDGetTree; +NwcGetPreferredDsTree xplatCall, *p; +u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen; +u_char *dPtr; + + cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcGetPreferredDsTree)); + datalen = sizeof(*pDGetTree) + xplatCall.uTreeLength; + cmdlen = datalen + sizeof(*cmd); + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + cmd->NwcCommand = NWC_GET_PREFERRED_DS_TREE; + cmdlen = sizeof(*cmd); + + retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + retCode = reply->Reply.ErrorCode; + if (!retCode) + { + pDGetTree = (PNwdCGetPreferredDsTree)reply->data; + dPtr = reply->data + pDGetTree->DsTreeNameOffset; + p = (NwcGetPreferredDsTree *)pdata->reqData; + + DbgPrint("NwcGetPreferredDSTree: Reply recieved\n"); + DbgPrint(" TreeLen = %x\n", pDGetTree->uTreeLength); + DbgPrint(" TreeName = %s\n", dPtr); + + cpylen = copy_to_user(p, &pDGetTree->uTreeLength, 4); + cpylen = copy_to_user(xplatCall.pDsTreeName, dPtr, pDGetTree->uTreeLength); + } + Novfs_Free(reply); + } + Novfs_Free(cmd); + } + return(retCode); + +} + +/*++======================================================================*/ +int NwcSetPreferredDSTree(PXPLAT pdata, session_t Session) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ + +{ +PXPLAT_CALL_REQUEST cmd; +PXPLAT_CALL_REPLY reply; +PNwdCSetPreferredDsTree pDSetTree; +NwcSetPreferredDsTree xplatCall; +u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen; +u_char *dPtr; + + cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcSetPreferredDsTree)); + datalen = sizeof(*pDSetTree) + xplatCall.uTreeLength; + cmdlen = datalen + sizeof(*cmd); + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + cmd->NwcCommand = NWC_SET_PREFERRED_DS_TREE; + + pDSetTree = (PNwdCSetPreferredDsTree)cmd->data; + pDSetTree->DsTreeNameOffset = sizeof(*pDSetTree); + pDSetTree->uTreeLength = xplatCall.uTreeLength; + + dPtr = cmd->data + sizeof(*pDSetTree); + cpylen = copy_from_user(dPtr, xplatCall.pDsTreeName, xplatCall.uTreeLength); + + + retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + retCode = reply->Reply.ErrorCode; + Novfs_Free(reply); + } + Novfs_Free(cmd); + } + return(retCode); + +} + + +/*++======================================================================*/ +int NwcSetDefaultNameCtx(PXPLAT pdata, session_t Session) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ + +{ +PXPLAT_CALL_REQUEST cmd; +PXPLAT_CALL_REPLY reply; +NwcSetDefaultNameContext xplatCall; +PNwdCSetDefaultNameContext pDSet; +u_long retCode = -ENOMEM, cmdlen, datalen, replylen, cpylen; +u_char *dPtr; + + cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcSetDefaultNameContext)); + datalen = sizeof(*pDSet) + xplatCall.uTreeLength + xplatCall.uNameLength; + cmdlen = datalen + sizeof(*cmd); + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + cmd->NwcCommand = NWC_SET_DEFAULT_NAME_CONTEXT; + cmd->dataLen = sizeof(NwdCSetDefaultNameContext) + xplatCall.uTreeLength + xplatCall.uNameLength; + + pDSet = (PNwdCSetDefaultNameContext)cmd->data; + dPtr = cmd->data; + + pDSet->TreeOffset = sizeof(NwdCSetDefaultNameContext); + pDSet->uTreeLength = xplatCall.uTreeLength; + pDSet->NameContextOffset = pDSet->TreeOffset+xplatCall.uTreeLength; + pDSet->uNameLength = xplatCall.uNameLength; + + cpylen = copy_from_user(dPtr+pDSet->TreeOffset, xplatCall.pTreeName, xplatCall.uTreeLength); + cpylen = copy_from_user(dPtr+pDSet->NameContextOffset, xplatCall.pNameContext, xplatCall.uNameLength); + + retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + retCode = reply->Reply.ErrorCode; + Novfs_Free(reply); + } + Novfs_Free(cmd); + } + return(retCode); + +} + +/*++======================================================================*/ +int NwcGetDefaultNameCtx(PXPLAT pdata, session_t Session) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ + +{ +PXPLAT_CALL_REQUEST cmd; +PXPLAT_CALL_REPLY reply; +NwcGetDefaultNameContext xplatCall; +PNwdCGetDefaultNameContext pGet; +char *dPtr; +int retCode = -ENOMEM; +u_long cmdlen, replylen, cpylen; + + cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcGetDefaultNameContext)); + cmdlen = sizeof(*cmd) + sizeof(NwdCGetDefaultNameContext) + xplatCall.uTreeLength; + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + cmd->NwcCommand = NWC_GET_DEFAULT_NAME_CONTEXT; + cmd->dataLen = sizeof(NwdCGetDefaultNameContext)+xplatCall.uTreeLength; + + pGet = (PNwdCGetDefaultNameContext)cmd->data; + dPtr = cmd->data; + + pGet->TreeOffset = sizeof(NwdCGetDefaultNameContext); + pGet->uTreeLength = xplatCall.uTreeLength; + + cpylen = copy_from_user( dPtr + pGet->TreeOffset, xplatCall.pTreeName, xplatCall.uTreeLength); + dPtr[pGet->TreeOffset+pGet->uTreeLength] = 0; + + retCode = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + retCode = reply->Reply.ErrorCode; + if (!retCode) + { + pGet = (PNwdCGetDefaultNameContext)reply->data; + + DbgPrint("NwcGetDefaultNameCtx: retCode=0x%x uNameLength1=%d uNameLength2=%d\n", retCode, pGet->uNameLength, xplatCall.uNameLength); + if (xplatCall.uNameLength < pGet->uNameLength) + { + pGet->uNameLength = xplatCall.uNameLength; + retCode = NWE_BUFFER_OVERFLOW; + } + dPtr = (char *)pGet + pGet->NameContextOffset; + cpylen = copy_to_user(xplatCall.pNameContext, dPtr, pGet->uNameLength); + } + + Novfs_Free(reply); + } + Novfs_Free(cmd); + } + return(retCode); + +} + +/*++======================================================================*/ +int NwQueryFeature(PXPLAT pdata, session_t Session) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + NwcQueryFeature xpCall; + int status = SUCCESS; + u_long cpylen; + + cpylen = copy_from_user(&xpCall, pdata->reqData, sizeof(NwcQueryFeature)); + switch (xpCall.Feature) + { + case NWC_FEAT_NDS: + case NWC_FEAT_NDS_MTREE: + case NWC_FEAT_PRN_CAPTURE: + case NWC_FEAT_NDS_RESOLVE: + + status = NWE_REQUESTER_FAILURE; + + } + return( status ); +} + +/*++======================================================================*/ +int NwcGetTreeMonitoredConn(PXPLAT pdata, session_t Session) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ +PXPLAT_CALL_REQUEST cmd; +PXPLAT_CALL_REPLY reply; +NwcGetTreeMonitoredConnRef xplatCall, *p; +PNwdCGetTreeMonitoredConnRef pDConnRef; +char *dPtr; +u_long status = -ENOMEM, cmdlen, datalen, replylen, cpylen; + + cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcGetTreeMonitoredConnRef)); + datalen = sizeof(*pDConnRef) + xplatCall.pTreeName->DataLen; + cmdlen = datalen + sizeof(*cmd); + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + cmd->NwcCommand = NWC_GET_TREE_MONITORED_CONN_REF; + + pDConnRef = (PNwdCGetTreeMonitoredConnRef)cmd->data; + pDConnRef->TreeName.boffset = sizeof(*pDConnRef); + pDConnRef->TreeName.len = xplatCall.pTreeName->DataLen; + pDConnRef->TreeName.type = xplatCall.pTreeName->DataType; + + dPtr = cmd->data + sizeof(*pDConnRef); + cpylen = copy_from_user(dPtr, xplatCall.pTreeName->pBuffer, pDConnRef->TreeName.len); + status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + pDConnRef = (PNwdCGetTreeMonitoredConnRef)reply->data; + dPtr = reply->data + pDConnRef->TreeName.boffset; + p = (NwcGetTreeMonitoredConnRef *)pdata->reqData; + cpylen = copy_to_user(&p->uConnReference, &pDConnRef->uConnReference, 4); + + status = reply->Reply.ErrorCode; + Novfs_Free(reply); + } + Novfs_Free(cmd); + + } + + return(status); +} + +/*++======================================================================*/ +int NwcEnumIdentities(PXPLAT pdata, session_t Session) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ +PXPLAT_CALL_REQUEST cmd; +PXPLAT_CALL_REPLY reply; +NwcEnumerateIdentities xplatCall, *eId; +PNwdCEnumerateIdentities pEnum; +NwcString xferStr; +char *str; +u_long status = -ENOMEM, cmdlen, datalen, replylen, cpylen; + + cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcEnumerateIdentities)); + datalen = sizeof(*pEnum); + cmdlen = datalen + sizeof(*cmd); + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + + if (cmd) + { + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + cmd->NwcCommand = NWC_ENUMERATE_IDENTITIES; + + DbgPrint("NwcEnumIdentities: Send Request\n"); + DbgPrint(" iterator = %x\n", xplatCall.Iterator); + DbgPrint(" cmdlen = %d\n", cmdlen); + + pEnum = (PNwdCEnumerateIdentities)cmd->data; + pEnum->Iterator = xplatCall.Iterator; + status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + status = reply->Reply.ErrorCode; + + eId = pdata->repData; + pEnum = (PNwdCEnumerateIdentities)reply->data; + cpylen = copy_to_user(&eId->Iterator, &pEnum->Iterator, sizeof(pEnum->Iterator)); + DbgPrint("[XPLAT NWCAPI] Found AuthId 0x%X\n", pEnum->AuthenticationId); + cpylen = copy_to_user(&eId->AuthenticationId, &pEnum->AuthenticationId, sizeof(pEnum->AuthenticationId)); + cpylen = copy_to_user(&eId->AuthType, &pEnum->AuthType, sizeof(pEnum->AuthType)); + cpylen = copy_to_user(&eId->IdentityFlags, &pEnum->IdentityFlags, sizeof(pEnum->IdentityFlags)); + cpylen = copy_to_user(&eId->NameType, &pEnum->NameType, sizeof(pEnum->NameType)); + cpylen = copy_to_user(&eId->ObjectType, &pEnum->ObjectType, sizeof(pEnum->ObjectType)); + + if (!status) + { + cpylen = copy_from_user(&xferStr, eId->pDomainName, sizeof(NwcString)); + str = (char *)((char *)reply->data + pEnum->domainNameOffset); + DbgPrint("[XPLAT NWCAPI] Found Domain %s\n", str); + cpylen = copy_to_user(xferStr.pBuffer, str, pEnum->domainNameLen); + xferStr.DataType = NWC_STRING_TYPE_ASCII; + xferStr.DataLen = pEnum->domainNameLen - 1; + cpylen = copy_to_user(eId->pDomainName, &xferStr, sizeof(NwcString)); + + + cpylen = copy_from_user(&xferStr, eId->pObjectName, sizeof(NwcString)); + str = (char *)((char *)reply->data + pEnum->objectNameOffset); + DbgPrint("[XPLAT NWCAPI] Found User %s\n", str); + cpylen = copy_to_user(xferStr.pBuffer, str, pEnum->objectNameLen); + xferStr.DataType = NWC_STRING_TYPE_ASCII; + xferStr.DataLen = pEnum->objectNameLen - 1; + cpylen = copy_to_user(eId->pObjectName, &xferStr, sizeof(NwcString)); + } + + Novfs_Free(reply); + + } + Novfs_Free(cmd); + + } + return(status); +} + +/*++======================================================================*/ +int NwcChangeAuthKey(PXPLAT pdata, session_t Session) +/* + * Arguments: + * + * Returns: + * + * Abstract: Change the password on the server + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ +PXPLAT_CALL_REQUEST cmd; +PXPLAT_CALL_REPLY reply; +NwcChangeKey xplatCall; +PNwdCChangeKey pNewKey; +NwcString xferStr; +char *str; +u_long status = -ENOMEM, cmdlen, datalen, replylen, cpylen; + + cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcChangeKey)); + + datalen = sizeof(NwdCChangeKey) + xplatCall.pDomainName->DataLen + xplatCall.pObjectName->DataLen + + xplatCall.pNewPassword->DataLen + xplatCall.pVerifyPassword->DataLen; + + cmdlen = sizeof(*cmd) + datalen; + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + + if (cmd) + { + pNewKey = (PNwdCChangeKey)cmd->data; + cmd->dataLen = datalen; + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + cmd->NwcCommand = NWC_CHANGE_KEY; + + pNewKey->NameType = xplatCall.NameType; + pNewKey->ObjectType = xplatCall.ObjectType; + pNewKey->AuthType = xplatCall.AuthType; + str = (char *)pNewKey; + + /* + * Get the tree name + */ + str += sizeof(*pNewKey); + cpylen = copy_from_user(&xferStr, xplatCall.pDomainName, sizeof(NwcString)); + pNewKey->domainNameOffset = sizeof(*pNewKey); + cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen); + pNewKey->domainNameLen = xferStr.DataLen; + + /* + * Get the User Name + */ + str += pNewKey->domainNameLen; + cpylen = copy_from_user(&xferStr, xplatCall.pObjectName, sizeof(NwcString)); + pNewKey->objectNameOffset = pNewKey->domainNameOffset + pNewKey->domainNameLen; + cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen); + pNewKey->objectNameLen = xferStr.DataLen; + + /* + * Get the New Password + */ + str += pNewKey->objectNameLen; + cpylen = copy_from_user(&xferStr, xplatCall.pNewPassword, sizeof(NwcString)); + pNewKey->newPasswordOffset = pNewKey->objectNameOffset + pNewKey->objectNameLen; + cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen); + pNewKey->newPasswordLen = xferStr.DataLen; + + /* + * Get the Verify Password + */ + str += pNewKey->newPasswordLen; + cpylen = copy_from_user(&xferStr, xplatCall.pVerifyPassword, sizeof(NwcString)); + pNewKey->verifyPasswordOffset = pNewKey->newPasswordOffset + pNewKey->newPasswordLen; + cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen); + pNewKey->verifyPasswordLen = xferStr.DataLen; + + status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + status = reply->Reply.ErrorCode; + Novfs_Free(reply); + } + memset(cmd, 0, cmdlen); + + Novfs_Free(cmd); + } + + return(status); +} + +/*++======================================================================*/ +int NwcSetPrimaryConn(PXPLAT pdata, session_t Session) +/* + * Arguments: + * + * Returns: + * + * Abstract: Set the primary connection Id + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ +PXPLAT_CALL_REQUEST cmd; +PXPLAT_CALL_REPLY reply; +NwcSetPrimaryConnection xplatCall; +PNwdCSetPrimaryConnection pConn; +u_long status = -ENOMEM, cmdlen, datalen, replylen, cpylen; + + cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcSetPrimaryConnection)); + + datalen = sizeof(NwdCSetPrimaryConnection); + cmdlen = sizeof(*cmd) + datalen; + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + if (cmd) + { + pConn = (PNwdCSetPrimaryConnection)cmd->data; + cmd->dataLen = datalen; + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + cmd->NwcCommand = NWC_SET_PRIMARY_CONN; + pConn->ConnHandle = xplatCall.ConnHandle; + status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); + + if (reply) + { + status = reply->Reply.ErrorCode; + Novfs_Free(reply); + } + + Novfs_Free(cmd); + } + + return(status); +} + +/*++======================================================================*/ +int NwcGetPrimaryConn(PXPLAT pdata, session_t Session) +/* + * Arguments: + * + * Returns: + * + * Abstract: Get the Primary connection + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ +XPLAT_CALL_REQUEST cmd; +PXPLAT_CALL_REPLY reply; +u_long status = -ENOMEM, cmdlen, replylen, cpylen; + + + cmdlen = (u_long)(&((PXPLAT_CALL_REQUEST)0)->data); + + cmd.dataLen = 0; + cmd.Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd.Command.SequenceNumber = 0; + cmd.Command.SessionId = Session; + cmd.NwcCommand = NWC_GET_PRIMARY_CONN; + + status = Queue_Daemon_Command((void *)&cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); + + if (reply) + { + status = reply->Reply.ErrorCode; + if (!status) + { + cpylen = copy_to_user(pdata->repData, reply->data, sizeof(u_long)); + } + + Novfs_Free(reply); + } + + return(status); +} + + +/*++======================================================================*/ +int NwcSetMapDrive(PXPLAT pdata, session_t Session) +/* + * Arguments: + * + * Returns: + * + * Abstract: Get the Primary connection + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + +PXPLAT_CALL_REQUEST cmd; +PXPLAT_CALL_REPLY reply; +u_long status = 0, datalen, cmdlen, replylen, cpylen; +NwcMapDriveEx symInfo; + + DbgPrint("Call to NwcSetMapDrive\n"); + cpylen = copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo)); + cmdlen = sizeof(*cmd); + datalen = sizeof(symInfo) + symInfo.dirPathOffsetLength + symInfo.linkOffsetLength; + + DbgPrint(" cmdlen = %d\n", cmdlen); + DbgPrint(" dataLen = %d\n", datalen); + DbgPrint(" symInfo.dirPathOffsetLength = %d\n", symInfo.dirPathOffsetLength); + DbgPrint(" symInfo.linkOffsetLength = %d\n", symInfo.linkOffsetLength); + DbgPrint(" pdata->datalen = %d\n", pdata->reqLen); + + mydump(sizeof(symInfo), &symInfo); + + cmdlen += datalen; + + + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + if (cmd) + { + cmd->dataLen = datalen; + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + cmd->NwcCommand = NWC_MAP_DRIVE; + + cpylen = copy_from_user(cmd->data, pdata->reqData, datalen); + status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); + + if (reply) + { + status = reply->Reply.ErrorCode; + Novfs_Free(reply); + } + Novfs_Free(cmd); + } + return(status); + +} + +/*++======================================================================*/ +int NwcUnMapDrive(PXPLAT pdata, session_t Session) +/* + * Arguments: + * + * Returns: + * + * Abstract: Get the Primary connection + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ +PXPLAT_CALL_REQUEST cmd; +PXPLAT_CALL_REPLY reply; +u_long status = 0, datalen, cmdlen, replylen, cpylen; +NwcUnmapDriveEx symInfo; + + DbgPrint("Call to NwcUnMapDrive\n"); + + cpylen = copy_from_user(&symInfo, pdata->reqData, sizeof(symInfo)); + cmdlen = sizeof(*cmd); + datalen = sizeof(symInfo) + symInfo.linkLen; + + cmdlen += datalen; + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + if (cmd) + { + cmd->dataLen = datalen; + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + cmd->NwcCommand = NWC_UNMAP_DRIVE; + + cpylen = copy_from_user(cmd->data, pdata->reqData, datalen); + status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); + + if (reply) + { + status = reply->Reply.ErrorCode; + Novfs_Free(reply); + } + Novfs_Free(cmd); + } + + return(status); +} + + +/*++======================================================================*/ +int NwcEnumerateDrives(PXPLAT pdata, session_t Session) +/* + * Arguments: + * + * Returns: + * + * Abstract: Get the Primary connection + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ +PXPLAT_CALL_REQUEST cmd; +PXPLAT_CALL_REPLY reply; +u_long status = 0, cmdlen, replylen, cpylen; +u_long offset; +char *cp; + + DbgPrint("Call to NwcEnumerateDrives\n"); + + cmdlen = sizeof(*cmd); + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + if (cmd) + { + cmd->dataLen = 0; + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + cmd->NwcCommand = NWC_ENUMERATE_DRIVES; + status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); + + if (reply) + { + status = reply->Reply.ErrorCode; + DbgPrint("Status Code = 0x%X\n", status); + if (!status) + { + offset = sizeof(u_long); + cp = reply->data; + replylen = ((PNwcGetMappedDrives)pdata->repData)->MapBuffLen; + cpylen = copy_to_user(pdata->repData, cp, offset); + cp += offset; + cpylen = copy_to_user(((PNwcGetMappedDrives)pdata->repData)->MapBuffer, cp, min(replylen - offset, reply->dataLen - offset)); + } + + Novfs_Free(reply); + } + Novfs_Free(cmd); + } + + return(status); +} + + +/*++======================================================================*/ +int NwcGetBroadcastMessage(PXPLAT pdata, session_t Session) +/* + * Arguments: + * + * Returns: + * + * Abstract: Get the Primary connection + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ +PXPLAT_CALL_REQUEST cmd; +PXPLAT_CALL_REPLY reply; +u_long status = 0x8866, cmdlen, replylen, cpylen; +NwcGetBroadcastNotification msg; +PNwdCGetBroadcastNotification dmsg; + + cmdlen = sizeof(*cmd) + sizeof(*dmsg); + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + if (cmd) + { + + cpylen = copy_from_user(&msg, pdata->reqData, sizeof(msg)); + cmd->dataLen = sizeof(*dmsg); + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + + cmd->NwcCommand = NWC_GET_BROADCAST_MESSAGE; + dmsg = (PNwdCGetBroadcastNotification)cmd->data; + dmsg->uConnReference = msg.uConnReference; + + status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); + + if (reply) + { + status = reply->Reply.ErrorCode; + DbgPrint("Status Code = 0x%X\n", status); + if (!status) + { + /* we have a message so copy it to the user buffer */ + cpylen = copy_to_user(pdata->repData, reply->data, min(pdata->repLen, reply->dataLen)); + } + else + { + msg.messageLen = 0; + msg.message[0] = 0; + cpylen = copy_to_user(pdata->repData, &msg, sizeof(msg)); + } + + Novfs_Free(reply); + } + Novfs_Free(cmd); + } + return(status); + +} + + +int NwdSetKeyValue(PXPLAT pdata, session_t Session) +{ +PXPLAT_CALL_REQUEST cmd; +PXPLAT_CALL_REPLY reply; +NwcSetKey xplatCall; +PNwdCSetKey pNewKey; +NwcString cstrObjectName, cstrPassword; +char *str; +u_long status = -ENOMEM, cmdlen, datalen, replylen, cpylen; + + cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcSetKey)); + cpylen = copy_from_user(&cstrObjectName, xplatCall.pObjectName, sizeof(NwcString)); + cpylen = copy_from_user(&cstrPassword, xplatCall.pNewPassword, sizeof(NwcString)); + + datalen = sizeof(NwdCSetKey) + cstrObjectName.DataLen + cstrPassword.DataLen; + + cmdlen = sizeof(*cmd) + datalen; + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + + if (cmd) + { + pNewKey = (PNwdCSetKey)cmd->data; + cmd->dataLen = datalen; + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + cmd->NwcCommand = NWC_SET_KEY; + + pNewKey->ObjectType = xplatCall.ObjectType; + pNewKey->AuthenticationId = xplatCall.AuthenticationId; + pNewKey->ConnHandle = xplatCall.ConnHandle; + str = (char *)pNewKey; + + /* + * Get the User Name + */ + str += sizeof(NwdCSetKey); + cpylen = copy_from_user(str, cstrObjectName.pBuffer, cstrObjectName.DataLen); + + str += + pNewKey->objectNameLen = cstrObjectName.DataLen; + pNewKey->objectNameOffset = sizeof(NwdCSetKey); + + /* + * Get the Verify Password + */ + cpylen = copy_from_user(str, cstrPassword.pBuffer, cstrPassword.DataLen); + + pNewKey->newPasswordLen = cstrPassword.DataLen; + pNewKey->newPasswordOffset = pNewKey->objectNameOffset+pNewKey->objectNameLen; + + status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + status = reply->Reply.ErrorCode; + Novfs_Free(reply); + } + memset(cmd, 0, cmdlen); + Novfs_Free(cmd); + } + + return(status); +} + +/*++======================================================================*/ +int NwdVerifyKeyValue(PXPLAT pdata, session_t Session) +/* + * Arguments: + * + * Returns: + * + * Abstract: Change the password on the server + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ +PXPLAT_CALL_REQUEST cmd; +PXPLAT_CALL_REPLY reply; +NwcVerifyKey xplatCall; +PNwdCVerifyKey pNewKey; +NwcString xferStr; +char *str; +u_long status = -ENOMEM, cmdlen, datalen, replylen, cpylen; + + cpylen = copy_from_user(&xplatCall, pdata->reqData, sizeof(NwcVerifyKey)); + + datalen = sizeof(NwdCVerifyKey) + xplatCall.pDomainName->DataLen + xplatCall.pObjectName->DataLen + + xplatCall.pVerifyPassword->DataLen; + + cmdlen = sizeof(*cmd) + datalen; + cmd = Novfs_Malloc(cmdlen, GFP_KERNEL); + + if (cmd) + { + pNewKey = (PNwdCVerifyKey)cmd->data; + cmd->dataLen = datalen; + cmd->Command.CommandType = VFS_COMMAND_XPLAT_CALL; + cmd->Command.SequenceNumber = 0; + cmd->Command.SessionId = Session; + cmd->NwcCommand = NWC_VERIFY_KEY; + + pNewKey->NameType = xplatCall.NameType; + pNewKey->ObjectType = xplatCall.ObjectType; + pNewKey->AuthType = xplatCall.AuthType; + str = (char *)pNewKey; + + /* + * Get the tree name + */ + str += sizeof(*pNewKey); + cpylen = copy_from_user(&xferStr, xplatCall.pDomainName, sizeof(NwcString)); + pNewKey->domainNameOffset = sizeof(*pNewKey); + cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen); + pNewKey->domainNameLen = xferStr.DataLen; + + /* + * Get the User Name + */ + str += pNewKey->domainNameLen; + cpylen = copy_from_user(&xferStr, xplatCall.pObjectName, sizeof(NwcString)); + pNewKey->objectNameOffset = pNewKey->domainNameOffset + pNewKey->domainNameLen; + cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen); + pNewKey->objectNameLen = xferStr.DataLen; + + /* + * Get the Verify Password + */ + str += pNewKey->objectNameLen; + cpylen = copy_from_user(&xferStr, xplatCall.pVerifyPassword, sizeof(NwcString)); + pNewKey->verifyPasswordOffset = pNewKey->objectNameOffset + pNewKey->objectNameLen; + cpylen = copy_from_user(str, xferStr.pBuffer, xferStr.DataLen); + pNewKey->verifyPasswordLen = xferStr.DataLen; + + status = Queue_Daemon_Command((void *)cmd, cmdlen, NULL, 0, (void **)&reply, &replylen, INTERRUPTIBLE); + if (reply) + { + status = reply->Reply.ErrorCode; + Novfs_Free(reply); + } + memset(cmd, 0, cmdlen); + Novfs_Free(cmd); + } + + return(status); +} diff -uNr src.old/src/proc.c src/src/proc.c --- src.old/src/proc.c 1970-01-01 01:00:00.000000000 +0100 +++ src/src/proc.c 2006-10-16 15:08:22.000000000 +0200 @@ -0,0 +1,339 @@ +/*++======================================================================== + * Program Name: Novell NCP Redirector for Linux + * File Name: proc.c + * Version: v1.00 + * Author: James Turner + * + * Abstract: This module contains functions that create the + * interface to the proc filesystem. + * Notes: + * Revision History: + * + * + * Copyright (C) 2005 Novell, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *======================================================================--*/ + +/*===[ Include files specific to Linux ]==================================*/ +#include +#include +#include +#include + +/*===[ Include files specific to this module ]============================*/ +#include "vfs.h" + +/*===[ External data ]====================================================*/ +extern char *Novfs_CurrentMount; + +/*===[ External prototypes ]==============================================*/ +extern int DbgPrint( char *Fmt, ... ); + +extern ssize_t +Daemon_Receive_Reply(struct file *file, const char *buf, size_t nbytes, loff_t *ppos); + +extern ssize_t +Daemon_Send_Command(struct file *file, char *buf, size_t len, loff_t *off); + +extern int Daemon_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); + +extern int Daemon_Library_close(struct inode *inode, struct file *file); +extern int Daemon_Library_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); +extern int Daemon_Library_open(struct inode *inode, struct file *file); +extern ssize_t Daemon_Library_read(struct file *file, char *buf, size_t len, loff_t *off); +extern ssize_t Daemon_Library_write(struct file *file, const char *buf, size_t len, loff_t *off); +extern loff_t Daemon_Library_llseek(struct file *file, loff_t offset, int origin); + +extern int Daemon_Open_Control(struct inode *Inode, struct file *File); +extern int Daemon_Close_Control(struct inode *Inode, struct file *File); + +extern int Daemon_getversion( char *Buf, int Length ); + +/*===[ Manifest constants ]===============================================*/ + +/*===[ Type definitions ]=================================================*/ + +/*===[ Function prototypes ]==============================================*/ +ssize_t +Novfs_User_proc_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos); + +ssize_t +Novfs_User_proc_write(struct file * file, char * buf, size_t nbytes, loff_t *ppos); + +int Novfs_User_proc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); + +int Init_Procfs_Interface( void ); +void Uninit_Procfs_Interface( void ); + +/*===[ Global variables ]=================================================*/ +struct proc_dir_entry *Novfs_Procfs_dir, *Novfs_Control, *Novfs_Library, *Novfs_Version; +static struct file_operations Daemon_proc_fops; +static struct file_operations Library_proc_fops; + +/*===[ Code ]=============================================================*/ + +/*++======================================================================*/ +int Novfs_Get_Version(char *page, char **start, off_t off, int count, int *eof, void *data) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + char *buf, tbuf[48]; + int len=0, i; + + if ( !off ) + { + buf = page+off; + *start = buf; + len = sprintf(buf, "Novfs Version=%s\n", NOVFS_VERSION_STRING); + i = Daemon_getversion(tbuf, sizeof(tbuf)); + if ((i > 0) && i < (count-len)) + { + len += sprintf(buf+len, "Novfsd Version=%s\n", tbuf); + } + + if (Novfs_CurrentMount) + { + i = strlen(Novfs_CurrentMount); + if ((i > 0) && i < (count-len)) + { + len += sprintf(buf+len, "Novfs mount=%s\n", Novfs_CurrentMount); + } + } + DbgPrint("Novfs_Get_Version:\n%s\n", buf); + } + *eof = 1; + return(len); +} + +/*++======================================================================*/ +ssize_t +Novfs_User_proc_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + ssize_t retval=0; + + UNUSED_VARIABLE(file); + UNUSED_VARIABLE(buf); + UNUSED_VARIABLE(nbytes); + UNUSED_VARIABLE(ppos); + + DbgPrint( "Novfs_User_proc_read: kernel_locked 0x%x\n", kernel_locked()); + + return retval; +} +/*++======================================================================*/ +ssize_t +Novfs_User_proc_write(struct file * file, char * buf, size_t nbytes, loff_t *ppos) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + ssize_t retval=0; + + UNUSED_VARIABLE(file); + UNUSED_VARIABLE(ppos); + + DbgPrint( "Novfs_User_proc_write: kernel_locked 0x%x\n", kernel_locked()); + if (buf && nbytes) + { + } + + return(retval); +} + +/*++======================================================================*/ +int Novfs_User_proc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int retval=-ENOSYS; + + UNUSED_VARIABLE(inode); + UNUSED_VARIABLE(file); + UNUSED_VARIABLE(cmd); + UNUSED_VARIABLE(arg); + + DbgPrint( "Novfs_User_proc_ioctl: kernel_locked 0x%x\n", kernel_locked()); + + return(retval); +} + +/*++======================================================================*/ +int Init_Procfs_Interface( void ) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + int retCode=0; + + Novfs_Procfs_dir = proc_mkdir(MODULE_NAME, NULL); + if ( Novfs_Procfs_dir ) + { + Novfs_Procfs_dir->owner = THIS_MODULE; + + Novfs_Control = create_proc_entry("Control", 0600, Novfs_Procfs_dir); + + if ( Novfs_Control ) + { + Novfs_Control->owner = THIS_MODULE; + Novfs_Control->size = 0; + memcpy(&Daemon_proc_fops, Novfs_Control->proc_fops, sizeof(struct file_operations)); + + /* + * Setup our functions + */ + Daemon_proc_fops.owner = THIS_MODULE; + Daemon_proc_fops.open = Daemon_Open_Control; + Daemon_proc_fops.release = Daemon_Close_Control; + Daemon_proc_fops.read = Daemon_Send_Command; + Daemon_proc_fops.write = Daemon_Receive_Reply; + Daemon_proc_fops.ioctl = Daemon_ioctl; + + Novfs_Control->proc_fops = &Daemon_proc_fops; + } + else + { + remove_proc_entry(MODULE_NAME, NULL); + return(-ENOENT); + } + + Novfs_Library = create_proc_entry("Library", 0666, Novfs_Procfs_dir); + if ( Novfs_Library ) + { + Novfs_Library->owner = THIS_MODULE; + Novfs_Library->size = 0; + + /* + * Setup our file functions + */ + memcpy(&Library_proc_fops, Novfs_Library->proc_fops, sizeof(struct file_operations)); + Library_proc_fops.owner = THIS_MODULE; + Library_proc_fops.open = Daemon_Library_open; + Library_proc_fops.release = Daemon_Library_close; + Library_proc_fops.read = Daemon_Library_read; + Library_proc_fops.write = Daemon_Library_write; + Library_proc_fops.llseek = Daemon_Library_llseek; + Library_proc_fops.ioctl = Daemon_Library_ioctl; + Novfs_Library->proc_fops = &Library_proc_fops; + } + else + { + remove_proc_entry("Control", Novfs_Procfs_dir); + remove_proc_entry(MODULE_NAME, NULL); + return(-ENOENT); + } + + Novfs_Version = create_proc_read_entry("Version", 0444, Novfs_Procfs_dir, Novfs_Get_Version, NULL); + if ( Novfs_Version ) + { + Novfs_Version->owner = THIS_MODULE; + Novfs_Version->size = 0; + } + else + { + remove_proc_entry("Library", Novfs_Procfs_dir); + remove_proc_entry("Control", Novfs_Procfs_dir); + remove_proc_entry(MODULE_NAME, NULL); + retCode = -ENOENT; + } + } + else + { + retCode = -ENOENT; + } + return(retCode); +} + +/*++======================================================================*/ +void Uninit_Procfs_Interface( void ) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + + DbgPrint("Uninit_Procfs_Interface remove_proc_entry(Version, NULL)\n"); + remove_proc_entry("Version", Novfs_Procfs_dir); + + DbgPrint("Uninit_Procfs_Interface remove_proc_entry(Control, NULL)\n"); + remove_proc_entry("Control", Novfs_Procfs_dir); + + DbgPrint("Uninit_Procfs_Interface remove_proc_entry(Library, NULL)\n"); + remove_proc_entry("Library", Novfs_Procfs_dir); + + DbgPrint("Uninit_Procfs_Interface remove_proc_entry(%s, NULL)\n", MODULE_NAME); + remove_proc_entry(MODULE_NAME, NULL); + + DbgPrint("Uninit_Procfs_Interface done\n"); +} diff -uNr src.old/src/profile.c src/src/profile.c --- src.old/src/profile.c 1970-01-01 01:00:00.000000000 +0100 +++ src/src/profile.c 2006-10-16 15:08:22.000000000 +0200 @@ -0,0 +1,1199 @@ +/*++======================================================================== + * Program Name: Novell NCP Redirector for Linux + * File Name: profile.c + * Version: v1.00 + * Author: James Turner + * + * Abstract: This module contains a debugging code for + * the novfs VFS. + * Notes: + * Revision History: + * + * + * Copyright (C) 2005 Novell, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *======================================================================--*/ + +/*===[ Include files specific to Linux ]==================================*/ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/*===[ Include files specific to this module ]============================*/ +#include "vfs.h" + +/*===[ External data ]====================================================*/ +extern struct dentry *Novfs_root; +extern struct proc_dir_entry *Novfs_Procfs_dir; +extern unsigned long File_update_timeout; +extern int PageCache; + +/*===[ External prototypes ]==============================================*/ +extern void Scope_Dump_Tasklist( void ); +extern void Scope_Dump_Scopetable( void ); +extern void Daemon_Dumpque( void ); +extern char *Scope_dget_path( struct dentry *Dentry, char *Buf, unsigned int Buflen, int Flags); +extern int Novfs_dump_inode_cache(int argc, const char **argv, const char **envp, struct pt_regs *regs); +extern void Novfs_dump_inode( void *pf ); +extern int Daemon_SendDebugCmd ( char *Command ); + + +/*===[ Manifest constants ]===============================================*/ +#define DBGBUFFERSIZE (1024*1024*32) + +/*===[ Type definitions ]=================================================*/ +typedef void daemon_command_t; + +typedef struct _SYMBOL_TABLE { + void *address; + char *name; +} SYMBOL_TABLE, *PSYMBOL_TABLE; + +struct local_rtc_time { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; +}; + +/*===[ Function prototypes ]==============================================*/ +int profile_task_exit_callback(struct notifier_block *self, unsigned long val, void *data) __attribute__((__no_instrument_function__)); +int init_profile( void ); + +char *ctime_r(time_t *clock, char *buf); +int LocalPrint( char *Fmt, ... ) __attribute__((__no_instrument_function__)); +int DbgPrint( char *Fmt, ... ) __attribute__((__no_instrument_function__)); + +void __cyg_profile_func_enter (void *this_fn, void *call_site) __attribute__((__no_instrument_function__)) ; +void __cyg_profile_func_exit (void *this_fn, void *call_site) __attribute__((__no_instrument_function__)); +void doline(unsigned char *b, unsigned char *p, unsigned char *l) __attribute__((__no_instrument_function__)); +void mydump(int size, void *dumpptr) __attribute__((__no_instrument_function__)); +void GregorianDay(struct local_rtc_time * tm) __attribute__((__no_instrument_function__)); +void to_tm(int tim, struct local_rtc_time * tm) __attribute__((__no_instrument_function__)); +char *ctime_r(time_t *clock, char *buf) __attribute__((__no_instrument_function__)); +int profile_dump_tasklist(int argc, const char **argv, const char **envp, struct pt_regs *regs); +int profile_dump_scopetable(int argc, const char **argv, const char **envp, struct pt_regs *regs); +int profile_dump_daemonque(int argc, const char **argv, const char **envp, struct pt_regs *regs); +int profile_dump_DbgBuffer(int argc, const char **argv, const char **envp, struct pt_regs *regs); +int profile_dump_DentryTree(int argc, const char **argv, const char **envp, struct pt_regs *regs); +int profile_dump_inode(int argc, const char **argv, const char **envp, struct pt_regs *regs); + +void *Novfs_Malloc( size_t size, int flags ) __attribute__((__no_instrument_function__)); +void Novfs_Free( const void *p ) __attribute__((__no_instrument_function__)); + +int profile_dump_memorylist_dbg(int argc, const char **argv, const char **envp, struct pt_regs *regs) __attribute__((__no_instrument_function__)); +void profile_dump_memorylist( void *pf ); + +static ssize_t User_proc_write_DbgBuffer(struct file * file, const char __user *buf, size_t nbytes, loff_t *ppos) __attribute__((__no_instrument_function__)); +static ssize_t User_proc_read_DbgBuffer(struct file * file, char * buf, size_t nbytes, loff_t *ppos) __attribute__((__no_instrument_function__)); +static int proc_read_DbgBuffer(char *page, char **start, + off_t off, int count, + int *eof, void *data) __attribute__((__no_instrument_function__)); + +void profile_dump_dt(struct dentry *parent, void *pf ); +ssize_t profile_inode_read(struct file *file, char *buf, size_t len, loff_t *off); +ssize_t profile_dentry_read(struct file *file, char *buf, size_t len, loff_t *off); +ssize_t profile_memory_read(struct file *file, char *buf, size_t len, loff_t *off); +uint64_t get_nanosecond_time( void ); + +/*===[ Global variables ]=================================================*/ +char *DbgPrintBuffer=NULL; +char DbgPrintOn=0; +char DbgSyslogOn=0; +unsigned long DbgPrintBufferOffset=0; +unsigned long DbgPrintBufferReadOffset=0; +unsigned long DbgPrintBufferSize = DBGBUFFERSIZE; + +int Indent = 0; +char IndentString[] = " "; + +static struct file_operations Dbg_proc_file_operations; +static struct file_operations dentry_proc_file_ops; +static struct file_operations inode_proc_file_ops; +static struct file_operations memory_proc_file_ops; + +static struct proc_dir_entry *dbg_dir=NULL, *dbg_file=NULL; +static struct proc_dir_entry *dentry_file=NULL; +static struct proc_dir_entry *inode_file=NULL; +static struct proc_dir_entry *memory_file=NULL; + +static struct notifier_block taskexit_nb; + + +DECLARE_MUTEX(LocalPrint_lock); +spinlock_t Syslog_lock = SPIN_LOCK_UNLOCKED; + +#include "profile_funcs.h" + + +/*===[ Code ]=============================================================*/ +int +profile_task_exit_callback(struct notifier_block *self, unsigned long val, void *data) +{ + struct task_struct *task = (struct task_struct *)data; + + DbgPrint("profile_task_exit_callback: task 0x%p %u exiting %s\n", task, task->pid, task->comm); + return(0); +} + +int init_profile( void ) +{ + int retCode = 0; + + if (Novfs_Procfs_dir) + { + dbg_dir = Novfs_Procfs_dir; + } + else + { + dbg_dir = proc_mkdir(MODULE_NAME, NULL); + } + + if( dbg_dir ) + { + dbg_dir->owner = THIS_MODULE; + dbg_file = create_proc_read_entry("Debug", + 0600, + dbg_dir, + proc_read_DbgBuffer, + NULL); + if ( dbg_file ) + { + dbg_file->owner = THIS_MODULE; + dbg_file->size = DBGBUFFERSIZE; + memcpy(&Dbg_proc_file_operations, dbg_file->proc_fops, sizeof(struct file_operations)); + Dbg_proc_file_operations.read = User_proc_read_DbgBuffer; + Dbg_proc_file_operations.write = User_proc_write_DbgBuffer; + dbg_file->proc_fops = &Dbg_proc_file_operations; + } + else + { + remove_proc_entry(MODULE_NAME, NULL); + vfree( DbgPrintBuffer ); + DbgPrintBuffer = NULL; + } + } + + if ( DbgPrintBuffer ) + { + if( dbg_dir ) + { + inode_file = create_proc_entry("inode", + 0600, + dbg_dir); + if ( inode_file ) + { + inode_file->owner = THIS_MODULE; + inode_file->size = 0; + memcpy(&inode_proc_file_ops, inode_file->proc_fops, sizeof(struct file_operations)); + inode_proc_file_ops.owner = THIS_MODULE; + inode_proc_file_ops.read = profile_inode_read; + inode_file->proc_fops = &inode_proc_file_ops; + } + + dentry_file = create_proc_entry("dentry", + 0600, + dbg_dir); + if ( dentry_file ) + { + dentry_file->owner = THIS_MODULE; + dentry_file->size = 0; + memcpy(&dentry_proc_file_ops, dentry_file->proc_fops, sizeof(struct file_operations)); + dentry_proc_file_ops.owner = THIS_MODULE; + dentry_proc_file_ops.read = profile_dentry_read; + dentry_file->proc_fops = &dentry_proc_file_ops; + } + + memory_file = create_proc_entry("memory", + 0600, + dbg_dir); + if ( memory_file ) + { + memory_file->owner = THIS_MODULE; + memory_file->size = 0; + memcpy(&memory_proc_file_ops, memory_file->proc_fops, sizeof(struct file_operations)); + memory_proc_file_ops.owner = THIS_MODULE; + memory_proc_file_ops.read = profile_memory_read; + memory_file->proc_fops = &memory_proc_file_ops; + } + + } + else + { + vfree( DbgPrintBuffer ); + DbgPrintBuffer = NULL; + } + } + return( retCode ); +} + + +void uninit_profile( void ) +{ + if (dbg_file) DbgPrint("Calling remove_proc_entry(Debug, NULL)\n"), remove_proc_entry( "Debug", dbg_dir ); + if (inode_file) DbgPrint("Calling remove_proc_entry(inode, NULL)\n"), remove_proc_entry( "inode", dbg_dir ); + if (dentry_file) DbgPrint("Calling remove_proc_entry(dentry, NULL)\n"), remove_proc_entry( "dentry", dbg_dir ); + if (memory_file) DbgPrint("Calling remove_proc_entry(memory, NULL)\n"), remove_proc_entry( "memory", dbg_dir ); + + if (dbg_dir && (dbg_dir != Novfs_Procfs_dir)) + { + DbgPrint("Calling remove_proc_entry(%s, NULL)\n", MODULE_NAME); + remove_proc_entry( MODULE_NAME, NULL ); + } +} + + +static +ssize_t +User_proc_write_DbgBuffer(struct file * file, const char __user *buf, size_t nbytes, loff_t *ppos) +{ + ssize_t retval=nbytes; + u_char *lbuf, *p; + int i; + u_long cpylen; + + + UNUSED_VARIABLE( *ppos ); + + lbuf = Novfs_Malloc(nbytes+1, GFP_KERNEL); + if (lbuf) + { + cpylen = copy_from_user(lbuf, buf, nbytes); + + lbuf[nbytes] = 0; + DbgPrint("User_proc_write_DbgBuffer: %s\n", lbuf); + + for (i=0; lbuf[i] && lbuf[i] != '\n'; i++) ; + + if ( '\n' == lbuf[i] ) + { + lbuf[i] = '\0'; + } + + if ( !strcmp("on", lbuf)) + { + DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0; + DbgPrintOn = 1; + } + else if ( !strcmp("off", lbuf)) + { + DbgPrintOn = 0; + } + else if ( !strcmp("reset", lbuf)) + { + DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0; + } + else if ( NULL != (p = strchr(lbuf, ' '))) + { + *p++ = '\0'; + if ( !strcmp("syslog", lbuf)) + { + + if (!strcmp("on", p)) + { + DbgSyslogOn = 1; + } + else if (!strcmp("off", p)) + { + DbgSyslogOn = 0; + } + } + else if ( !strcmp("novfsd", lbuf)) + { + Daemon_SendDebugCmd( p ); + } + else if ( !strcmp("file_update_timeout", lbuf)) + { + File_update_timeout = simple_strtoul(p, NULL, 0); + } + else if ( !strcmp("cache", lbuf)) + { + if (!strcmp("on", p)) + { + PageCache = 1; + } + else if (!strcmp("off", p)) + { + PageCache = 0; + } + } + } + Novfs_Free(lbuf); + } + + return (retval); +} + +static +ssize_t +User_proc_read_DbgBuffer(struct file * file, char * buf, size_t nbytes, loff_t *ppos) + +{ + ssize_t retval=0; + size_t count; + + UNUSED_VARIABLE( *ppos ); + + if (0 != (count = DbgPrintBufferOffset - DbgPrintBufferReadOffset)) + { + + if (count > nbytes) + { + count = nbytes; + } + + count -= copy_to_user(buf, &DbgPrintBuffer[DbgPrintBufferReadOffset], count); + + if (count == 0) + { + if (retval == 0) + retval = -EFAULT; + } + else + { + DbgPrintBufferReadOffset += count; + if (DbgPrintBufferReadOffset >= DbgPrintBufferOffset) + { + DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0; + } + retval = count; + } + } + + return retval; +} + +static +int +proc_read_DbgBuffer(char *page, char **start, + off_t off, int count, + int *eof, void *data) +{ + int len; + static char bufd[512]; + + UNUSED_VARIABLE(start); + UNUSED_VARIABLE(eof); + UNUSED_VARIABLE(data); + + sprintf(bufd, KERN_ALERT "proc_read_DbgBuffer: off=%ld count=%d DbgPrintBufferOffset=%lu DbgPrintBufferReadOffset=%lu\n", + off, count, DbgPrintBufferOffset, DbgPrintBufferReadOffset); + printk(bufd); + + len = DbgPrintBufferOffset - DbgPrintBufferReadOffset; + + if ((int)(DbgPrintBufferOffset-DbgPrintBufferReadOffset) > count) + { + len = count; + } + + if (len) + { + memcpy(page, &DbgPrintBuffer[DbgPrintBufferReadOffset], len); + DbgPrintBufferReadOffset += len; + } + + + if (DbgPrintBufferReadOffset >= DbgPrintBufferOffset) + { + DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0; + } + + sprintf(bufd, KERN_ALERT "proc_read_DbgBuffer: return %d\n", len); + printk(bufd); + + return len; +} + +#define DBG_BUFFER_SIZE (2*1024) + +int +LocalPrint( char *Fmt, ... ) +{ + int len=0; + va_list args; + + if (DbgPrintBuffer) + { + va_start(args, Fmt); + len += vsnprintf(DbgPrintBuffer+DbgPrintBufferOffset, DbgPrintBufferSize-DbgPrintBufferOffset, Fmt, args); + DbgPrintBufferOffset += len; + } + + return(len); +} + + +int +DbgPrint( char *Fmt, ... ) +{ + char *buf; + int len=0; + unsigned long offset; + va_list args; + + if ( (DbgPrintBuffer && DbgPrintOn) || DbgSyslogOn ) + { + buf = kmalloc( DBG_BUFFER_SIZE, GFP_KERNEL ); + + if (buf) + { + va_start(args, Fmt); + len = sprintf(buf, "[%d] ", current->pid); + + len += vsnprintf(buf+len, DBG_BUFFER_SIZE-len, Fmt, args); + if ( -1 == len ) + { + len = DBG_BUFFER_SIZE-1; + buf[len] = '\0'; + } + /* + len = sprintf(&DbgPrintBuffer[offset], "[%llu] ", ts); + len += vsprintf(&DbgPrintBuffer[offset+len], Fmt, args); + */ + + if (len) + { + if (DbgSyslogOn) + { + printk("<6>%s", buf); + } + + if ( DbgPrintBuffer && DbgPrintOn ) + { + if ((DbgPrintBufferOffset+len) > DbgPrintBufferSize) + { + offset = DbgPrintBufferOffset; + DbgPrintBufferOffset = 0; + memset(&DbgPrintBuffer[offset], 0, DbgPrintBufferSize-offset); + } + + mb(); + + if ((DbgPrintBufferOffset+len) < DbgPrintBufferSize) + { + DbgPrintBufferOffset += len; + offset = DbgPrintBufferOffset-len; + memcpy(&DbgPrintBuffer[offset], buf, len+1); + } + } + } + kfree(buf); + } + } + + return(len); +} + +void +__cyg_profile_func_enter (void *this_fn, void *call_site) +{ + PSYMBOL_TABLE sym; + uint64_t t64; + + + if ((void *)init_novfs == this_fn) + { + DbgPrintBuffer = vmalloc(DBGBUFFERSIZE); + taskexit_nb.notifier_call = profile_task_exit_callback; + +#ifdef CONFIG_KDB + kdb_register("novfs_tl", profile_dump_tasklist, "", "Dumps task list", 0); + kdb_register("novfs_st", profile_dump_scopetable, "", "Dumps the novfs scope table", 0); + kdb_register("novfs_dque", profile_dump_daemonque, "", "Dumps the novfs daemon que", 0); + kdb_register("novfs_db", profile_dump_DbgBuffer, "[-r] [-e size] [-i]", "Dumps the novfs DbgBuffer", 0); + kdb_register("novfs_den", profile_dump_DentryTree, "[dentry]", "Dumps a Dentry tree", 0); + kdb_register("novfs_ic", Novfs_dump_inode_cache, "[inode]", "Dumps a Inode Cache", 0); + kdb_register("novfs_inode", profile_dump_inode, "", "Dump allocated Inodes", 0); + kdb_register("novfs_mem", profile_dump_memorylist_dbg, "", "Dumps allocated memory", 0); +#endif + } + else if (exit_novfs == this_fn) + { + /* + if (dbg_file) DbgPrint("Calling remove_proc_entry(Debug, NULL)\n"), remove_proc_entry( "Debug", dbg_dir ); + if (inode_file) DbgPrint("Calling remove_proc_entry(inode, NULL)\n"), remove_proc_entry( "inode", dbg_dir ); + if (dentry_file) DbgPrint("Calling remove_proc_entry(dentry, NULL)\n"), remove_proc_entry( "dentry", dbg_dir ); + if (memory_file) DbgPrint("Calling remove_proc_entry(memory, NULL)\n"), remove_proc_entry( "memory", dbg_dir ); + + if (dbg_dir && (dbg_dir != Novfs_Procfs_dir)) + { + printk( KERN_INFO "Calling remove_proc_entry(%s, NULL)\n", MODULE_NAME); + remove_proc_entry( MODULE_NAME, NULL ); + } + */ + } + + sym = SymbolTable; + while (sym->address) + { + if (this_fn == sym->address ) + { + t64 = get_nanosecond_time(); + DbgPrint("[%llu]%sS %s (0x%p 0x%p)\n", t64, &IndentString[sizeof(IndentString)-Indent-1], sym->name, this_fn, call_site); + + Indent++; + if (Indent > (int)(sizeof(IndentString)-1)) + Indent--; + + break; + } + sym++; + } +} + +void +__cyg_profile_func_exit (void *this_fn, void *call_site) +{ + PSYMBOL_TABLE sym; + uint64_t t64; + + if (exit_novfs == this_fn) + { + if (DbgPrintBuffer) vfree( DbgPrintBuffer ); + DbgPrintBuffer = NULL; + +#ifdef CONFIG_KDB + kdb_unregister("novfs_tl"); + kdb_unregister("novfs_st"); + kdb_unregister("novfs_dque"); + kdb_unregister("novfs_db"); + kdb_unregister("novfs_den"); + kdb_unregister("novfs_ic"); + kdb_unregister("novfs_inode"); + kdb_unregister("novfs_mem"); +#endif + return; + } + + sym = SymbolTable; + while (sym->address) + { + if (this_fn == sym->address ) + { + Indent--; + if (Indent < 0) + Indent = 0; + + t64 = get_nanosecond_time(); + DbgPrint("[%llu]%sR %s (0x%p)\n", t64, &IndentString[sizeof(IndentString)-Indent-1], sym->name, call_site); + break; + } + sym++; + } +} + +void +doline(unsigned char *b, unsigned char *e, unsigned char *l) +{ + *b++ = ' '; + while (l < e) { + if ((*l < ' ') || (*l > '~')) + { + *b++ = '.'; + *b = '\0'; + } + else + { + b += sprintf(b, "%c", *l); + } + l++; + } +} + +void +mydump(int size, void *dumpptr) +{ + unsigned char *ptr = (unsigned char *)dumpptr; + unsigned char *line=0, buf[80], *bptr=buf; + int i; + + if ( DbgPrintBuffer ) + { + if (size) + { + for (i=0; i < size; i++) + { + if (0 == (i % 16)) + { + if (line) + { + doline(bptr, ptr, line); + DbgPrint("%s\n", buf); + bptr = buf; + } + bptr += sprintf(bptr, "0x%p: ", ptr); + line = ptr; + } + bptr += sprintf(bptr, "%02x ", *ptr++); + } + doline(bptr, ptr, line); + DbgPrint("%s\n", buf); + } + } +} + +#define FEBRUARY 2 +#define STARTOFTIME 1970 +#define SECDAY 86400L +#define SECYR (SECDAY * 365) +#define leapyear(year) ((year) % 4 == 0) +#define days_in_year(a) (leapyear(a) ? 366 : 365) +#define days_in_month(a) (month_days[(a) - 1]) + +static int month_days[12] = { + 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 +}; + +/* + * This only works for the Gregorian calendar - i.e. after 1752 (in the UK) + */ +void +GregorianDay(struct local_rtc_time * tm) +{ + int leapsToDate; + int lastYear; + int day; + int MonthOffset[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; + + lastYear=tm->tm_year-1; + + /* + * Number of leap corrections to apply up to end of last year + */ + leapsToDate = lastYear/4 - lastYear/100 + lastYear/400; + + /* + * This year is a leap year if it is divisible by 4 except when it is + * divisible by 100 unless it is divisible by 400 + * + * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 will be + */ + if((tm->tm_year%4==0) && + ((tm->tm_year%100!=0) || (tm->tm_year%400==0)) && + (tm->tm_mon>2)) + { + /* + * We are past Feb. 29 in a leap year + */ + day=1; + } + else + { + day=0; + } + + day += lastYear*365 + leapsToDate + MonthOffset[tm->tm_mon-1] + + tm->tm_mday; + + tm->tm_wday=day%7; +} + +void +to_tm(int tim, struct local_rtc_time * tm) +{ + register int i; + register long hms, day; + + day = tim / SECDAY; + hms = tim % SECDAY; + + /* Hours, minutes, seconds are easy */ + tm->tm_hour = hms / 3600; + tm->tm_min = (hms % 3600) / 60; + tm->tm_sec = (hms % 3600) % 60; + + /* Number of years in days */ + for (i = STARTOFTIME; day >= days_in_year(i); i++) + day -= days_in_year(i); + tm->tm_year = i; + + /* Number of months in days left */ + if (leapyear(tm->tm_year)) + days_in_month(FEBRUARY) = 29; + for (i = 1; day >= days_in_month(i); i++) + day -= days_in_month(i); + days_in_month(FEBRUARY) = 28; + tm->tm_mon = i; + + /* Days are what is left over (+1) from all that. */ + tm->tm_mday = day + 1; + + /* + * Determine the day of week + */ + GregorianDay(tm); +} + +char * +ctime_r(time_t *clock, char *buf) +{ + struct local_rtc_time tm; + static char *DAYOFWEEK[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; + static char *MONTHOFYEAR[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; + + to_tm(*clock, &tm); + + sprintf(buf, "%s %s %d %d:%02d:%02d %d", DAYOFWEEK[tm.tm_wday], MONTHOFYEAR[tm.tm_mon-1], tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_year); + return(buf); +} + + +#ifdef CONFIG_KDB + +int +NO_TRACE +profile_dump_tasklist(int argc, const char **argv, const char **envp, struct pt_regs *regs) +{ + Scope_Dump_Tasklist(); + return( 0 ); +} + +int +NO_TRACE +profile_dump_scopetable(int argc, const char **argv, const char **envp, struct pt_regs *regs) +{ + Scope_Dump_Scopetable(); + return( 0 ); +} + +int +NO_TRACE +profile_dump_daemonque(int argc, const char **argv, const char **envp, struct pt_regs *regs) +{ + Daemon_Dumpque(); + return( 0 ); +} + +int +NO_TRACE +profile_dump_DbgBuffer(int argc, const char **argv, const char **envp, struct pt_regs *regs) +{ + unsigned long offset = DbgPrintBufferReadOffset; + if (argc > 0) + { + if (!strcmp("-r", argv[1])) + { + DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0; + } + else if (!strcmp("-e", argv[1]) && (argc > 1)) + { + offset = simple_strtoul(argv[2], NULL, 0); + if (offset && offset < DbgPrintBufferOffset) + { + offset = DbgPrintBufferOffset - offset; + } + else + { + offset = DbgPrintBufferOffset; + } + } + else if (!strcmp("-i", argv[1])) + { + kdb_printf("DbgPrintBuffer =0x%p\n", DbgPrintBuffer); + kdb_printf("DbgPrintBufferOffset =0x%lx\n", DbgPrintBufferOffset); + kdb_printf("DbgPrintBufferSize =0x%lx\n", DbgPrintBufferSize); + offset = DbgPrintBufferOffset; + + } + } + while (DbgPrintBufferOffset > offset) + { + kdb_printf("%c", DbgPrintBuffer[offset++]); + } + return( 0 ); +} + +int +NO_TRACE +profile_dump_DentryTree(int argc, const char **argv, const char **envp, struct pt_regs *regs) +{ + struct dentry *parent=Novfs_root; + + if (argc > 0) + { + parent = (void *)simple_strtoul(argv[1], NULL, 0); + } + + if (parent) + { + profile_dump_dt(parent, kdb_printf ); + } + + return(0); +} + + +int +NO_TRACE +profile_dump_inode(int argc, const char **argv, const char **envp, struct pt_regs *regs) +{ + Novfs_dump_inode( kdb_printf ); + return( 0 ); +} + +#endif /* CONFIG_KDB */ + +typedef struct memory_header +{ + struct list_head list; + void *caller; + size_t size; +} MEMORY_LIST, *PMEMORY_LIST; + +spinlock_t Malloc_Lock = SPIN_LOCK_UNLOCKED; +LIST_HEAD( Memory_List ); + +void *Novfs_Malloc( size_t size, int flags ) +{ + void *p=NULL; + PMEMORY_LIST mh; + + mh = kmalloc(size + sizeof(MEMORY_LIST), flags); + if (mh) + { + mh->caller = __builtin_return_address(0); + mh->size = size; + spin_lock(&Malloc_Lock); + list_add(&mh->list, &Memory_List); + spin_unlock(&Malloc_Lock); + p = (char *)mh+sizeof(MEMORY_LIST); + /*DbgPrint("Novfs_Malloc: 0x%p 0x%p %d\n", p, mh->caller, size); + */ + } + return(p); +} + +void Novfs_Free( const void *p ) +{ + PMEMORY_LIST mh; + + if (p) + { + /*DbgPrint("Novfs_Free: 0x%p 0x%p\n", p, __builtin_return_address(0)); + */ + mh = (PMEMORY_LIST)((char *)p-sizeof(MEMORY_LIST)); + + spin_lock(&Malloc_Lock); + list_del(&mh->list); + spin_unlock(&Malloc_Lock); + kfree(mh); + } +} + + +int +NO_TRACE +profile_dump_memorylist_dbg(int argc, const char **argv, const char **envp, struct pt_regs *regs) +{ +#ifdef CONFIG_KDB + profile_dump_memorylist(kdb_printf); +#endif /* CONFIG_KDB */ + + return( 0 ); +} + +void +NO_TRACE +profile_dump_memorylist( void *pf ) +{ + void (*pfunc)(char *Fmt, ...) = pf; + + PMEMORY_LIST mh; + struct list_head *l; + + size_t total=0; + int count=0; + + spin_lock( &Malloc_Lock ); + + list_for_each( l, &Memory_List ) + { + mh = list_entry(l, MEMORY_LIST, list); + pfunc("0x%p 0x%p 0x%p %d\n", mh, (char *)mh+sizeof(MEMORY_LIST), mh->caller, mh->size); + count++; + total += mh->size; + } + spin_unlock( &Malloc_Lock ); + + pfunc("Blocks=%d Total=%d\n", count, total); +} + +void +NO_TRACE +profile_dump_dt(struct dentry *parent, void *pf ) +{ + void (*pfunc)(char *Fmt, ...) = pf; + struct l { + struct l *next; + struct dentry *dentry; + } *l, *n, *start; + struct list_head *p; + struct dentry *d; + char *buf, *path, *sd; + char inode_number[16]; + + buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); + + if( NULL == buf ) + { + return; + } + + if (parent) + { + pfunc("starting 0x%p %.*s\n", parent, parent->d_name.len, parent->d_name.name); + if (parent->d_subdirs.next == &parent->d_subdirs) + { + pfunc("No children...\n"); + } + else + { + start = Novfs_Malloc(sizeof(*start), GFP_KERNEL); + if (start) + { + start->next = NULL; + start->dentry = parent; + l = start; + while(l) + { + p = l->dentry->d_subdirs.next; + while(p != &l->dentry->d_subdirs) + { + d = list_entry(p, struct dentry, D_CHILD); + p = p->next; + + if (d->d_subdirs.next != &d->d_subdirs) + { + n = Novfs_Malloc(sizeof(*n), GFP_KERNEL); + if (n) + { + n->next = l->next; + l->next = n; + n->dentry = d; + } + } + else + { + path = Scope_dget_path(d, buf, PATH_LENGTH_BUFFER, 1); + if (path) + { + pfunc("1-0x%p %s\n" \ + " d_name: %.*s\n" \ + " d_parent: 0x%p\n" \ + " d_count: %d\n" \ + " d_flags: 0x%x\n" \ + " d_subdirs: 0x%p\n" \ + " d_inode: 0x%p\n", + d, path, d->d_name.len, d->d_name.name, d->d_parent, + atomic_read(&d->d_count), d->d_flags, d->d_subdirs.next, d->d_inode); + } + } + } + l = l->next; + } + l = start; + while(l) + { + d=l->dentry; + path = Scope_dget_path(d, buf, PATH_LENGTH_BUFFER, 1); + if (path) + { + sd = " (None)"; + if (&d->d_subdirs != d->d_subdirs.next) + { + sd = ""; + } + inode_number[0] = '\0'; + if (d->d_inode) + { + sprintf(inode_number, " (%lu)", d->d_inode->i_ino); + } + pfunc("0x%p %s\n" \ + " d_parent: 0x%p\n" \ + " d_count: %d\n" \ + " d_flags: 0x%x\n" \ + " d_subdirs: 0x%p%s\n" \ + " d_inode: 0x%p%s\n", + d, path, d->d_parent, + atomic_read(&d->d_count), d->d_flags, d->d_subdirs.next, sd, d->d_inode, inode_number); + } + + n = l; + l = l->next; + Novfs_Free(n); + } + } + } + } + + Novfs_Free(buf); + +} + +/*int profile_inode_open(struct inode *inode, struct file *file) +{ + +} + +int profile_inode_close(struct inode *inode, struct file *file) +{ +} +*/ +ssize_t profile_common_read( char *buf, size_t len, loff_t *off ) +{ + ssize_t retval=0; + size_t count; + unsigned long offset = *off; + + if (0 != (count = DbgPrintBufferOffset - offset)) + { + if (count > len) + { + count = len; + } + + count -= copy_to_user(buf, &DbgPrintBuffer[offset], count); + + if (count == 0) + { + retval = -EFAULT; + } + else + { + *off += (loff_t)count; + retval = count; + } + } + return retval; + +} + +//ssize_t NO_TRACE profile_inode_read(struct file *file, char *buf, size_t len, loff_t *off) +ssize_t profile_inode_read(struct file *file, char *buf, size_t len, loff_t *off) +{ + ssize_t retval=0; + unsigned long offset = *off; + static char save_DbgPrintOn; + + if (offset == 0) + { + down(&LocalPrint_lock); + save_DbgPrintOn = DbgPrintOn; + DbgPrintOn = 0; + + DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0; + Novfs_dump_inode( LocalPrint ); + } + + retval = profile_common_read(buf, len, off); + + if ( 0 == retval) + { + DbgPrintOn = save_DbgPrintOn; + DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0; + + up(&LocalPrint_lock); + } + + return retval; + +} + +ssize_t NO_TRACE profile_dentry_read(struct file *file, char *buf, size_t len, loff_t *off) +{ + ssize_t retval=0; + unsigned long offset = *off; + static char save_DbgPrintOn; + + if (offset == 0) + { + down(&LocalPrint_lock); + save_DbgPrintOn = DbgPrintOn; + DbgPrintOn = 0; + DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0; + profile_dump_dt(Novfs_root, LocalPrint); + } + + retval = profile_common_read(buf, len, off); + + if ( 0 == retval) + { + DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0; + DbgPrintOn = save_DbgPrintOn; + + up(&LocalPrint_lock); + } + + return retval; + +} + +ssize_t NO_TRACE profile_memory_read(struct file *file, char *buf, size_t len, loff_t *off) +{ + ssize_t retval=0; + unsigned long offset = *off; + static char save_DbgPrintOn; + + if (offset == 0) + { + down(&LocalPrint_lock); + save_DbgPrintOn = DbgPrintOn; + DbgPrintOn = 0; + DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0; + profile_dump_memorylist( LocalPrint ); + } + + retval = profile_common_read(buf, len, off); + + if ( 0 == retval) + { + DbgPrintBufferOffset = DbgPrintBufferReadOffset = 0; + DbgPrintOn = save_DbgPrintOn; + + up(&LocalPrint_lock); + } + + return retval; + +} + +uint64_t get_nanosecond_time() +{ + struct timespec ts; + uint64_t retVal; + + ts = current_kernel_time(); + + retVal = (uint64_t)NSEC_PER_SEC; + retVal *= (uint64_t)ts.tv_sec; + retVal += (uint64_t)ts.tv_nsec; + + return( retVal ); +} diff -uNr src.old/src/profile_funcs.h src/src/profile_funcs.h --- src.old/src/profile_funcs.h 1970-01-01 01:00:00.000000000 +0100 +++ src/src/profile_funcs.h 2006-10-16 15:08:22.000000000 +0200 @@ -0,0 +1,415 @@ +extern void Daemon_Added_Resource( void ); +extern void Daemon_Close_Control( void ); +extern void Daemon_CreateSessionId( void ); +extern void Daemon_DestroySessionId( void ); +extern void Daemon_Dumpque( void ); +extern void Daemon_Get_UserSpace( void ); +extern void Daemon_Library_close( void ); +extern void Daemon_Library_ioctl( void ); +extern void Daemon_Library_open( void ); +extern void Daemon_Library_read( void ); +extern void Daemon_Library_write( void ); +extern void Daemon_Login( void ); +extern void Daemon_Logout( void ); +extern void Daemon_Open_Control( void ); +extern void Daemon_Poll( void ); +extern void Daemon_Receive_Reply( void ); +extern void Daemon_Remove_Resource( void ); +extern void Daemon_Send_Command( void ); +extern void Daemon_SetMountPoint( void ); +extern void Daemon_getpwuid( void ); +extern void Daemon_getversion( void ); +extern void Daemon_ioctl( void ); +extern void GetConnData( void ); +extern void GetUserData( void ); +extern void Init_Daemon_Queue( void ); +extern void Init_Procfs_Interface( void ); +extern void Novfs_Add_to_Root( void ); +extern void Novfs_Add_to_Root2( void ); +extern void Novfs_Close_File( void ); +extern void Novfs_Close_Stream( void ); +extern void Novfs_Control_ioctl( void ); +extern void Novfs_Control_read( void ); +extern void Novfs_Control_write( void ); +extern void Novfs_Create( void ); +extern void Novfs_Delete( void ); +extern void Novfs_Find_Name_In_List( void ); +extern void Novfs_Get_Connected_Server_List( void ); +extern void Novfs_Get_Directory_List( void ); +extern void Novfs_Get_Directory_ListEx( void ); +extern void Novfs_Get_File_Info( void ); +extern void Novfs_Get_File_Info2( void ); +extern void Novfs_Get_Server_Volume_List( void ); +extern void Novfs_Get_Version( void ); +extern void Novfs_Open_File( void ); +extern void Novfs_Read_File( void ); +extern void Novfs_Read_Stream( void ); +extern void Novfs_Remove_from_Root( void ); +extern void Novfs_Rename_File( void ); +extern void Novfs_Set_Attr( void ); +extern void Novfs_Truncate_File( void ); +extern void Novfs_User_proc_ioctl( void ); +extern void Novfs_User_proc_read( void ); +extern void Novfs_User_proc_write( void ); +extern void Novfs_Verify_Server_Name( void ); +extern void Novfs_Verify_Volume_Name( void ); +extern void Novfs_Write_File( void ); +extern void Novfs_Write_Stream( void ); +extern void Novfs_a_readpage( void ); +extern void Novfs_add_inode_entry( void ); +extern void Novfs_clear_inode( void ); +extern void Novfs_d_add( void ); +extern void Novfs_d_compare( void ); +extern void Novfs_d_delete( void ); +extern void Novfs_d_hash( void ); +extern void Novfs_d_iput( void ); +extern void Novfs_d_lookup( void ); +extern void Novfs_d_release( void ); +extern void Novfs_d_revalidate( void ); +extern void Novfs_d_strcmp( void ); +extern void Novfs_dget_path( void ); +extern void Novfs_dir_fsync( void ); +extern void Novfs_dir_lseek( void ); +extern void Novfs_dir_open( void ); +extern void Novfs_dir_read( void ); +extern void Novfs_dir_readdir( void ); +extern void Novfs_dir_release( void ); +extern void Novfs_enumerate_inode_cache( void ); +extern void Novfs_f_flush( void ); +extern void Novfs_f_fsync( void ); +extern void Novfs_f_ioctl( void ); +extern void Novfs_f_llseek( void ); +extern void Novfs_f_lock( void ); +extern void Novfs_f_mmap( void ); +extern void Novfs_f_open( void ); +extern void Novfs_f_read( void ); +extern void Novfs_f_readdir( void ); +extern void Novfs_f_release( void ); +extern void Novfs_f_write( void ); +extern void Novfs_fill_super( void ); +extern void Novfs_free_inode_cache( void ); +extern void Novfs_free_invalid_entries( void ); +extern void Novfs_get_alltrees( void ); +extern void Novfs_get_entry( void ); +extern void Novfs_get_entry_time( void ); +extern void Novfs_get_inode( void ); +extern void Novfs_get_remove_entry( void ); +extern void Novfs_get_sb( void ); +extern void Novfs_i_create( void ); +extern void Novfs_i_getattr( void ); +extern void Novfs_i_lookup( void ); +extern void Novfs_i_mkdir( void ); +extern void Novfs_i_mknod( void ); +extern void Novfs_i_permission( void ); +extern void Novfs_i_rename( void ); +extern void Novfs_i_revalidate( void ); +extern void Novfs_i_rmdir( void ); +extern void Novfs_i_setattr( void ); +extern void Novfs_i_unlink( void ); +extern void Novfs_internal_hash( void ); +extern void Novfs_invalidate_inode_cache( void ); +extern void Novfs_kill_sb( void ); +extern void Novfs_lock_inode_cache( void ); +extern void Novfs_lookup_inode_cache( void ); +extern void Novfs_lookup_validate( void ); +extern void Novfs_notify_change( void ); +extern void Novfs_read_inode( void ); +extern void Novfs_remove_inode_entry( void ); +extern void Novfs_show_options( void ); +extern void Novfs_statfs( void ); +extern void Novfs_tree_read( void ); +extern void Novfs_unlock_inode_cache( void ); +extern void Novfs_update_entry( void ); +extern void Novfs_verify_file( void ); +extern void Novfs_write_inode( void ); +extern void NwAuthConnWithId( void ); +extern void NwConnClose( void ); +extern void NwGetConnInfo( void ); +extern void NwGetDaemonVersion( void ); +extern void NwGetIdentityInfo( void ); +extern void NwLicenseConn( void ); +extern void NwLoginIdentity( void ); +extern void NwLogoutIdentity( void ); +extern void NwOpenConnByAddr( void ); +extern void NwOpenConnByName( void ); +extern void NwOpenConnByRef( void ); +extern void NwQueryFeature( void ); +extern void NwRawSend( void ); +extern void NwScanConnInfo( void ); +extern void NwSetConnInfo( void ); +extern void NwSysConnClose( void ); +extern void NwUnAuthenticate( void ); +extern void NwUnlicenseConn( void ); +extern void NwcChangeAuthKey( void ); +extern void NwcEnumIdentities( void ); +extern void NwcEnumerateDrives( void ); +extern void NwcGetBroadcastMessage( void ); +extern void NwcGetDefaultNameCtx( void ); +extern void NwcGetPreferredDSTree( void ); +extern void NwcGetPrimaryConn( void ); +extern void NwcGetTreeMonitoredConn( void ); +extern void NwcSetDefaultNameCtx( void ); +extern void NwcSetMapDrive( void ); +extern void NwcSetPreferredDSTree( void ); +extern void NwcSetPrimaryConn( void ); +extern void NwcUnMapDrive( void ); +extern void NwdConvertLocalHandle( void ); +extern void NwdConvertNetwareHandle( void ); +extern void NwdGetMountPath( void ); +extern void NwdSetKeyValue( void ); +extern void NwdSetMapDrive( void ); +extern void NwdUnMapDrive( void ); +extern void NwdVerifyKeyValue( void ); +extern void Queue_Daemon_Command( void ); +extern void Queue_get( void ); +extern void Queue_put( void ); +extern void RemoveDriveMaps( void ); +extern void Scope_Cleanup( void ); +extern void Scope_Cleanup_Thread( void ); +extern void Scope_Dump_Scopetable( void ); +extern void Scope_Dump_Tasklist( void ); +extern void Scope_Find_Scope( void ); +extern void Scope_Get_Hash( void ); +extern void Scope_Get_ScopeUsers( void ); +extern void Scope_Get_ScopefromName( void ); +extern void Scope_Get_ScopefromPath( void ); +extern void Scope_Get_SessionId( void ); +extern void Scope_Get_Uid( void ); +extern void Scope_Get_UserName( void ); +extern void Scope_Get_UserSpace( void ); +extern void Scope_Init( void ); +extern void Scope_Lookup( void ); +extern void Scope_Search4Scope( void ); +extern void Scope_Set_UserSpace( void ); +extern void Scope_Timer_Function( void ); +extern void Scope_Uninit( void ); +extern void Scope_Validate_Scope( void ); +extern void Uninit_Daemon_Queue( void ); +extern void Uninit_Procfs_Interface( void ); +extern void add_to_list( void ); +extern void begin_directory_enumerate( void ); +extern void directory_enumerate( void ); +extern void directory_enumerate_ex( void ); +extern void do_login( void ); +extern void do_logout( void ); +extern void end_directory_enumerate( void ); +extern void exit_novfs( void ); +extern void find_queue( void ); +extern void get_next_queue( void ); +extern void init_novfs( void ); +extern void local_unlink( void ); +extern void process_list( void ); +extern void update_inode( void ); +extern void verify_dentry( void ); + +SYMBOL_TABLE SymbolTable[] = { + {Scope_Get_UserSpace, "Scope_Get_UserSpace"}, + {NwLoginIdentity, "NwLoginIdentity"}, + {Novfs_d_revalidate, "Novfs_d_revalidate"}, + {Daemon_SetMountPoint, "Daemon_SetMountPoint"}, + {Scope_Get_Hash, "Scope_Get_Hash"}, + {Queue_get, "Queue_get"}, + {Queue_Daemon_Command, "Queue_Daemon_Command"}, + {Novfs_dir_fsync, "Novfs_dir_fsync"}, + {Novfs_Read_File, "Novfs_Read_File"}, + {Daemon_Library_close, "Daemon_Library_close"}, + {NwRawSend, "NwRawSend"}, + {Novfs_get_inode, "Novfs_get_inode"}, + {Novfs_Remove_from_Root, "Novfs_Remove_from_Root"}, + {Novfs_Find_Name_In_List, "Novfs_Find_Name_In_List"}, + {Scope_Get_SessionId, "Scope_Get_SessionId"}, + {NwOpenConnByAddr, "NwOpenConnByAddr"}, + {Novfs_read_inode, "Novfs_read_inode"}, + {Novfs_Truncate_File, "Novfs_Truncate_File"}, + {Daemon_Login, "Daemon_Login"}, + {Scope_Get_ScopefromPath, "Scope_Get_ScopefromPath"}, + {NwcGetTreeMonitoredConn, "NwcGetTreeMonitoredConn"}, + {Novfs_write_inode, "Novfs_write_inode"}, + {Scope_Lookup, "Scope_Lookup"}, + {NwQueryFeature, "NwQueryFeature"}, + {Novfs_get_entry_time, "Novfs_get_entry_time"}, + {Novfs_Control_write, "Novfs_Control_write"}, + {Scope_Get_Uid, "Scope_Get_Uid"}, + {NwSysConnClose, "NwSysConnClose"}, + {NwConnClose, "NwConnClose"}, + {Novfs_get_entry, "Novfs_get_entry"}, + {Novfs_Rename_File, "Novfs_Rename_File"}, + {NwdConvertLocalHandle, "NwdConvertLocalHandle"}, + {Novfs_dir_lseek, "Novfs_dir_lseek"}, + {Scope_Get_ScopefromName, "Scope_Get_ScopefromName"}, + {NwcGetPrimaryConn, "NwcGetPrimaryConn"}, + {Novfs_d_strcmp, "Novfs_d_strcmp"}, + {Daemon_Library_ioctl, "Daemon_Library_ioctl"}, + {end_directory_enumerate, "end_directory_enumerate"}, + {directory_enumerate, "directory_enumerate"}, + {begin_directory_enumerate, "begin_directory_enumerate"}, + {NwdGetMountPath, "NwdGetMountPath"}, + {NwAuthConnWithId, "NwAuthConnWithId"}, + {Novfs_Set_Attr, "Novfs_Set_Attr"}, + {Daemon_getversion, "Daemon_getversion"}, + {Scope_Dump_Scopetable, "Scope_Dump_Scopetable"}, + {NwcSetMapDrive, "NwcSetMapDrive"}, + {Novfs_lookup_inode_cache, "Novfs_lookup_inode_cache"}, + {Novfs_i_mkdir, "Novfs_i_mkdir"}, + {Novfs_free_invalid_entries, "Novfs_free_invalid_entries"}, + {Novfs_dump_inode_cache, "Novfs_dump_inode_cache"}, + {Novfs_Write_Stream, "Novfs_Write_Stream"}, + {Novfs_Verify_Server_Name, "Novfs_Verify_Server_Name"}, + {GetConnData, "GetConnData"}, + {Uninit_Procfs_Interface, "Uninit_Procfs_Interface"}, + {Scope_Validate_Scope, "Scope_Validate_Scope"}, + {Scope_Timer_Function, "Scope_Timer_Function"}, + {Novfs_i_setattr, "Novfs_i_setattr"}, + {Novfs_i_mknod, "Novfs_i_mknod"}, + {Novfs_Verify_Volume_Name, "Novfs_Verify_Volume_Name"}, + {Novfs_Close_Stream, "Novfs_Close_Stream"}, + {Novfs_Add_to_Root, "Novfs_Add_to_Root"}, + {Init_Procfs_Interface, "Init_Procfs_Interface"}, + {Novfs_dump_inode, "Novfs_dump_inode"}, + {Novfs_Get_Directory_List, "Novfs_Get_Directory_List"}, + {Novfs_Get_Connected_Server_List, "Novfs_Get_Connected_Server_List"}, + {Daemon_Logout, "Daemon_Logout"}, + {do_logout, "do_logout"}, + {Scope_Search4Scope, "Scope_Search4Scope"}, + {NwdUnMapDrive, "NwdUnMapDrive"}, + {Novfs_Control_read, "Novfs_Control_read"}, + {Scope_Cleanup_Thread, "Scope_Cleanup_Thread"}, + {Novfs_invalidate_inode_cache, "Novfs_invalidate_inode_cache"}, + {Novfs_f_flush, "Novfs_f_flush"}, + {Novfs_enumerate_inode_cache, "Novfs_enumerate_inode_cache"}, + {Novfs_d_compare, "Novfs_d_compare"}, + {Daemon_Library_write, "Daemon_Library_write"}, + {GetUserData, "GetUserData"}, + {Daemon_Remove_Resource, "Daemon_Remove_Resource"}, + {Scope_Set_UserSpace, "Scope_Set_UserSpace"}, + {Novfs_get_alltrees, "Novfs_get_alltrees"}, + {Daemon_Get_UserSpace, "Daemon_Get_UserSpace"}, + {Uninit_Daemon_Queue, "Uninit_Daemon_Queue"}, + {NwcChangeAuthKey, "NwcChangeAuthKey"}, + {NwLicenseConn, "NwLicenseConn"}, + {Init_Daemon_Queue, "Init_Daemon_Queue"}, + {Novfs_tree_read, "Novfs_tree_read"}, + {Novfs_f_llseek, "Novfs_f_llseek"}, + {find_queue, "find_queue"}, + {Scope_Find_Scope, "Scope_Find_Scope"}, + {Novfs_lookup_validate, "Novfs_lookup_validate"}, + {Novfs_d_hash, "Novfs_d_hash"}, + {Novfs_a_readpage, "Novfs_a_readpage"}, + {Novfs_Create, "Novfs_Create"}, + {Novfs_Close_File, "Novfs_Close_File"}, + {Daemon_getpwuid, "Daemon_getpwuid"}, + {Daemon_CreateSessionId, "Daemon_CreateSessionId"}, + {Scope_dget_path, "Scope_dget_path"}, + {NwcSetDefaultNameCtx, "NwcSetDefaultNameCtx"}, + {NwcGetDefaultNameCtx, "NwcGetDefaultNameCtx"}, + {NwUnAuthenticate, "NwUnAuthenticate"}, + {Novfs_i_getattr, "Novfs_i_getattr"}, + {Novfs_get_remove_entry, "Novfs_get_remove_entry"}, + {Novfs_f_ioctl, "Novfs_f_ioctl"}, + {Scope_Get_ScopeUsers, "Scope_Get_ScopeUsers"}, + {Scope_Dump_Tasklist, "Scope_Dump_Tasklist"}, + {NwOpenConnByRef, "NwOpenConnByRef"}, + {Novfs_unlock_inode_cache, "Novfs_unlock_inode_cache"}, + {Novfs_lock_inode_cache, "Novfs_lock_inode_cache"}, + {Daemon_DestroySessionId, "Daemon_DestroySessionId"}, + {do_login, "do_login"}, + {Novfs_free_inode_cache, "Novfs_free_inode_cache"}, + {Novfs_Read_Stream, "Novfs_Read_Stream"}, + {Daemon_Library_read, "Daemon_Library_read"}, + {NwdSetMapDrive, "NwdSetMapDrive"}, + {Novfs_internal_hash, "Novfs_internal_hash"}, + {Daemon_Receive_Reply, "Daemon_Receive_Reply"}, + {Daemon_Library_open, "Daemon_Library_open"}, + {get_next_queue, "get_next_queue"}, + {exit_novfs, "exit_novfs"}, + {NwcGetBroadcastMessage, "NwcGetBroadcastMessage"}, + {Novfs_d_lookup, "Novfs_d_lookup"}, + {Novfs_clear_inode, "Novfs_clear_inode"}, + {Daemon_Open_Control, "Daemon_Open_Control"}, + {NwdConvertNetwareHandle, "NwdConvertNetwareHandle"}, + {NwcUnMapDrive, "NwcUnMapDrive"}, + {Novfs_notify_change, "Novfs_notify_change"}, + {Novfs_dir_release, "Novfs_dir_release"}, + {directory_enumerate_ex, "directory_enumerate_ex"}, + {RemoveDriveMaps, "RemoveDriveMaps"}, + {NwOpenConnByName, "NwOpenConnByName"}, + {Novfs_verify_file, "Novfs_verify_file"}, + {Novfs_statfs, "Novfs_statfs"}, + {Novfs_f_write, "Novfs_f_write"}, + {Novfs_Get_File_Info, "Novfs_Get_File_Info"}, + {Novfs_Delete, "Novfs_Delete"}, + {update_inode, "update_inode"}, + {NwcSetPreferredDSTree, "NwcSetPreferredDSTree"}, + {NwcGetPreferredDSTree, "NwcGetPreferredDSTree"}, + {Novfs_update_entry, "Novfs_update_entry"}, + {Novfs_kill_sb, "Novfs_kill_sb"}, + {Daemon_ioctl, "Daemon_ioctl"}, + {Scope_Get_UserName, "Scope_Get_UserName"}, + {NwcEnumerateDrives, "NwcEnumerateDrives"}, + {Novfs_i_revalidate, "Novfs_i_revalidate"}, + {Novfs_f_release, "Novfs_f_release"}, + {Novfs_f_read, "Novfs_f_read"}, + {Novfs_d_delete, "Novfs_d_delete"}, + {Novfs_Write_File, "Novfs_Write_File"}, + {Novfs_User_proc_ioctl, "Novfs_User_proc_ioctl"}, + {Novfs_Get_File_Info2, "Novfs_Get_File_Info2"}, + {NwdSetKeyValue, "NwdSetKeyValue"}, + {Novfs_remove_inode_entry, "Novfs_remove_inode_entry"}, + {Novfs_i_rename, "Novfs_i_rename"}, + {Novfs_f_open, "Novfs_f_open"}, + {Novfs_d_iput, "Novfs_d_iput"}, + {Novfs_Get_Directory_ListEx, "Novfs_Get_Directory_ListEx"}, + {Daemon_Close_Control, "Daemon_Close_Control"}, + {verify_dentry, "verify_dentry"}, + {process_list, "process_list"}, + {local_unlink, "local_unlink"}, + {init_novfs, "init_novfs"}, + {NwUnlicenseConn, "NwUnlicenseConn"}, + {NwGetConnInfo, "NwGetConnInfo"}, + {Novfs_i_permission, "Novfs_i_permission"}, + {Novfs_dir_read, "Novfs_dir_read"}, + {NwcSetPrimaryConn, "NwcSetPrimaryConn"}, + {Novfs_f_lock, "Novfs_f_lock"}, + {Novfs_dir_readdir, "Novfs_dir_readdir"}, + {Novfs_dir_open, "Novfs_dir_open"}, + {Queue_put, "Queue_put"}, + {NwLogoutIdentity, "NwLogoutIdentity"}, + {NwGetIdentityInfo, "NwGetIdentityInfo"}, + {Novfs_i_rmdir, "Novfs_i_rmdir"}, + {Novfs_i_create, "Novfs_i_create"}, + {Novfs_f_mmap, "Novfs_f_mmap"}, + {Novfs_User_proc_read, "Novfs_User_proc_read"}, + {Novfs_show_options, "Novfs_show_options"}, + {Novfs_add_inode_entry, "Novfs_add_inode_entry"}, + {Novfs_Open_File, "Novfs_Open_File"}, + {Novfs_Get_Version, "Novfs_Get_Version"}, + {Daemon_Poll, "Daemon_Poll"}, + {add_to_list, "add_to_list"}, + {Scope_Init, "Scope_Init"}, + {Scope_Cleanup, "Scope_Cleanup"}, + {NwSetConnInfo, "NwSetConnInfo"}, + {Novfs_i_unlink, "Novfs_i_unlink"}, + {Novfs_get_sb, "Novfs_get_sb"}, + {Novfs_f_readdir, "Novfs_f_readdir"}, + {Novfs_f_fsync, "Novfs_f_fsync"}, + {Novfs_d_release, "Novfs_d_release"}, + {Novfs_User_proc_write, "Novfs_User_proc_write"}, + {Daemon_Send_Command, "Daemon_Send_Command"}, + {Daemon_Dumpque, "Daemon_Dumpque"}, + {NwcEnumIdentities, "NwcEnumIdentities"}, + {NwGetDaemonVersion, "NwGetDaemonVersion"}, + {Novfs_i_lookup, "Novfs_i_lookup"}, + {Novfs_fill_super, "Novfs_fill_super"}, + {Novfs_Get_Server_Volume_List, "Novfs_Get_Server_Volume_List"}, + {Novfs_Add_to_Root2, "Novfs_Add_to_Root2"}, + {Daemon_SendDebugCmd, "Daemon_SendDebugCmd"}, + {Daemon_Added_Resource, "Daemon_Added_Resource"}, + {Scope_Uninit, "Scope_Uninit"}, + {NwdVerifyKeyValue, "NwdVerifyKeyValue"}, + {NwScanConnInfo, "NwScanConnInfo"}, + {Novfs_dget_path, "Novfs_dget_path"}, + {Novfs_d_add, "Novfs_d_add"}, + {Novfs_Control_ioctl, "Novfs_Control_ioctl"}, + // Terminate the table + {NULL, NULL} +}; diff -uNr src.old/src/scope.c src/src/scope.c --- src.old/src/scope.c 1970-01-01 01:00:00.000000000 +0100 +++ src/src/scope.c 2006-10-16 15:08:22.000000000 +0200 @@ -0,0 +1,1214 @@ +/*++======================================================================== + * Program Name: Novell NCP Redirector for Linux + * File Name: scope.c + * Version: v1.00 + * Author: James Turner + * + * Abstract: This module contains functions used to scope + * users. + * Notes: + * Revision History: + * + * + * Copyright (C) 2005 Novell, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *======================================================================--*/ + +/*===[ Include files specific to Linux ]==================================*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*===[ Include files specific to this module ]============================*/ +#include "vfs.h" +#define LEADER signal->leader + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18) + typedef struct task_struct task_t; +#endif + +/*===[ External data ]====================================================*/ + +/*===[ External prototypes ]==============================================*/ +extern int DbgPrint( char *Fmt, ... ); +extern int Daemon_CreateSessionId( uint64_t *SessionId ); +extern int Daemon_DestroySessionId( uint64_t SessionId ); +extern int Daemon_getpwuid( uid_t uid, int unamelen, char *uname ); +extern int Daemon_Get_UserSpace( uint64_t SessionId, uint64_t *TotalSize, uint64_t *TotalFree, uint64_t *TotalDirectoryEnties, uint64_t *FreeDirectoryEnties); + +extern int Novfs_Remove_from_Root(char *); +extern int Novfs_Add_to_Root(char *); + +/*===[ Manifest constants ]===============================================*/ +#define CLEANUP_INTERVAL 10 +#define MAX_USERNAME_LENGTH 32 + +/*===[ Type definitions ]=================================================*/ +typedef struct _SCOPE_LIST_ +{ + struct list_head ScopeList; + scope_t ScopeId; + session_t SessionId; + pid_t ScopePid; + task_t *ScopeTask; + unsigned long ScopeHash; + uid_t ScopeUid; + uint64_t ScopeUSize; + uint64_t ScopeUFree; + uint64_t ScopeUTEnties; + uint64_t ScopeUAEnties; + int ScopeUserNameLength; + unsigned char ScopeUserName[MAX_USERNAME_LENGTH]; +} SCOPE_LIST, *PSCOPE_LIST; + +/*===[ Function prototypes ]==============================================*/ +void Scope_Init( void ); +void Scope_Uninit( void ); + +PSCOPE_LIST Scope_Search4Scope( session_t Id, BOOLEAN Session, BOOLEAN Locked ); +PSCOPE_LIST Scope_Find_Scope( BOOLEAN Create ); +unsigned long Scope_Get_Hash( PSCOPE_LIST Scope ); +uid_t Scope_Get_Uid( PSCOPE_LIST Scope ); +int Scope_Validate_Scope( PSCOPE_LIST Scope ); +char *Scope_Get_UserName( PSCOPE_LIST Scope ); +session_t Scope_Get_SessionId( PSCOPE_LIST Scope ); +PSCOPE_LIST Scope_Get_ScopefromName( struct qstr *Name ); +int Scope_Set_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties ); +int Scope_Get_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties ); + +char *Scope_Get_ScopeUsers( void ); +void *Scope_Lookup( void ); + +void Scope_Timer_Function(unsigned long Context); +int Scope_Cleanup_Thread(void *Args); +void Scope_Cleanup( void ); +char *Scope_dget_path( struct dentry *Dentry, char *Buf, unsigned int Buflen, int Flags); +void Scope_Dump_Tasklist( void ); +void Scope_Dump_Scopetable( void ); + +/*===[ Global variables ]=================================================*/ +struct list_head Scope_List; +struct semaphore Scope_Lock; +struct semaphore Scope_Thread_Delay; +int Scope_Thread_Terminate=0; +struct semaphore Scope_Delay_Event; +struct timer_list Scope_Timer; +unsigned long Scope_Hash_Val=1; + +/*===[ Code ]=============================================================*/ + +/*++======================================================================*/ +void Scope_Init( void ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + INIT_LIST_HEAD( &Scope_List ); + init_MUTEX( &Scope_Lock ); + init_MUTEX_LOCKED( &Scope_Thread_Delay ); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) + kernel_thread( Scope_Cleanup_Thread, NULL, 0 ); +#else + kthread_run(Scope_Cleanup_Thread, NULL, "novfs_ST"); +#endif +} + +/*++======================================================================*/ +void Scope_Uninit( void ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + Scope_Thread_Terminate = 1; + + up(&Scope_Thread_Delay); + + mb(); + while( Scope_Thread_Terminate ) + { + yield(); + } + printk( KERN_INFO "Scope_Uninit: Exit\n"); + +} + +/*++======================================================================*/ +PSCOPE_LIST Scope_Search4Scope( session_t Id, BOOLEAN Session, BOOLEAN Locked ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + PSCOPE_LIST scope, rscope=NULL; + struct list_head *sl; + int offset; + + DbgPrint("Scope_Search4Scope: 0x%llx 0x%x 0x%x\n", Id, Session, Locked); + + if ( Session ) + { + offset = (int)(&((PSCOPE_LIST)0)->SessionId); + } + else + { + offset = (int)(&((PSCOPE_LIST)0)->ScopeId); + } + + if ( !Locked ) + { + down( &Scope_Lock ); + } + + sl = Scope_List.next; + DbgPrint("Scope_Search4Scope: 0x%x\n", sl); + while (sl != &Scope_List) + { + scope = list_entry(sl, SCOPE_LIST, ScopeList); + + if ( Id == *(session_t *)((char *)scope+offset) ) + { + rscope = scope; + break; + } + + sl = sl->next; + } + + if ( !Locked ) + { + up( &Scope_Lock ); + } + + DbgPrint("Scope_Search4Scope: return 0x%x\n", rscope); + return( rscope ); +} + +/*++======================================================================*/ +PSCOPE_LIST Scope_Find_Scope( BOOLEAN Create ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + PSCOPE_LIST scope=NULL, pscope=NULL; + task_t *task; + scope_t scopeId; + int addscope=0; + + task = current; + + DbgPrint("Scope_Find_Scope: %d %d %d %d\n", task->uid, task->euid, task->suid, task->fsuid); + + scopeId = task->euid; + + scope = Scope_Search4Scope( scopeId, FALSE, FALSE ); + + if ( !scope && Create ) + { + scope = Novfs_Malloc( sizeof(*pscope), GFP_KERNEL ); + if ( scope ) + { + scope->ScopeId = scopeId; + scope->SessionId = 0; + scope->ScopePid = task->pid; + scope->ScopeTask = task; + scope->ScopeHash = 0; + scope->ScopeUid = task->euid; + scope->ScopeUserName[0] = '\0'; + + if ( !Daemon_CreateSessionId( &scope->SessionId ) ) + { + DbgPrint("Scope_Find_Scope2: %d %d %d %d\n", task->uid, task->euid, task->suid, task->fsuid); + memset(scope->ScopeUserName, 0, sizeof(scope->ScopeUserName)); + scope->ScopeUserNameLength = 0; + Daemon_getpwuid(task->euid, sizeof(scope->ScopeUserName), scope->ScopeUserName); + scope->ScopeUserNameLength = strlen(scope->ScopeUserName); + addscope = 1; + } + + scope->ScopeHash = Scope_Hash_Val++; + DbgPrint("Scope_Find_Scope: Adding 0x%x\n" \ + " ScopeId: 0x%llx\n" \ + " SessionId: 0x%llx\n" \ + " ScopePid: %d\n" \ + " ScopeTask: 0x%x\n" \ + " ScopeHash: %d\n" \ + " ScopeUid: %d\n" \ + " ScopeUserNameLength: %d\n" \ + " ScopeUserName: %s\n", + scope, + scope->ScopeId, + scope->SessionId, + scope->ScopePid, + scope->ScopeTask, + scope->ScopeHash, + scope->ScopeUid, + scope->ScopeUserNameLength, + scope->ScopeUserName); + + if ( scope->SessionId ) + { + down( &Scope_Lock ); + list_add(&scope->ScopeList, &Scope_List); + up( &Scope_Lock ); + } + else + { + Novfs_Free(scope); + scope = NULL; + } + } + + if (addscope) + { + Novfs_Add_to_Root( scope->ScopeUserName ); + } + } + + return(scope); +} + +/*++======================================================================*/ +unsigned long Scope_Get_Hash( PSCOPE_LIST Scope ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + unsigned long hash=0; + + if ( NULL == Scope) + { + Scope = Scope_Find_Scope( TRUE ); + } + + if ( Scope && Scope_Validate_Scope( Scope )) + { + hash = Scope->ScopeHash; + } + return( hash ); +} + +/*++======================================================================*/ +uid_t Scope_Get_Uid( PSCOPE_LIST Scope ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + uid_t uid=0; + + if ( NULL == Scope) + { + Scope = Scope_Find_Scope( TRUE ); + } + + if ( Scope && Scope_Validate_Scope( Scope )) + { + uid = Scope->ScopeUid; + } + return( uid ); +} + +/*++======================================================================*/ +int Scope_Validate_Scope( PSCOPE_LIST Scope ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + PSCOPE_LIST s; + struct list_head *sl; + int retVal = 0; + + DbgPrint("Scope_Validate_Scope: 0x%x\n", Scope); + + down( &Scope_Lock ); + + sl = Scope_List.next; + while (sl != &Scope_List) + { + s = list_entry(sl, SCOPE_LIST, ScopeList); + + if ( s == Scope ) + { + retVal = 1; + break; + } + + sl = sl->next; + } + + up( &Scope_Lock ); + + return( retVal ); +} + +/*++======================================================================*/ +char *Scope_Get_UserName( PSCOPE_LIST Scope ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + char *name=NULL; + + if ( !Scope ) + { + Scope = Scope_Find_Scope( TRUE ); + } + + if ( Scope && Scope_Validate_Scope( Scope )) + { + name = Scope->ScopeUserName; + } + return( name ); +} + +/*++======================================================================*/ +session_t Scope_Get_SessionId( PSCOPE_LIST Scope ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + session_t sessionId=0; + + DbgPrint("Scope_Get_SessionId: 0x%p\n", Scope); + if ( !Scope ) + { + Scope = Scope_Find_Scope( TRUE ); + } + + if ( Scope && Scope_Validate_Scope( Scope )) + { + sessionId = Scope->SessionId; + } + DbgPrint("Scope_Get_SessionId: return 0x%llx\n", sessionId); + return( sessionId ); +} + +/*++======================================================================*/ +PSCOPE_LIST Scope_Get_ScopefromName( struct qstr *Name ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + PSCOPE_LIST scope, rscope=NULL; + struct list_head *sl; + + DbgPrint("Scope_Get_ScopefromName: %.*s\n", Name->len, Name->name); + + down( &Scope_Lock ); + + sl = Scope_List.next; + while (sl != &Scope_List) + { + scope = list_entry(sl, SCOPE_LIST, ScopeList); + + if ( (Name->len == scope->ScopeUserNameLength) && + (0 == strncmp(scope->ScopeUserName, Name->name, Name->len)) ) + { + rscope = scope; + break; + } + + sl = sl->next; + } + + up( &Scope_Lock ); + + return( rscope ); +} + +/*++======================================================================*/ +int Scope_Set_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + PSCOPE_LIST scope; + int retVal=0; + + scope = Scope_Find_Scope( TRUE ); + + if ( scope ) + { + if (TotalSize) scope->ScopeUSize = *TotalSize; + if (Free) scope->ScopeUFree = *Free; + if (TotalEnties) scope->ScopeUTEnties = *TotalEnties; + if (FreeEnties) scope->ScopeUAEnties = *FreeEnties; + } + + + return( retVal ); +} + +/*++======================================================================*/ +int Scope_Get_UserSpace( uint64_t *TotalSize, uint64_t *Free, uint64_t *TotalEnties, uint64_t *FreeEnties ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + PSCOPE_LIST scope; + int retVal=0; + + uint64_t td, fd, te, fe; + + scope = Scope_Find_Scope( TRUE ); + + td = fd = te = fe = 0; + if ( scope ) + { + + retVal = Daemon_Get_UserSpace(scope->SessionId, &td, &fd, &te, &fe); + + scope->ScopeUSize = td; + scope->ScopeUFree = fd; + scope->ScopeUTEnties = te; + scope->ScopeUAEnties = fe; + } + + if (TotalSize) *TotalSize = td; + if (Free) *Free = fd; + if (TotalEnties) *TotalEnties = te; + if (FreeEnties) *FreeEnties = fe; + + return( retVal ); +} + +/*++======================================================================*/ +PSCOPE_LIST Scope_Get_ScopefromPath( struct dentry *Dentry ) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + PSCOPE_LIST scope=NULL; + char *buf, *path, *cp; + struct qstr name; + + buf = (char *)Novfs_Malloc(PATH_LENGTH_BUFFER, GFP_KERNEL); + if (buf) + { + path = Scope_dget_path( Dentry, buf, PATH_LENGTH_BUFFER, 0 ); + if (path) + { + DbgPrint("Scope_Get_ScopefromPath: %s\n", path ); + + if (*path == '/') path++; + + cp = path; + if ( *cp ) + { + while ( *cp && (*cp != '/') ) cp++; + + *cp = '\0'; + name.hash = 0; + name.len = (int)(cp-path); + name.name = path; + scope = Scope_Get_ScopefromName( &name ); + } + } + Novfs_Free(buf); + } + + return( scope ); +} + +/*++======================================================================*/ +char *add_to_list(char *Name, char *List, char *EndOfList) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + while (*Name && (List < EndOfList) ) + { + *List++ = *Name++; + } + + if (List < EndOfList) + { + *List++ = '\0'; + } + return(List); +} + +/*++======================================================================*/ +char *Scope_Get_ScopeUsers() +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + PSCOPE_LIST scope; + struct list_head *sl; + int asize=8*MAX_USERNAME_LENGTH; + char *list, *cp, *ep; + + DbgPrint("Scope_Get_ScopeUsers\n"); + + do /* Copy list until done or out of memory */ + { + list = Novfs_Malloc(asize, GFP_KERNEL); + + DbgPrint("Scope_Get_ScopeUsers list=0x%p\n", list); + if (list) + { + cp = list; + ep = cp+asize; + + /* + * Add the tree and server entries + */ + cp = add_to_list(TREE_DIRECTORY_NAME, cp, ep); + cp = add_to_list(SERVER_DIRECTORY_NAME, cp, ep); + + down( &Scope_Lock ); + + sl = Scope_List.next; + while ( (sl != &Scope_List) && (cp < ep) ) + { + scope = list_entry(sl, SCOPE_LIST, ScopeList); + + DbgPrint("Scope_Get_ScopeUsers found 0x%p %s\n", scope, scope->ScopeUserName); + + cp = add_to_list(scope->ScopeUserName, cp, ep); + + sl = sl->next; + } + + up( &Scope_Lock ); + + if (cp < ep) + { + *cp++ = '\0'; + asize = 0; + } + else /* Allocation was to small, up size */ + { + asize *= 4; + Novfs_Free(list); + list=NULL; + } + } + else /* if allocation fails return an empty list */ + { + break; + } + } while ( !list ); /* List was to small try again */ + + return( list ); +} + +/*++======================================================================*/ +void *Scope_Lookup() +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + PSCOPE_LIST scope; + + scope = Scope_Find_Scope( TRUE ); + return( scope ); +} + +/*++======================================================================*/ +void +NO_TRACE +Scope_Timer_Function(unsigned long Context) +/* + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + up(&Scope_Thread_Delay); +} + +/*++======================================================================*/ +int Scope_Cleanup_Thread(void *Args) +/* + * + * Arguments: + * + * Returns: + * + * Abstract: + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + PSCOPE_LIST scope, rscope; + struct list_head *sl, cleanup; + task_t *task; + + DbgPrint( "Scope_Cleanup_Thread: %d\n", current->pid); + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) + lock_kernel(); + snprintf(current->comm, 16, "novfs_ST"); + unlock_kernel(); + sys_close(0); + sys_close(1); + sys_close(2); +#endif + + /* + * Setup and start que timer + */ + init_timer( &Scope_Timer ); + + for ( ;; ) + { + DbgPrint( "Scope_Cleanup_Thread: looping\n"); + if ( Scope_Thread_Terminate ) + { + break; + } + + /* + * Check scope list for any terminated processes + */ + down( &Scope_Lock ); + + sl = Scope_List.next; + INIT_LIST_HEAD( &cleanup ); + + while (sl != &Scope_List) + { + scope = list_entry(sl, SCOPE_LIST, ScopeList); + sl = sl->next; + + rscope = NULL; + read_lock(&tasklist_lock); + for_each_process(task) + { + if ( (task->uid == scope->ScopeUid) || (task->euid == scope->ScopeUid) ) + { + rscope = scope; + break; + } + } + read_unlock(&tasklist_lock); + if ( !rscope ) + { + list_move( &scope->ScopeList, &cleanup ); + DbgPrint("Scope_Cleanup_Thread: Scope=0x%x\n", rscope); + } + } + + up(&Scope_Lock); + + sl = cleanup.next; + while ( sl != &cleanup ) + { + scope = list_entry(sl, SCOPE_LIST, ScopeList); + sl = sl->next; + + DbgPrint("Scope_Cleanup_Thread: Removing 0x%x\n" \ + " ScopeId: 0x%llx\n" \ + " SessionId: 0x%llx\n" \ + " ScopePid: %d\n" \ + " ScopeTask: 0x%x\n" \ + " ScopeHash: %d\n" \ + " ScopeUid: %d\n" \ + " ScopeUserName: %s\n", + scope, + scope->ScopeId, + scope->SessionId, + scope->ScopePid, + scope->ScopeTask, + scope->ScopeHash, + scope->ScopeUid, + scope->ScopeUserName); + if ( !Scope_Search4Scope(scope->SessionId, TRUE, FALSE) ) + { + Novfs_Remove_from_Root( scope->ScopeUserName ); + Daemon_DestroySessionId( scope->SessionId ); + } + Novfs_Free( scope ); + } + + Scope_Timer.expires = jiffies + HZ*CLEANUP_INTERVAL; + Scope_Timer.data = (unsigned long)0; + Scope_Timer.function = Scope_Timer_Function; + add_timer(&Scope_Timer); + DbgPrint( "Scope_Cleanup_Thread: sleeping\n"); + + if (down_interruptible( &Scope_Thread_Delay )) + { + break; + } + del_timer(&Scope_Timer); + } + Scope_Thread_Terminate = 0; + + printk( KERN_INFO "Scope_Cleanup_Thread: Exit\n"); + DbgPrint( "Scope_Cleanup_Thread: Exit\n"); + return(0); +} + +/*++======================================================================*/ +void Scope_Cleanup( void ) +/* + * + * Arguments: None + * + * Returns: Nothing + * + * Abstract: Removes all knows scopes. + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + PSCOPE_LIST scope; + struct list_head *sl; + + DbgPrint( "Scope_Cleanup:\n"); + + /* + * Check scope list for any terminated processes + */ + down( &Scope_Lock ); + + sl = Scope_List.next; + + while (sl != &Scope_List) + { + scope = list_entry( sl, SCOPE_LIST, ScopeList ); + sl = sl->next; + + list_del( &scope->ScopeList ); + + DbgPrint("Scope_Cleanup: Removing 0x%x\n" \ + " ScopeId: 0x%llx\n" \ + " SessionId: 0x%llx\n" \ + " ScopePid: %d\n" \ + " ScopeTask: 0x%x\n" \ + " ScopeHash: %d\n" \ + " ScopeUid: %d\n" \ + " ScopeUserName: %s\n", + scope, + scope->ScopeId, + scope->SessionId, + scope->ScopePid, + scope->ScopeTask, + scope->ScopeHash, + scope->ScopeUid, + scope->ScopeUserName); + if ( !Scope_Search4Scope( scope->SessionId, TRUE, TRUE ) ) + { + Novfs_Remove_from_Root( scope->ScopeUserName ); + Daemon_DestroySessionId( scope->SessionId ); + } + Novfs_Free( scope ); + } + + up(&Scope_Lock); + +} + +/*++======================================================================*/ +char * +NO_TRACE +Scope_dget_path( struct dentry *Dentry, char *Buf, unsigned int Buflen, int Flags) +/* + * Arguments: struct dentry *Dentry - starting entry + * char *Buf - pointer to memory buffer + * unsigned int Buflen - size of memory buffer + * + * Returns: pointer to path. + * + * Abstract: Walks the dentry chain building a path. + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + char *retval=&Buf[Buflen]; + struct dentry *p=Dentry; + int len; + + *(--retval) = '\0'; + Buflen--; + +/* + if (!IS_ROOT(p)) + { + while (Buflen && !IS_ROOT(p)) + { + if (Buflen > p->d_name.len) + { + retval -= p->d_name.len; + Buflen -= p->d_name.len; + memcpy(retval, p->d_name.name, p->d_name.len); + *(--retval) = '/'; + Buflen--; + p = p->d_parent; + } + else + { + retval = NULL; + break; + } + } + } + if (Flags) + { + len = strlen(p->d_sb->s_type->name); + if (Buflen-len > 0) + { + retval -= len; + Buflen -= len; + memcpy(retval, p->d_sb->s_type->name, len); + *(--retval) = '/'; + Buflen--; + } + } + else + { + *(--retval) = '/'; + Buflen--; + } +*/ + do + { + if (Buflen > p->d_name.len) + { + retval -= p->d_name.len; + Buflen -= p->d_name.len; + memcpy(retval, p->d_name.name, p->d_name.len); + *(--retval) = '/'; + Buflen--; + p = p->d_parent; + } + else + { + retval = NULL; + break; + } + } while (!IS_ROOT(p)); + + if (IS_ROOT(Dentry)) + { + retval++; + } + + if (Flags) + { + len = strlen(p->d_sb->s_type->name); + if (Buflen-len > 0) + { + retval -= len; + Buflen -= len; + memcpy(retval, p->d_sb->s_type->name, len); + *(--retval) = '/'; + Buflen--; + } + } + + return(retval); +} + +void Scope_Dump_Tasklist( void ) +{ +#ifdef OLD_DEBUG_KERNEL + task_t *task; + struct files_struct *fs; + int i, open_files=0; + static char buf[1024]; + char *path; + + + for_each_process(task) + { + kdb_printf("Task List:\n" \ + " Task: 0x%p\n" \ + " pid: %d\n" \ + " tgid: %d\n" \ + " uid: %d %d %d %d\n" \ + " gid: %d\n" \ + " parent: 0x%p\n" \ + " comm: %s\n" \ + " user: 0x%p\n" \ + " real_parent: 0x%p\n" \ + " parent_exec_id: 0x%x\n" \ + " self_exec_id: 0x%x\n" \ + " did_exec: 0x%x\n" \ + " signal: 0x%p\n" \ + " thread_info: 0x%p\n" \ + " security: 0x%p\n", + task, + task->pid, + task->tgid, + task->uid,task->euid,task->suid,task->fsuid, + task->gid, + task->parent, + task->comm, + task->user, + task->real_parent, + task->parent_exec_id, + task->self_exec_id, + task->did_exec, + task->signal, + task->thread_info, + task->security); + + fs = task->files; + kdb_printf(" File List: 0x%p\n", fs); + if (fs) + { + open_files = fs->max_fds; + kdb_printf(" Max fds: %d\n", open_files); + for (i = 0; ifd[i]; + if (f && (f->f_dentry)) + { + path = Scope_dget_path(f->f_dentry, buf, sizeof(buf), 1); + if ( !path ) + { + path = buf; + memcpy(path, f->f_dentry->d_name.name, f->f_dentry->d_name.len); + path[f->f_dentry->d_name.len] = '\0'; + } + kdb_printf(" file(%d): 0x%p\n" \ + " f_dentry: 0x%p\n" \ + " d_name: %s\n" \ + " d_count: %d\n" \ + " d_inode: 0x%p\n", + i, f, f->f_dentry, path, + atomic_read(&f->f_dentry->d_count), + f->f_dentry->d_inode); + } + } + } + } +#endif +} + +void Scope_Dump_Scopetable( void ) +{ +#ifdef CONFIG_KDB + PSCOPE_LIST scope; + struct list_head *sl; + + sl = Scope_List.next; + while (sl != &Scope_List) + { + scope = list_entry(sl, SCOPE_LIST, ScopeList); + sl = sl->next; + kdb_printf("Scope List:\n" \ + " Scope: 0x%p\n" \ + " ScopeId: 0x%llx\n" \ + " SessionId: 0x%llx\n" \ + " ScopePid: %u\n" \ + " ScopeTask: 0x%p\n" \ + " ScopeHash: 0x%lx\n" \ + " ScopeUid: %ld\n" \ + " ScopeUserName: %s\n", + scope, + scope->ScopeId, + scope->SessionId, + scope->ScopePid, + scope->ScopeTask, + scope->ScopeHash, + (long)scope->ScopeUid, + scope->ScopeUserName); + + } + +#endif +} diff -uNr src.old/src/vfs.h src/src/vfs.h --- src.old/src/vfs.h 1970-01-01 01:00:00.000000000 +0100 +++ src/src/vfs.h 2006-10-16 15:08:22.000000000 +0200 @@ -0,0 +1,283 @@ +/*++======================================================================== + * Program Name: Novell NCP Redirector for Linux + * File Name: vfs.h + * Version: v1.00 + * Author: James Turner + * + * Abstract: Include module for novfs. + * Notes: + * Revision History: + * + * + * Copyright (C) 2005 Novell, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + *======================================================================--*/ +#ifndef __STDC_VERSION__ +#define __STDC_VERSION__ 0L +#endif + +/*===[ Include files specific to Linux ]==================================*/ +#ifdef CONFIG_KDB +#include +#include + +#endif /* CONFIG_KDB */ + +#include +#include + +/*===[ Include files specific to this module ]============================*/ + +/*===[ External data ]====================================================*/ +extern int Novfs_Version_Major; +extern int Novfs_Version_Minor; +extern int Novfs_Version_Sub; +extern int Novfs_Version_Release; + +/*===[ External prototypes ]==============================================*/ +extern void *Novfs_Malloc( size_t, int ); +extern void Novfs_Free( const void * ); + + +/*===[ Manifest constants ]===============================================*/ +#define NOVFS_MAGIC 0x4e574653 +#define MODULE_NAME "novfs" + +#define UNUSED_VARIABLE(a) (a) = (a) + +#define TREE_DIRECTORY_NAME ".Trees" +#define SERVER_DIRECTORY_NAME ".Servers" + +#define PATH_LENGTH_BUFFER PATH_MAX +#define NW_MAX_PATH_LENGTH 255 + +#define IOC_LOGIN 0x4a540000 +#define IOC_LOGOUT 0x4a540001 +#define IOC_XPLAT 0x4a540002 +#define IOC_SESSION 0x4a540003 +#define IOC_DEBUGPRINT 0x4a540004 + +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15) +#define D_CHILD d_u.d_child +#define AS_TREE_LOCK(l) read_lock_irq(l) +#define AS_TREE_UNLOCK(l) read_unlock_irq(l) +#else +#define D_CHILD d_child +#define AS_TREE_LOCK(l) spin_lock_irq(l) +#define AS_TREE_UNLOCK(l) spin_unlock_irq(l) +#endif + +/* + * NetWare file attributes + */ + +#define NW_ATTRIBUTE_NORMAL 0x00 +#define NW_ATTRIBUTE_READ_ONLY 0x01 +#define NW_ATTRIBUTE_HIDDEN 0x02 +#define NW_ATTRIBUTE_SYSTEM 0x04 +#define NW_ATTRIBUTE_EXECUTE_ONLY 0x08 +#define NW_ATTRIBUTE_DIRECTORY 0x10 +#define NW_ATTRIBUTE_ARCHIVE 0x20 +#define NW_ATTRIBUTE_EXECUTE 0x40 +#define NW_ATTRIBUTE_SHAREABLE 0x80 + +/* + * Define READ/WRITE flag for DATA_LIST + */ +#define DLREAD 0 +#define DLWRITE 1 + +/* + * Define list type + */ +#define USER_LIST 1 +#define SERVER_LIST 2 +#define VOLUME_LIST 3 + +/* + * Define flags used in for inodes + */ +#define USER_INODE 1 +#define UPDATE_INODE 2 + +/* + * Define flags for directory cache flags + */ +#define ENTRY_VALID 0x00000001 + +#ifdef INTENT_MAGIC +#define NDOPENFLAGS intent.it_flags +#else +#define NDOPENFLAGS intent.open.flags +#endif + +/* + * daemon_command_t flags values + */ +#define INTERRUPTIBLE 1 + +#define NO_TRACE __attribute__((__no_instrument_function__)) + +#ifndef NOVFS_VFS_MAJOR +#define NOVFS_VFS_MAJOR 0 +#endif + +#ifndef NOVFS_VFS_MINOR +#define NOVFS_VFS_MINOR 0 +#endif + +#ifndef NOVFS_VFS_SUB +#define NOVFS_VFS_SUB 0 +#endif + +#ifndef NOVFS_VFS_RELEASE +#define NOVFS_VFS_RELEASE 0 +#endif + +#define VALUE_TO_STR( value ) #value +#define DEFINE_TO_STR(value) VALUE_TO_STR(value) + + +#define NOVFS_VERSION_STRING \ + DEFINE_TO_STR(NOVFS_VFS_MAJOR)"." \ + DEFINE_TO_STR(NOVFS_VFS_MINOR)"." \ + DEFINE_TO_STR(NOVFS_VFS_SUB)"-" \ + DEFINE_TO_STR(NOVFS_VFS_RELEASE) \ + "\0" + +/*===[ Type definitions ]=================================================*/ +typedef struct _ENTRY_INFO +{ + int type; + umode_t mode; + uid_t uid; + gid_t gid; + loff_t size; + struct timespec atime; + struct timespec mtime; + struct timespec ctime; + int namelength; + unsigned char name[1]; +} ENTRY_INFO, *PENTRY_INFO; + +typedef struct _STRING_ +{ + int Length; + unsigned char *Data; +} STRING, *PSTRING; + +typedef struct _LOGIN_ +{ + STRING Server; + STRING UserName; + STRING Password; +} LOGIN, *PLOGIN; + +typedef struct _LOGOUT_ +{ + STRING Server; +} LOGOUT, *PLOGOUT; + +typedef uint64_t scope_t; +typedef uint64_t session_t; + +typedef struct _DIR_CACHE_ +{ + struct list_head list; + int flags; + u64 jiffies; + ino_t ino; + loff_t size; + umode_t mode; + struct timespec atime; + struct timespec mtime; + struct timespec ctime; + unsigned long hash; + int nameLen; + char name[1]; +} DIR_CACHE, *PDIR_CACHE; + +typedef struct _INODE_DATA_ +{ + void *Scope; + unsigned long Flags; + struct list_head IList; + struct inode *Inode; + struct list_head DirCache; + struct semaphore DirCacheLock; + unsigned long FileHandle; + int CacheFlag; + char Name[1]; /* Needs to be last entry */ +} INODE_DATA, *PINODE_DATA; + +typedef struct _DATA_LIST_ +{ + void *page; + void *offset; + int len; + int rwflag; +} DATA_LIST, *PDATA_LIST; + +typedef struct _XPLAT_ +{ + int xfunction; + unsigned long reqLen; + void *reqData; + unsigned long repLen; + void *repData; + +} XPLAT, *PXPLAT; + + +/*===[ Function prototypes ]==============================================*/ + +extern int DbgPrint( char *Fmt, ... ); +extern char *ctime_r(time_t *clock, char *buf); + + +/*++======================================================================*/ +static inline unsigned long InterlockedIncrement( unsigned long *p ) +/* + * + * Arguments: unsigned long *p - pointer to value. + * + * Returns: unsigned long - value prior to increment. + * + * Abstract: The value of *p is incremented and the value of *p before + * it was incremented is returned. This is an atomic operation. + * + * Notes: + * + * Environment: + * + *========================================================================*/ +{ + unsigned long x = 1; + + mb(); + +#if defined(__i386) || defined(__i386__) + __asm__ __volatile__( + " lock xadd %0,(%2)" + : "+r"(x), "=m"(p) + : "r"(p), "m"(p) + : "memory"); + +#else + x = *p++; +#endif + return( x ); +}