of storage depending on which compilers are selected. The following
versions are supported:
- Microsoft Visual C++ 6.0
Microsoft Visual .NET
+ available via a MSDN subscription
+
Microsoft Visual .NET 2003 (recommended)
+ available via a MSDN subscription
+
+ Microsoft Visual C++ Toolkit 2003 (same as .NET 2003)
+ http://msdn.microsoft.com/visualc/vctoolkit2003/
+
+The following Microsoft SDK is required:
+
+ Microsoft Platform SDK for Windows XP SP2 [Core, Data Access and Installer SDKs are required]
+ http://www.microsoft.com/msdownload/platformsdk/sdkupdate/downlevel.htm [IE required]
+ http://www.microsoft.com/msdownload/platformsdk/sdkupdate/XPSP2FULLInstall.htm
+
+The following Microsoft DDK is required:
- Microsoft Platform SDK for Windows XP SP2
- [Core and Data Access SDKs are required]
+ Microsoft Windows Server 2003 DDK
+ available via a MSDN subscription or via free CD
+ http://www.microsoft.com/whdc/devtools/ddk/orderddkcd.mspx
The NSIS installer requires about 14 MB of storage. The following
-version is supported.
+version is supported:
Nullsoft Scriptable Installation System 2.0
+ http://nsis.sourceforge.net/home/
+
+The WiX installer requires about 18 MB of storage. The following
+version is supported:
+
+ Wix 2.0.2217.0
+ http://prdownloads.sourceforge.net/wix/sources-2.0.2217.0.zip
The InstallShield scripts (although not supported) require version 5.5
of InstallShiled. Version 6.0 or higher of InstallShield are not
downloaded from the OpenAFS web site:
http://www.OpenAFS.org/release/snapindex.html.
-For this example, download source for version 1.3.60 using the
+For this example, download source for version 1.3.74 using the
following URL:
-http://www.openafs.org/dl/openafs/1.3.60/openafs-1.3.60-src.tar
+http://www.openafs.org/dl/openafs/1.3.74/openafs-1.3.74-src.tar
HINT: DailySnapShots are pre-release source trees and much more
likely to have compilation errors. If this is your first attempt, do
-your build based on a release version of the source, e.g. 1.3.60. Once
+your build based on a release version of the source, e.g. 1.3.74. Once
you have completed a build process successfully, you can experiment with
other source trees.
For example "Pkzip for Windows" from Pkware will uncompress tar files.
(http://www.pkware.com/)
-Expand the downloaded tar file (openafs-1.3.60-src.tar) into target
+Expand the downloaded tar file (openafs-1.3.74-src.tar) into target
directory (c:\OpenAFS), the unzip routine will expand the source into a
subdirectory tree:
- c:\OpenAFS\OpenAFS-1.3.60\src
+ c:\OpenAFS\OpenAFS-1.3.74\src
Copy the files 'NTMakefile' and 'ntbuild.bat' from 'src' to the OpenAFS
-base directory:
+base directory (aka %AFSROOT%):
From a DOS command prompt window, enter the following copy commands:
- copy c:\OpenAFS\OpenAFS-1.3.60\src\NTMakefile c:\OpenAFS\OpenAFS-1.3.60\.
- copy c:\OpenAFS\OpenAFS-1.3.60\src\ntbuild.bat c:\OpenAFS\OpenAFS-1.3.60\.
+ cd c:\OpenAFS\OpenAFS-1.3.74
+ copy src\NTMakefile .
+ copy src\ntbuild.bat .
The AFS base directory should look something like the following:
- c:\OpenAFS\OpenAFS-1.3.60\
+ c:\OpenAFS\OpenAFS-1.3.74\
NTMakefile
ntbuild.bat
src
STEP B. Install compiler and development tools.
-Install a copy of Microsoft Visual C++ 6.0, Visual .NET, or Visual .NET 2003.
-The "Typical" install setting is sufficient.
+Install a copy of Microsoft Visual .NET, Visual .NET 2003, Visual C++
+Toolkit 2003. The "Typical" install setting is sufficient.
(1) You can reduce the installation size by selecting "Custom" install
and remove all but the following Options:
STEP C. Install SDK header files.
-Files from Microsoft's Platform SDK (August 2001 or later) are required to
-complete a build on Windows 2000 or XP. You can install the "Core SDK"
-from
+Files from Microsoft's Platform SDK for Windows XP SP2 is required to
+complete a build on Windows 2000/XP/2003. You can install the "Core, Data
+Access and Installer SDKs" from
http://www.microsoft.com/msdownload/platformsdk/sdkupdate/
by using Internet Explorer 5.x or higher. (Active X controls are required)
+If you do not which to use IE a complete SDK package is available from
+
+ http://www.microsoft.com/msdownload/platformsdk/sdkupdate/XPSP2FULLInstall.htm
The header files that are required are found from a Microsoft SDK are:
- netspi.h (Windows 9x builds)
npapi.h (Windows 2000,XP,2003 builds)
netcfgx.h (NSIS Loopback Adapter installer - Windows 2000,XP,2003 builds)
netcfgn.h (NSIS Loopback Adapter installer - Windows 2000,XP,2003 builds)
These files come from the following Microsoft DDKs/SDKs:
npapi.h:
- Windows XP/2003 Platform SDK - include/
+ Windows XP SP2 Platform SDK - include/
netcfgn.h, netcfgx.h:
Windows XP/2003 DDK - inc/wxp/
- netmpr.h, netspi.h:
- July 1998 Windows 95 DDK - net/inc/netmpr.h and net/inc/netspi.h
- July 1999 Windows 98 DDK - src/net/inc/netmpr.h and src/net/inc/netspi.h
- - you need to install "Legacy and Related
- driver samples"
STEP D. Configure NTBUILD.BAT.
AFSVER_CL: Set to 1200 if using MS Visual C++ 6.0
Set to 1300 if using MS Visual .NET
Set to 1310 if using MS Visual .NET 2003
+ Set to 1400 if using MS Visual .NET 2005
MSVCDIR: Set to the short name version of the directory into which
the visual C++ compiler was installed regardless of version
AFSPRODUCT_VER_MINOR - Version Minor Number
AFSPRODUCT_VER_PATCH - Version Patch Number
AFSPRODUCT_VER_BUILD - Version Build Number
- CELLSERVDB_INSTALL - The default file name for the CellServDB
- included in the install Package.
- CELLNAME_DEFAULT - The default home cell name.
- CELLSERVDB_WEB - The default web address to obtain CellServDB
+ CELLSERVDB_INSTALL - The default file name for the CellServDB
+ included in the install Package.
+ CELLNAME_DEFAULT - The default home cell name.
+ CELLSERVDB_WEB - The default web address to obtain CellServDB
For example: in the file %AFSROOT%\src\config\NTMakefile.i386_nt40 you would
see the following:
AFSPRODUCT_VER_MAJOR=1
AFSPRODUCT_VER_MINOR=3
- AFSPRODUCT_VER_PATCH=6000
+ AFSPRODUCT_VER_PATCH=7400
AFSPRODUCT_VER_BUILD=0
CELLNAME_DEFAULT=openafs.org
CELLSERVDB_INSTALL=CellServDB.GrandCentral
STEP F. Begin the build
-(1) From Windows 2000/XP open up a DOS prompt window.
+(1) From Windows 2000/XP/2003 open up a DOS prompt window.
(2) Change to the %AFSROOT% directory
STEP H. Build OpenAFS NSIS install package
-From the DOS command prompt window run:
+From the %AFSROOT% directory execute:
nmake /f NTMakefile NSIS
STEP I. Install Wix MSI Installer
-Download the Wix 2.0.1927.1 installer from
+Download the Wix 2.0.2217.0 installer from
- http://prdownloads.sourceforge.net/wix/sources-2.0.1927.1.zip
+ http://prdownloads.sourceforge.net/wix/sources-2.0.2217.0.zip
Apply the following patches to the source tree and execute
from the \src\wix directory.
+Index: src/wix/Common.cs
+===================================================================
+RCS file: /cvsroot/wix/wix/src/wix/Common.cs,v
+retrieving revision 1.7
+diff -w -r1.7 Common.cs
+140a141,146
+> public static long GetFileTimeFromDateTime(string dateTime)
+> {
+> System.DateTime sdt = System.Xml.XmlConvert.ToDateTime(dateTime);
+> return sdt.ToFileTime();
+> }
+>
Index: src/wix/Compiler.cs
===================================================================
RCS file: /cvsroot/wix/wix/src/wix/Compiler.cs,v
-retrieving revision 1.10
-diff -u -w -r1.10 Compiler.cs
---- src/wix/Compiler.cs 28 Jul 2004 15:50:22 -0000 1.10
-+++ src/wix/Compiler.cs 4 Aug 2004 16:28:16 -0000
-@@ -647,7 +647,7 @@
- // add the core registry keys for each context in the class
- for (int i = 0; i < contextCount; ++i)
- {
-- this.AddRegistryKey(sourceLineNumbers, null, 0, String.Concat("CLSID\\", classId, "\\", context[i]), String.Empty, String.Concat("\"[!", fileServer, "]", argument == null ? String.Empty : " ", argument, "\""), componentId); // ClassId context
-+ this.AddRegistryKey(sourceLineNumbers, null, 0, String.Concat("CLSID\\", classId, "\\", context[i]), String.Empty, String.Concat("\"[#", fileServer, "]", argument == null ? String.Empty : " ", argument, "\""), componentId); // ClassId context
- if (null != icon) // ClassId default icon
- {
- if (null != iconIndex)
-@@ -7385,6 +7385,20 @@
- break;
- }
- break;
-+ case "Delete":
-+ switch (attrib.Value)
-+ {
-+ case "install":
-+ events |= MsiInterop.MsidbServiceControlEventDelete;
-+ break;
-+ case "uninstall":
-+ events |= MsiInterop.MsidbServiceControlEventUninstallDelete;
-+ break;
-+ case "both":
-+ events |= MsiInterop.MsidbServiceControlEventDelete | MsiInterop.MsidbServiceControlEventUninstallDelete;
-+ break;
-+ }
-+ break;
- case "Wait":
- wait = Common.IsYes(attrib.Value, sourceLineNumbers, node.Name, attrib.Name, id) ? "1" : "0"; // strings used since integer column is nullable
- break;
-@@ -8715,6 +8729,7 @@
- }
- bits ^= (bit * 65536);
- break;
-+
- default:
- bit = this.NameToBit(MsiInterop.CommonControlAttributes, attrib.Name, attrib.Value, node.Name, id);
- if (-1 == bit)
+retrieving revision 1.14
+diff -w -r1.14 Compiler.cs
+847c847
+< this.AddRegistryKey(sourceLineNumbers, null, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\", context[i]), String.Empty, String.Concat("\"[!", fileServer, "]", argument == null ? String.Empty : " ", argument, "\""), componentId); // ClassId context
+---
+> this.AddRegistryKey(sourceLineNumbers, null, MsiInterop.MsidbRegistryRootClassesRoot, String.Concat("CLSID\\", classId, "\\", context[i]), String.Empty, String.Concat("\"[#", fileServer, "]", argument == null ? String.Empty : " ", argument, "\""), componentId); // ClassId context
+2352a2353,2358
+> // if a Value attribute was given by itself, make this a type 19 custom action
+> if( sourceBits == 0 && targetBits == MsiInterop.MsidbCustomActionTypeTextData )
+> {
+> sourceBits = MsiInterop.MsidbCustomActionTypeSourceFile;
+> }
+>
+3881c3887
+< minDate = attrib.Value;
+---
+> minDate = Common.GetFileTimeFromDateTime( attrib.Value ).ToString();
+3884c3890
+< maxDate = attrib.Value;
+---
+> maxDate = Common.GetFileTimeFromDateTime( attrib.Value ).ToString();
+8187a8194,8207
+> case "Delete":
+> switch (attrib.Value)
+> {
+> case "install":
+> events |= MsiInterop.MsidbServiceControlEventDelete;
+> break;
+> case "uninstall":
+> events |= MsiInterop.MsidbServiceControlEventUninstallDelete;
+> break;
+> case "both":
+> events |= MsiInterop.MsidbServiceControlEventDelete | MsiInterop.MsidbServiceControlEventUninstallDelete;
+> break;
+> }
+> break;
+9685a9706
+>
Index: src/wix/Preprocessor.cs
===================================================================
RCS file: /cvsroot/wix/wix/src/wix/Preprocessor.cs,v
-retrieving revision 1.5
-diff -u -w -r1.5 Preprocessor.cs
---- src/wix/Preprocessor.cs 28 Jul 2004 15:50:22 -0000 1.5
-+++ src/wix/Preprocessor.cs 4 Aug 2004 16:28:16 -0000
-@@ -267,12 +267,12 @@
- break;
- case "ifdef":
- stack.Push(context);
-- context = new IfContext(context.IsTrue & context.Active, this.variables.ContainsKey(reader.Value.Trim()), IfState.If);
-+ context = new IfContext(context.IsTrue & context.Active, this.IsDefined(reader.Value.Trim()), IfState.If);
- ignore = true;
- break;
- case "ifndef":
- stack.Push(context);
-- context = new IfContext(context.IsTrue & context.Active, !this.variables.ContainsKey(reader.Value.Trim()), IfState.If);
-+ context = new IfContext(context.IsTrue & context.Active, !this.IsDefined(reader.Value.Trim()), IfState.If);
- ignore = true;
- break;
- case "elseif":
-@@ -354,6 +354,8 @@
- break;
- case "endforeach": // endforeach is handled in PreprocessForeach, so seeing it here is an error
- throw new WixPreprocessorException(this.GetCurrentSourceLineNumbers(), "Cannot have a <?endforeach?> processing instruction without a matching <?foreach?>.");
-+ case "error":
-+ throw new WixPreprocessorException(this.GetCurrentSourceLineNumbers(), this.PreprocessVariables(reader.Value));
- default:
- // Console.WriteLine("processing instruction: {0}, {1}", reader.Name, reader.Value);
- break;
-@@ -401,6 +403,22 @@
- }
-
- /// <summary>
-+ /// Returns true if the symbol exists.
-+ /// </summary>
-+ /// <param name="symbol">symbol name to check</param>
-+ /// <returns>true if symbol is defined</returns>
-+ private bool IsDefined(string symbol)
-+ {
-+ if( symbol.StartsWith("env.") )
-+ return Environment.GetEnvironmentVariable(symbol.Substring(4)) != null;
-+ if( symbol.StartsWith("var.") )
-+ return this.variables.ContainsKey(symbol.Substring(4));
-+ if( symbol.StartsWith("sys.") )
-+ return this.systemVariables.ContainsKey(symbol.Substring(4));
-+ return this.variables.ContainsKey(symbol);
-+ }
-+
-+ /// <summary>
- /// Replaces parameters in the source text.
- /// </summary>
- /// <param name="value">Text that may contain parameters to replace.</param>
+retrieving revision 1.6
+diff -w -r1.6 Preprocessor.cs
+274c274
+< context = new IfContext(context.IsTrue & context.Active, this.variables.ContainsKey(reader.Value.Trim()), IfState.If);
+---
+> context = new IfContext(context.IsTrue & context.Active, this.IsDefined(reader.Value.Trim()), IfState.If);
+279c279
+< context = new IfContext(context.IsTrue & context.Active, !this.variables.ContainsKey(reader.Value.Trim()), IfState.If);
+---
+> context = new IfContext(context.IsTrue & context.Active, !this.IsDefined(reader.Value.Trim()), IfState.If);
+360a361,362
+> case "error":
+> throw new WixPreprocessorException(this.GetCurrentSourceLineNumbers(), this.PreprocessVariables(reader.Value));
+419a422,437
+> /// Returns true if the symbol exists.
+> /// </summary>
+> /// <param name="symbol">symbol name to check</param>
+> /// <returns>true if symbol is defined</returns>
+> private bool IsDefined(string symbol)
+> {
+> if( symbol.StartsWith("env.") )
+> return Environment.GetEnvironmentVariable(symbol.Substring(4)) != null;
+> if( symbol.StartsWith("var.") )
+> return this.variables.ContainsKey(symbol.Substring(4));
+> if( symbol.StartsWith("sys.") )
+> return this.systemVariables.ContainsKey(symbol.Substring(4));
+> return this.variables.ContainsKey(symbol);
+> }
+>
+> /// <summary>
Index: src/wix/wix.csproj
===================================================================
RCS file: /cvsroot/wix/wix/src/wix/wix.csproj,v
retrieving revision 1.4
-diff -u -w -r1.4 wix.csproj
---- src/wix/wix.csproj 31 May 2004 01:07:40 -0000 1.4
-+++ src/wix/wix.csproj 4 Aug 2004 16:28:16 -0000
-@@ -659,9 +659,19 @@
- BuildAction = "EmbeddedResource"
- />
- <File
-+ RelPath = "Xsd\wix.xsx"
-+ DependentUpon = "wix.xsd"
-+ BuildAction = "None"
-+ />
-+ <File
- RelPath = "Xsd\wixloc.xsd"
- BuildAction = "Content"
- />
-+ <File
-+ RelPath = "Xsd\wixloc.xsx"
-+ DependentUpon = "wixloc.xsd"
-+ BuildAction = "None"
-+ />
- </Include>
- </Files>
- </CSHARP>
-Index: src/wix/Xsd/wix.xsd
-===================================================================
-RCS file: /cvsroot/wix/wix/src/wix/Xsd/wix.xsd,v
-retrieving revision 1.12
-diff -u -w -r1.12 wix.xsd
---- src/wix/Xsd/wix.xsd 28 Jul 2004 15:50:24 -0000 1.12
-+++ src/wix/Xsd/wix.xsd 4 Aug 2004 16:28:17 -0000
-@@ -2733,6 +2733,7 @@
- </xs:restriction>
- </xs:simpleType>
- </xs:attribute>
-+ <xs:attribute name="Separator" type="xs:string"/>
- <xs:attribute name="Permanent" type="YesNoType"/>
- <xs:attribute name="System" type="YesNoType"/>
- </xs:complexType>
+diff -w -r1.4 wix.csproj
+661a662,666
+> RelPath = "Xsd\wix.xsx"
+> DependentUpon = "wix.xsd"
+> BuildAction = "None"
+> />
+> <File
+664a670,674
+> <File
+> RelPath = "Xsd\wixloc.xsx"
+> DependentUpon = "wixloc.xsd"
+> BuildAction = "None"
+> />
STEP J. Build Wix MSI install package
-From the DOS command prompt window run:
+From the %AFSROOT% directory execute:
nmake /f NTMakefile wix
The build process generates its binaries in %AFSROOT%\DEST. The subdirectory
would look like the following:
-%AFSROOT%:\DEST\{checked,free}\
+%AFSROOT%\DEST\{checked,free}\
bin
etc
include
Bin - contains build utilities.
root.client - contains Open AFS binaries
root.server - contain Open AFS Server binaries
- WinInstall\OpenAFSforWindows.exe - is the install package for Open AFS
+ WinInstall\OpenAFSforWindows.exe - is the NSIS install package
+ WinInstall\openafs-en_US.msi - is the WiX MSI install package
STEP L. Optional Items
+Since 1.3.72/73:
+ * Fix the locking of objects during Directory Searches in the
+ SMB/CIFS server. The failure to properly lock the reference
+ counts was resulting in the premature freeing of smb_dirSearch_t
+ objects while they were still in use by the SMB/CIFS client.
+ This does not solve the "Invalid Handle" problem.
+
+ * Fix Find Cell By Name pioctl call to return a valid cell
+ name for the Freelance fake root.afs volume.
+ "Freelance.Local.Root".
+
+ * Fix the Explorer Shell Extension Symlinks->Add operation.
+ The dialog template was missing and the link destination
+ string was too short.
+
+ * Add support for symlinks to Freelance root.afs volume
+ Stored at HKLM\SOFTWARE\OpenAFS\Client\Freelance\Symlinks
+ <number> = "<linkname>:<relative-path>."
+ Use symlink.exe to create, list, or remove
+
+ * Remove the fallback to the use of KFW's KRB4 library when obtaining
+ tokens. We never obtain KRB4 tickets.
+
+ * Fix AFS Client Configuration Control Panel to support new SysName
+ protocol.
+ * Fix a bug in afsd_service.exe which could result in the SysName
+ not being read from the registry.
+
Since 1.3.71:
* Add code to block the issuance of AFS tokens by aklog.exe or
afscreds.exe when the Kerberos 5 principal name contains a dot.
-OpenAFS for Windows 1.3.72 Installation Notes
+OpenAFS for Windows 1.3.74 Installation Notes
---------------------------------------------
The OpenAFS for Windows product was very poorly maintained throughout the
dynamically constructed when the service starts. This mode is called
Freelance mode. Freelance mode is turned on by default.
-The contents of the
-fake "root.afs" volume are constructed dynamically as cells are accessed.
-When the fake "root.afs" volume is constructed it will only contain two
-mount points: a read-only and read-write mount point used to access the
-"root.cell" volume of the default AFS cell. Any attempt to access a
-valid cell name will automatically result in a new mount point
+The contents of the fake "root.afs" volume are constructed dynamically as
+cells are accessed. When the fake "root.afs" volume is constructed it will
+only contain two mount points: a read-only and read-write mount point used
+to access the "root.cell" volume of the default AFS cell. Any attempt to
+access a valid cell name will automatically result in a new mount point
being created in the fake "root.afs" volume. If the cellname begins with
a "." the mount point will be read-write; otherwise the mount point will
be read-only. These mount points are preserved in the registry at key:
+
HKLM\SOFTWARE\OpenAFS\Client\Freelance
Additional mount points may be manually created using the "fs mkmount"
command. Mount points may be removed using the "fs rmmount" command.
- fs mkmount \\AFS\all\athena.mit.edu root.cell athena.mit.edu
- fs mkmount \\AFS\all\.athena.mit.edu root.cell athena.mit.edu -rw
- fs rmmount \\AFS\all\athena.mit.edu
- fs rmmount \\AFS\all\.athena.mit.edu
+ >fs mkmount \\AFS\all\athena.mit.edu root.cell athena.mit.edu
+ >fs mkmount \\AFS\all\.athena.mit.edu root.cell athena.mit.edu -rw
+ >fs rmmount \\AFS\all\athena.mit.edu
+ >fs rmmount \\AFS\all\.athena.mit.edu
+
+Beginning in 1.3.74, the Freelance fake root.afs volume will support
+the creation of symlinks.
+
+ >symlink make \\afs\all\link \\afs\all\athena.mit.edu\user\j\a\jaltman
+
+ >symlink list \\afs\all\link
+ '\\afs\all\link' is a symlink to 'athena.mit.edu\user\j\a\jaltman'
+
+ >symlink rm \\afs\all\link
+
+The symlinks are stored in the registry at:
+
+ HKLM\SOFTWARE\OpenAFS\Client\Freelance\Symlinks
4. The OpenAFS for Windows client will use AFSDB DNS records to
such time as their organizations can provide a more permanent solution.
+25. The Status Cache (AFS Config Control Panel: Advanced Page) is defined
+to have a maximum number of entries. Each entry represents a single file
+or directory entry accessed within the AFS file system. When the maximum
+number of entries are allocated, entries will begin to be reused according
+to a least recently used (LRU) algorithm. If the number of files or
+directories being accessed repeatedly by your applications is greater then
+the maximum number of entries, your host will begin to experience thrashing
+of the Status Cache and all requests will result in network operations.
+
+If you are experiencing poor performance you might want to increase the
+maximum number of Status Cache entries. Each entry requires 164K. Only
+those entries which are used are allocated.
+
------------------------------------------------------------------------
description must be unique. "home" cannot be reused. We need a way
to remove "home" from the submount list.
+ [Actually, an end user should not be able to modify the submount list]
+
(16) WinAFS configuration values are still stored in old style INI files
instead of using the Registry. This is especially important for
per-user values such as drive mappings
can be executed prior to the completion of the SMB registration
and service thread initialization.
-(28) Should we allow the AFSCACHE file to be stored in the Virtual Paging
- file as long as we do not support persistent caches?
-
-(29) CIFS Remote Administration Protocol implementation is incomplete.
+(28) CIFS Remote Administration Protocol implementation is incomplete.
Notifications are not made to requestors when the view of a file
or folder changes due to token acquisition; token expiration; or
token destruction
-(30) Microsoft Office appears to have trouble editing files of ~20MB
- or larger from within AFS. Performance is particularly slow and
- applications such as Word often crash upon saving the files.
+(29) The Cache Manager Flush routines do not return or check error
+ codes.
+
+(30) Remove submount creation as a side effect of AFS drive mapping.
+
+ The AFS Submount is effectively a server side alias for a path
+ located in the AFS space. This alias is exported by the AFS
+ SMB/CIFS Server to the Windows SMB/CIFS client as a Share name.
+ This makes the AFS Submount a system global setting which should
+ only be modified by a member of the "AFS Client Admin" group.
-(31) The Cache Manager Flush routines do not return or check error
- codes.
+ afs_creds.exe and afs_config.exe should be modified to no longer
+ use submount names when creating drive maps. Drive maps should
+ simply use the full AFS path name. Submounts should not be
+ created as a side effect of a drive mapping.
+
+ The creation of submounts should only be possible via afsshare.exe
+ or by the new AFS Client Service Administration tool when executed
+ by an authorized user.
-------------------------------------------------------------------------
List of unfunded projects:
8. Re-write afs_config.exe to be only "per user" functionality which does not require admin
privileges
1. default cell and principal for the user
- 2. drive mappings
+ 2. drive mappings but no submounts
3. visibility of afs creds and setting of afs creds startup options
9. Create new afs_admin.exe tool to be installed in the administrator folder (or use MMS)
which contains
11. Add support for configurable Icon file representing AFS folders within the Explorer Shell
12. Documentation Documentation Documentation
13. Large File support (> 2GB)
- 14. Integrate KFW installation into the NSIS installer
+ 14. Integrate KFW installation into the NSIS and MSI installers
15. Add support for record locking to AFS (requires changes to the servers)
16. Unicode enable the SMB/CIFS server. OEM Code Pages:
1. prevent the use of interoperable file names
3. force share names to be no longer than 13 characters
4. restrict authentication to ASCII only names and passwords
17. Complete implementation of CIFS Remote Administration Protocol
- 18. Correct the problems with overlapped writes which adversely affect
- Microsoft Office applications storing documents and temporary files
- within AFS volumes
19. Add support for SMB/CIFS Digital Signatures
- 20. Development of afsmap.exe tool to provide AFS aware NET USE functionality
+ 19. Development of afsmap.exe tool to provide AFS aware NET USE functionality
afsmap.exe <drive> <afs-path> [/PERSISTENT]
afsmap.exe <drive> <unc-path> [/PERSISTENT]
afsmap.exe <drive> /DELETE
- 21. Write-through caching appears to be unsupported. Files copied to AFS
- do not end up in the local cache.
- 22. Missing SMB/CIFS functions:
+ 20. Missing SMB/CIFS functions:
Find
FindUnique
FindClose
WriteBulk
WriteBulkData
Tran2::SessionSetup
- 23. StoreBehind mode is not implemented. Or more correctly, all data is
+ 21. StoreBehind mode is not implemented. Or more correctly, all data is
written directly to the server and is not cached. Writes invalidate
the local cache entries which are then read back from the server.
- 24. The Power Management Flush Cache code does not work on Terminal
+ 22. The Power Management Flush Cache code does not work on Terminal
Server nor does it always successfully flush all of the dirty buffers
to the AFS servers before suspend/hibernate operations occur.
-
-
+ 23. Develop an optional Installable File System replacement for the SMB/CIFS
+ Server.
+ 24. Add support for storing Extended Attributes on files
+ 25. Add support for storing Windows ACLs on files
+ 26. Remove submount creation as a side effect of drive creation
Type : REG_SZ
Default : <none>
- This key is used to store newline terminated mount point strings
+ This key is used to store dot terminated mount point strings
for use in constructing the fake root.afs volume when Freelance
(dynamic roots) mode is activated.
- "athena.mit.edu#athena.mit.edu:root.cell.\n"
- ".athena.mit.edu%athena.mit.edu:root.cell.\n"
+ "athena.mit.edu#athena.mit.edu:root.cell."
+ ".athena.mit.edu%athena.mit.edu:root.cell."
These values used to be stored in afs_freelance.ini
+Regkey:
+[HKLM\SOFTWARE\OpenAFS\Client\Freelance\Symlinks]
+
+Value : "numeric value"
+Type : REG_SZ
+Default : <none>
+
+ This key is used to store a dot terminated symlink strings
+ for use in constructing the fake root.afs volume when Freelance
+ (dynamic roots) mode is activated.
+
+ "linkname:destination-path."
+ "athena:athena.mit.edu."
+ "home:athena.mit.edu\user\j\a\jaltman."
+ "filename:path\file."
+
+
Regkey:
[HKLM\SOFTWARE\OpenAFS\Client\Submounts]
$(DEL) $*.lib $*.exp
clean::
+ $(CD) lang
+ for /f %l in ('dir /B ??_??') do @$(NTLANG) %l $(MAKECMD) /nologo /f NTMakefile clean
+ $(CD) ..
############################################################################
AFSD_SDKLIBS =\
largeint.lib \
netapi32.lib \
- dnsapi.lib mpr.lib \
+ dnsapi.lib mpr.lib \
rpcrt4.lib \
user32.lib \
- Dbghelp.lib \
- strsafe.lib \
- mpr.lib \
- secur32.lib \
- ole32.lib \
- oleaut32.lib
+ Dbghelp.lib \
+ strsafe.lib \
+ mpr.lib \
+ secur32.lib \
+ ole32.lib \
+ oleaut32.lib
AFSD_EXELIBS =\
$(DESTDIR)\lib\libosi.lib \
$(DESTDIR)\lib\afsrpc.lib \
- $(DESTDIR)\lib\afsrx.lib \
+ $(DESTDIR)\lib\afsrx.lib \
$(DESTDIR)\lib\afsauthent.lib \
$(DESTDIR)\lib\afs\mtafsvldb.lib \
$(DESTDIR)\lib\afs\mtafsint.lib \
$(DESTDIR)\lib\libafsconf.lib \
$(DESTDIR)\lib\afs\afsreg.lib \
- $(LANAHELPERLIB)
+ $(LANAHELPERLIB)
$(AFSD_EXEFILE): $(OUT)\afsd.obj $(AFSDOBJS) $(OUT)\afsd.res $(RXOBJS) $(AFSD_EXELIBS)
$(EXEGUILINK) $(AFSD_SDKLIBS)
MessageBox(NULL, tbuffer, msgp, MB_OK|MB_ICONSTOP|MB_SETFOREGROUND);
afsd_ForceTrace(TRUE);
+ buf_ForceTrace(TRUE);
if (traceOnPanic) {
_asm int 3h;
/*MessageBox(NULL, tbuffer, msgp, MB_OK|MB_ICONSTOP|MB_SETFOREGROUND);*/
afsd_ForceTrace(TRUE);
+ buf_ForceTrace(TRUE);
if (traceOnPanic) {
/*asm("int 3");*/
#include "afsd.h"
#include <rx\rx.h>
#include <rx\rx_null.h>
-
#include <WINNT/syscfg.h>
#include "smb.h"
char * p, *q;
afsi_log("Sys name %s", buf);
- for (p = q = buf; p < cm_sysName + dummyLen; p++)
+ for (p = q = buf; p < buf + dummyLen; p++)
{
if (*p == '\0' || isspace(*p)) {
memcpy(cm_sysNameList[cm_sysNameCount],q,p-q);
osi_LogEnable(afsd_logp);
afsd_ForceTrace(TRUE);
+ buf_ForceTrace(TRUE);
afsi_log("--- begin dump ---");
cm_DumpSCache(afsi_file, "a");
RegCloseKey (parmKey);
if (code != ERROR_SUCCESS)
doTrace = 0;
- if (doTrace)
+ if (doTrace) {
afsd_ForceTrace(FALSE);
+ buf_ForceTrace(FALSE);
+ }
doneTrace:
ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
RegCloseKey (parmKey);
if (code != ERROR_SUCCESS)
doTrace = 0;
- if (doTrace)
+ if (doTrace) {
afsd_ForceTrace(FALSE);
+ buf_ForceTrace(FALSE);
+ }
doneTrace:
ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
#define USE_MS2MIT
-#define USE_KRB4
+#undef USE_KRB4
#include "afskfw-int.h"
#include "afskfw.h"
END_FUNC_INFO
};
+#ifdef USE_KRB4
FUNC_INFO k4_fi[] = {
MAKE_FUNC_INFO(krb_get_cred),
MAKE_FUNC_INFO(krb_get_tf_realm),
MAKE_FUNC_INFO(tkt_string),
END_FUNC_INFO
};
+#endif
FUNC_INFO k524_fi[] = {
MAKE_FUNC_INFO(krb524_init_ets),
if ( !inited ) {
inited = 1;
LoadFuncs(KRB5_DLL, k5_fi, &hKrb5, 0, 1, 0, 0);
+#ifdef USE_KRB4
LoadFuncs(KRB4_DLL, k4_fi, &hKrb4, 0, 1, 0, 0);
+#endif /* USE_KRB4 */
LoadFuncs(COMERR_DLL, ce_fi, &hComErr, 0, 0, 1, 0);
LoadFuncs(SERVICE_DLL, service_fi, &hService, 0, 1, 0, 0);
#ifdef USE_MS2MIT
len = sizeof(use524);
code = RegQueryValueEx(parmKey, "Use524", NULL, NULL,
(BYTE *) &use524, &len);
- if (code != ERROR_SUCCESS) {
- RegCloseKey(parmKey);
-
- code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, OpenAFSConfigKeyName,
- 0, KEY_QUERY_VALUE, &parmKey);
- if (code == ERROR_SUCCESS) {
- len = sizeof(use524);
- code = RegQueryValueEx(parmKey, "Use524", NULL, NULL,
- (BYTE *) &use524, &len);
- if (code != ERROR_SUCCESS)
- use524 = 0;
- }
+ RegCloseKey(parmKey);
+ }
+ if (code != ERROR_SUCCESS) {
+ code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, OpenAFSConfigKeyName,
+ 0, KEY_QUERY_VALUE, &parmKey);
+ if (code == ERROR_SUCCESS) {
+ len = sizeof(use524);
+ code = RegQueryValueEx(parmKey, "Use524", NULL, NULL,
+ (BYTE *) &use524, &len);
+ RegCloseKey (parmKey);
}
- RegCloseKey (parmKey);
}
return use524;
}
len = sizeof(enableKFW);
code = RegQueryValueEx(parmKey, "EnableKFW", NULL, NULL,
(BYTE *) &enableKFW, &len);
- if (code != ERROR_SUCCESS) {
- RegCloseKey(parmKey);
-
- code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, OpenAFSConfigKeyName,
- 0, KEY_QUERY_VALUE, &parmKey);
- if (code == ERROR_SUCCESS) {
- len = sizeof(enableKFW);
- code = RegQueryValueEx(parmKey, "EnableKFW", NULL, NULL,
- (BYTE *) &enableKFW, &len);
- if (code != ERROR_SUCCESS)
- enableKFW = 1;
- }
- }
RegCloseKey (parmKey);
}
+
+ if (code != ERROR_SUCCESS) {
+ code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, OpenAFSConfigKeyName,
+ 0, KEY_QUERY_VALUE, &parmKey);
+ if (code == ERROR_SUCCESS) {
+ len = sizeof(enableKFW);
+ code = RegQueryValueEx(parmKey, "EnableKFW", NULL, NULL,
+ (BYTE *) &enableKFW, &len);
+ RegCloseKey (parmKey);
+ }
+ }
+
if ( !enableKFW )
return FALSE;
}
}
#else
- goto cleanup;
+ if (!try_krb5)
+ goto cleanup;
#endif
strcpy(realm_of_cell, afs_realm_of_cell(ctx, &ak_cellconfig));
code = pkrb5_get_credentials(ctx, 0, cc, &increds, &k5creds);
if (code == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN ||
code == KRB5KRB_ERR_GENERIC /* heimdal */ ||
- code == KRB5KRB_AP_ERR_MSG_TYPE) {
+ code == KRB5KRB_AP_ERR_MSG_TYPE) {
/* Or service@REALM */
pkrb5_free_principal(ctx,increds.server);
increds.server = 0;
if ((code == KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN ||
code == KRB5KRB_ERR_GENERIC /* heimdal */ ||
- code == KRB5KRB_AP_ERR_MSG_TYPE) &&
+ code == KRB5KRB_AP_ERR_MSG_TYPE) &&
strcmp(RealmName, realm_of_cell)) {
/* Or service/cell@REALM_OF_CELL */
strcpy(RealmName, realm_of_cell);
if (ctx && (ctx != alt_ctx))
pkrb5_free_context(ctx);
- return(rc? rc : code);
+ return(rc? rc : code);
}
/**************************************/
#define CM_ERROR_BUFFERTOOSMALL (CM_ERROR_BASE+38)
#define CM_ERROR_RENAME_IDENTICAL (CM_ERROR_BASE+39)
#define CM_ERROR_ALLOFFLINE (CM_ERROR_BASE+40)
-#define CM_ERROR_AMBIGUOUS_FILENAME (CM_ERROR_BASE+41)
-#define CM_ERROR_BADLOGONTYPE (CM_ERROR_BASE+42)
-#define CM_ERROR_GSSCONTINUE (CM_ERROR_BASE+43)
-#define CM_ERROR_TIDIPC (CM_ERROR_BASE+44)
+#define CM_ERROR_AMBIGUOUS_FILENAME (CM_ERROR_BASE+41)
+#define CM_ERROR_BADLOGONTYPE (CM_ERROR_BASE+42)
+#define CM_ERROR_GSSCONTINUE (CM_ERROR_BASE+43)
+#define CM_ERROR_TIDIPC (CM_ERROR_BASE+44)
+#define CM_ERROR_TOO_MANY_SYMLINKS (CM_ERROR_BASE+45)
#endif /* __CM_H_ENV__ */
#include <malloc.h>
#include <stdio.h>
#include <assert.h>
+#include <strsafe.h>
#include "afsd.h"
+#ifdef DEBUG
+#define TRACE_BUFFER 1
+#endif
+
extern void afsi_log(char *pattern, ...);
/* This module implements the buffer package used by the local transaction
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
+ FreeCacheFileSA(psa);
if (hf == INVALID_HANDLE_VALUE) {
afsi_log("Error creating cache file \"%s\" error %d",
cm_CachePath, GetLastError());
return CM_ERROR_INVAL;
}
- FreeCacheFileSA(psa);
} else { /* buf_cacheType == CM_BUF_CACHETYPE_VIRTUAL */
hf = INVALID_HANDLE_VALUE;
}
/* just for safety's sake */
buf_maxReservedBufs = buf_nbuffers - 3;
+#ifdef TRACE_BUFFER
/* init the buffer trace log */
- buf_logp = osi_LogCreate("buffer", 10);
+ buf_logp = osi_LogCreate("buffer", 1000);
+ osi_LogEnable(buf_logp);
+#endif
osi_EndOnce(&once);
bp->flags |= CM_BUF_WAITING;
osi_SleepM((long) bp, &bp->mx);
lock_ObtainMutex(&bp->mx);
- osi_Log1(buf_logp, "buf_WaitIO conflict wait done for 0x%x", bp);
+ osi_Log1(buf_logp, "buf_WaitIO conflict wait done for 0x%x", bp);
}
/* if we get here, the IO is done, but we may have to wakeup people waiting for
return 0;
}
+void buf_ForceTrace(BOOL flush)
+{
+ HANDLE handle;
+ int len;
+ char buf[256];
+
+ if (!buf_logp)
+ return;
+
+ len = GetTempPath(sizeof(buf)-10, buf);
+ StringCbCopyA(&buf[len], sizeof(buf)-len, "/afs-buffer.log");
+ handle = CreateFile(buf, GENERIC_WRITE, FILE_SHARE_READ,
+ NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (handle == INVALID_HANDLE_VALUE) {
+ osi_panic("Cannot create log file", __FILE__, __LINE__);
+ }
+ osi_LogPrint(buf_logp, handle);
+ if (flush)
+ FlushFileBuffers(handle);
+ CloseHandle(handle);
+}
extern long buf_SetNBuffers(long nbuffers);
+extern void buf_ForceTrace(BOOL flush);
+
/* error codes */
#define CM_BUF_EXISTS 1 /* buffer exists, and shouldn't */
#define CM_ERROR_BASEBUF 0x33333333
long cm_ConnByMServers(cm_serverRef_t *serversp, cm_user_t *usersp,
cm_req_t *reqp, cm_conn_t **connpp)
{
- long code;
- cm_serverRef_t *tsrp;
+ long code;
+ cm_serverRef_t *tsrp;
cm_server_t *tsp;
long firstError = 0;
- int someBusy = 0, someOffline = 0, allBusy = 1, allDown = 1;
- long timeUsed, timeLeft, hardTimeLeft;
+ int someBusy = 0, someOffline = 0, allBusy = 1, allDown = 1;
+ long timeUsed, timeLeft, hardTimeLeft;
#ifdef DJGPP
struct timeval now;
#endif /* DJGPP */
*connpp = NULL;
#ifndef DJGPP
- timeUsed = (GetCurrentTime() - reqp->startTime) / 1000;
+ timeUsed = (GetCurrentTime() - reqp->startTime) / 1000;
#else
gettimeofday(&now, NULL);
timeUsed = sub_time(now, reqp->startTime) / 1000;
#endif
- /* leave 5 seconds margin of safety */
- timeLeft = ConnDeadtimeout - timeUsed - 5;
- hardTimeLeft = HardDeadtimeout - timeUsed - 5;
+ /* leave 5 seconds margin of safety */
+ timeLeft = ConnDeadtimeout - timeUsed - 5;
+ hardTimeLeft = HardDeadtimeout - timeUsed - 5;
- lock_ObtainWrite(&cm_serverLock);
+ lock_ObtainWrite(&cm_serverLock);
for (tsrp = serversp; tsrp; tsrp=tsrp->next) {
tsp = tsrp->server;
cm_GetServerNoLock(tsp);
else if (tsrp->status == offline)
someOffline = 1;
else {
- allBusy = 0;
+ allBusy = 0;
code = cm_ConnByServer(tsp, usersp, connpp);
if (code == 0) {
cm_PutServer(tsp);
if (firstError == 0)
firstError = code;
}
- }
+ }
lock_ObtainWrite(&cm_serverLock);
cm_PutServerNoLock(tsp);
}
- lock_ReleaseWrite(&cm_serverLock);
- if (firstError == 0) {
+ lock_ReleaseWrite(&cm_serverLock);
+ if (firstError == 0) {
if (serversp == NULL)
- firstError = CM_ERROR_NOSUCHVOLUME;
+ firstError = CM_ERROR_NOSUCHVOLUME;
else if (allDown)
- firstError = CM_ERROR_ALLOFFLINE;
- else if (allBusy)
- firstError = CM_ERROR_ALLBUSY;
- else
- firstError = CM_ERROR_TIMEDOUT;
- }
+ firstError = CM_ERROR_ALLOFFLINE;
+ else if (allBusy)
+ firstError = CM_ERROR_ALLBUSY;
+ else
+ firstError = CM_ERROR_TIMEDOUT;
+ }
- osi_Log1(afsd_logp, "cm_ConnByMServers returning %x", firstError);
+ osi_Log1(afsd_logp, "cm_ConnByMServers returning %x", firstError);
return firstError;
}
}
}
}
+
+void cm_FreelanceSymlinkChangeNotifier(void * parmp) {
+ HANDLE hFreelanceSymlinkChangeEvent = 0;
+ HKEY hkFreelance = 0;
+
+ if (RegOpenKeyEx( HKEY_LOCAL_MACHINE,
+ "SOFTWARE\\OpenAFS\\Client\\Freelance\\Symlinks",
+ 0,
+ KEY_NOTIFY,
+ &hkFreelance) == ERROR_SUCCESS) {
+
+ hFreelanceSymlinkChangeEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (hFreelanceSymlinkChangeEvent == NULL) {
+ RegCloseKey(hkFreelance);
+ return;
+ }
+ }
+
+ while ( TRUE ) {
+ /* check hFreelanceSymlinkChangeEvent to see if it is set.
+ * if so, call cm_noteLocalMountPointSymlinkChange()
+ */
+ if (RegNotifyChangeKeyValue( hkFreelance, /* hKey */
+ FALSE, /* bWatchSubtree */
+ REG_NOTIFY_CHANGE_LAST_SET, /* dwNotifyFilter */
+ hFreelanceSymlinkChangeEvent, /* hEvent */
+ TRUE /* fAsynchronous */
+ ) != ERROR_SUCCESS) {
+ RegCloseKey(hkFreelance);
+ CloseHandle(hFreelanceSymlinkChangeEvent);
+ return;
+ }
+
+ if (WaitForSingleObject(hFreelanceSymlinkChangeEvent, INFINITE) == WAIT_OBJECT_0)
+ {
+ cm_noteLocalMountPointChange();
+ }
+ }
+}
#endif
void cm_InitFreelance() {
NULL, 0, &lpid, "cm_FreelanceChangeNotifier");
osi_assert(phandle != NULL);
thrd_CloseHandle(phandle);
+
+ phandle = thrd_Create(NULL, 65536, (ThreadFunc) cm_FreelanceSymlinkChangeNotifier,
+ NULL, 0, &lpid, "cm_FreelanceSymlinkChangeNotifier");
+ osi_assert(phandle != NULL);
+ thrd_CloseHandle(phandle);
#endif
}
/* yj: Initialization of the fake root directory */
/* to be called while holding freelance lock unless during init. */
void cm_InitFakeRootDir() {
-
int i, t1, t2;
char* currentPos;
int noChunks;
long code;
char rootCellName[256];
#if !defined(DJGPP)
- HKEY hkFreelance = 0;
+ HKEY hkFreelance = 0, hkFreelanceSymlinks = 0;
DWORD dwType, dwSize;
- DWORD dwMountPoints;
+ DWORD dwMountPoints = 0;
DWORD dwIndex;
+ DWORD dwSymlinks = 0;
FILETIME ftLastWriteTime;
- afs_uint32 unixTime;
#endif
#if !defined(DJGPP)
dwMountPoints = 2;
}
+ if (RegCreateKeyEx( HKEY_LOCAL_MACHINE,
+ "SOFTWARE\\OpenAFS\\Client\\Freelance\\Symlinks",
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
+ NULL,
+ &hkFreelanceSymlinks,
+ NULL) == ERROR_SUCCESS) {
+
+ RegQueryInfoKey( hkFreelanceSymlinks,
+ NULL, /* lpClass */
+ NULL, /* lpcClass */
+ NULL, /* lpReserved */
+ NULL, /* lpcSubKeys */
+ NULL, /* lpcMaxSubKeyLen */
+ NULL, /* lpcMaxClassLen */
+ &dwSymlinks, /* lpcValues */
+ NULL, /* lpcMaxValueNameLen */
+ NULL, /* lpcMaxValueLen */
+ NULL, /* lpcbSecurityDescriptor */
+ NULL /* lpftLastWriteTime */
+ );
+ }
+
// get the number of entries there are from the first line
// that we read
- cm_noLocalMountPoints = dwMountPoints;
+ cm_noLocalMountPoints = dwMountPoints + dwSymlinks;
// create space to store the local mount points
cm_localMountPoints = malloc(sizeof(cm_localMountPoint_t) * cm_noLocalMountPoints);
cm_noLocalMountPoints--;
continue;
}
+
+ aLocalMountPoint->fileType = CM_SCACHETYPE_MOUNTPOINT;
aLocalMountPoint->namep=malloc(t-line+1);
strncpy(aLocalMountPoint->namep, line, t-line);
aLocalMountPoint->namep[t-line] = '\0';
- /* copy the mount point string without the trailing dot */
+ /* copy the mount point string */
aLocalMountPoint->mountPointStringp=malloc(strlen(t));
- strncpy(aLocalMountPoint->mountPointStringp, t, strlen(t)-1);
- aLocalMountPoint->mountPointStringp[strlen(t)-1] = '\0';
+ strncpy(aLocalMountPoint->mountPointStringp, t, strlen(t)-1);
+ aLocalMountPoint->mountPointStringp[strlen(t)-1] = '\0';
osi_Log2(afsd_logp,"found mount point: name %s, string %s",
osi_LogSaveString(afsd_logp,aLocalMountPoint->namep),
aLocalMountPoint++;
}
+ for ( dwIndex = 0 ; dwIndex < dwSymlinks; dwIndex++ ) {
+ TCHAR szValueName[16];
+ DWORD dwValueSize = 16;
+ dwSize = sizeof(line);
+ RegEnumValue( hkFreelanceSymlinks, dwIndex, szValueName, &dwValueSize, NULL,
+ &dwType, line, &dwSize);
+
+ /* find the trailing dot; null terminate after it */
+ t2 = strrchr(line, '.');
+ if (t2)
+ *(t2+1) = '\0';
+
+ // line is not empty, so let's parse it
+ t = strchr(line, ':');
+
+ // make sure that there is a ':' separator in the line
+ if (!t) {
+ afsi_log("error occurred while parsing symlink entry: no ':' separator in line %d", dwIndex);
+ fprintf(stderr, "error occurred while parsing symlink entry: no ':' separator in line %d", dwIndex);
+ cm_noLocalMountPoints--;
+ continue;
+ }
+
+ aLocalMountPoint->fileType = CM_SCACHETYPE_SYMLINK;
+ aLocalMountPoint->namep=malloc(t-line+1);
+ strncpy(aLocalMountPoint->namep, line, t-line);
+ aLocalMountPoint->namep[t-line] = '\0';
+
+ /* copy the symlink string */
+ aLocalMountPoint->mountPointStringp=malloc(strlen(t)-1);
+ strncpy(aLocalMountPoint->mountPointStringp, t+1, strlen(t)-2);
+ aLocalMountPoint->mountPointStringp[strlen(t)-2] = '\0';
+
+ osi_Log2(afsd_logp,"found symlink: name %s, string %s",
+ osi_LogSaveString(afsd_logp,aLocalMountPoint->namep),
+ osi_LogSaveString(afsd_logp,aLocalMountPoint->mountPointStringp));
+
+ aLocalMountPoint++;
+ }
+
+ if ( hkFreelanceSymlinks )
+ RegCloseKey( hkFreelanceSymlinks );
RegCloseKey(hkFreelance);
return 0;
}
return cm_noLocalMountPoints;
}
-cm_localMountPoint_t* cm_getLocalMountPoint(int vnode) {
- return 0;
-}
-
long cm_FreelanceAddMount(char *filename, char *cellname, char *volume, int rw, cm_fid_t *fidp)
{
FILE *fp;
);
if (rw)
- sprintf(line, "%s%%%s:%s\n", filename, fullname, volume);
+ sprintf(line, "%s%%%s:%s", filename, fullname, volume);
else
- sprintf(line, "%s#%s:%s\n", filename, fullname, volume);
+ sprintf(line, "%s#%s:%s", filename, fullname, volume);
/* If we are adding a new value, there must be an unused name
* within the range 0 to dwMountPoints
*/
for ( dwIndex = 0; dwIndex <= dwMountPoints; dwIndex++ ) {
char szIndex[16];
+ char szMount[1024];
+
+ dwSize = sizeof(szMount);
sprintf(szIndex, "%d", dwIndex);
- if (RegQueryValueEx( hkFreelance, szIndex, 0, &dwType, NULL, &dwSize) != ERROR_SUCCESS) {
+ if (RegQueryValueEx( hkFreelance, szIndex, 0, &dwType, szMount, &dwSize) != ERROR_SUCCESS) {
/* found an unused value */
dwType = REG_SZ;
dwSize = strlen(line) + 1;
RegSetValueEx( hkFreelance, szIndex, 0, dwType, line, dwSize);
break;
+ } else {
+ int len = strlen(filename);
+ if ( dwType == REG_SZ && !strncmp(filename, szMount, len) &&
+ (szMount[len] == '%' || szMount[len] == '#')) {
+ /* Replace the existing value */
+ dwType = REG_SZ;
+ dwSize = strlen(line) + 1;
+ RegSetValueEx( hkFreelance, szIndex, 0, dwType, line, dwSize);
+ break;
+ }
}
}
RegCloseKey(hkFreelance);
return 0;
}
+long cm_FreelanceAddSymlink(char *filename, char *destination, cm_fid_t *fidp)
+{
+ FILE *fp;
+ char hfile[120];
+ char line[512];
+ char fullname[200];
+ int n;
+ int alias = 0;
+#if !defined(DJGPP)
+ HKEY hkFreelanceSymlinks = 0;
+ DWORD dwType, dwSize;
+ DWORD dwSymlinks;
+ DWORD dwIndex;
+#endif
+
+ /* before adding, verify the cell name; if it is not a valid cell,
+ don't add the mount point.
+ allow partial matches as a means of poor man's alias. */
+ /* major performance issue? */
+ osi_Log2(afsd_logp,"Freelance Add Symlink request: filename=%s destination=%s",
+ osi_LogSaveString(afsd_logp,filename),
+ osi_LogSaveString(afsd_logp,destination));
+
+ lock_ObtainMutex(&cm_Freelance_Lock);
+
+#if !defined(DJGPP)
+ if (RegCreateKeyEx( HKEY_LOCAL_MACHINE,
+ "SOFTWARE\\OpenAFS\\Client\\Freelance\\Symlinks",
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
+ NULL,
+ &hkFreelanceSymlinks,
+ NULL) == ERROR_SUCCESS) {
+
+ RegQueryInfoKey( hkFreelanceSymlinks,
+ NULL, /* lpClass */
+ NULL, /* lpcClass */
+ NULL, /* lpReserved */
+ NULL, /* lpcSubKeys */
+ NULL, /* lpcMaxSubKeyLen */
+ NULL, /* lpcMaxClassLen */
+ &dwSymlinks, /* lpcValues */
+ NULL, /* lpcMaxValueNameLen */
+ NULL, /* lpcMaxValueLen */
+ NULL, /* lpcbSecurityDescriptor */
+ NULL /* lpftLastWriteTime */
+ );
+
+ sprintf(line, "%s:%s.", filename, destination);
+
+ /* If we are adding a new value, there must be an unused name
+ * within the range 0 to dwSymlinks
+ */
+ for ( dwIndex = 0; dwIndex <= dwSymlinks; dwIndex++ ) {
+ char szIndex[16];
+ char szLink[1024];
+
+ dwSize = sizeof(szLink);
+ sprintf(szIndex, "%d", dwIndex);
+ if (RegQueryValueEx( hkFreelanceSymlinks, szIndex, 0, &dwType, szLink, &dwSize) != ERROR_SUCCESS) {
+ /* found an unused value */
+ dwType = REG_SZ;
+ dwSize = strlen(line) + 1;
+ RegSetValueEx( hkFreelanceSymlinks, szIndex, 0, dwType, line, dwSize);
+ break;
+ } else {
+ int len = strlen(filename);
+ if ( dwType == REG_SZ && !strncmp(filename, szLink, len) && szLink[len] == ':') {
+ /* Replace the existing value */
+ dwType = REG_SZ;
+ dwSize = strlen(line) + 1;
+ RegSetValueEx( hkFreelanceSymlinks, szIndex, 0, dwType, line, dwSize);
+ break;
+ }
+ }
+ }
+ RegCloseKey(hkFreelanceSymlinks);
+ }
+#endif
+ lock_ReleaseMutex(&cm_Freelance_Lock);
+
+ /* cm_reInitLocalMountPoints(); */
+ if (fidp) {
+ fidp->unique = 1;
+ fidp->vnode = cm_noLocalMountPoints + 1; /* vnode value of last mt pt */
+ }
+ cm_noteLocalMountPointChange();
+ return 0;
+}
+
+long cm_FreelanceRemoveSymlink(char *toremove)
+{
+ int i, n;
+ char* cp;
+ char line[512];
+ char shortname[200];
+ char hfile[120], hfile2[120];
+ FILE *fp1, *fp2;
+ int found=0;
+#if !defined(DJGPP)
+ HKEY hkFreelanceSymlinks = 0;
+ DWORD dwType, dwSize;
+ DWORD dwSymlinks;
+ DWORD dwIndex;
+#endif
+
+ lock_ObtainMutex(&cm_Freelance_Lock);
+
+
+#if !defined(DJGPP)
+ if (RegOpenKeyEx( HKEY_LOCAL_MACHINE,
+ "SOFTWARE\\OpenAFS\\Client\\Freelance\\Symlinks",
+ 0,
+ KEY_READ|KEY_WRITE|KEY_QUERY_VALUE,
+ &hkFreelanceSymlinks) == ERROR_SUCCESS) {
+
+ RegQueryInfoKey( hkFreelanceSymlinks,
+ NULL, /* lpClass */
+ NULL, /* lpcClass */
+ NULL, /* lpReserved */
+ NULL, /* lpcSubKeys */
+ NULL, /* lpcMaxSubKeyLen */
+ NULL, /* lpcMaxClassLen */
+ &dwSymlinks, /* lpcValues */
+ NULL, /* lpcMaxValueNameLen */
+ NULL, /* lpcMaxValueLen */
+ NULL, /* lpcbSecurityDescriptor */
+ NULL /* lpftLastWriteTime */
+ );
+
+ for ( dwIndex = 0; dwIndex < dwSymlinks; dwIndex++ ) {
+ TCHAR szValueName[16];
+ DWORD dwValueSize = 16;
+ dwSize = sizeof(line);
+ RegEnumValue( hkFreelanceSymlinks, dwIndex, szValueName, &dwValueSize, NULL,
+ &dwType, line, &dwSize);
+
+ cp=strchr(line, ':');
+ memcpy(shortname, line, cp-line);
+ shortname[cp-line]=0;
+
+ if (!strcmp(shortname, toremove)) {
+ RegDeleteValue( hkFreelanceSymlinks, szValueName );
+ break;
+ }
+ }
+ RegCloseKey(hkFreelanceSymlinks);
+ }
+#endif
+
+ lock_ReleaseMutex(&cm_Freelance_Lock);
+ cm_noteLocalMountPointChange();
+ return 0;
+}
#endif /* AFS_FREELANCE_CLIENT */
typedef struct cm_localMountPoint {
- char* namep;
- char* mountPointStringp;
- struct cm_localMountPoint* next;
+ char* namep;
+ char* mountPointStringp;
+ unsigned int fileType;
+ struct cm_localMountPoint* next;
} cm_localMountPoint_t;
extern int cm_getNoLocalMountPoints();
extern long cm_InitLocalMountPoints();
extern int cm_getLocalMountPointChange();
extern int cm_reInitLocalMountPoints();
-extern cm_localMountPoint_t* cm_getLocalMountPoint(int vnode);
extern void cm_InitFreelance();
extern long cm_FreelanceRemoveMount(char *toremove);
extern long cm_FreelanceAddMount(char *filename, char *cellname, char *volume, int rw, cm_fid_t *fidp);
+extern long cm_FreelanceRemoveSymlink(char *toremove);
+extern long cm_FreelanceAddSymlink(char *filename, char *destination, cm_fid_t *fidp);
extern int cm_clearLocalMountPointChange();
extern int cm_FakeRootFid(cm_fid_t *fidp);
code = cm_ParseIoctlPath(ioctlp, userp, &req, &scp);
if (code) return code;
- cellp = cm_FindCellByID(scp->fid.cell);
- if (cellp) {
- strcpy(ioctlp->outDatap, cellp->namep);
+#ifdef AFS_FREELANCE_CLIENT
+ if ( cm_freelanceEnabled &&
+ scp->fid.cell==AFS_FAKE_ROOT_CELL_ID &&
+ scp->fid.volume==AFS_FAKE_ROOT_VOL_ID &&
+ scp->fid.vnode==0x1 && scp->fid.unique==0x1 ) {
+ strcpy(ioctlp->outDatap, "Freelance.Local.Root");
ioctlp->outDatap += strlen(ioctlp->outDatap) + 1;
code = 0;
+ } else
+#endif /* AFS_FREELANCE_CLIENT */
+ {
+ cellp = cm_FindCellByID(scp->fid.cell);
+ if (cellp) {
+ strcpy(ioctlp->outDatap, cellp->namep);
+ ioctlp->outDatap += strlen(ioctlp->outDatap) + 1;
+ code = 0;
+ }
+ else
+ code = CM_ERROR_NOSUCHCELL;
}
- else code = CM_ERROR_NOSUCHCELL;
cm_ReleaseSCache(scp);
return code;
/* print trace */
if (inValue & 8) {
afsd_ForceTrace(FALSE);
+ buf_ForceTrace(FALSE);
}
if (inValue & 2) {
* do lookups of @sys entries and thinks it can trust them */
/* privs ok, store the entry, ... */
strcpy(cm_sysName, inname);
+ strcpy(cm_sysNameList[0], inname);
if (setSysName > 1) { /* ... or list */
cp = ioctlp->inDatap;
for (count = 1; count < setSysName; ++count) {
osi_panic("cm_IoctlSysName: no cm_sysNameList entry to write\n",
__FILE__, __LINE__);
t = strlen(cp);
- memcpy(cm_sysNameList[count], cp, t + 1); /* include null */
+ strcpy(cm_sysNameList[count], cp);
cp += t + 1;
}
}
cp = ioctlp->inDatap; /* contents of link */
+#ifdef AFS_FREELANCE_CLIENT
+ if (cm_freelanceEnabled && dscp == cm_rootSCachep) {
+ /* we are adding the symlink to the root dir., so call
+ * the freelance code to do the add. */
+ if (cp[0] == cp[1] && cp[1] == '\\' &&
+ !_strnicmp(cm_NetbiosName,cp+2,strlen(cm_NetbiosName)))
+ {
+ /* skip \\AFS\ or \\AFS\all\ */
+ char * p;
+ p = cp + 2 + strlen(cm_NetbiosName) + 1;
+ if ( !_strnicmp("all", p, 3) )
+ p += 4;
+ cp = p;
+ }
+ osi_Log0(afsd_logp,"IoctlCreateSymlink within Freelance root dir");
+ code = cm_FreelanceAddSymlink(leaf, cp, NULL);
+ return code;
+ }
+#endif
+
/* Create symlink with mode 0755. */
tattr.mask = CM_ATTRMASK_UNIXMODEBITS;
tattr.unixModeBits = 0755;
cp = ioctlp->inDatap;
+#ifdef AFS_FREELANCE_CLIENT
+ if (cm_freelanceEnabled && dscp == cm_rootSCachep) {
+ /* we are adding the mount point to the root dir., so call
+ * the freelance code to do the add. */
+ osi_Log0(afsd_logp,"IoctlDeletelink from Freelance root dir");
+ code = cm_FreelanceRemoveSymlink(cp);
+ return code;
+ }
+#endif
+
code = cm_Lookup(dscp, cp, CM_FLAG_NOMOUNTCHASE, userp, &req, &scp);
/* if something went wrong, bail out now */
/* must be called with cm_scacheLock write-locked! */
void cm_AdjustLRU(cm_scache_t *scp)
{
- if (scp == cm_scacheLRULastp)
- cm_scacheLRULastp = (cm_scache_t *) osi_QPrev(&scp->q);
- osi_QRemove((osi_queue_t **) &cm_scacheLRUFirstp, &scp->q);
- osi_QAdd((osi_queue_t **) &cm_scacheLRUFirstp, &scp->q);
+ if (scp == cm_scacheLRULastp)
+ cm_scacheLRULastp = (cm_scache_t *) osi_QPrev(&scp->q);
+ osi_QRemove((osi_queue_t **) &cm_scacheLRUFirstp, &scp->q);
+ osi_QAdd((osi_queue_t **) &cm_scacheLRUFirstp, &scp->q);
if (!cm_scacheLRULastp)
cm_scacheLRULastp = scp;
}
*/
cm_scache_t *cm_GetNewSCache(void)
{
- cm_scache_t *scp;
- int i;
- cm_scache_t **lscpp;
- cm_scache_t *tscp;
-
- if (cm_currentSCaches >= cm_maxSCaches) {
- for (scp = cm_scacheLRULastp;
- scp;
- scp = (cm_scache_t *) osi_QPrev(&scp->q)) {
+ cm_scache_t *scp;
+ int i;
+ cm_scache_t **lscpp;
+ cm_scache_t *tscp;
+
+ if (cm_currentSCaches >= cm_maxSCaches) {
+ for (scp = cm_scacheLRULastp;
+ scp;
+ scp = (cm_scache_t *) osi_QPrev(&scp->q)) {
if (scp->refCount == 0)
break;
- }
+ }
- if (scp) {
- /* we found an entry, so return it */
- if (scp->flags & CM_SCACHEFLAG_INHASH) {
- /* hash it out first */
- i = CM_SCACHE_HASH(&scp->fid);
- lscpp = &cm_hashTablep[i];
- for (tscp = *lscpp;
- tscp;
- lscpp = &tscp->nextp, tscp = *lscpp) {
+ if (scp) {
+ /* we found an entry, so return it */
+ if (scp->flags & CM_SCACHEFLAG_INHASH) {
+ /* hash it out first */
+ i = CM_SCACHE_HASH(&scp->fid);
+ lscpp = &cm_hashTablep[i];
+ for (tscp = *lscpp;
+ tscp;
+ lscpp = &tscp->nextp, tscp = *lscpp) {
if (tscp == scp)
break;
- }
- osi_assertx(tscp, "afsd: scache hash screwup");
- *lscpp = scp->nextp;
- scp->flags &= ~CM_SCACHEFLAG_INHASH;
- }
-
- /* look for things that shouldn't still be set */
- osi_assert(scp->bufWritesp == NULL);
- osi_assert(scp->bufReadsp == NULL);
-
- /* invalidate so next merge works fine;
- * also initialize some flags */
- scp->flags &= ~(CM_SCACHEFLAG_STATD
- | CM_SCACHEFLAG_RO
- | CM_SCACHEFLAG_PURERO
- | CM_SCACHEFLAG_OVERQUOTA
- | CM_SCACHEFLAG_OUTOFSPACE);
- scp->serverModTime = 0;
- scp->dataVersion = 0;
- scp->bulkStatProgress = hzero;
-
- /* discard callback */
+ }
+ osi_assertx(tscp, "afsd: scache hash screwup");
+ *lscpp = scp->nextp;
+ scp->flags &= ~CM_SCACHEFLAG_INHASH;
+ }
+
+ /* look for things that shouldn't still be set */
+ osi_assert(scp->bufWritesp == NULL);
+ osi_assert(scp->bufReadsp == NULL);
+
+ /* invalidate so next merge works fine;
+ * also initialize some flags */
+ scp->flags &= ~(CM_SCACHEFLAG_STATD
+ | CM_SCACHEFLAG_RO
+ | CM_SCACHEFLAG_PURERO
+ | CM_SCACHEFLAG_OVERQUOTA
+ | CM_SCACHEFLAG_OUTOFSPACE);
+ scp->serverModTime = 0;
+ scp->dataVersion = 0;
+ scp->bulkStatProgress = hzero;
+
+ /* discard callback */
if (scp->cbServerp) {
cm_PutServer(scp->cbServerp);
- scp->cbServerp = NULL;
+ scp->cbServerp = NULL;
}
- scp->cbExpires = 0;
-
- /* remove from dnlc */
- cm_dnlcPurgedp(scp);
- cm_dnlcPurgevp(scp);
-
- /* discard cached status; if non-zero, Close
- * tried to store this to server but failed */
- scp->mask = 0;
-
- /* drop held volume ref */
- if (scp->volp) {
- cm_PutVolume(scp->volp);
- scp->volp = NULL;
- }
-
- /* discard symlink info */
- if (scp->mountPointStringp) {
- free(scp->mountPointStringp);
- scp->mountPointStringp = NULL;
- }
- if (scp->mountRootFidp) {
- free(scp->mountRootFidp);
- scp->mountRootFidp = NULL;
- }
- if (scp->dotdotFidp) {
- free(scp->dotdotFidp);
- scp->dotdotFidp = NULL;
- }
-
- /* not locked, but there can be no references to this guy
- * while we hold the global refcount lock.
- */
- cm_FreeAllACLEnts(scp);
-
- /* now remove from the LRU queue and put it back at the
- * head of the LRU queue.
- */
- cm_AdjustLRU(scp);
-
- /* and we're done */
- return scp;
- }
- }
+ scp->cbExpires = 0;
+
+ /* remove from dnlc */
+ cm_dnlcPurgedp(scp);
+ cm_dnlcPurgevp(scp);
+
+ /* discard cached status; if non-zero, Close
+ * tried to store this to server but failed */
+ scp->mask = 0;
+
+ /* drop held volume ref */
+ if (scp->volp) {
+ cm_PutVolume(scp->volp);
+ scp->volp = NULL;
+ }
+
+ /* discard symlink info */
+ if (scp->mountPointStringp) {
+ free(scp->mountPointStringp);
+ scp->mountPointStringp = NULL;
+ }
+ if (scp->mountRootFidp) {
+ free(scp->mountRootFidp);
+ scp->mountRootFidp = NULL;
+ }
+ if (scp->dotdotFidp) {
+ free(scp->dotdotFidp);
+ scp->dotdotFidp = NULL;
+ }
+
+ /* not locked, but there can be no references to this guy
+ * while we hold the global refcount lock.
+ */
+ cm_FreeAllACLEnts(scp);
+
+ /* now remove from the LRU queue and put it back at the
+ * head of the LRU queue.
+ */
+ cm_AdjustLRU(scp);
+
+ /* and we're done */
+ return scp;
+ }
+ }
- /* if we get here, we should allocate a new scache entry. We either are below
- * quota or we have a leak and need to allocate a new one to avoid panicing.
- */
- scp = malloc(sizeof(*scp));
- memset(scp, 0, sizeof(*scp));
- lock_InitializeMutex(&scp->mx, "cm_scache_t mutex");
- lock_InitializeRWLock(&scp->bufCreateLock, "cm_scache_t bufCreateLock");
-
- /* and put it in the LRU queue */
- osi_QAdd((osi_queue_t **) &cm_scacheLRUFirstp, &scp->q);
+ /* if we get here, we should allocate a new scache entry. We either are below
+ * quota or we have a leak and need to allocate a new one to avoid panicing.
+ */
+ scp = malloc(sizeof(*scp));
+ memset(scp, 0, sizeof(*scp));
+ lock_InitializeMutex(&scp->mx, "cm_scache_t mutex");
+ lock_InitializeRWLock(&scp->bufCreateLock, "cm_scache_t bufCreateLock");
+
+ /* and put it in the LRU queue */
+ osi_QAdd((osi_queue_t **) &cm_scacheLRUFirstp, &scp->q);
if (!cm_scacheLRULastp)
cm_scacheLRULastp = scp;
- cm_currentSCaches++;
- cm_dnlcPurgedp(scp); /* make doubly sure that this is not in dnlc */
- cm_dnlcPurgevp(scp);
- return scp;
-}
+ cm_currentSCaches++;
+ cm_dnlcPurgedp(scp); /* make doubly sure that this is not in dnlc */
+ cm_dnlcPurgevp(scp);
+ return scp;
+}
/* like strcmp, only for fids */
int cm_FidCmp(cm_fid_t *ap, cm_fid_t *bp)
return 1;
if (ap->cell != bp->cell)
return 1;
- return 0;
+ return 0;
}
void cm_fakeSCacheInit()
{
- memset(&cm_fakeSCache, 0, sizeof(cm_fakeSCache));
- lock_InitializeMutex(&cm_fakeSCache.mx, "cm_scache_t mutex");
- cm_fakeSCache.cbServerp = (struct cm_server *)(-1);
- /* can leave clientModTime at 0 */
- cm_fakeSCache.fileType = CM_SCACHETYPE_FILE;
- cm_fakeSCache.unixModeBits = 0777;
- cm_fakeSCache.length.LowPart = 1000;
- cm_fakeSCache.linkCount = 1;
-}
+ memset(&cm_fakeSCache, 0, sizeof(cm_fakeSCache));
+ lock_InitializeMutex(&cm_fakeSCache.mx, "cm_scache_t mutex");
+ cm_fakeSCache.cbServerp = (struct cm_server *)(-1);
+ /* can leave clientModTime at 0 */
+ cm_fakeSCache.fileType = CM_SCACHETYPE_FILE;
+ cm_fakeSCache.unixModeBits = 0777;
+ cm_fakeSCache.length.LowPart = 1000;
+ cm_fakeSCache.linkCount = 1;
+}
void cm_InitSCache(long maxSCaches)
{
- static osi_once_t once;
+ static osi_once_t once;
- if (osi_Once(&once)) {
- lock_InitializeRWLock(&cm_scacheLock, "cm_scacheLock");
- cm_hashTableSize = maxSCaches / 2;
- cm_hashTablep = malloc(sizeof(cm_scache_t *) * cm_hashTableSize);
- memset(cm_hashTablep, 0, sizeof(cm_scache_t *) * cm_hashTableSize);
- cm_allFileLocks = NULL;
- cm_currentSCaches = 0;
- cm_maxSCaches = maxSCaches;
- cm_fakeSCacheInit();
- cm_dnlcInit();
- osi_EndOnce(&once);
- }
+ if (osi_Once(&once)) {
+ lock_InitializeRWLock(&cm_scacheLock, "cm_scacheLock");
+ cm_hashTableSize = maxSCaches / 2;
+ cm_hashTablep = malloc(sizeof(cm_scache_t *) * cm_hashTableSize);
+ memset(cm_hashTablep, 0, sizeof(cm_scache_t *) * cm_hashTableSize);
+ cm_allFileLocks = NULL;
+ cm_currentSCaches = 0;
+ cm_maxSCaches = maxSCaches;
+ cm_fakeSCacheInit();
+ cm_dnlcInit();
+ osi_EndOnce(&once);
+ }
}
/* version that doesn't bother creating the entry if we don't find it */
cm_scache_t *cm_FindSCache(cm_fid_t *fidp)
{
- long hash;
- cm_scache_t *scp;
-
- hash = CM_SCACHE_HASH(fidp);
+ long hash;
+ cm_scache_t *scp;
+
+ hash = CM_SCACHE_HASH(fidp);
- osi_assert(fidp->cell != 0);
+ osi_assert(fidp->cell != 0);
- lock_ObtainWrite(&cm_scacheLock);
- for(scp=cm_hashTablep[hash]; scp; scp=scp->nextp) {
- if (cm_FidCmp(fidp, &scp->fid) == 0) {
- scp->refCount++;
- cm_AdjustLRU(scp);
- lock_ReleaseWrite(&cm_scacheLock);
- return scp;
- }
+ lock_ObtainWrite(&cm_scacheLock);
+ for(scp=cm_hashTablep[hash]; scp; scp=scp->nextp) {
+ if (cm_FidCmp(fidp, &scp->fid) == 0) {
+ scp->refCount++;
+ cm_AdjustLRU(scp);
+ lock_ReleaseWrite(&cm_scacheLock);
+ return scp;
}
- lock_ReleaseWrite(&cm_scacheLock);
- return NULL;
+ }
+ lock_ReleaseWrite(&cm_scacheLock);
+ return NULL;
}
long cm_GetSCache(cm_fid_t *fidp, cm_scache_t **outScpp, cm_user_t *userp,
- cm_req_t *reqp)
+ cm_req_t *reqp)
{
- long hash;
+ long hash;
cm_scache_t *scp;
long code;
cm_volume_t *volp = 0;
cm_cell_t *cellp;
char* mp = 0;
- int special; // yj: boolean variable to test if file is on root.afs
- int isRoot;
+ int special; // yj: boolean variable to test if file is on root.afs
+ int isRoot;
extern cm_fid_t cm_rootFid;
hash = CM_SCACHE_HASH(fidp);
- osi_assert(fidp->cell != 0);
+ osi_assert(fidp->cell != 0);
if (fidp->cell== cm_rootFid.cell &&
fidp->volume==cm_rootFid.volume &&
osi_Log0(afsd_logp,"cm_getSCache called with root cell/volume and vnode=0 and unique=0");
}
- // yj: check if we have the scp, if so, we don't need
- // to do anything else
+ // yj: check if we have the scp, if so, we don't need
+ // to do anything else
lock_ObtainWrite(&cm_scacheLock);
- for(scp=cm_hashTablep[hash]; scp; scp=scp->nextp) {
- if (cm_FidCmp(fidp, &scp->fid) == 0) {
- scp->refCount++;
+ for(scp=cm_hashTablep[hash]; scp; scp=scp->nextp) {
+ if (cm_FidCmp(fidp, &scp->fid) == 0) {
+ scp->refCount++;
*outScpp = scp;
cm_AdjustLRU(scp);
lock_ReleaseWrite(&cm_scacheLock);
- return 0;
+ return 0;
}
}
- // yj: when we get here, it means we don't have an scp
- // so we need to either load it or fake it, depending
- // on whether the file is "special", see below.
-
- // yj: if we're trying to get an scp for a file that's
- // on root.afs of homecell, we want to handle it specially
- // because we have to fill in the status stuff 'coz we
- // don't want trybulkstat to fill it in for us
+ // yj: when we get here, it means we don't have an scp
+ // so we need to either load it or fake it, depending
+ // on whether the file is "special", see below.
+
+ // yj: if we're trying to get an scp for a file that's
+ // on root.afs of homecell, we want to handle it specially
+ // because we have to fill in the status stuff 'coz we
+ // don't want trybulkstat to fill it in for us
#ifdef AFS_FREELANCE_CLIENT
- special = (fidp->cell==AFS_FAKE_ROOT_CELL_ID &&
+ special = (fidp->cell==AFS_FAKE_ROOT_CELL_ID &&
fidp->volume==AFS_FAKE_ROOT_VOL_ID &&
- !(fidp->vnode==0x1 && fidp->unique==0x1));
- isRoot = (fidp->cell==AFS_FAKE_ROOT_CELL_ID &&
+ !(fidp->vnode==0x1 && fidp->unique==0x1));
+ isRoot = (fidp->cell==AFS_FAKE_ROOT_CELL_ID &&
fidp->volume==AFS_FAKE_ROOT_VOL_ID &&
- fidp->vnode==0x1 && fidp->unique==0x1);
- if (cm_freelanceEnabled && isRoot) {
- osi_Log0(afsd_logp,"cm_getSCache Freelance and isRoot");
- /* freelance: if we are trying to get the root scp for the first
+ fidp->vnode==0x1 && fidp->unique==0x1);
+ if (cm_freelanceEnabled && isRoot) {
+ osi_Log0(afsd_logp,"cm_getSCache Freelance and isRoot");
+ /* freelance: if we are trying to get the root scp for the first
* time, we will just put in a place holder entry.
*/
- volp = NULL;
- }
+ volp = NULL;
+ }
- if (cm_freelanceEnabled && special) {
- osi_Log0(afsd_logp,"cm_getSCache Freelance and special");
+ if (cm_freelanceEnabled && special) {
+ osi_Log0(afsd_logp,"cm_getSCache Freelance and special");
if (fidp->vnode > 1) {
lock_ObtainMutex(&cm_Freelance_Lock);
- mp =(cm_localMountPoints+fidp->vnode-2)->mountPointStringp;
- lock_ReleaseMutex(&cm_Freelance_Lock);
+ mp =(cm_localMountPoints+fidp->vnode-2)->mountPointStringp;
+ lock_ReleaseMutex(&cm_Freelance_Lock);
} else {
mp = "";
}
- scp = cm_GetNewSCache();
+ scp = cm_GetNewSCache();
- scp->fid = *fidp;
- scp->volp = cm_rootSCachep->volp;
- if (scp->dotdotFidp == (cm_fid_t *) NULL)
- scp->dotdotFidp = (cm_fid_t *) malloc (sizeof(cm_fid_t));
- scp->dotdotFidp->cell=AFS_FAKE_ROOT_CELL_ID;
- scp->dotdotFidp->volume=AFS_FAKE_ROOT_VOL_ID;
- scp->dotdotFidp->unique=1;
- scp->dotdotFidp->vnode=1;
- scp->flags |= (CM_SCACHEFLAG_PURERO | CM_SCACHEFLAG_RO);
- scp->nextp=cm_hashTablep[hash];
- cm_hashTablep[hash]=scp;
- scp->flags |= CM_SCACHEFLAG_INHASH;
- scp->refCount = 1;
- scp->fileType = CM_SCACHETYPE_MOUNTPOINT;
-
- lock_ObtainMutex(&cm_Freelance_Lock);
- scp->length.LowPart = strlen(mp)+4;
- scp->mountPointStringp=malloc(strlen(mp)+1);
- strcpy(scp->mountPointStringp,mp);
- lock_ReleaseMutex(&cm_Freelance_Lock);
-
- scp->owner=0x0;
- scp->unixModeBits=0x1ff;
- scp->clientModTime=FakeFreelanceModTime;
- scp->serverModTime=FakeFreelanceModTime;
- scp->parentUnique = 0x1;
- scp->parentVnode=0x1;
- scp->group=0;
- scp->dataVersion=0x8;
- *outScpp = scp;
- lock_ReleaseWrite(&cm_scacheLock);
- /*afsi_log(" getscache done");*/
- return 0;
- }
- // end of yj code
+ scp->fid = *fidp;
+ scp->volp = cm_rootSCachep->volp;
+ if (scp->dotdotFidp == (cm_fid_t *) NULL)
+ scp->dotdotFidp = (cm_fid_t *) malloc (sizeof(cm_fid_t));
+ scp->dotdotFidp->cell=AFS_FAKE_ROOT_CELL_ID;
+ scp->dotdotFidp->volume=AFS_FAKE_ROOT_VOL_ID;
+ scp->dotdotFidp->unique=1;
+ scp->dotdotFidp->vnode=1;
+ scp->flags |= (CM_SCACHEFLAG_PURERO | CM_SCACHEFLAG_RO);
+ scp->nextp=cm_hashTablep[hash];
+ cm_hashTablep[hash]=scp;
+ scp->flags |= CM_SCACHEFLAG_INHASH;
+ scp->refCount = 1;
+ scp->fileType = (cm_localMountPoints+fidp->vnode-2)->fileType;
+
+ lock_ObtainMutex(&cm_Freelance_Lock);
+ scp->length.LowPart = strlen(mp)+4;
+ scp->mountPointStringp=malloc(strlen(mp)+1);
+ strcpy(scp->mountPointStringp,mp);
+ lock_ReleaseMutex(&cm_Freelance_Lock);
+
+ scp->owner=0x0;
+ scp->unixModeBits=0x1ff;
+ scp->clientModTime=FakeFreelanceModTime;
+ scp->serverModTime=FakeFreelanceModTime;
+ scp->parentUnique = 0x1;
+ scp->parentVnode=0x1;
+ scp->group=0;
+ scp->dataVersion=0x8;
+ *outScpp = scp;
+ lock_ReleaseWrite(&cm_scacheLock);
+ /*afsi_log(" getscache done");*/
+ return 0;
+ }
+ // end of yj code
#endif /* AFS_FREELANCE_CLIENT */
/* otherwise, we need to find the volume */
- if (!cm_freelanceEnabled || !isRoot) {
+ if (!cm_freelanceEnabled || !isRoot) {
lock_ReleaseWrite(&cm_scacheLock); /* for perf. reasons */
cellp = cm_FindCellByID(fidp->cell);
if (!cellp)
if (code)
return code;
lock_ObtainWrite(&cm_scacheLock);
- }
+ }
- /* otherwise, we have the volume, now reverify that the scp doesn't
- * exist, and proceed.
- */
- for(scp=cm_hashTablep[hash]; scp; scp=scp->nextp) {
- if (cm_FidCmp(fidp, &scp->fid) == 0) {
- scp->refCount++;
+ /* otherwise, we have the volume, now reverify that the scp doesn't
+ * exist, and proceed.
+ */
+ for(scp=cm_hashTablep[hash]; scp; scp=scp->nextp) {
+ if (cm_FidCmp(fidp, &scp->fid) == 0) {
+ scp->refCount++;
cm_AdjustLRU(scp);
lock_ReleaseWrite(&cm_scacheLock);
if (volp)
- cm_PutVolume(volp);
+ cm_PutVolume(volp);
*outScpp = scp;
- return 0;
+ return 0;
}
}
/* now, if we don't have the fid, recycle something */
- scp = cm_GetNewSCache();
- osi_assert(!(scp->flags & CM_SCACHEFLAG_INHASH));
- scp->fid = *fidp;
- scp->volp = volp; /* a held reference */
-
- if (!cm_freelanceEnabled || !isRoot) {
- /* if this scache entry represents a volume root then we need
- * to copy the dotdotFipd from the volume structure where the
- * "master" copy is stored (defect 11489)
- */
- if(scp->fid.vnode == 1 && scp->fid.unique == 1 && volp->dotdotFidp) {
+ scp = cm_GetNewSCache();
+ osi_assert(!(scp->flags & CM_SCACHEFLAG_INHASH));
+ scp->fid = *fidp;
+ scp->volp = volp; /* a held reference */
+
+ if (!cm_freelanceEnabled || !isRoot) {
+ /* if this scache entry represents a volume root then we need
+ * to copy the dotdotFipd from the volume structure where the
+ * "master" copy is stored (defect 11489)
+ */
+ if (scp->fid.vnode == 1 && scp->fid.unique == 1 && volp->dotdotFidp) {
if (scp->dotdotFidp == (cm_fid_t *) NULL)
- scp->dotdotFidp = (cm_fid_t *) malloc(sizeof(cm_fid_t));
+ scp->dotdotFidp = (cm_fid_t *) malloc(sizeof(cm_fid_t));
*(scp->dotdotFidp) = *volp->dotdotFidp;
- }
+ }
- if (volp->roID == fidp->volume)
+ if (volp->roID == fidp->volume)
scp->flags |= (CM_SCACHEFLAG_PURERO | CM_SCACHEFLAG_RO);
- else if (volp->bkID == fidp->volume)
+ else if (volp->bkID == fidp->volume)
scp->flags |= CM_SCACHEFLAG_RO;
- }
- scp->nextp = cm_hashTablep[hash];
- cm_hashTablep[hash] = scp;
+ }
+ scp->nextp = cm_hashTablep[hash];
+ cm_hashTablep[hash] = scp;
scp->flags |= CM_SCACHEFLAG_INHASH;
- scp->refCount = 1;
-
- /* XXX - The following fields in the cm_scache are
- * uninitialized:
- * fileType
- * parentVnode
- * parentUnique
- */
+ scp->refCount = 1;
+
+ /* XXX - The following fields in the cm_scache are
+ * uninitialized:
+ * fileType
+ * parentVnode
+ * parentUnique
+ */
lock_ReleaseWrite(&cm_scacheLock);
/* now we have a held scache entry; just return it */
* CM_SCACHESYNC_STOREDATA_EXCL and CM_SCACHEFLAG_DATASTORING.
*/
long cm_SyncOp(cm_scache_t *scp, cm_buf_t *bufp, cm_user_t *up, cm_req_t *reqp,
- long rights, long flags)
+ long rights, long flags)
{
- osi_queueData_t *qdp;
- long code;
- cm_buf_t *tbufp;
- long outRights;
- int bufLocked;
-
- /* lookup this first */
- bufLocked = flags & CM_SCACHESYNC_BUFLOCKED;
-
- /* some minor assertions */
- if (flags & (CM_SCACHESYNC_STOREDATA | CM_SCACHESYNC_FETCHDATA
- | CM_SCACHESYNC_READ | CM_SCACHESYNC_WRITE
- | CM_SCACHESYNC_SETSIZE)) {
- if (bufp) {
- osi_assert(bufp->refCount > 0);
- /*
- osi_assert(cm_FidCmp(&bufp->fid, &scp->fid) == 0);
- */
- }
- }
- else osi_assert(bufp == NULL);
-
- /* Do the access check. Now we don't really do the access check
- * atomically, since the caller doesn't expect the parent dir to be
- * returned locked, and that is what we'd have to do to prevent a
- * callback breaking message on the parent due to a setacl call from
- * being processed while we're running. So, instead, we check things
- * here, and if things look fine with the access, we proceed to finish
- * the rest of this check. Sort of a hack, but probably good enough.
- */
+ osi_queueData_t *qdp;
+ long code;
+ cm_buf_t *tbufp;
+ long outRights;
+ int bufLocked;
+
+ /* lookup this first */
+ bufLocked = flags & CM_SCACHESYNC_BUFLOCKED;
+
+ /* some minor assertions */
+ if (flags & (CM_SCACHESYNC_STOREDATA | CM_SCACHESYNC_FETCHDATA
+ | CM_SCACHESYNC_READ | CM_SCACHESYNC_WRITE
+ | CM_SCACHESYNC_SETSIZE)) {
+ if (bufp) {
+ osi_assert(bufp->refCount > 0);
+ /*
+ osi_assert(cm_FidCmp(&bufp->fid, &scp->fid) == 0);
+ */
+ }
+ }
+ else osi_assert(bufp == NULL);
+
+ /* Do the access check. Now we don't really do the access check
+ * atomically, since the caller doesn't expect the parent dir to be
+ * returned locked, and that is what we'd have to do to prevent a
+ * callback breaking message on the parent due to a setacl call from
+ * being processed while we're running. So, instead, we check things
+ * here, and if things look fine with the access, we proceed to finish
+ * the rest of this check. Sort of a hack, but probably good enough.
+ */
+
+ while (1) {
+ if (flags & CM_SCACHESYNC_FETCHSTATUS) {
+ /* if we're bringing in a new status block, ensure that
+ * we aren't already doing so, and that no one is
+ * changing the status concurrently, either. We need
+ * to do this, even if the status is of a different
+ * type, since we don't have the ability to figure out,
+ * in the AFS 3 protocols, which status-changing
+ * operation ran first, or even which order a read and
+ * a write occurred in.
+ */
+ if (scp->flags & (CM_SCACHEFLAG_FETCHING | CM_SCACHEFLAG_STORING
+ | CM_SCACHEFLAG_SIZESTORING | CM_SCACHEFLAG_GETCALLBACK))
+ goto sleep;
+ }
+ if (flags & (CM_SCACHESYNC_STORESIZE | CM_SCACHESYNC_STORESTATUS
+ | CM_SCACHESYNC_SETSIZE | CM_SCACHESYNC_GETCALLBACK)) {
+ /* if we're going to make an RPC to change the status, make sure
+ * that no one is bringing in or sending out the status.
+ */
+ if (scp->flags & (CM_SCACHEFLAG_FETCHING | CM_SCACHEFLAG_STORING
+ | CM_SCACHEFLAG_SIZESTORING | CM_SCACHEFLAG_GETCALLBACK))
+ goto sleep;
+ if (scp->bufReadsp || scp->bufWritesp) goto sleep;
+ }
+ if (flags & CM_SCACHESYNC_FETCHDATA) {
+ /* if we're bringing in a new chunk of data, make sure that
+ * nothing is happening to that chunk, and that we aren't
+ * changing the basic file status info, either.
+ */
+ if (scp->flags & (CM_SCACHEFLAG_FETCHING | CM_SCACHEFLAG_STORING
+ | CM_SCACHEFLAG_SIZESTORING | CM_SCACHEFLAG_GETCALLBACK))
+ goto sleep;
+ if (bufp && (bufp->cmFlags & (CM_BUF_CMFETCHING | CM_BUF_CMSTORING)))
+ goto sleep;
+ }
+ if (flags & CM_SCACHESYNC_STOREDATA) {
+ /* same as fetch data */
+ if (scp->flags & (CM_SCACHEFLAG_FETCHING | CM_SCACHEFLAG_STORING
+ | CM_SCACHEFLAG_SIZESTORING | CM_SCACHEFLAG_GETCALLBACK))
+ goto sleep;
+ if (bufp && (bufp->cmFlags & (CM_BUF_CMFETCHING | CM_BUF_CMSTORING)))
+ goto sleep;
+ }
- while (1) {
- if (flags & CM_SCACHESYNC_FETCHSTATUS) {
- /* if we're bringing in a new status block, ensure that
- * we aren't already doing so, and that no one is
- * changing the status concurrently, either. We need
- * to do this, even if the status is of a different
- * type, since we don't have the ability to figure out,
- * in the AFS 3 protocols, which status-changing
- * operation ran first, or even which order a read and
- * a write occurred in.
- */
- if (scp->flags & (CM_SCACHEFLAG_FETCHING | CM_SCACHEFLAG_STORING
- | CM_SCACHEFLAG_SIZESTORING | CM_SCACHEFLAG_GETCALLBACK))
- goto sleep;
- }
- if (flags & (CM_SCACHESYNC_STORESIZE | CM_SCACHESYNC_STORESTATUS
- | CM_SCACHESYNC_SETSIZE | CM_SCACHESYNC_GETCALLBACK)) {
- /* if we're going to make an RPC to change the status, make sure
- * that no one is bringing in or sending out the status.
- */
- if (scp->flags & (CM_SCACHEFLAG_FETCHING | CM_SCACHEFLAG_STORING
- | CM_SCACHEFLAG_SIZESTORING | CM_SCACHEFLAG_GETCALLBACK))
- goto sleep;
- if (scp->bufReadsp || scp->bufWritesp) goto sleep;
- }
- if (flags & CM_SCACHESYNC_FETCHDATA) {
- /* if we're bringing in a new chunk of data, make sure that
- * nothing is happening to that chunk, and that we aren't
- * changing the basic file status info, either.
- */
- if (scp->flags & (CM_SCACHEFLAG_FETCHING | CM_SCACHEFLAG_STORING
- | CM_SCACHEFLAG_SIZESTORING | CM_SCACHEFLAG_GETCALLBACK))
- goto sleep;
- if (bufp && (bufp->cmFlags & (CM_BUF_CMFETCHING | CM_BUF_CMSTORING)))
- goto sleep;
- }
- if (flags & CM_SCACHESYNC_STOREDATA) {
- /* same as fetch data */
- if (scp->flags & (CM_SCACHEFLAG_FETCHING | CM_SCACHEFLAG_STORING
- | CM_SCACHEFLAG_SIZESTORING | CM_SCACHEFLAG_GETCALLBACK))
- goto sleep;
- if (bufp && (bufp->cmFlags & (CM_BUF_CMFETCHING | CM_BUF_CMSTORING)))
- goto sleep;
- }
+ if (flags & CM_SCACHESYNC_STOREDATA_EXCL) {
+ /* Don't allow concurrent StoreData RPC's */
+ if (scp->flags & CM_SCACHEFLAG_DATASTORING)
+ goto sleep;
+ }
- if (flags & CM_SCACHESYNC_STOREDATA_EXCL) {
- /* Don't allow concurrent StoreData RPC's */
- if (scp->flags & CM_SCACHEFLAG_DATASTORING)
- goto sleep;
- }
-
- if (flags & CM_SCACHESYNC_ASYNCSTORE) {
- /* Don't allow more than one BKG store request */
- if (scp->flags & CM_SCACHEFLAG_ASYNCSTORING)
- goto sleep;
- }
-
- if (flags & CM_SCACHESYNC_LOCK) {
- /* Don't allow concurrent fiddling with lock lists */
- if (scp->flags & CM_SCACHEFLAG_LOCKING)
- goto sleep;
- }
-
- /* now the operations that don't correspond to making RPCs */
- if (flags & CM_SCACHESYNC_GETSTATUS) {
- /* we can use the status that's here, if we're not
- * bringing in new status.
- */
- if (scp->flags & (CM_SCACHEFLAG_FETCHING))
- goto sleep;
- }
- if (flags & CM_SCACHESYNC_SETSTATUS) {
- /* we can make a change to the local status, as long as
- * the status isn't changing now.
- *
- * If we're fetching or storing a chunk of data, we can
- * change the status locally, since the fetch/store
- * operations don't change any of the data that we're
- * changing here.
- */
- if (scp->flags & (CM_SCACHEFLAG_FETCHING | CM_SCACHEFLAG_STORING
- | CM_SCACHEFLAG_SIZESTORING))
- goto sleep;
- }
- if (flags & CM_SCACHESYNC_READ) {
- /* we're going to read the data, make sure that the
- * status is available, and that the data is here. It
- * is OK to read while storing the data back.
- */
- if (scp->flags & CM_SCACHEFLAG_FETCHING)
- goto sleep;
- if (bufp && ((bufp->cmFlags
- & (CM_BUF_CMFETCHING
- | CM_BUF_CMFULLYFETCHED))
- == CM_BUF_CMFETCHING))
- goto sleep;
- }
- if (flags & CM_SCACHESYNC_WRITE) {
- /* don't write unless the status is stable and the chunk
- * is stable.
- */
- if (scp->flags & (CM_SCACHEFLAG_FETCHING | CM_SCACHEFLAG_STORING
- | CM_SCACHEFLAG_SIZESTORING))
- goto sleep;
- if (bufp && (bufp->cmFlags & (CM_BUF_CMFETCHING | CM_BUF_CMSTORING)))
- goto sleep;
- }
+ if (flags & CM_SCACHESYNC_ASYNCSTORE) {
+ /* Don't allow more than one BKG store request */
+ if (scp->flags & CM_SCACHEFLAG_ASYNCSTORING)
+ goto sleep;
+ }
+
+ if (flags & CM_SCACHESYNC_LOCK) {
+ /* Don't allow concurrent fiddling with lock lists */
+ if (scp->flags & CM_SCACHEFLAG_LOCKING)
+ goto sleep;
+ }
- // yj: modified this so that callback only checked if we're
- // not checking something on /afs
+ /* now the operations that don't correspond to making RPCs */
+ if (flags & CM_SCACHESYNC_GETSTATUS) {
+ /* we can use the status that's here, if we're not
+ * bringing in new status.
+ */
+ if (scp->flags & (CM_SCACHEFLAG_FETCHING))
+ goto sleep;
+ }
+ if (flags & CM_SCACHESYNC_SETSTATUS) {
+ /* we can make a change to the local status, as long as
+ * the status isn't changing now.
+ *
+ * If we're fetching or storing a chunk of data, we can
+ * change the status locally, since the fetch/store
+ * operations don't change any of the data that we're
+ * changing here.
+ */
+ if (scp->flags & (CM_SCACHEFLAG_FETCHING | CM_SCACHEFLAG_STORING
+ | CM_SCACHEFLAG_SIZESTORING))
+ goto sleep;
+ }
+ if (flags & CM_SCACHESYNC_READ) {
+ /* we're going to read the data, make sure that the
+ * status is available, and that the data is here. It
+ * is OK to read while storing the data back.
+ */
+ if (scp->flags & CM_SCACHEFLAG_FETCHING)
+ goto sleep;
+ if (bufp && ((bufp->cmFlags
+ & (CM_BUF_CMFETCHING
+ | CM_BUF_CMFULLYFETCHED))
+ == CM_BUF_CMFETCHING))
+ goto sleep;
+ }
+ if (flags & CM_SCACHESYNC_WRITE) {
+ /* don't write unless the status is stable and the chunk
+ * is stable.
+ */
+ if (scp->flags & (CM_SCACHEFLAG_FETCHING | CM_SCACHEFLAG_STORING
+ | CM_SCACHEFLAG_SIZESTORING))
+ goto sleep;
+ if (bufp && (bufp->cmFlags & (CM_BUF_CMFETCHING | CM_BUF_CMSTORING)))
+ goto sleep;
+ }
+
+ // yj: modified this so that callback only checked if we're
+ // not checking something on /afs
/* fix the conditional to match the one in cm_HaveCallback */
- if ( (flags & CM_SCACHESYNC_NEEDCALLBACK)
+ if ( (flags & CM_SCACHESYNC_NEEDCALLBACK)
#ifdef AFS_FREELANCE_CLIENT
&& (!cm_freelanceEnabled ||
!(scp->fid.vnode==0x1 && scp->fid.unique==0x1) ||
scp->fid.cell!=AFS_FAKE_ROOT_CELL_ID ||
scp->fid.volume!=AFS_FAKE_ROOT_VOL_ID ||
- cm_fakeDirCallback < 2)
+ cm_fakeDirCallback < 2)
#endif /* AFS_FREELANCE_CLIENT */
- ) {
- if (!cm_HaveCallback(scp)) {
- osi_Log1(afsd_logp, "CM SyncOp getting callback on scp %x",
- (long) scp);
- if (bufLocked) lock_ReleaseMutex(&bufp->mx);
- code = cm_GetCallback(scp, up, reqp, 0);
- if (bufLocked) {
- lock_ReleaseMutex(&scp->mx);
- lock_ObtainMutex(&bufp->mx);
- lock_ObtainMutex(&scp->mx);
- }
- if (code) return code;
- continue;
- }
+ ) {
+ if (!cm_HaveCallback(scp)) {
+ osi_Log1(afsd_logp, "CM SyncOp getting callback on scp %x",
+ (long) scp);
+ if (bufLocked) lock_ReleaseMutex(&bufp->mx);
+ code = cm_GetCallback(scp, up, reqp, 0);
+ if (bufLocked) {
+ lock_ReleaseMutex(&scp->mx);
+ lock_ObtainMutex(&bufp->mx);
+ lock_ObtainMutex(&scp->mx);
}
-
- if (rights) {
- /* can't check access rights without a callback */
- osi_assert(flags & CM_SCACHESYNC_NEEDCALLBACK);
-
- if ((rights & PRSFS_WRITE) && (scp->flags & CM_SCACHEFLAG_RO))
- return CM_ERROR_READONLY;
-
- if (cm_HaveAccessRights(scp, up, rights, &outRights)) {
- if (~outRights & rights) return CM_ERROR_NOACCESS;
- }
- else {
- /* we don't know the required access rights */
- if (bufLocked) lock_ReleaseMutex(&bufp->mx);
- code = cm_GetAccessRights(scp, up, reqp);
- if (code) return code;
- if (bufLocked) {
- lock_ReleaseMutex(&scp->mx);
- lock_ObtainMutex(&bufp->mx);
- lock_ObtainMutex(&scp->mx);
- }
- continue;
- }
+ if (code) return code;
+ continue;
+ }
+ }
+
+ if (rights) {
+ /* can't check access rights without a callback */
+ osi_assert(flags & CM_SCACHESYNC_NEEDCALLBACK);
+
+ if ((rights & PRSFS_WRITE) && (scp->flags & CM_SCACHEFLAG_RO))
+ return CM_ERROR_READONLY;
+
+ if (cm_HaveAccessRights(scp, up, rights, &outRights)) {
+ if (~outRights & rights) return CM_ERROR_NOACCESS;
+ }
+ else {
+ /* we don't know the required access rights */
+ if (bufLocked) lock_ReleaseMutex(&bufp->mx);
+ code = cm_GetAccessRights(scp, up, reqp);
+ if (code) return code;
+ if (bufLocked) {
+ lock_ReleaseMutex(&scp->mx);
+ lock_ObtainMutex(&bufp->mx);
+ lock_ObtainMutex(&scp->mx);
}
+ continue;
+ }
+ }
- /* if we get here, we're happy */
- break;
+ /* if we get here, we're happy */
+ break;
-sleep:
- /* first check if we're not supposed to wait: fail
- * in this case, returning with everything still locked.
- */
- if (flags & CM_SCACHESYNC_NOWAIT) return CM_ERROR_WOULDBLOCK;
+ sleep:
+ /* first check if we're not supposed to wait: fail
+ * in this case, returning with everything still locked.
+ */
+ if (flags & CM_SCACHESYNC_NOWAIT) return CM_ERROR_WOULDBLOCK;
- /* wait here, then try again */
- osi_Log1(afsd_logp, "CM SyncOp sleeping scp %x", (long) scp);
+ /* wait here, then try again */
+ osi_Log1(afsd_logp, "CM SyncOp sleeping scp %x", (long) scp);
if ( scp->flags & CM_SCACHEFLAG_WAITING )
osi_Log1(afsd_logp, "CM SyncOp CM_SCACHEFLAG_WAITING already set for 0x%x", scp);
else
osi_Log1(afsd_logp, "CM SyncOp CM_SCACHEFLAG_WAITING set for 0x%x", scp);
- scp->flags |= CM_SCACHEFLAG_WAITING;
- if (bufLocked) lock_ReleaseMutex(&bufp->mx);
+ scp->flags |= CM_SCACHEFLAG_WAITING;
+ if (bufLocked) lock_ReleaseMutex(&bufp->mx);
osi_SleepM((long) &scp->flags, &scp->mx);
osi_Log0(afsd_logp, "CM SyncOp woke!");
if (bufLocked)
lock_ObtainMutex(&bufp->mx);
lock_ObtainMutex(&scp->mx);
- } /* big while loop */
+ } /* big while loop */
- /* now, update the recorded state for RPC-type calls */
- if (flags & CM_SCACHESYNC_FETCHSTATUS)
- scp->flags |= CM_SCACHEFLAG_FETCHING;
- if (flags & CM_SCACHESYNC_STORESTATUS)
- scp->flags |= CM_SCACHEFLAG_STORING;
- if (flags & CM_SCACHESYNC_STORESIZE)
- scp->flags |= CM_SCACHEFLAG_SIZESTORING;
- if (flags & CM_SCACHESYNC_GETCALLBACK)
- scp->flags |= CM_SCACHEFLAG_GETCALLBACK;
- if (flags & CM_SCACHESYNC_STOREDATA_EXCL)
- scp->flags |= CM_SCACHEFLAG_DATASTORING;
- if (flags & CM_SCACHESYNC_ASYNCSTORE)
- scp->flags |= CM_SCACHEFLAG_ASYNCSTORING;
- if (flags & CM_SCACHESYNC_LOCK)
- scp->flags |= CM_SCACHEFLAG_LOCKING;
-
- /* now update the buffer pointer */
- if (flags & CM_SCACHESYNC_FETCHDATA) {
- /* ensure that the buffer isn't already in the I/O list */
- if (bufp) {
- for(qdp = scp->bufReadsp; qdp; qdp = (osi_queueData_t *) osi_QNext(&qdp->q)) {
- tbufp = osi_GetQData(qdp);
- osi_assert(tbufp != bufp);
- }
- }
-
- /* queue a held reference to the buffer in the "reading" I/O list */
- qdp = osi_QDAlloc();
- osi_SetQData(qdp, bufp);
- if (bufp) {
- buf_Hold(bufp);
- bufp->cmFlags |= CM_BUF_CMFETCHING;
- }
- osi_QAdd((osi_queue_t **) &scp->bufReadsp, &qdp->q);
+ /* now, update the recorded state for RPC-type calls */
+ if (flags & CM_SCACHESYNC_FETCHSTATUS)
+ scp->flags |= CM_SCACHEFLAG_FETCHING;
+ if (flags & CM_SCACHESYNC_STORESTATUS)
+ scp->flags |= CM_SCACHEFLAG_STORING;
+ if (flags & CM_SCACHESYNC_STORESIZE)
+ scp->flags |= CM_SCACHEFLAG_SIZESTORING;
+ if (flags & CM_SCACHESYNC_GETCALLBACK)
+ scp->flags |= CM_SCACHEFLAG_GETCALLBACK;
+ if (flags & CM_SCACHESYNC_STOREDATA_EXCL)
+ scp->flags |= CM_SCACHEFLAG_DATASTORING;
+ if (flags & CM_SCACHESYNC_ASYNCSTORE)
+ scp->flags |= CM_SCACHEFLAG_ASYNCSTORING;
+ if (flags & CM_SCACHESYNC_LOCK)
+ scp->flags |= CM_SCACHEFLAG_LOCKING;
+
+ /* now update the buffer pointer */
+ if (flags & CM_SCACHESYNC_FETCHDATA) {
+ /* ensure that the buffer isn't already in the I/O list */
+ if (bufp) {
+ for(qdp = scp->bufReadsp; qdp; qdp = (osi_queueData_t *) osi_QNext(&qdp->q)) {
+ tbufp = osi_GetQData(qdp);
+ osi_assert(tbufp != bufp);
+ }
}
- if (flags & CM_SCACHESYNC_STOREDATA) {
- /* ensure that the buffer isn't already in the I/O list */
- if (bufp) {
- for(qdp = scp->bufWritesp; qdp; qdp = (osi_queueData_t *) osi_QNext(&qdp->q)) {
- tbufp = osi_GetQData(qdp);
- osi_assert(tbufp != bufp);
- }
- }
-
- /* queue a held reference to the buffer in the "writing" I/O list */
- qdp = osi_QDAlloc();
- osi_SetQData(qdp, bufp);
- if (bufp) {
- buf_Hold(bufp);
- bufp->cmFlags |= CM_BUF_CMSTORING;
- }
- osi_QAdd((osi_queue_t **) &scp->bufWritesp, &qdp->q);
+ /* queue a held reference to the buffer in the "reading" I/O list */
+ qdp = osi_QDAlloc();
+ osi_SetQData(qdp, bufp);
+ if (bufp) {
+ buf_Hold(bufp);
+ bufp->cmFlags |= CM_BUF_CMFETCHING;
}
-
- return 0;
+ osi_QAdd((osi_queue_t **) &scp->bufReadsp, &qdp->q);
+ }
+
+ if (flags & CM_SCACHESYNC_STOREDATA) {
+ /* ensure that the buffer isn't already in the I/O list */
+ if (bufp) {
+ for(qdp = scp->bufWritesp; qdp; qdp = (osi_queueData_t *) osi_QNext(&qdp->q)) {
+ tbufp = osi_GetQData(qdp);
+ osi_assert(tbufp != bufp);
+ }
+ }
+
+ /* queue a held reference to the buffer in the "writing" I/O list */
+ qdp = osi_QDAlloc();
+ osi_SetQData(qdp, bufp);
+ if (bufp) {
+ buf_Hold(bufp);
+ bufp->cmFlags |= CM_BUF_CMSTORING;
+ }
+ osi_QAdd((osi_queue_t **) &scp->bufWritesp, &qdp->q);
+ }
+
+ return 0;
}
/* for those syncops that setup for RPCs.
*/
void cm_SyncOpDone(cm_scache_t *scp, cm_buf_t *bufp, long flags)
{
- osi_queueData_t *qdp;
- cm_buf_t *tbufp;
-
- /* now, update the recorded state for RPC-type calls */
- if (flags & CM_SCACHESYNC_FETCHSTATUS)
- scp->flags &= ~CM_SCACHEFLAG_FETCHING;
- if (flags & CM_SCACHESYNC_STORESTATUS)
- scp->flags &= ~CM_SCACHEFLAG_STORING;
- if (flags & CM_SCACHESYNC_STORESIZE)
- scp->flags &= ~CM_SCACHEFLAG_SIZESTORING;
- if (flags & CM_SCACHESYNC_GETCALLBACK)
- scp->flags &= ~CM_SCACHEFLAG_GETCALLBACK;
- if (flags & CM_SCACHESYNC_STOREDATA_EXCL)
- scp->flags &= ~CM_SCACHEFLAG_DATASTORING;
- if (flags & CM_SCACHESYNC_ASYNCSTORE)
- scp->flags &= ~CM_SCACHEFLAG_ASYNCSTORING;
- if (flags & CM_SCACHESYNC_LOCK)
- scp->flags &= ~CM_SCACHEFLAG_LOCKING;
-
- /* now update the buffer pointer */
- if (flags & CM_SCACHESYNC_FETCHDATA) {
- /* ensure that the buffer isn't already in the I/O list */
- for(qdp = scp->bufReadsp; qdp; qdp = (osi_queueData_t *) osi_QNext(&qdp->q)) {
- tbufp = osi_GetQData(qdp);
- if (tbufp == bufp) break;
- }
- osi_assert(qdp != NULL);
- osi_assert(osi_GetQData(qdp) == bufp);
- osi_QRemove((osi_queue_t **) &scp->bufReadsp, &qdp->q);
- osi_QDFree(qdp);
- if (bufp) {
- bufp->cmFlags &=
- ~(CM_BUF_CMFETCHING | CM_BUF_CMFULLYFETCHED);
- buf_Release(bufp);
- }
+ osi_queueData_t *qdp;
+ cm_buf_t *tbufp;
+
+ /* now, update the recorded state for RPC-type calls */
+ if (flags & CM_SCACHESYNC_FETCHSTATUS)
+ scp->flags &= ~CM_SCACHEFLAG_FETCHING;
+ if (flags & CM_SCACHESYNC_STORESTATUS)
+ scp->flags &= ~CM_SCACHEFLAG_STORING;
+ if (flags & CM_SCACHESYNC_STORESIZE)
+ scp->flags &= ~CM_SCACHEFLAG_SIZESTORING;
+ if (flags & CM_SCACHESYNC_GETCALLBACK)
+ scp->flags &= ~CM_SCACHEFLAG_GETCALLBACK;
+ if (flags & CM_SCACHESYNC_STOREDATA_EXCL)
+ scp->flags &= ~CM_SCACHEFLAG_DATASTORING;
+ if (flags & CM_SCACHESYNC_ASYNCSTORE)
+ scp->flags &= ~CM_SCACHEFLAG_ASYNCSTORING;
+ if (flags & CM_SCACHESYNC_LOCK)
+ scp->flags &= ~CM_SCACHEFLAG_LOCKING;
+
+ /* now update the buffer pointer */
+ if (flags & CM_SCACHESYNC_FETCHDATA) {
+ /* ensure that the buffer isn't already in the I/O list */
+ for(qdp = scp->bufReadsp; qdp; qdp = (osi_queueData_t *) osi_QNext(&qdp->q)) {
+ tbufp = osi_GetQData(qdp);
+ if (tbufp == bufp) break;
+ }
+ osi_assert(qdp != NULL);
+ osi_assert(osi_GetQData(qdp) == bufp);
+ osi_QRemove((osi_queue_t **) &scp->bufReadsp, &qdp->q);
+ osi_QDFree(qdp);
+ if (bufp) {
+ bufp->cmFlags &=
+ ~(CM_BUF_CMFETCHING | CM_BUF_CMFULLYFETCHED);
+ buf_Release(bufp);
}
+ }
- /* now update the buffer pointer */
- if (flags & CM_SCACHESYNC_STOREDATA) {
- /* ensure that the buffer isn't already in the I/O list */
- for(qdp = scp->bufWritesp; qdp; qdp = (osi_queueData_t *) osi_QNext(&qdp->q)) {
- tbufp = osi_GetQData(qdp);
- if (tbufp == bufp) break;
- }
- osi_assert(qdp != NULL);
- osi_assert(osi_GetQData(qdp) == bufp);
- osi_QRemove((osi_queue_t **) &scp->bufWritesp, &qdp->q);
- osi_QDFree(qdp);
- if (bufp) {
- bufp->cmFlags &= ~CM_BUF_CMSTORING;
- buf_Release(bufp);
- }
+ /* now update the buffer pointer */
+ if (flags & CM_SCACHESYNC_STOREDATA) {
+ /* ensure that the buffer isn't already in the I/O list */
+ for(qdp = scp->bufWritesp; qdp; qdp = (osi_queueData_t *) osi_QNext(&qdp->q)) {
+ tbufp = osi_GetQData(qdp);
+ if (tbufp == bufp) break;
}
-
- /* and wakeup anyone who is waiting */
- if (scp->flags & CM_SCACHEFLAG_WAITING) {
- osi_Log1(afsd_logp, "CM SyncOp CM_SCACHEFLAG_WAITING reset for 0x%x", scp);
- scp->flags &= ~CM_SCACHEFLAG_WAITING;
- osi_Wakeup((long) &scp->flags);
+ osi_assert(qdp != NULL);
+ osi_assert(osi_GetQData(qdp) == bufp);
+ osi_QRemove((osi_queue_t **) &scp->bufWritesp, &qdp->q);
+ osi_QDFree(qdp);
+ if (bufp) {
+ bufp->cmFlags &= ~CM_BUF_CMSTORING;
+ buf_Release(bufp);
}
-}
+ }
+
+ /* and wakeup anyone who is waiting */
+ if (scp->flags & CM_SCACHEFLAG_WAITING) {
+ osi_Log1(afsd_logp, "CM SyncOp CM_SCACHEFLAG_WAITING reset for 0x%x", scp);
+ scp->flags &= ~CM_SCACHEFLAG_WAITING;
+ osi_Wakeup((long) &scp->flags);
+ }
+}
/* merge in a response from an RPC. The scp must be locked, and the callback
* is optional.
* started before that, can cause old info to be merged from the first call.
*/
void cm_MergeStatus(cm_scache_t *scp, AFSFetchStatus *statusp, AFSVolSync *volp,
- cm_user_t *userp, int flags)
+ cm_user_t *userp, int flags)
{
- // yj: i want to create some fake status for the /afs directory and the
- // entries under that directory
+ // yj: i want to create some fake status for the /afs directory and the
+ // entries under that directory
#ifdef AFS_FREELANCE_CLIENT
- if (cm_freelanceEnabled && scp == cm_rootSCachep) {
- osi_Log0(afsd_logp,"cm_MergeStatus Freelance cm_rootSCachep");
- statusp->InterfaceVersion = 0x1;
+ if (cm_freelanceEnabled && scp == cm_rootSCachep) {
+ osi_Log0(afsd_logp,"cm_MergeStatus Freelance cm_rootSCachep");
+ statusp->InterfaceVersion = 0x1;
statusp->FileType = CM_SCACHETYPE_DIRECTORY;
- statusp->LinkCount = scp->linkCount;
- statusp->Length = cm_fakeDirSize;
- statusp->DataVersion = cm_fakeDirVersion;
- statusp->Author = 0x1;
- statusp->Owner = 0x0;
- statusp->CallerAccess = 0x9;
- statusp->AnonymousAccess = 0x9;
- statusp->UnixModeBits = 0x1ff;
- statusp->ParentVnode = 0x1;
- statusp->ParentUnique = 0x1;
- statusp->ResidencyMask = 0;
- statusp->ClientModTime = FakeFreelanceModTime;
- statusp->ServerModTime = FakeFreelanceModTime;
- statusp->Group = 0;
- statusp->SyncCounter = 0;
- statusp->dataVersionHigh = 0;
- }
+ statusp->LinkCount = scp->linkCount;
+ statusp->Length = cm_fakeDirSize;
+ statusp->DataVersion = cm_fakeDirVersion;
+ statusp->Author = 0x1;
+ statusp->Owner = 0x0;
+ statusp->CallerAccess = 0x9;
+ statusp->AnonymousAccess = 0x9;
+ statusp->UnixModeBits = 0x1ff;
+ statusp->ParentVnode = 0x1;
+ statusp->ParentUnique = 0x1;
+ statusp->ResidencyMask = 0;
+ statusp->ClientModTime = FakeFreelanceModTime;
+ statusp->ServerModTime = FakeFreelanceModTime;
+ statusp->Group = 0;
+ statusp->SyncCounter = 0;
+ statusp->dataVersionHigh = 0;
+ }
#endif /* AFS_FREELANCE_CLIENT */
- if (!(flags & CM_MERGEFLAG_FORCE)
- && statusp->DataVersion < (unsigned long) scp->dataVersion) {
- struct cm_cell *cellp;
- struct cm_volume *volp;
-
- cellp = cm_FindCellByID(scp->fid.cell);
- cm_GetVolumeByID(cellp, scp->fid.volume, userp,
- (cm_req_t *) NULL, &volp);
- if (scp->cbServerp)
- osi_Log2(afsd_logp, "old data from server %x volume %s",
- scp->cbServerp->addr.sin_addr.s_addr,
- volp->namep);
- osi_Log3(afsd_logp, "Bad merge, scp %x, scp dv %d, RPC dv %d",
- scp, scp->dataVersion, statusp->DataVersion);
- /* we have a number of data fetch/store operations running
- * concurrently, and we can tell which one executed last at the
- * server by its mtime.
- * Choose the one with the largest mtime, and ignore the rest.
- *
- * These concurrent calls are incompatible with setting the
- * mtime, so we won't have a locally changed mtime here.
- *
- * We could also have ACL info for a different user than usual,
- * in which case we have to do that part of the merge, anyway.
- * We won't have to worry about the info being old, since we
- * won't have concurrent calls
- * that change file status running from this machine.
- *
- * Added 3/17/98: if we see data version regression on an RO
- * file, it's probably due to a server holding an out-of-date
- * replica, rather than to concurrent RPC's. Failures to
- * release replicas are now flagged by the volserver, but only
- * since AFS 3.4 5.22, so there are plenty of clients getting
- * out-of-date replicas out there.
- *
- * If we discover an out-of-date replica, by this time it's too
- * late to go to another server and retry. Also, we can't
- * reject the merge, because then there is no way for
- * GetAccess to do its work, and the caller gets into an
- * infinite loop. So we just grin and bear it.
- */
- if (!(scp->flags & CM_SCACHEFLAG_RO))
- return;
- }
- scp->serverModTime = statusp->ServerModTime;
-
- if (!(scp->mask & CM_SCACHEMASK_CLIENTMODTIME)) {
- scp->clientModTime = statusp->ClientModTime;
- }
- if (!(scp->mask & CM_SCACHEMASK_LENGTH)) {
- scp->length.LowPart = statusp->Length;
- scp->length.HighPart = 0;
- }
-
- scp->serverLength.LowPart = statusp->Length;
- scp->serverLength.HighPart = 0;
-
- scp->linkCount = statusp->LinkCount;
- scp->dataVersion = statusp->DataVersion;
- scp->owner = statusp->Owner;
- scp->group = statusp->Group;
- scp->unixModeBits = statusp->UnixModeBits & 07777;
-
- if (statusp->FileType == File)
- scp->fileType = CM_SCACHETYPE_FILE;
- else if (statusp->FileType == Directory)
- scp->fileType = CM_SCACHETYPE_DIRECTORY;
- else if (statusp->FileType == SymbolicLink) {
- if ((scp->unixModeBits & 0111) == 0)
- scp->fileType = CM_SCACHETYPE_MOUNTPOINT;
- else
- scp->fileType = CM_SCACHETYPE_SYMLINK;
- }
+ if (!(flags & CM_MERGEFLAG_FORCE)
+ && statusp->DataVersion < (unsigned long) scp->dataVersion) {
+ struct cm_cell *cellp;
+ struct cm_volume *volp;
+
+ cellp = cm_FindCellByID(scp->fid.cell);
+ cm_GetVolumeByID(cellp, scp->fid.volume, userp,
+ (cm_req_t *) NULL, &volp);
+ if (scp->cbServerp)
+ osi_Log2(afsd_logp, "old data from server %x volume %s",
+ scp->cbServerp->addr.sin_addr.s_addr,
+ volp->namep);
+ osi_Log3(afsd_logp, "Bad merge, scp %x, scp dv %d, RPC dv %d",
+ scp, scp->dataVersion, statusp->DataVersion);
+ /* we have a number of data fetch/store operations running
+ * concurrently, and we can tell which one executed last at the
+ * server by its mtime.
+ * Choose the one with the largest mtime, and ignore the rest.
+ *
+ * These concurrent calls are incompatible with setting the
+ * mtime, so we won't have a locally changed mtime here.
+ *
+ * We could also have ACL info for a different user than usual,
+ * in which case we have to do that part of the merge, anyway.
+ * We won't have to worry about the info being old, since we
+ * won't have concurrent calls
+ * that change file status running from this machine.
+ *
+ * Added 3/17/98: if we see data version regression on an RO
+ * file, it's probably due to a server holding an out-of-date
+ * replica, rather than to concurrent RPC's. Failures to
+ * release replicas are now flagged by the volserver, but only
+ * since AFS 3.4 5.22, so there are plenty of clients getting
+ * out-of-date replicas out there.
+ *
+ * If we discover an out-of-date replica, by this time it's too
+ * late to go to another server and retry. Also, we can't
+ * reject the merge, because then there is no way for
+ * GetAccess to do its work, and the caller gets into an
+ * infinite loop. So we just grin and bear it.
+ */
+ if (!(scp->flags & CM_SCACHEFLAG_RO))
+ return;
+ }
+ scp->serverModTime = statusp->ServerModTime;
+
+ if (!(scp->mask & CM_SCACHEMASK_CLIENTMODTIME)) {
+ scp->clientModTime = statusp->ClientModTime;
+ }
+ if (!(scp->mask & CM_SCACHEMASK_LENGTH)) {
+ scp->length.LowPart = statusp->Length;
+ scp->length.HighPart = 0;
+ }
+
+ scp->serverLength.LowPart = statusp->Length;
+ scp->serverLength.HighPart = 0;
+
+ scp->linkCount = statusp->LinkCount;
+ scp->dataVersion = statusp->DataVersion;
+ scp->owner = statusp->Owner;
+ scp->group = statusp->Group;
+ scp->unixModeBits = statusp->UnixModeBits & 07777;
+
+ if (statusp->FileType == File)
+ scp->fileType = CM_SCACHETYPE_FILE;
+ else if (statusp->FileType == Directory)
+ scp->fileType = CM_SCACHETYPE_DIRECTORY;
+ else if (statusp->FileType == SymbolicLink) {
+ if ((scp->unixModeBits & 0111) == 0)
+ scp->fileType = CM_SCACHETYPE_MOUNTPOINT;
+ else
+ scp->fileType = CM_SCACHETYPE_SYMLINK;
+ }
else {
osi_Log1(afsd_logp, "Merge, Invalid File Type, scp %x", scp);
scp->fileType = 0; /* invalid */
}
- /* and other stuff */
- scp->parentVnode = statusp->ParentVnode;
- scp->parentUnique = statusp->ParentUnique;
+ /* and other stuff */
+ scp->parentVnode = statusp->ParentVnode;
+ scp->parentUnique = statusp->ParentUnique;
- /* and merge in the private acl cache info, if this is more than the public
- * info; merge in the public stuff in any case.
- */
- scp->anyAccess = statusp->AnonymousAccess;
+ /* and merge in the private acl cache info, if this is more than the public
+ * info; merge in the public stuff in any case.
+ */
+ scp->anyAccess = statusp->AnonymousAccess;
- if (userp != NULL) {
- cm_AddACLCache(scp, userp, statusp->CallerAccess);
- }
+ if (userp != NULL) {
+ cm_AddACLCache(scp, userp, statusp->CallerAccess);
+ }
}
/* note that our stat cache info is incorrect, so force us eventually
*/
void cm_DiscardSCache(cm_scache_t *scp)
{
- lock_AssertMutex(&scp->mx);
+ lock_AssertMutex(&scp->mx);
if (scp->cbServerp) {
cm_PutServer(scp->cbServerp);
scp->cbServerp = NULL;
}
- scp->cbExpires = 0;
- cm_dnlcPurgedp(scp);
- cm_FreeAllACLEnts(scp);
+ scp->cbExpires = 0;
+ cm_dnlcPurgedp(scp);
+ cm_FreeAllACLEnts(scp);
}
void cm_AFSFidFromFid(AFSFid *afsFidp, cm_fid_t *fidp)
{
- afsFidp->Volume = fidp->volume;
- afsFidp->Vnode = fidp->vnode;
- afsFidp->Unique = fidp->unique;
-}
+ afsFidp->Volume = fidp->volume;
+ afsFidp->Vnode = fidp->vnode;
+ afsFidp->Unique = fidp->unique;
+}
void cm_HoldSCache(cm_scache_t *scp)
{
- lock_ObtainWrite(&cm_scacheLock);
- osi_assert(scp->refCount > 0);
- scp->refCount++;
- lock_ReleaseWrite(&cm_scacheLock);
+ lock_ObtainWrite(&cm_scacheLock);
+ osi_assert(scp->refCount > 0);
+ scp->refCount++;
+ lock_ReleaseWrite(&cm_scacheLock);
}
void cm_ReleaseSCache(cm_scache_t *scp)
{
- lock_ObtainWrite(&cm_scacheLock);
- osi_assert(scp->refCount-- > 0);
- lock_ReleaseWrite(&cm_scacheLock);
+ lock_ObtainWrite(&cm_scacheLock);
+ osi_assert(scp->refCount-- > 0);
+ lock_ReleaseWrite(&cm_scacheLock);
}
/* just look for the scp entry to get filetype */
/* doesn't need to be perfectly accurate, so locking doesn't matter too much */
int cm_FindFileType(cm_fid_t *fidp)
{
- long hash;
- cm_scache_t *scp;
+ long hash;
+ cm_scache_t *scp;
- hash = CM_SCACHE_HASH(fidp);
+ hash = CM_SCACHE_HASH(fidp);
- osi_assert(fidp->cell != 0);
+ osi_assert(fidp->cell != 0);
- lock_ObtainWrite(&cm_scacheLock);
- for(scp=cm_hashTablep[hash]; scp; scp=scp->nextp) {
- if (cm_FidCmp(fidp, &scp->fid) == 0) {
- /*scp->refCount++;*/
- /*cm_AdjustLRU(scp);*/
- lock_ReleaseWrite(&cm_scacheLock);
- return scp->fileType;
- }
+ lock_ObtainWrite(&cm_scacheLock);
+ for (scp=cm_hashTablep[hash]; scp; scp=scp->nextp) {
+ if (cm_FidCmp(fidp, &scp->fid) == 0) {
+ lock_ReleaseWrite(&cm_scacheLock);
+ return scp->fileType;
}
- lock_ReleaseWrite(&cm_scacheLock);
- return 0;
+ }
+ lock_ReleaseWrite(&cm_scacheLock);
+ return 0;
}
/* dump all scp's that have reference count > 0 to a file.
typedef struct cm_accessCache {
osi_queue_t q; /* queue header */
struct cm_user *userp; /* user having access rights */
- long rights; /* rights */
+ unsigned long rights; /* rights */
} cm_accessCache_t;
typedef struct cm_file_lock {
osi_queue_t q; /* lru queue; cm_scacheLock */
struct cm_scache *nextp; /* next in hash; cm_scacheLock */
cm_fid_t fid;
- long flags; /* flags; locked by mx */
+ unsigned long flags; /* flags; locked by mx */
/* synchronization stuff */
osi_mutex_t mx; /* mutex for this structure */
long parentUnique; /* for ACL callbacks */
/* local modification stat */
- long mask; /* for clientModTime, length and
+ unsigned long mask; /* for clientModTime, length and
* truncPos */
/* file status */
- int fileType; /* file type */
+ unsigned int fileType; /* file type */
time_t clientModTime; /* mtime */
time_t serverModTime; /* at server, for concurrent call
* comparisons */
osi_hyper_t length; /* file length */
cm_prefetch_t prefetch; /* prefetch info structure */
- int unixModeBits; /* unix protection mode bits */
+ unsigned int unixModeBits; /* unix protection mode bits */
int linkCount; /* link count */
long dataVersion; /* data version */
long owner; /* file owner */
osi_hyper_t bulkStatProgress; /* track bulk stats of large dirs */
/* open state */
- short openReads; /* opens for reading */
+ short openReads; /* open for reading */
short openWrites; /* open for writing */
short openShares; /* open for read excl */
short openExcls; /* open for exclusives */
* Iterate through all entries in a directory.
* When the function funcp is called, the buffer is locked but the
* directory vnode is not.
+ *
+ * If the retscp parameter is not NULL, the parmp must be a
+ * cm_lookupSearch_t object.
*/
long cm_ApplyDir(cm_scache_t *scp, cm_DirFuncp_t funcp, void *parmp,
osi_hyper_t *startOffsetp, cm_user_t *userp, cm_req_t *reqp,
if (retscp) /* if this is a lookup call */
{
cm_lookupSearch_t* sp = parmp;
- int casefold = sp->caseFold;
-
- sp->caseFold = 0; /* we have a strong preference for exact matches */
- if ( *retscp = cm_dnlcLookup(scp, sp)) /* dnlc hit */
- {
- sp->caseFold = casefold;
- lock_ReleaseMutex(&scp->mx);
- return 0;
- }
- sp->caseFold = casefold;
+#ifdef AFS_FREELANCE_CLIENT
+ /* Freelance entries never end up in the DNLC because they
+ * do not have an associated cm_server_t
+ */
+ if ( !(cm_freelanceEnabled &&
+ sp->fid.cell==AFS_FAKE_ROOT_CELL_ID &&
+ sp->fid.volume==AFS_FAKE_ROOT_VOL_ID ) )
+#endif /* AFS_FREELANCE_CLIENT */
+ {
+ int casefold = sp->caseFold;
+ sp->caseFold = 0; /* we have a strong preference for exact matches */
+ if ( *retscp = cm_dnlcLookup(scp, sp)) /* dnlc hit */
+ {
+ sp->caseFold = casefold;
+ lock_ReleaseMutex(&scp->mx);
+ return 0;
+ }
+ sp->caseFold = casefold;
+ }
}
/*
}
}
/* locked, has callback, has valid data in buffer */
- if ((tlen = scp->length.LowPart) > 1000) return CM_ERROR_TOOBIG;
+ if ((tlen = scp->length.LowPart) > 1000)
+ return CM_ERROR_TOOBIG;
if (tlen <= 0) {
code = CM_ERROR_INVAL;
goto done;
int sysNameIndex = 0;
cm_scache_t *scp = 0;
+ if ( stricmp(namep,SMB_IOCTL_FILENAME_NOSLASH) == 0 ) {
+ if (flags & CM_FLAG_CHECKPATH)
+ return CM_ERROR_NOSUCHPATH;
+ else
+ return CM_ERROR_NOSUCHFILE;
+ }
+
for ( sysNameIndex = 0; sysNameIndex < MAXNUMSYSNAMES; sysNameIndex++) {
code = cm_ExpandSysName(namep, tname, sizeof(tname), sysNameIndex);
if (code > 0) {
*outpScpp = scp;
return 0;
}
- if (scp) {
- cm_ReleaseSCache(scp);
- scp = 0;
- }
+ if (scp) {
+ cm_ReleaseSCache(scp);
+ scp = 0;
+ }
} else {
return cm_LookupInternal(dscp, namep, flags, userp, reqp, outpScpp);
}
if (tscp->fileType == CM_SCACHETYPE_SYMLINK) {
/* this is a symlink; assemble a new buffer */
lock_ReleaseMutex(&tscp->mx);
- if (symlinkCount++ >= 16) {
+ if (symlinkCount++ >= MAX_SYMLINK_COUNT) {
cm_ReleaseSCache(tscp);
cm_ReleaseSCache(dirScp);
if (psp)
cm_FreeSpace(psp);
- return CM_ERROR_TOOBIG;
+ return CM_ERROR_TOO_MANY_SYMLINKS;
}
if (tc == 0)
restp = "";
bb.counter = 0;
bb.bufOffset = *offsetp;
+ lock_ReleaseMutex(&dscp->mx);
/* first, assemble the file IDs we need to stat */
- code = cm_ApplyDir(dscp, cm_TryBulkProc, (void *) &bb, offsetp, userp,
- reqp, NULL);
+ code = cm_ApplyDir(dscp, cm_TryBulkProc, (void *) &bb, offsetp, userp, reqp, NULL);
+ lock_ObtainMutex(&dscp->mx);
/* if we failed, bail out early */
if (code && code != CM_ERROR_STOPNOW) return;
* time.
*/
filex = 0;
- while(filex < bb.counter) {
+ while (filex < bb.counter) {
filesThisCall = bb.counter - filex;
if (filesThisCall > AFSCBMAX) filesThisCall = AFSCBMAX;
extern long cm_RetryLock(cm_file_lock_t *oldFileLock, int vcp_is_dead);
+#define MAX_SYMLINK_COUNT 16
#endif /* __CM_VNODEOPS_H_ENV__ */
{
unsigned int attrs;
- if (scp->fileType == CM_SCACHETYPE_DIRECTORY
- || scp->fileType == CM_SCACHETYPE_MOUNTPOINT)
+ if ( scp->fileType == CM_SCACHETYPE_DIRECTORY ||
+ scp->fileType == CM_SCACHETYPE_MOUNTPOINT)
+ {
attrs = SMB_ATTR_DIRECTORY;
- else
+#ifdef SPECIAL_FOLDERS
+#ifdef AFS_FREELANCE_CLIENT
+ if ( cm_freelanceEnabled &&
+ scp->fid.cell==AFS_FAKE_ROOT_CELL_ID &&
+ scp->fid.volume==AFS_FAKE_ROOT_VOL_ID &&
+ scp->fid.vnode==0x1 && scp->fid.unique==0x1) {
+ attrs |= SMB_ATTR_SYSTEM; /* FILE_ATTRIBUTE_SYSTEM */
+ }
+#endif /* AFS_FREELANCE_CLIENT */
+#endif /* SPECIAL_FOLDERS */
+ } else
attrs = 0;
/*
{
int matchType = 0;
smb_findShare_rock_t * vrock = (smb_findShare_rock_t *) rockp;
- if(!strnicmp(dep->name, vrock->shareName, 12)) {
+ if (!strnicmp(dep->name, vrock->shareName, 12)) {
if(!stricmp(dep->name, vrock->shareName))
matchType = SMB_FINDSHARE_EXACT_MATCH;
else
(uidp? (uidp->unp ? uidp->unp->userp : NULL) : NULL), &req, NULL);
cm_ReleaseSCache(cm_rootSCachep);
- if(vrock.matchType) {
+ if (vrock.matchType) {
sprintf(pathName,"/%s/",vrock.match);
*pathNamep = strdup(strlwr(pathName));
free(vrock.match);
/* find a dir search structure by cookie value, and return it held.
* Must be called with smb_globalLock held.
*/
-smb_dirSearch_t *smb_FindDirSearchNL(long cookie)
+smb_dirSearch_t *smb_FindDirSearchNoLock(long cookie)
{
smb_dirSearch_t *dsp;
- for(dsp = smb_firstDirSearchp; dsp; dsp = (smb_dirSearch_t *) osi_QNext(&dsp->q)) {
+ for (dsp = smb_firstDirSearchp; dsp; dsp = (smb_dirSearch_t *) osi_QNext(&dsp->q)) {
if (dsp->cookie == cookie) {
if (dsp != smb_firstDirSearchp) {
/* move to head of LRU queue, too, if we're not already there */
if (!smb_lastDirSearchp)
smb_lastDirSearchp = (smb_dirSearch_t *) &dsp->q;
}
+ lock_ObtainMutex(&dsp->mx);
dsp->refCount++;
+ lock_ReleaseMutex(&dsp->mx);
break;
}
}
void smb_DeleteDirSearch(smb_dirSearch_t *dsp)
{
lock_ObtainWrite(&smb_globalLock);
- dsp->flags |= SMB_DIRSEARCH_DELETE;
- lock_ReleaseWrite(&smb_globalLock);
lock_ObtainMutex(&dsp->mx);
- if(dsp->scp != NULL) {
+ dsp->flags |= SMB_DIRSEARCH_DELETE;
+ if (dsp->scp != NULL) {
lock_ObtainMutex(&dsp->scp->mx);
if (dsp->flags & SMB_DIRSEARCH_BULKST) {
dsp->flags &= ~SMB_DIRSEARCH_BULKST;
lock_ReleaseMutex(&dsp->scp->mx);
}
lock_ReleaseMutex(&dsp->mx);
+ lock_ReleaseWrite(&smb_globalLock);
}
-void smb_ReleaseDirSearch(smb_dirSearch_t *dsp)
+/* Must be called with the smb_globalLock held */
+void smb_ReleaseDirSearchNoLock(smb_dirSearch_t *dsp)
{
cm_scache_t *scp;
scp = NULL;
- lock_ObtainWrite(&smb_globalLock);
+ lock_ObtainMutex(&dsp->mx);
osi_assert(dsp->refCount-- > 0);
if (dsp->refCount == 0 && (dsp->flags & SMB_DIRSEARCH_DELETE)) {
if (&dsp->q == (osi_queue_t *) smb_lastDirSearchp)
smb_lastDirSearchp = (smb_dirSearch_t *) osi_QPrev(&smb_lastDirSearchp->q);
osi_QRemove((osi_queue_t **) &smb_firstDirSearchp, &dsp->q);
+ lock_ReleaseMutex(&dsp->mx);
lock_FinalizeMutex(&dsp->mx);
scp = dsp->scp;
free(dsp);
+ } else {
+ lock_ReleaseMutex(&dsp->mx);
}
- lock_ReleaseWrite(&smb_globalLock);
-
/* do this now to avoid spurious locking hierarchy creation */
if (scp) cm_ReleaseSCache(scp);
}
+void smb_ReleaseDirSearch(smb_dirSearch_t *dsp)
+{
+ lock_ObtainWrite(&smb_globalLock);
+ smb_ReleaseDirSearchNoLock(dsp);
+ lock_ReleaseWrite(&smb_globalLock);
+}
+
/* find a dir search structure by cookie value, and return it held */
smb_dirSearch_t *smb_FindDirSearch(long cookie)
{
smb_dirSearch_t *dsp;
lock_ObtainWrite(&smb_globalLock);
- dsp = smb_FindDirSearchNL(cookie);
+ dsp = smb_FindDirSearchNoLock(cookie);
lock_ReleaseWrite(&smb_globalLock);
return dsp;
}
}
/* don't do more than this */
- if (victimCount >= SMB_DIRSEARCH_GCMAX) break;
+ if (victimCount >= SMB_DIRSEARCH_GCMAX)
+ break;
}
/* now release them */
- lock_ReleaseWrite(&smb_globalLock);
- for(i = 0; i < victimCount; i++) {
- smb_ReleaseDirSearch(victimsp[i]);
+ for (i = 0; i < victimCount; i++) {
+ smb_ReleaseDirSearchNoLock(victimsp[i]);
}
- lock_ObtainWrite(&smb_globalLock);
}
/* function for allocating a dir search entry. We need these to remember enough context
counter = 0;
/* what's the biggest ID allowed in this version of the protocol */
- if (isV3) maxAllowed = 65535;
- else maxAllowed = 255;
+ maxAllowed = isV3 ? 65535 : 255;
- while(1) {
+ while (1) {
/* twice so we have enough tries to find guys we GC after one pass;
* 10 extra is just in case I mis-counted.
*/
- if (++counter > 2*maxAllowed+10) osi_panic("afsd: dir search cookie leak",
- __FILE__, __LINE__);
+ if (++counter > 2*maxAllowed+10)
+ osi_panic("afsd: dir search cookie leak", __FILE__, __LINE__);
+
if (smb_dirSearchCounter > maxAllowed) {
smb_dirSearchCounter = 1;
- smb_GCDirSearches(isV3); /* GC some (drops global lock) */
+ smb_GCDirSearches(isV3); /* GC some */
}
- dsp = smb_FindDirSearchNL(smb_dirSearchCounter);
+ dsp = smb_FindDirSearchNoLock(smb_dirSearchCounter);
if (dsp) {
/* don't need to watch for refcount zero and deleted, since
* we haven't dropped the global lock.
*/
+ lock_ObtainMutex(&dsp->mx);
dsp->refCount--;
+ lock_ReleaseMutex(&dsp->mx);
++smb_dirSearchCounter;
continue;
}
dsp = malloc(sizeof(*dsp));
memset(dsp, 0, sizeof(*dsp));
osi_QAdd((osi_queue_t **) &smb_firstDirSearchp, &dsp->q);
- if (!smb_lastDirSearchp) smb_lastDirSearchp = (smb_dirSearch_t *) &dsp->q;
+ if (!smb_lastDirSearchp)
+ smb_lastDirSearchp = (smb_dirSearch_t *) &dsp->q;
dsp->cookie = smb_dirSearchCounter;
++smb_dirSearchCounter;
dsp->refCount = 1;
else if (code == CM_ERROR_GSSCONTINUE) {
NTStatus = 0xC0000016L; /* more processing required */
}
+ else if (code == CM_ERROR_TOO_MANY_SYMLINKS) {
+#ifdef COMMENT
+ NTStatus = 0xC0000280L; /* reparse point not resolved */
+#else
+ NTStatus = 0xC0000022L; /* Access Denied */
+#endif
+ }
else {
NTStatus = 0xC0982001L; /* SMB non-specific error */
}
else {
spacep = inp->spacep;
smb_StripLastComponent(spacep->data, NULL, pathp);
- lock_ReleaseMutex(&dsp->mx);
code = smb_LookupTIDPath(vcp, ((smb_t *)inp)->tid, &tidPathp);
if (code) {
lock_ReleaseMutex(&dsp->mx);
}
code = cm_NameI(cm_rootSCachep, spacep->data,
caseFold | CM_FLAG_FOLLOW, userp, tidPathp, &req, &scp);
- lock_ObtainMutex(&dsp->mx);
if (code == 0) {
- if (dsp->scp != 0) cm_ReleaseSCache(dsp->scp);
+ if (dsp->scp != 0)
+ cm_ReleaseSCache(dsp->scp);
dsp->scp = scp;
/* we need one hold for the entry we just stored into,
* and one for our own processing. When we're done with this
lock_ObtainRead(&scp->bufCreateLock);
code = buf_Get(scp, &thyper, &bufferp);
lock_ReleaseRead(&scp->bufCreateLock);
+ lock_ObtainMutex(&dsp->mx);
/* now, if we're doing a star match, do bulk fetching of all of
* the status info for files in the dir.
*/
if (starPattern) {
- smb_ApplyDirListPatches(&dirListPatchesp, userp,
- &req);
+ smb_ApplyDirListPatches(&dirListPatchesp, userp, &req);
+ lock_ObtainMutex(&scp->mx);
if ((dsp->flags & SMB_DIRSEARCH_BULKST) &&
LargeIntegerGreaterThanOrEqualTo(thyper,
scp->bulkStatProgress)) {
} else
cm_TryBulkStat(scp, &thyper, userp, &req);
}
+ } else {
+ lock_ObtainMutex(&scp->mx);
}
-
- lock_ObtainMutex(&scp->mx);
+ lock_ReleaseMutex(&dsp->mx);
if (code)
break;
+
bufferOffset = thyper;
/* now get the data in the cache */
rock.name = pathp;
rock.vnode = scp;
- code = cm_ApplyDir(dscp, smb_FullNameProc, &rock, NULL,
- userp, reqp, NULL);
+ code = cm_ApplyDir(dscp, smb_FullNameProc, &rock, NULL, userp, reqp, NULL);
if (code == CM_ERROR_STOPNOW)
*newPathp = rock.fullName;
else
}
afsd_ForceTrace(TRUE);
+ buf_ForceTrace(TRUE);
return EXCEPTION_CONTINUE_SEARCH;
}
#endif
unsigned long attrs;
if (scp->fileType == CM_SCACHETYPE_DIRECTORY ||
- scp->fileType == CM_SCACHETYPE_MOUNTPOINT)
+ scp->fileType == CM_SCACHETYPE_MOUNTPOINT)
+ {
attrs = SMB_ATTR_DIRECTORY;
- else
+#ifdef SPECIAL_FOLDERS
+#ifdef AFS_FREELANCE_CLIENT
+ if ( cm_freelanceEnabled &&
+ scp->fid.cell==AFS_FAKE_ROOT_CELL_ID &&
+ scp->fid.volume==AFS_FAKE_ROOT_VOL_ID &&
+ scp->fid.vnode==0x1 && scp->fid.unique==0x1) {
+ attrs |= SMB_ATTR_SYSTEM; /* FILE_ATTRIBUTE_SYSTEM */
+ }
+#endif /* AFS_FREELANCE_CLIENT */
+#endif /* SPECIAL_FOLDERS */
+ } else
attrs = 0;
/*
* We used to mark a file RO if it was in an RO volume, but that
rock.shortName = shortName;
rock.vnode = vnode;
rock.maskp = lastNamep;
- code = cm_ApplyDir(dscp, cm_GetShortNameProc, &rock, &thyper, userp,
- reqp, NULL);
+ code = cm_ApplyDir(dscp, cm_GetShortNameProc, &rock, &thyper, userp, reqp, NULL);
cm_ReleaseSCache(dscp);
pathp = ((char *) p->parmsp) + 12; /* points to path */
nextCookie = 0;
maskp = strrchr(pathp, '\\');
- if (maskp == NULL) maskp = pathp;
- else maskp++; /* skip over backslash */
+ if (maskp == NULL)
+ maskp = pathp;
+ else
+ maskp++; /* skip over backslash */
strcpy(dsp->mask, maskp); /* and save mask */
/* track if this is likely to match a lot of entries */
starPattern = smb_V3IsStarMask(maskp);
osi_assert(p->opcode == 2);
/* find next; obtain basic parameters from request or open dir file */
dsp = smb_FindDirSearch(p->parmsp[0]);
- if (!dsp) return CM_ERROR_BADFD;
+ if (!dsp)
+ return CM_ERROR_BADFD;
attribute = dsp->attribute;
maxCount = p->parmsp[1];
infoLevel = p->parmsp[2];
else {
spacep = cm_GetSpace();
smb_StripLastComponent(spacep->data, NULL, pathp);
- lock_ReleaseMutex(&dsp->mx);
-
code = smb_LookupTIDPath(vcp, p->tid, &tidPathp);
if (code) {
+ lock_ReleaseMutex(&dsp->mx);
cm_ReleaseUser(userp);
smb_SendTran2Error(vcp, p, opx, CM_ERROR_NOFILES);
smb_FreeTran2Packet(outp);
userp, tidPathp, &req, &scp);
cm_FreeSpace(spacep);
- lock_ObtainMutex(&dsp->mx);
if (code == 0) {
- if (dsp->scp != 0) cm_ReleaseSCache(dsp->scp);
+ if (dsp->scp != 0)
+ cm_ReleaseSCache(dsp->scp);
dsp->scp = scp;
/* we need one hold for the entry we just stored into,
* and one for our own processing. When we're done
lock_ObtainRead(&scp->bufCreateLock);
code = buf_Get(scp, &thyper, &bufferp);
lock_ReleaseRead(&scp->bufCreateLock);
+ lock_ObtainMutex(&dsp->mx);
/* now, if we're doing a star match, do bulk fetching
* of all of the status info for files in the dir.
smb_ApplyV3DirListPatches(scp, &dirListPatchesp,
infoLevel, userp,
&req);
+ lock_ObtainMutex(&scp->mx);
if ((dsp->flags & SMB_DIRSEARCH_BULKST) &&
LargeIntegerGreaterThanOrEqualTo(thyper, scp->bulkStatProgress)) {
/* Don't bulk stat if risking timeout */
} else
cm_TryBulkStat(scp, &thyper, userp, &req);
}
+ } else {
+ lock_ObtainMutex(&scp->mx);
}
+ lock_ReleaseMutex(&dsp->mx);
+ if (code)
+ break;
- lock_ObtainMutex(&scp->mx);
- if (code) break;
bufferOffset = thyper;
/* now get the data in the cache */
#include <osi.h>
#include <afsint.h>
-typedef long afs_int32;
-
#include "fs_utils.h"
#include "cmd.h"
/* create symlink with a special pioctl for Windows NT, since it doesn't
* have a symlink system call.
*/
+
+ /* TODO: Code needs to go here to prevent the creation of symlinks
+ * in \\AFS\all when not in the "AFS Client Admins" group.
+ */
+
blob.out_size = 0;
blob.in_size = 1 + strlen(space);
blob.in = space;
# Local clean target; augments predefined clean target
clean::
+ $(CD) lang
+ for /f %l in ('dir /B ??_??') do @$(NTLANG) %l $(MAKECMD) /nologo /f NTMakefile clean
+ $(CD) ..
mkdir:
-mkdir $(OUT)\lang
# Local clean target; augments predefined clean target
clean::
-
+ $(CD) lang
+ for /f %l in ('dir /B ??_??') do @$(NTLANG) %l $(MAKECMD) /nologo /f NTMakefile clean
+ $(CD) ..
mkdir:
-mkdir $(OUT)\lang
$(OUT)\svrmgr_stub.res : AFS_component_version_number.h
+clean::
+ $(CD) lang
+ for /f %l in ('dir /B ??_??') do @$(NTLANG) %l $(MAKECMD) /nologo /f NTMakefile clean
+ $(CD) ..
+
mkdir:
-mkdir $(OUT)\lang
cd lang
nmake /nologo /f ntmakefile SRC=$(SRC) OBJ=$(OBJ) mkdir
cd ..
-
+
$(OUT)\AfsUsrMgr_stub.res : AFS_component_version_number.h
+clean::
+ $(CD) lang
+ for /f %l in ('dir /B ??_??') do @$(NTLANG) %l $(MAKECMD) /nologo /f NTMakefile clean
+ $(CD) ..
+
mkdir:
-mkdir $(OUT)\lang
cd lang
void Config_GetSysName (LPTSTR pszName)
{
- if (!Config_ReadGlobalString (TEXT("SysName"), pszName, MAX_PATH))
- lstrcpy (pszName, TEXT("i386_nt40"));
+ if (!Config_ReadGlobalString (TEXT("SysName"), pszName, MAX_PATH))
+ lstrcpy (pszName, TEXT("i386_nt40"));
}
BOOL Config_SetSysName (LPCTSTR pszName, ULONG *pStatus)
{
- BOOL rc = TRUE;
- ULONG status = 0;
-
- if (Config_GetServiceState() == SERVICE_RUNNING)
- {
- struct {
- ULONG cbData;
- TCHAR szData[ PIOCTL_MAXSIZE ];
- } InData;
- memset (&InData, 0x00, sizeof(InData));
- InData.cbData = lstrlen(pszName);
- lstrcpy (InData.szData, pszName);
-
- BYTE OutData[ PIOCTL_MAXSIZE ];
- memset (OutData, 0x00, sizeof(OutData));
-
- struct ViceIoctl IOInfo;
- IOInfo.in_size = sizeof(ULONG) +lstrlen(pszName) +1;
- IOInfo.in = (char *)&InData;
- IOInfo.out = (char *)OutData;
- IOInfo.out_size = PIOCTL_MAXSIZE;
-
- if ((status = pioctl (0, VIOC_AFS_SYSNAME, &IOInfo, 1)) != 0)
- {
- rc = FALSE;
- }
- }
-
- if (rc)
- {
- Config_WriteGlobalString (TEXT("SysName"), pszName);
- }
-
- if (pStatus && !rc)
- *pStatus = status;
- if (!rc)
- Message (MB_ICONHAND, GetErrorTitle(), IDS_FAILCONFIG_SYSNAME, TEXT("%ld"), status);
- return rc;
+ BOOL rc = TRUE;
+ ULONG status = 0;
+
+ if (Config_GetServiceState() == SERVICE_RUNNING)
+ {
+ struct {
+ ULONG cbData;
+ TCHAR szData[ PIOCTL_MAXSIZE ];
+ } InData;
+ memset (&InData, 0x00, sizeof(InData));
+ USHORT i=0, j=0, len=lstrlen(pszName);
+
+ if ( len == 0 ) {
+ Message (MB_ICONHAND, GetErrorTitle(), IDS_FAILCONFIG_SYSNAME, TEXT("A sysname must be specified"));
+ return(-1);
+ }
+
+ while ( pszName[i] ) {
+ if ( !isspace(pszName[i]) ) {
+ InData.szData[j++] = pszName[i];
+ } else if (InData.szData[j-1] != '\0') {
+ InData.szData[j++] = '\0';
+ InData.cbData++;
+ }
+ i++;
+ }
+ InData.szData[j++] = '\0';
+ InData.cbData++; /* one word */
+
+ BYTE OutData[ PIOCTL_MAXSIZE ];
+ memset (OutData, 0x00, sizeof(OutData));
+
+ struct ViceIoctl IOInfo;
+ IOInfo.in_size = sizeof(ULONG) + j;
+ IOInfo.in = (char *)&InData;
+ IOInfo.out = (char *)OutData;
+ IOInfo.out_size = PIOCTL_MAXSIZE;
+
+ if ((status = pioctl (0, VIOC_AFS_SYSNAME, &IOInfo, 1)) != 0)
+ {
+ rc = FALSE;
+ }
+ }
+
+ if (rc)
+ {
+ Config_WriteGlobalString (TEXT("SysName"), pszName);
+ }
+
+ if (pStatus && !rc)
+ *pStatus = status;
+ if (!rc)
+ Message (MB_ICONHAND, GetErrorTitle(), IDS_FAILCONFIG_SYSNAME, TEXT("%ld"), status);
+ return rc;
}
$(OUT)\afscreds_stub.res : afscreds_stub.rc AFS_component_version_number.h
+clean::
+ $(CD) lang
+ for /f %l in ('dir /B ??_??') do @$(NTLANG) %l $(MAKECMD) /nologo /f NTMakefile clean
+ $(CD) ..
+
mkdir:
-mkdir $(OUT)\lang
cd lang
PUSHBUTTON "OK",IDOK,22,53,45,14
PUSHBUTTON "Cancel",IDCANCEL,92,53,45,14
PUSHBUTTON "Help",9,167,53,45,14
- LTEXT "Share Name:",IDC_STATIC,18,10,29,8
+ LTEXT "Submount Name:",IDC_STATIC,18,10,29,8
+ LTEXT "Path Name:",IDC_STATIC,19,25,28,8
+END
+
+IDD_SYMBOLICLINK_ADD DIALOG DISCARDABLE 0, 0, 235, 79
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Add Symbolic Link"
+FONT 8, "MS Sans Serif"
+BEGIN
+ EDITTEXT IDC_NAME,62,8,163,12,ES_AUTOHSCROLL
+ EDITTEXT IDC_DIR,62,23,163,12,ES_AUTOHSCROLL
+ PUSHBUTTON "OK",IDOK,22,53,45,14
+ PUSHBUTTON "Cancel",IDCANCEL,92,53,45,14
+ PUSHBUTTON "Help",9,167,53,45,14
+ LTEXT "Link Name:",IDC_STATIC,18,10,29,8
LTEXT "Path Name:",IDC_STATIC,19,25,28,8
END
DDX_Text(pDX, IDC_NAME, m_strName);
DDV_MaxChars(pDX, m_strName, 63);
DDX_Text(pDX, IDC_DIR, m_strDir);
- DDV_MaxChars(pDX, m_strDir, 63);
+ DDV_MaxChars(pDX, m_strDir, 255);
//}}AFX_DATA_MAP
}
# Cleanup
clean::
- for %l in ( $(LANGUAGES) ) do (
+ for %l in ( $(LANGUAGES) ) do \
$(MAKE) /f NTMakefile /nologo LANG=%l lang_clean
- )
$(CD) custom
$(MAKE) /f NTMakefile /nologo clean
$(CD) ..
<!-- We are including debug symbols anyway. Undefine this for a leaner installer witout debug syms. -->
<?define DebugSyms?>
+
+ <!-- Parameters for the features containing debug symbols -->
+ <?ifdef DebugSyms?>
+ <?ifdef Debug?>
+ <?define DebugSymInstallDefault="followParent"?>
+ <?define DebugSymLowLevel="30"?>
+ <?define DebugSymHighLevel="130"?>
+ <?else?>
+ <?define DebugSymInstallDefault="followParent"?>
+ <?define DebugSymLowLevel="130"?>
+ <?define DebugSymHighLevel="130"?>
+ <?endif?>
+ <?endif?>
<!-- Use the afsloopback.dll instead of instloop.exe -->
<?define UseDllLoopbackInstaller?>
<?error AFSVER_CL needs to be set to the compiler version?>
<?endif?>
<?define SystemDir="$(env.SystemRoot)\System32\"?>
+
+
</Include>
<?xml version="1.0" ?>
<Include>
-
- <?ifdef DebugSyms?>
- <?ifdef Debug?>
- <?define DebugSymFollowParent="yes"?>
- <?define DebugSymLowLevel="30"?>
- <?define DebugSymHighLevel="130"?>
- <?else?>
- <?define DebugSymFollowParent="no"?>
- <?define DebugSymLowLevel="130"?>
- <?define DebugSymHighLevel="130"?>
- <?endif?>
- <?endif?>
-
<Feature Id="feaOpenAFS" AllowAdvertise="no" Absent="disallow" ConfigurableDirectory="AFSDIR"
Description="$(loc.StrAFSProdDesc)" Display="expand" InstallDefault="local" Level="30"
Title="OpenAFS">
<Feature Id="feaClient" AllowAdvertise="no" Description="$(loc.StrAFSClientLongDesc)" Display="expand"
- FollowParent="yes" InstallDefault="local" Level="30" Title="$(loc.StrAFSClientDesc)">
+ InstallDefault="followParent" Level="30" Title="$(loc.StrAFSClientDesc)">
- <Feature Id="feaLoopback" FollowParent="yes" AllowAdvertise="no" Description="$(loc.StrLoopbackLongDesc)"
- Display="expand" InstallDefault="local" Level="30" Title="$(loc.StrLoopbackDesc)">
+ <Feature Id="feaLoopback" AllowAdvertise="no" Description="$(loc.StrLoopbackLongDesc)"
+ Display="expand" InstallDefault="followParent" Level="30" Title="$(loc.StrLoopbackDesc)">
<ComponentRef Id="rcm_Loopback"/>
</Feature>
- <Feature Id="feaKB301673" AllowAdvertise="no" Absent="disallow" Display="hidden" InstallDefault="local" Level="0" FollowParent="yes">
+ <Feature Id="feaKB301673" AllowAdvertise="no" Absent="disallow" Display="hidden" InstallDefault="followParent" Level="0">
<ComponentRef Id="rcm_KB301673" />
<Condition Level="30">VersionNT = 500 And ServicePackLevel < 3</Condition>
</Feature>
- <Feature Id="feaCredsStartup" AllowAdvertise="no" FollowParent="yes" Display="hidden" InstallDefault="local" Level="30">
+ <Feature Id="feaCredsStartup" AllowAdvertise="no" Display="hidden" InstallDefault="followParent" Level="30">
<ComponentRef Id="cmp_credsStartup" />
<Condition Level="130">CREDSSTARTUP = 0</Condition>
</Feature>
<?ifdef DebugSyms?>
<Feature Id="feaClientDebug" AllowAdvertise="no" Description="$(loc.StrAFSClientDebugLongDesc)" Display="expand"
- FollowParent="$(var.DebugSymFollowParent)" InstallDefault="local" Level="$(var.DebugSymLowLevel)" Title="$(loc.StrAFSClientDebugDesc)">
+ InstallDefault="$(var.DebugSymInstallDefault)" Level="$(var.DebugSymLowLevel)" Title="$(loc.StrAFSClientDebugDesc)">
<ComponentRef Id="cmp_ClientProgramDebug" />
<ComponentRef Id="cmp_CommonCommonDebug" />
<ComponentRef Id="cmp_ClientCommonDebug" />
</Feature>
<Feature Id="feaServer" AllowAdvertise="no" Description="$(loc.StrAFSServerLongDesc)" Display="expand"
- FollowParent="yes" InstallDefault="local" Level="130" Title="$(loc.StrAFSServerDesc)">
+ InstallDefault="followParent" Level="130" Title="$(loc.StrAFSServerDesc)">
<ComponentRef Id="rcm_Server" />
<ComponentRef Id="cmp_CommonDir" />
<?ifdef DebugSyms?>
<Feature Id="feaServerDebug" AllowAdvertise="no" Description="$(loc.StrAFSServerDebugLongDesc)" Display="expand"
- FollowParent="$(var.DebugSymFollowParent)" InstallDefault="local" Level="$(var.DebugSymHighLevel)" Title="$(loc.StrAFSServerDebugDesc)">
+ InstallDefault="$(var.DebugSymInstallDefault)" Level="$(var.DebugSymHighLevel)" Title="$(loc.StrAFSServerDebugDesc)">
<ComponentRef Id="cmp_Server_Program_Debug" />
<ComponentRef Id="cmp_ServerCommonDebug" />
<ComponentRef Id="cmp_CommonCommonDebug" />
<?include runtime.wxi?>
</Feature>
<Feature Id="feaControlCenter" AllowAdvertise="no" Description="$(loc.StrAFSCCLongDesc)"
- Display="expand" FollowParent="yes" InstallDefault="local" Level="130" Title="$(loc.StrAFSCCDesc)">
+ Display="expand" InstallDefault="followParent" Level="130" Title="$(loc.StrAFSCCDesc)">
<ComponentRef Id="rcm_Control_Center" />
<ComponentRef Id="cmp_CommonDir" />
<?ifdef DebugSyms?>
<Feature Id="feaControlCenterDebug" AllowAdvertise="no" Description="$(loc.StrAFSCCDebugLongDesc)"
- Display="expand" FollowParent="$(var.DebugSymFollowParent)" InstallDefault="local" Level="$(var.DebugSymHighLevel)" Title="$(loc.StrAFSCCDebugDesc)">
+ Display="expand" InstallDefault="$(var.DebugSymInstallDefault)" Level="$(var.DebugSymHighLevel)" Title="$(loc.StrAFSCCDebugDesc)">
<ComponentRef Id="cmp_Control_CenterDebug" />
<ComponentRef Id="cmp_ServerCommonDebug" />
<ComponentRef Id="cmp_CommonCommonDebug" />
<?include runtime.wxi?>
</Feature>
<Feature Id="feaSDK" AllowAdvertise="no" Description="$(loc.StrAFSSDKLongDesc)" Display="expand"
- FollowParent="yes" InstallDefault="local" Level="130" Title="$(loc.StrAFSSDKDesc)">
+ InstallDefault="followParent" Level="130" Title="$(loc.StrAFSSDKDesc)">
<ComponentRef Id="rcm_SDK" />
<?ifdef DebugSyms?>
<Feature Id="feaSDKDebug" AllowAdvertise="no" Description="$(loc.StrAFSSDKDebugLongDesc)" Display="expand"
- FollowParent="$(var.DebugSymFollowParent)" InstallDefault="local" Level="$(var.DebugSymHighLevel)" Title="$(loc.StrAFSSDKDebugDesc)">
+ InstallDefault="$(var.DebugSymInstallDefault)" Level="$(var.DebugSymHighLevel)" Title="$(loc.StrAFSSDKDebugDesc)">
<?include runtime_debug.wxi?>
</Feature>
<?endif?>
</Feature>
<Feature Id="feaDocumentation" AllowAdvertise="no" Description="$(loc.StrAFSDocLongDesc)"
- Display="expand" FollowParent="yes" InstallDefault="local" Level="130" Title="$(loc.StrAFSDocDesc)">
+ Display="expand" InstallDefault="followParent" Level="130" Title="$(loc.StrAFSDocDesc)">
<ComponentRef Id="rcm_Documentation" />
<?xml version="1.0"?>
<Include>
- <Directory Id="SystemFolder" SourceName="System" LongSource="System">
+ <Directory Id="SystemFolder" SourceName="System">
<Component Id="cmf_afslogon_DLL" Guid="123197FE-4F53-4035-8D51-FCFB6B50A777">
<File Id="fileafslogon_DLL" Name="afslogon.dll" LongName="afslogon.dll" KeyPath="yes" DiskId="1" src="$(var.ClientDir)afslogon.dll" />
<Registry Id="reg_afslogon01" Root="HKLM" Key="SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\AfsLogon" Action="createKeyAndRemoveKeyOnUninstall" />
</Directory>
<Directory Id="ProgramFilesFolder">
<Directory Id="AFSDIR" Name="OpenAFS" SourceName=".">
- <Directory Id="dirCommon" Name="Common" LongName="Common" SourceName="Common">
+ <Directory Id="dirCommon" Name="Common">
<Component Id="cmp_CommonDir" Guid="C86B03A1-AE97-48B1-A77B-1B2395F1E117" KeyPath="yes">
<Environment Id="envCommon" Name="PATH" Action="create" System="yes" Permanent="no" Part="last" Separator=";" Value="[AFSDIR]Common" />
<CreateFolder />
<File Id="fileafs_shl_ext_1033_DLL" Name="ashl1033.dll" LongName="afs_shl_ext_1033.dll" KeyPath="yes" DiskId="1" src="$(var.ClientDir)\afs_shl_ext_1033.dll"/>
</Component>
- <Directory Id="dirCommon_en_US" Name="en_US" LongName="en_US" SourceName="en_US" src="$(var.SrcDir)\WINNT\doc\help\en_US\">
+ <Directory Id="dirCommon_en_US" Name="en_US" src="$(var.SrcDir)\WINNT\doc\help\en_US\">
<Component Id="cmf_afs_nt_HLP_en_US" Guid="A59FF1E3-984F-47E0-8A65-590A01B6E1C4">
<File Id="fileafs_nt_HLP_en_US" Name="afs-nt.hlp" LongName="afs-nt.hlp" KeyPath="yes" DiskId="1">
<Shortcut Id="scClientHelp_en_US" Directory="dirShortCut" Name="CliHelp.lnk" LongName="Client Help.lnk" Description="$(loc.StrHlpFileDesc)" Icon="ico_Help" IconIndex="0" Show="normal" WorkingDirectory="dirCommon" />
<Directory Id="dirDocumentation" Name="Docum" LongName="Documentation" SourceName="Docs">
<!-- The following directory and everything below it is language dependent. -->
- <Directory Id="dirDoc_$(var.Language)" Name="$(var.Language)" LongName="$(var.Language)" SourceName="$(var.Language)">
- <Directory Id="dirHtml_$(var.Language)" Name="Html" LongName="Html" SourceName="html" src="$(var.SrcDir)\WINNT\doc\install\Documentation\$(var.Language)\html\">
+ <Directory Id="dirDoc_$(var.Language)" Name="$(var.Language)">
+ <Directory Id="dirHtml_$(var.Language)" Name="Html" src="$(var.SrcDir)\WINNT\doc\install\Documentation\$(var.Language)\html\">
<Component Id="cmf_index2_HTM_$(var.Language)" Guid="$(var.DocHtmlIndexGuid)">
<File Id="fileindex2_HTM_$(var.Language)" Name="index.htm" LongName="index.htm" KeyPath="yes" DiskId="1">
<Shortcut Id="scDoc_$(var.Language)" Directory="dirShortCut" Name="Doc$(var.Language).lnk" LongName="Documentation ($(var.Language)).lnk" Description="$(loc.StrDocLnkDesc)" Icon="ico_Help" IconIndex="0" Show="normal" WorkingDirectory="dirCommon" />
<File Id="filetop_GIF_$(var.Language)" Name="top.gif" LongName="top.gif" DiskId="1" />
<File Id="file$(var.Language)_RTF" Name="$(var.Language).rtf" LongName="$(var.Language).rtf" KeyPath="yes" DiskId="1" src="$(var.SrcDir)\WINNT\license\lang\$(var.Language).rtf"/>
</Component>
- <Directory Id="dirCmdRef_$(var.Language)" Name="CmdRef" LongName="CmdRef" SourceName="CmdRef" src="$(var.SrcDir)\WINNT\doc\install\Documentation\$(var.Language)\html\CmdRef\">
+ <Directory Id="dirCmdRef_$(var.Language)" Name="CmdRef" src="$(var.SrcDir)\WINNT\doc\install\Documentation\$(var.Language)\html\CmdRef\">
<Component Id="cmp_Cmd_Ref_$(var.Language)" Guid="$(var.DocHtmlCmdRefGuid)">
<File Id="fileauarf000_HTM_$(var.Language)" Name="auarf000.htm" LongName="auarf000.htm" KeyPath="yes" DiskId="1" />
<File Id="fileauarf002_HTM_$(var.Language)" Name="auarf002.htm" LongName="auarf002.htm" DiskId="1" />
<File Id="fileauarf284_HTM_$(var.Language)" Name="auarf284.htm" LongName="auarf284.htm" DiskId="1" />
</Component>
</Directory> <!-- CmdRef -->
- <Directory Id="dirInstallGd_$(var.Language)" Name="InstalGd" LongName="InstallGd" SourceName="InstGd" LongSource="InstallGuide" src="$(var.SrcDir)\WINNT\doc\install\Documentation\$(var.Language)\html\InstallGd\">
+ <Directory Id="dirInstallGd_$(var.Language)" Name="InstalGd" SourceName="InstGd" LongSource="InstallGuide" src="$(var.SrcDir)\WINNT\doc\install\Documentation\$(var.Language)\html\InstallGd\">
<Component Id="cmp_Install_Guide_$(var.Language)" Guid="$(var.DocHtmlInstallGuid)">
<File Id="fileawqbg000_HTM_$(var.Language)" Name="awqbg000.htm" LongName="awqbg000.htm" KeyPath="yes" DiskId="1" />
<File Id="fileawqbg002_HTM_$(var.Language)" Name="awqbg002.htm" LongName="awqbg002.htm" DiskId="1" />
<File Id="filecachmgr_GIF_$(var.Language)" Name="cachm.gif" LongName="cachmgr.gif" DiskId="1" />
</Component>
</Directory> <!-- Sys Admin guide -->
- <Directory Id="dirReleaseNotes_$(var.Language)" Name="Relea" LongName="ReleaseNotes" SourceName="Relea" LongSource="ReleaseNotes" src="$(var.SrcDir)\WINNT\doc\install\Documentation\$(var.Language)\html\ReleaseNotes\">
+ <Directory Id="dirReleaseNotes_$(var.Language)" Name="Relea" LongName="ReleaseNotes" src="$(var.SrcDir)\WINNT\doc\install\Documentation\$(var.Language)\html\ReleaseNotes\">
<Component Id="cmp_Release_Notes_$(var.Language)" Guid="$(var.DocHtmlRelNotesGuid)">
<File Id="fileawrns000_HTM_$(var.Language)" Name="awrns.htm" LongName="awrns000.htm" KeyPath="yes" DiskId="1" />
<File Id="fileawrns002_HTM_$(var.Language)" Name="awrns~2.htm" LongName="awrns002.htm" DiskId="1" />
</Directory> <!-- $(var.Language) -->
</Directory> <!-- Documentation -->
- <Directory Id="dirClient" Name="Client" LongName="Client" SourceName="Client">
+ <Directory Id="dirClient" Name="Client">
<Component Id="efl_CellServDB" Guid="8E69FDAB-08C5-4927-B1AA-57FCEEB065F2" NeverOverwrite="yes" Permanent="yes">
<File Id="file_CellServDB" Name="CelSrvDB" LongName="CellServDB" KeyPath="yes" DiskId="1" src="$(var.CellDbFile)"/>
<Condition>OLDCELLSERVDB = ""</Condition>
<CopyFile Id="copy_CellServDB" Delete="yes" DestinationDirectory="dirClient" DestinationName="CellServ|CellServDB" SourceDirectory="WindowsFolder" SourceName="afsdcell.ini" />
<Condition>OLDCELLSERVDB <> ""</Condition>
</Component>
- <Directory Id="dirProgram" Name="Program" LongName="Program" SourceName="Program" src="$(var.ClientDir)">
+ <Directory Id="dirProgram" Name="Program" src="$(var.ClientDir)">
<Component Id="cmf_afsshare_EXE" Guid="E972DA35-E950-4736-AE48-E6DDCE8C97D0">
<File Id="fileafsshare_EXE" Name="afsshare.exe" LongName="afsshare.exe" KeyPath="yes" DiskId="1" />
</Component>
</Component>
<?endif?>
- <Directory Id="dirSample" Name="Sampl" LongName="Sample" SourceName="Sample">
+ <Directory Id="dirSample" Name="Sample">
<Component Id="cmp_SDK_Sample" Guid="F9373E95-F410-4AA5-AA79-07C11EE00334">
<File Id="filetoken_C" Name="token.c" LongName="token.c" KeyPath="yes" DiskId="1" src="$(var.SrcDir)WINNT\afsd\sample\token.c"/>
</Component>
</Directory>
- <Directory Id="dirInclude" Name="Include" LongName="Include" SourceName="Include">
+ <Directory Id="dirInclude" Name="Include">
<Component Id="cmp_SDK_Include" Guid="9B12B216-B104-4E49-BE31-4042F2CBD318">
<File Id="filebasic_H" Name="basic.h" LongName="basic.h" DiskId="1" src="$(var.IncDir)basic.h" />
<File Id="filecrypt_H" Name="crypt.h" LongName="crypt.h" DiskId="1" src="$(var.IncDir)crypt.h" />
<File Id="fileubik_H" Name="ubik.h" LongName="ubik.h" DiskId="1" src="$(var.IncDir)ubik.h" />
<File Id="fileubik_int_H" Name="ubik_int.h" LongName="ubik_int.h" DiskId="1" src="$(var.IncDir)ubik_int.h" />
</Component>
- <Directory Id="dirIncludeAfs" Name="afs" LongName="afs" SourceName="afs">
+ <Directory Id="dirIncludeAfs" Name="afs">
<Component Id="cmp_SDK_Include_afs" Guid="692D18AD-4901-4124-8B1F-5D414E65A7D0">
<File Id="fileacl_H" Name="acl.h" LongName="acl.h" DiskId="1" src="$(var.IncDir)afs\acl.h" />
<File Id="fileafscbint_H" Name="afscbint.h" LongName="afscbint.h" DiskId="1" src="$(var.IncDir)afs\afscbint.h" />
<File Id="filevolume_H" Name="volume.h" LongName="volume.h" DiskId="1" src="$(var.IncDir)afs\volume.h" />
</Component>
</Directory>
- <Directory Id="dirIncludeRx" Name="rx" LongName="rx" SourceName="rx">
+ <Directory Id="dirIncludeRx" Name="rx">
<Component Id="cmp_SDK_Include_rx" Guid="2E215D10-C080-42A3-B692-AFF94C7A1A2B">
<File Id="fileasn1_err_H" Name="asn1_err.h" LongName="asn1_err.h" DiskId="1" src="$(var.IncDir)rx\asn1_err.h" />
<File Id="filefcrypt_H" Name="fcrypt.h" LongName="fcrypt.h" DiskId="1" src="$(var.IncDir)rx\fcrypt.h" />
<File Id="filexdr_prototypes_H" Name="XDR_PR~1.h" LongName="xdr_prototypes.h" DiskId="1" src="$(var.IncDir)rx\xdr_prototypes.h" />
</Component>
</Directory>
- <Directory Id="dirIncludeWinnt" Name="WINNT" LongName="WINNT" SourceName="WINNT">
+ <Directory Id="dirIncludeWinnt" Name="WINNT">
<Component Id="cmp_SDK_Include_Winnt" Guid="BAAF0193-5C33-4EC1-9D40-DD4595F176E6">
<File Id="fileafsapplib_H" Name="AFSAPP~1.h" LongName="afsapplib.h" DiskId="1" src="$(var.IncDir)WINNT\afsapplib.h" />
<File Id="fileafsclass_H" Name="afsclass.h" LongName="afsclass.h" DiskId="1" src="$(var.IncDir)WINNT\afsclass.h" />
</Component>
</Directory>
</Directory>
- <Directory Id="dirLib" Name="lib" LongName="lib" SourceName="lib">
+ <Directory Id="dirLib" Name="lib">
<Component Id="cmp_SDK_Lib" Guid="71BC1B4E-4C4C-4FF8-8DDA-C6AB2BE22142">
<File Id="fileafsauthent_LIB" Name="AFSAUT~1.lib" LongName="afsauthent.lib" DiskId="1" src="$(var.LibDir)afsauthent.lib" />
<File Id="fileafsdes_LIB" Name="afsdes.lib" LongName="afsdes.lib" DiskId="1" src="$(var.LibDir)afsdes.lib" />
<File Id="filecm_config_OBJ" Name="CM_CON~1.obj" LongName="cm_config.obj" DiskId="1" src="$(var.LibDir)cm_config.obj" />
<File Id="filecm_dns_OBJ" Name="cm_dns.obj" LongName="cm_dns.obj" DiskId="1" src="$(var.LibDir)cm_dns.obj" />
</Component>
- <Directory Id="dirLibAfs" Name="afs" LongName="afs" SourceName="afs">
+ <Directory Id="dirLibAfs" Name="afs">
<Component Id="cmp_SDK_Lib_Afs" Guid="CD671A64-D491-4363-A7AD-645482B481BE">
<File Id="fileafsacl_LIB" Name="afsacl.lib" LongName="afsacl.lib" DiskId="1" src="$(var.LibDir)afs\afsacl.lib" />
<File Id="fileafsadminutil_LIB" Name="AFSADM~1.lib" LongName="afsadminutil.lib" DiskId="1" src="$(var.LibDir)afs\afsadminutil.lib" />
</Directory>
</Directory> <!-- /Program -->
</Directory> <!-- /Client -->
- <Directory Id="dirServer" Name="Server" LongName="Server" SourceName="Server">
- <Directory Id="dirusr" Name="usr" LongName="usr" SourceName="usr">
- <Directory Id="dirafs" Name="afs" LongName="afs" SourceName="afs">
- <Directory Id="dirbin" Name="bin" LongName="bin" SourceName="bin" src="$(var.ServerDir)">
+ <Directory Id="dirServer" Name="Server">
+ <Directory Id="dirusr" Name="usr">
+ <Directory Id="dirafs" Name="afs">
+ <Directory Id="dirbin" Name="bin" src="$(var.ServerDir)">
<Component Id="cmf_vlserver_EXE" Guid="F6A43B78-EE17-4483-AA81-4B6C6957977D">
<File Id="filevlserver_EXE" Name="vlser.exe" LongName="vlserver.exe" KeyPath="yes" DiskId="1" />
</Component>
</Directory> <!-- program files -->
<!-- References -->
<Directory Id="ProgramMenuFolder" Name=".">
- <Directory Id="dirShortCut" Name="OpenAFS" LongName="OpenAFS"/>
+ <Directory Id="dirShortCut" Name="OpenAFS"/>
</Directory>
<Directory Id="StartupFolder" Name="." />
<Directory Id="WindowsVolume" Name="." />
BinaryKey="BIN_afsCustom"
DllEntry="UninstallNsisInstallation"
Execute="immediate" />
- <CustomAction
+ <CustomAction
Id="CreateAFSAdminGroup"
BinaryKey="BIN_afsCustom"
DllEntry="CreateAFSClientAdminGroup"
(pthread_cache_done || pthread_once(&pthread_cache_once, create_once));
if (terminate_thread_handle == INVALID_HANDLE_VALUE) {
- CHAR eventName[MAX_PATH];
- static eventCount = 0;
- sprintf(eventName, "terminate_thread_wakeup_event %d::%d", _getpid(), eventCount++);
- terminate_thread_wakeup_event = CreateEvent((LPSECURITY_ATTRIBUTES) 0,
- TRUE, FALSE, (LPCTSTR) eventName);
- terminate_thread_handle = CreateThread((LPSECURITY_ATTRIBUTES) 0, 0,
- terminate_thread_routine, (LPVOID) 0, 0,
- &terminate_thread_id);
+ terminate_thread_wakeup_event = CreateEvent((LPSECURITY_ATTRIBUTES) 0,
+ TRUE, FALSE, (LPCTSTR) 0);
+ terminate_thread_handle = CreateThread((LPSECURITY_ATTRIBUTES) 0, 0,
+ terminate_thread_routine, (LPVOID) 0, 0,
+ &terminate_thread_id);
} else {
SetEvent (terminate_thread_wakeup_event);
}
if (queue_IsEmpty(&waiter_cache)) {
new = (cond_waiters_t *) malloc(sizeof(cond_waiters_t));
if (new != NULL) {
- CHAR eventName[MAX_PATH];
- static eventCount = 0;
- sprintf(eventName, "cond_waiters_t %d::%d", _getpid(), eventCount++);
- new->event = CreateEvent((LPSECURITY_ATTRIBUTES) 0, FALSE,
- FALSE, (LPCTSTR) eventName);
+ new->event = CreateEvent((LPSECURITY_ATTRIBUTES) 0, FALSE,
+ FALSE, (LPCTSTR) 0);
if (new->event == NULL) {
free(new);
new = NULL;
CloseHandle(reqHandle);
errno = CMtoUNIXerror(temp);
if ( IoctlDebug() )
- fprintf(stderr, "pioctl temp != 0: %d\r\n",temp);
+ fprintf(stderr, "pioctl temp != 0: 0x%X\r\n",temp);
return -1;
}