fresh git tree for public release
we regretfully had to remove our git history for licensing reasons Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
This commit is contained in:
commit
0ad4db4fad
271 changed files with 71255 additions and 0 deletions
107
README.html
Normal file
107
README.html
Normal file
|
|
@ -0,0 +1,107 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
|
<title>Windows NFS 4.1 Client Instructions</title>
|
||||||
|
<link rel="stylesheet" title="CITI Default" href="http://www.citi.umich.edu/format/citi.css" type="text/css"/>
|
||||||
|
<link rel="icon" href="http://www.citi.umich.edu/images/citilogo-16x16.png" type="image/png"/>
|
||||||
|
<link rel="shortcut icon" href="http://www.citi.umich.edu/images/citilogo-16x16.png" type="image/png"/>
|
||||||
|
<style type="text/css">
|
||||||
|
/*<![CDATA[*/
|
||||||
|
body { min-width: 600px; background-color: #DDDDFF; font-family: serif; }
|
||||||
|
#page { padding: 0 12px 0 12px; }
|
||||||
|
#content { margin: 12px 0 12px 0; padding: 8px; background-color: #FFFFFF; border: 1px solid #88A; }
|
||||||
|
#index { padding-right: 12px; float: right; background-color: #FFFFFF; border: 1px solid #88A; }
|
||||||
|
a { color: #0282b4; }
|
||||||
|
a:hover { color: #0244b4; }
|
||||||
|
h1 { font-size: 2em; text-align: center; background: none; }
|
||||||
|
h2 { margin: 24px 0 8px 0; font-variant: small-caps; border-bottom: 1px dashed #88A; }
|
||||||
|
h3 { margin-left: 8px; }
|
||||||
|
span.filename { font-weight: bold; }
|
||||||
|
span.code { font-family: Courier; }
|
||||||
|
/*]]>*/
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="page">
|
||||||
|
<h1>Windows NFS 4.1 Client Instructions</h1>
|
||||||
|
<div id="content">
|
||||||
|
<div id="index">
|
||||||
|
<ol>
|
||||||
|
<li><a href="#build">Building</a></li>
|
||||||
|
<li><a href="#install">Installation</a></li>
|
||||||
|
<li><a href="#mount">Mounting</a></li>
|
||||||
|
<li><a href="#cthon">Connectation</a></li>
|
||||||
|
<li><a href="#issues">Known Issues</a></li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
<h2>1. <a name="build">Building</a></h2>
|
||||||
|
<h3>Requirements</h3>
|
||||||
|
<ul>
|
||||||
|
<li>ms-nfs41-client source code:
|
||||||
|
<br/><span class="code">> git clone git://citi.umich.edu/projects/ms-nfs41-client.git</span></li>
|
||||||
|
<li>Windows Driver Development Kit (WinDDK 6000 or later)</li>
|
||||||
|
</ul>
|
||||||
|
<h3>Instructions</h3>
|
||||||
|
<ol>
|
||||||
|
<li>Open the WinDDK build environment for the target platform.</li>
|
||||||
|
<li>Change directory to <span class="filename">ms-nfs41-client</span> and type <span class="code">build</span>. The project should build without errors.</li>
|
||||||
|
</ol>
|
||||||
|
<h2>2. <a name="install">Installation</a></h2>
|
||||||
|
<h3>Requirements</h3>
|
||||||
|
<ul>
|
||||||
|
<li>ms-nfs41-client binaries: <span class="filename">nfs41_driver.sys</span>, <span class="filename">nfs41_np.dll</span>, <span class="filename">libtirpc.dll</span>, <span class="filename">nfs_install.exe</span>, <span class="filename">nfsd.exe</span>, <span class="filename">nfs_mount.exe</span></li>
|
||||||
|
<li>ms-nfs41-client configuration files: <span class="filename">nfs41rdr.inf</span>, <span class="filename">install.bat</span>, <span class="filename">uninstall.bat</span>, <span class="filename">etc_netconfig</span></li>
|
||||||
|
<li>a certificate for test signing (<a href="http://msdn.microsoft.com/en-us/library/aa906283.aspx" title="Test-Signing a Driver File">http://msdn.microsoft.com/en-us/library/aa906283.aspx</a>)</li>
|
||||||
|
</ul>
|
||||||
|
<h3>Instructions</h3>
|
||||||
|
<ol>
|
||||||
|
<li>Copy or extract all ms-nfs41-client binaries and configuration files into a directory that's convenient for testing.</li>
|
||||||
|
<li>Open an Administrator command prompt in this directory.</li>
|
||||||
|
<li>Test sign <span class="filename">nfs41_driver.sys</span>.</li>
|
||||||
|
<li>Install the driver and update the registry:
|
||||||
|
<br/><span class="code">> install.bat</span></li>
|
||||||
|
<li>Copy the libtirpc configuration:
|
||||||
|
<br/><span class="code">> mkdir C:\etc</span>
|
||||||
|
<br/><span class="code">> copy etc_netconfig C:\etc\netconfig</span></li>
|
||||||
|
<li>Allow windows to load test-signed drivers:
|
||||||
|
<br/><span class="code">> bcdedit /set testsigning on</span></li>
|
||||||
|
<li>Install the certificate used for test signing to the 'Trusted Root Certificate Authorities' store.</li>
|
||||||
|
<li>Open the Control Panel, navigate to User Accounts, and disable User Account Control (see <a href="#issues">5. Known Issues</a>).</li>
|
||||||
|
<li>Reboot.</li>
|
||||||
|
</ol>
|
||||||
|
<h2>3. <a name="mount">Mounting</a></h2>
|
||||||
|
<h3>Instructions</h3>
|
||||||
|
<ol>
|
||||||
|
<li>Run <span class="filename">nfsd.exe</span></li>
|
||||||
|
<li>Open a command prompt and run <span class="filename">nfs_mount.exe</span> to mount a share:
|
||||||
|
<br/><span class="code">> nfs_mount.exe Z: nfs.citi.umich.edu:\</span></li>
|
||||||
|
<li>You can later unmount with:
|
||||||
|
<br/><span class="code">> nfs_mount.exe -d Z</span></li>
|
||||||
|
</ol>
|
||||||
|
<h2>4. <a name="cthon">Connectathon</a></h2>
|
||||||
|
<h3>Requirements</h3>
|
||||||
|
<ul>
|
||||||
|
<li><a href="http://www.cygwin.com" title="www.cygwin.com">Cygwin</a>, including packages gcc-core, make, sunrpc, time</li>
|
||||||
|
<li>ms-nfs41-client source code (ported tests are located in <span class="filename">ms-nfs41-client\tests\cthon04</span>)</li>
|
||||||
|
</ul>
|
||||||
|
<h3>Instructions</h3>
|
||||||
|
<ol>
|
||||||
|
<li>Copy <span class="filename">ms-nfs41-client\tests\cthon04</span> into a directory that's convenient for testing.</li>
|
||||||
|
<li>Open a cygwin shell, and change directory to cthon04.</li>
|
||||||
|
<li>Run the test suite on a mounted directory:
|
||||||
|
<br/><span class="code">> ./runtests -a -t z:/testdir</span></li>
|
||||||
|
</ol>
|
||||||
|
<h2>5. <a name="issues">Known Issues</a></h2>
|
||||||
|
<ul>
|
||||||
|
<li>Mounts must be obtained through nfs_mount.exe, and not via 'net use' or 'Map Network Drive'.</li>
|
||||||
|
<li>When nfs_mount.exe is run without arguments, it does not properly list mounted drives.</li>
|
||||||
|
<li>If nfsd.exe is restarted while a drive is mapped, that drive needs to be remounted before further use.</li>
|
||||||
|
<li>Symbolic links are not supported. Connectathon's basic test8 will not pass.</li>
|
||||||
|
<li>Does not properly handle renaming a file on top of an existing open file- the existing file is removed on rename, and not preserved until last close.</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
7
build.vc10/.gitignore
vendored
Normal file
7
build.vc10/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
# exclude all build files by default
|
||||||
|
*
|
||||||
|
|
||||||
|
# allow visual studio project and solution files
|
||||||
|
!*.vcxproj
|
||||||
|
!*.vcxproj.filters
|
||||||
|
!*.sln
|
||||||
254
build.vc10/daemon.vcxproj
Normal file
254
build.vc10/daemon.vcxproj
Normal file
|
|
@ -0,0 +1,254 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{D0D81A98-2946-4A16-A4A1-800387C3F3D1}</ProjectGuid>
|
||||||
|
<RootNamespace>daemon</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="env.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="env.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="env.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="env.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
||||||
|
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||||
|
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||||
|
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
|
||||||
|
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
|
||||||
|
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||||
|
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||||
|
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
|
||||||
|
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
|
||||||
|
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">nfsd</TargetName>
|
||||||
|
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">nfsd</TargetName>
|
||||||
|
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">nfsd</TargetName>
|
||||||
|
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">nfsd</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalOptions>/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<AdditionalIncludeDirectories>..\sys;..\xdr;..\dll;..\libtirpc\tirpc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
|
<ExceptionHandling>
|
||||||
|
</ExceptionHandling>
|
||||||
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||||
|
<WarningLevel>Level4</WarningLevel>
|
||||||
|
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||||
|
<CompileAs>CompileAsC</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Midl>
|
||||||
|
<TargetEnvironment>X64</TargetEnvironment>
|
||||||
|
</Midl>
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalOptions>/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<AdditionalIncludeDirectories>..\sys;..\xdr;..\dll;..\libtirpc\tirpc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
|
<ExceptionHandling>
|
||||||
|
</ExceptionHandling>
|
||||||
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||||
|
<WarningLevel>Level4</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<CompileAs>CompileAsC</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<TargetMachine>MachineX64</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalOptions>/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<AdditionalIncludeDirectories>..\sys;..\xdr;..\dll;..\libtirpc\tirpc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ExceptionHandling>
|
||||||
|
</ExceptionHandling>
|
||||||
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||||
|
<WarningLevel>Level4</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<CompileAs>CompileAsC</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Midl>
|
||||||
|
<TargetEnvironment>X64</TargetEnvironment>
|
||||||
|
</Midl>
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalOptions>/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<AdditionalIncludeDirectories>..\sys;..\xdr;..\dll;..\libtirpc\tirpc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>WIN32_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ExceptionHandling>
|
||||||
|
</ExceptionHandling>
|
||||||
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||||
|
<WarningLevel>Level4</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<CompileAs>CompileAsC</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<TargetMachine>MachineX64</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\daemon\callback_xdr.c" />
|
||||||
|
<ClCompile Include="..\daemon\callback_server.c" />
|
||||||
|
<ClCompile Include="..\daemon\daemon_debug.c" />
|
||||||
|
<ClCompile Include="..\daemon\getattr.c" />
|
||||||
|
<ClCompile Include="..\daemon\lock.c" />
|
||||||
|
<ClCompile Include="..\daemon\lookup.c" />
|
||||||
|
<ClCompile Include="..\daemon\mount.c" />
|
||||||
|
<ClCompile Include="..\daemon\namespace.c" />
|
||||||
|
<ClCompile Include="..\daemon\name_cache.c" />
|
||||||
|
<ClCompile Include="..\daemon\nfs41_client.c" />
|
||||||
|
<ClCompile Include="..\daemon\nfs41_compound.c" />
|
||||||
|
<ClCompile Include="..\daemon\nfs41_daemon.c" />
|
||||||
|
<ClCompile Include="..\daemon\nfs41_ops.c" />
|
||||||
|
<ClCompile Include="..\daemon\nfs41_rpc.c" />
|
||||||
|
<ClCompile Include="..\daemon\nfs41_server.c" />
|
||||||
|
<ClCompile Include="..\daemon\nfs41_session.c" />
|
||||||
|
<ClCompile Include="..\daemon\nfs41_superblock.c" />
|
||||||
|
<ClCompile Include="..\daemon\nfs41_xdr.c" />
|
||||||
|
<ClCompile Include="..\daemon\open.c" />
|
||||||
|
<ClCompile Include="..\daemon\pnfs_debug.c" />
|
||||||
|
<ClCompile Include="..\daemon\pnfs_device.c" />
|
||||||
|
<ClCompile Include="..\daemon\pnfs_io.c" />
|
||||||
|
<ClCompile Include="..\daemon\pnfs_layout.c" />
|
||||||
|
<ClCompile Include="..\daemon\rbtree.c" />
|
||||||
|
<ClCompile Include="..\daemon\readdir.c" />
|
||||||
|
<ClCompile Include="..\daemon\readwrite.c" />
|
||||||
|
<ClCompile Include="..\daemon\setattr.c" />
|
||||||
|
<ClCompile Include="..\daemon\upcall.c" />
|
||||||
|
<ClCompile Include="..\daemon\util.c" />
|
||||||
|
<ClCompile Include="..\daemon\volume.c" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\daemon\daemon_debug.h" />
|
||||||
|
<ClInclude Include="..\daemon\from_kernel.h" />
|
||||||
|
<ClInclude Include="..\daemon\list.h" />
|
||||||
|
<ClInclude Include="..\daemon\name_cache.h" />
|
||||||
|
<ClInclude Include="..\daemon\nfs41.h" />
|
||||||
|
<ClInclude Include="..\daemon\nfs41_callback.h" />
|
||||||
|
<ClInclude Include="..\daemon\nfs41_compound.h" />
|
||||||
|
<ClInclude Include="..\daemon\nfs41_const.h" />
|
||||||
|
<ClInclude Include="..\daemon\nfs41_ops.h" />
|
||||||
|
<ClInclude Include="..\daemon\nfs41_types.h" />
|
||||||
|
<ClInclude Include="..\daemon\nfs41_xdr.h" />
|
||||||
|
<ClInclude Include="..\daemon\pnfs.h" />
|
||||||
|
<ClInclude Include="..\daemon\rbtree.h" />
|
||||||
|
<ClInclude Include="..\daemon\upcall.h" />
|
||||||
|
<ClInclude Include="..\daemon\util.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="..\daemon\sources" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="libtirpc.vcxproj">
|
||||||
|
<Project>{2d918a9b-de52-470a-93d5-78ea2c8113a1}</Project>
|
||||||
|
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
160
build.vc10/daemon.vcxproj.filters
Normal file
160
build.vc10/daemon.vcxproj.filters
Normal file
|
|
@ -0,0 +1,160 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Source Files">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resource Files">
|
||||||
|
<UniqueIdentifier>{b39281cd-23c6-401e-844b-3d6c763da90b}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\daemon\daemon_debug.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\daemon\getattr.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\daemon\lock.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\daemon\mount.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\daemon\nfs41_client.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\daemon\nfs41_compound.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\daemon\nfs41_daemon.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\daemon\nfs41_ops.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\daemon\nfs41_rpc.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\daemon\nfs41_server.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\daemon\nfs41_session.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\daemon\nfs41_superblock.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\daemon\nfs41_xdr.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\daemon\open.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\daemon\pnfs_debug.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\daemon\pnfs_device.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\daemon\pnfs_layout.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\daemon\readdir.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\daemon\readwrite.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\daemon\setattr.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\daemon\upcall.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\daemon\util.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\daemon\pnfs_io.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\daemon\lookup.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\daemon\rbtree.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\daemon\name_cache.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\daemon\namespace.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\daemon\volume.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\daemon\callback_server.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\daemon\callback_xdr.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\daemon\daemon_debug.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\daemon\from_kernel.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\daemon\nfs41.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\daemon\nfs41_compound.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\daemon\nfs41_const.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\daemon\nfs41_ops.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\daemon\nfs41_types.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\daemon\nfs41_xdr.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\daemon\pnfs.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\daemon\upcall.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\daemon\util.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\daemon\list.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\daemon\rbtree.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\daemon\name_cache.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\daemon\nfs41_callback.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="..\daemon\sources">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
208
build.vc10/dll.vcxproj
Normal file
208
build.vc10/dll.vcxproj
Normal file
|
|
@ -0,0 +1,208 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{372D9D02-CDC5-43AE-BB0A-FB57CEFC639C}</ProjectGuid>
|
||||||
|
<RootNamespace>dll</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="env.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="env.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="env.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="env.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
||||||
|
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||||
|
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||||
|
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
|
||||||
|
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
|
||||||
|
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||||
|
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||||
|
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
|
||||||
|
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalOptions>/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<AdditionalIncludeDirectories>..\sys;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>UNICODE;_UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
|
<ExceptionHandling>
|
||||||
|
</ExceptionHandling>
|
||||||
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||||
|
<WarningLevel>Level4</WarningLevel>
|
||||||
|
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||||
|
<CompileAs>CompileAsC</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<OutputFile>$(OutDir)nfs41_np.dll</OutputFile>
|
||||||
|
<ModuleDefinitionFile>..\dll\nfs41_np.def</ModuleDefinitionFile>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<BaseAddress>0x1010000</BaseAddress>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Midl>
|
||||||
|
<TargetEnvironment>X64</TargetEnvironment>
|
||||||
|
</Midl>
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalOptions>/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<AdditionalIncludeDirectories>..\sys;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>UNICODE;_UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
|
<ExceptionHandling>
|
||||||
|
</ExceptionHandling>
|
||||||
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||||
|
<WarningLevel>Level4</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<CompileAs>CompileAsC</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<OutputFile>$(OutDir)nfs41_np.dll</OutputFile>
|
||||||
|
<ModuleDefinitionFile>..\dll\nfs41_np.def</ModuleDefinitionFile>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<BaseAddress>0x1010000</BaseAddress>
|
||||||
|
<TargetMachine>MachineX64</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalOptions>/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<AdditionalIncludeDirectories>..\sys;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>UNICODE;_UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ExceptionHandling>
|
||||||
|
</ExceptionHandling>
|
||||||
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||||
|
<WarningLevel>Level4</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<CompileAs>CompileAsC</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<OutputFile>$(OutDir)nfs41_np.dll</OutputFile>
|
||||||
|
<ModuleDefinitionFile>..\dll\nfs41_np.def</ModuleDefinitionFile>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<BaseAddress>0x1010000</BaseAddress>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Midl>
|
||||||
|
<TargetEnvironment>X64</TargetEnvironment>
|
||||||
|
</Midl>
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalOptions>/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<AdditionalIncludeDirectories>..\sys;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>UNICODE;_UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ExceptionHandling>
|
||||||
|
</ExceptionHandling>
|
||||||
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||||
|
<WarningLevel>Level4</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<CompileAs>CompileAsC</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<OutputFile>$(OutDir)nfs41_np.dll</OutputFile>
|
||||||
|
<ModuleDefinitionFile>..\dll\nfs41_np.def</ModuleDefinitionFile>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<BaseAddress>0x1010000</BaseAddress>
|
||||||
|
<TargetMachine>MachineX64</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\dll\dllmain.c" />
|
||||||
|
<ClCompile Include="..\dll\nfs41_np.c" />
|
||||||
|
<ClCompile Include="..\dll\options.c" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\dll\nfs41_np.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="..\dll\nfs41_np.def" />
|
||||||
|
<None Include="..\dll\sources" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
41
build.vc10/dll.vcxproj.filters
Normal file
41
build.vc10/dll.vcxproj.filters
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Source Files">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resource Files">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\dll\dllmain.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\dll\nfs41_np.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\dll\options.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\dll\nfs41_np.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="..\dll\nfs41_np.def">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="..\dll\sources">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
20
build.vc10/env.props.example
Normal file
20
build.vc10/env.props.example
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup Label="UserMacros">
|
||||||
|
<WDKPATH>C:\WinDDK\7600.16385.0</WDKPATH>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||||
|
<_PropertySheetDisplayName>ddk_env</_PropertySheetDisplayName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup>
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalIncludeDirectories>$(WDKPATH)\inc\ddk;$(WDKPATH)\inc\api;$(WDKPATH)\inc\crt;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<BuildMacro Include="WDKPATH">
|
||||||
|
<Value>$(WDKPATH)</Value>
|
||||||
|
</BuildMacro>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
308
build.vc10/libtirpc.vcxproj
Normal file
308
build.vc10/libtirpc.vcxproj
Normal file
|
|
@ -0,0 +1,308 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{2D918A9B-DE52-470A-93D5-78EA2C8113A1}</ProjectGuid>
|
||||||
|
<RootNamespace>libtirpc</RootNamespace>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
||||||
|
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
||||||
|
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
||||||
|
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
||||||
|
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
|
||||||
|
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||||
|
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||||
|
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
|
||||||
|
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
|
||||||
|
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||||
|
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||||
|
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
|
||||||
|
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<AdditionalIncludeDirectories>..\libtirpc\tirpc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>INET6;FD_SETSIZE=128;PORTMAP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<ModuleDefinitionFile>..\libtirpc\libtirpc\libtirpc.def</ModuleDefinitionFile>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Midl>
|
||||||
|
<TargetEnvironment>X64</TargetEnvironment>
|
||||||
|
</Midl>
|
||||||
|
<ClCompile>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<AdditionalIncludeDirectories>..\libtirpc\tirpc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>INET6;FD_SETSIZE=128;PORTMAP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<ModuleDefinitionFile>..\libtirpc\libtirpc\libtirpc.def</ModuleDefinitionFile>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<EntryPointSymbol>
|
||||||
|
</EntryPointSymbol>
|
||||||
|
<TargetMachine>MachineX64</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<AdditionalIncludeDirectories>..\libtirpc\tirpc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>INET6;FD_SETSIZE=128;PORTMAP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<ModuleDefinitionFile>..\libtirpc\libtirpc\libtirpc.def</ModuleDefinitionFile>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Midl>
|
||||||
|
<TargetEnvironment>X64</TargetEnvironment>
|
||||||
|
</Midl>
|
||||||
|
<ClCompile>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<AdditionalIncludeDirectories>..\libtirpc\tirpc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>INET6;FD_SETSIZE=128;PORTMAP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<PrecompiledHeader>
|
||||||
|
</PrecompiledHeader>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<ModuleDefinitionFile>..\libtirpc\libtirpc\libtirpc.def</ModuleDefinitionFile>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<EntryPointSymbol>
|
||||||
|
</EntryPointSymbol>
|
||||||
|
<TargetMachine>MachineX64</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\libtirpc\src\asprintf.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\auth_none.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\auth_time.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\auth_unix.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\authunix_prot.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\bindresvport.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\clnt_bcast.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\clnt_dg.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\clnt_generic.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\clnt_perror.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\clnt_raw.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\clnt_simple.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\clnt_vc.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\des_soft.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\epoll_sub.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\getnetconfig.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\getnetpath.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\getpeereid.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\getpublickey.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\getrpcent.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\getrpcport.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\gettimeofday.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\key_call.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\key_prot_xdr.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\mt_misc.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\netname.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\netnamer.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\pmap_clnt.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\pmap_getmaps.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\pmap_getport.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\pmap_prot.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\pmap_prot2.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\pmap_rmt.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\rpc_callmsg.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\rpc_commondata.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\rpc_dtablesize.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\rpc_generic.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\rpc_prot.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\rpc_soc.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\rpcb_clnt.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\rpcb_prot.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\rpcb_st_xdr.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\rpcdname.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\rtime.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\svc.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\svc_auth.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\svc_auth_none.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\svc_auth_unix.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\svc_dg.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\svc_generic.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\svc_raw.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\svc_run.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\svc_simple.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\svc_vc.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\winstubs.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\wintirpc.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\xdr.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\xdr_array.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\xdr_float.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\xdr_mem.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\xdr_rec.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\xdr_reference.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\xdr_sizeof.c" />
|
||||||
|
<ClCompile Include="..\libtirpc\src\xdr_stdio.c" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\libtirpc\src\rpc_com.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\auth.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\auth_des.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\auth_gss.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\auth_kerb.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\auth_unix.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\clnt.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\clnt_soc.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\clnt_stat.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpcsvc\crypt.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\des.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\des_crypt.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\misc\event.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\fpmath.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\getpeereid.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\libc_private.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\namespace.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\netconfig.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\nettype.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpcsvc\nis.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\nss_tls.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\pmap_clnt.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\pmap_prot.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\pmap_rmt.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\sys\queue.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\misc\queue.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\raw.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\reentrant.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\rpc.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\rpc_com.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\rpc_msg.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\rpcb_clnt.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\rpcb_prot.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\rpcent.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\misc\socket.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\spinlock.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\svc.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\svc_auth.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\svc_dg.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\svc_soc.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\types.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\un-namespace.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\wintirpc.h" />
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\xdr.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="..\libtirpc\libtirpc\libtirpc.rc" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="..\libtirpc\libtirpc\libtirpc.def" />
|
||||||
|
<None Include="..\libtirpc\src\sources" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
358
build.vc10/libtirpc.vcxproj.filters
Normal file
358
build.vc10/libtirpc.vcxproj.filters
Normal file
|
|
@ -0,0 +1,358 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Source Files">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resource Files">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\libtirpc\src\asprintf.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\auth_none.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\auth_time.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\auth_unix.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\authunix_prot.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\bindresvport.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\clnt_bcast.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\clnt_dg.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\clnt_generic.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\clnt_perror.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\clnt_raw.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\clnt_simple.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\clnt_vc.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\des_soft.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\epoll_sub.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\getnetconfig.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\getnetpath.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\getpeereid.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\getpublickey.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\getrpcent.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\getrpcport.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\gettimeofday.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\key_call.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\key_prot_xdr.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\mt_misc.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\netname.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\netnamer.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\pmap_clnt.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\pmap_getmaps.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\pmap_getport.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\pmap_prot.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\pmap_prot2.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\pmap_rmt.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\rpc_callmsg.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\rpc_commondata.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\rpc_dtablesize.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\rpc_generic.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\rpc_prot.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\rpc_soc.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\rpcb_clnt.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\rpcb_prot.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\rpcb_st_xdr.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\rpcdname.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\rtime.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\svc.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\svc_auth.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\svc_auth_none.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\svc_auth_unix.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\svc_dg.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\svc_generic.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\svc_raw.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\svc_run.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\svc_simple.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\svc_vc.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\winstubs.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\wintirpc.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\xdr.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\xdr_array.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\xdr_float.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\xdr_mem.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\xdr_rec.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\xdr_reference.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\xdr_sizeof.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\libtirpc\src\xdr_stdio.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\libtirpc\src\rpc_com.h">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\auth.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\auth_des.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\auth_gss.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\auth_kerb.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\auth_unix.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\clnt.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\clnt_soc.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\clnt_stat.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpcsvc\crypt.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\des.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\des_crypt.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\misc\event.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\fpmath.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\getpeereid.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\libc_private.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\namespace.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\netconfig.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\nettype.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpcsvc\nis.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\nss_tls.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\pmap_clnt.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\pmap_prot.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\pmap_rmt.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\sys\queue.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\misc\queue.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\raw.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\reentrant.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\rpc.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\rpc_com.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\rpc_msg.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\rpcb_clnt.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\rpcb_prot.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\rpcent.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\misc\socket.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\spinlock.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\svc.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\svc_auth.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\svc_dg.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\svc_soc.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\types.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\un-namespace.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\wintirpc.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\libtirpc\tirpc\rpc\xdr.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="..\libtirpc\libtirpc\libtirpc.rc">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</ResourceCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="..\libtirpc\src\sources">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="..\libtirpc\libtirpc\libtirpc.def">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
187
build.vc10/mount.vcxproj
Normal file
187
build.vc10/mount.vcxproj
Normal file
|
|
@ -0,0 +1,187 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{5AEA3497-6852-471B-A252-ADA60B22A342}</ProjectGuid>
|
||||||
|
<RootNamespace>mount</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
||||||
|
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||||
|
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||||
|
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
|
||||||
|
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
|
||||||
|
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||||
|
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||||
|
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
|
||||||
|
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalOptions>/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<AdditionalIncludeDirectories>..\sys;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
|
<ExceptionHandling>
|
||||||
|
</ExceptionHandling>
|
||||||
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
<WarningLevel>Level4</WarningLevel>
|
||||||
|
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||||
|
<CompileAs>CompileAsC</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>mpr.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalOptions>/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<AdditionalIncludeDirectories>..\sys;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<ExceptionHandling>
|
||||||
|
</ExceptionHandling>
|
||||||
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<WarningLevel>Level4</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<CompileAs>CompileAsC</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>mpr.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Midl>
|
||||||
|
<TargetEnvironment>X64</TargetEnvironment>
|
||||||
|
</Midl>
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalOptions>/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<AdditionalIncludeDirectories>..\sys;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
|
<ExceptionHandling>
|
||||||
|
</ExceptionHandling>
|
||||||
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
<WarningLevel>Level4</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<CompileAs>CompileAsC</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>mpr.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<TargetMachine>MachineX64</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Midl>
|
||||||
|
<TargetEnvironment>X64</TargetEnvironment>
|
||||||
|
</Midl>
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalOptions>/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<AdditionalIncludeDirectories>..\sys;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<ExceptionHandling>
|
||||||
|
</ExceptionHandling>
|
||||||
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<WarningLevel>Level4</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<CompileAs>CompileAsC</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>mpr.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<TargetMachine>MachineX64</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\mount\enum.c" />
|
||||||
|
<ClCompile Include="..\mount\mount.c" />
|
||||||
|
<ClCompile Include="..\mount\options.c" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\mount\options.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="..\mount\sources" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
38
build.vc10/mount.vcxproj.filters
Normal file
38
build.vc10/mount.vcxproj.filters
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Source Files">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resource Files">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\mount\enum.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\mount\mount.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\mount\options.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\mount\options.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="..\mount\sources">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
76
build.vc10/ms-nfs41-client.sln
Normal file
76
build.vc10/ms-nfs41-client.sln
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||||
|
# Visual Studio 2010
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "daemon", "daemon.vcxproj", "{D0D81A98-2946-4A16-A4A1-800387C3F3D1}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dll", "dll.vcxproj", "{372D9D02-CDC5-43AE-BB0A-FB57CEFC639C}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nfs41_driver", "nfs41_driver.vcxproj", "{B64D3074-519F-476A-A3AA-DAD6554CBB68}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mount", "mount.vcxproj", "{5AEA3497-6852-471B-A252-ADA60B22A342}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libtirpc", "libtirpc.vcxproj", "{2D918A9B-DE52-470A-93D5-78EA2C8113A1}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nfs_install", "nfs_install.vcxproj", "{A453DC17-BE6B-4271-A020-66E054AB5908}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Win32 = Debug|Win32
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Release|Win32 = Release|Win32
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{D0D81A98-2946-4A16-A4A1-800387C3F3D1}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{D0D81A98-2946-4A16-A4A1-800387C3F3D1}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{D0D81A98-2946-4A16-A4A1-800387C3F3D1}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{D0D81A98-2946-4A16-A4A1-800387C3F3D1}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{D0D81A98-2946-4A16-A4A1-800387C3F3D1}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{D0D81A98-2946-4A16-A4A1-800387C3F3D1}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{D0D81A98-2946-4A16-A4A1-800387C3F3D1}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{D0D81A98-2946-4A16-A4A1-800387C3F3D1}.Release|x64.Build.0 = Release|x64
|
||||||
|
{372D9D02-CDC5-43AE-BB0A-FB57CEFC639C}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{372D9D02-CDC5-43AE-BB0A-FB57CEFC639C}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{372D9D02-CDC5-43AE-BB0A-FB57CEFC639C}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{372D9D02-CDC5-43AE-BB0A-FB57CEFC639C}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{372D9D02-CDC5-43AE-BB0A-FB57CEFC639C}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{372D9D02-CDC5-43AE-BB0A-FB57CEFC639C}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{372D9D02-CDC5-43AE-BB0A-FB57CEFC639C}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{372D9D02-CDC5-43AE-BB0A-FB57CEFC639C}.Release|x64.Build.0 = Release|x64
|
||||||
|
{B64D3074-519F-476A-A3AA-DAD6554CBB68}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{B64D3074-519F-476A-A3AA-DAD6554CBB68}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{B64D3074-519F-476A-A3AA-DAD6554CBB68}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{B64D3074-519F-476A-A3AA-DAD6554CBB68}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{B64D3074-519F-476A-A3AA-DAD6554CBB68}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{B64D3074-519F-476A-A3AA-DAD6554CBB68}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{B64D3074-519F-476A-A3AA-DAD6554CBB68}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{B64D3074-519F-476A-A3AA-DAD6554CBB68}.Release|x64.Build.0 = Release|x64
|
||||||
|
{5AEA3497-6852-471B-A252-ADA60B22A342}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{5AEA3497-6852-471B-A252-ADA60B22A342}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{5AEA3497-6852-471B-A252-ADA60B22A342}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{5AEA3497-6852-471B-A252-ADA60B22A342}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{5AEA3497-6852-471B-A252-ADA60B22A342}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{5AEA3497-6852-471B-A252-ADA60B22A342}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{5AEA3497-6852-471B-A252-ADA60B22A342}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{5AEA3497-6852-471B-A252-ADA60B22A342}.Release|x64.Build.0 = Release|x64
|
||||||
|
{2D918A9B-DE52-470A-93D5-78EA2C8113A1}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{2D918A9B-DE52-470A-93D5-78EA2C8113A1}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{2D918A9B-DE52-470A-93D5-78EA2C8113A1}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{2D918A9B-DE52-470A-93D5-78EA2C8113A1}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{2D918A9B-DE52-470A-93D5-78EA2C8113A1}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{2D918A9B-DE52-470A-93D5-78EA2C8113A1}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{2D918A9B-DE52-470A-93D5-78EA2C8113A1}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{2D918A9B-DE52-470A-93D5-78EA2C8113A1}.Release|x64.Build.0 = Release|x64
|
||||||
|
{A453DC17-BE6B-4271-A020-66E054AB5908}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{A453DC17-BE6B-4271-A020-66E054AB5908}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{A453DC17-BE6B-4271-A020-66E054AB5908}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{A453DC17-BE6B-4271-A020-66E054AB5908}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{A453DC17-BE6B-4271-A020-66E054AB5908}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{A453DC17-BE6B-4271-A020-66E054AB5908}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{A453DC17-BE6B-4271-A020-66E054AB5908}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{A453DC17-BE6B-4271-A020-66E054AB5908}.Release|x64.Build.0 = Release|x64
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
148
build.vc10/nfs41_driver.vcxproj
Normal file
148
build.vc10/nfs41_driver.vcxproj
Normal file
|
|
@ -0,0 +1,148 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{B64D3074-519F-476A-A3AA-DAD6554CBB68}</ProjectGuid>
|
||||||
|
<Keyword>MakeFileProj</Keyword>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Makefile</ConfigurationType>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Makefile</ConfigurationType>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Makefile</ConfigurationType>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Makefile</ConfigurationType>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="env.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="env.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="env.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
<Import Project="env.props" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">C:\projects\ms-nfs41-client\sys\objchk_wlh_x86\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">C:\projects\ms-nfs41-client\sys\objchk_wlh_x86\</IntDir>
|
||||||
|
<NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">call $(WDKPATH)\bin\setenv.bat $(WDKPATH) chk x86 wlh
|
||||||
|
cd /d C:\projects\ms-nfs41-client\sys
|
||||||
|
build</NMakeBuildCommandLine>
|
||||||
|
<NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">rmdir /s /q C:\projects\ms-nfs41-client\sys\objchk_wlh_x86
|
||||||
|
call $(WDKPATH)\bin\setenv.bat $(WDKPATH) chk x86 wlh
|
||||||
|
cd /d C:\projects\ms-nfs41-client\sys
|
||||||
|
build</NMakeReBuildCommandLine>
|
||||||
|
<NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">rmdir /s /q C:\projects\ms-nfs41-client\sys\objchk_wlh_x86</NMakeCleanCommandLine>
|
||||||
|
<NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">C:\projects\ms-nfs41-client\sys\objchk_wlh_x86\i386\nfs41_driver.sys</NMakeOutput>
|
||||||
|
<NMakePreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">WIN32;_CONSOLE;_X86_;_DDK_;_DEBUG;DBG=1;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
|
||||||
|
<NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(WDKPATH)\inc\ddk;$(WDKPATH)\inc\api;$(WDKPATH)\inc\crt;$(NMakeIncludeSearchPath)</NMakeIncludeSearchPath>
|
||||||
|
<NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(NMakeForcedIncludes)</NMakeForcedIncludes>
|
||||||
|
<NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(NMakeAssemblySearchPath)</NMakeAssemblySearchPath>
|
||||||
|
<NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(NMakeForcedUsingAssemblies)</NMakeForcedUsingAssemblies>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">C:\projects\ms-nfs41-client\sys\objchk_wlh_amd64\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">C:\projects\ms-nfs41-client\sys\objchk_wlh_amd64\</IntDir>
|
||||||
|
<NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">call $(WDKPATH)\bin\setenv.bat $(WDKPATH) chk x64 wlh
|
||||||
|
cd /d C:\projects\ms-nfs41-client\sys
|
||||||
|
build</NMakeBuildCommandLine>
|
||||||
|
<NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">rmdir /s /q C:\projects\ms-nfs41-client\sys\objchk_wlh_amd64
|
||||||
|
call $(WDKPATH)\bin\setenv.bat $(WDKPATH) chk x64 wlh
|
||||||
|
cd /d C:\projects\ms-nfs41-client\sys
|
||||||
|
build</NMakeReBuildCommandLine>
|
||||||
|
<NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">rmdir /s /q C:\projects\ms-nfs41-client\sys\objchk_wlh_amd64</NMakeCleanCommandLine>
|
||||||
|
<NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">C:\projects\ms-nfs41-client\sys\objchk_wlh_amd64\amd64\nfs41_driver.sys</NMakeOutput>
|
||||||
|
<NMakePreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WIN32;_CONSOLE;_AMD64_;_DDK_;_DEBUG;DBG=1;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
|
||||||
|
<NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(WDKPATH)\inc\ddk;$(WDKPATH)\inc\api;$(WDKPATH)\inc\crt;$(NMakeIncludeSearchPath)</NMakeIncludeSearchPath>
|
||||||
|
<NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(NMakeForcedIncludes)</NMakeForcedIncludes>
|
||||||
|
<NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(NMakeAssemblySearchPath)</NMakeAssemblySearchPath>
|
||||||
|
<NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(NMakeForcedUsingAssemblies)</NMakeForcedUsingAssemblies>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">C:\projects\ms-nfs41-client\sys\objfre_wlh_x86\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">C:\projects\ms-nfs41-client\sys\objfre_wlh_x86\</IntDir>
|
||||||
|
<NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">call $(WDKPATH)\bin\setenv.bat $(WDKPATH) fre x86 wlh
|
||||||
|
cd /d C:\projects\ms-nfs41-client\sys
|
||||||
|
build</NMakeBuildCommandLine>
|
||||||
|
<NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">rmdir /s /q C:\projects\ms-nfs41-client\sys\objfre_wlh_x86
|
||||||
|
call $(WDKPATH)\bin\setenv.bat $(WDKPATH) fre x86 wlh
|
||||||
|
cd /d C:\projects\ms-nfs41-client\sys
|
||||||
|
build</NMakeReBuildCommandLine>
|
||||||
|
<NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">rmdir /s /q C:\projects\ms-nfs41-client\sys\objfre_wlh_x86</NMakeCleanCommandLine>
|
||||||
|
<NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">C:\projects\ms-nfs41-client\sys\objfre_wlh_x86\i386\nfs41_driver.sys</NMakeOutput>
|
||||||
|
<NMakePreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">WIN32;_CONSOLE;_X86_;_DDK_;_NDEBUG;DBG=0;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
|
||||||
|
<NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(WDKPATH)\inc\ddk;$(WDKPATH)\inc\api;$(WDKPATH)\inc\crt;$(NMakeIncludeSearchPath)</NMakeIncludeSearchPath>
|
||||||
|
<NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(NMakeForcedIncludes)</NMakeForcedIncludes>
|
||||||
|
<NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(NMakeAssemblySearchPath)</NMakeAssemblySearchPath>
|
||||||
|
<NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(NMakeForcedUsingAssemblies)</NMakeForcedUsingAssemblies>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">C:\projects\ms-nfs41-client\sys\objfre_wlh_amd64\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">C:\projects\ms-nfs41-client\sys\objfre_wlh_amd64\</IntDir>
|
||||||
|
<NMakeBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|x64'">call $(WDKPATH)\bin\setenv.bat $(WDKPATH) fre x64 wlh
|
||||||
|
cd /d C:\projects\ms-nfs41-client\sys
|
||||||
|
build</NMakeBuildCommandLine>
|
||||||
|
<NMakeReBuildCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|x64'">rmdir /s /q C:\projects\ms-nfs41-client\sys\objfre_wlh_amd64
|
||||||
|
call $(WDKPATH)\bin\setenv.bat $(WDKPATH) fre x64 wlh
|
||||||
|
cd /d C:\projects\ms-nfs41-client\sys
|
||||||
|
build</NMakeReBuildCommandLine>
|
||||||
|
<NMakeCleanCommandLine Condition="'$(Configuration)|$(Platform)'=='Release|x64'">rmdir /s /q C:\projects\ms-nfs41-client\sys\objfre_wlh_amd64</NMakeCleanCommandLine>
|
||||||
|
<NMakeOutput Condition="'$(Configuration)|$(Platform)'=='Release|x64'">C:\projects\ms-nfs41-client\sys\objfre_wlh_amd64\amd64\nfs41_driver.sys</NMakeOutput>
|
||||||
|
<NMakePreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">WIN32;_CONSOLE;_AMD64_;_DDK_;_NDEBUG;DBG=0;$(NMakePreprocessorDefinitions)</NMakePreprocessorDefinitions>
|
||||||
|
<NMakeIncludeSearchPath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(WDKPATH)\inc\ddk;$(WDKPATH)\inc\api;$(WDKPATH)\inc\crt;$(NMakeIncludeSearchPath)</NMakeIncludeSearchPath>
|
||||||
|
<NMakeForcedIncludes Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(NMakeForcedIncludes)</NMakeForcedIncludes>
|
||||||
|
<NMakeAssemblySearchPath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(NMakeAssemblySearchPath)</NMakeAssemblySearchPath>
|
||||||
|
<NMakeForcedUsingAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(NMakeForcedUsingAssemblies)</NMakeForcedUsingAssemblies>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\sys\nfs41_debug.c" />
|
||||||
|
<ClCompile Include="..\sys\nfs41_driver.c" />
|
||||||
|
<ClCompile Include="..\sys\wmlkm.c" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="..\sys\makefile" />
|
||||||
|
<None Include="..\sys\nfs41_driver.ini" />
|
||||||
|
<None Include="..\sys\sources" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="..\sys\nfs41_driver.rc" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\sys\nfs41_debug.h" />
|
||||||
|
<ClInclude Include="..\sys\nfs41_driver.h" />
|
||||||
|
<ClInclude Include="..\sys\wmlkm.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
55
build.vc10/nfs41_driver.vcxproj.filters
Normal file
55
build.vc10/nfs41_driver.vcxproj.filters
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Source files">
|
||||||
|
<UniqueIdentifier>{5cb3db05-7cb6-47df-835b-1f900bc6588b}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resource files">
|
||||||
|
<UniqueIdentifier>{3eaffb55-1a2a-45b8-9ab0-1ae04813d050}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header files">
|
||||||
|
<UniqueIdentifier>{b673e717-daca-4c21-8935-bee66da864fb}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\sys\nfs41_debug.c">
|
||||||
|
<Filter>Source files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\sys\nfs41_driver.c">
|
||||||
|
<Filter>Source files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\sys\wmlkm.c">
|
||||||
|
<Filter>Source files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="..\sys\makefile">
|
||||||
|
<Filter>Resource files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="..\sys\nfs41_driver.ini">
|
||||||
|
<Filter>Resource files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="..\sys\sources">
|
||||||
|
<Filter>Resource files</Filter>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ResourceCompile Include="..\sys\nfs41_driver.rc">
|
||||||
|
<Filter>Resource files</Filter>
|
||||||
|
</ResourceCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\sys\nfs41_debug.h">
|
||||||
|
<Filter>Header files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\sys\nfs41_driver.h">
|
||||||
|
<Filter>Header files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\sys\wmlkm.h">
|
||||||
|
<Filter>Header files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
182
build.vc10/nfs_install.vcxproj
Normal file
182
build.vc10/nfs_install.vcxproj
Normal file
|
|
@ -0,0 +1,182 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>{A453DC17-BE6B-4271-A020-66E054AB5908}</ProjectGuid>
|
||||||
|
<RootNamespace>nfs_install</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
||||||
|
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)$(Platform)\$(Configuration)\$(ProjectName)\</IntDir>
|
||||||
|
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||||
|
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||||
|
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
|
||||||
|
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
|
||||||
|
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||||
|
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||||
|
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
|
||||||
|
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalOptions>/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127 /wd4201 /wd4214 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<AdditionalIncludeDirectories>..\sys;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
|
<ExceptionHandling>
|
||||||
|
</ExceptionHandling>
|
||||||
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||||
|
<CompileAs>CompileAsC</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalOptions>/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127 /wd4201 /wd4214 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<AdditionalIncludeDirectories>..\sys;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<ExceptionHandling>
|
||||||
|
</ExceptionHandling>
|
||||||
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<CompileAs>CompileAsC</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Midl>
|
||||||
|
<TargetEnvironment>X64</TargetEnvironment>
|
||||||
|
</Midl>
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalOptions>/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127 /wd4201 /wd4214 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<AdditionalIncludeDirectories>..\sys;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<MinimalRebuild>true</MinimalRebuild>
|
||||||
|
<ExceptionHandling>
|
||||||
|
</ExceptionHandling>
|
||||||
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<CompileAs>CompileAsC</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<TargetMachine>MachineX64</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Midl>
|
||||||
|
<TargetEnvironment>X64</TargetEnvironment>
|
||||||
|
</Midl>
|
||||||
|
<ClCompile>
|
||||||
|
<AdditionalOptions>/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127 /wd4201 /wd4214 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<AdditionalIncludeDirectories>..\sys;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<ExceptionHandling>
|
||||||
|
</ExceptionHandling>
|
||||||
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<CompileAs>CompileAsC</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<TargetMachine>MachineX64</TargetMachine>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\install\nfs_install.c" />
|
||||||
|
<ClCompile Include="..\install\nfsreginst.c" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\install\nfsreginst.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="..\install\sources" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
35
build.vc10/nfs_install.vcxproj.filters
Normal file
35
build.vc10/nfs_install.vcxproj.filters
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Source Files">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resource Files">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\install\nfs_install.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\install\nfsreginst.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="..\install\nfsreginst.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="..\install\sources">
|
||||||
|
<Filter>Resource Files</Filter>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
6
build.vc9/.gitignore
vendored
Normal file
6
build.vc9/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
# exclude all build files by default
|
||||||
|
*
|
||||||
|
|
||||||
|
# allow visual studio project and solution files
|
||||||
|
!*.vcproj
|
||||||
|
!*.sln
|
||||||
536
build.vc9/daemon.vcproj
Normal file
536
build.vc9/daemon.vcproj
Normal file
|
|
@ -0,0 +1,536 @@
|
||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="9.00"
|
||||||
|
Name="daemon"
|
||||||
|
ProjectGUID="{D0D81A98-2946-4A16-A4A1-800387C3F3D1}"
|
||||||
|
RootNamespace="daemon"
|
||||||
|
TargetFrameworkVersion="196613"
|
||||||
|
>
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"
|
||||||
|
/>
|
||||||
|
<Platform
|
||||||
|
Name="x64"
|
||||||
|
/>
|
||||||
|
</Platforms>
|
||||||
|
<ToolFiles>
|
||||||
|
</ToolFiles>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\$(ProjectName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
InheritedPropertySheets=".\env.vsprops"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalOptions="/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="..\sys;..\xdr;..\dll;..\libtirpc\tirpc"
|
||||||
|
PreprocessorDefinitions="WIN32_LEAN_AND_MEAN"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
ExceptionHandling="0"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
RuntimeTypeInfo="false"
|
||||||
|
WarningLevel="4"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
CompileAs="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="ws2_32.lib iphlpapi.lib"
|
||||||
|
OutputFile="$(OutDir)\nfsd.exe"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|x64"
|
||||||
|
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\$(ProjectName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
InheritedPropertySheets=".\env.vsprops"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TargetEnvironment="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalOptions="/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="..\sys;..\xdr;..\dll;..\libtirpc\tirpc"
|
||||||
|
PreprocessorDefinitions="WIN32_LEAN_AND_MEAN"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
ExceptionHandling="0"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
RuntimeTypeInfo="false"
|
||||||
|
WarningLevel="4"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
CompileAs="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="ws2_32.lib iphlpapi.lib"
|
||||||
|
OutputFile="$(OutDir)\nfsd.exe"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
TargetMachine="17"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\$(ProjectName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
InheritedPropertySheets=".\env.vsprops"
|
||||||
|
CharacterSet="2"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalOptions="/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127"
|
||||||
|
Optimization="2"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
AdditionalIncludeDirectories="..\sys;..\xdr;..\dll;..\libtirpc\tirpc"
|
||||||
|
PreprocessorDefinitions="WIN32_LEAN_AND_MEAN"
|
||||||
|
ExceptionHandling="0"
|
||||||
|
RuntimeLibrary="2"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
RuntimeTypeInfo="false"
|
||||||
|
WarningLevel="4"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
CompileAs="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="ws2_32.lib iphlpapi.lib"
|
||||||
|
OutputFile="$(OutDir)\nfsd.exe"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|x64"
|
||||||
|
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\$(ProjectName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
InheritedPropertySheets=".\env.vsprops"
|
||||||
|
CharacterSet="2"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TargetEnvironment="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalOptions="/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127"
|
||||||
|
Optimization="2"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
AdditionalIncludeDirectories="..\sys;..\xdr;..\dll;..\libtirpc\tirpc"
|
||||||
|
PreprocessorDefinitions="WIN32_LEAN_AND_MEAN"
|
||||||
|
ExceptionHandling="0"
|
||||||
|
RuntimeLibrary="2"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
RuntimeTypeInfo="false"
|
||||||
|
WarningLevel="4"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
CompileAs="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="ws2_32.lib iphlpapi.lib"
|
||||||
|
OutputFile="$(OutDir)\nfsd.exe"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
TargetMachine="17"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="Source Files"
|
||||||
|
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||||
|
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\callback_server.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\callback_xdr.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\daemon_debug.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\getattr.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\lock.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\lookup.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\mount.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\name_cache.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\namespace.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\nfs41_client.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\nfs41_compound.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\nfs41_daemon.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\nfs41_ops.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\nfs41_rpc.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\nfs41_server.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\nfs41_session.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\nfs41_superblock.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\nfs41_xdr.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\open.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\pnfs_debug.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\pnfs_device.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\pnfs_io.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\pnfs_layout.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\rbtree.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\readdir.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\readwrite.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\setattr.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\upcall.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\util.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\volume.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Header Files"
|
||||||
|
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||||
|
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\daemon_debug.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\from_kernel.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\list.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\name_cache.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\nfs41.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\nfs41_compound.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\nfs41_const.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\nfs41_ops.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\nfs41_types.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\nfs41_xdr.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\pnfs.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\rbtree.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\upcall.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\util.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Resource Files"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\daemon\sources"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
||||||
386
build.vc9/dll.vcproj
Normal file
386
build.vc9/dll.vcproj
Normal file
|
|
@ -0,0 +1,386 @@
|
||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="9.00"
|
||||||
|
Name="dll"
|
||||||
|
ProjectGUID="{372D9D02-CDC5-43AE-BB0A-FB57CEFC639C}"
|
||||||
|
RootNamespace="dll"
|
||||||
|
TargetFrameworkVersion="196613"
|
||||||
|
>
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"
|
||||||
|
/>
|
||||||
|
<Platform
|
||||||
|
Name="x64"
|
||||||
|
/>
|
||||||
|
</Platforms>
|
||||||
|
<ToolFiles>
|
||||||
|
</ToolFiles>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\$(ProjectName)"
|
||||||
|
ConfigurationType="2"
|
||||||
|
InheritedPropertySheets=".\env.vsprops"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalOptions="/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="..\sys"
|
||||||
|
PreprocessorDefinitions="UNICODE;_UNICODE"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
ExceptionHandling="0"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
RuntimeTypeInfo="false"
|
||||||
|
WarningLevel="4"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
CompileAs="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
OutputFile="$(OutDir)\nfs41_np.dll"
|
||||||
|
ModuleDefinitionFile="..\dll\nfs41_np.def"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
BaseAddress="0x1010000"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|x64"
|
||||||
|
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\$(ProjectName)"
|
||||||
|
ConfigurationType="2"
|
||||||
|
InheritedPropertySheets=".\env.vsprops"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TargetEnvironment="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalOptions="/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="..\sys"
|
||||||
|
PreprocessorDefinitions="UNICODE;_UNICODE"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
ExceptionHandling="0"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
RuntimeTypeInfo="false"
|
||||||
|
WarningLevel="4"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
CompileAs="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
OutputFile="$(OutDir)\nfs41_np.dll"
|
||||||
|
ModuleDefinitionFile="..\dll\nfs41_np.def"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
BaseAddress="0x1010000"
|
||||||
|
TargetMachine="17"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\$(ProjectName)"
|
||||||
|
ConfigurationType="2"
|
||||||
|
InheritedPropertySheets=".\env.vsprops"
|
||||||
|
CharacterSet="2"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalOptions="/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127"
|
||||||
|
Optimization="2"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
AdditionalIncludeDirectories="..\sys"
|
||||||
|
PreprocessorDefinitions="UNICODE;_UNICODE"
|
||||||
|
ExceptionHandling="0"
|
||||||
|
RuntimeLibrary="2"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
RuntimeTypeInfo="false"
|
||||||
|
WarningLevel="4"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
CompileAs="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
OutputFile="$(OutDir)\nfs41_np.dll"
|
||||||
|
ModuleDefinitionFile="..\dll\nfs41_np.def"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
BaseAddress="0x1010000"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|x64"
|
||||||
|
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\$(ProjectName)"
|
||||||
|
ConfigurationType="2"
|
||||||
|
InheritedPropertySheets=".\env.vsprops"
|
||||||
|
CharacterSet="2"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TargetEnvironment="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalOptions="/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127"
|
||||||
|
Optimization="2"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
AdditionalIncludeDirectories="..\sys"
|
||||||
|
PreprocessorDefinitions="UNICODE;_UNICODE"
|
||||||
|
ExceptionHandling="0"
|
||||||
|
RuntimeLibrary="2"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
RuntimeTypeInfo="false"
|
||||||
|
WarningLevel="4"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
CompileAs="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
OutputFile="$(OutDir)\nfs41_np.dll"
|
||||||
|
ModuleDefinitionFile="..\dll\nfs41_np.def"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
BaseAddress="0x1010000"
|
||||||
|
TargetMachine="17"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="Source Files"
|
||||||
|
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||||
|
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\dll\dllmain.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\dll\nfs41_np.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\dll\options.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Header Files"
|
||||||
|
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||||
|
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\dll\nfs41_np.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Resource Files"
|
||||||
|
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||||
|
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\dll\nfs41_np.def"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\dll\sources"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
||||||
28
build.vc9/env.vsprops.example
Normal file
28
build.vc9/env.vsprops.example
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioPropertySheet
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="8.00"
|
||||||
|
Name="ddk_env"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalIncludeDirectories="$(WDKPATH)\inc\ddk;$(WDKPATH)\inc\api;$(WDKPATH)\inc\crt"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCNMakeTool"
|
||||||
|
BuildCommandLine=""
|
||||||
|
ReBuildCommandLine=""
|
||||||
|
CleanCommandLine=""
|
||||||
|
Output=""
|
||||||
|
PreprocessorDefinitions=""
|
||||||
|
IncludeSearchPath="$(WDKPATH)\inc\ddk;$(WDKPATH)\inc\api;$(WDKPATH)\inc\crt"
|
||||||
|
ForcedIncludes=""
|
||||||
|
AssemblySearchPath=""
|
||||||
|
ForcedUsingAssemblies=""
|
||||||
|
CompileAsManaged=""
|
||||||
|
/>
|
||||||
|
<UserMacro
|
||||||
|
Name="WDKPATH"
|
||||||
|
Value="C:\WinDDK\7600.16385.0"
|
||||||
|
/>
|
||||||
|
</VisualStudioPropertySheet>
|
||||||
793
build.vc9/libtirpc.vcproj
Normal file
793
build.vc9/libtirpc.vcproj
Normal file
|
|
@ -0,0 +1,793 @@
|
||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="9.00"
|
||||||
|
Name="libtirpc"
|
||||||
|
ProjectGUID="{2D918A9B-DE52-470A-93D5-78EA2C8113A1}"
|
||||||
|
RootNamespace="libtirpc"
|
||||||
|
Keyword="Win32Proj"
|
||||||
|
TargetFrameworkVersion="196613"
|
||||||
|
>
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"
|
||||||
|
/>
|
||||||
|
<Platform
|
||||||
|
Name="x64"
|
||||||
|
/>
|
||||||
|
</Platforms>
|
||||||
|
<ToolFiles>
|
||||||
|
</ToolFiles>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\$(ProjectName)"
|
||||||
|
ConfigurationType="2"
|
||||||
|
CharacterSet="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="..\libtirpc\tirpc"
|
||||||
|
PreprocessorDefinitions="INET6;FD_SETSIZE=128;PORTMAP"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="ws2_32.lib"
|
||||||
|
LinkIncremental="1"
|
||||||
|
ModuleDefinitionFile="..\libtirpc\libtirpc\libtirpc.def"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="2"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|x64"
|
||||||
|
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\$(ProjectName)"
|
||||||
|
ConfigurationType="2"
|
||||||
|
CharacterSet="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TargetEnvironment="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="..\libtirpc\tirpc"
|
||||||
|
PreprocessorDefinitions="INET6;FD_SETSIZE=128;PORTMAP"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="ws2_32.lib"
|
||||||
|
LinkIncremental="1"
|
||||||
|
ModuleDefinitionFile="..\libtirpc\libtirpc\libtirpc.def"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="2"
|
||||||
|
EntryPointSymbol=""
|
||||||
|
TargetMachine="17"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\$(ProjectName)"
|
||||||
|
ConfigurationType="2"
|
||||||
|
CharacterSet="1"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
AdditionalIncludeDirectories="..\libtirpc\tirpc"
|
||||||
|
PreprocessorDefinitions="INET6;FD_SETSIZE=128;PORTMAP"
|
||||||
|
RuntimeLibrary="2"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="ws2_32.lib"
|
||||||
|
LinkIncremental="1"
|
||||||
|
ModuleDefinitionFile="..\libtirpc\libtirpc\libtirpc.def"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="2"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|x64"
|
||||||
|
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\$(ProjectName)"
|
||||||
|
ConfigurationType="2"
|
||||||
|
CharacterSet="1"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TargetEnvironment="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
AdditionalIncludeDirectories="..\libtirpc\tirpc"
|
||||||
|
PreprocessorDefinitions="INET6;FD_SETSIZE=128;PORTMAP"
|
||||||
|
RuntimeLibrary="2"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="ws2_32.lib"
|
||||||
|
LinkIncremental="1"
|
||||||
|
ModuleDefinitionFile="..\libtirpc\libtirpc\libtirpc.def"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="2"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
EntryPointSymbol=""
|
||||||
|
TargetMachine="17"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="Source Files"
|
||||||
|
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||||
|
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\asprintf.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\auth_none.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\auth_time.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\auth_unix.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\authunix_prot.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\bindresvport.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\clnt_bcast.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\clnt_dg.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\clnt_generic.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\clnt_perror.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\clnt_raw.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\clnt_simple.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\clnt_vc.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\des_soft.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\epoll_sub.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\getnetconfig.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\getnetpath.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\getpeereid.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\getpublickey.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\getrpcent.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\getrpcport.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\gettimeofday.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\key_call.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\key_prot_xdr.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\mt_misc.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\netname.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\netnamer.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\pmap_clnt.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\pmap_getmaps.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\pmap_getport.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\pmap_prot.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\pmap_prot2.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\pmap_rmt.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\rpc_callmsg.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\rpc_com.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\rpc_commondata.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\rpc_dtablesize.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\rpc_generic.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\rpc_prot.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\rpc_soc.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\rpcb_clnt.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\rpcb_prot.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\rpcb_st_xdr.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\rpcdname.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\rtime.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\svc.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\svc_auth.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\svc_auth_none.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\svc_auth_unix.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\svc_dg.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\svc_generic.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\svc_raw.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\svc_run.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\svc_simple.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\svc_vc.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\winstubs.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\wintirpc.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\xdr.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\xdr_array.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\xdr_float.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\xdr_mem.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\xdr_rec.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\xdr_reference.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\xdr_sizeof.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\xdr_stdio.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Header Files"
|
||||||
|
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||||
|
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\rpc\auth.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\rpc\auth_des.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\rpc\auth_gss.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\rpc\auth_kerb.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\rpc\auth_unix.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\rpc\clnt.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\rpc\clnt_soc.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\rpc\clnt_stat.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\rpcsvc\crypt.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\rpc\des.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\rpc\des_crypt.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\misc\event.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\fpmath.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\getpeereid.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\libc_private.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\namespace.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\netconfig.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\rpc\nettype.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\rpcsvc\nis.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\nss_tls.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\rpc\pmap_clnt.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\rpc\pmap_prot.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\rpc\pmap_rmt.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\sys\queue.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\misc\queue.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\rpc\raw.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\reentrant.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\rpc\rpc.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\rpc\rpc_com.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\rpc\rpc_msg.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\rpc\rpcb_clnt.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\rpc\rpcb_prot.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\rpc\rpcent.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\misc\socket.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\spinlock.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\rpc\svc.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\rpc\svc_auth.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\rpc\svc_dg.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\rpc\svc_soc.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\rpc\types.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\un-namespace.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\wintirpc.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\tirpc\rpc\xdr.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Resource Files"
|
||||||
|
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||||
|
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\libtirpc\libtirpc.rc"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\libtirpc\src\sources"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
||||||
362
build.vc9/mount.vcproj
Normal file
362
build.vc9/mount.vcproj
Normal file
|
|
@ -0,0 +1,362 @@
|
||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="9.00"
|
||||||
|
Name="mount"
|
||||||
|
ProjectGUID="{5AEA3497-6852-471B-A252-ADA60B22A342}"
|
||||||
|
RootNamespace="mount"
|
||||||
|
TargetFrameworkVersion="196613"
|
||||||
|
>
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"
|
||||||
|
/>
|
||||||
|
<Platform
|
||||||
|
Name="x64"
|
||||||
|
/>
|
||||||
|
</Platforms>
|
||||||
|
<ToolFiles>
|
||||||
|
</ToolFiles>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\$(ProjectName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalOptions="/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="..\sys"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
ExceptionHandling="0"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
WarningLevel="4"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
CompileAs="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="mpr.lib"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\$(ProjectName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalOptions="/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127"
|
||||||
|
Optimization="2"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
AdditionalIncludeDirectories="..\sys"
|
||||||
|
ExceptionHandling="0"
|
||||||
|
RuntimeLibrary="2"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
WarningLevel="4"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
CompileAs="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="mpr.lib"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|x64"
|
||||||
|
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\$(ProjectName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TargetEnvironment="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalOptions="/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="..\sys"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
ExceptionHandling="0"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
WarningLevel="4"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
CompileAs="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="mpr.lib"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
TargetMachine="17"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|x64"
|
||||||
|
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\$(ProjectName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TargetEnvironment="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalOptions="/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127"
|
||||||
|
Optimization="2"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
AdditionalIncludeDirectories="..\sys"
|
||||||
|
ExceptionHandling="0"
|
||||||
|
RuntimeLibrary="2"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
WarningLevel="4"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
CompileAs="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="mpr.lib"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
TargetMachine="17"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="Source Files"
|
||||||
|
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||||
|
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\mount\enum.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\mount\mount.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\mount\options.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Header Files"
|
||||||
|
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||||
|
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\mount\options.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Resource Files"
|
||||||
|
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||||
|
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\mount\sources"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
||||||
79
build.vc9/ms-nfs41-client.sln
Normal file
79
build.vc9/ms-nfs41-client.sln
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||||
|
# Visual Studio 2008
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "daemon", "daemon.vcproj", "{D0D81A98-2946-4A16-A4A1-800387C3F3D1}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{2D918A9B-DE52-470A-93D5-78EA2C8113A1} = {2D918A9B-DE52-470A-93D5-78EA2C8113A1}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dll", "dll.vcproj", "{372D9D02-CDC5-43AE-BB0A-FB57CEFC639C}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nfs41_driver", "nfs41_driver.vcproj", "{B64D3074-519F-476A-A3AA-DAD6554CBB68}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mount", "mount.vcproj", "{5AEA3497-6852-471B-A252-ADA60B22A342}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libtirpc", "libtirpc.vcproj", "{2D918A9B-DE52-470A-93D5-78EA2C8113A1}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nfs_install", "nfs_install.vcproj", "{A453DC17-BE6B-4271-A020-66E054AB5908}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Win32 = Debug|Win32
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Release|Win32 = Release|Win32
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{D0D81A98-2946-4A16-A4A1-800387C3F3D1}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{D0D81A98-2946-4A16-A4A1-800387C3F3D1}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{D0D81A98-2946-4A16-A4A1-800387C3F3D1}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{D0D81A98-2946-4A16-A4A1-800387C3F3D1}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{D0D81A98-2946-4A16-A4A1-800387C3F3D1}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{D0D81A98-2946-4A16-A4A1-800387C3F3D1}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{D0D81A98-2946-4A16-A4A1-800387C3F3D1}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{D0D81A98-2946-4A16-A4A1-800387C3F3D1}.Release|x64.Build.0 = Release|x64
|
||||||
|
{372D9D02-CDC5-43AE-BB0A-FB57CEFC639C}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{372D9D02-CDC5-43AE-BB0A-FB57CEFC639C}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{372D9D02-CDC5-43AE-BB0A-FB57CEFC639C}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{372D9D02-CDC5-43AE-BB0A-FB57CEFC639C}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{372D9D02-CDC5-43AE-BB0A-FB57CEFC639C}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{372D9D02-CDC5-43AE-BB0A-FB57CEFC639C}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{372D9D02-CDC5-43AE-BB0A-FB57CEFC639C}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{372D9D02-CDC5-43AE-BB0A-FB57CEFC639C}.Release|x64.Build.0 = Release|x64
|
||||||
|
{B64D3074-519F-476A-A3AA-DAD6554CBB68}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{B64D3074-519F-476A-A3AA-DAD6554CBB68}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{B64D3074-519F-476A-A3AA-DAD6554CBB68}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{B64D3074-519F-476A-A3AA-DAD6554CBB68}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{B64D3074-519F-476A-A3AA-DAD6554CBB68}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{B64D3074-519F-476A-A3AA-DAD6554CBB68}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{B64D3074-519F-476A-A3AA-DAD6554CBB68}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{B64D3074-519F-476A-A3AA-DAD6554CBB68}.Release|x64.Build.0 = Release|x64
|
||||||
|
{5AEA3497-6852-471B-A252-ADA60B22A342}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{5AEA3497-6852-471B-A252-ADA60B22A342}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{5AEA3497-6852-471B-A252-ADA60B22A342}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{5AEA3497-6852-471B-A252-ADA60B22A342}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{5AEA3497-6852-471B-A252-ADA60B22A342}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{5AEA3497-6852-471B-A252-ADA60B22A342}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{5AEA3497-6852-471B-A252-ADA60B22A342}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{5AEA3497-6852-471B-A252-ADA60B22A342}.Release|x64.Build.0 = Release|x64
|
||||||
|
{2D918A9B-DE52-470A-93D5-78EA2C8113A1}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{2D918A9B-DE52-470A-93D5-78EA2C8113A1}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{2D918A9B-DE52-470A-93D5-78EA2C8113A1}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{2D918A9B-DE52-470A-93D5-78EA2C8113A1}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{2D918A9B-DE52-470A-93D5-78EA2C8113A1}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{2D918A9B-DE52-470A-93D5-78EA2C8113A1}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{2D918A9B-DE52-470A-93D5-78EA2C8113A1}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{2D918A9B-DE52-470A-93D5-78EA2C8113A1}.Release|x64.Build.0 = Release|x64
|
||||||
|
{A453DC17-BE6B-4271-A020-66E054AB5908}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{A453DC17-BE6B-4271-A020-66E054AB5908}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{A453DC17-BE6B-4271-A020-66E054AB5908}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{A453DC17-BE6B-4271-A020-66E054AB5908}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{A453DC17-BE6B-4271-A020-66E054AB5908}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{A453DC17-BE6B-4271-A020-66E054AB5908}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
{A453DC17-BE6B-4271-A020-66E054AB5908}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{A453DC17-BE6B-4271-A020-66E054AB5908}.Release|x64.Build.0 = Release|x64
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
167
build.vc9/nfs41_driver.vcproj
Normal file
167
build.vc9/nfs41_driver.vcproj
Normal file
|
|
@ -0,0 +1,167 @@
|
||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="9.00"
|
||||||
|
Name="nfs41_driver"
|
||||||
|
ProjectGUID="{B64D3074-519F-476A-A3AA-DAD6554CBB68}"
|
||||||
|
Keyword="MakeFileProj"
|
||||||
|
TargetFrameworkVersion="196613"
|
||||||
|
>
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"
|
||||||
|
/>
|
||||||
|
<Platform
|
||||||
|
Name="x64"
|
||||||
|
/>
|
||||||
|
</Platforms>
|
||||||
|
<ToolFiles>
|
||||||
|
</ToolFiles>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="C:\projects\ms-nfs41-client\sys\objchk_wlh_x86"
|
||||||
|
IntermediateDirectory="C:\projects\ms-nfs41-client\sys\objchk_wlh_x86"
|
||||||
|
ConfigurationType="0"
|
||||||
|
InheritedPropertySheets=".\env.vsprops"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCNMakeTool"
|
||||||
|
BuildCommandLine="call $(WDKPATH)\bin\setenv.bat $(WDKPATH) chk x86 wlh
cd /d C:\projects\ms-nfs41-client\sys
build"
|
||||||
|
ReBuildCommandLine="rmdir /s /q C:\projects\ms-nfs41-client\sys\objchk_wlh_x86
call $(WDKPATH)\bin\setenv.bat $(WDKPATH) chk x86 wlh
cd /d C:\projects\ms-nfs41-client\sys
build"
|
||||||
|
CleanCommandLine="rmdir /s /q C:\projects\ms-nfs41-client\sys\objchk_wlh_x86"
|
||||||
|
Output="C:\projects\ms-nfs41-client\sys\objchk_wlh_x86\i386\nfs41_driver.sys"
|
||||||
|
PreprocessorDefinitions="WIN32;_CONSOLE;_X86_;_DDK_;_DEBUG;DBG=1"
|
||||||
|
IncludeSearchPath="$(WDKPATH)\inc\ddk;$(WDKPATH)\inc\api;$(WDKPATH)\inc\crt"
|
||||||
|
ForcedIncludes=""
|
||||||
|
AssemblySearchPath=""
|
||||||
|
ForcedUsingAssemblies=""
|
||||||
|
CompileAsManaged=""
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|x64"
|
||||||
|
OutputDirectory="C:\projects\ms-nfs41-client\sys\objchk_wlh_amd64"
|
||||||
|
IntermediateDirectory="C:\projects\ms-nfs41-client\sys\objchk_wlh_amd64"
|
||||||
|
ConfigurationType="0"
|
||||||
|
InheritedPropertySheets=".\env.vsprops"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCNMakeTool"
|
||||||
|
BuildCommandLine="call $(WDKPATH)\bin\setenv.bat $(WDKPATH) chk x64 wlh
cd /d C:\projects\ms-nfs41-client\sys
build"
|
||||||
|
ReBuildCommandLine="rmdir /s /q C:\projects\ms-nfs41-client\sys\objchk_wlh_amd64
call $(WDKPATH)\bin\setenv.bat $(WDKPATH) chk x64 wlh
cd /d C:\projects\ms-nfs41-client\sys
build"
|
||||||
|
CleanCommandLine="rmdir /s /q C:\projects\ms-nfs41-client\sys\objchk_wlh_amd64"
|
||||||
|
Output="C:\projects\ms-nfs41-client\sys\objchk_wlh_amd64\amd64\nfs41_driver.sys"
|
||||||
|
PreprocessorDefinitions="WIN32;_CONSOLE;_AMD64_;_DDK_;_DEBUG;DBG=1"
|
||||||
|
IncludeSearchPath="$(WDKPATH)\inc\ddk;$(WDKPATH)\inc\api;$(WDKPATH)\inc\crt"
|
||||||
|
ForcedIncludes=""
|
||||||
|
AssemblySearchPath=""
|
||||||
|
ForcedUsingAssemblies=""
|
||||||
|
CompileAsManaged=""
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="C:\projects\ms-nfs41-client\sys\objfre_wlh_x86"
|
||||||
|
IntermediateDirectory="C:\projects\ms-nfs41-client\sys\objfre_wlh_x86"
|
||||||
|
ConfigurationType="0"
|
||||||
|
InheritedPropertySheets=".\env.vsprops"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCNMakeTool"
|
||||||
|
BuildCommandLine="call $(WDKPATH)\bin\setenv.bat $(WDKPATH) fre x86 wlh
cd /d C:\projects\ms-nfs41-client\sys
build"
|
||||||
|
ReBuildCommandLine="rmdir /s /q C:\projects\ms-nfs41-client\sys\objfre_wlh_x86
call $(WDKPATH)\bin\setenv.bat $(WDKPATH) fre x86 wlh
cd /d C:\projects\ms-nfs41-client\sys
build"
|
||||||
|
CleanCommandLine="rmdir /s /q C:\projects\ms-nfs41-client\sys\objfre_wlh_x86"
|
||||||
|
Output="C:\projects\ms-nfs41-client\sys\objfre_wlh_x86\i386\nfs41_driver.sys"
|
||||||
|
PreprocessorDefinitions="WIN32;_CONSOLE;_X86_;_DDK_;_NDEBUG;DBG=0"
|
||||||
|
IncludeSearchPath="$(WDKPATH)\inc\ddk;$(WDKPATH)\inc\api;$(WDKPATH)\inc\crt"
|
||||||
|
ForcedIncludes=""
|
||||||
|
AssemblySearchPath=""
|
||||||
|
ForcedUsingAssemblies=""
|
||||||
|
CompileAsManaged=""
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|x64"
|
||||||
|
OutputDirectory="C:\projects\ms-nfs41-client\sys\objfre_wlh_amd64"
|
||||||
|
IntermediateDirectory="C:\projects\ms-nfs41-client\sys\objfre_wlh_amd64"
|
||||||
|
ConfigurationType="0"
|
||||||
|
InheritedPropertySheets=".\env.vsprops"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCNMakeTool"
|
||||||
|
BuildCommandLine="call $(WDKPATH)\bin\setenv.bat $(WDKPATH) fre x64 wlh
cd /d C:\projects\ms-nfs41-client\sys
build"
|
||||||
|
ReBuildCommandLine="rmdir /s /q C:\projects\ms-nfs41-client\sys\objfre_wlh_amd64
call $(WDKPATH)\bin\setenv.bat $(WDKPATH) fre x64 wlh
cd /d C:\projects\ms-nfs41-client\sys
build"
|
||||||
|
CleanCommandLine="rmdir /s /q C:\projects\ms-nfs41-client\sys\objfre_wlh_amd64"
|
||||||
|
Output="C:\projects\ms-nfs41-client\sys\objfre_wlh_amd64\amd64\nfs41_driver.sys"
|
||||||
|
PreprocessorDefinitions="WIN32;_CONSOLE;_AMD64_;_DDK_;_NDEBUG;DBG=0"
|
||||||
|
IncludeSearchPath="$(WDKPATH)\inc\ddk;$(WDKPATH)\inc\api;$(WDKPATH)\inc\crt"
|
||||||
|
ForcedIncludes=""
|
||||||
|
AssemblySearchPath=""
|
||||||
|
ForcedUsingAssemblies=""
|
||||||
|
CompileAsManaged=""
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="Source files"
|
||||||
|
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sys\nfs41_debug.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sys\nfs41_driver.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sys\wmlkm.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Resource files"
|
||||||
|
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sys\makefile"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sys\nfs41_driver.ini"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sys\nfs41_driver.rc"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sys\sources"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Header files"
|
||||||
|
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sys\nfs41_debug.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sys\nfs41_driver.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\sys\wmlkm.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
||||||
354
build.vc9/nfs_install.vcproj
Normal file
354
build.vc9/nfs_install.vcproj
Normal file
|
|
@ -0,0 +1,354 @@
|
||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="9.00"
|
||||||
|
Name="nfs_install"
|
||||||
|
ProjectGUID="{A453DC17-BE6B-4271-A020-66E054AB5908}"
|
||||||
|
RootNamespace="nfs_install"
|
||||||
|
TargetFrameworkVersion="196613"
|
||||||
|
>
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"
|
||||||
|
/>
|
||||||
|
<Platform
|
||||||
|
Name="x64"
|
||||||
|
/>
|
||||||
|
</Platforms>
|
||||||
|
<ToolFiles>
|
||||||
|
</ToolFiles>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\$(ProjectName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalOptions="/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127 /wd4201 /wd4214"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="..\sys"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
ExceptionHandling="0"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
CompileAs="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\$(ProjectName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalOptions="/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127 /wd4201 /wd4214"
|
||||||
|
Optimization="2"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
AdditionalIncludeDirectories="..\sys"
|
||||||
|
ExceptionHandling="0"
|
||||||
|
RuntimeLibrary="2"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
CompileAs="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|x64"
|
||||||
|
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\$(ProjectName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TargetEnvironment="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalOptions="/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127 /wd4201 /wd4214"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="..\sys"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
ExceptionHandling="0"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
CompileAs="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
TargetMachine="17"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|x64"
|
||||||
|
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)\$(ProjectName)"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
TargetEnvironment="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalOptions="/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127 /wd4201 /wd4214"
|
||||||
|
Optimization="2"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
AdditionalIncludeDirectories="..\sys"
|
||||||
|
ExceptionHandling="0"
|
||||||
|
RuntimeLibrary="2"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
CompileAs="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
TargetMachine="17"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="Source Files"
|
||||||
|
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||||
|
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\install\nfs_install.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\install\nfsreginst.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Header Files"
|
||||||
|
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||||
|
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\install\nfsreginst.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Resource Files"
|
||||||
|
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||||
|
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\install\sources"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
||||||
381
daemon/callback_server.c
Normal file
381
daemon/callback_server.c
Normal file
|
|
@ -0,0 +1,381 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <strsafe.h>
|
||||||
|
|
||||||
|
#include "nfs41.h"
|
||||||
|
#include "nfs41_ops.h"
|
||||||
|
#include "nfs41_callback.h"
|
||||||
|
#include "daemon_debug.h"
|
||||||
|
|
||||||
|
#define CBSLVL 2 /* dprintf level for callback server logging */
|
||||||
|
|
||||||
|
|
||||||
|
static const char g_server_tag[] = "ms-nfs41-callback";
|
||||||
|
|
||||||
|
|
||||||
|
/* OP_CB_LAYOUTRECALL */
|
||||||
|
static enum_t handle_cb_layoutrecall(
|
||||||
|
IN nfs41_rpc_clnt *rpc_clnt,
|
||||||
|
IN struct cb_layoutrecall_args *args,
|
||||||
|
OUT struct cb_layoutrecall_res *res)
|
||||||
|
{
|
||||||
|
enum pnfs_status status;
|
||||||
|
/* forgetful model for layout recalls; return NOMATCHING_LAYOUT
|
||||||
|
* and flag the layout(s) to prevent further use */
|
||||||
|
res->status = NFS4ERR_NOMATCHING_LAYOUT;
|
||||||
|
|
||||||
|
dprintf(CBSLVL, " OP_CB_LAYOUTRECALL { %s, %s, recall %u } %s\n",
|
||||||
|
pnfs_layout_type_string(args->type),
|
||||||
|
pnfs_iomode_string(args->iomode), args->recall.type,
|
||||||
|
nfs_error_string(res->status));
|
||||||
|
|
||||||
|
status = pnfs_file_layout_recall(rpc_clnt->client->layouts, args);
|
||||||
|
if (status)
|
||||||
|
eprintf("pnfs_file_layout_recall() failed with %s\n",
|
||||||
|
pnfs_error_string(status));
|
||||||
|
|
||||||
|
return res->status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* OP_CB_RECALL_SLOT */
|
||||||
|
static enum_t handle_cb_recall_slot(
|
||||||
|
IN struct cb_recall_slot_args *args,
|
||||||
|
OUT struct cb_recall_slot_res *res)
|
||||||
|
{
|
||||||
|
res->status = NFS4_OK;
|
||||||
|
|
||||||
|
dprintf(CBSLVL, " OP_CB_RECALL_SLOT { %u } %s\n",
|
||||||
|
args->target_highest_slotid, nfs_error_string(res->status));
|
||||||
|
return res->status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* OP_CB_SEQUENCE */
|
||||||
|
static enum_t handle_cb_sequence(
|
||||||
|
IN nfs41_rpc_clnt *rpc_clnt,
|
||||||
|
IN struct cb_sequence_args *args,
|
||||||
|
OUT struct cb_sequence_res *res)
|
||||||
|
{
|
||||||
|
nfs41_cb_session *cb_session = &rpc_clnt->client->session->cb_session;
|
||||||
|
uint32_t status = NFS4_OK;
|
||||||
|
res->status = NFS4_OK;
|
||||||
|
|
||||||
|
if (!cb_session->cb_is_valid_state) {
|
||||||
|
memcpy(cb_session->cb_sessionid, args->sessionid, NFS4_SESSIONID_SIZE);
|
||||||
|
if (args->sequenceid != 1) {
|
||||||
|
eprintf("[cb] 1st seq#=%d is not 1\n", args->sequenceid);
|
||||||
|
res->status = NFS4ERR_SEQ_MISORDERED;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
cb_session->cb_is_valid_state = TRUE;
|
||||||
|
} else {
|
||||||
|
if (memcmp(cb_session->cb_sessionid, args->sessionid,
|
||||||
|
NFS4_SESSIONID_SIZE)) {
|
||||||
|
eprintf("[cb] received sessionid doesn't match saved info\n");
|
||||||
|
print_hexbuf(1, (unsigned char *)"received sessionid",
|
||||||
|
(unsigned char *)args->sessionid, NFS4_SESSIONID_SIZE);
|
||||||
|
print_hexbuf(1, (unsigned char *)"saved sessionid",
|
||||||
|
cb_session->cb_sessionid, NFS4_SESSIONID_SIZE);
|
||||||
|
res->status = NFS4ERR_BADSESSION;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 20.9.3.: If the difference between csa_sequenceid and the client's
|
||||||
|
* cachedsequence ID at the slot ID is two (2) or more, or if
|
||||||
|
* csa_sequenceid is less than the cached sequence ID (accounting for
|
||||||
|
* wraparound of the unsigned sequence ID value), then the client
|
||||||
|
* MUST return NFS4ERR_SEQ_MISORDERED.
|
||||||
|
*/
|
||||||
|
if (args->sequenceid < cb_session->cb_seqnum ||
|
||||||
|
(args->sequenceid - cb_session->cb_seqnum >= 2)) {
|
||||||
|
eprintf("[cb] bad received seq#=%d, expected=%d\n",
|
||||||
|
args->sequenceid, cb_session->cb_seqnum+1);
|
||||||
|
res->status = NFS4ERR_SEQ_MISORDERED;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we only support 1 slot for the back channel so slotid MUST be 0 */
|
||||||
|
if (args->slotid != 0) {
|
||||||
|
eprintf("[cb] received unexpected slotid=%d\n", args->slotid);
|
||||||
|
res->status = NFS4ERR_BADSLOT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (args->highest_slotid != 0) {
|
||||||
|
eprintf("[cb] received unexpected highest_slotid=%d\n",
|
||||||
|
args->highest_slotid);
|
||||||
|
res->status = NFS4ERR_BAD_HIGH_SLOT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args->sequenceid == cb_session->cb_seqnum) {
|
||||||
|
// check if the request is same as the original, if different need
|
||||||
|
// to return NFS4ERR_SEQ_FALSE_RETRY
|
||||||
|
if (!cb_session->cb_cache_this) {
|
||||||
|
res->status = NFS4_OK;
|
||||||
|
status = NFS4ERR_RETRY_UNCACHED_REP;
|
||||||
|
goto out;
|
||||||
|
} else {
|
||||||
|
res->status = NFS4ERR_REP_TOO_BIG_TO_CACHE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cb_session->cb_seqnum + 1 == 0)
|
||||||
|
cb_session->cb_seqnum = 0;
|
||||||
|
else
|
||||||
|
cb_session->cb_seqnum = args->sequenceid;
|
||||||
|
cb_session->cb_cache_this = args->cachethis;
|
||||||
|
|
||||||
|
memcpy(res->ok.sessionid, args->sessionid, NFS4_SESSIONID_SIZE);
|
||||||
|
res->ok.sequenceid = args->sequenceid;
|
||||||
|
res->ok.slotid = args->slotid;
|
||||||
|
res->ok.highest_slotid = args->highest_slotid;
|
||||||
|
res->ok.target_highest_slotid = args->highest_slotid;
|
||||||
|
|
||||||
|
out:
|
||||||
|
dprintf(CBSLVL, " OP_CB_SEQUENCE { seqid %u, slot %u, cachethis %d } "
|
||||||
|
"%s\n", args->sequenceid, args->slotid, args->cachethis,
|
||||||
|
nfs_error_string(res->status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* OP_CB_RECALL */
|
||||||
|
typedef struct _nfs41_cb_recall {
|
||||||
|
nfs41_rpc_clnt *rpc_clnt;
|
||||||
|
struct cb_recall_args *args;
|
||||||
|
} nfs41_cb_recall;
|
||||||
|
|
||||||
|
static unsigned int WINAPI _handle_cb_recall(void *args)
|
||||||
|
{
|
||||||
|
nfs41_cb_recall *cb_args = (nfs41_cb_recall *)args;
|
||||||
|
nfs41_path_fh path_fh;
|
||||||
|
|
||||||
|
dprintf(1, "_handle_cb_recall: start\n");
|
||||||
|
print_hexbuf(3, (unsigned char *)"_handle_cb_recall: fh ",
|
||||||
|
cb_args->args->fh.fh, cb_args->args->fh.len);
|
||||||
|
print_hexbuf(3, (unsigned char *)"_handle_cb_recall: stateid ",
|
||||||
|
cb_args->args->stateid.other, 12);
|
||||||
|
ZeroMemory(&path_fh, sizeof(nfs41_path_fh));
|
||||||
|
memcpy(&path_fh.fh, &cb_args->args->fh, sizeof(nfs41_fh));
|
||||||
|
path_fh.fh.superblock = NULL;
|
||||||
|
path_fh.path = NULL;
|
||||||
|
path_fh.name.len = 0;
|
||||||
|
dprintf(1, "_handle_cb_recall: sending nfs41_delegreturn\n");
|
||||||
|
nfs41_delegreturn(cb_args->rpc_clnt->client->session, &path_fh,
|
||||||
|
&cb_args->args->stateid);
|
||||||
|
free(cb_args);
|
||||||
|
dprintf(1, "_handle_cb_recall: end\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum_t handle_cb_recall(
|
||||||
|
IN nfs41_rpc_clnt *rpc_clnt,
|
||||||
|
IN struct cb_recall_args *args,
|
||||||
|
OUT struct cb_recall_res *res)
|
||||||
|
{
|
||||||
|
nfs41_cb_recall *cb_args;
|
||||||
|
res->status = NFS4_OK;
|
||||||
|
|
||||||
|
dprintf(CBSLVL, "OP_CB_RECALL\n");
|
||||||
|
cb_args = calloc(1, sizeof(nfs41_cb_recall));
|
||||||
|
if (cb_args == NULL) {
|
||||||
|
res->status = NFS4ERR_RESOURCE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
cb_args->rpc_clnt = rpc_clnt;
|
||||||
|
cb_args->args = args;
|
||||||
|
_beginthreadex(NULL, 0, _handle_cb_recall, cb_args, 0, NULL);
|
||||||
|
out:
|
||||||
|
return res->status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CB_COMPOUND */
|
||||||
|
static void handle_cb_compound(nfs41_rpc_clnt *rpc_clnt, cb_req *req, struct cb_compound_res **reply)
|
||||||
|
{
|
||||||
|
struct cb_compound_args args = { 0 };
|
||||||
|
struct cb_compound_res *res = NULL;
|
||||||
|
struct cb_argop *argop;
|
||||||
|
struct cb_resop *resop;
|
||||||
|
XDR *xdr = (XDR*)req->xdr;
|
||||||
|
uint32_t i, status = NFS4_OK;
|
||||||
|
|
||||||
|
dprintf(CBSLVL, "--> handle_compound()\n");
|
||||||
|
|
||||||
|
/* decode the arguments */
|
||||||
|
proc_cb_compound_args(xdr, &args);
|
||||||
|
dprintf(CBSLVL, "CB_COMPOUND('%s', %u)\n", args.tag.str, args.argarray_count);
|
||||||
|
if (args.minorversion != 1) {
|
||||||
|
status = NFS4ERR_MINOR_VERS_MISMATCH; //XXXXX
|
||||||
|
eprintf("args.minorversion %u != 1\n", args.minorversion);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocate the compound results */
|
||||||
|
res = calloc(1, sizeof(struct cb_compound_res));
|
||||||
|
if (res == NULL) {
|
||||||
|
status = NFS4ERR_RESOURCE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
res->status = NFS4_OK;
|
||||||
|
StringCchCopyA(res->tag.str, CB_COMPOUND_MAX_TAG, g_server_tag);
|
||||||
|
res->tag.str[CB_COMPOUND_MAX_TAG-1] = 0;
|
||||||
|
res->tag.len = (uint32_t)strlen(res->tag.str);
|
||||||
|
res->resarray = calloc(args.argarray_count, sizeof(struct cb_resop));
|
||||||
|
if (res->resarray == NULL) {
|
||||||
|
res->status = NFS4ERR_RESOURCE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* handle each operation in the compound */
|
||||||
|
for (i = 0; i < args.argarray_count && res->status == NFS4_OK; i++) {
|
||||||
|
argop = &args.argarray[i];
|
||||||
|
resop = &res->resarray[i];
|
||||||
|
|
||||||
|
/* 20.9.3: The error NFS4ERR_SEQUENCE_POS MUST be returned
|
||||||
|
* when CB_SEQUENCE is found in any position in a CB_COMPOUND
|
||||||
|
* beyond the first. If any other operation is in the first
|
||||||
|
* position of CB_COMPOUND, NFS4ERR_OP_NOT_IN_SESSION MUST
|
||||||
|
* be returned.
|
||||||
|
*/
|
||||||
|
if (i == 0 && argop->opnum != OP_CB_SEQUENCE) {
|
||||||
|
res->status = NFS4ERR_OP_NOT_IN_SESSION;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (i != 0 && argop->opnum == OP_CB_SEQUENCE) {
|
||||||
|
res->status = NFS4ERR_SEQUENCE_POS;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
resop->opnum = argop->opnum;
|
||||||
|
if (status == NFS4ERR_RETRY_UNCACHED_REP) {
|
||||||
|
res->status = status;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (argop->opnum) {
|
||||||
|
case OP_CB_LAYOUTRECALL:
|
||||||
|
dprintf(1, "OP_CB_LAYOUTRECALL\n");
|
||||||
|
res->status = handle_cb_layoutrecall(rpc_clnt,
|
||||||
|
&argop->args.layoutrecall, &resop->res.layoutrecall);
|
||||||
|
break;
|
||||||
|
case OP_CB_RECALL_SLOT:
|
||||||
|
dprintf(1, "OP_CB_RECALL_SLOT\n");
|
||||||
|
res->status = handle_cb_recall_slot(&argop->args.recall_slot,
|
||||||
|
&resop->res.recall_slot);
|
||||||
|
break;
|
||||||
|
case OP_CB_SEQUENCE:
|
||||||
|
dprintf(1, "OP_CB_SEQUENCE\n");
|
||||||
|
status = handle_cb_sequence(rpc_clnt, &argop->args.sequence,
|
||||||
|
&resop->res.sequence);
|
||||||
|
if (status == NFS4_OK)
|
||||||
|
res->status = resop->res.sequence.status;
|
||||||
|
break;
|
||||||
|
case OP_CB_GETATTR:
|
||||||
|
dprintf(1, "OP_CB_GETATTR\n");
|
||||||
|
res->status = NFS4ERR_NOTSUPP;
|
||||||
|
break;
|
||||||
|
case OP_CB_RECALL:
|
||||||
|
dprintf(1, "OP_CB_RECALL\n");
|
||||||
|
res->status = handle_cb_recall(rpc_clnt,
|
||||||
|
&argop->args.recall, &resop->res.recall);
|
||||||
|
break;
|
||||||
|
case OP_CB_NOTIFY:
|
||||||
|
dprintf(1, "OP_CB_NOTIFY\n");
|
||||||
|
res->status = NFS4ERR_NOTSUPP;
|
||||||
|
break;
|
||||||
|
case OP_CB_PUSH_DELEG:
|
||||||
|
dprintf(1, "OP_CB_PUSH_DELEG\n");
|
||||||
|
res->status = NFS4ERR_NOTSUPP;
|
||||||
|
break;
|
||||||
|
case OP_CB_RECALL_ANY:
|
||||||
|
dprintf(1, "OP_CB_RECALL_ANY\n");
|
||||||
|
res->status = NFS4ERR_NOTSUPP;
|
||||||
|
break;
|
||||||
|
case OP_CB_RECALLABLE_OBJ_AVAIL:
|
||||||
|
dprintf(1, "OP_CB_RECALLABLE_OBJ_AVAIL\n");
|
||||||
|
res->status = NFS4ERR_NOTSUPP;
|
||||||
|
break;
|
||||||
|
case OP_CB_WANTS_CANCELLED:
|
||||||
|
dprintf(1, "OP_CB_WANTS_CANCELLED\n");
|
||||||
|
res->status = NFS4ERR_NOTSUPP;
|
||||||
|
break;
|
||||||
|
case OP_CB_NOTIFY_LOCK:
|
||||||
|
dprintf(1, "OP_CB_NOTIFY_LOCK\n");
|
||||||
|
res->status = NFS4ERR_NOTSUPP;
|
||||||
|
break;
|
||||||
|
case OP_CB_NOTIFY_DEVICEID:
|
||||||
|
dprintf(1, "OP_CB_NOTIFY_DEVICEID\n");
|
||||||
|
res->status = NFS4ERR_NOTSUPP;
|
||||||
|
break;
|
||||||
|
case OP_CB_ILLEGAL:
|
||||||
|
dprintf(1, "OP_CB_ILLEGAL\n");
|
||||||
|
res->status = NFS4ERR_NOTSUPP;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
eprintf("operation %u not supported\n", argop->opnum);
|
||||||
|
res->status = NFS4ERR_NOTSUPP;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
res->resarray_count++;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
/* free the arguments */
|
||||||
|
xdr->x_op = XDR_FREE;
|
||||||
|
proc_cb_compound_args(xdr, &args);
|
||||||
|
|
||||||
|
*reply = res;
|
||||||
|
dprintf(CBSLVL, "<-- handle_compound() returning %s (%u results)\n",
|
||||||
|
nfs_error_string(res->status), res->resarray_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
int nfs41_handle_callback(void *rpc_clnt, void *cb, struct cb_compound_res **reply)
|
||||||
|
{
|
||||||
|
nfs41_rpc_clnt *rpc = (nfs41_rpc_clnt *)rpc_clnt;
|
||||||
|
cb_req *request = (cb_req *)cb;
|
||||||
|
uint32_t status = 0;
|
||||||
|
|
||||||
|
dprintf(1, "nfs41_handle_callback: received call\n");
|
||||||
|
if (request->rq_prog != NFS41_RPC_CBPROGRAM) {
|
||||||
|
eprintf("invalid rpc program %u\n", request->rq_prog);
|
||||||
|
status = 2;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (request->rq_proc) {
|
||||||
|
case CB_NULL:
|
||||||
|
dprintf(1, "CB_NULL\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CB_COMPOUND:
|
||||||
|
dprintf(1, "CB_COMPOUND\n");
|
||||||
|
handle_cb_compound(rpc, request, reply);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
dprintf(1, "invalid rpc procedure %u\n", request->rq_proc);
|
||||||
|
status = 3;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
539
daemon/callback_xdr.c
Normal file
539
daemon/callback_xdr.c
Normal file
|
|
@ -0,0 +1,539 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nfs41_callback.h"
|
||||||
|
|
||||||
|
#include "nfs41_ops.h"
|
||||||
|
#include "daemon_debug.h"
|
||||||
|
|
||||||
|
#define CBXLVL 2 /* dprintf level for callback xdr logging */
|
||||||
|
#define CBX_ERR(msg) dprintf((CBXLVL), __FUNCTION__ ": failed at " msg "\n")
|
||||||
|
|
||||||
|
|
||||||
|
/* common types */
|
||||||
|
static bool_t common_stateid(XDR *xdr, stateid4 *stateid)
|
||||||
|
{
|
||||||
|
return xdr_u_int32_t(xdr, &stateid->seqid)
|
||||||
|
&& xdr_opaque(xdr, (char*)stateid->other, 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t common_fh(XDR *xdr, nfs41_fh *fh)
|
||||||
|
{
|
||||||
|
return xdr_u_int32_t(xdr, &fh->len)
|
||||||
|
&& fh->len <= NFS4_FHSIZE
|
||||||
|
&& xdr_opaque(xdr, (char*)fh->fh, fh->len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t common_fsid(XDR *xdr, nfs41_fsid *fsid)
|
||||||
|
{
|
||||||
|
return xdr_u_int64_t(xdr, &fsid->major)
|
||||||
|
&& xdr_u_int64_t(xdr, &fsid->minor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* OP_CB_LAYOUTRECALL */
|
||||||
|
static bool_t op_cb_layoutrecall_file(XDR *xdr, struct cb_recall_file *args)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
result = common_fh(xdr, &args->fh);
|
||||||
|
if (!result) { CBX_ERR("layoutrecall_file.fh"); goto out; }
|
||||||
|
|
||||||
|
result = xdr_u_int64_t(xdr, &args->offset);
|
||||||
|
if (!result) { CBX_ERR("layoutrecall_file.offset"); goto out; }
|
||||||
|
|
||||||
|
result = xdr_u_int64_t(xdr, &args->length);
|
||||||
|
if (!result) { CBX_ERR("layoutrecall_file.length"); goto out; }
|
||||||
|
|
||||||
|
result = common_stateid(xdr, &args->stateid);
|
||||||
|
if (!result) { CBX_ERR("layoutrecall_file.stateid"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t op_cb_layoutrecall_fsid(XDR *xdr, union cb_recall_file_args *args)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
result = common_fsid(xdr, &args->fsid);
|
||||||
|
if (!result) { CBX_ERR("layoutrecall_fsid.fsid"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct xdr_discrim cb_layoutrecall_discrim[] = {
|
||||||
|
{ PNFS_RETURN_FILE, (xdrproc_t)op_cb_layoutrecall_file },
|
||||||
|
{ PNFS_RETURN_FSID, (xdrproc_t)op_cb_layoutrecall_fsid },
|
||||||
|
{ PNFS_RETURN_ALL, (xdrproc_t)xdr_void },
|
||||||
|
{ 0, NULL_xdrproc_t }
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool_t op_cb_layoutrecall_args(XDR *xdr, struct cb_layoutrecall_args *args)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
result = xdr_enum(xdr, (enum_t*)&args->type);
|
||||||
|
if (!result) { CBX_ERR("layoutrecall_args.type"); goto out; }
|
||||||
|
|
||||||
|
result = xdr_enum(xdr, (enum_t*)&args->iomode);
|
||||||
|
if (!result) { CBX_ERR("layoutrecall_args.iomode"); goto out; }
|
||||||
|
|
||||||
|
result = xdr_bool(xdr, &args->changed);
|
||||||
|
if (!result) { CBX_ERR("layoutrecall_args.changed"); goto out; }
|
||||||
|
|
||||||
|
result = xdr_union(xdr, (enum_t*)&args->recall.type,
|
||||||
|
(char*)&args->recall.args, cb_layoutrecall_discrim, NULL_xdrproc_t);
|
||||||
|
if (!result) { CBX_ERR("layoutrecall_args.recall"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t op_cb_layoutrecall_res(XDR *xdr, struct cb_layoutrecall_res *res)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
result = xdr_enum(xdr, &res->status);
|
||||||
|
if (!result) { CBX_ERR("layoutrecall_res.status"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* OP_CB_RECALL_SLOT */
|
||||||
|
static bool_t op_cb_recall_slot_args(XDR *xdr, struct cb_recall_slot_args *res)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
result = xdr_u_int32_t(xdr, &res->target_highest_slotid);
|
||||||
|
if (!result) { CBX_ERR("recall_slot.target_highest_slotid"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t op_cb_recall_slot_res(XDR *xdr, struct cb_recall_slot_res *res)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
result = xdr_enum(xdr, &res->status);
|
||||||
|
if (!result) { CBX_ERR("recall_slot.status"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* OP_CB_SEQUENCE */
|
||||||
|
static bool_t op_cb_sequence_ref(XDR *xdr, struct cb_sequence_ref *args)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
result = xdr_u_int32_t(xdr, &args->sequenceid);
|
||||||
|
if (!result) { CBX_ERR("sequence_ref.sequenceid"); goto out; }
|
||||||
|
|
||||||
|
result = xdr_u_int32_t(xdr, &args->slotid);
|
||||||
|
if (!result) { CBX_ERR("sequence_ref.slotid"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t op_cb_sequence_ref_list(XDR *xdr, struct cb_sequence_ref_list *args)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
result = xdr_opaque(xdr, args->sessionid, NFS4_SESSIONID_SIZE);
|
||||||
|
if (!result) { CBX_ERR("sequence_ref_list.sessionid"); goto out; }
|
||||||
|
|
||||||
|
result = xdr_array(xdr, (char**)&args->calls, &args->call_count,
|
||||||
|
64, sizeof(struct cb_sequence_ref), (xdrproc_t)op_cb_sequence_ref);
|
||||||
|
if (!result) { CBX_ERR("sequence_ref_list.calls"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t op_cb_sequence_args(XDR *xdr, struct cb_sequence_args *args)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
dprintf(1, "decoding sequence args\n");
|
||||||
|
result = xdr_opaque(xdr, args->sessionid, NFS4_SESSIONID_SIZE);
|
||||||
|
if (!result) { CBX_ERR("sequence_args.sessionid"); goto out; }
|
||||||
|
|
||||||
|
result = xdr_u_int32_t(xdr, &args->sequenceid);
|
||||||
|
if (!result) { CBX_ERR("sequence_args.sequenceid"); goto out; }
|
||||||
|
|
||||||
|
result = xdr_u_int32_t(xdr, &args->slotid);
|
||||||
|
if (!result) { CBX_ERR("sequence_args.slotid"); goto out; }
|
||||||
|
|
||||||
|
result = xdr_u_int32_t(xdr, &args->highest_slotid);
|
||||||
|
if (!result) { CBX_ERR("sequence_args.highest_slotid"); goto out; }
|
||||||
|
|
||||||
|
result = xdr_bool(xdr, &args->cachethis);
|
||||||
|
if (!result) { CBX_ERR("sequence_args.cachethis"); goto out; }
|
||||||
|
|
||||||
|
result = xdr_array(xdr, (char**)&args->ref_lists,
|
||||||
|
&args->ref_list_count, 64, sizeof(struct cb_sequence_ref_list),
|
||||||
|
(xdrproc_t)op_cb_sequence_ref_list);
|
||||||
|
if (!result) { CBX_ERR("sequence_args.ref_lists"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t op_cb_sequence_res_ok(XDR *xdr, struct cb_sequence_res_ok *res)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
result = xdr_opaque(xdr, res->sessionid, NFS4_SESSIONID_SIZE);
|
||||||
|
if (!result) { CBX_ERR("sequence_res.sessionid"); goto out; }
|
||||||
|
|
||||||
|
result = xdr_u_int32_t(xdr, &res->sequenceid);
|
||||||
|
if (!result) { CBX_ERR("sequence_res.sequenceid"); goto out; }
|
||||||
|
|
||||||
|
result = xdr_u_int32_t(xdr, &res->slotid);
|
||||||
|
if (!result) { CBX_ERR("sequence_res.slotid"); goto out; }
|
||||||
|
|
||||||
|
result = xdr_u_int32_t(xdr, &res->highest_slotid);
|
||||||
|
if (!result) { CBX_ERR("sequence_res.highest_slotid"); goto out; }
|
||||||
|
|
||||||
|
result = xdr_u_int32_t(xdr, &res->target_highest_slotid);
|
||||||
|
if (!result) { CBX_ERR("sequence_res.target_highest_slotid"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct xdr_discrim cb_sequence_res_discrim[] = {
|
||||||
|
{ NFS4_OK, (xdrproc_t)op_cb_sequence_res_ok },
|
||||||
|
{ 0, NULL_xdrproc_t }
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool_t op_cb_sequence_res(XDR *xdr, struct cb_sequence_res *res)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
result = xdr_union(xdr, &res->status, (char*)&res->ok,
|
||||||
|
cb_sequence_res_discrim, (xdrproc_t)xdr_void);
|
||||||
|
if (!result) { CBX_ERR("seq:argop.args"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* OP_CB_GETATTR */
|
||||||
|
static bool_t op_cb_getattr_args(XDR *xdr, struct cb_getattr_args *res)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
result = xdr_u_int32_t(xdr, &res->target_highest_slotid);
|
||||||
|
if (!result) { CBX_ERR("getattr.target_highest_slotid"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t op_cb_getattr_res(XDR *xdr, struct cb_getattr_res *res)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
result = xdr_enum(xdr, &res->status);
|
||||||
|
if (!result) { CBX_ERR("getattr.status"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* OP_CB_RECALL */
|
||||||
|
static bool_t op_cb_recall_args(XDR *xdr, struct cb_recall_args *args)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
dprintf(1, "decoding recall args\n");
|
||||||
|
result = common_stateid(xdr, &args->stateid);
|
||||||
|
if (!result) { CBX_ERR("recall.stateid"); goto out; }
|
||||||
|
|
||||||
|
result = xdr_bool(xdr, &args->truncate);
|
||||||
|
if (!result) { CBX_ERR("recall.truncate"); goto out; }
|
||||||
|
|
||||||
|
result = common_fh(xdr, &args->fh);
|
||||||
|
if (!result) { CBX_ERR("recall.fh"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t op_cb_recall_res(XDR *xdr, struct cb_recall_res *res)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
result = xdr_enum(xdr, &res->status);
|
||||||
|
if (!result) { CBX_ERR("recall.status"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* OP_CB_NOTIFY */
|
||||||
|
static bool_t op_cb_notify_args(XDR *xdr, struct cb_notify_args *res)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
result = xdr_u_int32_t(xdr, &res->target_highest_slotid);
|
||||||
|
if (!result) { CBX_ERR("notify.target_highest_slotid"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t op_cb_notify_res(XDR *xdr, struct cb_notify_res *res)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
result = xdr_enum(xdr, &res->status);
|
||||||
|
if (!result) { CBX_ERR("notify.status"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* OP_CB_PUSH_DELEG */
|
||||||
|
static bool_t op_cb_push_deleg_args(XDR *xdr, struct cb_push_deleg_args *res)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
result = xdr_u_int32_t(xdr, &res->target_highest_slotid);
|
||||||
|
if (!result) { CBX_ERR("push_deleg.target_highest_slotid"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t op_cb_push_deleg_res(XDR *xdr, struct cb_push_deleg_res *res)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
result = xdr_enum(xdr, &res->status);
|
||||||
|
if (!result) { CBX_ERR("push_deleg.status"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* OP_CB_RECALL_ANY */
|
||||||
|
static bool_t op_cb_recall_any_args(XDR *xdr, struct cb_recall_any_args *res)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
result = xdr_u_int32_t(xdr, &res->target_highest_slotid);
|
||||||
|
if (!result) { CBX_ERR("recall_any.target_highest_slotid"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t op_cb_recall_any_res(XDR *xdr, struct cb_recall_any_res *res)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
result = xdr_enum(xdr, &res->status);
|
||||||
|
if (!result) { CBX_ERR("recall_any.status"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* OP_CB_RECALLABLE_OBJ_AVAIL */
|
||||||
|
static bool_t op_cb_recallable_obj_avail_args(XDR *xdr, struct cb_recallable_obj_avail_args *res)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
result = xdr_u_int32_t(xdr, &res->target_highest_slotid);
|
||||||
|
if (!result) { CBX_ERR("recallable_obj_avail.target_highest_slotid"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t op_cb_recallable_obj_avail_res(XDR *xdr, struct cb_recallable_obj_avail_res *res)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
result = xdr_enum(xdr, &res->status);
|
||||||
|
if (!result) { CBX_ERR("recallable_obj_avail.status"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* OP_CB_WANTS_CANCELLED */
|
||||||
|
static bool_t op_cb_wants_cancelled_args(XDR *xdr, struct cb_wants_cancelled_args *res)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
result = xdr_u_int32_t(xdr, &res->target_highest_slotid);
|
||||||
|
if (!result) { CBX_ERR("wants_cancelled.target_highest_slotid"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t op_cb_wants_cancelled_res(XDR *xdr, struct cb_wants_cancelled_res *res)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
result = xdr_enum(xdr, &res->status);
|
||||||
|
if (!result) { CBX_ERR("wants_cancelled.status"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* OP_CB_NOTIFY_LOCK */
|
||||||
|
static bool_t op_cb_notify_lock_args(XDR *xdr, struct cb_notify_lock_args *res)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
result = xdr_u_int32_t(xdr, &res->target_highest_slotid);
|
||||||
|
if (!result) { CBX_ERR("notify_lock.target_highest_slotid"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t op_cb_notify_lock_res(XDR *xdr, struct cb_notify_lock_res *res)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
result = xdr_enum(xdr, &res->status);
|
||||||
|
if (!result) { CBX_ERR("notify_lock.status"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* OP_CB_NOTIFY_DEVICEID */
|
||||||
|
static bool_t op_cb_notify_deviceid_args(XDR *xdr, struct cb_notify_deviceid_args *res)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
result = xdr_u_int32_t(xdr, &res->target_highest_slotid);
|
||||||
|
if (!result) { CBX_ERR("notify_deviceid.target_highest_slotid"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t op_cb_notify_deviceid_res(XDR *xdr, struct cb_notify_deviceid_res *res)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
result = xdr_enum(xdr, &res->status);
|
||||||
|
if (!result) { CBX_ERR("notify_deviceid.status"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CB_COMPOUND */
|
||||||
|
static bool_t cb_compound_tag(XDR *xdr, struct cb_compound_tag *args)
|
||||||
|
{
|
||||||
|
return xdr_u_int32_t(xdr, &args->len)
|
||||||
|
&& args->len <= CB_COMPOUND_MAX_TAG
|
||||||
|
&& xdr_opaque(xdr, args->str, args->len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct xdr_discrim cb_argop_discrim[] = {
|
||||||
|
{ OP_CB_LAYOUTRECALL, (xdrproc_t)op_cb_layoutrecall_args },
|
||||||
|
{ OP_CB_RECALL_SLOT, (xdrproc_t)op_cb_recall_slot_args },
|
||||||
|
{ OP_CB_SEQUENCE, (xdrproc_t)op_cb_sequence_args },
|
||||||
|
{ OP_CB_GETATTR, (xdrproc_t)op_cb_getattr_args },
|
||||||
|
{ OP_CB_RECALL, (xdrproc_t)op_cb_recall_args },
|
||||||
|
{ OP_CB_NOTIFY, (xdrproc_t)op_cb_notify_args },
|
||||||
|
{ OP_CB_PUSH_DELEG, (xdrproc_t)op_cb_push_deleg_args },
|
||||||
|
{ OP_CB_RECALL_ANY, (xdrproc_t)op_cb_recall_any_args },
|
||||||
|
{ OP_CB_RECALLABLE_OBJ_AVAIL, (xdrproc_t)op_cb_recallable_obj_avail_args },
|
||||||
|
{ OP_CB_WANTS_CANCELLED, (xdrproc_t)op_cb_wants_cancelled_args },
|
||||||
|
{ OP_CB_NOTIFY_LOCK, (xdrproc_t)op_cb_notify_lock_args },
|
||||||
|
{ OP_CB_NOTIFY_DEVICEID, (xdrproc_t)op_cb_notify_deviceid_args },
|
||||||
|
{ OP_CB_ILLEGAL, NULL_xdrproc_t },
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool_t cb_compound_argop(XDR *xdr, struct cb_argop *args)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
result = xdr_union(xdr, &args->opnum, (char*)&args->args,
|
||||||
|
cb_argop_discrim, NULL_xdrproc_t);
|
||||||
|
if (!result) { CBX_ERR("cmb:argop.args"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t proc_cb_compound_args(XDR *xdr, struct cb_compound_args *args)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
result = cb_compound_tag(xdr, &args->tag);
|
||||||
|
if (!result) { CBX_ERR("compound.tag"); goto out; }
|
||||||
|
|
||||||
|
result = xdr_u_int32_t(xdr, &args->minorversion);
|
||||||
|
if (!result) { CBX_ERR("compound.minorversion"); goto out; }
|
||||||
|
|
||||||
|
/* "superfluous in NFSv4.1 and MUST be ignored by the client" */
|
||||||
|
result = xdr_u_int32_t(xdr, &args->callback_ident);
|
||||||
|
if (!result) { CBX_ERR("compound.callback_ident"); goto out; }
|
||||||
|
|
||||||
|
result = xdr_array(xdr, (char**)&args->argarray,
|
||||||
|
&args->argarray_count, CB_COMPOUND_MAX_OPERATIONS,
|
||||||
|
sizeof(struct cb_argop), (xdrproc_t)cb_compound_argop);
|
||||||
|
if (!result) { CBX_ERR("compound.argarray"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct xdr_discrim cb_resop_discrim[] = {
|
||||||
|
{ OP_CB_LAYOUTRECALL, (xdrproc_t)op_cb_layoutrecall_res },
|
||||||
|
{ OP_CB_RECALL_SLOT, (xdrproc_t)op_cb_recall_slot_res },
|
||||||
|
{ OP_CB_SEQUENCE, (xdrproc_t)op_cb_sequence_res },
|
||||||
|
{ OP_CB_GETATTR, (xdrproc_t)op_cb_getattr_res },
|
||||||
|
{ OP_CB_RECALL, (xdrproc_t)op_cb_recall_res },
|
||||||
|
{ OP_CB_NOTIFY, (xdrproc_t)op_cb_notify_res },
|
||||||
|
{ OP_CB_PUSH_DELEG, (xdrproc_t)op_cb_push_deleg_res },
|
||||||
|
{ OP_CB_RECALL_ANY, (xdrproc_t)op_cb_recall_any_res },
|
||||||
|
{ OP_CB_RECALLABLE_OBJ_AVAIL, (xdrproc_t)op_cb_recallable_obj_avail_res },
|
||||||
|
{ OP_CB_WANTS_CANCELLED, (xdrproc_t)op_cb_wants_cancelled_res },
|
||||||
|
{ OP_CB_NOTIFY_LOCK, (xdrproc_t)op_cb_notify_lock_res },
|
||||||
|
{ OP_CB_NOTIFY_DEVICEID, (xdrproc_t)op_cb_notify_deviceid_res },
|
||||||
|
{ OP_CB_ILLEGAL, NULL_xdrproc_t },
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool_t cb_compound_resop(XDR *xdr, struct cb_resop *res)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
result = xdr_union(xdr, &res->opnum, (char*)&res->res,
|
||||||
|
cb_resop_discrim, NULL_xdrproc_t);
|
||||||
|
if (!result) { CBX_ERR("resop.res"); goto out; }
|
||||||
|
out:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t proc_cb_compound_res(XDR *xdr, struct cb_compound_res *res)
|
||||||
|
{
|
||||||
|
bool_t result;
|
||||||
|
|
||||||
|
if (res == NULL)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
result = xdr_enum(xdr, &res->status);
|
||||||
|
if (!result) { CBX_ERR("compound_res.status"); goto out; }
|
||||||
|
|
||||||
|
result = cb_compound_tag(xdr, &res->tag);
|
||||||
|
if (!result) { CBX_ERR("compound_res.tag"); goto out; }
|
||||||
|
|
||||||
|
result = xdr_array(xdr, (char**)&res->resarray,
|
||||||
|
&res->resarray_count, CB_COMPOUND_MAX_OPERATIONS,
|
||||||
|
sizeof(struct cb_resop), (xdrproc_t)cb_compound_resop);
|
||||||
|
if (!result) { CBX_ERR("compound_res.resarray"); goto out; }
|
||||||
|
out:
|
||||||
|
free(res->resarray);
|
||||||
|
free(res);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
440
daemon/daemon_debug.c
Normal file
440
daemon/daemon_debug.c
Normal file
|
|
@ -0,0 +1,440 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "daemon_debug.h"
|
||||||
|
#include "from_kernel.h"
|
||||||
|
#include "nfs41_driver.h"
|
||||||
|
#include "nfs41_ops.h"
|
||||||
|
|
||||||
|
|
||||||
|
static int g_debug_level = DEFAULT_DEBUG_LEVEL;
|
||||||
|
|
||||||
|
void set_debug_level(int level) { g_debug_level = level; }
|
||||||
|
|
||||||
|
void dprintf(int level, LPCSTR format, ...)
|
||||||
|
{
|
||||||
|
if (level <= g_debug_level) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
printf("%04x: ", GetCurrentThreadId());
|
||||||
|
vprintf(format, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void eprintf(LPCSTR format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
fprintf(stderr, "%04x: ", GetCurrentThreadId());
|
||||||
|
vfprintf(stderr, format, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_hexbuf(int level, unsigned char *title, unsigned char *buf, int len)
|
||||||
|
{
|
||||||
|
int j, k;
|
||||||
|
if (level > g_debug_level) return;
|
||||||
|
printf("%s", title);
|
||||||
|
for(j = 0, k = 0; j < len; j++, k++) {
|
||||||
|
printf("%02x '%c' ", buf[j], isascii(buf[j])? buf[j]:' ');
|
||||||
|
if (((k+1) % 10 == 0 && k > 0)) {
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_create_attributes(int level, DWORD create_opts) {
|
||||||
|
if (level > g_debug_level) return;
|
||||||
|
printf("create attributes: ");
|
||||||
|
if (create_opts & FILE_DIRECTORY_FILE)
|
||||||
|
printf("DIRECTORY_FILE ");
|
||||||
|
if (create_opts & FILE_NON_DIRECTORY_FILE)
|
||||||
|
printf("NON_DIRECTORY_FILE ");
|
||||||
|
if (create_opts & FILE_WRITE_THROUGH)
|
||||||
|
printf("WRITE_THROUGH ");
|
||||||
|
if (create_opts & FILE_SEQUENTIAL_ONLY)
|
||||||
|
printf("SEQUENTIAL_ONLY ");
|
||||||
|
if (create_opts & FILE_RANDOM_ACCESS)
|
||||||
|
printf("RANDOM_ACCESS ");
|
||||||
|
if (create_opts & FILE_NO_INTERMEDIATE_BUFFERING)
|
||||||
|
printf("NO_INTERMEDIATE_BUFFERING ");
|
||||||
|
if (create_opts & FILE_SYNCHRONOUS_IO_ALERT)
|
||||||
|
printf("SYNCHRONOUS_IO_ALERT ");
|
||||||
|
if (create_opts & FILE_SYNCHRONOUS_IO_NONALERT)
|
||||||
|
printf("SYNCHRONOUS_IO_NONALERT ");
|
||||||
|
if (create_opts & FILE_CREATE_TREE_CONNECTION)
|
||||||
|
printf("CREATE_TREE_CONNECTION ");
|
||||||
|
if (create_opts & FILE_COMPLETE_IF_OPLOCKED)
|
||||||
|
printf("COMPLETE_IF_OPLOCKED ");
|
||||||
|
if (create_opts & FILE_NO_EA_KNOWLEDGE)
|
||||||
|
printf("NO_EA_KNOWLEDGE ");
|
||||||
|
if (create_opts & FILE_OPEN_REPARSE_POINT)
|
||||||
|
printf("OPEN_REPARSE_POINT ");
|
||||||
|
if (create_opts & FILE_DELETE_ON_CLOSE)
|
||||||
|
printf("DELETE_ON_CLOSE ");
|
||||||
|
if (create_opts & FILE_OPEN_BY_FILE_ID)
|
||||||
|
printf("OPEN_BY_FILE_ID ");
|
||||||
|
if (create_opts & FILE_OPEN_FOR_BACKUP_INTENT)
|
||||||
|
printf("OPEN_FOR_BACKUP_INTENT ");
|
||||||
|
if (create_opts & FILE_RESERVE_OPFILTER)
|
||||||
|
printf("RESERVE_OPFILTER");
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_disposition(int level, DWORD disposition) {
|
||||||
|
if (level > g_debug_level) return;
|
||||||
|
printf("userland disposition = ");
|
||||||
|
if (disposition == FILE_SUPERSEDE)
|
||||||
|
printf("FILE_SUPERSEDE\n");
|
||||||
|
else if (disposition == FILE_CREATE)
|
||||||
|
printf("FILE_CREATE\n");
|
||||||
|
else if (disposition == FILE_OPEN)
|
||||||
|
printf("FILE_OPEN\n");
|
||||||
|
else if (disposition == FILE_OPEN_IF)
|
||||||
|
printf("FILE_OPEN_IF\n");
|
||||||
|
else if (disposition == FILE_OVERWRITE)
|
||||||
|
printf("FILE_OVERWRITE\n");
|
||||||
|
else if (disposition == FILE_OVERWRITE_IF)
|
||||||
|
printf("FILE_OVERWRITE_IF\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_access_mask(int level, DWORD access_mask) {
|
||||||
|
if (level > g_debug_level) return;
|
||||||
|
printf("access mask: ");
|
||||||
|
if (access_mask & FILE_READ_DATA)
|
||||||
|
printf("READ ");
|
||||||
|
if (access_mask & STANDARD_RIGHTS_READ)
|
||||||
|
printf("READ_ACL ");
|
||||||
|
if (access_mask & FILE_READ_ATTRIBUTES)
|
||||||
|
printf("READ_ATTR ");
|
||||||
|
if (access_mask & FILE_READ_EA)
|
||||||
|
printf("READ_EA ");
|
||||||
|
if (access_mask & FILE_WRITE_DATA)
|
||||||
|
printf("WRITE ");
|
||||||
|
if (access_mask & STANDARD_RIGHTS_WRITE)
|
||||||
|
printf("WRITE_ACL ");
|
||||||
|
if (access_mask & FILE_WRITE_ATTRIBUTES)
|
||||||
|
printf("WRITE_ATTR ");
|
||||||
|
if (access_mask & FILE_WRITE_EA)
|
||||||
|
printf("WRITE_EA ");
|
||||||
|
if (access_mask & FILE_APPEND_DATA)
|
||||||
|
printf("APPEND ");
|
||||||
|
if (access_mask & FILE_EXECUTE)
|
||||||
|
printf("EXECUTE ");
|
||||||
|
if (access_mask & FILE_LIST_DIRECTORY)
|
||||||
|
printf("LIST ");
|
||||||
|
if (access_mask & FILE_TRAVERSE)
|
||||||
|
printf("TRAVERSE ");
|
||||||
|
if (access_mask & SYNCHRONIZE)
|
||||||
|
printf("SYNC ");
|
||||||
|
if (access_mask & FILE_DELETE_CHILD)
|
||||||
|
printf("DELETE_CHILD");
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_share_mode(int level, DWORD mode)
|
||||||
|
{
|
||||||
|
if (level > g_debug_level) return;
|
||||||
|
printf("share mode: ");
|
||||||
|
if (mode & FILE_SHARE_READ)
|
||||||
|
printf("READ ");
|
||||||
|
if (mode & FILE_SHARE_WRITE)
|
||||||
|
printf("WRITE ");
|
||||||
|
if (mode & FILE_SHARE_DELETE)
|
||||||
|
printf("DELETE");
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_file_id_both_dir_info(int level, FILE_ID_BOTH_DIR_INFO *pboth_dir_info)
|
||||||
|
{
|
||||||
|
if (level > g_debug_level) return;
|
||||||
|
printf("FILE_ID_BOTH_DIR_INFO %p %d\n", pboth_dir_info, sizeof(unsigned char *));
|
||||||
|
printf("\tNextEntryOffset=%ld %d %d\n", pboth_dir_info->NextEntryOffset, sizeof(pboth_dir_info->NextEntryOffset), sizeof(DWORD));
|
||||||
|
printf("\tFileIndex=%ld %d\n", pboth_dir_info->FileIndex, sizeof(pboth_dir_info->FileIndex));
|
||||||
|
printf("\tCreationTime=0x%x %d\n", pboth_dir_info->CreationTime.QuadPart, sizeof(pboth_dir_info->CreationTime));
|
||||||
|
printf("\tLastAccessTime=0x%x %d\n", pboth_dir_info->LastAccessTime.QuadPart, sizeof(pboth_dir_info->LastAccessTime));
|
||||||
|
printf("\tLastWriteTime=0x%x %d\n", pboth_dir_info->LastWriteTime.QuadPart, sizeof(pboth_dir_info->LastWriteTime));
|
||||||
|
printf("\tChangeTime=0x%x %d\n", pboth_dir_info->ChangeTime.QuadPart, sizeof(pboth_dir_info->ChangeTime));
|
||||||
|
printf("\tEndOfFile=0x%x %d\n", pboth_dir_info->EndOfFile.QuadPart, sizeof(pboth_dir_info->EndOfFile));
|
||||||
|
printf("\tAllocationSize=0x%x %d\n", pboth_dir_info->AllocationSize.QuadPart, sizeof(pboth_dir_info->AllocationSize));
|
||||||
|
printf("\tFileAttributes=%ld %d\n", pboth_dir_info->FileAttributes, sizeof(pboth_dir_info->FileAttributes));
|
||||||
|
printf("\tFileNameLength=%ld %d\n", pboth_dir_info->FileNameLength, sizeof(pboth_dir_info->FileNameLength));
|
||||||
|
printf("\tEaSize=%ld %d\n", pboth_dir_info->EaSize, sizeof(pboth_dir_info->EaSize));
|
||||||
|
printf("\tShortNameLength=%d %d\n", pboth_dir_info->ShortNameLength, sizeof(pboth_dir_info->ShortNameLength));
|
||||||
|
printf("\tShortName='%S' %d\n", pboth_dir_info->ShortName, sizeof(pboth_dir_info->ShortName));
|
||||||
|
printf("\tFileId=0x%x %d\n", pboth_dir_info->FileId.QuadPart, sizeof(pboth_dir_info->FileId));
|
||||||
|
printf("\tFileName='%S' %p\n", pboth_dir_info->FileName, pboth_dir_info->FileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_opcode(int level, DWORD opcode)
|
||||||
|
{
|
||||||
|
dprintf(level, (LPCSTR)opcode2string(opcode));
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* opcode2string(DWORD opcode)
|
||||||
|
{
|
||||||
|
switch(opcode) {
|
||||||
|
case NFS41_SHUTDOWN: return "NFS41_SHUTDOWN";
|
||||||
|
case NFS41_MOUNT: return "NFS41_MOUNT";
|
||||||
|
case NFS41_UNMOUNT: return "NFS41_UNMOUNT";
|
||||||
|
case NFS41_OPEN: return "NFS41_OPEN";
|
||||||
|
case NFS41_CLOSE: return "NFS41_CLOSE";
|
||||||
|
case NFS41_READ: return "NFS41_READ";
|
||||||
|
case NFS41_WRITE: return "NFS41_WRITE";
|
||||||
|
case NFS41_LOCK: return "NFS41_LOCK";
|
||||||
|
case NFS41_UNLOCK: return "NFS41_UNLOCK";
|
||||||
|
case NFS41_DIR_QUERY: return "NFS41_DIR_QUERY";
|
||||||
|
case NFS41_FILE_QUERY: return "NFS41_FILE_QUERY";
|
||||||
|
case NFS41_FILE_SET: return "NFS41_FILE_SET";
|
||||||
|
case NFS41_EA_SET: return "NFS41_EA_SET";
|
||||||
|
case NFS41_VOLUME_QUERY: return "NFS41_VOLUME_QUERY";
|
||||||
|
default: return "UNKNOWN";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* nfs_opnum_to_string(int opnum)
|
||||||
|
{
|
||||||
|
switch (opnum)
|
||||||
|
{
|
||||||
|
case OP_ACCESS: return "ACCESS";
|
||||||
|
case OP_CLOSE: return "CLOSE";
|
||||||
|
case OP_COMMIT: return "COMMIT";
|
||||||
|
case OP_CREATE: return "CREATE";
|
||||||
|
case OP_DELEGPURGE: return "DELEGPURGE";
|
||||||
|
case OP_DELEGRETURN: return "DELEGRETURN";
|
||||||
|
case OP_GETATTR: return "GETATTR";
|
||||||
|
case OP_GETFH: return "GETFH";
|
||||||
|
case OP_LINK: return "LINK";
|
||||||
|
case OP_LOCK: return "LOCK";
|
||||||
|
case OP_LOCKT: return "LOCKT";
|
||||||
|
case OP_LOCKU: return "LOCKU";
|
||||||
|
case OP_LOOKUP: return "LOOKUP";
|
||||||
|
case OP_LOOKUPP: return "LOOKUPP";
|
||||||
|
case OP_NVERIFY: return "NVERIFY";
|
||||||
|
case OP_OPEN: return "OPEN";
|
||||||
|
case OP_OPENATTR: return "OPENATTR";
|
||||||
|
case OP_OPEN_CONFIRM: return "OPEN_CONFIRM";
|
||||||
|
case OP_OPEN_DOWNGRADE: return "OPEN_DOWNGRADE";
|
||||||
|
case OP_PUTFH: return "PUTFH";
|
||||||
|
case OP_PUTPUBFH: return "PUTPUBFH";
|
||||||
|
case OP_PUTROOTFH: return "PUTROOTFH";
|
||||||
|
case OP_READ: return "READ";
|
||||||
|
case OP_READDIR: return "READDIR";
|
||||||
|
case OP_READLINK: return "READLINK";
|
||||||
|
case OP_REMOVE: return "REMOVE";
|
||||||
|
case OP_RENAME: return "RENAME";
|
||||||
|
case OP_RENEW: return "RENEW";
|
||||||
|
case OP_RESTOREFH: return "RESTOREFH";
|
||||||
|
case OP_SAVEFH: return "SAVEFH";
|
||||||
|
case OP_SECINFO: return "SECINFO";
|
||||||
|
case OP_SETATTR: return "SETATTR";
|
||||||
|
case OP_SETCLIENTID: return "SETCLIENTID";
|
||||||
|
case OP_SETCLIENTID_CONFIRM: return "SETCLIENTID_CONFIRM";
|
||||||
|
case OP_VERIFY: return "VERIFY";
|
||||||
|
case OP_WRITE: return "WRITE";
|
||||||
|
case OP_RELEASE_LOCKOWNER: return "RELEASE_LOCKOWNER";
|
||||||
|
case OP_BACKCHANNEL_CTL: return "BACKCHANNEL_CTL";
|
||||||
|
case OP_BIND_CONN_TO_SESSION: return "BIND_CONN_TO_SESSION";
|
||||||
|
case OP_EXCHANGE_ID: return "EXCHANGE_ID";
|
||||||
|
case OP_CREATE_SESSION: return "CREATE_SESSION";
|
||||||
|
case OP_DESTROY_SESSION: return "DESTROY_SESSION";
|
||||||
|
case OP_FREE_STATEID: return "FREE_STATEID";
|
||||||
|
case OP_GET_DIR_DELEGATION: return "GET_DIR_DELEGATION";
|
||||||
|
case OP_GETDEVICEINFO: return "GETDEVICEINFO";
|
||||||
|
case OP_GETDEVICELIST: return "GETDEVICELIST";
|
||||||
|
case OP_LAYOUTCOMMIT: return "LAYOUTCOMMIT";
|
||||||
|
case OP_LAYOUTGET: return "LAYOUTGET";
|
||||||
|
case OP_LAYOUTRETURN: return "LAYOUTRETURN";
|
||||||
|
case OP_SECINFO_NO_NAME: return "SECINFO_NO_NAME";
|
||||||
|
case OP_SEQUENCE: return "SEQUENCE";
|
||||||
|
case OP_SET_SSV: return "SET_SSV";
|
||||||
|
case OP_TEST_STATEID: return "TEST_STATEID";
|
||||||
|
case OP_WANT_DELEGATION: return "WANT_DELEGATION";
|
||||||
|
case OP_DESTROY_CLIENTID: return "DESTROY_CLIENTID";
|
||||||
|
case OP_RECLAIM_COMPLETE: return "RECLAIM_COMPLETE";
|
||||||
|
case OP_ILLEGAL: return "ILLEGAL";
|
||||||
|
default: return "invalid nfs opnum";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* nfs_error_string(int status)
|
||||||
|
{
|
||||||
|
switch (status)
|
||||||
|
{
|
||||||
|
case NFS4_OK: return "NFS4_OK";
|
||||||
|
case NFS4ERR_PERM: return "NFS4ERR_PERM";
|
||||||
|
case NFS4ERR_NOENT: return "NFS4ERR_NOENT";
|
||||||
|
case NFS4ERR_IO: return "NFS4ERR_IO";
|
||||||
|
case NFS4ERR_NXIO: return "NFS4ERR_NXIO";
|
||||||
|
case NFS4ERR_ACCESS: return "NFS4ERR_ACCESS";
|
||||||
|
case NFS4ERR_EXIST: return "NFS4ERR_EXIST";
|
||||||
|
case NFS4ERR_XDEV: return "NFS4ERR_XDEV";
|
||||||
|
case NFS4ERR_NOTDIR: return "NFS4ERR_NOTDIR";
|
||||||
|
case NFS4ERR_ISDIR: return "NFS4ERR_ISDIR";
|
||||||
|
case NFS4ERR_INVAL: return "NFS4ERR_INVAL";
|
||||||
|
case NFS4ERR_FBIG: return "NFS4ERR_FBIG";
|
||||||
|
case NFS4ERR_NOSPC: return "NFS4ERR_NOSPC";
|
||||||
|
case NFS4ERR_ROFS: return "NFS4ERR_ROFS";
|
||||||
|
case NFS4ERR_MLINK: return "NFS4ERR_MLINK";
|
||||||
|
case NFS4ERR_NAMETOOLONG: return "NFS4ERR_NAMETOOLONG";
|
||||||
|
case NFS4ERR_NOTEMPTY: return "NFS4ERR_NOTEMPTY";
|
||||||
|
case NFS4ERR_DQUOT: return "NFS4ERR_DQUOT";
|
||||||
|
case NFS4ERR_STALE: return "NFS4ERR_STALE";
|
||||||
|
case NFS4ERR_BADHANDLE: return "NFS4ERR_BADHANDLE";
|
||||||
|
case NFS4ERR_BAD_COOKIE: return "NFS4ERR_BAD_COOKIE";
|
||||||
|
case NFS4ERR_NOTSUPP: return "NFS4ERR_NOTSUPP";
|
||||||
|
case NFS4ERR_TOOSMALL: return "NFS4ERR_TOOSMALL";
|
||||||
|
case NFS4ERR_SERVERFAULT: return "NFS4ERR_SERVERFAULT";
|
||||||
|
case NFS4ERR_BADTYPE: return "NFS4ERR_BADTYPE";
|
||||||
|
case NFS4ERR_DELAY: return "NFS4ERR_DELAY";
|
||||||
|
case NFS4ERR_SAME: return "NFS4ERR_SAME";
|
||||||
|
case NFS4ERR_DENIED: return "NFS4ERR_DENIED";
|
||||||
|
case NFS4ERR_EXPIRED: return "NFS4ERR_EXPIRED";
|
||||||
|
case NFS4ERR_LOCKED: return "NFS4ERR_LOCKED";
|
||||||
|
case NFS4ERR_GRACE: return "NFS4ERR_GRACE";
|
||||||
|
case NFS4ERR_FHEXPIRED: return "NFS4ERR_FHEXPIRED";
|
||||||
|
case NFS4ERR_SHARE_DENIED: return "NFS4ERR_SHARE_DENIED";
|
||||||
|
case NFS4ERR_WRONGSEC: return "NFS4ERR_WRONGSEC";
|
||||||
|
case NFS4ERR_CLID_INUSE: return "NFS4ERR_CLID_INUSE";
|
||||||
|
case NFS4ERR_RESOURCE: return "NFS4ERR_RESOURCE";
|
||||||
|
case NFS4ERR_MOVED: return "NFS4ERR_MOVED";
|
||||||
|
case NFS4ERR_NOFILEHANDLE: return "NFS4ERR_NOFILEHANDLE";
|
||||||
|
case NFS4ERR_MINOR_VERS_MISMATCH: return "NFS4ERR_MINOR_VERS_MISMATCH";
|
||||||
|
case NFS4ERR_STALE_CLIENTID: return "NFS4ERR_STALE_CLIENTID";
|
||||||
|
case NFS4ERR_STALE_STATEID: return "NFS4ERR_STALE_STATEID";
|
||||||
|
case NFS4ERR_OLD_STATEID: return "NFS4ERR_OLD_STATEID";
|
||||||
|
case NFS4ERR_BAD_STATEID: return "NFS4ERR_BAD_STATEID";
|
||||||
|
case NFS4ERR_BAD_SEQID: return "NFS4ERR_BAD_SEQID";
|
||||||
|
case NFS4ERR_NOT_SAME: return "NFS4ERR_NOT_SAME";
|
||||||
|
case NFS4ERR_LOCK_RANGE: return "NFS4ERR_LOCK_RANGE";
|
||||||
|
case NFS4ERR_SYMLINK: return "NFS4ERR_SYMLINK";
|
||||||
|
case NFS4ERR_RESTOREFH: return "NFS4ERR_RESTOREFH";
|
||||||
|
case NFS4ERR_LEASE_MOVED: return "NFS4ERR_LEASE_MOVED";
|
||||||
|
case NFS4ERR_ATTRNOTSUPP: return "NFS4ERR_ATTRNOTSUPP";
|
||||||
|
case NFS4ERR_NO_GRACE: return "NFS4ERR_NO_GRACE";
|
||||||
|
case NFS4ERR_RECLAIM_BAD: return "NFS4ERR_RECLAIM_BAD";
|
||||||
|
case NFS4ERR_RECLAIM_CONFLICT: return "NFS4ERR_RECLAIM_CONFLICT";
|
||||||
|
case NFS4ERR_BADXDR: return "NFS4ERR_BADXDR";
|
||||||
|
case NFS4ERR_LOCKS_HELD: return "NFS4ERR_LOCKS_HELD";
|
||||||
|
case NFS4ERR_OPENMODE: return "NFS4ERR_OPENMODE";
|
||||||
|
case NFS4ERR_BADOWNER: return "NFS4ERR_BADOWNER";
|
||||||
|
case NFS4ERR_BADCHAR: return "NFS4ERR_BADCHAR";
|
||||||
|
case NFS4ERR_BADNAME: return "NFS4ERR_BADNAME";
|
||||||
|
case NFS4ERR_BAD_RANGE: return "NFS4ERR_BAD_RANGE";
|
||||||
|
case NFS4ERR_LOCK_NOTSUPP: return "NFS4ERR_LOCK_NOTSUPP";
|
||||||
|
case NFS4ERR_OP_ILLEGAL: return "NFS4ERR_OP_ILLEGAL";
|
||||||
|
case NFS4ERR_DEADLOCK: return "NFS4ERR_DEADLOCK";
|
||||||
|
case NFS4ERR_FILE_OPEN: return "NFS4ERR_FILE_OPEN";
|
||||||
|
case NFS4ERR_ADMIN_REVOKED: return "NFS4ERR_ADMIN_REVOKED";
|
||||||
|
case NFS4ERR_CB_PATH_DOWN: return "NFS4ERR_CB_PATH_DOWN";
|
||||||
|
case NFS4ERR_BADIOMODE: return "NFS4ERR_BADIOMODE";
|
||||||
|
case NFS4ERR_BADLAYOUT: return "NFS4ERR_BADLAYOUT";
|
||||||
|
case NFS4ERR_BAD_SESSION_DIGEST: return "NFS4ERR_BAD_SESSION_DIGEST";
|
||||||
|
case NFS4ERR_BADSESSION: return "NFS4ERR_BADSESSION";
|
||||||
|
case NFS4ERR_BADSLOT: return "NFS4ERR_BADSLOT";
|
||||||
|
case NFS4ERR_COMPLETE_ALREADY: return "NFS4ERR_COMPLETE_ALREADY";
|
||||||
|
case NFS4ERR_CONN_NOT_BOUND_TO_SESSION: return "NFS4ERR_CONN_NOT_BOUND_TO_SESSION";
|
||||||
|
case NFS4ERR_DELEG_ALREADY_WANTED: return "NFS4ERR_DELEG_ALREADY_WANTED";
|
||||||
|
case NFS4ERR_BACK_CHAN_BUSY: return "NFS4ERR_BACK_CHAN_BUSY";
|
||||||
|
case NFS4ERR_LAYOUTTRYLATER: return "NFS4ERR_LAYOUTTRYLATER";
|
||||||
|
case NFS4ERR_LAYOUTUNAVAILABLE: return "NFS4ERR_LAYOUTUNAVAILABLE";
|
||||||
|
case NFS4ERR_NOMATCHING_LAYOUT: return "NFS4ERR_NOMATCHING_LAYOUT";
|
||||||
|
case NFS4ERR_RECALLCONFLICT: return "NFS4ERR_RECALLCONFLICT";
|
||||||
|
case NFS4ERR_UNKNOWN_LAYOUTTYPE: return "NFS4ERR_UNKNOWN_LAYOUTTYPE";
|
||||||
|
case NFS4ERR_SEQ_MISORDERED: return "NFS4ERR_SEQ_MISORDERED";
|
||||||
|
case NFS4ERR_SEQUENCE_POS: return "NFS4ERR_SEQUENCE_POS";
|
||||||
|
case NFS4ERR_REQ_TOO_BIG: return "NFS4ERR_REQ_TOO_BIG";
|
||||||
|
case NFS4ERR_REP_TOO_BIG: return "NFS4ERR_REP_TOO_BIG";
|
||||||
|
case NFS4ERR_REP_TOO_BIG_TO_CACHE: return "NFS4ERR_REP_TOO_BIG_TO_CACHE";
|
||||||
|
case NFS4ERR_RETRY_UNCACHED_REP: return "NFS4ERR_RETRY_UNCACHED_REP";
|
||||||
|
case NFS4ERR_UNSAFE_COMPOUND: return "NFS4ERR_UNSAFE_COMPOUND";
|
||||||
|
case NFS4ERR_TOO_MANY_OPS: return "NFS4ERR_TOO_MANY_OPS";
|
||||||
|
case NFS4ERR_OP_NOT_IN_SESSION: return "NFS4ERR_OP_NOT_IN_SESSION";
|
||||||
|
case NFS4ERR_HASH_ALG_UNSUPP: return "NFS4ERR_HASH_ALG_UNSUPP";
|
||||||
|
case NFS4ERR_CLIENTID_BUSY: return "NFS4ERR_CLIENTID_BUSY";
|
||||||
|
case NFS4ERR_PNFS_IO_HOLE: return "NFS4ERR_PNFS_IO_HOLE";
|
||||||
|
case NFS4ERR_SEQ_FALSE_RETRY: return "NFS4ERR_SEQ_FALSE_RETRY";
|
||||||
|
case NFS4ERR_BAD_HIGH_SLOT: return "NFS4ERR_BAD_HIGH_SLOT";
|
||||||
|
case NFS4ERR_DEADSESSION: return "NFS4ERR_DEADSESSION";
|
||||||
|
case NFS4ERR_ENCR_ALG_UNSUPP: return "NFS4ERR_ENCR_ALG_UNSUPP";
|
||||||
|
case NFS4ERR_PNFS_NO_LAYOUT: return "NFS4ERR_PNFS_NO_LAYOUT";
|
||||||
|
case NFS4ERR_NOT_ONLY_OP: return "NFS4ERR_NOT_ONLY_OP";
|
||||||
|
case NFS4ERR_WRONG_CRED: return "NFS4ERR_WRONG_CRED";
|
||||||
|
case NFS4ERR_WRONG_TYPE: return "NFS4ERR_WRONG_TYPE";
|
||||||
|
case NFS4ERR_DIRDELEG_UNAVAIL: return "NFS4ERR_DIRDELEG_UNAVAIL";
|
||||||
|
case NFS4ERR_REJECT_DELEG: return "NFS4ERR_REJECT_DELEG";
|
||||||
|
case NFS4ERR_RETURNCONFLICT: return "NFS4ERR_RETURNCONFLICT";
|
||||||
|
case NFS4ERR_DELEG_REVOKED: return "NFS4ERR_DELEG_REVOKED";
|
||||||
|
default: return "invalid nfs error code";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_condwait_status(int level, int status)
|
||||||
|
{
|
||||||
|
if (level > g_debug_level) return;
|
||||||
|
switch(status) {
|
||||||
|
case WAIT_ABANDONED: printf("WAIT_ABANDONED\n"); break;
|
||||||
|
case WAIT_OBJECT_0: printf("WAIT_OBJECT_0\n"); break;
|
||||||
|
case WAIT_TIMEOUT: printf("WAIT_TIMEOUT\n"); break;
|
||||||
|
case WAIT_FAILED: printf("WAIT_FAILED %d\n", GetLastError());
|
||||||
|
default: printf("unknown status =%d\n", status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_sr_status_flags(int level, int flags)
|
||||||
|
{
|
||||||
|
if (level > g_debug_level) return;
|
||||||
|
printf("%04x: sr_status_flags: ", GetCurrentThreadId());
|
||||||
|
if (flags & SEQ4_STATUS_CB_PATH_DOWN)
|
||||||
|
printf("SEQ4_STATUS_CB_PATH_DOWN ");
|
||||||
|
if (flags & SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING)
|
||||||
|
printf("SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRING ");
|
||||||
|
if (flags & SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED)
|
||||||
|
printf("SEQ4_STATUS_CB_GSS_CONTEXTS_EXPIRED ");
|
||||||
|
if (flags & SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED)
|
||||||
|
printf("SEQ4_STATUS_EXPIRED_ALL_STATE_REVOKED ");
|
||||||
|
if (flags & SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED)
|
||||||
|
printf("SEQ4_STATUS_EXPIRED_SOME_STATE_REVOKED ");
|
||||||
|
if (flags & SEQ4_STATUS_ADMIN_STATE_REVOKED)
|
||||||
|
printf("SEQ4_STATUS_ADMIN_STATE_REVOKED ");
|
||||||
|
if (flags & SEQ4_STATUS_RECALLABLE_STATE_REVOKED)
|
||||||
|
printf("SEQ4_STATUS_RECALLABLE_STATE_REVOKED ");
|
||||||
|
if (flags & SEQ4_STATUS_LEASE_MOVED)
|
||||||
|
printf("SEQ4_STATUS_LEASE_MOVED ");
|
||||||
|
if (flags & SEQ4_STATUS_RESTART_RECLAIM_NEEDED)
|
||||||
|
printf("SEQ4_STATUS_RESTART_RECLAIM_NEEDED ");
|
||||||
|
if (flags & SEQ4_STATUS_CB_PATH_DOWN_SESSION)
|
||||||
|
printf("SEQ4_STATUS_CB_PATH_DOWN_SESSION ");
|
||||||
|
if (flags & SEQ4_STATUS_BACKCHANNEL_FAULT)
|
||||||
|
printf("SEQ4_STATUS_BACKCHANNEL_FAULT ");
|
||||||
|
if (flags & SEQ4_STATUS_DEVID_CHANGED)
|
||||||
|
printf("SEQ4_STATUS_DEVID_CHANGED ");
|
||||||
|
if (flags & SEQ4_STATUS_DEVID_DELETED)
|
||||||
|
printf("SEQ4_STATUS_DEVID_DELETED ");
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
73
daemon/daemon_debug.h
Normal file
73
daemon/daemon_debug.h
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _DAEMON_DEBUG_
|
||||||
|
#define _DAEMON_DEBUG_
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
/* use visual studio's debug heap */
|
||||||
|
# define _CRTDBG_MAP_ALLOC
|
||||||
|
# include <stdlib.h>
|
||||||
|
# include <crtdbg.h>
|
||||||
|
#else
|
||||||
|
# include <stdlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DEFAULT_DEBUG_LEVEL 1
|
||||||
|
|
||||||
|
|
||||||
|
/* daemon_debug.h */
|
||||||
|
void set_debug_level(int level);
|
||||||
|
void dprintf(int level, LPCSTR format, ...);
|
||||||
|
void eprintf(LPCSTR format, ...);
|
||||||
|
|
||||||
|
void print_hexbuf(int level, unsigned char *title, unsigned char *buf, int len);
|
||||||
|
void print_create_attributes(int level, DWORD create_opts);
|
||||||
|
void print_disposition(int level, DWORD disposition);
|
||||||
|
void print_access_mask(int level, DWORD access_mask);
|
||||||
|
void print_share_mode(int level, DWORD mode);
|
||||||
|
void print_file_id_both_dir_info(int level, FILE_ID_BOTH_DIR_INFO *p);
|
||||||
|
void print_opcode(int level, DWORD opcode);
|
||||||
|
const char* opcode2string(DWORD opcode);
|
||||||
|
const char* nfs_opnum_to_string(int opnum);
|
||||||
|
const char* nfs_error_string(int status);
|
||||||
|
void print_condwait_status(int level, int status);
|
||||||
|
void print_sr_status_flags(int level, int flags);
|
||||||
|
|
||||||
|
|
||||||
|
/* pnfs_debug.c */
|
||||||
|
enum pnfs_status;
|
||||||
|
enum pnfs_layout_type;
|
||||||
|
enum pnfs_iomode;
|
||||||
|
struct __pnfs_file_layout;
|
||||||
|
struct __pnfs_file_device;
|
||||||
|
|
||||||
|
const char* pnfs_error_string(enum pnfs_status status);
|
||||||
|
const char* pnfs_layout_type_string(enum pnfs_layout_type type);
|
||||||
|
const char* pnfs_iomode_string(enum pnfs_iomode iomode);
|
||||||
|
|
||||||
|
void dprint_deviceid(int level, const char *title, const unsigned char *deviceid);
|
||||||
|
void dprint_layout(int level, const struct __pnfs_file_layout *layout);
|
||||||
|
void dprint_device(int level, const struct __pnfs_file_device *device);
|
||||||
|
|
||||||
|
#endif
|
||||||
195
daemon/from_kernel.h
Normal file
195
daemon/from_kernel.h
Normal file
|
|
@ -0,0 +1,195 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _NFS41_DAEMON_
|
||||||
|
#define _NFS41_DAEMON_
|
||||||
|
|
||||||
|
#define FILE_DIRECTORY_FILE 0x00000001
|
||||||
|
#define FILE_WRITE_THROUGH 0x00000002
|
||||||
|
#define FILE_SEQUENTIAL_ONLY 0x00000004
|
||||||
|
#define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008
|
||||||
|
|
||||||
|
#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010
|
||||||
|
#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
|
||||||
|
#define FILE_NON_DIRECTORY_FILE 0x00000040
|
||||||
|
#define FILE_CREATE_TREE_CONNECTION 0x00000080
|
||||||
|
|
||||||
|
#define FILE_COMPLETE_IF_OPLOCKED 0x00000100
|
||||||
|
#define FILE_NO_EA_KNOWLEDGE 0x00000200
|
||||||
|
#define FILE_OPEN_REMOTE_INSTANCE 0x00000400
|
||||||
|
#define FILE_RANDOM_ACCESS 0x00000800
|
||||||
|
|
||||||
|
#define FILE_DELETE_ON_CLOSE 0x00001000
|
||||||
|
#define FILE_OPEN_BY_FILE_ID 0x00002000
|
||||||
|
#define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000
|
||||||
|
#define FILE_NO_COMPRESSION 0x00008000
|
||||||
|
|
||||||
|
#define FILE_RESERVE_OPFILTER 0x00100000
|
||||||
|
#define FILE_OPEN_REPARSE_POINT 0x00200000
|
||||||
|
#define FILE_OPEN_NO_RECALL 0x00400000
|
||||||
|
#define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000
|
||||||
|
|
||||||
|
#define FILE_COPY_STRUCTURED_STORAGE 0x00000041
|
||||||
|
#define FILE_STRUCTURED_STORAGE 0x00000441
|
||||||
|
|
||||||
|
#define FILE_SUPERSEDE 0x00000000
|
||||||
|
#define FILE_OPEN 0x00000001
|
||||||
|
#define FILE_CREATE 0x00000002
|
||||||
|
#define FILE_OPEN_IF 0x00000003
|
||||||
|
#define FILE_OVERWRITE 0x00000004
|
||||||
|
#define FILE_OVERWRITE_IF 0x00000005
|
||||||
|
#define FILE_MAXIMUM_DISPOSITION 0x00000005
|
||||||
|
|
||||||
|
typedef enum _FILE_INFORMATION_CLASS {
|
||||||
|
FileDirectoryInformation = 1,
|
||||||
|
FileFullDirectoryInformation, // 2
|
||||||
|
FileBothDirectoryInformation, // 3
|
||||||
|
FileBasicInformation, // 4
|
||||||
|
FileStandardInformation, // 5
|
||||||
|
FileInternalInformation, // 6
|
||||||
|
FileEaInformation, // 7
|
||||||
|
FileAccessInformation, // 8
|
||||||
|
FileNameInformation, // 9
|
||||||
|
FileRenameInformation, // 10
|
||||||
|
FileLinkInformation, // 11
|
||||||
|
FileNamesInformation, // 12
|
||||||
|
FileDispositionInformation, // 13
|
||||||
|
FilePositionInformation, // 14
|
||||||
|
FileFullEaInformation, // 15
|
||||||
|
FileModeInformation, // 16
|
||||||
|
FileAlignmentInformation, // 17
|
||||||
|
FileAllInformation, // 18
|
||||||
|
FileAllocationInformation, // 19
|
||||||
|
FileEndOfFileInformation, // 20
|
||||||
|
FileAlternateNameInformation, // 21
|
||||||
|
FileStreamInformation, // 22
|
||||||
|
FilePipeInformation, // 23
|
||||||
|
FilePipeLocalInformation, // 24
|
||||||
|
FilePipeRemoteInformation, // 25
|
||||||
|
FileMailslotQueryInformation, // 26
|
||||||
|
FileMailslotSetInformation, // 27
|
||||||
|
FileCompressionInformation, // 28
|
||||||
|
FileObjectIdInformation, // 29
|
||||||
|
FileCompletionInformation, // 30
|
||||||
|
FileMoveClusterInformation, // 31
|
||||||
|
FileQuotaInformation, // 32
|
||||||
|
FileReparsePointInformation, // 33
|
||||||
|
FileNetworkOpenInformation, // 34
|
||||||
|
FileAttributeTagInformation, // 35
|
||||||
|
FileTrackingInformation, // 36
|
||||||
|
FileIdBothDirectoryInformation, // 37
|
||||||
|
FileIdFullDirectoryInformation, // 38
|
||||||
|
FileValidDataLengthInformation, // 39
|
||||||
|
FileShortNameInformation, // 40
|
||||||
|
FileIoCompletionNotificationInformation, // 41
|
||||||
|
FileIoStatusBlockRangeInformation, // 42
|
||||||
|
FileIoPriorityHintInformation, // 43
|
||||||
|
FileSfioReserveInformation, // 44
|
||||||
|
FileSfioVolumeInformation, // 45
|
||||||
|
FileHardLinkInformation, // 46
|
||||||
|
FileProcessIdsUsingFileInformation, // 47
|
||||||
|
FileNormalizedNameInformation, // 48
|
||||||
|
FileNetworkPhysicalNameInformation, // 49
|
||||||
|
FileIdGlobalTxDirectoryInformation, // 50
|
||||||
|
FileMaximumInformation
|
||||||
|
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
|
||||||
|
|
||||||
|
|
||||||
|
/* kernel structures for QueryDirectory results */
|
||||||
|
typedef struct _FILE_NAMES_INFORMATION {
|
||||||
|
ULONG NextEntryOffset;
|
||||||
|
ULONG FileIndex;
|
||||||
|
ULONG FileNameLength;
|
||||||
|
WCHAR FileName[1];
|
||||||
|
} FILE_NAMES_INFORMATION, *PFILE_NAMES_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_DIRECTORY_INFO {
|
||||||
|
ULONG NextEntryOffset;
|
||||||
|
ULONG FileIndex;
|
||||||
|
LARGE_INTEGER CreationTime;
|
||||||
|
LARGE_INTEGER LastAccessTime;
|
||||||
|
LARGE_INTEGER LastWriteTime;
|
||||||
|
LARGE_INTEGER ChangeTime;
|
||||||
|
LARGE_INTEGER EndOfFile;
|
||||||
|
LARGE_INTEGER AllocationSize;
|
||||||
|
ULONG FileAttributes;
|
||||||
|
ULONG FileNameLength;
|
||||||
|
WCHAR FileName[1];
|
||||||
|
} FILE_DIRECTORY_INFO, *PFILE_DIRECTORY_INFO;
|
||||||
|
|
||||||
|
typedef struct _FILE_BOTH_DIR_INFORMATION {
|
||||||
|
ULONG NextEntryOffset;
|
||||||
|
ULONG FileIndex;
|
||||||
|
LARGE_INTEGER CreationTime;
|
||||||
|
LARGE_INTEGER LastAccessTime;
|
||||||
|
LARGE_INTEGER LastWriteTime;
|
||||||
|
LARGE_INTEGER ChangeTime;
|
||||||
|
LARGE_INTEGER EndOfFile;
|
||||||
|
LARGE_INTEGER AllocationSize;
|
||||||
|
ULONG FileAttributes;
|
||||||
|
ULONG FileNameLength;
|
||||||
|
ULONG EaSize;
|
||||||
|
CCHAR ShortNameLength;
|
||||||
|
WCHAR ShortName[12];
|
||||||
|
WCHAR FileName[1];
|
||||||
|
} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _FILE_FULL_DIR_INFO {
|
||||||
|
ULONG NextEntryOffset;
|
||||||
|
ULONG FileIndex;
|
||||||
|
LARGE_INTEGER CreationTime;
|
||||||
|
LARGE_INTEGER LastAccessTime;
|
||||||
|
LARGE_INTEGER LastWriteTime;
|
||||||
|
LARGE_INTEGER ChangeTime;
|
||||||
|
LARGE_INTEGER EndOfFile;
|
||||||
|
LARGE_INTEGER AllocationSize;
|
||||||
|
ULONG FileAttributes;
|
||||||
|
ULONG FileNameLength;
|
||||||
|
ULONG EaSize;
|
||||||
|
WCHAR FileName[1];
|
||||||
|
} FILE_FULL_DIR_INFO, *PFILE_FULL_DIR_INFO;
|
||||||
|
|
||||||
|
typedef struct _FILE_ID_FULL_DIR_INFO {
|
||||||
|
ULONG NextEntryOffset;
|
||||||
|
ULONG FileIndex;
|
||||||
|
LARGE_INTEGER CreationTime;
|
||||||
|
LARGE_INTEGER LastAccessTime;
|
||||||
|
LARGE_INTEGER LastWriteTime;
|
||||||
|
LARGE_INTEGER ChangeTime;
|
||||||
|
LARGE_INTEGER EndOfFile;
|
||||||
|
LARGE_INTEGER AllocationSize;
|
||||||
|
ULONG FileAttributes;
|
||||||
|
ULONG FileNameLength;
|
||||||
|
ULONG EaSize;
|
||||||
|
LARGE_INTEGER FileId;
|
||||||
|
WCHAR FileName[1];
|
||||||
|
} FILE_ID_FULL_DIR_INFO, *PFILE_ID_FULL_DIR_INFO;
|
||||||
|
|
||||||
|
typedef struct _FILE_LINK_INFORMATION {
|
||||||
|
BOOLEAN ReplaceIfExists;
|
||||||
|
HANDLE RootDirectory;
|
||||||
|
ULONG FileNameLength;
|
||||||
|
WCHAR FileName[1];
|
||||||
|
} FILE_LINK_INFORMATION, *PFILE_LINK_INFORMATION;
|
||||||
|
|
||||||
|
#endif
|
||||||
152
daemon/getattr.c
Normal file
152
daemon/getattr.c
Normal file
|
|
@ -0,0 +1,152 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "from_kernel.h"
|
||||||
|
#include "daemon_debug.h"
|
||||||
|
#include "nfs41_ops.h"
|
||||||
|
#include "name_cache.h"
|
||||||
|
#include "upcall.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
|
||||||
|
int nfs41_cached_getattr(
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN nfs41_path_fh *file,
|
||||||
|
OUT nfs41_file_info *info)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
/* first look for cached attributes */
|
||||||
|
status = nfs41_attr_cache_lookup(session_name_cache(session),
|
||||||
|
file->fh.fileid, info);
|
||||||
|
|
||||||
|
if (status) {
|
||||||
|
/* fetch attributes from the server */
|
||||||
|
bitmap4 attr_request;
|
||||||
|
init_getattr_request(&attr_request);
|
||||||
|
|
||||||
|
status = nfs41_getattr(session, file, &attr_request, info);
|
||||||
|
if (status) {
|
||||||
|
eprintf("nfs41_getattr() failed with %s\n",
|
||||||
|
nfs_error_string(status));
|
||||||
|
status = nfs_to_windows_error(status, ERROR_BAD_NET_RESP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int parse_getattr(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
getattr_upcall_args *args = &upcall->args.getattr;
|
||||||
|
|
||||||
|
status = safe_read(&buffer, &length, &args->query_class, sizeof(args->query_class));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->buf_len, sizeof(args->buf_len));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->root, sizeof(HANDLE));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->state, sizeof(args->state));
|
||||||
|
out:
|
||||||
|
if (status)
|
||||||
|
eprintf("parsing NFS41_FILE_QUERY failed with %d\n", status);
|
||||||
|
else
|
||||||
|
dprintf(1, "parsing NFS41_FILE_QUERY: info_class=%d buf_len=%d "
|
||||||
|
"root=0x%p open_state=0x%p\n",
|
||||||
|
args->query_class, args->buf_len, args->root, args->state);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int handle_getattr(nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
getattr_upcall_args *args = &upcall->args.getattr;
|
||||||
|
nfs41_open_state *state = args->state;
|
||||||
|
nfs41_file_info info;
|
||||||
|
|
||||||
|
ZeroMemory(&info, sizeof(info));
|
||||||
|
|
||||||
|
status = nfs41_cached_getattr(state->session, &state->file, &info);
|
||||||
|
if (status) {
|
||||||
|
eprintf("nfs41_cached_getattr() failed with %d\n", status);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (args->query_class) {
|
||||||
|
case FileBasicInformation:
|
||||||
|
nfs_to_basic_info(&info, &args->basic_info);
|
||||||
|
break;
|
||||||
|
case FileStandardInformation:
|
||||||
|
nfs_to_standard_info(&info, &args->std_info);
|
||||||
|
break;
|
||||||
|
case FileAttributeTagInformation:
|
||||||
|
args->tag_info.FileAttributes = nfs_file_info_to_attributes(&info);
|
||||||
|
args->tag_info.ReparseTag = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
eprintf("unhandled file query class %d\n", args->query_class);
|
||||||
|
status = ERROR_INVALID_PARAMETER;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int marshall_getattr(unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
getattr_upcall_args *args = &upcall->args.getattr;
|
||||||
|
uint32_t info_len;
|
||||||
|
|
||||||
|
switch (args->query_class) {
|
||||||
|
case FileBasicInformation:
|
||||||
|
info_len = sizeof(args->basic_info);
|
||||||
|
status = safe_write(&buffer, length, &info_len, sizeof(info_len));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_write(&buffer, length, &args->basic_info, info_len);
|
||||||
|
if (status) goto out;
|
||||||
|
break;
|
||||||
|
case FileStandardInformation:
|
||||||
|
info_len = sizeof(args->std_info);
|
||||||
|
status = safe_write(&buffer, length, &info_len, sizeof(info_len));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_write(&buffer, length, &args->std_info, info_len);
|
||||||
|
if (status) goto out;
|
||||||
|
break;
|
||||||
|
case FileAttributeTagInformation:
|
||||||
|
info_len = sizeof(args->tag_info);
|
||||||
|
status = safe_write(&buffer, length, &info_len, sizeof(info_len));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_write(&buffer, length, &args->tag_info, info_len);
|
||||||
|
if (status) goto out;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
eprintf("unknown file query class %d\n", args->query_class);
|
||||||
|
status = 103;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
116
daemon/list.h
Normal file
116
daemon/list.h
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NFS41_LIST_H
|
||||||
|
#define NFS41_LIST_H
|
||||||
|
|
||||||
|
|
||||||
|
/* doubly-linked list */
|
||||||
|
struct list_entry {
|
||||||
|
struct list_entry *prev;
|
||||||
|
struct list_entry *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define list_container(entry, type, field) \
|
||||||
|
((type*)((const char*)(entry) - (const char*)(&((type*)0)->field)))
|
||||||
|
|
||||||
|
#define list_for_each(entry, head) \
|
||||||
|
for (entry = (head)->next; entry != (head); entry = entry->next)
|
||||||
|
|
||||||
|
#define list_for_each_tmp(entry, tmp, head) \
|
||||||
|
for (entry = (head)->next, tmp = entry->next; entry != (head); \
|
||||||
|
entry = tmp, tmp = entry->next)
|
||||||
|
|
||||||
|
#define list_for_each_reverse(entry, head) \
|
||||||
|
for (entry = (head)->prev; entry != (head); entry = entry->prev)
|
||||||
|
|
||||||
|
#define list_for_each_reverse_tmp(entry, tmp, head) \
|
||||||
|
for (entry = (head)->next, tmp = entry->next; entry != (head); \
|
||||||
|
entry = tmp, tmp = entry->next)
|
||||||
|
|
||||||
|
|
||||||
|
static void list_init(
|
||||||
|
struct list_entry *head)
|
||||||
|
{
|
||||||
|
head->prev = head;
|
||||||
|
head->next = head;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int list_empty(
|
||||||
|
struct list_entry *head)
|
||||||
|
{
|
||||||
|
return head->next == head;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void list_add(
|
||||||
|
struct list_entry *entry,
|
||||||
|
struct list_entry *prev,
|
||||||
|
struct list_entry *next)
|
||||||
|
{
|
||||||
|
/* assert(prev->next == next && next->prev == prev); */
|
||||||
|
entry->prev = prev;
|
||||||
|
entry->next = next;
|
||||||
|
prev->next = entry;
|
||||||
|
next->prev = entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void list_add_head(
|
||||||
|
struct list_entry *head,
|
||||||
|
struct list_entry *entry)
|
||||||
|
{
|
||||||
|
list_add(entry, head, head->next);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void list_add_tail(
|
||||||
|
struct list_entry *head,
|
||||||
|
struct list_entry *entry)
|
||||||
|
{
|
||||||
|
list_add(entry, head->prev, head);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void list_remove(
|
||||||
|
struct list_entry *entry)
|
||||||
|
{
|
||||||
|
if (!list_empty(entry)) {
|
||||||
|
entry->next->prev = entry->prev;
|
||||||
|
entry->prev->next = entry->next;
|
||||||
|
list_init(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef int (*list_compare_fn)(const struct list_entry*, const void*);
|
||||||
|
|
||||||
|
static struct list_entry* list_search(
|
||||||
|
const struct list_entry *head,
|
||||||
|
const void *value,
|
||||||
|
list_compare_fn compare)
|
||||||
|
{
|
||||||
|
struct list_entry *entry;
|
||||||
|
list_for_each(entry, head)
|
||||||
|
if (compare(entry, value) == 0)
|
||||||
|
return entry;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* !NFS41_LIST_H */
|
||||||
252
daemon/lock.c
Normal file
252
daemon/lock.c
Normal file
|
|
@ -0,0 +1,252 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "daemon_debug.h"
|
||||||
|
#include "nfs41_ops.h"
|
||||||
|
#include "upcall.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define LKLVL 2 /* dprintf level for lock logging */
|
||||||
|
|
||||||
|
|
||||||
|
stateid4* nfs41_lock_stateid_copy(
|
||||||
|
IN nfs41_lock_state *lock_state,
|
||||||
|
IN OUT stateid4 *dest)
|
||||||
|
{
|
||||||
|
stateid4 *result;
|
||||||
|
AcquireSRWLockShared(&lock_state->lock);
|
||||||
|
if (lock_state->initialized) {
|
||||||
|
memcpy(dest, &lock_state->stateid, sizeof(stateid4));
|
||||||
|
result = dest;
|
||||||
|
dprintf(LKLVL, "nfs41_lock_stateid_copy: copying existing stateid "
|
||||||
|
"with seqid=%u\n", result->seqid);
|
||||||
|
} else {
|
||||||
|
result = NULL;
|
||||||
|
dprintf(LKLVL, "nfs41_lock_stateid_copy: no existing lock state\n");
|
||||||
|
}
|
||||||
|
ReleaseSRWLockShared(&lock_state->lock);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void update_last_lock_state(
|
||||||
|
OUT nfs41_lock_state *lock_state,
|
||||||
|
IN stateid4 *stateid)
|
||||||
|
{
|
||||||
|
/* update the lock state if the seqid is more recent */
|
||||||
|
AcquireSRWLockShared(&lock_state->lock);
|
||||||
|
if (stateid->seqid > lock_state->stateid.seqid) {
|
||||||
|
ReleaseSRWLockShared(&lock_state->lock);
|
||||||
|
|
||||||
|
AcquireSRWLockExclusive(&lock_state->lock);
|
||||||
|
if (stateid->seqid > lock_state->stateid.seqid) {
|
||||||
|
if (lock_state->initialized) {
|
||||||
|
/* if the lock state already existed, update the seqid only;
|
||||||
|
* assume that stateid->other remains unchanged */
|
||||||
|
dprintf(LKLVL, "update_last_lock_state: setting seqid=%u "
|
||||||
|
"(was %u)\n", stateid->seqid, lock_state->stateid.seqid);
|
||||||
|
lock_state->stateid.seqid = stateid->seqid;
|
||||||
|
} else {
|
||||||
|
/* copy the entire stateid and mark as initialized */
|
||||||
|
dprintf(LKLVL, "update_last_lock_state: stateid "
|
||||||
|
"initialized with seqid=%u\n", stateid->seqid);
|
||||||
|
memcpy(&lock_state->stateid, stateid, sizeof(stateid4));
|
||||||
|
lock_state->initialized = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ReleaseSRWLockExclusive(&lock_state->lock);
|
||||||
|
} else {
|
||||||
|
dprintf(LKLVL, "update_last_lock_state: discarding seqid=%u "
|
||||||
|
"(already %u)\n", stateid->seqid, lock_state->stateid.seqid);
|
||||||
|
ReleaseSRWLockShared(&lock_state->lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* NFS41_LOCK */
|
||||||
|
int parse_lock(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
lock_upcall_args *args = &upcall->args.lock;
|
||||||
|
|
||||||
|
status = safe_read(&buffer, &length, &args->state, sizeof(HANDLE));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->root, sizeof(HANDLE));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->offset, sizeof(LONGLONG));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->length, sizeof(LONGLONG));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->exclusive, sizeof(BOOLEAN));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->blocking, sizeof(BOOLEAN));
|
||||||
|
if (status) goto out;
|
||||||
|
out:
|
||||||
|
if (status)
|
||||||
|
eprintf("parsing NFS41_LOCK failed with %d\n", status);
|
||||||
|
else
|
||||||
|
dprintf(1, "parsing NFS41_LOCK: state=%p root=%p offset=0x%llx "
|
||||||
|
"length=0x%llx exclusive=%u blocking=%u\n",
|
||||||
|
args->state, args->root, args->offset, args->length,
|
||||||
|
args->exclusive, args->blocking);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline uint32_t get_lock_type(BOOLEAN exclusive, BOOLEAN blocking)
|
||||||
|
{
|
||||||
|
return blocking == 0
|
||||||
|
? ( exclusive == 0 ? READ_LT : WRITE_LT )
|
||||||
|
: ( exclusive == 0 ? READW_LT : WRITEW_LT );
|
||||||
|
}
|
||||||
|
|
||||||
|
int handle_lock(nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
lock_upcall_args *args = &upcall->args.lock;
|
||||||
|
nfs41_open_state *state = args->state;
|
||||||
|
const uint32_t type = get_lock_type(args->exclusive, args->blocking);
|
||||||
|
stateid4 stateid, *prev_stateid;
|
||||||
|
|
||||||
|
prev_stateid = nfs41_lock_stateid_copy(&state->last_lock, &stateid);
|
||||||
|
|
||||||
|
status = nfs41_lock(state->session, state, prev_stateid,
|
||||||
|
type, args->offset, args->length, &stateid);
|
||||||
|
if (status) {
|
||||||
|
dprintf(LKLVL, "nfs41_lock failed with %s\n",
|
||||||
|
nfs_error_string(status));
|
||||||
|
status = nfs_to_windows_error(status, ERROR_BAD_NET_RESP);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
update_last_lock_state(&state->last_lock, &stateid);
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int marshall_lock(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cancel_lock(IN nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
int status = NO_ERROR;
|
||||||
|
lock_upcall_args *args = &upcall->args.lock;
|
||||||
|
nfs41_open_state *state = args->state;
|
||||||
|
stateid4 stateid, *prev_stateid;
|
||||||
|
|
||||||
|
dprintf(1, "--> cancel_lock()\n");
|
||||||
|
|
||||||
|
if (upcall->status)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
prev_stateid = nfs41_lock_stateid_copy(&state->last_lock, &stateid);
|
||||||
|
|
||||||
|
status = nfs41_unlock(state->session, state,
|
||||||
|
prev_stateid, args->offset, args->length);
|
||||||
|
if (status) {
|
||||||
|
dprintf(LKLVL, "cancel_lock: nfs41_unlock() failed with %s\n",
|
||||||
|
nfs_error_string(status));
|
||||||
|
status = nfs_to_windows_error(status, ERROR_BAD_NET_RESP);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
update_last_lock_state(&state->last_lock, &stateid);
|
||||||
|
out:
|
||||||
|
dprintf(1, "<-- cancel_lock() returning %d\n", status);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* NFS41_UNLOCK */
|
||||||
|
int parse_unlock(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
unlock_upcall_args *args = &upcall->args.unlock;
|
||||||
|
|
||||||
|
status = safe_read(&buffer, &length, &args->state, sizeof(HANDLE));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->root, sizeof(HANDLE));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->count, sizeof(ULONG));
|
||||||
|
if (status) goto out;
|
||||||
|
|
||||||
|
args->buf = buffer;
|
||||||
|
args->buf_len = length;
|
||||||
|
out:
|
||||||
|
if (status)
|
||||||
|
eprintf("parsing NFS41_UNLOCK failed with %d\n", status);
|
||||||
|
else
|
||||||
|
dprintf(1, "parsing NFS41_UNLOCK: state=%p root=%p count=%u\n",
|
||||||
|
args->state, args->root, args->count);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int handle_unlock(nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
unlock_upcall_args *args = &upcall->args.unlock;
|
||||||
|
nfs41_open_state *state = args->state;
|
||||||
|
stateid4 stateid;
|
||||||
|
uint32_t i, nsuccess = 0;
|
||||||
|
unsigned char *buf = args->buf;
|
||||||
|
uint32_t buf_len = args->buf_len;
|
||||||
|
uint64_t offset;
|
||||||
|
uint64_t length;
|
||||||
|
|
||||||
|
if (nfs41_lock_stateid_copy(&state->last_lock, &stateid) == NULL) {
|
||||||
|
eprintf("attempt to unlock a file with no lock state\n");
|
||||||
|
status = ERROR_NOT_LOCKED;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = NO_ERROR;
|
||||||
|
for (i = 0; i < args->count; i++) {
|
||||||
|
if (safe_read(&buf, &buf_len, &offset, sizeof(LONGLONG))) break;
|
||||||
|
if (safe_read(&buf, &buf_len, &length, sizeof(LONGLONG))) break;
|
||||||
|
|
||||||
|
status = nfs41_unlock(state->session, state, &stateid, offset, length);
|
||||||
|
if (status == NFS4_OK) {
|
||||||
|
nsuccess++;
|
||||||
|
} else {
|
||||||
|
dprintf(LKLVL, "nfs41_unlock failed with %s\n",
|
||||||
|
nfs_error_string(status));
|
||||||
|
status = nfs_to_windows_error(status, ERROR_BAD_NET_RESP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nsuccess) {
|
||||||
|
update_last_lock_state(&state->last_lock, &stateid);
|
||||||
|
status = NO_ERROR;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int marshall_unlock(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
500
daemon/lookup.c
Normal file
500
daemon/lookup.c
Normal file
|
|
@ -0,0 +1,500 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <strsafe.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include "nfs41_compound.h"
|
||||||
|
#include "nfs41_ops.h"
|
||||||
|
#include "name_cache.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "daemon_debug.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define LULVL 2 /* dprintf level for lookup logging */
|
||||||
|
|
||||||
|
|
||||||
|
#define MAX_LOOKUP_COMPONENTS 8
|
||||||
|
|
||||||
|
/* calculate how much space to allocate for rpc reply */
|
||||||
|
#define MAX_LOOKUP_RES_SIZE 4
|
||||||
|
#define MAX_GETFH_RES_SIZE (NFS4_FHSIZE + 8)
|
||||||
|
#define MAX_GETATTR_RES_SIZE 128 /* depends on what we request */
|
||||||
|
#define MAX_COMPONENT_RES_SIZE \
|
||||||
|
(MAX_LOOKUP_RES_SIZE + MAX_GETFH_RES_SIZE + MAX_GETATTR_RES_SIZE)
|
||||||
|
#define MAX_RPC_RES_SIZE(num_components) \
|
||||||
|
(MAX_COMPONENT_RES_SIZE * ((num_components) + 1))
|
||||||
|
|
||||||
|
|
||||||
|
/* map NFS4ERR_MOVED to an arbitrary windows error */
|
||||||
|
#define ERROR_FILESYSTEM_ABSENT ERROR_DEVICE_REMOVED
|
||||||
|
|
||||||
|
struct lookup_referral {
|
||||||
|
nfs41_path_fh parent;
|
||||||
|
nfs41_component name;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct __nfs41_lookup_component_args {
|
||||||
|
nfs41_sequence_args sequence;
|
||||||
|
nfs41_putfh_args putfh;
|
||||||
|
nfs41_lookup_args lookup[MAX_LOOKUP_COMPONENTS];
|
||||||
|
nfs41_getattr_args getrootattr;
|
||||||
|
nfs41_getattr_args getattr[MAX_LOOKUP_COMPONENTS];
|
||||||
|
bitmap4 attr_request;
|
||||||
|
} nfs41_lookup_component_args;
|
||||||
|
|
||||||
|
typedef struct __nfs41_lookup_component_res {
|
||||||
|
nfs41_sequence_res sequence;
|
||||||
|
nfs41_putfh_res putfh;
|
||||||
|
nfs41_lookup_res lookup[MAX_LOOKUP_COMPONENTS];
|
||||||
|
nfs41_getfh_res getrootfh;
|
||||||
|
nfs41_getfh_res getfh[MAX_LOOKUP_COMPONENTS];
|
||||||
|
nfs41_path_fh root;
|
||||||
|
nfs41_path_fh file[MAX_LOOKUP_COMPONENTS];
|
||||||
|
nfs41_getattr_res getrootattr;
|
||||||
|
nfs41_getattr_res getattr[MAX_LOOKUP_COMPONENTS];
|
||||||
|
nfs41_file_info rootinfo;
|
||||||
|
nfs41_file_info info[MAX_LOOKUP_COMPONENTS];
|
||||||
|
struct lookup_referral *referral;
|
||||||
|
} nfs41_lookup_component_res;
|
||||||
|
|
||||||
|
|
||||||
|
static void init_component_args(
|
||||||
|
IN nfs41_lookup_component_args *args,
|
||||||
|
IN nfs41_lookup_component_res *res,
|
||||||
|
IN nfs41_abs_path *path,
|
||||||
|
IN struct lookup_referral *referral)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
ZeroMemory(args, sizeof(nfs41_lookup_component_args));
|
||||||
|
ZeroMemory(res, sizeof(nfs41_lookup_component_res));
|
||||||
|
|
||||||
|
args->attr_request.count = 2;
|
||||||
|
args->attr_request.arr[0] = FATTR4_WORD0_TYPE
|
||||||
|
| FATTR4_WORD0_CHANGE | FATTR4_WORD0_SIZE
|
||||||
|
| FATTR4_WORD0_FSID | FATTR4_WORD0_FILEID;
|
||||||
|
args->attr_request.arr[1] = FATTR4_WORD1_MODE
|
||||||
|
| FATTR4_WORD1_NUMLINKS | FATTR4_WORD1_TIME_ACCESS
|
||||||
|
| FATTR4_WORD1_TIME_CREATE | FATTR4_WORD1_TIME_MODIFY;
|
||||||
|
|
||||||
|
args->getrootattr.attr_request = &args->attr_request;
|
||||||
|
res->root.path = path;
|
||||||
|
res->getrootfh.fh = &res->root.fh;
|
||||||
|
res->getrootattr.info = &res->rootinfo;
|
||||||
|
res->getrootattr.obj_attributes.attr_vals_len = NFS4_OPAQUE_LIMIT;
|
||||||
|
res->referral = referral;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_LOOKUP_COMPONENTS; i++) {
|
||||||
|
args->getattr[i].attr_request = &args->attr_request;
|
||||||
|
res->file[i].path = path;
|
||||||
|
args->lookup[i].name = &res->file[i].name;
|
||||||
|
res->getfh[i].fh = &res->file[i].fh;
|
||||||
|
res->getattr[i].info = &res->info[i];
|
||||||
|
res->getattr[i].obj_attributes.attr_vals_len = NFS4_OPAQUE_LIMIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lookup_rpc(
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN nfs41_path_fh *dir,
|
||||||
|
IN uint32_t component_count,
|
||||||
|
IN nfs41_lookup_component_args *args,
|
||||||
|
OUT nfs41_lookup_component_res *res)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
uint32_t i, buffer_size;
|
||||||
|
nfs41_compound compound;
|
||||||
|
nfs_argop4 argops[4+MAX_LOOKUP_COMPONENTS*3];
|
||||||
|
nfs_resop4 resops[4+MAX_LOOKUP_COMPONENTS*3];
|
||||||
|
|
||||||
|
compound_init(&compound, argops, resops);
|
||||||
|
|
||||||
|
compound_add_op(&compound, OP_SEQUENCE, &args->sequence, &res->sequence);
|
||||||
|
status = nfs41_session_sequence(&args->sequence, session, 0);
|
||||||
|
if (status)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (dir == &res->root) {
|
||||||
|
compound_add_op(&compound, OP_PUTROOTFH,
|
||||||
|
NULL, &res->putfh);
|
||||||
|
compound_add_op(&compound, OP_GETFH,
|
||||||
|
NULL, &res->getrootfh);
|
||||||
|
compound_add_op(&compound, OP_GETATTR,
|
||||||
|
&args->getrootattr, &res->getrootattr);
|
||||||
|
} else {
|
||||||
|
args->putfh.file = dir;
|
||||||
|
compound_add_op(&compound, OP_PUTFH,
|
||||||
|
&args->putfh, &res->putfh);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < component_count; i++) {
|
||||||
|
compound_add_op(&compound, OP_LOOKUP,
|
||||||
|
&args->lookup[i], &res->lookup[i]);
|
||||||
|
compound_add_op(&compound, OP_GETFH,
|
||||||
|
NULL, &res->getfh[i]);
|
||||||
|
compound_add_op(&compound, OP_GETATTR,
|
||||||
|
&args->getattr[i], &res->getattr[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer_size = MAX_RPC_RES_SIZE(component_count);
|
||||||
|
status = compound_encode_send_decode(session, &compound, 0, buffer_size);
|
||||||
|
if (status)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
compound_error(status = compound.res.status);
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int server_lookup(
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN nfs41_path_fh *dir,
|
||||||
|
IN const char *path,
|
||||||
|
IN const char *path_end,
|
||||||
|
IN uint32_t count,
|
||||||
|
IN nfs41_lookup_component_args *args,
|
||||||
|
IN nfs41_lookup_component_res *res,
|
||||||
|
OUT OPTIONAL nfs41_path_fh **parent_out,
|
||||||
|
OUT OPTIONAL nfs41_path_fh **target_out,
|
||||||
|
OUT OPTIONAL nfs41_file_info *info_out)
|
||||||
|
{
|
||||||
|
nfs41_path_fh *file, *parent;
|
||||||
|
uint32_t i = 0;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
if (parent_out) *parent_out = NULL;
|
||||||
|
if (target_out) *target_out = NULL;
|
||||||
|
|
||||||
|
lookup_rpc(session, dir, count, args, res);
|
||||||
|
|
||||||
|
status = res->sequence.sr_status; if (status) goto out;
|
||||||
|
status = res->putfh.status; if (status) goto out;
|
||||||
|
status = res->getrootfh.status; if (status) goto out;
|
||||||
|
status = res->getrootattr.status; if (status) goto out;
|
||||||
|
|
||||||
|
if (dir == &res->root) {
|
||||||
|
nfs41_component name = { 0 };
|
||||||
|
|
||||||
|
/* fill in the file handle's fileid and superblock */
|
||||||
|
dir->fh.fileid = res->getrootattr.info->fileid;
|
||||||
|
status = nfs41_superblock_for_fh(session,
|
||||||
|
&res->getrootattr.info->fsid, NULL, dir);
|
||||||
|
if (status)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* get the name of the parent (empty if its the root) */
|
||||||
|
last_component(path, count ? args->lookup[0].name->name : path_end, &name);
|
||||||
|
|
||||||
|
/* add the file handle and attributes to the name cache */
|
||||||
|
memcpy(&res->getrootattr.info->attrmask,
|
||||||
|
&res->getrootattr.obj_attributes.attrmask, sizeof(bitmap4));
|
||||||
|
nfs41_name_cache_insert(session_name_cache(session),
|
||||||
|
path, &name, &dir->fh, res->getrootattr.info, NULL);
|
||||||
|
}
|
||||||
|
file = dir;
|
||||||
|
|
||||||
|
if (count == 0) {
|
||||||
|
if (target_out)
|
||||||
|
*target_out = dir;
|
||||||
|
if (info_out)
|
||||||
|
memcpy(info_out, res->getrootattr.info, sizeof(nfs41_file_info));
|
||||||
|
} else if (count == 1) {
|
||||||
|
if (parent_out)
|
||||||
|
*parent_out = dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
status = res->lookup[i].status; if (status) break;
|
||||||
|
if (res->getfh[i].status == NFS4ERR_MOVED) {
|
||||||
|
/* save enough information to follow the referral */
|
||||||
|
path_fh_copy(&res->referral->parent, file);
|
||||||
|
res->referral->name.name = args->lookup[i].name->name;
|
||||||
|
res->referral->name.len = args->lookup[i].name->len;
|
||||||
|
return ERROR_FILESYSTEM_ABSENT;
|
||||||
|
}
|
||||||
|
status = res->getfh[i].status; if (status) break;
|
||||||
|
status = res->getattr[i].status; if (status) break;
|
||||||
|
|
||||||
|
parent = file;
|
||||||
|
file = &res->file[i];
|
||||||
|
|
||||||
|
/* fill in the file handle's fileid and superblock */
|
||||||
|
file->fh.fileid = res->getattr[i].info->fileid;
|
||||||
|
status = nfs41_superblock_for_fh(session,
|
||||||
|
&res->getattr[i].info->fsid, &parent->fh, file);
|
||||||
|
if (status)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* add the file handle and attributes to the name cache */
|
||||||
|
memcpy(&res->getattr[i].info->attrmask,
|
||||||
|
&res->getattr[i].obj_attributes.attrmask, sizeof(bitmap4));
|
||||||
|
nfs41_name_cache_insert(session_name_cache(session),
|
||||||
|
path, args->lookup[i].name, &res->file[i].fh,
|
||||||
|
res->getattr[i].info, NULL);
|
||||||
|
|
||||||
|
if (i == count-1) {
|
||||||
|
if (target_out)
|
||||||
|
*target_out = file;
|
||||||
|
if (info_out)
|
||||||
|
memcpy(info_out, res->getattr[i].info, sizeof(nfs41_file_info));
|
||||||
|
} else if (i == count-2) {
|
||||||
|
if (parent_out)
|
||||||
|
*parent_out = file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
status = nfs_to_windows_error(status, ERROR_FILE_NOT_FOUND);
|
||||||
|
|
||||||
|
/* use PATH_NOT_FOUND for all but the last name */
|
||||||
|
if (status == ERROR_FILE_NOT_FOUND && i != count-1)
|
||||||
|
status = ERROR_PATH_NOT_FOUND;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t max_lookup_components(
|
||||||
|
IN const nfs41_session *session)
|
||||||
|
{
|
||||||
|
const uint32_t comps = (session->fore_chan_attrs.ca_maxoperations - 4) / 3;
|
||||||
|
return min(comps, MAX_LOOKUP_COMPONENTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t get_component_array(
|
||||||
|
IN OUT const char **path_pos,
|
||||||
|
IN const char *path_end,
|
||||||
|
IN uint32_t max_components,
|
||||||
|
OUT nfs41_path_fh *components,
|
||||||
|
OUT uint32_t *component_count)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < max_components; i++) {
|
||||||
|
if (!next_component(*path_pos, path_end, &components[i].name))
|
||||||
|
break;
|
||||||
|
*path_pos = components[i].name.name + components[i].name.len;
|
||||||
|
}
|
||||||
|
|
||||||
|
*component_count = i;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int server_lookup_loop(
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN OPTIONAL nfs41_path_fh *parent_in,
|
||||||
|
IN nfs41_abs_path *path,
|
||||||
|
IN const char *path_pos,
|
||||||
|
IN struct lookup_referral *referral,
|
||||||
|
OUT OPTIONAL nfs41_path_fh *parent_out,
|
||||||
|
OUT OPTIONAL nfs41_path_fh *target_out,
|
||||||
|
OUT OPTIONAL nfs41_file_info *info_out)
|
||||||
|
{
|
||||||
|
nfs41_lookup_component_args args;
|
||||||
|
nfs41_lookup_component_res res;
|
||||||
|
nfs41_path_fh *dir, *parent, *target;
|
||||||
|
const char *path_end;
|
||||||
|
const uint32_t max_components = max_lookup_components(session);
|
||||||
|
uint32_t count;
|
||||||
|
int status = NO_ERROR;
|
||||||
|
|
||||||
|
init_component_args(&args, &res, path, referral);
|
||||||
|
parent = NULL;
|
||||||
|
target = NULL;
|
||||||
|
|
||||||
|
path_end = path->path + path->len;
|
||||||
|
dir = parent_in ? parent_in : &res.root;
|
||||||
|
|
||||||
|
while (get_component_array(&path_pos, path_end,
|
||||||
|
max_components, res.file, &count)) {
|
||||||
|
|
||||||
|
status = server_lookup(session, dir, path->path, path_end, count,
|
||||||
|
&args, &res, &parent, &target, info_out);
|
||||||
|
|
||||||
|
if (status == ERROR_FILE_NOT_FOUND && is_last_component(path_pos, path_end))
|
||||||
|
goto out_parent;
|
||||||
|
if (status)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
dir = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dir == &res.root && (target_out || info_out)) {
|
||||||
|
/* didn't get any components, so we just need the root */
|
||||||
|
status = server_lookup(session, dir, path->path, path_end,
|
||||||
|
0, &args, &res, &parent, &target, info_out);
|
||||||
|
if (status)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target_out && target) fh_copy(&target_out->fh, &target->fh);
|
||||||
|
out_parent:
|
||||||
|
if (parent_out && parent) fh_copy(&parent_out->fh, &parent->fh);
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void referral_locations_free(
|
||||||
|
IN fs_locations4 *locations)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
if (locations->locations) {
|
||||||
|
for (i = 0; i < locations->location_count; i++)
|
||||||
|
free(locations->locations[i].servers);
|
||||||
|
free(locations->locations);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int referral_resolve(
|
||||||
|
IN nfs41_root *root,
|
||||||
|
IN nfs41_session *session_in,
|
||||||
|
IN struct lookup_referral *referral,
|
||||||
|
OUT nfs41_abs_path *path_out,
|
||||||
|
OUT nfs41_session **session_out)
|
||||||
|
{
|
||||||
|
char rest_of_path[NFS41_MAX_PATH_LEN];
|
||||||
|
fs_locations4 locations = { 0 };
|
||||||
|
const fs_location4 *location;
|
||||||
|
nfs41_client *client;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
/* get fs_locations */
|
||||||
|
status = nfs41_fs_locations(session_in, &referral->parent,
|
||||||
|
&referral->name, &locations);
|
||||||
|
if (status) {
|
||||||
|
eprintf("nfs41_fs_locations() failed with %s\n",
|
||||||
|
nfs_error_string(status));
|
||||||
|
status = nfs_to_windows_error(status, ERROR_PATH_NOT_FOUND);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* mount the first location available */
|
||||||
|
status = nfs41_root_mount_referral(root, &locations, &location, &client);
|
||||||
|
if (status) {
|
||||||
|
eprintf("nfs41_root_mount_referral() failed with %d\n",
|
||||||
|
status);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* format a new path from that location's root */
|
||||||
|
StringCchCopyA(rest_of_path, NFS41_MAX_PATH_LEN,
|
||||||
|
referral->name.name + referral->name.len);
|
||||||
|
|
||||||
|
AcquireSRWLockExclusive(&path_out->lock);
|
||||||
|
abs_path_copy(path_out, &location->path);
|
||||||
|
StringCchCatA(path_out->path, NFS41_MAX_PATH_LEN, rest_of_path);
|
||||||
|
path_out->len += (unsigned short)strlen(rest_of_path);
|
||||||
|
ReleaseSRWLockExclusive(&path_out->lock);
|
||||||
|
|
||||||
|
if (session_out) *session_out = client->session;
|
||||||
|
out:
|
||||||
|
referral_locations_free(&locations);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nfs41_lookup(
|
||||||
|
IN nfs41_root *root,
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN OUT nfs41_abs_path *path_inout,
|
||||||
|
OUT OPTIONAL nfs41_path_fh *parent_out,
|
||||||
|
OUT OPTIONAL nfs41_path_fh *target_out,
|
||||||
|
OUT OPTIONAL nfs41_file_info *info_out,
|
||||||
|
OUT nfs41_session **session_out)
|
||||||
|
{
|
||||||
|
nfs41_abs_path path;
|
||||||
|
struct nfs41_name_cache *cache = session_name_cache(session);
|
||||||
|
nfs41_path_fh parent, target, *server_start;
|
||||||
|
const char *path_pos, *path_end;
|
||||||
|
struct lookup_referral referral;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
if (session_out) *session_out = session;
|
||||||
|
|
||||||
|
InitializeSRWLock(&path.lock);
|
||||||
|
|
||||||
|
/* to avoid holding this lock over multiple rpcs,
|
||||||
|
* make a copy of the path and use that instead */
|
||||||
|
AcquireSRWLockShared(&path_inout->lock);
|
||||||
|
abs_path_copy(&path, path_inout);
|
||||||
|
ReleaseSRWLockShared(&path_inout->lock);
|
||||||
|
|
||||||
|
path_pos = path.path;
|
||||||
|
path_end = path.path + path.len;
|
||||||
|
|
||||||
|
dprintf(LULVL, "--> nfs41_lookup('%s')\n", path.path);
|
||||||
|
|
||||||
|
if (parent_out == NULL) parent_out = &parent;
|
||||||
|
if (target_out == NULL) target_out = ⌖
|
||||||
|
parent_out->fh.len = target_out->fh.len = 0;
|
||||||
|
|
||||||
|
status = nfs41_name_cache_lookup(cache,
|
||||||
|
path_pos, path_end, &path_pos,
|
||||||
|
&parent_out->fh, &target_out->fh, info_out);
|
||||||
|
if (status == NO_ERROR)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (target_out->fh.len) {
|
||||||
|
/* start where the name cache left off */
|
||||||
|
if (target_out != &target) {
|
||||||
|
/* must make a copy for server_start, because
|
||||||
|
* server_lookup_loop() will overwrite target_out */
|
||||||
|
path_fh_copy(&target, target_out);
|
||||||
|
}
|
||||||
|
server_start = ⌖
|
||||||
|
} else {
|
||||||
|
/* start with PUTROOTFH */
|
||||||
|
server_start = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = server_lookup_loop(session, server_start,
|
||||||
|
&path, path_pos, &referral, parent_out, target_out, info_out);
|
||||||
|
|
||||||
|
if (status == ERROR_FILESYSTEM_ABSENT) {
|
||||||
|
nfs41_session *new_session;
|
||||||
|
|
||||||
|
/* create a session to the referred server and
|
||||||
|
* reformat the path relative to that server's root */
|
||||||
|
status = referral_resolve(root, session,
|
||||||
|
&referral, path_inout, &new_session);
|
||||||
|
if (status) {
|
||||||
|
eprintf("referral_resolve() failed with %d\n", status);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* update the positions of the parent and target components */
|
||||||
|
last_component(path_inout->path, path_inout->path + path_inout->len,
|
||||||
|
&target_out->name);
|
||||||
|
last_component(path_inout->path, target_out->name.name,
|
||||||
|
&parent_out->name);
|
||||||
|
|
||||||
|
if (session_out) *session_out = new_session;
|
||||||
|
|
||||||
|
/* look up the new path */
|
||||||
|
status = nfs41_lookup(root, new_session, path_inout,
|
||||||
|
parent_out, target_out, info_out, session_out);
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
dprintf(LULVL, "<-- nfs41_lookup() returning %d\n", status);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
8
daemon/makefile
Normal file
8
daemon/makefile
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
#
|
||||||
|
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
|
||||||
|
# file to this component. This file merely indirects to the real make file
|
||||||
|
# that is shared by all the driver components of the Windows NT DDK
|
||||||
|
#
|
||||||
|
|
||||||
|
!INCLUDE $(NTMAKEENV)\makefile.def
|
||||||
|
|
||||||
131
daemon/mount.c
Normal file
131
daemon/mount.c
Normal file
|
|
@ -0,0 +1,131 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "daemon_debug.h"
|
||||||
|
#include "nfs41_ops.h"
|
||||||
|
#include "upcall.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
/* NFS41_MOUNT */
|
||||||
|
int parse_mount(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
mount_upcall_args *args = &upcall->args.mount;
|
||||||
|
|
||||||
|
status = get_name(&buffer, &length, args->srv_name);
|
||||||
|
if(status) goto out;
|
||||||
|
ZeroMemory(&args->path, sizeof(nfs41_abs_path));
|
||||||
|
status = get_abs_path(&buffer, &length, &args->path);
|
||||||
|
out:
|
||||||
|
if (status)
|
||||||
|
eprintf("parsing of NFS41_MOUNT failed with %d\n", status);
|
||||||
|
else
|
||||||
|
dprintf(1, "parsing NFS14_MOUNT: srv_name=%s root=%s\n",
|
||||||
|
args->srv_name, args->path.path);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int handle_mount(nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
mount_upcall_args *args = &upcall->args.mount;
|
||||||
|
multi_addr4 addrs;
|
||||||
|
const unsigned short port = 2049;
|
||||||
|
nfs41_root *root;
|
||||||
|
nfs41_client *client;
|
||||||
|
|
||||||
|
// resolve hostname,port
|
||||||
|
status = nfs41_server_resolve(args->srv_name, port, &addrs);
|
||||||
|
if (status) {
|
||||||
|
eprintf("nfs41_server_resolve() failed with %d\n", status);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
// create root
|
||||||
|
status = nfs41_root_create(args->srv_name, port, &args->path,
|
||||||
|
NFS41_MAX_FILEIO_SIZE + WRITE_OVERHEAD,
|
||||||
|
NFS41_MAX_FILEIO_SIZE + READ_OVERHEAD, &root);
|
||||||
|
if (status) {
|
||||||
|
eprintf("nfs41_rpc_clnt_create failed %d\n", status);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
// add a mount
|
||||||
|
status = nfs41_root_mount_addrs(root, &addrs, 0, 0, &client);
|
||||||
|
if (status) {
|
||||||
|
eprintf("nfs41_root_mount() failed with %d\n", status);
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
|
// look up the mount path, and fail if it doesn't exist
|
||||||
|
status = nfs41_lookup(root, client->session,
|
||||||
|
&args->path, NULL, NULL, NULL, NULL);
|
||||||
|
if (status) {
|
||||||
|
eprintf("nfs41_lookup('%s') failed with %d\n",
|
||||||
|
args->path.path, status);
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
args->root = root;
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
|
||||||
|
out_err:
|
||||||
|
nfs41_root_free(root);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
int marshall_mount(unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
mount_upcall_args *args = &upcall->args.mount;
|
||||||
|
dprintf(2, "NFS41_MOUNT: writing pointer to nfs41_root %p\n", args->root);
|
||||||
|
return safe_write(&buffer, length, &args->root, sizeof(args->root));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* NFS41_UNMOUNT */
|
||||||
|
int parse_unmount(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
unmount_upcall_args *args = &upcall->args.unmount;
|
||||||
|
|
||||||
|
status = safe_read(&buffer, &length, &args->root, sizeof(nfs41_session *));
|
||||||
|
if (status)
|
||||||
|
eprintf("parsing NFS41_UNMOUNT failed with %d\n", status);
|
||||||
|
else
|
||||||
|
dprintf(1, "parsing NFS41_UNMOUNT: unmount root=%p\n", args->root);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int handle_unmount(nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
int status = NO_ERROR;
|
||||||
|
unmount_upcall_args *args = &upcall->args.unmount;
|
||||||
|
nfs41_root_free(args->root);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int marshall_unmount(unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
1243
daemon/name_cache.c
Normal file
1243
daemon/name_cache.c
Normal file
File diff suppressed because it is too large
Load diff
99
daemon/name_cache.h
Normal file
99
daemon/name_cache.h
Normal file
|
|
@ -0,0 +1,99 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __NFS41_DAEMON_NAME_CACHE_H__
|
||||||
|
#define __NFS41_DAEMON_NAME_CACHE_H__
|
||||||
|
|
||||||
|
#include "nfs41.h"
|
||||||
|
|
||||||
|
|
||||||
|
static __inline struct nfs41_name_cache* client_name_cache(
|
||||||
|
IN nfs41_client *client)
|
||||||
|
{
|
||||||
|
return client_server(client)->name_cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline struct nfs41_name_cache* session_name_cache(
|
||||||
|
IN nfs41_session *session)
|
||||||
|
{
|
||||||
|
return client_name_cache(session->client);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* attribute cache */
|
||||||
|
int nfs41_attr_cache_lookup(
|
||||||
|
IN struct nfs41_name_cache *cache,
|
||||||
|
IN uint64_t fileid,
|
||||||
|
OUT nfs41_file_info *info_out);
|
||||||
|
|
||||||
|
int nfs41_attr_cache_update(
|
||||||
|
IN struct nfs41_name_cache *cache,
|
||||||
|
IN uint64_t fileid,
|
||||||
|
IN const nfs41_file_info *info);
|
||||||
|
|
||||||
|
|
||||||
|
/* name cache */
|
||||||
|
int nfs41_name_cache_create(
|
||||||
|
OUT struct nfs41_name_cache **cache_out);
|
||||||
|
|
||||||
|
int nfs41_name_cache_free(
|
||||||
|
IN OUT struct nfs41_name_cache **cache_out);
|
||||||
|
|
||||||
|
int nfs41_name_cache_lookup(
|
||||||
|
IN struct nfs41_name_cache *cache,
|
||||||
|
IN const char *path,
|
||||||
|
IN const char *path_end,
|
||||||
|
OUT OPTIONAL const char **remaining_path_out,
|
||||||
|
OUT OPTIONAL nfs41_fh *parent_out,
|
||||||
|
OUT OPTIONAL nfs41_fh *target_out,
|
||||||
|
OUT OPTIONAL nfs41_file_info *info_out);
|
||||||
|
|
||||||
|
int nfs41_name_cache_insert(
|
||||||
|
IN struct nfs41_name_cache *cache,
|
||||||
|
IN const char *path,
|
||||||
|
IN const nfs41_component *name,
|
||||||
|
IN const nfs41_fh *fh,
|
||||||
|
IN const nfs41_file_info *info,
|
||||||
|
IN OPTIONAL const change_info4 *cinfo);
|
||||||
|
|
||||||
|
int nfs41_name_cache_remove(
|
||||||
|
IN struct nfs41_name_cache *cache,
|
||||||
|
IN const char *path,
|
||||||
|
IN const nfs41_component *name,
|
||||||
|
IN const change_info4 *cinfo);
|
||||||
|
|
||||||
|
int nfs41_name_cache_rename(
|
||||||
|
IN struct nfs41_name_cache *cache,
|
||||||
|
IN const char *src_path,
|
||||||
|
IN const nfs41_component *src_name,
|
||||||
|
IN const change_info4 *src_cinfo,
|
||||||
|
IN const char *dst_path,
|
||||||
|
IN const nfs41_component *dst_name,
|
||||||
|
IN const change_info4 *dst_cinfo);
|
||||||
|
|
||||||
|
int nfs41_name_cache_remove_stale(
|
||||||
|
IN struct nfs41_name_cache *cache,
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN nfs41_abs_path *path);
|
||||||
|
|
||||||
|
#endif /* !__NFS41_DAEMON_NAME_CACHE_H__ */
|
||||||
458
daemon/namespace.c
Normal file
458
daemon/namespace.c
Normal file
|
|
@ -0,0 +1,458 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <strsafe.h>
|
||||||
|
|
||||||
|
#include "nfs41_ops.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "daemon_debug.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define NSLVL 2 /* dprintf level for namespace logging */
|
||||||
|
|
||||||
|
|
||||||
|
#define client_entry(pos) list_container(pos, nfs41_client, root_entry)
|
||||||
|
|
||||||
|
|
||||||
|
/* nfs41_root */
|
||||||
|
int nfs41_root_create(
|
||||||
|
IN const char *hostname,
|
||||||
|
IN unsigned short port,
|
||||||
|
IN const nfs41_abs_path *path,
|
||||||
|
IN uint32_t wsize,
|
||||||
|
IN uint32_t rsize,
|
||||||
|
OUT nfs41_root **root_out)
|
||||||
|
{
|
||||||
|
int status = NO_ERROR;
|
||||||
|
nfs41_root *root;
|
||||||
|
|
||||||
|
dprintf(NSLVL, "--> nfs41_root_create(%s:%u:%s)\n",
|
||||||
|
hostname, port, path);
|
||||||
|
|
||||||
|
root = calloc(1, sizeof(nfs41_root));
|
||||||
|
if (root == NULL) {
|
||||||
|
status = GetLastError();
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
list_init(&root->clients);
|
||||||
|
root->port = port;
|
||||||
|
root->wsize = wsize;
|
||||||
|
root->rsize = rsize;
|
||||||
|
InitializeCriticalSection(&root->lock);
|
||||||
|
|
||||||
|
/* generate a unique client_owner */
|
||||||
|
status = nfs41_client_owner(&root->client_owner);
|
||||||
|
if (status) {
|
||||||
|
eprintf("nfs41_client_owner() failed with %d\n", status);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
*root_out = root;
|
||||||
|
out:
|
||||||
|
dprintf(NSLVL, "<-- nfs41_root_create() returning %d\n", status);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfs41_root_free(
|
||||||
|
IN nfs41_root *root)
|
||||||
|
{
|
||||||
|
struct list_entry *entry, *tmp;
|
||||||
|
|
||||||
|
dprintf(NSLVL, "--> nfs41_root_free()\n");
|
||||||
|
|
||||||
|
/* free clients */
|
||||||
|
list_for_each_tmp(entry, tmp, &root->clients)
|
||||||
|
nfs41_client_free(client_entry(entry));
|
||||||
|
free(root);
|
||||||
|
|
||||||
|
dprintf(NSLVL, "<-- nfs41_root_free()\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* root_client_find_addrs() */
|
||||||
|
struct cl_addr_info {
|
||||||
|
const multi_addr4 *addrs;
|
||||||
|
uint32_t roles;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int cl_addr_compare(
|
||||||
|
IN const struct list_entry *entry,
|
||||||
|
IN const void *value)
|
||||||
|
{
|
||||||
|
nfs41_client *client = client_entry(entry);
|
||||||
|
const struct cl_addr_info *info = (const struct cl_addr_info*)value;
|
||||||
|
uint32_t i, roles;
|
||||||
|
|
||||||
|
/* match any of the desired roles */
|
||||||
|
AcquireSRWLockShared(&client->exid_lock);
|
||||||
|
roles = info->roles & client->roles;
|
||||||
|
ReleaseSRWLockShared(&client->exid_lock);
|
||||||
|
|
||||||
|
if (roles == 0)
|
||||||
|
return ERROR_FILE_NOT_FOUND;
|
||||||
|
|
||||||
|
/* match any address in 'addrs' with any address in client->rpc->addrs */
|
||||||
|
for (i = 0; i < info->addrs->count; i++)
|
||||||
|
if (multi_addr_find(&client->rpc->addrs, &info->addrs->arr[i], NULL))
|
||||||
|
return NO_ERROR;
|
||||||
|
|
||||||
|
return ERROR_FILE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int root_client_find_addrs(
|
||||||
|
IN nfs41_root *root,
|
||||||
|
IN const multi_addr4 *addrs,
|
||||||
|
IN bool_t is_data,
|
||||||
|
OUT nfs41_client **client_out)
|
||||||
|
{
|
||||||
|
struct cl_addr_info info;
|
||||||
|
struct list_entry *entry;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
dprintf(NSLVL, "--> root_client_find_addrs()\n");
|
||||||
|
|
||||||
|
info.addrs = addrs;
|
||||||
|
info.roles = nfs41_exchange_id_flags(is_data) & EXCHGID4_FLAG_MASK_PNFS;
|
||||||
|
|
||||||
|
entry = list_search(&root->clients, &info, cl_addr_compare);
|
||||||
|
if (entry) {
|
||||||
|
*client_out = client_entry(entry);
|
||||||
|
status = NO_ERROR;
|
||||||
|
dprintf(NSLVL, "<-- root_client_find_addrs() returning 0x%p\n",
|
||||||
|
*client_out);
|
||||||
|
} else {
|
||||||
|
status = ERROR_FILE_NOT_FOUND;
|
||||||
|
dprintf(NSLVL, "<-- root_client_find_addrs() failed with %d\n",
|
||||||
|
status);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* root_client_find() */
|
||||||
|
struct cl_exid_info {
|
||||||
|
const nfs41_exchange_id_res *exchangeid;
|
||||||
|
uint32_t roles;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int cl_exid_compare(
|
||||||
|
IN const struct list_entry *entry,
|
||||||
|
IN const void *value)
|
||||||
|
{
|
||||||
|
nfs41_client *client = client_entry(entry);
|
||||||
|
const struct cl_exid_info *info = (const struct cl_exid_info*)value;
|
||||||
|
int status = ERROR_FILE_NOT_FOUND;
|
||||||
|
|
||||||
|
AcquireSRWLockShared(&client->exid_lock);
|
||||||
|
|
||||||
|
/* match any of the desired roles */
|
||||||
|
if ((info->roles & client->roles) == 0)
|
||||||
|
goto out;
|
||||||
|
/* match clientid */
|
||||||
|
if (info->exchangeid->clientid != client->clnt_id)
|
||||||
|
goto out;
|
||||||
|
/* match server_owner.major_id */
|
||||||
|
if (strncmp(info->exchangeid->server_owner.so_major_id,
|
||||||
|
client->server->owner, NFS4_OPAQUE_LIMIT) != 0)
|
||||||
|
goto out;
|
||||||
|
/* match server_scope */
|
||||||
|
if (strncmp(info->exchangeid->server_scope,
|
||||||
|
client->server->scope, NFS4_OPAQUE_LIMIT) != 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
status = NO_ERROR;
|
||||||
|
out:
|
||||||
|
ReleaseSRWLockShared(&client->exid_lock);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int root_client_find(
|
||||||
|
IN nfs41_root *root,
|
||||||
|
IN const nfs41_exchange_id_res *exchangeid,
|
||||||
|
IN bool_t is_data,
|
||||||
|
OUT nfs41_client **client_out)
|
||||||
|
{
|
||||||
|
struct cl_exid_info info;
|
||||||
|
struct list_entry *entry;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
dprintf(NSLVL, "--> root_client_find()\n");
|
||||||
|
|
||||||
|
info.exchangeid = exchangeid;
|
||||||
|
info.roles = nfs41_exchange_id_flags(is_data) & EXCHGID4_FLAG_MASK_PNFS;
|
||||||
|
|
||||||
|
entry = list_search(&root->clients, &info, cl_exid_compare);
|
||||||
|
if (entry) {
|
||||||
|
*client_out = client_entry(entry);
|
||||||
|
status = NO_ERROR;
|
||||||
|
dprintf(NSLVL, "<-- root_client_find() returning 0x%p\n",
|
||||||
|
*client_out);
|
||||||
|
} else {
|
||||||
|
status = ERROR_FILE_NOT_FOUND;
|
||||||
|
dprintf(NSLVL, "<-- root_client_find() failed with %d\n",
|
||||||
|
status);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int session_get_lease(
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN OPTIONAL uint32_t lease_time)
|
||||||
|
{
|
||||||
|
bool_t use_mds_lease;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
/* http://tools.ietf.org/html/rfc5661#section-13.1.1
|
||||||
|
* 13.1.1. Sessions Considerations for Data Servers:
|
||||||
|
* If the reply to EXCHANGE_ID has just the EXCHGID4_FLAG_USE_PNFS_DS role
|
||||||
|
* set, then (as noted in Section 13.6) the client will not be able to
|
||||||
|
* determine the data server's lease_time attribute because GETATTR will
|
||||||
|
* not be permitted. Instead, the rule is that any time a client
|
||||||
|
* receives a layout referring it to a data server that returns just the
|
||||||
|
* EXCHGID4_FLAG_USE_PNFS_DS role, the client MAY assume that the
|
||||||
|
* lease_time attribute from the metadata server that returned the
|
||||||
|
* layout applies to the data server. */
|
||||||
|
AcquireSRWLockShared(&session->client->exid_lock);
|
||||||
|
use_mds_lease = session->client->roles == EXCHGID4_FLAG_USE_PNFS_DS;
|
||||||
|
ReleaseSRWLockShared(&session->client->exid_lock);
|
||||||
|
|
||||||
|
if (!use_mds_lease) {
|
||||||
|
/* the client is allowed to GETATTR, so query the lease_time */
|
||||||
|
nfs41_file_info info = { 0 };
|
||||||
|
bitmap4 attr_request = { 1, { FATTR4_WORD0_LEASE_TIME, 0, 0 } };
|
||||||
|
|
||||||
|
status = nfs41_getattr(session, NULL, &attr_request, &info);
|
||||||
|
if (status) {
|
||||||
|
eprintf("nfs41_getattr() failed with %s\n",
|
||||||
|
nfs_error_string(status));
|
||||||
|
status = nfs_to_windows_error(status, ERROR_BAD_NET_RESP);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
lease_time = info.lease_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = nfs41_session_set_lease(session, lease_time);
|
||||||
|
if (status) {
|
||||||
|
eprintf("nfs41_session_set_lease() failed %d\n", status);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int root_client_create(
|
||||||
|
IN nfs41_root *root,
|
||||||
|
IN nfs41_rpc_clnt *rpc,
|
||||||
|
IN bool_t is_data,
|
||||||
|
IN OPTIONAL uint32_t lease_time,
|
||||||
|
IN const nfs41_exchange_id_res *exchangeid,
|
||||||
|
OUT nfs41_client **client_out)
|
||||||
|
{
|
||||||
|
nfs41_client *client;
|
||||||
|
nfs41_session *session;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
/* create client (transfers ownership of rpc to client) */
|
||||||
|
status = nfs41_client_create(rpc, &root->client_owner,
|
||||||
|
is_data, exchangeid, &client);
|
||||||
|
if (status) {
|
||||||
|
eprintf("nfs41_client_create() failed with %d\n", status);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
rpc->client = client;
|
||||||
|
|
||||||
|
/* create session (and client takes ownership) */
|
||||||
|
status = nfs41_session_create(client, &session);
|
||||||
|
if (status) {
|
||||||
|
eprintf("nfs41_session_create failed %d\n", status);
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_data) {
|
||||||
|
/* send RECLAIM_COMPLETE, but don't fail on ERR_NOTSUPP */
|
||||||
|
status = nfs41_reclaim_complete(session);
|
||||||
|
if (status && status != NFS4ERR_NOTSUPP) {
|
||||||
|
eprintf("nfs41_reclaim_complete() failed with %s\n",
|
||||||
|
nfs_error_string(status));
|
||||||
|
status = ERROR_BAD_NETPATH;
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get least time and start session renewal thread */
|
||||||
|
status = session_get_lease(session, lease_time);
|
||||||
|
if (status)
|
||||||
|
goto out_err;
|
||||||
|
|
||||||
|
*client_out = client;
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
|
||||||
|
out_err:
|
||||||
|
nfs41_client_free(client);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nfs41_root_mount_addrs(
|
||||||
|
IN nfs41_root *root,
|
||||||
|
IN const multi_addr4 *addrs,
|
||||||
|
IN bool_t is_data,
|
||||||
|
IN OPTIONAL uint32_t lease_time,
|
||||||
|
OUT nfs41_client **client_out)
|
||||||
|
{
|
||||||
|
nfs41_exchange_id_res exchangeid;
|
||||||
|
nfs41_rpc_clnt *rpc;
|
||||||
|
nfs41_client *client, *existing;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
dprintf(NSLVL, "--> nfs41_root_mount_addrs()\n");
|
||||||
|
|
||||||
|
/* look for an existing client that matches the address and role */
|
||||||
|
EnterCriticalSection(&root->lock);
|
||||||
|
status = root_client_find_addrs(root, addrs, is_data, &client);
|
||||||
|
LeaveCriticalSection(&root->lock);
|
||||||
|
|
||||||
|
if (status == NO_ERROR)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* create an rpc client */
|
||||||
|
status = nfs41_rpc_clnt_create(addrs, root->wsize, root->rsize, !is_data, &rpc);
|
||||||
|
if (status) {
|
||||||
|
eprintf("nfs41_rpc_clnt_create() failed %d\n", status);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get a clientid with exchangeid */
|
||||||
|
ZeroMemory(&exchangeid, sizeof(exchangeid));
|
||||||
|
status = nfs41_exchange_id(rpc, &root->client_owner,
|
||||||
|
nfs41_exchange_id_flags(is_data), &exchangeid);
|
||||||
|
if (status) {
|
||||||
|
eprintf("nfs41_exchange_id() failed %s\n",
|
||||||
|
nfs_error_string(status));
|
||||||
|
status = ERROR_BAD_NET_RESP;
|
||||||
|
goto out_free_rpc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* attempt to match existing clients by the exchangeid response */
|
||||||
|
EnterCriticalSection(&root->lock);
|
||||||
|
status = root_client_find(root, &exchangeid, is_data, &client);
|
||||||
|
LeaveCriticalSection(&root->lock);
|
||||||
|
|
||||||
|
if (status == NO_ERROR)
|
||||||
|
goto out_free_rpc;
|
||||||
|
|
||||||
|
/* create a client for this clientid */
|
||||||
|
status = root_client_create(root, rpc, is_data,
|
||||||
|
lease_time, &exchangeid, &client);
|
||||||
|
if (status) {
|
||||||
|
eprintf("nfs41_client_create() failed %d\n", status);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* because we don't hold the root's lock over session creation,
|
||||||
|
* we could end up creating multiple clients with the same
|
||||||
|
* server and roles */
|
||||||
|
EnterCriticalSection(&root->lock);
|
||||||
|
status = root_client_find(root, &exchangeid, is_data, &existing);
|
||||||
|
|
||||||
|
if (status) {
|
||||||
|
dprintf(NSLVL, "caching new client 0x%p\n", client);
|
||||||
|
|
||||||
|
/* the client is not a duplicate, so add it to the list */
|
||||||
|
list_add_tail(&root->clients, &client->root_entry);
|
||||||
|
status = NO_ERROR;
|
||||||
|
} else {
|
||||||
|
dprintf(NSLVL, "created a duplicate client 0x%p! using "
|
||||||
|
"existing client 0x%p instead\n", client, existing);
|
||||||
|
|
||||||
|
/* a matching client has been created in parallel, so free
|
||||||
|
* the one we created and use the existing client instead */
|
||||||
|
nfs41_client_free(client);
|
||||||
|
client = existing;
|
||||||
|
}
|
||||||
|
LeaveCriticalSection(&root->lock);
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (status == NO_ERROR)
|
||||||
|
*client_out = client;
|
||||||
|
dprintf(NSLVL, "<-- nfs41_root_mount_addrs() returning %d\n", status);
|
||||||
|
return status;
|
||||||
|
|
||||||
|
out_free_rpc:
|
||||||
|
nfs41_rpc_clnt_free(rpc);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* http://tools.ietf.org/html/rfc5661#section-11.9
|
||||||
|
* 11.9. The Attribute fs_locations
|
||||||
|
* An entry in the server array is a UTF-8 string and represents one of a
|
||||||
|
* traditional DNS host name, IPv4 address, IPv6 address, or a zero-length
|
||||||
|
* string. An IPv4 or IPv6 address is represented as a universal address
|
||||||
|
* (see Section 3.3.9 and [15]), minus the netid, and either with or without
|
||||||
|
* the trailing ".p1.p2" suffix that represents the port number. If the
|
||||||
|
* suffix is omitted, then the default port, 2049, SHOULD be assumed. A
|
||||||
|
* zero-length string SHOULD be used to indicate the current address being
|
||||||
|
* used for the RPC call. */
|
||||||
|
static int referral_mount_location(
|
||||||
|
IN nfs41_root *root,
|
||||||
|
IN const fs_location4 *loc,
|
||||||
|
OUT nfs41_client **client_out)
|
||||||
|
{
|
||||||
|
multi_addr4 addrs;
|
||||||
|
int status = ERROR_BAD_NET_NAME;
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
/* create a client and session for the first available server */
|
||||||
|
for (i = 0; i < loc->server_count; i++) {
|
||||||
|
/* XXX: only deals with 'address' as a hostname with default port */
|
||||||
|
status = nfs41_server_resolve(loc->servers[i].address, 2049, &addrs);
|
||||||
|
if (status) continue;
|
||||||
|
|
||||||
|
status = nfs41_root_mount_addrs(root, &addrs, 0, 0, client_out);
|
||||||
|
if (status == NO_ERROR)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nfs41_root_mount_referral(
|
||||||
|
IN nfs41_root *root,
|
||||||
|
IN const fs_locations4 *locations,
|
||||||
|
OUT const fs_location4 **loc_out,
|
||||||
|
OUT nfs41_client **client_out)
|
||||||
|
{
|
||||||
|
int status = ERROR_BAD_NET_NAME;
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
/* establish a mount to the first available location */
|
||||||
|
for (i = 0; i < locations->location_count; i++) {
|
||||||
|
status = referral_mount_location(root,
|
||||||
|
&locations->locations[i], client_out);
|
||||||
|
if (status == NO_ERROR) {
|
||||||
|
*loc_out = &locations->locations[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
357
daemon/nfs41.h
Normal file
357
daemon/nfs41.h
Normal file
|
|
@ -0,0 +1,357 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __NFS41__
|
||||||
|
#define __NFS41__
|
||||||
|
|
||||||
|
#include "nfs41_types.h"
|
||||||
|
#include "list.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct __nfs41_session;
|
||||||
|
struct __nfs41_client;
|
||||||
|
struct __rpc_client;
|
||||||
|
|
||||||
|
typedef struct __nfs41_superblock {
|
||||||
|
nfs41_fsid fsid;
|
||||||
|
bitmap4 supported_attrs;
|
||||||
|
uint64_t maxread;
|
||||||
|
uint64_t maxwrite;
|
||||||
|
uint32_t layout_types;
|
||||||
|
struct list_entry entry; /* position in nfs41_server.superblocks */
|
||||||
|
|
||||||
|
SRWLOCK lock;
|
||||||
|
} nfs41_superblock;
|
||||||
|
|
||||||
|
typedef struct __nfs41_superblock_list {
|
||||||
|
struct list_entry head;
|
||||||
|
SRWLOCK lock;
|
||||||
|
} nfs41_superblock_list;
|
||||||
|
|
||||||
|
struct server_addrs {
|
||||||
|
multi_addr4 addrs; /* list of addrs we've used with this server */
|
||||||
|
uint32_t next_index;
|
||||||
|
SRWLOCK lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct __nfs41_server {
|
||||||
|
char scope[NFS4_OPAQUE_LIMIT]; /* server_scope from exchangeid */
|
||||||
|
char owner[NFS4_OPAQUE_LIMIT]; /* server_owner.major_id from exchangeid */
|
||||||
|
struct server_addrs addrs;
|
||||||
|
nfs41_superblock_list superblocks;
|
||||||
|
struct nfs41_name_cache *name_cache;
|
||||||
|
struct list_entry entry; /* position in global server list */
|
||||||
|
LONG ref_count;
|
||||||
|
} nfs41_server;
|
||||||
|
|
||||||
|
typedef struct __nfs41_lock_state {
|
||||||
|
bool_t initialized;
|
||||||
|
stateid4 stateid;
|
||||||
|
SRWLOCK lock;
|
||||||
|
} nfs41_lock_state;
|
||||||
|
|
||||||
|
typedef struct __nfs41_open_state {
|
||||||
|
nfs41_abs_path path;
|
||||||
|
nfs41_path_fh parent;
|
||||||
|
nfs41_path_fh file;
|
||||||
|
struct __nfs41_session *session;
|
||||||
|
uint32_t type;
|
||||||
|
bool_t do_close;
|
||||||
|
stateid4 stateid;
|
||||||
|
state_owner4 owner;
|
||||||
|
nfs41_lock_state last_lock;
|
||||||
|
struct __pnfs_file_layout *layout;
|
||||||
|
SRWLOCK lock;
|
||||||
|
} nfs41_open_state;
|
||||||
|
|
||||||
|
typedef struct __nfs41_rpc_clnt {
|
||||||
|
struct __rpc_client *rpc;
|
||||||
|
SRWLOCK lock;
|
||||||
|
HANDLE cond;
|
||||||
|
struct __nfs41_client *client;
|
||||||
|
multi_addr4 addrs;
|
||||||
|
uint32_t addr_index; /* index of addr we're using */
|
||||||
|
uint32_t wsize;
|
||||||
|
uint32_t rsize;
|
||||||
|
uint32_t version;
|
||||||
|
bool_t is_valid_session;
|
||||||
|
bool_t in_recovery;
|
||||||
|
} nfs41_rpc_clnt;
|
||||||
|
|
||||||
|
typedef struct __nfs41_client {
|
||||||
|
nfs41_server *server;
|
||||||
|
client_owner4 owner;
|
||||||
|
uint64_t clnt_id;
|
||||||
|
uint32_t seq_id;
|
||||||
|
uint32_t roles;
|
||||||
|
SRWLOCK exid_lock;
|
||||||
|
struct __nfs41_session *session;
|
||||||
|
SRWLOCK session_lock;
|
||||||
|
nfs41_rpc_clnt *rpc;
|
||||||
|
bool_t is_data;
|
||||||
|
struct pnfs_file_layout_list *layouts;
|
||||||
|
struct pnfs_file_device_list *devices;
|
||||||
|
struct list_entry root_entry; /* position in nfs41_root.clients */
|
||||||
|
HANDLE cond;
|
||||||
|
bool_t in_recovery;
|
||||||
|
} nfs41_client;
|
||||||
|
|
||||||
|
#define NFS41_MAX_NUM_SLOTS NFS41_MAX_RPC_REQS
|
||||||
|
typedef struct __nfs41_slot_table {
|
||||||
|
uint32_t seq_nums[NFS41_MAX_NUM_SLOTS];
|
||||||
|
uint32_t used_slots[NFS41_MAX_NUM_SLOTS];
|
||||||
|
uint32_t max_slots;
|
||||||
|
uint32_t highest_used;
|
||||||
|
HANDLE lock;
|
||||||
|
HANDLE cond;
|
||||||
|
} nfs41_slot_table;
|
||||||
|
|
||||||
|
typedef struct __nfs41_channel_attrs {
|
||||||
|
uint32_t ca_headerpadsize;
|
||||||
|
uint32_t ca_maxrequestsize;
|
||||||
|
uint32_t ca_maxresponsesize;
|
||||||
|
uint32_t ca_maxresponsesize_cached;
|
||||||
|
uint32_t ca_maxoperations;
|
||||||
|
uint32_t ca_maxrequests;
|
||||||
|
uint32_t *ca_rdma_ird;
|
||||||
|
} nfs41_channel_attrs;
|
||||||
|
|
||||||
|
typedef struct __nfs41_cb_session {
|
||||||
|
unsigned char cb_sessionid[NFS4_SESSIONID_SIZE];
|
||||||
|
uint32_t cb_seqnum;
|
||||||
|
uint32_t cb_slotid;
|
||||||
|
bool_t cb_is_valid_state;
|
||||||
|
bool_t cb_cache_this;
|
||||||
|
} nfs41_cb_session;
|
||||||
|
|
||||||
|
typedef struct __nfs41_session {
|
||||||
|
nfs41_client *client;
|
||||||
|
unsigned char session_id[NFS4_SESSIONID_SIZE];
|
||||||
|
nfs41_channel_attrs fore_chan_attrs;
|
||||||
|
nfs41_channel_attrs back_chan_attrs;
|
||||||
|
uint32_t lease_time;
|
||||||
|
nfs41_slot_table table;
|
||||||
|
// array of slots
|
||||||
|
HANDLE renew_thread;
|
||||||
|
bool_t isValidState;
|
||||||
|
uint32_t flags;
|
||||||
|
nfs41_cb_session cb_session;
|
||||||
|
} nfs41_session;
|
||||||
|
|
||||||
|
typedef struct __nfs41_root {
|
||||||
|
client_owner4 client_owner;
|
||||||
|
CRITICAL_SECTION lock;
|
||||||
|
struct list_entry clients;
|
||||||
|
uint32_t wsize;
|
||||||
|
uint32_t rsize;
|
||||||
|
unsigned short port;
|
||||||
|
} nfs41_root;
|
||||||
|
|
||||||
|
|
||||||
|
/* nfs41_namespace.c */
|
||||||
|
int nfs41_root_create(
|
||||||
|
IN const char *hostname,
|
||||||
|
IN unsigned short port,
|
||||||
|
IN const nfs41_abs_path *path,
|
||||||
|
IN uint32_t wsize,
|
||||||
|
IN uint32_t rsize,
|
||||||
|
OUT nfs41_root **root_out);
|
||||||
|
|
||||||
|
void nfs41_root_free(
|
||||||
|
IN nfs41_root *root);
|
||||||
|
|
||||||
|
int nfs41_root_mount_addrs(
|
||||||
|
IN nfs41_root *root,
|
||||||
|
IN const multi_addr4 *addrs,
|
||||||
|
IN bool_t is_data,
|
||||||
|
IN OPTIONAL uint32_t lease_time,
|
||||||
|
OUT nfs41_client **client_out);
|
||||||
|
|
||||||
|
int nfs41_root_mount_server(
|
||||||
|
IN nfs41_root *root,
|
||||||
|
IN nfs41_server *server,
|
||||||
|
IN bool_t is_data,
|
||||||
|
IN OPTIONAL uint32_t lease_time,
|
||||||
|
OUT nfs41_client **client_out);
|
||||||
|
|
||||||
|
int nfs41_root_mount_referral(
|
||||||
|
IN nfs41_root *root,
|
||||||
|
IN const fs_locations4 *locations,
|
||||||
|
OUT const fs_location4 **loc_out,
|
||||||
|
OUT nfs41_client **client_out);
|
||||||
|
|
||||||
|
static __inline nfs41_session* nfs41_root_session(
|
||||||
|
IN nfs41_root *root)
|
||||||
|
{
|
||||||
|
nfs41_client *client;
|
||||||
|
/* return a session for the server at the root of the namespace.
|
||||||
|
* because we created it on mount, it's the first one in the list */
|
||||||
|
EnterCriticalSection(&root->lock);
|
||||||
|
client = list_container(root->clients.next, nfs41_client, root_entry);
|
||||||
|
LeaveCriticalSection(&root->lock);
|
||||||
|
return client->session;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* nfs41_session.c */
|
||||||
|
int nfs41_session_create(
|
||||||
|
IN nfs41_client *client,
|
||||||
|
IN nfs41_session **session_out);
|
||||||
|
|
||||||
|
int nfs41_session_renew(
|
||||||
|
IN nfs41_session *session);
|
||||||
|
|
||||||
|
int nfs41_session_set_lease(
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN uint32_t lease_time);
|
||||||
|
|
||||||
|
void nfs41_session_free(
|
||||||
|
IN nfs41_session *session);
|
||||||
|
|
||||||
|
int nfs41_session_bump_seq(
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN uint32_t slotid);
|
||||||
|
|
||||||
|
int nfs41_session_free_slot(
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN uint32_t slotid);
|
||||||
|
|
||||||
|
int nfs41_session_get_slot(
|
||||||
|
IN nfs41_session *session,
|
||||||
|
OUT uint32_t *slot,
|
||||||
|
OUT uint32_t *seq,
|
||||||
|
OUT uint32_t *highest);
|
||||||
|
|
||||||
|
struct __nfs41_sequence_args;
|
||||||
|
int nfs41_session_sequence(
|
||||||
|
struct __nfs41_sequence_args *args,
|
||||||
|
nfs41_session *session,
|
||||||
|
bool_t cachethis);
|
||||||
|
|
||||||
|
|
||||||
|
/* nfs41_server.c */
|
||||||
|
void nfs41_server_list_init();
|
||||||
|
|
||||||
|
int nfs41_server_resolve(
|
||||||
|
IN const char *hostname,
|
||||||
|
IN unsigned short port,
|
||||||
|
OUT multi_addr4 *addrs);
|
||||||
|
|
||||||
|
int nfs41_server_find_or_create(
|
||||||
|
IN const char *server_owner_major_id,
|
||||||
|
IN const char *server_scope,
|
||||||
|
IN const netaddr4 *addr,
|
||||||
|
OUT nfs41_server **server_out);
|
||||||
|
|
||||||
|
void nfs41_server_ref(
|
||||||
|
IN nfs41_server *server);
|
||||||
|
|
||||||
|
void nfs41_server_deref(
|
||||||
|
IN nfs41_server *server);
|
||||||
|
|
||||||
|
void nfs41_server_addrs(
|
||||||
|
IN nfs41_server *server,
|
||||||
|
OUT multi_addr4 *addrs);
|
||||||
|
|
||||||
|
|
||||||
|
/* nfs41_client.c */
|
||||||
|
int nfs41_client_owner(
|
||||||
|
OUT client_owner4 *owner);
|
||||||
|
|
||||||
|
uint32_t nfs41_exchange_id_flags(
|
||||||
|
IN bool_t is_data);
|
||||||
|
|
||||||
|
struct __nfs41_exchange_id_res;
|
||||||
|
|
||||||
|
int nfs41_client_create(
|
||||||
|
IN nfs41_rpc_clnt *rpc,
|
||||||
|
IN const client_owner4 *owner,
|
||||||
|
IN bool_t is_data,
|
||||||
|
IN const struct __nfs41_exchange_id_res *exchangeid,
|
||||||
|
OUT nfs41_client **client_out);
|
||||||
|
|
||||||
|
int nfs41_client_renew(
|
||||||
|
IN nfs41_client *client);
|
||||||
|
|
||||||
|
void nfs41_client_free(
|
||||||
|
IN nfs41_client *client);
|
||||||
|
|
||||||
|
static __inline nfs41_server* client_server(
|
||||||
|
IN nfs41_client *client)
|
||||||
|
{
|
||||||
|
/* the client's server could change during nfs41_client_renew(),
|
||||||
|
* so access to client->server must be protected */
|
||||||
|
nfs41_server *server;
|
||||||
|
AcquireSRWLockShared(&client->exid_lock);
|
||||||
|
server = client->server;
|
||||||
|
ReleaseSRWLockShared(&client->exid_lock);
|
||||||
|
return server;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* nfs41_superblock.c */
|
||||||
|
int nfs41_superblock_for_fh(
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN const nfs41_fsid *fsid,
|
||||||
|
IN const nfs41_fh *parent OPTIONAL,
|
||||||
|
OUT nfs41_path_fh *file);
|
||||||
|
|
||||||
|
void nfs41_superblock_list_init(
|
||||||
|
IN nfs41_superblock_list *superblocks);
|
||||||
|
|
||||||
|
void nfs41_superblock_list_free(
|
||||||
|
IN nfs41_superblock_list *superblocks);
|
||||||
|
|
||||||
|
|
||||||
|
/* nfs41_rpc.c */
|
||||||
|
int nfs41_rpc_clnt_create(
|
||||||
|
IN const multi_addr4 *addrs,
|
||||||
|
IN uint32_t wsize,
|
||||||
|
IN uint32_t rsize,
|
||||||
|
IN bool_t needcb,
|
||||||
|
OUT nfs41_rpc_clnt **rpc_out);
|
||||||
|
|
||||||
|
void nfs41_rpc_clnt_free(
|
||||||
|
IN nfs41_rpc_clnt *rpc);
|
||||||
|
|
||||||
|
int nfs41_send_compound(
|
||||||
|
IN nfs41_rpc_clnt *rpc,
|
||||||
|
IN char *inbuf,
|
||||||
|
OUT char *outbuf);
|
||||||
|
|
||||||
|
static __inline netaddr4* nfs41_rpc_netaddr(
|
||||||
|
IN nfs41_rpc_clnt *rpc)
|
||||||
|
{
|
||||||
|
uint32_t id;
|
||||||
|
AcquireSRWLockShared(&rpc->lock);
|
||||||
|
/* only addr_index needs to be protected, as rpc->addrs is write-once */
|
||||||
|
id = rpc->addr_index;
|
||||||
|
ReleaseSRWLockShared(&rpc->lock);
|
||||||
|
|
||||||
|
/* return the netaddr used to create the rpc client */
|
||||||
|
return &rpc->addrs.arr[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t nfs41_renew_in_progress(nfs41_client *client, bool_t *value);
|
||||||
|
|
||||||
|
#endif /* __NFS41__ */
|
||||||
254
daemon/nfs41_callback.h
Normal file
254
daemon/nfs41_callback.h
Normal file
|
|
@ -0,0 +1,254 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __NFS41_CALLBACK_H__
|
||||||
|
#define __NFS41_CALLBACK_H__
|
||||||
|
|
||||||
|
//#include "nfs41.h"
|
||||||
|
#include "wintirpc.h"
|
||||||
|
#include "rpc/rpc.h"
|
||||||
|
#include "nfs41_types.h"
|
||||||
|
|
||||||
|
|
||||||
|
enum nfs41_callback_proc {
|
||||||
|
CB_NULL = 0,
|
||||||
|
CB_COMPOUND = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum nfs41_callback_op {
|
||||||
|
OP_CB_GETATTR = 3,
|
||||||
|
OP_CB_RECALL = 4,
|
||||||
|
OP_CB_LAYOUTRECALL = 5,
|
||||||
|
OP_CB_NOTIFY = 6,
|
||||||
|
OP_CB_PUSH_DELEG = 7,
|
||||||
|
OP_CB_RECALL_ANY = 8,
|
||||||
|
OP_CB_RECALLABLE_OBJ_AVAIL = 9,
|
||||||
|
OP_CB_RECALL_SLOT = 10,
|
||||||
|
OP_CB_SEQUENCE = 11,
|
||||||
|
OP_CB_WANTS_CANCELLED = 12,
|
||||||
|
OP_CB_NOTIFY_LOCK = 13,
|
||||||
|
OP_CB_NOTIFY_DEVICEID = 14,
|
||||||
|
OP_CB_ILLEGAL = 10044
|
||||||
|
};
|
||||||
|
|
||||||
|
int nfs41_handle_callback(void *, void *, void *);
|
||||||
|
|
||||||
|
/* OP_CB_LAYOUTRECALL */
|
||||||
|
struct cb_recall_file {
|
||||||
|
nfs41_fh fh;
|
||||||
|
uint64_t offset;
|
||||||
|
uint64_t length;
|
||||||
|
stateid4 stateid;
|
||||||
|
};
|
||||||
|
union cb_recall_file_args {
|
||||||
|
struct cb_recall_file file;
|
||||||
|
nfs41_fsid fsid;
|
||||||
|
};
|
||||||
|
struct cb_recall {
|
||||||
|
enum pnfs_return_type type;
|
||||||
|
union cb_recall_file_args args;
|
||||||
|
};
|
||||||
|
struct cb_layoutrecall_args {
|
||||||
|
enum pnfs_layout_type type;
|
||||||
|
enum pnfs_iomode iomode;
|
||||||
|
bool_t changed;
|
||||||
|
struct cb_recall recall;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cb_layoutrecall_res {
|
||||||
|
enum_t status;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* OP_CB_RECALL_SLOT */
|
||||||
|
struct cb_recall_slot_args {
|
||||||
|
uint32_t target_highest_slotid;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cb_recall_slot_res {
|
||||||
|
enum_t status;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* OP_CB_SEQUENCE */
|
||||||
|
struct cb_sequence_ref {
|
||||||
|
uint32_t sequenceid;
|
||||||
|
uint32_t slotid;
|
||||||
|
};
|
||||||
|
struct cb_sequence_ref_list {
|
||||||
|
char sessionid[NFS4_SESSIONID_SIZE];
|
||||||
|
struct cb_sequence_ref *calls;
|
||||||
|
uint32_t call_count;
|
||||||
|
};
|
||||||
|
struct cb_sequence_args {
|
||||||
|
char sessionid[NFS4_SESSIONID_SIZE];
|
||||||
|
uint32_t sequenceid;
|
||||||
|
uint32_t slotid;
|
||||||
|
uint32_t highest_slotid;
|
||||||
|
bool_t cachethis;
|
||||||
|
struct cb_sequence_ref_list *ref_lists;
|
||||||
|
uint32_t ref_list_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cb_sequence_res_ok {
|
||||||
|
char sessionid[NFS4_SESSIONID_SIZE];
|
||||||
|
uint32_t sequenceid;
|
||||||
|
uint32_t slotid;
|
||||||
|
uint32_t highest_slotid;
|
||||||
|
uint32_t target_highest_slotid;
|
||||||
|
};
|
||||||
|
struct cb_sequence_res {
|
||||||
|
enum_t status;
|
||||||
|
struct cb_sequence_res_ok ok;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* OP_CB_GETATTR */
|
||||||
|
struct cb_getattr_args {
|
||||||
|
uint32_t target_highest_slotid;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cb_getattr_res {
|
||||||
|
enum_t status;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* OP_CB_RECALL */
|
||||||
|
struct cb_recall_args {
|
||||||
|
stateid4 stateid;
|
||||||
|
bool_t truncate;
|
||||||
|
nfs41_fh fh;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cb_recall_res {
|
||||||
|
enum_t status;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* OP_CB_NOTIFY */
|
||||||
|
struct cb_notify_args {
|
||||||
|
uint32_t target_highest_slotid;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cb_notify_res {
|
||||||
|
enum_t status;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* OP_CB_PUSH_DELEG */
|
||||||
|
struct cb_push_deleg_args {
|
||||||
|
uint32_t target_highest_slotid;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cb_push_deleg_res {
|
||||||
|
enum_t status;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* OP_CB_RECALL_ANY */
|
||||||
|
struct cb_recall_any_args {
|
||||||
|
uint32_t target_highest_slotid;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cb_recall_any_res {
|
||||||
|
enum_t status;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* OP_CB_RECALLABLE_OBJ_AVAIL */
|
||||||
|
struct cb_recallable_obj_avail_args {
|
||||||
|
uint32_t target_highest_slotid;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cb_recallable_obj_avail_res {
|
||||||
|
enum_t status;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* OP_CB_WANTS_CANCELLED */
|
||||||
|
struct cb_wants_cancelled_args {
|
||||||
|
uint32_t target_highest_slotid;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cb_wants_cancelled_res {
|
||||||
|
enum_t status;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* OP_CB_NOTIFY_LOCK */
|
||||||
|
struct cb_notify_lock_args {
|
||||||
|
uint32_t target_highest_slotid;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cb_notify_lock_res {
|
||||||
|
enum_t status;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* OP_CB_NOTIFY_DEVICEID */
|
||||||
|
struct cb_notify_deviceid_args {
|
||||||
|
uint32_t target_highest_slotid;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cb_notify_deviceid_res {
|
||||||
|
enum_t status;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* CB_COMPOUND */
|
||||||
|
#define CB_COMPOUND_MAX_TAG 64
|
||||||
|
#define CB_COMPOUND_MAX_OPERATIONS 16
|
||||||
|
|
||||||
|
union cb_op_args {
|
||||||
|
struct cb_layoutrecall_args layoutrecall;
|
||||||
|
struct cb_recall_slot_args recall_slot;
|
||||||
|
struct cb_sequence_args sequence;
|
||||||
|
struct cb_recall_args recall;
|
||||||
|
};
|
||||||
|
struct cb_argop {
|
||||||
|
enum_t opnum;
|
||||||
|
union cb_op_args args;
|
||||||
|
};
|
||||||
|
struct cb_compound_tag {
|
||||||
|
char str[CB_COMPOUND_MAX_TAG];
|
||||||
|
uint32_t len;
|
||||||
|
};
|
||||||
|
struct cb_compound_args {
|
||||||
|
struct cb_compound_tag tag;
|
||||||
|
uint32_t minorversion;
|
||||||
|
uint32_t callback_ident; /* client MUST ignore */
|
||||||
|
struct cb_argop *argarray;
|
||||||
|
uint32_t argarray_count; /* <= CB_COMPOUND_MAX_OPERATIONS */
|
||||||
|
};
|
||||||
|
|
||||||
|
union cb_op_res {
|
||||||
|
struct cb_layoutrecall_res layoutrecall;
|
||||||
|
struct cb_recall_slot_res recall_slot;
|
||||||
|
struct cb_sequence_res sequence;
|
||||||
|
struct cb_recall_res recall;
|
||||||
|
};
|
||||||
|
struct cb_resop {
|
||||||
|
enum_t opnum;
|
||||||
|
union cb_op_res res;
|
||||||
|
};
|
||||||
|
struct cb_compound_res {
|
||||||
|
enum_t status;
|
||||||
|
struct cb_compound_tag tag;
|
||||||
|
struct cb_resop *resarray;
|
||||||
|
uint32_t resarray_count; /* <= CB_COMPOUND_MAX_OPERATIONS */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* callback_xdr.c */
|
||||||
|
bool_t proc_cb_compound_args(XDR *xdr, struct cb_compound_args *args);
|
||||||
|
bool_t proc_cb_compound_res(XDR *xdr, struct cb_compound_res *res);
|
||||||
|
#endif /* !__NFS41_CALLBACK_H__ */
|
||||||
437
daemon/nfs41_client.c
Normal file
437
daemon/nfs41_client.c
Normal file
|
|
@ -0,0 +1,437 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <iphlpapi.h> /* for GetAdaptersAddresses() */
|
||||||
|
|
||||||
|
#include "rbtree.h"
|
||||||
|
#include "daemon_debug.h"
|
||||||
|
#include "nfs41_ops.h"
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t nfs41_exchange_id_flags(
|
||||||
|
IN bool_t is_data)
|
||||||
|
{
|
||||||
|
uint32_t flags = EXCHGID4_FLAG_SUPP_MOVED_REFER;
|
||||||
|
if (is_data)
|
||||||
|
flags |= EXCHGID4_FLAG_USE_PNFS_DS;
|
||||||
|
else
|
||||||
|
flags |= EXCHGID4_FLAG_USE_NON_PNFS | EXCHGID4_FLAG_USE_PNFS_MDS;
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pnfs_client_init(
|
||||||
|
IN nfs41_client *client)
|
||||||
|
{
|
||||||
|
enum pnfs_status pnfsstat;
|
||||||
|
int status = NO_ERROR;
|
||||||
|
|
||||||
|
/* initialize the pnfs layout and device lists for metadata clients */
|
||||||
|
pnfsstat = pnfs_file_layout_list_create(&client->layouts);
|
||||||
|
if (pnfsstat) {
|
||||||
|
status = ERROR_NOT_ENOUGH_MEMORY;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
pnfsstat = pnfs_file_device_list_create(&client->devices);
|
||||||
|
if (pnfsstat) {
|
||||||
|
status = ERROR_NOT_ENOUGH_MEMORY;
|
||||||
|
goto out_err_layouts;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
|
||||||
|
out_err_layouts:
|
||||||
|
pnfs_file_layout_list_free(client->layouts);
|
||||||
|
client->layouts = NULL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void update_server(
|
||||||
|
IN nfs41_client *client,
|
||||||
|
IN const char *server_scope,
|
||||||
|
IN const server_owner4 *owner)
|
||||||
|
{
|
||||||
|
nfs41_server *server;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
/* find a server matching the owner.major_id and scope */
|
||||||
|
status = nfs41_server_find_or_create(owner->so_major_id,
|
||||||
|
server_scope, nfs41_rpc_netaddr(client->rpc), &server);
|
||||||
|
|
||||||
|
if (status == NO_ERROR) {
|
||||||
|
/* if the server is the same, we now have an extra reference. if
|
||||||
|
* the servers are different, we still need to deref the old server.
|
||||||
|
* so both cases can be treated the same */
|
||||||
|
if (client->server)
|
||||||
|
nfs41_server_deref(client->server);
|
||||||
|
client->server = server;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void update_exchangeid_res(
|
||||||
|
IN nfs41_client *client,
|
||||||
|
IN const nfs41_exchange_id_res *exchangeid)
|
||||||
|
{
|
||||||
|
update_server(client, exchangeid->server_scope, &exchangeid->server_owner);
|
||||||
|
client->clnt_id = exchangeid->clientid;
|
||||||
|
client->seq_id = exchangeid->sequenceid;
|
||||||
|
client->roles = exchangeid->flags & EXCHGID4_FLAG_MASK_PNFS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nfs41_client_create(
|
||||||
|
IN nfs41_rpc_clnt *rpc,
|
||||||
|
IN const client_owner4 *owner,
|
||||||
|
IN bool_t is_data,
|
||||||
|
IN const nfs41_exchange_id_res *exchangeid,
|
||||||
|
OUT nfs41_client **client_out)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
nfs41_client *client;
|
||||||
|
|
||||||
|
client = calloc(1, sizeof(nfs41_client));
|
||||||
|
if (client == NULL) {
|
||||||
|
status = GetLastError();
|
||||||
|
goto out_err_rpc;
|
||||||
|
}
|
||||||
|
|
||||||
|
client->cond = CreateEvent(NULL, TRUE, FALSE, "client_recovery_cond");
|
||||||
|
if (client->cond == NULL) {
|
||||||
|
status = GetLastError();
|
||||||
|
eprintf("CreateEvent failed %d\n", status);
|
||||||
|
goto out_err_rpc;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&client->owner, owner, sizeof(client_owner4));
|
||||||
|
client->rpc = rpc;
|
||||||
|
client->is_data = is_data;
|
||||||
|
update_exchangeid_res(client, exchangeid);
|
||||||
|
|
||||||
|
//initialize a lock used to protect access to client id and client id seq#
|
||||||
|
InitializeSRWLock(&client->exid_lock);
|
||||||
|
|
||||||
|
status = pnfs_client_init(client);
|
||||||
|
if (status) {
|
||||||
|
eprintf("pnfs_client_init() failed with %d\n", status);
|
||||||
|
goto out_err_client;
|
||||||
|
}
|
||||||
|
*client_out = client;
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
out_err_client:
|
||||||
|
nfs41_client_free(client); /* also calls nfs41_rpc_clnt_free() */
|
||||||
|
goto out;
|
||||||
|
out_err_rpc:
|
||||||
|
nfs41_rpc_clnt_free(rpc);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dprint_roles(
|
||||||
|
IN int level,
|
||||||
|
IN uint32_t roles)
|
||||||
|
{
|
||||||
|
dprintf(level, "roles: %s%s%s\n",
|
||||||
|
(roles & EXCHGID4_FLAG_USE_NON_PNFS) ? "USE_NON_PNFS " : "",
|
||||||
|
(roles & EXCHGID4_FLAG_USE_PNFS_MDS) ? "USE_PNFS_MDS " : "",
|
||||||
|
(roles & EXCHGID4_FLAG_USE_PNFS_DS) ? "USE_PNFS_DS" : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
int nfs41_client_renew(
|
||||||
|
IN nfs41_client *client)
|
||||||
|
{
|
||||||
|
nfs41_exchange_id_res exchangeid;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
ZeroMemory(&exchangeid, sizeof(exchangeid));
|
||||||
|
|
||||||
|
status = nfs41_exchange_id(client->rpc, &client->owner,
|
||||||
|
nfs41_exchange_id_flags(client->is_data), &exchangeid);
|
||||||
|
if (status) {
|
||||||
|
eprintf("nfs41_exchange_id() failed with %d\n", status);
|
||||||
|
status = ERROR_BAD_NET_RESP;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (client->is_data) { /* require USE_PNFS_DS */
|
||||||
|
if ((exchangeid.flags & EXCHGID4_FLAG_USE_PNFS_DS) == 0) {
|
||||||
|
eprintf("client expected USE_PNFS_DS\n");
|
||||||
|
status = ERROR_BAD_NET_RESP;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
} else { /* require USE_NON_PNFS or USE_PNFS_MDS */
|
||||||
|
if ((exchangeid.flags & EXCHGID4_FLAG_USE_NON_PNFS) == 0 &&
|
||||||
|
(exchangeid.flags & EXCHGID4_FLAG_USE_PNFS_MDS) == 0) {
|
||||||
|
eprintf("client expected USE_NON_PNFS OR USE_PNFS_MDS\n");
|
||||||
|
status = ERROR_BAD_NET_RESP;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dprint_roles(2, exchangeid.flags);
|
||||||
|
|
||||||
|
AcquireSRWLockExclusive(&client->exid_lock);
|
||||||
|
update_exchangeid_res(client, &exchangeid);
|
||||||
|
ReleaseSRWLockExclusive(&client->exid_lock);
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t nfs41_renew_in_progress(nfs41_client *client, bool_t *value)
|
||||||
|
{
|
||||||
|
bool_t status = FALSE;
|
||||||
|
if (value) {
|
||||||
|
dprintf(1, "nfs41_renew_in_progress: setting value %d\n", *value);
|
||||||
|
AcquireSRWLockExclusive(&client->exid_lock);
|
||||||
|
client->in_recovery = *value;
|
||||||
|
if (!client->in_recovery)
|
||||||
|
SetEvent(client->cond);
|
||||||
|
ReleaseSRWLockExclusive(&client->exid_lock);
|
||||||
|
} else {
|
||||||
|
AcquireSRWLockShared(&client->exid_lock);
|
||||||
|
status = client->in_recovery;
|
||||||
|
ReleaseSRWLockShared(&client->exid_lock);
|
||||||
|
dprintf(1, "nfs41_renew_in_progress: returning value %d\n", status);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfs41_client_free(
|
||||||
|
IN nfs41_client *client)
|
||||||
|
{
|
||||||
|
dprintf(2, "nfs41_client_free(%llu)\n", client->clnt_id);
|
||||||
|
if (client->session) nfs41_session_free(client->session);
|
||||||
|
if (client->server) nfs41_server_deref(client->server);
|
||||||
|
nfs41_rpc_clnt_free(client->rpc);
|
||||||
|
if (client->layouts) pnfs_file_layout_list_free(client->layouts);
|
||||||
|
if (client->devices) pnfs_file_device_list_free(client->devices);
|
||||||
|
CloseHandle(client->cond);
|
||||||
|
free(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* client_owner generation
|
||||||
|
* we choose to use MAC addresses to generate a client_owner value that
|
||||||
|
* is unique to a machine and persists over restarts. because the client
|
||||||
|
* can have multiple network adapters/addresses, we take each adapter into
|
||||||
|
* account. the specification suggests that "for privacy reasons, it is
|
||||||
|
* best to perform some one-way function," so we apply an md5 hash to the
|
||||||
|
* sorted list of MAC addresses */
|
||||||
|
|
||||||
|
/* References:
|
||||||
|
* RFC 5661: 2.4. Client Identifiers and Client Owners
|
||||||
|
* http://tools.ietf.org/html/rfc5661#section-2.4
|
||||||
|
*
|
||||||
|
* MSDN: GetAdaptersAddresses Function
|
||||||
|
* http://msdn.microsoft.com/en-us/library/aa365915%28VS.85%29.aspx
|
||||||
|
*
|
||||||
|
* MSDN: Example C Program: Creating an MD5 Hash from File Content
|
||||||
|
* http://msdn.microsoft.com/en-us/library/aa382380%28VS.85%29.aspx */
|
||||||
|
|
||||||
|
|
||||||
|
/* use an rbtree to sort mac address entries */
|
||||||
|
struct mac_entry {
|
||||||
|
struct rb_node rbnode;
|
||||||
|
PBYTE address;
|
||||||
|
ULONG length;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void mac_entry_insert(
|
||||||
|
IN struct rb_root *root,
|
||||||
|
IN PBYTE address,
|
||||||
|
IN ULONG length)
|
||||||
|
{
|
||||||
|
struct rb_node **node, *prev;
|
||||||
|
struct mac_entry *entry;
|
||||||
|
int diff;
|
||||||
|
|
||||||
|
node = &root->rb_node;
|
||||||
|
prev = NULL;
|
||||||
|
|
||||||
|
while (*node) {
|
||||||
|
entry = rb_entry(*node, struct mac_entry, rbnode);
|
||||||
|
prev = *node;
|
||||||
|
|
||||||
|
diff = length - entry->length;
|
||||||
|
if (diff == 0)
|
||||||
|
diff = memcmp(address, entry->address, length);
|
||||||
|
|
||||||
|
if (diff < 0)
|
||||||
|
node = &(*node)->rb_left;
|
||||||
|
else if (diff > 0)
|
||||||
|
node = &(*node)->rb_right;
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry = calloc(1, sizeof(struct mac_entry));
|
||||||
|
if (entry) {
|
||||||
|
entry->address = address;
|
||||||
|
entry->length = length;
|
||||||
|
|
||||||
|
rb_link_node(&entry->rbnode, prev, node);
|
||||||
|
rb_insert_color(&entry->rbnode, root);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int adapter_valid(
|
||||||
|
IN const IP_ADAPTER_ADDRESSES *addr)
|
||||||
|
{
|
||||||
|
/* ignore generic interfaces whose address is not unique */
|
||||||
|
switch (addr->IfType) {
|
||||||
|
case IF_TYPE_SOFTWARE_LOOPBACK:
|
||||||
|
case IF_TYPE_TUNNEL:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* must have an address */
|
||||||
|
if (addr->PhysicalAddressLength == 0)
|
||||||
|
return 0;
|
||||||
|
/* must support ip */
|
||||||
|
return addr->Ipv4Enabled || addr->Ipv6Enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DWORD hash_mac_addrs(
|
||||||
|
IN HCRYPTHASH hash)
|
||||||
|
{
|
||||||
|
PIP_ADAPTER_ADDRESSES addr, addrs = NULL;
|
||||||
|
struct rb_root rbtree = { NULL };
|
||||||
|
struct rb_node *node;
|
||||||
|
struct mac_entry *entry;
|
||||||
|
ULONG len;
|
||||||
|
DWORD status;
|
||||||
|
|
||||||
|
/* start with enough room for DEFAULT_MINIMUM_ENTITIES */
|
||||||
|
len = DEFAULT_MINIMUM_ENTITIES * sizeof(IP_ADAPTER_ADDRESSES);
|
||||||
|
|
||||||
|
do {
|
||||||
|
PIP_ADAPTER_ADDRESSES tmp;
|
||||||
|
/* reallocate the buffer until we can fit all of it */
|
||||||
|
tmp = realloc(addrs, len);
|
||||||
|
if (tmp == NULL) {
|
||||||
|
status = GetLastError();
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
addrs = tmp;
|
||||||
|
status = GetAdaptersAddresses(AF_UNSPEC,
|
||||||
|
GAA_FLAG_INCLUDE_ALL_INTERFACES | GAA_FLAG_SKIP_ANYCAST |
|
||||||
|
GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME |
|
||||||
|
GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_UNICAST,
|
||||||
|
NULL, addrs, &len);
|
||||||
|
} while (status == ERROR_BUFFER_OVERFLOW);
|
||||||
|
|
||||||
|
if (status) {
|
||||||
|
eprintf("GetAdaptersAddresses() failed with %d\n", status);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the mac address of each adapter */
|
||||||
|
for (addr = addrs; addr; addr = addr->Next)
|
||||||
|
if (adapter_valid(addr))
|
||||||
|
mac_entry_insert(&rbtree, addr->PhysicalAddress,
|
||||||
|
addr->PhysicalAddressLength);
|
||||||
|
|
||||||
|
/* require at least one valid address */
|
||||||
|
node = rb_first(&rbtree);
|
||||||
|
if (node == NULL) {
|
||||||
|
status = ERROR_FILE_NOT_FOUND;
|
||||||
|
eprintf("GetAdaptersAddresses() did not return "
|
||||||
|
"any valid mac addresses, failing with %d.\n", status);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (node) {
|
||||||
|
entry = rb_entry(node, struct mac_entry, rbnode);
|
||||||
|
node = rb_next(node);
|
||||||
|
rb_erase(&entry->rbnode, &rbtree);
|
||||||
|
|
||||||
|
if (!CryptHashData(hash, entry->address, entry->length, 0)) {
|
||||||
|
status = GetLastError();
|
||||||
|
eprintf("CryptHashData() failed with %d\n", status);
|
||||||
|
/* don't break here, we need to free the rest */
|
||||||
|
}
|
||||||
|
free(entry);
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
free(addrs);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nfs41_client_owner(
|
||||||
|
OUT client_owner4 *owner)
|
||||||
|
{
|
||||||
|
HCRYPTPROV context;
|
||||||
|
HCRYPTHASH hash;
|
||||||
|
PBYTE buffer;
|
||||||
|
DWORD length;
|
||||||
|
const time_t time_created = time(NULL);
|
||||||
|
int status;
|
||||||
|
|
||||||
|
/* owner.verifier = "time created" */
|
||||||
|
ZeroMemory(owner->co_verifier, sizeof(owner->co_verifier));
|
||||||
|
memcpy(owner->co_verifier, &time_created, sizeof(time_created));
|
||||||
|
|
||||||
|
/* set up the md5 hash generator */
|
||||||
|
if (!CryptAcquireContext(&context, NULL, NULL,
|
||||||
|
PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
|
||||||
|
status = GetLastError();
|
||||||
|
eprintf("CryptAcquireContext() failed with %d\n", status);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (!CryptCreateHash(context, CALG_MD5, 0, 0, &hash)) {
|
||||||
|
status = GetLastError();
|
||||||
|
eprintf("CryptCreateHash() failed with %d\n", status);
|
||||||
|
goto out_context;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add the mac address from each applicable adapter to the hash */
|
||||||
|
status = hash_mac_addrs(hash);
|
||||||
|
if (status) {
|
||||||
|
eprintf("hash_mac_addrs() failed with %d\n", status);
|
||||||
|
goto out_hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* extract the hash size (should always be 16 for md5) */
|
||||||
|
buffer = (PBYTE)&owner->co_ownerid_len;
|
||||||
|
length = (DWORD)sizeof(DWORD);
|
||||||
|
if (!CryptGetHashParam(hash, HP_HASHSIZE, buffer, &length, 0)) {
|
||||||
|
status = GetLastError();
|
||||||
|
eprintf("CryptGetHashParam(size) failed with %d\n", status);
|
||||||
|
goto out_hash;
|
||||||
|
}
|
||||||
|
/* extract the hash buffer */
|
||||||
|
buffer = owner->co_ownerid;
|
||||||
|
length = owner->co_ownerid_len;
|
||||||
|
if (!CryptGetHashParam(hash, HP_HASHVAL, buffer, &length, 0)) {
|
||||||
|
status = GetLastError();
|
||||||
|
eprintf("CryptGetHashParam(val) failed with %d\n", status);
|
||||||
|
goto out_hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
out_hash:
|
||||||
|
CryptDestroyHash(hash);
|
||||||
|
out_context:
|
||||||
|
CryptReleaseContext(context, 0);
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
333
daemon/nfs41_compound.c
Normal file
333
daemon/nfs41_compound.c
Normal file
|
|
@ -0,0 +1,333 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "nfs41_compound.h"
|
||||||
|
#include "nfs41_xdr.h"
|
||||||
|
#include "nfs41_ops.h"
|
||||||
|
#include "name_cache.h"
|
||||||
|
#include "daemon_debug.h"
|
||||||
|
|
||||||
|
#define BUF_SIZE 1024
|
||||||
|
|
||||||
|
|
||||||
|
int compound_error(int status)
|
||||||
|
{
|
||||||
|
if (status != NFS4_OK)
|
||||||
|
dprintf(1, "COMPOUND failed with status %d.\n", status);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void compound_args_init(
|
||||||
|
nfs41_compound_args *compound,
|
||||||
|
nfs_argop4 *argarray)
|
||||||
|
{
|
||||||
|
compound->tag_len = 8;
|
||||||
|
memcpy(compound->tag, "ms-nfs41", 8);
|
||||||
|
compound->minorversion = 1;
|
||||||
|
compound->argarray_count = 0;
|
||||||
|
compound->argarray = argarray;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void compound_args_add_op(
|
||||||
|
nfs41_compound_args *compound,
|
||||||
|
uint32_t opnum,
|
||||||
|
void *arg)
|
||||||
|
{
|
||||||
|
const uint32_t i = compound->argarray_count++;
|
||||||
|
compound->argarray[i].op = opnum;
|
||||||
|
compound->argarray[i].arg = arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void compound_res_init(
|
||||||
|
nfs41_compound_res *compound,
|
||||||
|
nfs_resop4 *resarray)
|
||||||
|
{
|
||||||
|
ZeroMemory(compound, sizeof(nfs41_compound_res));
|
||||||
|
compound->tag_len = NFS4_OPAQUE_LIMIT;
|
||||||
|
compound->resarray_count = 0;
|
||||||
|
compound->resarray = resarray;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void compound_res_add_op(
|
||||||
|
nfs41_compound_res *compound,
|
||||||
|
void *res)
|
||||||
|
{
|
||||||
|
compound->resarray[compound->resarray_count++].res = res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void compound_init(
|
||||||
|
nfs41_compound *compound,
|
||||||
|
nfs_argop4 *argops,
|
||||||
|
nfs_resop4 *resops)
|
||||||
|
{
|
||||||
|
compound_args_init(&compound->args, argops);
|
||||||
|
compound_res_init(&compound->res, resops);
|
||||||
|
}
|
||||||
|
|
||||||
|
void compound_add_op(
|
||||||
|
nfs41_compound *compound,
|
||||||
|
uint32_t opnum,
|
||||||
|
void *arg,
|
||||||
|
void *res)
|
||||||
|
{
|
||||||
|
compound_args_add_op(&compound->args, opnum, arg);
|
||||||
|
compound_res_add_op(&compound->res, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Due to the possibility of replays, we might get a response to a different
|
||||||
|
* call than the one we're expecting. If we don't have a way to check for
|
||||||
|
* this, we'll likely crash trying to decode into the wrong structures.
|
||||||
|
* This function copies the number of operations and all of the operation
|
||||||
|
* numbers from the compound arguments into the response, so we can verify
|
||||||
|
* them on decode and fail before doing any damage. */
|
||||||
|
static void set_expected_res(
|
||||||
|
nfs41_compound *compound)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
compound->res.resarray_count = compound->args.argarray_count;
|
||||||
|
for (i = 0; i < compound->res.resarray_count; i++)
|
||||||
|
compound->res.resarray[i].op = compound->args.argarray[i].op;
|
||||||
|
}
|
||||||
|
|
||||||
|
int check_renew_in_progress(
|
||||||
|
IN nfs41_session *session)
|
||||||
|
{
|
||||||
|
int status = 0;
|
||||||
|
bool_t one = 1, zero = 0;;
|
||||||
|
while (nfs41_renew_in_progress(session->client, NULL)) {
|
||||||
|
status = WaitForSingleObject(session->client->cond, INFINITE);
|
||||||
|
if (status != WAIT_OBJECT_0) {
|
||||||
|
dprintf(1, "nfs41_renew_in_progress: WaitForSingleObject failed\n");
|
||||||
|
print_condwait_status(1, status);
|
||||||
|
status = ERROR_LOCK_VIOLATION;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
nfs41_renew_in_progress(session->client, &zero);
|
||||||
|
status = 1;
|
||||||
|
}
|
||||||
|
nfs41_renew_in_progress(session->client, &one);
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
int compound_encode_send_decode(
|
||||||
|
nfs41_session *session,
|
||||||
|
nfs41_compound *compound,
|
||||||
|
uint32_t bufsize_in,
|
||||||
|
uint32_t bufsize_out)
|
||||||
|
{
|
||||||
|
int status, retry_count = 0, delayby = 0;
|
||||||
|
nfs41_sequence_args *args =
|
||||||
|
(nfs41_sequence_args *)compound->args.argarray[0].arg;
|
||||||
|
bool_t zero = 0;
|
||||||
|
|
||||||
|
retry:
|
||||||
|
/* send compound */
|
||||||
|
retry_count++;
|
||||||
|
set_expected_res(compound);
|
||||||
|
status = nfs41_send_compound(session->client->rpc,
|
||||||
|
(char *)&compound->args, (char *)&compound->res);
|
||||||
|
|
||||||
|
if (status) {
|
||||||
|
eprintf("nfs41_send_compound failed %d for seqid=%d, slotid=%d\n",
|
||||||
|
status, args->sa_sequenceid, args->sa_slotid);
|
||||||
|
status = NFS4ERR_IO;
|
||||||
|
goto out_free_slot;
|
||||||
|
} else {
|
||||||
|
// bump sequence number if sequence op succeeded
|
||||||
|
if (compound->res.resarray_count > 0 &&
|
||||||
|
compound->res.resarray[0].op == OP_SEQUENCE) {
|
||||||
|
nfs41_sequence_res *seq =
|
||||||
|
(nfs41_sequence_res *)compound->res.resarray[0].res;
|
||||||
|
if (seq->sr_status == NFS4_OK) {
|
||||||
|
// returned slotid must be the same we sent
|
||||||
|
status = NFS4ERR_IO;
|
||||||
|
if (seq->sr_resok4.sr_slotid != args->sa_slotid) {
|
||||||
|
eprintf("[session] sr_slotid=%d != sa_slotid=%d\n",
|
||||||
|
seq->sr_resok4.sr_slotid, args->sa_slotid);
|
||||||
|
goto out_free_slot;
|
||||||
|
}
|
||||||
|
// returned sessionid must be the same we sent
|
||||||
|
if (memcmp(seq->sr_resok4.sr_sessionid, args->sa_sessionid,
|
||||||
|
NFS4_SESSIONID_SIZE)) {
|
||||||
|
eprintf("[session] sr_sessionid != sa_sessionid\n");
|
||||||
|
print_hexbuf(1, (unsigned char *)"sr_sessionid",
|
||||||
|
seq->sr_resok4.sr_sessionid, NFS4_SESSIONID_SIZE);
|
||||||
|
print_hexbuf(1, (unsigned char *)"sa_sessionid",
|
||||||
|
args->sa_sessionid, NFS4_SESSIONID_SIZE);
|
||||||
|
goto out_free_slot;
|
||||||
|
}
|
||||||
|
if (seq->sr_resok4.sr_status_flags)
|
||||||
|
print_sr_status_flags(1, seq->sr_resok4.sr_status_flags);
|
||||||
|
|
||||||
|
status = nfs41_session_bump_seq(session, args->sa_slotid);
|
||||||
|
if (status)
|
||||||
|
goto out_free_slot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compound->res.status != NFS4_OK)
|
||||||
|
dprintf(1, "\n################ %s ################\n\n",
|
||||||
|
nfs_error_string(compound->res.status));
|
||||||
|
if (compound->res.status != NFS4_OK &&
|
||||||
|
compound->args.argarray[0].op == OP_DESTROY_SESSION) {
|
||||||
|
dprintf(1, "OP_DESTROY_SESSION ignoring errors\n");
|
||||||
|
compound->res.status = NFS4_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (compound->res.status) {
|
||||||
|
case NFS4_OK:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NFS4ERR_STALE_CLIENTID:
|
||||||
|
//try to create a new client
|
||||||
|
status = check_renew_in_progress(session);
|
||||||
|
if (status == ERROR_LOCK_VIOLATION)
|
||||||
|
goto out_free_slot;
|
||||||
|
else if (status == 1)
|
||||||
|
goto do_retry;
|
||||||
|
status = nfs41_client_renew(session->client);
|
||||||
|
if (status) {
|
||||||
|
eprintf("nfs41_exchange_id() failed with %d\n", status);
|
||||||
|
status = ERROR_BAD_NET_RESP;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
//fallthru and reestablish the session
|
||||||
|
case NFS4ERR_BADSESSION:
|
||||||
|
//try to create a new session
|
||||||
|
if (compound->res.status == NFS4ERR_BADSESSION) {
|
||||||
|
status = check_renew_in_progress(session);
|
||||||
|
if (status == ERROR_LOCK_VIOLATION)
|
||||||
|
goto out_free_slot;
|
||||||
|
else if (status == 1)
|
||||||
|
goto do_retry;
|
||||||
|
}
|
||||||
|
status = nfs41_session_renew(session);
|
||||||
|
if (status == NFS4ERR_STALE_CLIENTID) {
|
||||||
|
status = nfs41_client_renew(session->client);
|
||||||
|
if (status) {
|
||||||
|
eprintf("nfs41_exchange_id() failed with %d\n", status);
|
||||||
|
status = ERROR_BAD_NET_RESP;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
status = nfs41_session_renew(session);
|
||||||
|
if (status) {
|
||||||
|
eprintf("after reestablishing clientid: nfs41_session_renew() "
|
||||||
|
"failed with %d\n", status);
|
||||||
|
status = ERROR_BAD_NET_RESP;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
} else if (status && status != NFS4ERR_STALE_CLIENTID) {
|
||||||
|
eprintf("nfs41_session_renew: failed with %d\n", status);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (nfs41_renew_in_progress(session->client, NULL))
|
||||||
|
nfs41_renew_in_progress(session->client, &zero);
|
||||||
|
goto do_retry;
|
||||||
|
|
||||||
|
case NFS4ERR_GRACE:
|
||||||
|
case NFS4ERR_DELAY:
|
||||||
|
#define RETRY_INDEFINITELY
|
||||||
|
#ifndef RETRY_INDEFINITELY
|
||||||
|
#define NUMBER_2_RETRY 19
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef RETRY_INDEFINITELY
|
||||||
|
if (retry_count < NUMBER_2_RETRY) {
|
||||||
|
#endif
|
||||||
|
if (compound->args.argarray[0].op == OP_SEQUENCE) {
|
||||||
|
nfs41_sequence_args *seq = (nfs41_sequence_args*)
|
||||||
|
compound->args.argarray[0].arg;
|
||||||
|
nfs41_session_free_slot(session, seq->sa_slotid);
|
||||||
|
}
|
||||||
|
if (compound->res.status == NFS4ERR_GRACE)
|
||||||
|
delayby = 5000;
|
||||||
|
else
|
||||||
|
delayby = 500*retry_count;
|
||||||
|
dprintf(1, "Compound returned %s: sleeping for %ums..\n",
|
||||||
|
(compound->res.status==NFS4ERR_GRACE)?"NFS4ERR_GRACE":"NFS4ERR_DELAY",
|
||||||
|
delayby);
|
||||||
|
Sleep(delayby);
|
||||||
|
dprintf(1, "Attempting to resend compound.\n");
|
||||||
|
goto do_retry;
|
||||||
|
#ifndef RETRY_INDEFINITELY
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NFS4ERR_FHEXPIRED: /* TODO: recover expired volatile filehandles */
|
||||||
|
status = NFS4ERR_STALE; /* for now, treat them as ERR_STALE */
|
||||||
|
/* no break */
|
||||||
|
case NFS4ERR_STALE:
|
||||||
|
{
|
||||||
|
nfs_argop4 *argarray = compound->args.argarray;
|
||||||
|
struct nfs41_name_cache *name_cache =
|
||||||
|
session_name_cache(session);
|
||||||
|
nfs41_putfh_args *putfh;
|
||||||
|
uint32_t i, start = 0;
|
||||||
|
|
||||||
|
/* NFS4ERR_STALE generally comes from a PUTFH operation. in
|
||||||
|
* this case, remove its filehandle from the name cache. but
|
||||||
|
* because COMPOUNDs are not atomic, a file can be removed
|
||||||
|
* between PUTFH and the operation that uses it. in this
|
||||||
|
* case, we can't tell which PUTFH operation is to blame, so
|
||||||
|
* we must invalidate filehandles of all PUTFH operations in
|
||||||
|
* the COMPOUND */
|
||||||
|
|
||||||
|
if (argarray[compound->res.resarray_count-1].op == OP_PUTFH)
|
||||||
|
start = compound->res.resarray_count-1;
|
||||||
|
|
||||||
|
for (i = start; i < compound->res.resarray_count; i++) {
|
||||||
|
if (argarray[i].op == OP_PUTFH) {
|
||||||
|
putfh = (nfs41_putfh_args*)argarray[i].arg;
|
||||||
|
|
||||||
|
if (!putfh->in_recovery)
|
||||||
|
nfs41_name_cache_remove_stale(name_cache,
|
||||||
|
session, putfh->file->path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
out_free_slot:
|
||||||
|
if (compound->args.argarray[0].op == OP_SEQUENCE) {
|
||||||
|
nfs41_sequence_args *seq = (nfs41_sequence_args *)compound->args.argarray[0].arg;
|
||||||
|
nfs41_session_free_slot(session, seq->sa_slotid);
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
|
||||||
|
do_retry:
|
||||||
|
if (compound->res.resarray[0].op == OP_SEQUENCE) {
|
||||||
|
nfs41_sequence_args *seq = (nfs41_sequence_args*)
|
||||||
|
compound->args.argarray[0].arg;
|
||||||
|
status = nfs41_session_get_slot(session, &seq->sa_slotid,
|
||||||
|
&seq->sa_sequenceid, &seq->sa_highest_slotid);
|
||||||
|
if (status)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
82
daemon/nfs41_compound.h
Normal file
82
daemon/nfs41_compound.h
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __NFS41_DAEMON_COMPOUND_H__
|
||||||
|
#define __NFS41_DAEMON_COMPOUND_H__
|
||||||
|
|
||||||
|
#include "nfs41.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* COMPOUND */
|
||||||
|
typedef struct __nfs_argop4 {
|
||||||
|
uint32_t op;
|
||||||
|
void *arg;
|
||||||
|
} nfs_argop4;
|
||||||
|
|
||||||
|
typedef struct __nfs41_compound_args {
|
||||||
|
uint32_t tag_len;
|
||||||
|
unsigned char tag[NFS4_OPAQUE_LIMIT];
|
||||||
|
uint32_t minorversion;
|
||||||
|
uint32_t argarray_count;
|
||||||
|
nfs_argop4 *argarray; /* <> */
|
||||||
|
} nfs41_compound_args;
|
||||||
|
|
||||||
|
typedef struct __nfs_resop4 {
|
||||||
|
uint32_t op;
|
||||||
|
void *res;
|
||||||
|
} nfs_resop4;
|
||||||
|
|
||||||
|
typedef struct __nfs41_compound_res {
|
||||||
|
uint32_t status;
|
||||||
|
uint32_t tag_len;
|
||||||
|
unsigned char tag[NFS4_OPAQUE_LIMIT];
|
||||||
|
uint32_t resarray_count;
|
||||||
|
nfs_resop4 *resarray; /* <> */
|
||||||
|
} nfs41_compound_res;
|
||||||
|
|
||||||
|
typedef struct __nfs41_compound {
|
||||||
|
nfs41_compound_args args;
|
||||||
|
nfs41_compound_res res;
|
||||||
|
} nfs41_compound;
|
||||||
|
|
||||||
|
|
||||||
|
int compound_error(int status);
|
||||||
|
|
||||||
|
void compound_init(
|
||||||
|
nfs41_compound *compound,
|
||||||
|
nfs_argop4 *argops,
|
||||||
|
nfs_resop4 *resops);
|
||||||
|
|
||||||
|
void compound_add_op(
|
||||||
|
nfs41_compound *compound,
|
||||||
|
uint32_t opnum,
|
||||||
|
void *arg,
|
||||||
|
void *res);
|
||||||
|
|
||||||
|
int compound_encode_send_decode(
|
||||||
|
nfs41_session *session,
|
||||||
|
nfs41_compound *compound,
|
||||||
|
uint32_t bufsize_in,
|
||||||
|
uint32_t bufsize_out);
|
||||||
|
|
||||||
|
#endif /* __NFS41_DAEMON_COMPOUND_H__ */
|
||||||
306
daemon/nfs41_const.h
Normal file
306
daemon/nfs41_const.h
Normal file
|
|
@ -0,0 +1,306 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __NFS41_NFS_CONST_H__
|
||||||
|
#define __NFS41_NFS_CONST_H__
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sizes
|
||||||
|
*/
|
||||||
|
#define NFS4_FHSIZE 128
|
||||||
|
#define NFS4_VERIFIER_SIZE 8
|
||||||
|
#define NFS4_OPAQUE_LIMIT 1024
|
||||||
|
#define NFS4_SESSIONID_SIZE 16
|
||||||
|
|
||||||
|
#define NFS41_MAX_FILEIO_SIZE (1024 * 1024)
|
||||||
|
#define NFS41_MAX_SERVER_CACHE 1024
|
||||||
|
#define NFS41_MAX_RPC_REQS 128
|
||||||
|
|
||||||
|
#define NFS41_MAX_COMPONENT_SIZE 64
|
||||||
|
|
||||||
|
#define UPCALL_BUF_SIZE 1024
|
||||||
|
|
||||||
|
/* see MaximumComponentNameLength in FileFsAttributeInformation
|
||||||
|
* in nfs41_driver.c:nfs41_QueryVolumeInformation() */
|
||||||
|
#define NFS41_MAX_COMPONENT_LEN 64
|
||||||
|
#define NFS41_MAX_PATH_LEN MAX_PATH
|
||||||
|
|
||||||
|
#define NFS41_HOSTNAME_LEN 64
|
||||||
|
#define NFS41_ADDRS_PER_SERVER 4
|
||||||
|
|
||||||
|
/* max length of ipv6 address 48
|
||||||
|
* sizeof(".255.255") + 8 */
|
||||||
|
#define NFS41_UNIVERSAL_ADDR_LEN 56
|
||||||
|
|
||||||
|
/* "udp" "tcp" "udp6" "tcp6" */
|
||||||
|
#define NFS41_NETWORK_ID_LEN 4
|
||||||
|
|
||||||
|
|
||||||
|
/* 424 bytes: max rpc header for reply with data */
|
||||||
|
/* 32 bytes: max COMPOUND response */
|
||||||
|
/* 40 bytes: max SEQUENCE response */
|
||||||
|
/* 4 bytes: max PUTFH response */
|
||||||
|
/* 12 bytes: max READ response */
|
||||||
|
#define READ_OVERHEAD 512
|
||||||
|
|
||||||
|
/* 840 bytes: max rpc header for call */
|
||||||
|
/* 32 bytes: max COMPOUND request */
|
||||||
|
/* 32 bytes: max SEQUENCE request */
|
||||||
|
/* 132 bytes: max PUTFH request */
|
||||||
|
/* 32 bytes: max WRITE request */
|
||||||
|
#define WRITE_OVERHEAD 1068
|
||||||
|
|
||||||
|
|
||||||
|
#define NFS41_RPC_PROGRAM 100003
|
||||||
|
#define NFS41_RPC_VERSION 4
|
||||||
|
#define NFS41_RPC_CBPROGRAM 0x2358
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Error status
|
||||||
|
*/
|
||||||
|
enum nfsstat4 {
|
||||||
|
NFS4_OK = 0, /* everything is okay */
|
||||||
|
NFS4ERR_PERM = 1, /* caller not privileged */
|
||||||
|
NFS4ERR_NOENT = 2, /* no such file/directory */
|
||||||
|
NFS4ERR_IO = 5, /* hard I/O error */
|
||||||
|
NFS4ERR_NXIO = 6, /* no such device */
|
||||||
|
NFS4ERR_ACCESS = 13, /* access denied */
|
||||||
|
NFS4ERR_EXIST = 17, /* file already exists */
|
||||||
|
NFS4ERR_XDEV = 18, /* different filesystems */
|
||||||
|
|
||||||
|
NFS4ERR_NOTDIR = 20, /* should be a directory */
|
||||||
|
NFS4ERR_ISDIR = 21, /* should not be directory */
|
||||||
|
NFS4ERR_INVAL = 22, /* invalid argument */
|
||||||
|
NFS4ERR_FBIG = 27, /* file exceeds server max */
|
||||||
|
NFS4ERR_NOSPC = 28, /* no space on filesystem */
|
||||||
|
NFS4ERR_ROFS = 30, /* read-only filesystem */
|
||||||
|
NFS4ERR_MLINK = 31, /* too many hard links */
|
||||||
|
NFS4ERR_NAMETOOLONG = 63, /* name exceeds server max */
|
||||||
|
NFS4ERR_NOTEMPTY = 66, /* directory not empty */
|
||||||
|
NFS4ERR_DQUOT = 69, /* hard quota limit reached*/
|
||||||
|
NFS4ERR_STALE = 70, /* file no longer exists */
|
||||||
|
NFS4ERR_BADHANDLE = 10001, /* Illegal filehandle */
|
||||||
|
NFS4ERR_BAD_COOKIE = 10003, /* READDIR cookie is stale */
|
||||||
|
NFS4ERR_NOTSUPP = 10004, /* operation not supported */
|
||||||
|
NFS4ERR_TOOSMALL = 10005, /* response limit exceeded */
|
||||||
|
NFS4ERR_SERVERFAULT = 10006, /* undefined server error */
|
||||||
|
NFS4ERR_BADTYPE = 10007, /* type invalid for CREATE */
|
||||||
|
NFS4ERR_DELAY = 10008, /* file "busy" - retry */
|
||||||
|
NFS4ERR_SAME = 10009, /* nverify says attrs same */
|
||||||
|
NFS4ERR_DENIED = 10010, /* lock unavailable */
|
||||||
|
NFS4ERR_EXPIRED = 10011, /* lock lease expired */
|
||||||
|
NFS4ERR_LOCKED = 10012, /* I/O failed due to lock */
|
||||||
|
NFS4ERR_GRACE = 10013, /* in grace period */
|
||||||
|
NFS4ERR_FHEXPIRED = 10014, /* filehandle expired */
|
||||||
|
NFS4ERR_SHARE_DENIED = 10015, /* share reserve denied */
|
||||||
|
NFS4ERR_WRONGSEC = 10016, /* wrong security flavor */
|
||||||
|
NFS4ERR_CLID_INUSE = 10017, /* clientid in use */
|
||||||
|
|
||||||
|
/* NFS4ERR_RESOURCE is not a valid error in NFSv4.1 */
|
||||||
|
NFS4ERR_RESOURCE = 10018, /* resource exhaustion */
|
||||||
|
NFS4ERR_MOVED = 10019, /* filesystem relocated */
|
||||||
|
NFS4ERR_NOFILEHANDLE = 10020, /* current FH is not set */
|
||||||
|
NFS4ERR_MINOR_VERS_MISMATCH = 10021, /* minor vers not supp */
|
||||||
|
NFS4ERR_STALE_CLIENTID = 10022, /* server has rebooted */
|
||||||
|
NFS4ERR_STALE_STATEID = 10023, /* server has rebooted */
|
||||||
|
NFS4ERR_OLD_STATEID = 10024, /* state is out of sync */
|
||||||
|
NFS4ERR_BAD_STATEID = 10025, /* incorrect stateid */
|
||||||
|
NFS4ERR_BAD_SEQID = 10026, /* request is out of seq. */
|
||||||
|
NFS4ERR_NOT_SAME = 10027, /* verify - attrs not same */
|
||||||
|
NFS4ERR_LOCK_RANGE = 10028, /* overlapping lock range */
|
||||||
|
NFS4ERR_SYMLINK = 10029, /* should be file/directory*/
|
||||||
|
NFS4ERR_RESTOREFH = 10030, /* no saved filehandle */
|
||||||
|
NFS4ERR_LEASE_MOVED = 10031, /* some filesystem moved */
|
||||||
|
NFS4ERR_ATTRNOTSUPP = 10032, /* recommended attr not sup*/
|
||||||
|
NFS4ERR_NO_GRACE = 10033, /* reclaim outside of grace*/
|
||||||
|
NFS4ERR_RECLAIM_BAD = 10034, /* reclaim error at server */
|
||||||
|
NFS4ERR_RECLAIM_CONFLICT = 10035, /* conflict on reclaim */
|
||||||
|
NFS4ERR_BADXDR = 10036, /* XDR decode failed */
|
||||||
|
NFS4ERR_LOCKS_HELD = 10037, /* file locks held at CLOSE*/
|
||||||
|
NFS4ERR_OPENMODE = 10038, /* conflict in OPEN and I/O*/
|
||||||
|
NFS4ERR_BADOWNER = 10039, /* owner translation bad */
|
||||||
|
NFS4ERR_BADCHAR = 10040, /* utf-8 char not supported*/
|
||||||
|
NFS4ERR_BADNAME = 10041, /* name not supported */
|
||||||
|
NFS4ERR_BAD_RANGE = 10042, /* lock range not supported*/
|
||||||
|
NFS4ERR_LOCK_NOTSUPP = 10043, /* no atomic up/downgrade */
|
||||||
|
NFS4ERR_OP_ILLEGAL = 10044, /* undefined operation */
|
||||||
|
NFS4ERR_DEADLOCK = 10045, /* file locking deadlock */
|
||||||
|
NFS4ERR_FILE_OPEN = 10046, /* open file blocks op. */
|
||||||
|
NFS4ERR_ADMIN_REVOKED = 10047, /* lockowner state revoked */
|
||||||
|
NFS4ERR_CB_PATH_DOWN = 10048, /* callback path down */
|
||||||
|
|
||||||
|
/* NFSv4.1 errors start here. */
|
||||||
|
NFS4ERR_BADIOMODE = 10049,
|
||||||
|
NFS4ERR_BADLAYOUT = 10050,
|
||||||
|
NFS4ERR_BAD_SESSION_DIGEST = 10051,
|
||||||
|
NFS4ERR_BADSESSION = 10052,
|
||||||
|
NFS4ERR_BADSLOT = 10053,
|
||||||
|
NFS4ERR_COMPLETE_ALREADY = 10054,
|
||||||
|
NFS4ERR_CONN_NOT_BOUND_TO_SESSION = 10055,
|
||||||
|
NFS4ERR_DELEG_ALREADY_WANTED = 10056,
|
||||||
|
NFS4ERR_BACK_CHAN_BUSY = 10057, /*backchan reqs outstanding*/
|
||||||
|
NFS4ERR_LAYOUTTRYLATER = 10058,
|
||||||
|
NFS4ERR_LAYOUTUNAVAILABLE = 10059,
|
||||||
|
NFS4ERR_NOMATCHING_LAYOUT = 10060,
|
||||||
|
NFS4ERR_RECALLCONFLICT = 10061,
|
||||||
|
NFS4ERR_UNKNOWN_LAYOUTTYPE = 10062,
|
||||||
|
NFS4ERR_SEQ_MISORDERED = 10063, /* unexpected seq.ID in req*/
|
||||||
|
NFS4ERR_SEQUENCE_POS = 10064, /* [CB_]SEQ. op not 1st op */
|
||||||
|
NFS4ERR_REQ_TOO_BIG = 10065, /* request too big */
|
||||||
|
NFS4ERR_REP_TOO_BIG = 10066, /* reply too big */
|
||||||
|
NFS4ERR_REP_TOO_BIG_TO_CACHE = 10067, /* rep. not all cached */
|
||||||
|
NFS4ERR_RETRY_UNCACHED_REP = 10068, /* retry & rep. uncached */
|
||||||
|
NFS4ERR_UNSAFE_COMPOUND = 10069, /* retry/recovery too hard */
|
||||||
|
NFS4ERR_TOO_MANY_OPS = 10070, /*too many ops in [CB_]COMP*/
|
||||||
|
NFS4ERR_OP_NOT_IN_SESSION = 10071, /* op needs [CB_]SEQ. op */
|
||||||
|
NFS4ERR_HASH_ALG_UNSUPP = 10072, /* hash alg. not supp. */
|
||||||
|
/* Error 10073 is unused. */
|
||||||
|
NFS4ERR_CLIENTID_BUSY = 10074, /* clientid has state */
|
||||||
|
NFS4ERR_PNFS_IO_HOLE = 10075, /* IO to _SPARSE file hole */
|
||||||
|
NFS4ERR_SEQ_FALSE_RETRY = 10076, /* Retry != original req. */
|
||||||
|
NFS4ERR_BAD_HIGH_SLOT = 10077, /* req has bad highest_slot*/
|
||||||
|
NFS4ERR_DEADSESSION = 10078, /*new req sent to dead sess*/
|
||||||
|
NFS4ERR_ENCR_ALG_UNSUPP = 10079, /* encr alg. not supp. */
|
||||||
|
NFS4ERR_PNFS_NO_LAYOUT = 10080, /* I/O without a layout */
|
||||||
|
NFS4ERR_NOT_ONLY_OP = 10081, /* addl ops not allowed */
|
||||||
|
NFS4ERR_WRONG_CRED = 10082, /* op done by wrong cred */
|
||||||
|
NFS4ERR_WRONG_TYPE = 10083, /* op on wrong type object */
|
||||||
|
NFS4ERR_DIRDELEG_UNAVAIL = 10084, /* delegation not avail. */
|
||||||
|
NFS4ERR_REJECT_DELEG = 10085, /* cb rejected delegation */
|
||||||
|
NFS4ERR_RETURNCONFLICT = 10086, /* layout get before return*/
|
||||||
|
NFS4ERR_DELEG_REVOKED = 10087 /* deleg./layout revoked */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MAKE_WORD0(XXX) (1 << XXX)
|
||||||
|
#define MAKE_WORD1(XXX) (1 << (XXX-32))
|
||||||
|
#define MAKE_WORD2(XXX) (1 << (XXX-64))
|
||||||
|
|
||||||
|
enum {
|
||||||
|
/*
|
||||||
|
* Mandatory Attributes
|
||||||
|
*/
|
||||||
|
FATTR4_WORD0_SUPPORTED_ATTRS = MAKE_WORD0(0),
|
||||||
|
FATTR4_WORD0_TYPE = MAKE_WORD0(1),
|
||||||
|
FATTR4_WORD0_FH_EXPIRE_TYPE = MAKE_WORD0(2),
|
||||||
|
FATTR4_WORD0_CHANGE = MAKE_WORD0(3),
|
||||||
|
FATTR4_WORD0_SIZE = MAKE_WORD0(4),
|
||||||
|
FATTR4_WORD0_LINK_SUPPORT = MAKE_WORD0(5),
|
||||||
|
FATTR4_WORD0_SYMLINK_SUPPORT = MAKE_WORD0(6),
|
||||||
|
FATTR4_WORD0_NAMED_ATTR = MAKE_WORD0(7),
|
||||||
|
FATTR4_WORD0_FSID = MAKE_WORD0(8),
|
||||||
|
FATTR4_WORD0_UNIQUE_HANDLES = MAKE_WORD0(9),
|
||||||
|
FATTR4_WORD0_LEASE_TIME = MAKE_WORD0(10),
|
||||||
|
FATTR4_WORD0_RDATTR_ERROR = MAKE_WORD0(11),
|
||||||
|
FATTR4_WORD0_FILEHANDLE = MAKE_WORD0(19),
|
||||||
|
FATTR4_WORD2_SUPPATTR_EXCLCREAT = MAKE_WORD2(75),
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Recommended Attributes
|
||||||
|
*/
|
||||||
|
FATTR4_WORD0_ACL = MAKE_WORD0(12),
|
||||||
|
FATTR4_WORD0_ACLSUPPORT = MAKE_WORD0(13),
|
||||||
|
FATTR4_WORD0_ARCHIVE = MAKE_WORD0(14),
|
||||||
|
FATTR4_WORD0_CANSETTIME = MAKE_WORD0(15),
|
||||||
|
FATTR4_WORD0_CASE_INSENSITIVE = MAKE_WORD0(16),
|
||||||
|
FATTR4_WORD0_CASE_PRESERVING = MAKE_WORD0(17),
|
||||||
|
FATTR4_WORD0_CHOWN_RESTRICTED = MAKE_WORD0(18),
|
||||||
|
FATTR4_WORD0_FILEID = MAKE_WORD0(20),
|
||||||
|
FATTR4_WORD0_FILES_AVAIL = MAKE_WORD0(21),
|
||||||
|
FATTR4_WORD0_FILES_FREE = MAKE_WORD0(22),
|
||||||
|
FATTR4_WORD0_FILES_TOTAL = MAKE_WORD0(23),
|
||||||
|
FATTR4_WORD0_FS_LOCATIONS = MAKE_WORD0(24),
|
||||||
|
FATTR4_WORD0_HIDDEN = MAKE_WORD0(25),
|
||||||
|
FATTR4_WORD0_HOMOGENEOUS = MAKE_WORD0(26),
|
||||||
|
FATTR4_WORD0_MAXFILESIZE = MAKE_WORD0(27),
|
||||||
|
FATTR4_WORD0_MAXLINK = MAKE_WORD0(28),
|
||||||
|
FATTR4_WORD0_MAXNAME = MAKE_WORD0(29),
|
||||||
|
FATTR4_WORD0_MAXREAD = MAKE_WORD0(30),
|
||||||
|
FATTR4_WORD0_MAXWRITE = MAKE_WORD0(31),
|
||||||
|
FATTR4_WORD1_MIMETYPE = MAKE_WORD1(32),
|
||||||
|
FATTR4_WORD1_MODE = MAKE_WORD1(33),
|
||||||
|
FATTR4_WORD1_NO_TRUNC = MAKE_WORD1(34),
|
||||||
|
FATTR4_WORD1_NUMLINKS = MAKE_WORD1(35),
|
||||||
|
FATTR4_WORD1_OWNER = MAKE_WORD1(36),
|
||||||
|
FATTR4_WORD1_OWNER_GROUP = MAKE_WORD1(37),
|
||||||
|
FATTR4_WORD1_QUOTA_AVAIL_HARD = MAKE_WORD1(38),
|
||||||
|
FATTR4_WORD1_QUOTA_AVAIL_SOFT = MAKE_WORD1(39),
|
||||||
|
FATTR4_WORD1_QUOTA_USED = MAKE_WORD1(40),
|
||||||
|
FATTR4_WORD1_RAWDEV = MAKE_WORD1(41),
|
||||||
|
FATTR4_WORD1_SPACE_AVAIL = MAKE_WORD1(42),
|
||||||
|
FATTR4_WORD1_SPACE_FREE = MAKE_WORD1(43),
|
||||||
|
FATTR4_WORD1_SPACE_TOTAL = MAKE_WORD1(44),
|
||||||
|
FATTR4_WORD1_SPACE_USED = MAKE_WORD1(45),
|
||||||
|
FATTR4_WORD1_SYSTEM = MAKE_WORD1(46),
|
||||||
|
FATTR4_WORD1_TIME_ACCESS = MAKE_WORD1(47),
|
||||||
|
FATTR4_WORD1_TIME_ACCESS_SET = MAKE_WORD1(48),
|
||||||
|
FATTR4_WORD1_TIME_BACKUP = MAKE_WORD1(49),
|
||||||
|
FATTR4_WORD1_TIME_CREATE = MAKE_WORD1(50),
|
||||||
|
FATTR4_WORD1_TIME_DELTA = MAKE_WORD1(51),
|
||||||
|
FATTR4_WORD1_TIME_METADATA = MAKE_WORD1(52),
|
||||||
|
FATTR4_WORD1_TIME_MODIFY = MAKE_WORD1(53),
|
||||||
|
FATTR4_WORD1_TIME_MODIFY_SET = MAKE_WORD1(54),
|
||||||
|
FATTR4_WORD1_MOUNTED_ON_FILEID = MAKE_WORD1(55),
|
||||||
|
FATTR4_WORD1_DIR_NOTIF_DELAY = MAKE_WORD1(56),
|
||||||
|
FATTR4_WORD1_DIRENT_NOTIF_DELAY = MAKE_WORD1(57),
|
||||||
|
FATTR4_WORD1_DACL = MAKE_WORD1(58),
|
||||||
|
FATTR4_WORD1_SACL = MAKE_WORD1(59),
|
||||||
|
FATTR4_WORD1_CHANGE_POLICY = MAKE_WORD1(60),
|
||||||
|
FATTR4_WORD1_FS_STATUS = MAKE_WORD1(61),
|
||||||
|
FATTR4_WORD1_FS_LAYOUT_TYPE = MAKE_WORD1(62),
|
||||||
|
FATTR4_WORD1_LAYOUT_HINT = MAKE_WORD1(63),
|
||||||
|
FATTR4_WORD2_LAYOUT_TYPE = MAKE_WORD2(64),
|
||||||
|
FATTR4_WORD2_LAYOUT_BLKSIZE = MAKE_WORD2(65),
|
||||||
|
FATTR4_WORD2_LAYOUT_ALIGNMENT = MAKE_WORD2(66),
|
||||||
|
FATTR4_WORD2_FS_LOCATIONS_INFO = MAKE_WORD2(67),
|
||||||
|
FATTR4_WORD2_MDSTHRESHOLD = MAKE_WORD2(68),
|
||||||
|
FATTR4_WORD2_RETENTION_GET = MAKE_WORD2(69),
|
||||||
|
FATTR4_WORD2_RETENTION_SET = MAKE_WORD2(70),
|
||||||
|
FATTR4_WORD2_RETENTEVT_GET = MAKE_WORD2(71),
|
||||||
|
FATTR4_WORD2_RETENTEVT_SET = MAKE_WORD2(72),
|
||||||
|
FATTR4_WORD2_RETENTION_HOLD = MAKE_WORD2(73),
|
||||||
|
FATTR4_WORD2_MODE_SET_MASKED = MAKE_WORD2(74),
|
||||||
|
FATTR4_WORD2_FS_CHARSET_CAP = MAKE_WORD2(76),
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* File types
|
||||||
|
*/
|
||||||
|
enum nfs_ftype4 {
|
||||||
|
NF4REG = 1, /* Regular File */
|
||||||
|
NF4DIR = 2, /* Directory */
|
||||||
|
NF4BLK = 3, /* Special File - block device */
|
||||||
|
NF4CHR = 4, /* Special File - character device */
|
||||||
|
NF4LNK = 5, /* Symbolic Link */
|
||||||
|
NF4SOCK = 6, /* Special File - socket */
|
||||||
|
NF4FIFO = 7, /* Special File - fifo */
|
||||||
|
NF4ATTRDIR = 8, /* Attribute Directory */
|
||||||
|
NF4NAMEDATTR = 9, /* Named Attribute */
|
||||||
|
|
||||||
|
NFS_FTYPE_MASK = 0xF
|
||||||
|
};
|
||||||
|
|
||||||
|
#define CREATE_SESSION4_FLAG_CONN_BACK_CHAN 0x00000002;
|
||||||
|
|
||||||
|
#endif /* !__NFS41_NFS_CONST_H__ */
|
||||||
217
daemon/nfs41_daemon.c
Normal file
217
daemon/nfs41_daemon.c
Normal file
|
|
@ -0,0 +1,217 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <process.h>
|
||||||
|
#include <tchar.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <devioctl.h>
|
||||||
|
|
||||||
|
#include "nfs41_driver.h" /* for NFS41_USER_DEVICE_NAME_A */
|
||||||
|
#include "nfs41_np.h" /* for NFS41NP_SHARED_MEMORY */
|
||||||
|
|
||||||
|
#include "daemon_debug.h"
|
||||||
|
#include "upcall.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define MAX_NUM_THREADS 128
|
||||||
|
BOOLEAN CREATED_SESSION = FALSE;
|
||||||
|
|
||||||
|
typedef struct _nfs41_process_thread {
|
||||||
|
HANDLE handle;
|
||||||
|
uint32_t tid;
|
||||||
|
} nfs41_process_thread;
|
||||||
|
|
||||||
|
DWORD InitSharedMemory(
|
||||||
|
OUT PHANDLE phMutex)
|
||||||
|
{
|
||||||
|
DWORD status = NO_ERROR;
|
||||||
|
|
||||||
|
*phMutex = CreateMutex(NULL, FALSE, TEXT(NFS41NP_MUTEX_NAME));
|
||||||
|
if (*phMutex == NULL) {
|
||||||
|
status = GetLastError();
|
||||||
|
eprintf("CreateMutex failed with %d\n", status);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int WINAPI thread_main(void *args)
|
||||||
|
{
|
||||||
|
DWORD status = 0;
|
||||||
|
HANDLE pipe;
|
||||||
|
// buffer used to process upcall, assumed to be fixed size.
|
||||||
|
// if we ever need to handle non-cached IO, need to make it dynamic
|
||||||
|
unsigned char outbuf[UPCALL_BUF_SIZE];
|
||||||
|
// buffer used to send downcall content, need to dynamically allocated
|
||||||
|
// as we don't know the length of the buffer (ie. size of directory listing
|
||||||
|
unsigned char *inbuf = NULL;
|
||||||
|
DWORD inbuf_len, outbuf_len;
|
||||||
|
nfs41_upcall upcall;
|
||||||
|
|
||||||
|
pipe = CreateFile(NFS41_USER_DEVICE_NAME_A, GENERIC_READ | GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
|
||||||
|
0, NULL);
|
||||||
|
if (pipe == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
eprintf("Unable to open upcall pipe %d\n", GetLastError());
|
||||||
|
return GetLastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
status = DeviceIoControl(pipe, IOCTL_NFS41_READ, NULL, 0,
|
||||||
|
outbuf, UPCALL_BUF_SIZE, (LPDWORD)&outbuf_len, NULL);
|
||||||
|
if (!status) {
|
||||||
|
eprintf("IOCTL_NFS41_READ failed %d\n", GetLastError());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = upcall_parse(outbuf, (uint32_t)outbuf_len, &upcall);
|
||||||
|
if (status)
|
||||||
|
goto write_downcall;
|
||||||
|
|
||||||
|
#if 1 //AGLO: this is just a placeholder for a real solution. I know this variable needs a lock in a
|
||||||
|
//normal case. However, this does not prevent us from receiving an upcall for an old mount
|
||||||
|
//that was not reestablished. It will only work for erroring requests until the 1st mount upcall.
|
||||||
|
if (!CREATED_SESSION && (upcall.opcode != NFS41_MOUNT && upcall.opcode != NFS41_SHUTDOWN)) {
|
||||||
|
eprintf("nfs41_daemon restarted and does not have a valid session established\n");
|
||||||
|
upcall.status = 116;
|
||||||
|
goto write_downcall;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (upcall.opcode == NFS41_SHUTDOWN) {
|
||||||
|
printf("Shutting down..\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
status = upcall_handle(&upcall);
|
||||||
|
|
||||||
|
#if 1 //AGLO: place holder for a real solution
|
||||||
|
if (upcall.opcode == NFS41_MOUNT && upcall.status == NO_ERROR)
|
||||||
|
CREATED_SESSION = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
write_downcall:
|
||||||
|
dprintf(1, "writing downcall: xid=%d opcode=%s status=%d "
|
||||||
|
"get_last_error=%d\n", upcall.xid, opcode2string(upcall.opcode),
|
||||||
|
upcall.status, upcall.last_error);
|
||||||
|
|
||||||
|
if (upcall.opcode == NFS41_DIR_QUERY)
|
||||||
|
inbuf_len = UPCALL_BUF_SIZE + upcall.args.readdir.query_reply_len;
|
||||||
|
else
|
||||||
|
inbuf_len = UPCALL_BUF_SIZE;
|
||||||
|
|
||||||
|
inbuf = malloc(inbuf_len);
|
||||||
|
status = upcall_marshall(&upcall, inbuf, (uint32_t)inbuf_len, (uint32_t*)&outbuf_len);
|
||||||
|
|
||||||
|
dprintf(2, "making a downcall: outbuf_len %ld\n", outbuf_len);
|
||||||
|
status = DeviceIoControl(pipe, IOCTL_NFS41_WRITE,
|
||||||
|
inbuf, inbuf_len, NULL, 0, (LPDWORD)&outbuf_len, NULL);
|
||||||
|
free(inbuf);
|
||||||
|
if (!status) {
|
||||||
|
eprintf("IOCTL_NFS41_WRITE failed with %d xid=%d opcode=%s\n",
|
||||||
|
GetLastError(), upcall.xid, opcode2string(upcall.opcode));
|
||||||
|
status = upcall_cancel(&upcall);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
dprintf(3, "downcall returned %d\n", status);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
CloseHandle(pipe);
|
||||||
|
|
||||||
|
return GetLastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
void __cdecl _tmain(int argc, TCHAR *argv[])
|
||||||
|
{
|
||||||
|
DWORD status = 0, len;
|
||||||
|
// handles related to shared memory
|
||||||
|
HANDLE hSharedMemoryMutex;
|
||||||
|
// handle to our drivers
|
||||||
|
HANDLE pipe;
|
||||||
|
nfs41_process_thread tids[MAX_NUM_THREADS];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (argc > 2) {
|
||||||
|
const char *process = strip_path(argv[0], NULL);
|
||||||
|
printf("Usage: %s [#debug level]\n", process);
|
||||||
|
} else if (argc == 2) {
|
||||||
|
set_debug_level(_ttoi(argv[1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
/* dump memory leaks to stderr on exit; this requires the debug heap,
|
||||||
|
/* available only when built in debug mode under visual studio -cbodley */
|
||||||
|
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
|
||||||
|
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
|
||||||
|
_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
|
||||||
|
dprintf(1, "debug mode. dumping memory leaks to stderr on exit.\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
nfs41_server_list_init();
|
||||||
|
|
||||||
|
pipe = CreateFile(NFS41_USER_DEVICE_NAME_A, GENERIC_READ | GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
|
||||||
|
0, NULL);
|
||||||
|
if (pipe == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
eprintf("Unable to open upcall pipe %d\n", GetLastError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = InitSharedMemory(&hSharedMemoryMutex);
|
||||||
|
if (status)
|
||||||
|
goto quit_pipe;
|
||||||
|
|
||||||
|
dprintf(1, "starting nfs41 mini redirector\n");
|
||||||
|
status = DeviceIoControl(pipe, IOCTL_NFS41_START,
|
||||||
|
NULL, 0, NULL, 0, (LPDWORD)&len, NULL);
|
||||||
|
if (!status) {
|
||||||
|
eprintf("IOCTL_NFS41_START failed with %d\n",
|
||||||
|
GetLastError());
|
||||||
|
goto quit;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_NUM_THREADS; i++) {
|
||||||
|
tids[i].handle = (HANDLE)_beginthreadex(NULL, 0, thread_main,
|
||||||
|
NULL, 0, &tids[i].tid);
|
||||||
|
if (tids[i].handle == INVALID_HANDLE_VALUE) {
|
||||||
|
status = GetLastError();
|
||||||
|
eprintf("_beginthreadex failed %d\n", status);
|
||||||
|
goto quit_pipe;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//This can be changed to waiting on an array of handles and using waitformultipleobjects
|
||||||
|
dprintf(1, "Parent waiting for children threads\n");
|
||||||
|
for (i = 0; i < MAX_NUM_THREADS; i++)
|
||||||
|
WaitForSingleObject(tids[i].handle, INFINITE );
|
||||||
|
dprintf(1, "Parent woke up!!!!\n");
|
||||||
|
|
||||||
|
quit:
|
||||||
|
CloseHandle(hSharedMemoryMutex);
|
||||||
|
quit_pipe:
|
||||||
|
CloseHandle(pipe);
|
||||||
|
return;
|
||||||
|
}
|
||||||
1745
daemon/nfs41_ops.c
Normal file
1745
daemon/nfs41_ops.c
Normal file
File diff suppressed because it is too large
Load diff
1074
daemon/nfs41_ops.h
Normal file
1074
daemon/nfs41_ops.h
Normal file
File diff suppressed because it is too large
Load diff
298
daemon/nfs41_rpc.c
Normal file
298
daemon/nfs41_rpc.c
Normal file
|
|
@ -0,0 +1,298 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "nfs41.h"
|
||||||
|
#include "daemon_debug.h"
|
||||||
|
#include "nfs41_xdr.h"
|
||||||
|
#include "nfs41_callback.h"
|
||||||
|
|
||||||
|
#include "rpc/rpc.h"
|
||||||
|
|
||||||
|
static enum clnt_stat send_null(CLIENT *client)
|
||||||
|
{
|
||||||
|
struct timeval timeout = {10, 0};
|
||||||
|
|
||||||
|
return clnt_call(client, 0,
|
||||||
|
(xdrproc_t)xdr_void, NULL,
|
||||||
|
(xdrproc_t)xdr_void, NULL, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_client_for_netaddr(
|
||||||
|
IN const netaddr4 *netaddr,
|
||||||
|
IN uint32_t wsize,
|
||||||
|
IN uint32_t rsize,
|
||||||
|
IN nfs41_rpc_clnt *rpc,
|
||||||
|
OUT CLIENT **client_out)
|
||||||
|
{
|
||||||
|
int status = ERROR_NETWORK_UNREACHABLE;
|
||||||
|
struct netconfig *nconf;
|
||||||
|
struct netbuf *addr;
|
||||||
|
CLIENT *client;
|
||||||
|
|
||||||
|
nconf = getnetconfigent(netaddr->netid);
|
||||||
|
if (nconf == NULL)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
addr = uaddr2taddr(nconf, netaddr->uaddr);
|
||||||
|
if (addr == NULL)
|
||||||
|
goto out_free_conf;
|
||||||
|
|
||||||
|
dprintf(1, "callback function %p args %p\n", nfs41_handle_callback, rpc);
|
||||||
|
client = clnt_tli_create(RPC_ANYFD, nconf, addr,
|
||||||
|
NFS41_RPC_PROGRAM, NFS41_RPC_VERSION, wsize, rsize,
|
||||||
|
rpc?proc_cb_compound_res:NULL, rpc?nfs41_handle_callback:NULL, rpc?rpc:NULL);
|
||||||
|
if (client) {
|
||||||
|
*client_out = client;
|
||||||
|
status = NO_ERROR;
|
||||||
|
goto out_free_addr;
|
||||||
|
}
|
||||||
|
out_free_addr:
|
||||||
|
freenetbuf(addr);
|
||||||
|
out_free_conf:
|
||||||
|
freenetconfigent(nconf);
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_client_for_multi_addr(
|
||||||
|
IN const multi_addr4 *addrs,
|
||||||
|
IN uint32_t wsize,
|
||||||
|
IN uint32_t rsize,
|
||||||
|
IN nfs41_rpc_clnt *rpc,
|
||||||
|
OUT CLIENT **client_out,
|
||||||
|
OUT uint32_t *addr_index)
|
||||||
|
{
|
||||||
|
int status = ERROR_NETWORK_UNREACHABLE;
|
||||||
|
uint32_t i;
|
||||||
|
for (i = 0; i < addrs->count; i++) {
|
||||||
|
status = get_client_for_netaddr(&addrs->arr[i],
|
||||||
|
wsize, rsize, rpc, client_out);
|
||||||
|
if (status == NO_ERROR) {
|
||||||
|
*addr_index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns a client structure and an associated lock */
|
||||||
|
int nfs41_rpc_clnt_create(
|
||||||
|
IN const multi_addr4 *addrs,
|
||||||
|
IN uint32_t wsize,
|
||||||
|
IN uint32_t rsize,
|
||||||
|
bool_t needcb,
|
||||||
|
OUT nfs41_rpc_clnt **rpc_out)
|
||||||
|
{
|
||||||
|
CLIENT *client;
|
||||||
|
nfs41_rpc_clnt *rpc;
|
||||||
|
uint32_t addr_index;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
rpc = calloc(1, sizeof(nfs41_rpc_clnt));
|
||||||
|
if (rpc == NULL) {
|
||||||
|
status = GetLastError();
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
rpc->cond = CreateEvent(NULL, TRUE, FALSE, "rpc_recovery_cond");
|
||||||
|
if (rpc->cond == NULL) {
|
||||||
|
status = GetLastError();
|
||||||
|
fprintf(stderr, "CreateEvent failed %d\n", status);
|
||||||
|
goto out_free_rpc_clnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = get_client_for_multi_addr(addrs,
|
||||||
|
wsize, rsize, needcb?rpc:NULL, &client, &addr_index);
|
||||||
|
if (status) {
|
||||||
|
clnt_pcreateerror("connecting failed");
|
||||||
|
goto out_free_rpc_clnt;
|
||||||
|
}
|
||||||
|
// XXX Pick credentials in better manner
|
||||||
|
client->cl_auth = authsys_create_default();
|
||||||
|
if (client->cl_auth == NULL) {
|
||||||
|
// XXX log failure in auth creation somewhere
|
||||||
|
// XXX Better error return
|
||||||
|
status = ERROR_NETWORK_UNREACHABLE;
|
||||||
|
goto out_err_client;
|
||||||
|
}
|
||||||
|
if (send_null(client) != RPC_SUCCESS) {
|
||||||
|
// XXX Do what here?
|
||||||
|
dprintf(1, " send_null failed\n");
|
||||||
|
status = ERROR_NETWORK_UNREACHABLE;
|
||||||
|
goto out_err_auth;
|
||||||
|
}
|
||||||
|
|
||||||
|
rpc->rpc = client;
|
||||||
|
|
||||||
|
/* keep a copy of the address and buffer sizes for reconnect */
|
||||||
|
memcpy(&rpc->addrs, addrs, sizeof(multi_addr4));
|
||||||
|
/* save the index of the address we connected to */
|
||||||
|
rpc->addr_index = addr_index;
|
||||||
|
rpc->wsize = wsize;
|
||||||
|
rpc->rsize = rsize;
|
||||||
|
rpc->is_valid_session = TRUE;
|
||||||
|
|
||||||
|
//initialize rpc client lock
|
||||||
|
InitializeSRWLock(&rpc->lock);
|
||||||
|
|
||||||
|
*rpc_out = rpc;
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
out_err_auth:
|
||||||
|
auth_destroy(client->cl_auth);
|
||||||
|
out_err_client:
|
||||||
|
CloseHandle(rpc->cond);
|
||||||
|
clnt_destroy(client);
|
||||||
|
out_free_rpc_clnt:
|
||||||
|
free(rpc);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Frees resources allocated in clnt_create */
|
||||||
|
void nfs41_rpc_clnt_free(
|
||||||
|
IN nfs41_rpc_clnt *rpc)
|
||||||
|
{
|
||||||
|
auth_destroy(rpc->rpc->cl_auth);
|
||||||
|
clnt_destroy(rpc->rpc);
|
||||||
|
CloseHandle(rpc->cond);
|
||||||
|
free(rpc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t rpc_renew_in_progress(nfs41_rpc_clnt *rpc, int *value)
|
||||||
|
{
|
||||||
|
bool_t status = FALSE;
|
||||||
|
AcquireSRWLockExclusive(&rpc->lock);
|
||||||
|
if (value) {
|
||||||
|
dprintf(1, "nfs41_rpc_renew_in_progress: setting value %d\n", *value);
|
||||||
|
rpc->in_recovery = *value;
|
||||||
|
if (!rpc->in_recovery)
|
||||||
|
SetEvent(rpc->cond);
|
||||||
|
} else {
|
||||||
|
status = rpc->in_recovery;
|
||||||
|
dprintf(1, "nfs41_rpc_renew_in_progress: returning value %d\n", status);
|
||||||
|
}
|
||||||
|
ReleaseSRWLockExclusive(&rpc->lock);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t rpc_should_retry(nfs41_rpc_clnt *rpc, uint32_t version)
|
||||||
|
{
|
||||||
|
bool_t status = 0;
|
||||||
|
AcquireSRWLockExclusive(&rpc->lock);
|
||||||
|
if (rpc->version > version)
|
||||||
|
status = 1;
|
||||||
|
ReleaseSRWLockExclusive(&rpc->lock);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rpc_reconnect(
|
||||||
|
IN nfs41_rpc_clnt *rpc)
|
||||||
|
{
|
||||||
|
CLIENT *client = NULL;
|
||||||
|
uint32_t addr_index;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
AcquireSRWLockExclusive(&rpc->lock);
|
||||||
|
|
||||||
|
status = get_client_for_multi_addr(&rpc->addrs,
|
||||||
|
rpc->wsize, rpc->rsize, rpc, &client, &addr_index);
|
||||||
|
if (status)
|
||||||
|
goto out_unlock;
|
||||||
|
|
||||||
|
client->cl_auth = rpc->rpc->cl_auth;
|
||||||
|
if (send_null(client) != RPC_SUCCESS)
|
||||||
|
goto out_err_client;
|
||||||
|
|
||||||
|
clnt_destroy(rpc->rpc);
|
||||||
|
rpc->rpc = client;
|
||||||
|
rpc->addr_index = addr_index;
|
||||||
|
rpc->version++;
|
||||||
|
dprintf(1, "nfs41_send_compound: reestablished RPC connection\n");
|
||||||
|
|
||||||
|
out_unlock:
|
||||||
|
ReleaseSRWLockExclusive(&rpc->lock);
|
||||||
|
return status;
|
||||||
|
|
||||||
|
out_err_client:
|
||||||
|
clnt_destroy(client);
|
||||||
|
goto out_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nfs41_send_compound(
|
||||||
|
IN nfs41_rpc_clnt *rpc,
|
||||||
|
IN char *inbuf,
|
||||||
|
OUT char *outbuf)
|
||||||
|
{
|
||||||
|
struct timeval timeout = {10, 0};
|
||||||
|
enum clnt_stat rpc_status;
|
||||||
|
int status, count = 0, one = 1, zero = 0;
|
||||||
|
uint32_t version;
|
||||||
|
|
||||||
|
try_again:
|
||||||
|
AcquireSRWLockShared(&rpc->lock);
|
||||||
|
version = rpc->version;
|
||||||
|
rpc_status = clnt_call(rpc->rpc, 1,
|
||||||
|
(xdrproc_t)nfs_encode_compound, inbuf,
|
||||||
|
(xdrproc_t)nfs_decode_compound, outbuf,
|
||||||
|
timeout);
|
||||||
|
ReleaseSRWLockShared(&rpc->lock);
|
||||||
|
|
||||||
|
if (rpc_status != RPC_SUCCESS) {
|
||||||
|
eprintf("clnt_call returned rpc_status=%i\n", rpc_status);
|
||||||
|
switch(rpc_status) {
|
||||||
|
case RPC_CANTRECV:
|
||||||
|
case RPC_CANTSEND:
|
||||||
|
case RPC_TIMEDOUT:
|
||||||
|
if (!rpc->is_valid_session && ++count > 3) {
|
||||||
|
status = ERROR_NETWORK_UNREACHABLE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (rpc_should_retry(rpc, version))
|
||||||
|
goto try_again;
|
||||||
|
while (rpc_renew_in_progress(rpc, NULL)) {
|
||||||
|
status = WaitForSingleObject(rpc->cond, INFINITE);
|
||||||
|
if (status != WAIT_OBJECT_0) {
|
||||||
|
dprintf(1, "nfs41_rpc_renew_in_progress: WaitForSingleObject failed\n");
|
||||||
|
print_condwait_status(1, status);
|
||||||
|
status = ERROR_LOCK_VIOLATION;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
rpc_renew_in_progress(rpc, &zero);
|
||||||
|
goto try_again;
|
||||||
|
}
|
||||||
|
rpc_renew_in_progress(rpc, &one);
|
||||||
|
if (rpc_reconnect(rpc))
|
||||||
|
eprintf("Failed to reconnect!\n");
|
||||||
|
rpc_renew_in_progress(rpc, &zero);
|
||||||
|
goto try_again;
|
||||||
|
default:
|
||||||
|
eprintf("UNHANDLED RPC_ERROR: %d\n", rpc_status);
|
||||||
|
status = ERROR_NETWORK_UNREACHABLE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = 0;
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
332
daemon/nfs41_server.c
Normal file
332
daemon/nfs41_server.c
Normal file
|
|
@ -0,0 +1,332 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <strsafe.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "wintirpc.h"
|
||||||
|
#include "rpc/rpc.h"
|
||||||
|
|
||||||
|
#include "name_cache.h"
|
||||||
|
#include "daemon_debug.h"
|
||||||
|
#include "nfs41.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define SRVLVL 2 /* dprintf level for server logging */
|
||||||
|
|
||||||
|
|
||||||
|
/* nfs41_server_list */
|
||||||
|
struct server_list {
|
||||||
|
struct list_entry head;
|
||||||
|
CRITICAL_SECTION lock;
|
||||||
|
};
|
||||||
|
static struct server_list g_server_list;
|
||||||
|
|
||||||
|
#define server_entry(pos) list_container(pos, nfs41_server, entry)
|
||||||
|
|
||||||
|
|
||||||
|
void nfs41_server_list_init()
|
||||||
|
{
|
||||||
|
list_init(&g_server_list.head);
|
||||||
|
InitializeCriticalSection(&g_server_list.lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* http://tools.ietf.org/html/rfc5661#section-1.6
|
||||||
|
* 1.6. General Definitions: Server Owner:
|
||||||
|
* "When the client has two connections each to a peer with the same major
|
||||||
|
* identifier, the client assumes that both peers are the same server (the
|
||||||
|
* server namespace is the same via each connection)" */
|
||||||
|
|
||||||
|
/* http://tools.ietf.org/html/rfc5661#section-2.10.4
|
||||||
|
* 2.10.4. Server Scope
|
||||||
|
* "When the server scope values are the same, server owner value may be
|
||||||
|
* validly compared. In cases where the server scope values are different,
|
||||||
|
* server owner values are treated as different even if they contain all
|
||||||
|
* identical bytes." */
|
||||||
|
|
||||||
|
/* given these definitions, we require that both the server_owner.major_id
|
||||||
|
* and server_scope are identical when matching instances of nfs41_server */
|
||||||
|
|
||||||
|
struct server_info {
|
||||||
|
const char *scope;
|
||||||
|
const char *owner;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int server_compare(
|
||||||
|
const struct list_entry *entry,
|
||||||
|
const void *value)
|
||||||
|
{
|
||||||
|
const nfs41_server *server = server_entry(entry);
|
||||||
|
const struct server_info *info = (const struct server_info*)value;
|
||||||
|
const int diff = strncmp(server->scope, info->scope, NFS4_OPAQUE_LIMIT);
|
||||||
|
return diff ? diff : strncmp(server->owner, info->owner, NFS4_OPAQUE_LIMIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int server_entry_find(
|
||||||
|
IN struct server_list *servers,
|
||||||
|
IN const struct server_info *info,
|
||||||
|
OUT struct list_entry **entry_out)
|
||||||
|
{
|
||||||
|
*entry_out = list_search(&servers->head, info, server_compare);
|
||||||
|
return *entry_out ? NO_ERROR : ERROR_FILE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int server_create(
|
||||||
|
IN const struct server_info *info,
|
||||||
|
OUT nfs41_server **server_out)
|
||||||
|
{
|
||||||
|
int status = NO_ERROR;
|
||||||
|
nfs41_server *server;
|
||||||
|
|
||||||
|
server = calloc(1, sizeof(nfs41_server));
|
||||||
|
if (server == NULL) {
|
||||||
|
status = GetLastError();
|
||||||
|
eprintf("failed to allocate server %s\n", info->owner);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringCchCopyA(server->scope, NFS4_OPAQUE_LIMIT, info->scope);
|
||||||
|
StringCchCopyA(server->owner, NFS4_OPAQUE_LIMIT, info->owner);
|
||||||
|
InitializeSRWLock(&server->addrs.lock);
|
||||||
|
nfs41_superblock_list_init(&server->superblocks);
|
||||||
|
nfs41_name_cache_create(&server->name_cache);
|
||||||
|
*server_out = server;
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void server_free(
|
||||||
|
IN nfs41_server *server)
|
||||||
|
{
|
||||||
|
dprintf(SRVLVL, "server_free(%s)\n", server->owner);
|
||||||
|
nfs41_superblock_list_free(&server->superblocks);
|
||||||
|
nfs41_name_cache_free(&server->name_cache);
|
||||||
|
free(server);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline void server_ref_locked(
|
||||||
|
IN nfs41_server *server)
|
||||||
|
{
|
||||||
|
server->ref_count++;
|
||||||
|
dprintf(SRVLVL, "nfs41_server_ref(%s) count %d\n",
|
||||||
|
server->owner, server->ref_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfs41_server_ref(
|
||||||
|
IN nfs41_server *server)
|
||||||
|
{
|
||||||
|
EnterCriticalSection(&g_server_list.lock);
|
||||||
|
|
||||||
|
server_ref_locked(server);
|
||||||
|
|
||||||
|
LeaveCriticalSection(&g_server_list.lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfs41_server_deref(
|
||||||
|
IN nfs41_server *server)
|
||||||
|
{
|
||||||
|
EnterCriticalSection(&g_server_list.lock);
|
||||||
|
|
||||||
|
server->ref_count--;
|
||||||
|
dprintf(SRVLVL, "nfs41_server_deref(%s) count %d\n",
|
||||||
|
server->owner, server->ref_count);
|
||||||
|
if (server->ref_count == 0) {
|
||||||
|
list_remove(&server->entry);
|
||||||
|
server_free(server);
|
||||||
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection(&g_server_list.lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void server_addrs_add(
|
||||||
|
IN OUT struct server_addrs *addrs,
|
||||||
|
IN const netaddr4 *addr)
|
||||||
|
{
|
||||||
|
/* we keep a list of addrs used to connect to each server. once it gets
|
||||||
|
* bigger than NFS41_ADDRS_PER_SERVER, overwrite the oldest addrs. use
|
||||||
|
* server_addrs.next_index to implement a circular array */
|
||||||
|
|
||||||
|
AcquireSRWLockExclusive(&addrs->lock);
|
||||||
|
|
||||||
|
if (multi_addr_find(&addrs->addrs, addr, NULL)) {
|
||||||
|
dprintf(SRVLVL, "server_addrs_add() found existing addr '%s'.\n",
|
||||||
|
addr->uaddr);
|
||||||
|
} else {
|
||||||
|
/* overwrite the address at 'next_index' */
|
||||||
|
StringCchCopyA(addrs->addrs.arr[addrs->next_index].netid,
|
||||||
|
NFS41_NETWORK_ID_LEN, addr->netid);
|
||||||
|
StringCchCopyA(addrs->addrs.arr[addrs->next_index].uaddr,
|
||||||
|
NFS41_UNIVERSAL_ADDR_LEN, addr->uaddr);
|
||||||
|
|
||||||
|
/* increment/wrap next_index */
|
||||||
|
addrs->next_index = (addrs->next_index + 1) % NFS41_ADDRS_PER_SERVER;
|
||||||
|
/* update addrs.count if necessary */
|
||||||
|
if (addrs->addrs.count < addrs->next_index)
|
||||||
|
addrs->addrs.count = addrs->next_index;
|
||||||
|
|
||||||
|
dprintf(SRVLVL, "server_addrs_add() added new addr '%s'.\n",
|
||||||
|
addr->uaddr);
|
||||||
|
}
|
||||||
|
ReleaseSRWLockExclusive(&addrs->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfs41_server_addrs(
|
||||||
|
IN nfs41_server *server,
|
||||||
|
OUT multi_addr4 *addrs)
|
||||||
|
{
|
||||||
|
struct server_addrs *saddrs = &server->addrs;
|
||||||
|
uint32_t i, j;
|
||||||
|
|
||||||
|
/* make a copy of the server's addrs, with most recent first */
|
||||||
|
AcquireSRWLockShared(&saddrs->lock);
|
||||||
|
j = saddrs->next_index;
|
||||||
|
for (i = 0; i < saddrs->addrs.count; i++) {
|
||||||
|
/* decrement/wrap j */
|
||||||
|
j = (NFS41_ADDRS_PER_SERVER + j - 1) % NFS41_ADDRS_PER_SERVER;
|
||||||
|
memcpy(&addrs->arr[i], &saddrs->addrs.arr[j], sizeof(netaddr4));
|
||||||
|
}
|
||||||
|
ReleaseSRWLockShared(&saddrs->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
int nfs41_server_find_or_create(
|
||||||
|
IN const char *server_owner_major_id,
|
||||||
|
IN const char *server_scope,
|
||||||
|
IN const netaddr4 *addr,
|
||||||
|
OUT nfs41_server **server_out)
|
||||||
|
{
|
||||||
|
const struct server_info info = { server_scope, server_owner_major_id };
|
||||||
|
struct list_entry *entry;
|
||||||
|
nfs41_server *server;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
dprintf(SRVLVL, "--> nfs41_server_find_or_create(%s)\n", info.owner);
|
||||||
|
|
||||||
|
EnterCriticalSection(&g_server_list.lock);
|
||||||
|
|
||||||
|
/* search for an existing server */
|
||||||
|
status = server_entry_find(&g_server_list, &info, &entry);
|
||||||
|
if (status) {
|
||||||
|
/* create a new server */
|
||||||
|
status = server_create(&info, &server);
|
||||||
|
if (status == NO_ERROR) {
|
||||||
|
/* add it to the list */
|
||||||
|
list_add_tail(&g_server_list.head, &server->entry);
|
||||||
|
*server_out = server;
|
||||||
|
|
||||||
|
dprintf(SRVLVL, "<-- nfs41_server_find_or_create() "
|
||||||
|
"returning new server %p\n", server);
|
||||||
|
} else {
|
||||||
|
dprintf(SRVLVL, "<-- nfs41_server_find_or_create() "
|
||||||
|
"returning %d\n", status);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
server = server_entry(entry);
|
||||||
|
|
||||||
|
dprintf(SRVLVL, "<-- nfs41_server_find_or_create() "
|
||||||
|
"returning existing server %p\n", server);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (server) {
|
||||||
|
/* register the address used to connect */
|
||||||
|
server_addrs_add(&server->addrs, addr);
|
||||||
|
|
||||||
|
server_ref_locked(server);
|
||||||
|
}
|
||||||
|
|
||||||
|
*server_out = server;
|
||||||
|
LeaveCriticalSection(&g_server_list.lock);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nfs41_server_resolve(
|
||||||
|
IN const char *hostname,
|
||||||
|
IN unsigned short port,
|
||||||
|
OUT multi_addr4 *addrs)
|
||||||
|
{
|
||||||
|
int status = ERROR_BAD_NET_NAME;
|
||||||
|
char service[16];
|
||||||
|
struct addrinfo hints, *res, *info;
|
||||||
|
struct netconfig *nconf;
|
||||||
|
struct netbuf addr;
|
||||||
|
char *netid, *uaddr;
|
||||||
|
|
||||||
|
dprintf(SRVLVL, "--> nfs41_server_resolve(%s:%u)\n",
|
||||||
|
hostname, port);
|
||||||
|
|
||||||
|
addrs->count = 0;
|
||||||
|
|
||||||
|
StringCchPrintfA(service, 16, "%u", port);
|
||||||
|
|
||||||
|
/* request a list of tcp addrs for the given hostname,port */
|
||||||
|
ZeroMemory(&hints, sizeof(hints));
|
||||||
|
hints.ai_family = AF_UNSPEC;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
hints.ai_protocol = IPPROTO_TCP;
|
||||||
|
|
||||||
|
if (getaddrinfo(hostname, service, &hints, &res) != 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
for (info = res; info != NULL; info = info->ai_next) {
|
||||||
|
/* find the appropriate entry in /etc/netconfig */
|
||||||
|
switch (info->ai_family) {
|
||||||
|
case AF_INET: netid = "tcp"; break;
|
||||||
|
case AF_INET6: netid = "tcp6"; break;
|
||||||
|
default: continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
nconf = getnetconfigent(netid);
|
||||||
|
if (nconf == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* convert to a transport-independent universal address */
|
||||||
|
addr.buf = info->ai_addr;
|
||||||
|
addr.maxlen = addr.len = (unsigned int)info->ai_addrlen;
|
||||||
|
|
||||||
|
uaddr = taddr2uaddr(nconf, &addr);
|
||||||
|
freenetconfigent(nconf);
|
||||||
|
|
||||||
|
if (uaddr == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
StringCchCopyA(addrs->arr[addrs->count].netid,
|
||||||
|
NFS41_NETWORK_ID_LEN+1, netid);
|
||||||
|
StringCchCopyA(addrs->arr[addrs->count].uaddr,
|
||||||
|
NFS41_UNIVERSAL_ADDR_LEN+1, uaddr);
|
||||||
|
freeuaddr(uaddr);
|
||||||
|
|
||||||
|
status = NO_ERROR;
|
||||||
|
if (++addrs->count >= NFS41_ADDRS_PER_SERVER)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
freeaddrinfo(res);
|
||||||
|
out:
|
||||||
|
if (status)
|
||||||
|
dprintf(SRVLVL, "<-- nfs41_server_resolve(%s:%u) returning "
|
||||||
|
"error %d\n", hostname, port, status);
|
||||||
|
else
|
||||||
|
dprintf(SRVLVL, "<-- nfs41_server_resolve(%s:%u) returning "
|
||||||
|
"%s\n", hostname, port, addrs->arr[0].uaddr);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
385
daemon/nfs41_session.c
Normal file
385
daemon/nfs41_session.c
Normal file
|
|
@ -0,0 +1,385 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <process.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "daemon_debug.h"
|
||||||
|
#include "nfs41_ops.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* session slot mechanism */
|
||||||
|
static int init_slot_table(nfs41_slot_table *table)
|
||||||
|
{
|
||||||
|
int i, status = 0;
|
||||||
|
|
||||||
|
//initialize slot table lock
|
||||||
|
table->lock = CreateMutex(NULL, FALSE, "session_table_lock");
|
||||||
|
if (table->lock == NULL) {
|
||||||
|
status = GetLastError();
|
||||||
|
eprintf("CreateMutext failed %d\n", status);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
//initialize condition variable for slots
|
||||||
|
table->cond = CreateEvent(NULL, TRUE, FALSE, "session_table_cond");
|
||||||
|
if (table->cond == NULL) {
|
||||||
|
status = GetLastError();
|
||||||
|
eprintf("CreateEvent failed %d\n", status);
|
||||||
|
goto out_mutex;
|
||||||
|
}
|
||||||
|
|
||||||
|
table->max_slots = NFS41_MAX_NUM_SLOTS;
|
||||||
|
for(i = 0; i < NFS41_MAX_NUM_SLOTS; i++) {
|
||||||
|
table->seq_nums[i] = 1;
|
||||||
|
table->used_slots[i] = 0;
|
||||||
|
}
|
||||||
|
table->highest_used = 0;
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
out_mutex:
|
||||||
|
CloseHandle(table->lock);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int reinit_slot_table(nfs41_slot_table *table)
|
||||||
|
{
|
||||||
|
int i, status = 0;
|
||||||
|
|
||||||
|
status = WaitForSingleObject(table->lock, INFINITE);
|
||||||
|
if (status != WAIT_OBJECT_0) {
|
||||||
|
dprintf(1, "nfs41_session_bump_seq: WaitForSingleObject failed\n");
|
||||||
|
print_condwait_status(1, status);
|
||||||
|
status = ERROR_LOCK_VIOLATION;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
table->max_slots = NFS41_MAX_NUM_SLOTS;
|
||||||
|
for(i = 0; i < NFS41_MAX_NUM_SLOTS; i++) {
|
||||||
|
table->seq_nums[i] = 1;
|
||||||
|
table->used_slots[i] = 0;
|
||||||
|
}
|
||||||
|
table->highest_used = 0;
|
||||||
|
SetEvent(table->cond);
|
||||||
|
ReleaseMutex(table->lock);
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void free_slot_table(nfs41_slot_table *table)
|
||||||
|
{
|
||||||
|
CloseHandle(table->lock);
|
||||||
|
CloseHandle(table->cond);
|
||||||
|
}
|
||||||
|
|
||||||
|
int nfs41_session_bump_seq(
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN uint32_t slotid)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
AcquireSRWLockShared(&session->client->session_lock);
|
||||||
|
status = WaitForSingleObject(session->table.lock, INFINITE);
|
||||||
|
if (status != WAIT_OBJECT_0) {
|
||||||
|
dprintf(1, "nfs41_session_bump_seq: WaitForSingleObject failed\n");
|
||||||
|
print_condwait_status(1, status);
|
||||||
|
status = ERROR_LOCK_VIOLATION;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
session->table.seq_nums[slotid]++;
|
||||||
|
ReleaseMutex(session->table.lock);
|
||||||
|
out:
|
||||||
|
ReleaseSRWLockShared(&session->client->session_lock);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nfs41_session_free_slot(
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN uint32_t slotid)
|
||||||
|
{
|
||||||
|
int status, i;
|
||||||
|
|
||||||
|
AcquireSRWLockShared(&session->client->session_lock);
|
||||||
|
status = WaitForSingleObject(session->table.lock, INFINITE);
|
||||||
|
if (status != WAIT_OBJECT_0) {
|
||||||
|
dprintf(1, "nfs41_session_free_slot: WaitForSingleObject failed\n");
|
||||||
|
print_condwait_status(1, status);
|
||||||
|
status = ERROR_LOCK_VIOLATION;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
session->table.used_slots[slotid] = 0;
|
||||||
|
if (slotid == session->table.highest_used) {
|
||||||
|
session->table.highest_used = 0;
|
||||||
|
for (i = slotid; i > 0; i--) {
|
||||||
|
if (session->table.used_slots[i]) {
|
||||||
|
session->table.highest_used = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dprintf(3, "freeing slot#=%d highest=%d\n", slotid, session->table.highest_used);
|
||||||
|
SetEvent(session->table.cond);
|
||||||
|
ReleaseMutex(session->table.lock);
|
||||||
|
out:
|
||||||
|
ReleaseSRWLockShared(&session->client->session_lock);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nfs41_session_get_slot(
|
||||||
|
IN nfs41_session *session,
|
||||||
|
OUT uint32_t *slot,
|
||||||
|
OUT uint32_t *seq,
|
||||||
|
OUT uint32_t *highest)
|
||||||
|
{
|
||||||
|
uint32_t status = NO_ERROR;
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
AcquireSRWLockShared(&session->client->session_lock);
|
||||||
|
look_for_slot:
|
||||||
|
status = WaitForSingleObject(session->table.lock, INFINITE);
|
||||||
|
if (status != WAIT_OBJECT_0) {
|
||||||
|
dprintf(1, "nfs41_session_get_slot: WaitForSingleObject failed\n");
|
||||||
|
print_condwait_status(1, status);
|
||||||
|
status = ERROR_LOCK_VIOLATION;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
dprintf(3, "looking for a free slot in the slot table\n");
|
||||||
|
*highest = session->table.highest_used;
|
||||||
|
for (i = 0; i < session->table.max_slots; i++) {
|
||||||
|
if (!session->table.used_slots[i]) {
|
||||||
|
session->table.used_slots[i] = 1; // mark slot used
|
||||||
|
*slot = i; // return slot number
|
||||||
|
*seq = session->table.seq_nums[i]; // return sequence number for the slot
|
||||||
|
//update highest_slot_used if needed
|
||||||
|
if (i > session->table.highest_used)
|
||||||
|
*highest = session->table.highest_used = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i == session->table.max_slots) {
|
||||||
|
dprintf(1, "all (%d) slots are used. waiting for a free slot\n", session->table.max_slots);
|
||||||
|
ReleaseMutex(session->table.lock);
|
||||||
|
status = WaitForSingleObject(session->table.cond, INFINITE);
|
||||||
|
if (status == WAIT_OBJECT_0) {
|
||||||
|
dprintf(1, "received a signal to look for a free slot\n");
|
||||||
|
ResetEvent(session->table.cond);
|
||||||
|
goto look_for_slot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ReleaseMutex(session->table.lock);
|
||||||
|
dprintf(2, "session %p: using slot#=%d with seq#=%d highest=%d\n", session, *slot, *seq, *highest);
|
||||||
|
out:
|
||||||
|
ReleaseSRWLockShared(&session->client->session_lock);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nfs41_session_sequence(
|
||||||
|
nfs41_sequence_args *args,
|
||||||
|
nfs41_session *session,
|
||||||
|
bool_t cachethis)
|
||||||
|
{
|
||||||
|
uint32_t status = NO_ERROR;
|
||||||
|
|
||||||
|
status = nfs41_session_get_slot(session, &args->sa_slotid,
|
||||||
|
&args->sa_sequenceid, &args->sa_highest_slotid);
|
||||||
|
if (status)
|
||||||
|
goto out;
|
||||||
|
args->sa_sessionid = session->session_id;
|
||||||
|
args->sa_cachethis = cachethis;
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* session renewal */
|
||||||
|
static unsigned int WINAPI renew_session(void *args)
|
||||||
|
{
|
||||||
|
int status = NO_ERROR;
|
||||||
|
nfs41_session *session = (nfs41_session *)args;
|
||||||
|
/* sleep for 2/3 of lease_time */
|
||||||
|
const uint32_t sleep_time = (2 * session->lease_time*1000)/3;
|
||||||
|
|
||||||
|
dprintf(1, "Creating renew_session thread: %p\n", session->renew_thread);
|
||||||
|
while(1) {
|
||||||
|
dprintf(1, "Going to sleep for %dmsecs\n", sleep_time);
|
||||||
|
Sleep(sleep_time);
|
||||||
|
status = nfs41_send_sequence(session);
|
||||||
|
if (status)
|
||||||
|
dprintf(1, "renewal thread: nfs41_send_sequence failed %d\n", status);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* session creation */
|
||||||
|
static int session_alloc(
|
||||||
|
IN nfs41_client *client,
|
||||||
|
OUT nfs41_session **session_out)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
nfs41_session *session;
|
||||||
|
|
||||||
|
session = calloc(1, sizeof(nfs41_session));
|
||||||
|
if (session == NULL) {
|
||||||
|
status = GetLastError();
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
session->client = client;
|
||||||
|
session->renew_thread = INVALID_HANDLE_VALUE;
|
||||||
|
session->isValidState = FALSE;
|
||||||
|
|
||||||
|
status = init_slot_table(&session->table);
|
||||||
|
if (status) {
|
||||||
|
eprintf("init_slot_table failed %d\n", status);
|
||||||
|
goto out_err_session;
|
||||||
|
}
|
||||||
|
|
||||||
|
//initialize session lock
|
||||||
|
InitializeSRWLock(&client->session_lock);
|
||||||
|
|
||||||
|
*session_out = session;
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
out_err_session:
|
||||||
|
free(session);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nfs41_session_create(
|
||||||
|
IN nfs41_client *client,
|
||||||
|
IN nfs41_session **session_out)
|
||||||
|
{
|
||||||
|
nfs41_session *session;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
status = session_alloc(client, &session);
|
||||||
|
if (status) {
|
||||||
|
eprintf("session_alloc() failed with %d\n", status);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
AcquireSRWLockShared(&client->exid_lock);
|
||||||
|
if (client->roles & (EXCHGID4_FLAG_USE_PNFS_MDS |
|
||||||
|
EXCHGID4_FLAG_USE_NON_PNFS))
|
||||||
|
session->flags |= CREATE_SESSION4_FLAG_CONN_BACK_CHAN;
|
||||||
|
ReleaseSRWLockShared(&client->exid_lock);
|
||||||
|
|
||||||
|
status = nfs41_create_session(client, session);
|
||||||
|
if (status) {
|
||||||
|
eprintf("nfs41_create_session failed %d\n", status);
|
||||||
|
status = ERROR_BAD_NET_RESP;
|
||||||
|
goto out_err;
|
||||||
|
}
|
||||||
|
|
||||||
|
AcquireSRWLockExclusive(&session->client->session_lock);
|
||||||
|
client->session = session;
|
||||||
|
session->isValidState = TRUE;
|
||||||
|
ReleaseSRWLockExclusive(&session->client->session_lock);
|
||||||
|
*session_out = session;
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
|
||||||
|
out_err:
|
||||||
|
nfs41_session_free(session);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* session renewal */
|
||||||
|
int nfs41_session_renew(
|
||||||
|
IN nfs41_session *session)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
AcquireSRWLockExclusive(&session->client->session_lock);
|
||||||
|
status = reinit_slot_table(&session->table);
|
||||||
|
if (status) {
|
||||||
|
eprintf("init_slot_table failed %d\n", status);
|
||||||
|
goto out_err_session;
|
||||||
|
}
|
||||||
|
status = nfs41_create_session(session->client, session);
|
||||||
|
if (status && status != NFS4ERR_STALE_CLIENTID) {
|
||||||
|
eprintf("nfs41_create_session failed %d\n", status);
|
||||||
|
status = ERROR_BAD_NET_RESP;
|
||||||
|
goto out_err_slot;
|
||||||
|
}
|
||||||
|
ReleaseSRWLockExclusive(&session->client->session_lock);
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
out_err_slot:
|
||||||
|
free_slot_table(&session->table);
|
||||||
|
out_err_session:
|
||||||
|
ReleaseSRWLockExclusive(&session->client->session_lock);
|
||||||
|
free(session);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nfs41_session_set_lease(
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN uint32_t lease_time)
|
||||||
|
{
|
||||||
|
int status = NO_ERROR;
|
||||||
|
uint32_t thread_id;
|
||||||
|
|
||||||
|
if (valid_handle(session->renew_thread)) {
|
||||||
|
eprintf("nfs41_session_set_lease(): session "
|
||||||
|
"renewal thread already started!\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lease_time == 0) {
|
||||||
|
eprintf("nfs41_session_set_lease(): invalid lease_time=0\n");
|
||||||
|
status = ERROR_INVALID_PARAMETER;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
session->lease_time = lease_time;
|
||||||
|
session->renew_thread = (HANDLE)_beginthreadex(NULL,
|
||||||
|
0, renew_session, session, 0, &thread_id);
|
||||||
|
if (!valid_handle(session->renew_thread)) {
|
||||||
|
status = GetLastError();
|
||||||
|
eprintf("_beginthreadex failed %d\n", status);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfs41_session_free(
|
||||||
|
IN nfs41_session *session)
|
||||||
|
{
|
||||||
|
AcquireSRWLockExclusive(&session->client->session_lock);
|
||||||
|
if (valid_handle(session->renew_thread)) {
|
||||||
|
dprintf(1, "nfs41_session_free: terminating session renewal thread\n");
|
||||||
|
if (!TerminateThread(session->renew_thread, NO_ERROR))
|
||||||
|
eprintf("failed to terminate renewal thread %p\n",
|
||||||
|
session->renew_thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (session->isValidState) {
|
||||||
|
session->client->rpc->is_valid_session = FALSE;
|
||||||
|
nfs41_destroy_session(session);
|
||||||
|
}
|
||||||
|
free_slot_table(&session->table);
|
||||||
|
ReleaseSRWLockExclusive(&session->client->session_lock);
|
||||||
|
free(session);
|
||||||
|
}
|
||||||
228
daemon/nfs41_superblock.c
Normal file
228
daemon/nfs41_superblock.c
Normal file
|
|
@ -0,0 +1,228 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "daemon_debug.h"
|
||||||
|
#include "nfs41.h"
|
||||||
|
#include "nfs41_ops.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define SBLVL 3 /* dprintf level for superblock logging */
|
||||||
|
|
||||||
|
|
||||||
|
static __inline int compare_fsid(
|
||||||
|
IN const nfs41_fsid *lhs,
|
||||||
|
IN const nfs41_fsid *rhs)
|
||||||
|
{
|
||||||
|
if (lhs->major > rhs->major) return 1;
|
||||||
|
if (lhs->major < rhs->major) return -1;
|
||||||
|
if (lhs->minor > rhs->minor) return 1;
|
||||||
|
if (lhs->minor < rhs->minor) return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* nfs41_superblock */
|
||||||
|
static int superblock_create(
|
||||||
|
IN const nfs41_fsid *fsid,
|
||||||
|
OUT nfs41_superblock **superblock_out)
|
||||||
|
{
|
||||||
|
int status = NO_ERROR;
|
||||||
|
nfs41_superblock *superblock;
|
||||||
|
|
||||||
|
dprintf(SBLVL, "creating superblock for fsid(%llu,%llu)\n",
|
||||||
|
fsid->major, fsid->minor);
|
||||||
|
|
||||||
|
superblock = calloc(1, sizeof(nfs41_superblock));
|
||||||
|
if (superblock == NULL) {
|
||||||
|
status = GetLastError();
|
||||||
|
eprintf("failed to allocate superblock "
|
||||||
|
"for fsid(%llu,%llu)\n", fsid->major, fsid->minor);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&superblock->fsid, fsid, sizeof(nfs41_fsid));
|
||||||
|
InitializeSRWLock(&superblock->lock);
|
||||||
|
|
||||||
|
*superblock_out = superblock;
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void superblock_free(
|
||||||
|
IN nfs41_superblock *superblock)
|
||||||
|
{
|
||||||
|
free(superblock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_superblock_attrs(
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN nfs41_superblock *superblock,
|
||||||
|
IN nfs41_path_fh *file)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
bitmap4 attr_request;
|
||||||
|
nfs41_file_info info;
|
||||||
|
|
||||||
|
attr_request.arr[0] = (uint32_t)(FATTR4_WORD0_SUPPORTED_ATTRS |
|
||||||
|
FATTR4_WORD0_MAXREAD | FATTR4_WORD0_MAXWRITE);
|
||||||
|
attr_request.arr[1] = FATTR4_WORD1_FS_LAYOUT_TYPE;
|
||||||
|
attr_request.count = 2;
|
||||||
|
|
||||||
|
ZeroMemory(&info, sizeof(info));
|
||||||
|
info.supported_attrs = &superblock->supported_attrs;
|
||||||
|
|
||||||
|
status = nfs41_getattr(session, file, &attr_request, &info);
|
||||||
|
if (status) {
|
||||||
|
eprintf("nfs41_getattr() failed with %s when "
|
||||||
|
"fetching attributes for fsid(%llu,%llu)\n",
|
||||||
|
nfs_error_string(status),
|
||||||
|
superblock->fsid.major, superblock->fsid.minor);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.maxread)
|
||||||
|
superblock->maxread = info.maxread;
|
||||||
|
else
|
||||||
|
superblock->maxread = session->fore_chan_attrs.ca_maxresponsesize;
|
||||||
|
|
||||||
|
if (info.maxwrite)
|
||||||
|
superblock->maxwrite = info.maxwrite;
|
||||||
|
else
|
||||||
|
superblock->maxwrite = session->fore_chan_attrs.ca_maxrequestsize;
|
||||||
|
|
||||||
|
superblock->layout_types = info.fs_layout_types;
|
||||||
|
|
||||||
|
dprintf(SBLVL, "attributes for fsid(%llu,%llu): "
|
||||||
|
"maxread=%llu, maxwrite=%llu, layout_types: 0x%X\n",
|
||||||
|
superblock->fsid.major, superblock->fsid.minor,
|
||||||
|
superblock->maxread, superblock->maxwrite,
|
||||||
|
superblock->layout_types);
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* nfs41_superblock_list */
|
||||||
|
#define superblock_entry(pos) list_container(pos, nfs41_superblock, entry)
|
||||||
|
|
||||||
|
static int superblock_compare(
|
||||||
|
const struct list_entry *entry,
|
||||||
|
const void *value)
|
||||||
|
{
|
||||||
|
const nfs41_superblock *superblock = superblock_entry(entry);
|
||||||
|
return compare_fsid(&superblock->fsid, (const nfs41_fsid*)value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static nfs41_superblock* find_superblock(
|
||||||
|
IN nfs41_superblock_list *superblocks,
|
||||||
|
IN const nfs41_fsid *fsid)
|
||||||
|
{
|
||||||
|
struct list_entry *entry;
|
||||||
|
entry = list_search(&superblocks->head, fsid, superblock_compare);
|
||||||
|
return entry ? superblock_entry(entry) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfs41_superblock_list_init(
|
||||||
|
IN nfs41_superblock_list *superblocks)
|
||||||
|
{
|
||||||
|
list_init(&superblocks->head);
|
||||||
|
InitializeSRWLock(&superblocks->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfs41_superblock_list_free(
|
||||||
|
IN nfs41_superblock_list *superblocks)
|
||||||
|
{
|
||||||
|
struct list_entry *entry, *tmp;
|
||||||
|
|
||||||
|
dprintf(SBLVL, "nfs41_superblock_list_free()\n");
|
||||||
|
|
||||||
|
list_for_each_tmp(entry, tmp, &superblocks->head)
|
||||||
|
superblock_free(superblock_entry(entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int nfs41_superblock_for_fh(
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN const nfs41_fsid *fsid,
|
||||||
|
IN const nfs41_fh *parent OPTIONAL,
|
||||||
|
OUT nfs41_path_fh *file)
|
||||||
|
{
|
||||||
|
int status = NFS4_OK;
|
||||||
|
nfs41_server *server = client_server(session->client);
|
||||||
|
nfs41_superblock_list *superblocks = &server->superblocks;
|
||||||
|
nfs41_superblock *superblock;
|
||||||
|
|
||||||
|
dprintf(SBLVL, "--> nfs41_superblock_for_fh(fsid(%llu,%llu))\n",
|
||||||
|
fsid->major, fsid->minor);
|
||||||
|
|
||||||
|
/* compare with the parent's fsid, and use that if it matches */
|
||||||
|
if (parent && parent->superblock &&
|
||||||
|
compare_fsid(fsid, &parent->superblock->fsid) == 0) {
|
||||||
|
file->fh.superblock = parent->superblock;
|
||||||
|
dprintf(SBLVL, "using superblock from parent\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* using a shared lock, search for an existing superblock */
|
||||||
|
AcquireSRWLockShared(&superblocks->lock);
|
||||||
|
superblock = find_superblock(superblocks, fsid);
|
||||||
|
ReleaseSRWLockShared(&superblocks->lock);
|
||||||
|
|
||||||
|
if (superblock) {
|
||||||
|
dprintf(SBLVL, "found existing superblock in server list "
|
||||||
|
"[shared lock]\n");
|
||||||
|
} else {
|
||||||
|
AcquireSRWLockExclusive(&superblocks->lock);
|
||||||
|
/* must search again under an exclusive lock, in case another thread
|
||||||
|
* created it after our first search */
|
||||||
|
superblock = find_superblock(superblocks, fsid);
|
||||||
|
if (superblock) {
|
||||||
|
dprintf(SBLVL, "found newly created superblock in server list "
|
||||||
|
"[exclusive lock]\n");
|
||||||
|
} else {
|
||||||
|
/* create the superblock */
|
||||||
|
status = superblock_create(fsid, &superblock);
|
||||||
|
if (status == NO_ERROR) /* add it to the list */
|
||||||
|
list_add_tail(&superblocks->head, &superblock->entry);
|
||||||
|
}
|
||||||
|
ReleaseSRWLockExclusive(&superblocks->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == NO_ERROR && superblock->supported_attrs.count == 0) {
|
||||||
|
/* exclusive lock on the superblock while fetching attributes */
|
||||||
|
AcquireSRWLockExclusive(&superblock->lock);
|
||||||
|
if (superblock->supported_attrs.count == 0)
|
||||||
|
status = get_superblock_attrs(session, superblock, file);
|
||||||
|
ReleaseSRWLockExclusive(&superblock->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
file->fh.superblock = superblock;
|
||||||
|
out:
|
||||||
|
dprintf(SBLVL, "<-- nfs41_superblock_for_fh() returning %p, status %d\n",
|
||||||
|
file->fh.superblock, status);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
185
daemon/nfs41_types.h
Normal file
185
daemon/nfs41_types.h
Normal file
|
|
@ -0,0 +1,185 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __NFS41_DAEMON_TYPES_H__
|
||||||
|
#define __NFS41_DAEMON_TYPES_H__
|
||||||
|
|
||||||
|
#include "wintirpc.h"
|
||||||
|
#include "rpc/xdr.h"
|
||||||
|
#include "nfs41_const.h"
|
||||||
|
|
||||||
|
typedef char* caddr_t;
|
||||||
|
|
||||||
|
static const int64_t NFS4_INT64_MAX = 0x7fffffffffffffff;
|
||||||
|
static const uint64_t NFS4_UINT64_MAX = 0xffffffffffffffff;
|
||||||
|
static const int32_t NFS4_INT32_MAX = 0x7fffffff;
|
||||||
|
static const uint32_t NFS4_UINT32_MAX = 0xffffffff;
|
||||||
|
|
||||||
|
static const uint64_t NFS4_MAXFILELEN = 0xffffffffffffffff;
|
||||||
|
static const uint64_t NFS4_MAXFILEOFF = 0xfffffffffffffffe;
|
||||||
|
|
||||||
|
|
||||||
|
/* common nfs types */
|
||||||
|
typedef struct __nfs41_abs_path {
|
||||||
|
char path[NFS41_MAX_PATH_LEN];
|
||||||
|
unsigned short len;
|
||||||
|
SRWLOCK lock;
|
||||||
|
} nfs41_abs_path;
|
||||||
|
|
||||||
|
typedef struct __nfs41_component {
|
||||||
|
const char *name;
|
||||||
|
unsigned short len;
|
||||||
|
} nfs41_component;
|
||||||
|
|
||||||
|
typedef struct __nfs41_fh {
|
||||||
|
unsigned char fh[NFS4_FHSIZE];
|
||||||
|
uint32_t len;
|
||||||
|
uint64_t fileid;
|
||||||
|
struct __nfs41_superblock *superblock;
|
||||||
|
} nfs41_fh;
|
||||||
|
|
||||||
|
typedef struct __nfs41_path_fh {
|
||||||
|
nfs41_abs_path *path;
|
||||||
|
nfs41_component name;
|
||||||
|
nfs41_fh fh;
|
||||||
|
} nfs41_path_fh;
|
||||||
|
|
||||||
|
typedef struct __nfs41_fsid {
|
||||||
|
uint64_t major;
|
||||||
|
uint64_t minor;
|
||||||
|
} nfs41_fsid;
|
||||||
|
|
||||||
|
typedef struct __netaddr4 {
|
||||||
|
char netid[NFS41_NETWORK_ID_LEN+1];
|
||||||
|
char uaddr[NFS41_UNIVERSAL_ADDR_LEN+1];
|
||||||
|
} netaddr4;
|
||||||
|
|
||||||
|
typedef struct __multi_addr4 {
|
||||||
|
netaddr4 arr[NFS41_ADDRS_PER_SERVER];
|
||||||
|
uint32_t count;
|
||||||
|
} multi_addr4;
|
||||||
|
|
||||||
|
typedef struct __bitmap4 {
|
||||||
|
uint32_t count;
|
||||||
|
uint32_t arr[3];
|
||||||
|
} bitmap4;
|
||||||
|
|
||||||
|
typedef struct __nfstime4 {
|
||||||
|
int64_t seconds;
|
||||||
|
uint32_t nseconds;
|
||||||
|
} nfstime4;
|
||||||
|
|
||||||
|
typedef struct __client_owner4 {
|
||||||
|
unsigned char co_verifier[NFS4_VERIFIER_SIZE];
|
||||||
|
uint32_t co_ownerid_len;
|
||||||
|
unsigned char co_ownerid[NFS4_OPAQUE_LIMIT];
|
||||||
|
} client_owner4;
|
||||||
|
|
||||||
|
typedef struct __server_owner4 {
|
||||||
|
uint64_t so_minor_id;
|
||||||
|
uint32_t so_major_id_len;
|
||||||
|
char so_major_id[NFS4_OPAQUE_LIMIT];
|
||||||
|
} server_owner4;
|
||||||
|
|
||||||
|
typedef struct __state_owner4 {
|
||||||
|
uint32_t owner_len;
|
||||||
|
unsigned char owner[NFS4_OPAQUE_LIMIT];
|
||||||
|
} state_owner4;
|
||||||
|
|
||||||
|
typedef struct __nfs_impl_id4 {
|
||||||
|
uint32_t nii_domain_len;
|
||||||
|
unsigned char *nii_domain;
|
||||||
|
uint32_t nii_name_len;
|
||||||
|
unsigned char *nii_name;
|
||||||
|
nfstime4 nii_date;
|
||||||
|
} nfs_impl_id4;
|
||||||
|
|
||||||
|
typedef struct __nfsace4 {
|
||||||
|
uint32_t acetype;
|
||||||
|
uint32_t aceflag;
|
||||||
|
uint32_t acemask;
|
||||||
|
unsigned char who[NFS4_OPAQUE_LIMIT];
|
||||||
|
} nfsace4;
|
||||||
|
|
||||||
|
typedef struct __stateid4 {
|
||||||
|
uint32_t seqid;
|
||||||
|
unsigned char other[12];
|
||||||
|
} stateid4;
|
||||||
|
|
||||||
|
typedef struct __fattr4 {
|
||||||
|
bitmap4 attrmask;
|
||||||
|
uint32_t attr_vals_len;
|
||||||
|
unsigned char attr_vals[NFS4_OPAQUE_LIMIT];
|
||||||
|
} fattr4;
|
||||||
|
|
||||||
|
typedef struct __change_info4 {
|
||||||
|
bool_t atomic;
|
||||||
|
uint64_t before;
|
||||||
|
uint64_t after;
|
||||||
|
} change_info4;
|
||||||
|
|
||||||
|
typedef struct __fs_location_server {
|
||||||
|
/* 'address' represents one of a traditional DNS host name,
|
||||||
|
* IPv4 address, IPv6 address, or a zero-length string */
|
||||||
|
char address[NFS41_HOSTNAME_LEN+1];
|
||||||
|
} fs_location_server;
|
||||||
|
|
||||||
|
typedef struct __fs_location4 {
|
||||||
|
nfs41_abs_path path; /* path to fs from referred server's root */
|
||||||
|
fs_location_server *servers;
|
||||||
|
uint32_t server_count;
|
||||||
|
} fs_location4;
|
||||||
|
|
||||||
|
typedef struct __fs_locations4 {
|
||||||
|
nfs41_abs_path path; /* path to fs from referring server's root */
|
||||||
|
fs_location4 *locations;
|
||||||
|
uint32_t location_count;
|
||||||
|
} fs_locations4;
|
||||||
|
|
||||||
|
typedef struct __nfs41_file_info {
|
||||||
|
nfs41_fsid fsid;
|
||||||
|
nfstime4 time_access;
|
||||||
|
nfstime4 time_create;
|
||||||
|
nfstime4 time_modify;
|
||||||
|
bitmap4 attrmask;
|
||||||
|
bitmap4 *supported_attrs; /* XXX: per-fs */
|
||||||
|
uint64_t maxread; /* XXX: per-fs */
|
||||||
|
uint64_t maxwrite; /* XXX: per-fs */
|
||||||
|
uint64_t change;
|
||||||
|
uint64_t size;
|
||||||
|
uint64_t fileid;
|
||||||
|
uint64_t space_avail; /* XXX: per-fs */
|
||||||
|
uint64_t space_free; /* XXX: per-fs */
|
||||||
|
uint64_t space_total; /* XXX: per-fs */
|
||||||
|
uint32_t type;
|
||||||
|
uint32_t numlinks;
|
||||||
|
uint32_t rdattr_error;
|
||||||
|
uint32_t mode;
|
||||||
|
uint32_t mode_mask;
|
||||||
|
fs_locations4 *fs_locations; /* XXX: per-fs */
|
||||||
|
uint32_t lease_time; /* XXX: per-server */
|
||||||
|
uint32_t fs_layout_types; /* pnfs, XXX: per-fs */
|
||||||
|
bool_t hidden;
|
||||||
|
} nfs41_file_info;
|
||||||
|
|
||||||
|
#endif /* !__NFS41_DAEMON_TYPES_H__ */
|
||||||
3124
daemon/nfs41_xdr.c
Normal file
3124
daemon/nfs41_xdr.c
Normal file
File diff suppressed because it is too large
Load diff
33
daemon/nfs41_xdr.h
Normal file
33
daemon/nfs41_xdr.h
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __NFS41_NFS_XDR_H__
|
||||||
|
#define __NFS41_NFS_XDR_H__
|
||||||
|
|
||||||
|
#include "nfs41_types.h"
|
||||||
|
|
||||||
|
bool_t nfs_encode_compound(XDR *xdr, caddr_t *args);
|
||||||
|
bool_t nfs_decode_compound(XDR *xdr, caddr_t *res);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* !__NFS41_NFS_XDR_H__ */
|
||||||
445
daemon/open.c
Normal file
445
daemon/open.c
Normal file
|
|
@ -0,0 +1,445 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <strsafe.h>
|
||||||
|
|
||||||
|
#include "nfs41_ops.h"
|
||||||
|
#include "from_kernel.h"
|
||||||
|
#include "daemon_debug.h"
|
||||||
|
#include "upcall.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
|
||||||
|
static int create_open_state(
|
||||||
|
IN const nfs41_abs_path *path,
|
||||||
|
IN uint32_t open_owner_id,
|
||||||
|
OUT nfs41_open_state **state_out)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
nfs41_open_state *state;
|
||||||
|
|
||||||
|
state = calloc(1, sizeof(nfs41_open_state));
|
||||||
|
if (state == NULL) {
|
||||||
|
status = GetLastError();
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
InitializeSRWLock(&state->path.lock);
|
||||||
|
abs_path_copy(&state->path, path);
|
||||||
|
path_fh_init(&state->file, &state->path);
|
||||||
|
path_fh_init(&state->parent, &state->path);
|
||||||
|
last_component(state->path.path, state->file.name.name,
|
||||||
|
&state->parent.name);
|
||||||
|
|
||||||
|
StringCchPrintfA((LPSTR)state->owner.owner, NFS4_OPAQUE_LIMIT,
|
||||||
|
"%u", open_owner_id);
|
||||||
|
state->owner.owner_len = (uint32_t)strlen(
|
||||||
|
(const char*)state->owner.owner);
|
||||||
|
|
||||||
|
*state_out = state;
|
||||||
|
status = NO_ERROR;
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void free_open_state(
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN nfs41_open_state *state)
|
||||||
|
{
|
||||||
|
free(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* NFS41_OPEN */
|
||||||
|
int parse_open(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
open_upcall_args *args = &upcall->args.open;
|
||||||
|
|
||||||
|
ZeroMemory(&args->path, sizeof(nfs41_abs_path));
|
||||||
|
status = get_abs_path(&buffer, &length, &args->path);
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->access_mask, sizeof(ULONG));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->access_mode, sizeof(ULONG));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->file_attrs, sizeof(ULONG));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->create_opts, sizeof(ULONG));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->disposition, sizeof(ULONG));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->root, sizeof(HANDLE));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->open_owner_id, sizeof(ULONG));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->mode, sizeof(DWORD));
|
||||||
|
out:
|
||||||
|
if (status)
|
||||||
|
eprintf("parsing NFS41_OPEN failed with %d\n", status);
|
||||||
|
else {
|
||||||
|
dprintf(1, "parsing NFS41_OPEN: filename='%s' access mask=%d "
|
||||||
|
"access mode=%d\n\tfile attrs=0x%x create attrs=0x%x "
|
||||||
|
"(kernel) disposition=%d\n\tsession=%p open_owner_id=%d mode=%o\n",
|
||||||
|
args->path.path, args->access_mask, args->access_mode, args->file_attrs,
|
||||||
|
args->create_opts, args->disposition, args->root, args->open_owner_id,
|
||||||
|
args->mode);
|
||||||
|
print_disposition(2, args->disposition);
|
||||||
|
print_access_mask(2, args->access_mask);
|
||||||
|
print_share_mode(2, args->access_mode);
|
||||||
|
print_create_attributes(2, args->create_opts);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOLEAN do_lookup(uint32_t type, ULONG access_mask, ULONG disposition)
|
||||||
|
{
|
||||||
|
if (type == NF4DIR) {
|
||||||
|
if (disposition == FILE_OPEN || disposition == FILE_OVERWRITE) {
|
||||||
|
dprintf(1, "Opening a directory\n");
|
||||||
|
return TRUE;
|
||||||
|
} else {
|
||||||
|
dprintf(1, "Creating a directory\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((access_mask & FILE_READ_DATA) ||
|
||||||
|
(access_mask & FILE_WRITE_DATA) ||
|
||||||
|
(access_mask & FILE_APPEND_DATA) ||
|
||||||
|
(access_mask & FILE_EXECUTE))
|
||||||
|
return FALSE;
|
||||||
|
else {
|
||||||
|
dprintf(1, "Open call that wants to manage attributes\n");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int map_disposition_2_nfsopen(ULONG disposition, int in_status,
|
||||||
|
uint32_t *create, uint32_t *last_error)
|
||||||
|
{
|
||||||
|
int status = NO_ERROR;
|
||||||
|
if (disposition == FILE_SUPERSEDE) {
|
||||||
|
if (in_status == NFS4ERR_NOENT) {
|
||||||
|
*create = OPEN4_CREATE;
|
||||||
|
*last_error = ERROR_FILE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
else // we need to truncate the file file then open it
|
||||||
|
*create = OPEN4_NOCREATE;
|
||||||
|
} else if (disposition == FILE_CREATE) {
|
||||||
|
// if lookup succeeded which means the file exist, return an error
|
||||||
|
if (!in_status)
|
||||||
|
status = ERROR_FILE_EXISTS;
|
||||||
|
else
|
||||||
|
*create = OPEN4_CREATE;
|
||||||
|
} else if (disposition == FILE_OPEN) {
|
||||||
|
if (in_status == NFS4ERR_NOENT)
|
||||||
|
status = ERROR_FILE_NOT_FOUND;
|
||||||
|
else
|
||||||
|
*create = OPEN4_NOCREATE;
|
||||||
|
} else if (disposition == FILE_OPEN_IF) {
|
||||||
|
if (in_status == NFS4ERR_NOENT) {
|
||||||
|
dprintf(1, "creating new file\n");
|
||||||
|
*create = OPEN4_CREATE;
|
||||||
|
*last_error = ERROR_FILE_NOT_FOUND;
|
||||||
|
} else {
|
||||||
|
dprintf(1, "opening existing file\n");
|
||||||
|
*create = OPEN4_NOCREATE;
|
||||||
|
}
|
||||||
|
} else if (disposition == FILE_OVERWRITE) {
|
||||||
|
if (in_status == NFS4ERR_NOENT)
|
||||||
|
status = ERROR_FILE_NOT_FOUND;
|
||||||
|
//truncate file
|
||||||
|
*create = OPEN4_CREATE;
|
||||||
|
} else if (disposition == FILE_OVERWRITE_IF) {
|
||||||
|
if (in_status == NFS4ERR_NOENT)
|
||||||
|
*last_error = ERROR_FILE_NOT_FOUND;
|
||||||
|
//truncate file
|
||||||
|
*create = OPEN4_CREATE;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int check_execute_access(nfs41_open_state *state)
|
||||||
|
{
|
||||||
|
uint32_t supported, access;
|
||||||
|
int status = nfs41_access(state->session, &state->file,
|
||||||
|
ACCESS4_EXECUTE | ACCESS4_READ, &supported, &access);
|
||||||
|
if (status) {
|
||||||
|
dprintf(1, "nfs41_access() failed with %s\n",
|
||||||
|
nfs_error_string(status));
|
||||||
|
status = ERROR_ACCESS_DENIED;
|
||||||
|
} else if ((supported & ACCESS4_EXECUTE) == 0) {
|
||||||
|
/* server can't verify execute access;
|
||||||
|
* for now, assume that read access is good enough */
|
||||||
|
if ((supported & ACCESS4_READ) == 0 || (access & ACCESS4_READ) == 0) {
|
||||||
|
dprintf(2, "server can't verify execute access, and user does "
|
||||||
|
"not have read access\n");
|
||||||
|
status = ERROR_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
} else if ((access & ACCESS4_EXECUTE) == 0) {
|
||||||
|
dprintf(2, "user does not have execute access to file\n");
|
||||||
|
status = ERROR_ACCESS_DENIED;
|
||||||
|
} else
|
||||||
|
dprintf(2, "user has execute access to file\n");
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int handle_open(nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
int status = 0;
|
||||||
|
open_upcall_args *args = &upcall->args.open;
|
||||||
|
nfs41_open_state *state;
|
||||||
|
bitmap4 attr_request;
|
||||||
|
nfs41_file_info info;
|
||||||
|
|
||||||
|
init_getattr_request(&attr_request);
|
||||||
|
|
||||||
|
status = create_open_state(&args->path, args->open_owner_id, &state);
|
||||||
|
if (status) {
|
||||||
|
eprintf("create_open_state(%u) failed with %d\n",
|
||||||
|
args->open_owner_id, status);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// first check if windows told us it's a directory
|
||||||
|
if (args->create_opts & FILE_DIRECTORY_FILE)
|
||||||
|
state->type = NF4DIR;
|
||||||
|
else
|
||||||
|
state->type = NF4REG;
|
||||||
|
|
||||||
|
// always do a lookup
|
||||||
|
status = nfs41_lookup(args->root, nfs41_root_session(args->root),
|
||||||
|
&state->path, &state->parent, &state->file, &info, &state->session);
|
||||||
|
// now if file/dir exists, use type returned by lookup
|
||||||
|
if (status == NO_ERROR) {
|
||||||
|
if (info.type == NF4DIR) {
|
||||||
|
dprintf(2, "handle_nfs41_open: DIRECTORY\n");
|
||||||
|
if (args->create_opts & FILE_NON_DIRECTORY_FILE) {
|
||||||
|
eprintf("trying to open directory %s as a file\n",
|
||||||
|
args->path.path);
|
||||||
|
status = ERROR_ACCESS_DENIED;
|
||||||
|
goto out_free_state;
|
||||||
|
}
|
||||||
|
} else if (info.type == NF4REG) {
|
||||||
|
dprintf(2, "handle nfs41_open: FILE\n");
|
||||||
|
if (args->create_opts & FILE_DIRECTORY_FILE) {
|
||||||
|
eprintf("trying to open file %s as a directory\n",
|
||||||
|
args->path.path);
|
||||||
|
#ifdef NOTEPAD_OPEN_FILE_AS_DIRFILE_FIXED
|
||||||
|
status = ERROR_ACCESS_DENIED;
|
||||||
|
goto out_free_state;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
dprintf(2, "handle nfs41_open: is it SYMLINK?\n");
|
||||||
|
state->type = info.type;
|
||||||
|
} else if (status != ERROR_FILE_NOT_FOUND)
|
||||||
|
goto out_free_state;
|
||||||
|
if (do_lookup(state->type, args->access_mask, args->disposition)) {
|
||||||
|
if (status) {
|
||||||
|
dprintf(1, "nfs41_lookup failed with %d\n", status);
|
||||||
|
goto out_free_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
nfs_to_basic_info(&info, &args->basic_info);
|
||||||
|
nfs_to_standard_info(&info, &args->std_info);
|
||||||
|
args->mode = info.mode;
|
||||||
|
args->changeattr = info.change;
|
||||||
|
} else {
|
||||||
|
uint32_t allow = 0, deny = 0, create = 0;
|
||||||
|
|
||||||
|
map_access_2_allowdeny(args->access_mask, args->access_mode, &allow, &deny);
|
||||||
|
status = map_disposition_2_nfsopen(args->disposition, status, &create, &upcall->last_error);
|
||||||
|
if (status)
|
||||||
|
goto out_free_state;
|
||||||
|
|
||||||
|
if (args->access_mask & FILE_EXECUTE && state->file.fh.len) {
|
||||||
|
status = check_execute_access(state);
|
||||||
|
if (status)
|
||||||
|
goto out_free_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (create == OPEN4_CREATE && (args->create_opts & FILE_DIRECTORY_FILE)) {
|
||||||
|
status = nfs41_create(state->session, NF4DIR, args->mode,
|
||||||
|
&state->parent, &state->file);
|
||||||
|
args->std_info.Directory = 1;
|
||||||
|
args->created = status == NFS4_OK;
|
||||||
|
} else {
|
||||||
|
status = nfs41_open(state->session, allow, deny, create,
|
||||||
|
args->mode, state, &info);
|
||||||
|
|
||||||
|
if (status == NFS4_OK) {
|
||||||
|
nfs_to_basic_info(&info, &args->basic_info);
|
||||||
|
nfs_to_standard_info(&info, &args->std_info);
|
||||||
|
state->do_close = 1;
|
||||||
|
args->mode = info.mode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (status) {
|
||||||
|
dprintf(1, "%s failed with %s\n", (create == OPEN4_CREATE &&
|
||||||
|
(args->create_opts & FILE_DIRECTORY_FILE))?"nfs41_create":"nfs41_open",
|
||||||
|
nfs_error_string(status));
|
||||||
|
status = nfs_to_windows_error(status, ERROR_FILE_NOT_FOUND);
|
||||||
|
goto out_free_state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args->state = state;
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
out_free_state:
|
||||||
|
free(state);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
int marshall_open(unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
open_upcall_args *args = &upcall->args.open;
|
||||||
|
|
||||||
|
status = safe_write(&buffer, length, &args->basic_info, sizeof(args->basic_info));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_write(&buffer, length, &args->std_info, sizeof(args->std_info));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_write(&buffer, length, &args->state, sizeof(args->state));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_write(&buffer, length, &args->mode, sizeof(args->mode));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_write(&buffer, length, &args->changeattr, sizeof(args->changeattr));
|
||||||
|
dprintf(2, "NFS41_OPEN: passing open_state=0x%p mode %o changeattr 0x%x\n",
|
||||||
|
args->state, args->mode, args->changeattr);
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cancel_open(IN nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
int status = NFS4_OK;
|
||||||
|
open_upcall_args *args = &upcall->args.open;
|
||||||
|
nfs41_open_state *state = args->state;
|
||||||
|
|
||||||
|
dprintf(1, "--> cancel_open('%s')\n", args->path.path);
|
||||||
|
|
||||||
|
if (upcall->status)
|
||||||
|
goto out; /* if handle_open() failed, the state was already freed */
|
||||||
|
|
||||||
|
if (state->do_close) {
|
||||||
|
status = nfs41_close(state->session, state);
|
||||||
|
if (status)
|
||||||
|
dprintf(1, "cancel_open: nfs41_close() failed with %s\n",
|
||||||
|
nfs_error_string(status));
|
||||||
|
} else if (args->created) {
|
||||||
|
const nfs41_component *name = &state->file.name;
|
||||||
|
status = nfs41_remove(state->session, &state->parent, name);
|
||||||
|
if (status)
|
||||||
|
dprintf(1, "cancel_open: nfs41_remove() failed with %s\n",
|
||||||
|
nfs_error_string(status));
|
||||||
|
}
|
||||||
|
|
||||||
|
free_open_state(state->session, state);
|
||||||
|
out:
|
||||||
|
status = nfs_to_windows_error(status, ERROR_INTERNAL_ERROR);
|
||||||
|
dprintf(1, "<-- cancel_open() returning %d\n", status);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* NFS41_CLOSE */
|
||||||
|
int parse_close(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
close_upcall_args *args = &upcall->args.close;
|
||||||
|
|
||||||
|
status = safe_read(&buffer, &length, &args->root, sizeof(HANDLE));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->state, sizeof(nfs41_open_state *));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->remove, sizeof(BOOLEAN));
|
||||||
|
if (status) goto out;
|
||||||
|
if (args->remove) {
|
||||||
|
ZeroMemory(&args->path, sizeof(nfs41_abs_path));
|
||||||
|
status = get_abs_path(&buffer, &length, &args->path);
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->renamed, sizeof(BOOLEAN));
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
if (status)
|
||||||
|
eprintf("parsing NFS41_CLOSE failed with %d\n", status);
|
||||||
|
else
|
||||||
|
dprintf(1, "parsing NFS41_CLOSE: close root=0x%p "
|
||||||
|
"open_state=0x%p remove=%d renamed=%d filename='%s'\n",
|
||||||
|
args->root, args->state, args->remove, args->renamed,
|
||||||
|
args->remove ? args->path.path : "");
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int handle_close(nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
int status = NFS4_OK, rm_status = NFS4_OK;
|
||||||
|
close_upcall_args *args = &upcall->args.close;
|
||||||
|
nfs41_open_state *state = args->state;
|
||||||
|
|
||||||
|
/* return associated file layouts if necessary */
|
||||||
|
if (state->type == NF4REG)
|
||||||
|
pnfs_open_state_close(state->session, state, args->remove);
|
||||||
|
|
||||||
|
if (args->remove) {
|
||||||
|
nfs41_component *name = &state->file.name;
|
||||||
|
|
||||||
|
if (args->renamed) {
|
||||||
|
dprintf(1, "removing a renamed file %s\n", name->name);
|
||||||
|
create_silly_rename(&state->path, &state->file.fh, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
dprintf(1, "calling nfs41_remove for %s\n", name->name);
|
||||||
|
rm_status = nfs41_remove(state->session, &state->parent, name);
|
||||||
|
if (rm_status) {
|
||||||
|
dprintf(1, "nfs41_remove() failed with error %s.\n",
|
||||||
|
nfs_error_string(rm_status));
|
||||||
|
rm_status = nfs_to_windows_error(rm_status, ERROR_INTERNAL_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->do_close) {
|
||||||
|
status = nfs41_close(state->session, state);
|
||||||
|
if (status) {
|
||||||
|
dprintf(1, "nfs41_close() failed with error %s.\n",
|
||||||
|
nfs_error_string(status));
|
||||||
|
status = nfs_to_windows_error(status, ERROR_INTERNAL_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args->state->type == NF4REG || !args->remove)
|
||||||
|
free_open_state(state->session, state);
|
||||||
|
if (status || !rm_status)
|
||||||
|
return status;
|
||||||
|
else
|
||||||
|
return rm_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int marshall_close(unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
352
daemon/pnfs.h
Normal file
352
daemon/pnfs.h
Normal file
|
|
@ -0,0 +1,352 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __PNFS_H__
|
||||||
|
#define __PNFS_H__
|
||||||
|
|
||||||
|
#include "nfs41_types.h"
|
||||||
|
#include "list.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* preprocessor options */
|
||||||
|
#ifndef PNFS_DISABLE
|
||||||
|
|
||||||
|
# ifndef PNFS_DISABLE_READ
|
||||||
|
# define PNFS_ENABLE_READ
|
||||||
|
# endif
|
||||||
|
# ifndef PNFS_DISABLE_WRITE
|
||||||
|
# define PNFS_ENABLE_WRITE
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# define PNFS_THREADING
|
||||||
|
# define PNFS_THREAD_BY_SERVER
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* forward declarations from nfs41.h */
|
||||||
|
struct __nfs41_client;
|
||||||
|
struct __nfs41_session;
|
||||||
|
struct __nfs41_open_state;
|
||||||
|
struct __nfs41_root;
|
||||||
|
|
||||||
|
|
||||||
|
/* pnfs error values, in order of increasing severity */
|
||||||
|
enum pnfs_status {
|
||||||
|
PNFS_SUCCESS = 0,
|
||||||
|
PNFS_PENDING,
|
||||||
|
PNFS_READ_EOF,
|
||||||
|
PNFSERR_NOT_SUPPORTED,
|
||||||
|
PNFSERR_NOT_CONNECTED,
|
||||||
|
PNFSERR_IO,
|
||||||
|
PNFSERR_NO_DEVICE,
|
||||||
|
PNFSERR_NO_LAYOUT,
|
||||||
|
PNFSERR_INVALID_FH_LIST,
|
||||||
|
PNFSERR_INVALID_DS_INDEX,
|
||||||
|
PNFSERR_RESOURCES,
|
||||||
|
PNFSERR_LAYOUT_RECALLED,
|
||||||
|
PNFSERR_LAYOUT_CHANGED,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum pnfs_layout_type {
|
||||||
|
PNFS_LAYOUTTYPE_FILE = 1,
|
||||||
|
PNFS_LAYOUTTYPE_OBJECT = 2,
|
||||||
|
PNFS_LAYOUTTYPE_BLOCK = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
enum pnfs_iomode {
|
||||||
|
PNFS_IOMODE_READ = 0x1,
|
||||||
|
PNFS_IOMODE_RW = 0x2,
|
||||||
|
PNFS_IOMODE_ANY = PNFS_IOMODE_READ | PNFS_IOMODE_RW
|
||||||
|
};
|
||||||
|
|
||||||
|
enum pnfs_layout_status {
|
||||||
|
/* LAYOUTGET was successful, and the layout has not been returned or
|
||||||
|
* otherwise revoked by the server */
|
||||||
|
PNFS_LAYOUT_GRANTED = 0x01,
|
||||||
|
/* GETDEVICEINFO was successful, and we have a valid 'device' pointer */
|
||||||
|
PNFS_LAYOUT_HAS_DEVICE = 0x02,
|
||||||
|
/* CB_LAYOUTRECALL indicated that the server has recalled this layout,
|
||||||
|
* and it should be returned on completion of any pending io */
|
||||||
|
PNFS_LAYOUT_RECALLED = 0x04,
|
||||||
|
/* CB_LAYOUTRECALL indicated that the layout is changing, and "the client
|
||||||
|
* SHOULD NOT write and commit modified data to the storage devices!" */
|
||||||
|
PNFS_LAYOUT_CHANGED = 0x08,
|
||||||
|
|
||||||
|
/* a LAYOUTGET error indicated that this layout will never be granted */
|
||||||
|
PNFS_LAYOUT_UNAVAILABLE = 0x10,
|
||||||
|
/* LAYOUTGET returned BADIOMODE, so a RW layout will never be granted */
|
||||||
|
PNFS_LAYOUT_NOT_RW = 0x20,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum pnfs_return_type {
|
||||||
|
PNFS_RETURN_FILE = 1,
|
||||||
|
PNFS_RETURN_FSID = 2,
|
||||||
|
PNFS_RETURN_ALL = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NFL4_UFLG_MASK 0x0000003F
|
||||||
|
#define NFL4_UFLG_DENSE 0x00000001
|
||||||
|
#define NFL4_UFLG_COMMIT_THRU_MDS 0x00000002
|
||||||
|
#define NFL4_UFLG_STRIPE_UNIT_SIZE_MASK 0xFFFFFFC0
|
||||||
|
|
||||||
|
#define PNFS_DEVICEID_SIZE 16
|
||||||
|
|
||||||
|
|
||||||
|
/* device */
|
||||||
|
typedef struct __pnfs_device {
|
||||||
|
unsigned char deviceid[PNFS_DEVICEID_SIZE];
|
||||||
|
enum pnfs_layout_type type;
|
||||||
|
} pnfs_device;
|
||||||
|
|
||||||
|
typedef struct __pnfs_stripe_indices {
|
||||||
|
uint32_t count;
|
||||||
|
uint32_t *arr;
|
||||||
|
} pnfs_stripe_indices;
|
||||||
|
|
||||||
|
typedef struct __pnfs_data_server {
|
||||||
|
struct __nfs41_client *client;
|
||||||
|
multi_addr4 addrs;
|
||||||
|
SRWLOCK lock;
|
||||||
|
} pnfs_data_server;
|
||||||
|
|
||||||
|
typedef struct __pnfs_data_server_list {
|
||||||
|
uint32_t count;
|
||||||
|
pnfs_data_server *arr;
|
||||||
|
} pnfs_data_server_list;
|
||||||
|
|
||||||
|
typedef struct __pnfs_file_device {
|
||||||
|
pnfs_device device;
|
||||||
|
pnfs_stripe_indices stripes;
|
||||||
|
pnfs_data_server_list servers;
|
||||||
|
struct list_entry entry; /* position in nfs41_client.devices */
|
||||||
|
SRWLOCK lock;
|
||||||
|
} pnfs_file_device;
|
||||||
|
|
||||||
|
|
||||||
|
/* layout */
|
||||||
|
typedef struct __pnfs_layout {
|
||||||
|
stateid4 state;
|
||||||
|
uint64_t offset;
|
||||||
|
uint64_t length;
|
||||||
|
enum pnfs_layout_type type;
|
||||||
|
enum pnfs_iomode iomode;
|
||||||
|
enum pnfs_layout_status status;
|
||||||
|
bool_t return_on_close;
|
||||||
|
uint32_t io_count; /* number of pending io operations */
|
||||||
|
SRWLOCK lock;
|
||||||
|
} pnfs_layout;
|
||||||
|
|
||||||
|
typedef struct __pnfs_file_layout_handles {
|
||||||
|
uint32_t count;
|
||||||
|
nfs41_path_fh *arr;
|
||||||
|
} pnfs_file_layout_handles;
|
||||||
|
|
||||||
|
typedef struct __pnfs_file_layout {
|
||||||
|
pnfs_layout layout;
|
||||||
|
pnfs_file_layout_handles filehandles;
|
||||||
|
unsigned char deviceid[PNFS_DEVICEID_SIZE];
|
||||||
|
struct list_entry entry; /* position in nfs41_client.layouts */
|
||||||
|
pnfs_file_device *device;
|
||||||
|
nfs41_fh meta_fh;
|
||||||
|
uint64_t pattern_offset;
|
||||||
|
uint32_t first_index;
|
||||||
|
uint32_t util;
|
||||||
|
} pnfs_file_layout;
|
||||||
|
|
||||||
|
typedef struct __pnfs_layout_recall {
|
||||||
|
enum pnfs_layout_type type;
|
||||||
|
enum pnfs_iomode iomode;
|
||||||
|
bool_t changed;
|
||||||
|
|
||||||
|
enum pnfs_return_type recall;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
nfs41_fh fh;
|
||||||
|
stateid4 stateid;
|
||||||
|
} file;
|
||||||
|
nfs41_fsid fsid;
|
||||||
|
} args;
|
||||||
|
} pnfs_layout_recall;
|
||||||
|
|
||||||
|
|
||||||
|
/* io */
|
||||||
|
typedef struct __pnfs_io_pattern {
|
||||||
|
struct __pnfs_io_thread *threads;
|
||||||
|
struct __nfs41_root *root;
|
||||||
|
nfs41_path_fh *meta_file;
|
||||||
|
stateid4 *stateid;
|
||||||
|
pnfs_file_layout *layout;
|
||||||
|
unsigned char *buffer;
|
||||||
|
uint64_t offset_start;
|
||||||
|
uint64_t offset_end;
|
||||||
|
uint32_t count;
|
||||||
|
uint32_t default_lease;
|
||||||
|
} pnfs_io_pattern;
|
||||||
|
|
||||||
|
typedef struct __pnfs_io_thread {
|
||||||
|
pnfs_io_pattern *pattern;
|
||||||
|
uint64_t offset;
|
||||||
|
uint64_t offset_end;
|
||||||
|
uint32_t id;
|
||||||
|
enum stable_how4 stable;
|
||||||
|
} pnfs_io_thread;
|
||||||
|
|
||||||
|
typedef struct __pnfs_io_unit {
|
||||||
|
nfs41_path_fh *file;
|
||||||
|
unsigned char *buffer;
|
||||||
|
uint64_t offset;
|
||||||
|
uint64_t length;
|
||||||
|
uint32_t stripeid;
|
||||||
|
uint32_t serverid;
|
||||||
|
} pnfs_io_unit;
|
||||||
|
|
||||||
|
typedef uint32_t (WINAPI *pnfs_io_thread_fn)(void*);
|
||||||
|
|
||||||
|
|
||||||
|
/* pnfs_layout.c */
|
||||||
|
struct pnfs_file_layout_list;
|
||||||
|
struct cb_layoutrecall_args;
|
||||||
|
|
||||||
|
enum pnfs_status pnfs_file_layout_list_create(
|
||||||
|
OUT struct pnfs_file_layout_list **layouts_out);
|
||||||
|
|
||||||
|
void pnfs_file_layout_list_free(
|
||||||
|
IN struct pnfs_file_layout_list *layouts);
|
||||||
|
|
||||||
|
enum pnfs_status pnfs_open_state_layout(
|
||||||
|
IN struct pnfs_file_layout_list *layouts,
|
||||||
|
IN struct __nfs41_session *session,
|
||||||
|
IN struct __nfs41_open_state *state,
|
||||||
|
IN enum pnfs_iomode iomode,
|
||||||
|
IN uint64_t offset,
|
||||||
|
IN uint64_t length,
|
||||||
|
OUT pnfs_file_layout **layout_out);
|
||||||
|
|
||||||
|
void pnfs_open_state_close(
|
||||||
|
IN struct __nfs41_session *session,
|
||||||
|
IN struct __nfs41_open_state *state,
|
||||||
|
IN bool_t remove);
|
||||||
|
|
||||||
|
enum pnfs_status pnfs_file_layout_recall(
|
||||||
|
IN struct pnfs_file_layout_list *layouts,
|
||||||
|
IN const struct cb_layoutrecall_args *recall);
|
||||||
|
|
||||||
|
enum pnfs_status pnfs_layout_io_start(
|
||||||
|
IN pnfs_layout *layout);
|
||||||
|
|
||||||
|
void pnfs_layout_io_finished(
|
||||||
|
IN pnfs_layout *layout);
|
||||||
|
|
||||||
|
|
||||||
|
__inline int is_dense(
|
||||||
|
IN const pnfs_file_layout *layout)
|
||||||
|
{
|
||||||
|
return (layout->util & NFL4_UFLG_DENSE) != 0;
|
||||||
|
}
|
||||||
|
__inline int should_commit_to_mds(
|
||||||
|
IN const pnfs_file_layout *layout)
|
||||||
|
{
|
||||||
|
return (layout->util & NFL4_UFLG_COMMIT_THRU_MDS) != 0;
|
||||||
|
}
|
||||||
|
__inline uint32_t layout_unit_size(
|
||||||
|
IN const pnfs_file_layout *layout)
|
||||||
|
{
|
||||||
|
return layout->util & NFL4_UFLG_STRIPE_UNIT_SIZE_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* pnfs_device.c */
|
||||||
|
struct pnfs_file_device_list;
|
||||||
|
|
||||||
|
enum pnfs_status pnfs_file_device_list_create(
|
||||||
|
OUT struct pnfs_file_device_list **devices_out);
|
||||||
|
|
||||||
|
void pnfs_file_device_list_free(
|
||||||
|
IN struct pnfs_file_device_list *devices);
|
||||||
|
|
||||||
|
enum pnfs_status pnfs_file_device_get(
|
||||||
|
IN struct __nfs41_session *session,
|
||||||
|
IN struct pnfs_file_device_list *devices,
|
||||||
|
IN unsigned char *deviceid,
|
||||||
|
OUT pnfs_file_device **device_out);
|
||||||
|
|
||||||
|
enum pnfs_status pnfs_data_server_client(
|
||||||
|
IN struct __nfs41_root *root,
|
||||||
|
IN pnfs_data_server *server,
|
||||||
|
IN uint32_t default_lease,
|
||||||
|
OUT struct __nfs41_client **client_out);
|
||||||
|
|
||||||
|
enum pnfs_status pnfs_file_device_io_unit(
|
||||||
|
IN pnfs_io_pattern *pattern,
|
||||||
|
IN uint64_t offset,
|
||||||
|
OUT pnfs_io_unit *io);
|
||||||
|
|
||||||
|
|
||||||
|
__inline uint64_t stripe_unit_number(
|
||||||
|
IN pnfs_file_layout *layout,
|
||||||
|
IN uint64_t offset,
|
||||||
|
IN uint32_t unit_size)
|
||||||
|
{
|
||||||
|
const uint64_t relative_offset = offset - layout->pattern_offset;
|
||||||
|
return relative_offset / unit_size;
|
||||||
|
}
|
||||||
|
__inline uint32_t stripe_index(
|
||||||
|
IN pnfs_file_layout *layout,
|
||||||
|
IN uint64_t sui,
|
||||||
|
IN uint32_t stripe_count)
|
||||||
|
{
|
||||||
|
return (sui + layout->first_index) % stripe_count;
|
||||||
|
}
|
||||||
|
__inline uint32_t data_server_index(
|
||||||
|
IN pnfs_file_device *device,
|
||||||
|
IN uint32_t stripeid)
|
||||||
|
{
|
||||||
|
return device->stripes.arr[stripeid];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* pnfs_io.c */
|
||||||
|
enum pnfs_status pnfs_read(
|
||||||
|
IN struct __nfs41_root *root,
|
||||||
|
IN struct __nfs41_session *session,
|
||||||
|
IN nfs41_path_fh *file,
|
||||||
|
IN stateid4 *stateid,
|
||||||
|
IN pnfs_file_layout *layout,
|
||||||
|
IN uint64_t offset,
|
||||||
|
IN uint64_t length,
|
||||||
|
OUT unsigned char *buffer_out,
|
||||||
|
OUT ULONG *len_out);
|
||||||
|
|
||||||
|
enum pnfs_status pnfs_write(
|
||||||
|
IN struct __nfs41_root *root,
|
||||||
|
IN struct __nfs41_session *session,
|
||||||
|
IN nfs41_path_fh *file,
|
||||||
|
IN stateid4 *stateid,
|
||||||
|
IN pnfs_file_layout *layout,
|
||||||
|
IN uint64_t offset,
|
||||||
|
IN uint64_t length,
|
||||||
|
IN unsigned char *buffer,
|
||||||
|
OUT ULONG *len_out);
|
||||||
|
|
||||||
|
#endif /* !__PNFS_H__ */
|
||||||
125
daemon/pnfs_debug.c
Normal file
125
daemon/pnfs_debug.c
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <strsafe.h>
|
||||||
|
#include "pnfs.h"
|
||||||
|
#include "daemon_debug.h"
|
||||||
|
|
||||||
|
|
||||||
|
const char* pnfs_error_string(enum pnfs_status status)
|
||||||
|
{
|
||||||
|
switch (status) {
|
||||||
|
case PNFS_SUCCESS: return "PNFS_SUCCESS";
|
||||||
|
case PNFS_PENDING: return "PNFS_PENDING";
|
||||||
|
case PNFS_READ_EOF: return "PNFS_READ_EOF";
|
||||||
|
case PNFSERR_NOT_SUPPORTED: return "PNFSERR_NOT_SUPPORTED";
|
||||||
|
case PNFSERR_NOT_CONNECTED: return "PNFSERR_NOT_CONNECTED";
|
||||||
|
case PNFSERR_IO: return "PNFSERR_IO";
|
||||||
|
case PNFSERR_NO_DEVICE: return "PNFSERR_NO_DEVICE";
|
||||||
|
case PNFSERR_NO_LAYOUT: return "PNFSERR_NO_LAYOUT";
|
||||||
|
case PNFSERR_INVALID_FH_LIST: return "PNFSERR_INVALID_FH_LIST";
|
||||||
|
case PNFSERR_INVALID_DS_INDEX: return "PNFSERR_INVALID_DS_INDEX";
|
||||||
|
case PNFSERR_RESOURCES: return "PNFSERR_RESOURCES";
|
||||||
|
case PNFSERR_LAYOUT_RECALLED: return "PNFSERR_LAYOUT_RECALLED";
|
||||||
|
case PNFSERR_LAYOUT_CHANGED: return "PNFSERR_LAYOUT_CHANGED";
|
||||||
|
default: return "Invalid pnfs status";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* pnfs_layout_type_string(enum pnfs_layout_type type)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case PNFS_LAYOUTTYPE_FILE: return "PNFS_LAYOUTTYPE_FILE";
|
||||||
|
case PNFS_LAYOUTTYPE_OBJECT: return "PNFS_LAYOUTTYPE_OBJECT";
|
||||||
|
case PNFS_LAYOUTTYPE_BLOCK: return "PNFS_LAYOUTTYPE_BLOCK";
|
||||||
|
default: return "Invalid layout type";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* pnfs_iomode_string(enum pnfs_iomode iomode)
|
||||||
|
{
|
||||||
|
switch (iomode) {
|
||||||
|
case PNFS_IOMODE_READ: return "PNFS_IOMODE_READ";
|
||||||
|
case PNFS_IOMODE_RW: return "PNFS_IOMODE_RW";
|
||||||
|
case PNFS_IOMODE_ANY: return "PNFS_IOMODE_ANY";
|
||||||
|
default: return "Invalid io mode";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dprint_deviceid(
|
||||||
|
IN int level,
|
||||||
|
IN const char *title,
|
||||||
|
IN const unsigned char *deviceid)
|
||||||
|
{
|
||||||
|
/* deviceid is 16 bytes, so print it as 4 uints */
|
||||||
|
uint32_t *p = (uint32_t*)deviceid;
|
||||||
|
dprintf(level, "%s%08X.%08X.%08X.%08X\n",
|
||||||
|
title, htonl(p[0]), htonl(p[1]), htonl(p[2]), htonl(p[3]));
|
||||||
|
}
|
||||||
|
|
||||||
|
void dprint_layout(
|
||||||
|
IN int level,
|
||||||
|
IN const pnfs_file_layout *layout)
|
||||||
|
{
|
||||||
|
dprintf(level, " type: %s\n", pnfs_layout_type_string(layout->layout.type));
|
||||||
|
dprintf(level, " iomode: %s\n", pnfs_iomode_string(layout->layout.iomode));
|
||||||
|
dprint_deviceid(level, " deviceid: ", layout->deviceid);
|
||||||
|
dprintf(level, " offset: %llu\n", layout->layout.offset);
|
||||||
|
dprintf(level, " length: %llu\n", layout->layout.length);
|
||||||
|
dprintf(level, " pattern_offset: %llu\n", layout->pattern_offset);
|
||||||
|
dprintf(level, " first_index: %u\n", layout->first_index);
|
||||||
|
dprintf(level, " dense: %u\n", is_dense(layout));
|
||||||
|
dprintf(level, " commit_to_mds: %u\n", should_commit_to_mds(layout));
|
||||||
|
dprintf(level, " stripe_unit_size: %u\n", layout_unit_size(layout));
|
||||||
|
dprintf(level, " file handles: %u\n", layout->filehandles.count);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MULTI_ADDR_BUFFER_LEN \
|
||||||
|
(NFS41_ADDRS_PER_SERVER*(NFS41_UNIVERSAL_ADDR_LEN+1)+1)
|
||||||
|
|
||||||
|
static void dprint_multi_addr(
|
||||||
|
IN int level,
|
||||||
|
IN uint32_t index,
|
||||||
|
IN const multi_addr4 *addrs)
|
||||||
|
{
|
||||||
|
char buffer[MULTI_ADDR_BUFFER_LEN] = "";
|
||||||
|
uint32_t i;
|
||||||
|
for (i = 0; i < addrs->count; i++) {
|
||||||
|
StringCchCatA(buffer, MULTI_ADDR_BUFFER_LEN, addrs->arr[i].uaddr);
|
||||||
|
StringCchCatA(buffer, MULTI_ADDR_BUFFER_LEN, " ");
|
||||||
|
}
|
||||||
|
dprintf(level, " servers[%d]: [ %s]\n", index, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dprint_device(
|
||||||
|
IN int level,
|
||||||
|
IN const pnfs_file_device *device)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
dprint_deviceid(level, " deviceid: ", device->device.deviceid);
|
||||||
|
dprintf(level, " type: %s\n", pnfs_layout_type_string(device->device.type));
|
||||||
|
dprintf(level, " stripes: %u\n", device->stripes.count);
|
||||||
|
for (i = 0; i < device->servers.count; i++)
|
||||||
|
dprint_multi_addr(level, i, &device->servers.arr[i].addrs);
|
||||||
|
}
|
||||||
376
daemon/pnfs_device.c
Normal file
376
daemon/pnfs_device.c
Normal file
|
|
@ -0,0 +1,376 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <strsafe.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "nfs41_ops.h"
|
||||||
|
#include "daemon_debug.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define FDLVL 2 /* dprintf level for file device logging */
|
||||||
|
|
||||||
|
|
||||||
|
/* pnfs_file_device_list */
|
||||||
|
struct pnfs_file_device_list {
|
||||||
|
struct list_entry head;
|
||||||
|
CRITICAL_SECTION lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define device_entry(pos) list_container(pos, pnfs_file_device, entry)
|
||||||
|
|
||||||
|
|
||||||
|
static enum pnfs_status file_device_create(
|
||||||
|
IN const unsigned char *deviceid,
|
||||||
|
OUT pnfs_file_device **device_out)
|
||||||
|
{
|
||||||
|
enum pnfs_status status = PNFS_SUCCESS;
|
||||||
|
pnfs_file_device *device;
|
||||||
|
|
||||||
|
device = calloc(1, sizeof(pnfs_file_device));
|
||||||
|
if (device == NULL) {
|
||||||
|
status = PNFSERR_RESOURCES;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(device->device.deviceid, deviceid, PNFS_DEVICEID_SIZE);
|
||||||
|
InitializeSRWLock(&device->lock);
|
||||||
|
*device_out = device;
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void file_device_free(
|
||||||
|
IN pnfs_file_device *device)
|
||||||
|
{
|
||||||
|
free(device->servers.arr);
|
||||||
|
free(device->stripes.arr);
|
||||||
|
free(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int deviceid_compare(
|
||||||
|
const struct list_entry *entry,
|
||||||
|
const void *deviceid)
|
||||||
|
{
|
||||||
|
const pnfs_file_device *device = device_entry(entry);
|
||||||
|
return memcmp(device->device.deviceid, deviceid, PNFS_DEVICEID_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum pnfs_status file_device_entry_find(
|
||||||
|
IN struct pnfs_file_device_list *devices,
|
||||||
|
IN const unsigned char *deviceid,
|
||||||
|
OUT struct list_entry **entry_out)
|
||||||
|
{
|
||||||
|
*entry_out = list_search(&devices->head, deviceid, deviceid_compare);
|
||||||
|
return *entry_out ? PNFS_SUCCESS : PNFSERR_NO_DEVICE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum pnfs_status file_device_find_or_create(
|
||||||
|
IN const unsigned char *deviceid,
|
||||||
|
IN struct pnfs_file_device_list *devices,
|
||||||
|
OUT pnfs_file_device **device_out)
|
||||||
|
{
|
||||||
|
struct list_entry *entry;
|
||||||
|
enum pnfs_status status;
|
||||||
|
|
||||||
|
dprintf(FDLVL, "--> pnfs_file_device_find_or_create()\n");
|
||||||
|
|
||||||
|
EnterCriticalSection(&devices->lock);
|
||||||
|
|
||||||
|
/* search for an existing device */
|
||||||
|
status = file_device_entry_find(devices, deviceid, &entry);
|
||||||
|
if (status) {
|
||||||
|
/* create a new device */
|
||||||
|
pnfs_file_device *device;
|
||||||
|
status = file_device_create(deviceid, &device);
|
||||||
|
if (status == PNFS_SUCCESS) {
|
||||||
|
/* add it to the list */
|
||||||
|
list_add_tail(&devices->head, &device->entry);
|
||||||
|
*device_out = device;
|
||||||
|
|
||||||
|
dprintf(FDLVL, "<-- pnfs_file_device_find_or_create() "
|
||||||
|
"returning new device %p\n", device);
|
||||||
|
} else {
|
||||||
|
dprintf(FDLVL, "<-- pnfs_file_device_find_or_create() "
|
||||||
|
"returning %s\n", pnfs_error_string(status));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*device_out = device_entry(entry);
|
||||||
|
|
||||||
|
dprintf(FDLVL, "<-- pnfs_file_device_find_or_create() "
|
||||||
|
"returning existing device %p\n", *device_out);
|
||||||
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection(&devices->lock);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enum pnfs_status pnfs_file_device_list_create(
|
||||||
|
OUT struct pnfs_file_device_list **devices_out)
|
||||||
|
{
|
||||||
|
enum pnfs_status status = PNFS_SUCCESS;
|
||||||
|
struct pnfs_file_device_list *devices;
|
||||||
|
|
||||||
|
devices = calloc(1, sizeof(struct pnfs_file_device_list));
|
||||||
|
if (devices == NULL) {
|
||||||
|
status = PNFSERR_RESOURCES;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
list_init(&devices->head);
|
||||||
|
InitializeCriticalSection(&devices->lock);
|
||||||
|
|
||||||
|
*devices_out = devices;
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pnfs_file_device_list_free(
|
||||||
|
IN struct pnfs_file_device_list *devices)
|
||||||
|
{
|
||||||
|
struct list_entry *entry, *tmp;
|
||||||
|
|
||||||
|
EnterCriticalSection(&devices->lock);
|
||||||
|
|
||||||
|
list_for_each_tmp(entry, tmp, &devices->head)
|
||||||
|
file_device_free(device_entry(entry));
|
||||||
|
|
||||||
|
LeaveCriticalSection(&devices->lock);
|
||||||
|
|
||||||
|
free(devices);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* pnfs_file_device */
|
||||||
|
static enum pnfs_status file_device_status(
|
||||||
|
IN pnfs_file_device *device)
|
||||||
|
{
|
||||||
|
return device->device.type == 0 ? PNFS_PENDING : PNFS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum pnfs_status pnfs_file_device_get(
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN struct pnfs_file_device_list *devices,
|
||||||
|
IN unsigned char *deviceid,
|
||||||
|
OUT pnfs_file_device **device_out)
|
||||||
|
{
|
||||||
|
pnfs_file_device *device;
|
||||||
|
enum pnfs_status status;
|
||||||
|
enum nfsstat4 nfsstat;
|
||||||
|
|
||||||
|
dprintf(FDLVL, "--> pnfs_file_device_get()\n");
|
||||||
|
|
||||||
|
status = file_device_find_or_create(deviceid, devices, &device);
|
||||||
|
if (status)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
AcquireSRWLockShared(&device->lock);
|
||||||
|
status = file_device_status(device);
|
||||||
|
ReleaseSRWLockShared(&device->lock);
|
||||||
|
|
||||||
|
if (status == PNFS_PENDING) {
|
||||||
|
AcquireSRWLockExclusive(&device->lock);
|
||||||
|
|
||||||
|
status = file_device_status(device);
|
||||||
|
if (status == PNFS_PENDING) {
|
||||||
|
nfsstat = pnfs_rpc_getdeviceinfo(session, deviceid, device);
|
||||||
|
if (nfsstat == NFS4_OK) {
|
||||||
|
status = PNFS_SUCCESS;
|
||||||
|
|
||||||
|
dprintf(FDLVL, "Received device info:\n");
|
||||||
|
dprint_device(FDLVL, device);
|
||||||
|
} else {
|
||||||
|
status = PNFSERR_NO_DEVICE;
|
||||||
|
|
||||||
|
eprintf("pnfs_rpc_getdeviceinfo() failed with %s\n",
|
||||||
|
nfs_error_string(nfsstat));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseSRWLockExclusive(&device->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
*device_out = device;
|
||||||
|
out:
|
||||||
|
dprintf(FDLVL, "<-- pnfs_file_device_get() returning %s\n",
|
||||||
|
pnfs_error_string(status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum pnfs_status data_client_status(
|
||||||
|
IN pnfs_data_server *server,
|
||||||
|
OUT nfs41_client **client_out)
|
||||||
|
{
|
||||||
|
enum pnfs_status status = PNFSERR_NOT_CONNECTED;
|
||||||
|
|
||||||
|
if (server->client) {
|
||||||
|
dprintf(FDLVL, "pnfs_data_server_client() returning "
|
||||||
|
"existing client %llu\n", server->client->clnt_id);
|
||||||
|
*client_out = server->client;
|
||||||
|
status = PNFS_SUCCESS;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum pnfs_status pnfs_data_server_client(
|
||||||
|
IN nfs41_root *root,
|
||||||
|
IN pnfs_data_server *server,
|
||||||
|
IN uint32_t default_lease,
|
||||||
|
OUT nfs41_client **client_out)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
enum pnfs_status pnfsstat;
|
||||||
|
|
||||||
|
dprintf(FDLVL, "--> pnfs_data_server_client('%s')\n",
|
||||||
|
server->addrs.arr[0].uaddr);
|
||||||
|
|
||||||
|
/* if we've already created the client, return it */
|
||||||
|
AcquireSRWLockShared(&server->lock);
|
||||||
|
pnfsstat = data_client_status(server, client_out);
|
||||||
|
ReleaseSRWLockShared(&server->lock);
|
||||||
|
|
||||||
|
if (pnfsstat) {
|
||||||
|
AcquireSRWLockExclusive(&server->lock);
|
||||||
|
|
||||||
|
pnfsstat = data_client_status(server, client_out);
|
||||||
|
if (pnfsstat) {
|
||||||
|
status = nfs41_root_mount_addrs(root, &server->addrs,
|
||||||
|
1, default_lease, &server->client);
|
||||||
|
if (status) {
|
||||||
|
dprintf(FDLVL, "data_client_create('%s') failed with %d\n",
|
||||||
|
server->addrs.arr[0].uaddr, status);
|
||||||
|
} else {
|
||||||
|
*client_out = server->client;
|
||||||
|
pnfsstat = PNFS_SUCCESS;
|
||||||
|
|
||||||
|
dprintf(FDLVL, "pnfs_data_server_client() returning "
|
||||||
|
"new client %llu\n", server->client->clnt_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseSRWLockExclusive(&server->lock);
|
||||||
|
}
|
||||||
|
return pnfsstat;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 13.4.2. Interpreting the File Layout Using Sparse Packing
|
||||||
|
* http://tools.ietf.org/html/rfc5661#section-13.4.2 */
|
||||||
|
|
||||||
|
static enum pnfs_status get_sparse_fh(
|
||||||
|
IN pnfs_io_pattern *pattern,
|
||||||
|
IN uint32_t stripeid,
|
||||||
|
OUT nfs41_path_fh **file_out)
|
||||||
|
{
|
||||||
|
pnfs_file_layout *layout = pattern->layout;
|
||||||
|
const uint32_t filehandle_count = layout->filehandles.count;
|
||||||
|
const uint32_t server_count = layout->device->servers.count;
|
||||||
|
enum pnfs_status status = PNFS_SUCCESS;
|
||||||
|
|
||||||
|
if (filehandle_count == server_count) {
|
||||||
|
const uint32_t serverid = data_server_index(layout->device, stripeid);
|
||||||
|
*file_out = &layout->filehandles.arr[serverid];
|
||||||
|
} else if (filehandle_count == 1) {
|
||||||
|
*file_out = &layout->filehandles.arr[0];
|
||||||
|
} else if (filehandle_count == 0) {
|
||||||
|
*file_out = pattern->meta_file;
|
||||||
|
} else {
|
||||||
|
eprintf("invalid sparse layout! has %u file handles "
|
||||||
|
"and %u servers\n", filehandle_count, server_count);
|
||||||
|
status = PNFSERR_INVALID_FH_LIST;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 13.4.3. Interpreting the File Layout Using Dense Packing
|
||||||
|
* http://tools.ietf.org/html/rfc5661#section-13.4.3 */
|
||||||
|
|
||||||
|
static enum pnfs_status get_dense_fh(
|
||||||
|
IN pnfs_io_pattern *pattern,
|
||||||
|
IN uint32_t stripeid,
|
||||||
|
OUT nfs41_path_fh **file_out)
|
||||||
|
{
|
||||||
|
pnfs_file_layout *layout = pattern->layout;
|
||||||
|
const uint32_t filehandle_count = layout->filehandles.count;
|
||||||
|
const uint32_t stripe_count = layout->device->stripes.count;
|
||||||
|
enum pnfs_status status = PNFS_SUCCESS;
|
||||||
|
|
||||||
|
if (filehandle_count == stripe_count) {
|
||||||
|
*file_out = &layout->filehandles.arr[stripeid];
|
||||||
|
} else {
|
||||||
|
eprintf("invalid dense layout! has %u file handles "
|
||||||
|
"and %u stripes\n", filehandle_count, stripe_count);
|
||||||
|
status = PNFSERR_INVALID_FH_LIST;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline uint64_t positive_remainder(
|
||||||
|
IN uint64_t dividend,
|
||||||
|
IN uint32_t divisor)
|
||||||
|
{
|
||||||
|
const uint64_t remainder = dividend % divisor;
|
||||||
|
return remainder < divisor ? remainder : remainder + divisor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 13.4.4. Sparse and Dense Stripe Unit Packing
|
||||||
|
* http://tools.ietf.org/html/rfc5661#section-13.4.4 */
|
||||||
|
|
||||||
|
enum pnfs_status pnfs_file_device_io_unit(
|
||||||
|
IN pnfs_io_pattern *pattern,
|
||||||
|
IN uint64_t offset,
|
||||||
|
OUT pnfs_io_unit *io)
|
||||||
|
{
|
||||||
|
pnfs_file_layout *layout = pattern->layout;
|
||||||
|
enum pnfs_status status = PNFS_SUCCESS;
|
||||||
|
|
||||||
|
const uint32_t unit_size = layout_unit_size(layout);
|
||||||
|
const uint32_t stripe_count = layout->device->stripes.count;
|
||||||
|
const uint64_t sui = stripe_unit_number(layout, offset, unit_size);
|
||||||
|
const uint64_t offset_end = layout->pattern_offset + unit_size * (sui + 1);
|
||||||
|
|
||||||
|
io->stripeid = stripe_index(layout, sui, stripe_count);
|
||||||
|
io->serverid = data_server_index(layout->device, io->stripeid);
|
||||||
|
|
||||||
|
if (is_dense(layout)) {
|
||||||
|
const uint64_t rel_offset = offset - layout->pattern_offset;
|
||||||
|
const uint64_t remainder = positive_remainder(rel_offset, unit_size);
|
||||||
|
const uint32_t stride = unit_size * stripe_count;
|
||||||
|
|
||||||
|
io->offset = (rel_offset / stride) * unit_size + remainder;
|
||||||
|
|
||||||
|
status = get_dense_fh(pattern, io->stripeid, &io->file);
|
||||||
|
} else {
|
||||||
|
io->offset = offset;
|
||||||
|
|
||||||
|
status = get_sparse_fh(pattern, io->stripeid, &io->file);
|
||||||
|
}
|
||||||
|
|
||||||
|
io->buffer = pattern->buffer + offset - pattern->offset_start;
|
||||||
|
io->length = offset_end - offset;
|
||||||
|
if (offset + io->length > pattern->offset_end)
|
||||||
|
io->length = pattern->offset_end - offset;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
565
daemon/pnfs_io.c
Normal file
565
daemon/pnfs_io.c
Normal file
|
|
@ -0,0 +1,565 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <process.h>
|
||||||
|
|
||||||
|
#include "nfs41_ops.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "daemon_debug.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define IOLVL 2 /* dprintf level for pnfs io logging */
|
||||||
|
|
||||||
|
|
||||||
|
static uint32_t io_unit_count(
|
||||||
|
const pnfs_file_layout *layout,
|
||||||
|
uint64_t length)
|
||||||
|
{
|
||||||
|
const uint32_t unit_size = layout_unit_size(layout);
|
||||||
|
return (uint32_t)(length / unit_size) + (length % unit_size ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum pnfs_status pattern_init(
|
||||||
|
IN pnfs_io_pattern *pattern,
|
||||||
|
IN nfs41_root *root,
|
||||||
|
IN nfs41_path_fh *meta_file,
|
||||||
|
IN stateid4 *stateid,
|
||||||
|
IN pnfs_file_layout *layout,
|
||||||
|
IN unsigned char *buffer,
|
||||||
|
IN uint64_t offset,
|
||||||
|
IN uint64_t length,
|
||||||
|
IN uint32_t default_lease)
|
||||||
|
{
|
||||||
|
#ifndef PNFS_THREAD_BY_SERVER
|
||||||
|
pnfs_io_unit io;
|
||||||
|
#endif
|
||||||
|
uint64_t pos;
|
||||||
|
uint32_t i;
|
||||||
|
enum pnfs_status status;
|
||||||
|
|
||||||
|
/* take a reference on the layout so we don't return it during io */
|
||||||
|
status = pnfs_layout_io_start(&layout->layout);
|
||||||
|
if (status)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
#ifdef PNFS_THREAD_BY_SERVER
|
||||||
|
pattern->count = layout->device->servers.count;
|
||||||
|
#else
|
||||||
|
pattern->count = io_unit_count(layout, length);
|
||||||
|
#endif
|
||||||
|
pattern->threads = calloc(pattern->count, sizeof(pnfs_io_thread));
|
||||||
|
if (pattern->threads == NULL) {
|
||||||
|
status = PNFSERR_RESOURCES;
|
||||||
|
free(pattern);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
pattern->root = root;
|
||||||
|
pattern->meta_file = meta_file;
|
||||||
|
pattern->stateid = stateid;
|
||||||
|
pattern->layout = layout;
|
||||||
|
pattern->buffer = buffer;
|
||||||
|
pattern->offset_start = offset;
|
||||||
|
pattern->offset_end = offset + length;
|
||||||
|
pattern->default_lease = default_lease;
|
||||||
|
|
||||||
|
pos = pattern->offset_start;
|
||||||
|
for (i = 0; i < pattern->count; i++) {
|
||||||
|
pattern->threads[i].pattern = pattern;
|
||||||
|
pattern->threads[i].stable = DATA_SYNC4;
|
||||||
|
#ifdef PNFS_THREAD_BY_SERVER
|
||||||
|
pattern->threads[i].offset = pattern->offset_start;
|
||||||
|
pattern->threads[i].offset_end = pattern->offset_end;
|
||||||
|
pattern->threads[i].id = i;
|
||||||
|
#else
|
||||||
|
pnfs_file_device_io_unit(pattern, pos, &io);
|
||||||
|
pattern->threads[i].offset = pos;
|
||||||
|
pattern->threads[i].offset_end = pos += io.length;
|
||||||
|
pattern->threads[i].id = io.stripeid;
|
||||||
|
|
||||||
|
if (pattern->threads[i].offset > pattern->offset_end)
|
||||||
|
pattern->threads[i].offset = pattern->offset_end;
|
||||||
|
if (pattern->threads[i].offset_end > pattern->offset_end)
|
||||||
|
pattern->threads[i].offset_end = pattern->offset_end;
|
||||||
|
|
||||||
|
dprintf(IOLVL, "io_unit(off=%llu end=%llu id=%u)\n",
|
||||||
|
pattern->threads[i].offset,
|
||||||
|
pattern->threads[i].offset_end,
|
||||||
|
pattern->threads[i].id);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pattern_free(
|
||||||
|
IN pnfs_io_pattern *pattern)
|
||||||
|
{
|
||||||
|
/* inform the layout that our io is finished */
|
||||||
|
pnfs_layout_io_finished(&pattern->layout->layout);
|
||||||
|
free(pattern->threads);
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum pnfs_status thread_next_unit(
|
||||||
|
IN pnfs_io_thread *thread,
|
||||||
|
OUT pnfs_io_unit *io)
|
||||||
|
{
|
||||||
|
pnfs_io_pattern *pattern = thread->pattern;
|
||||||
|
pnfs_file_layout *layout = pattern->layout;
|
||||||
|
enum pnfs_status status = PNFS_SUCCESS;
|
||||||
|
|
||||||
|
AcquireSRWLockShared(&layout->layout.lock);
|
||||||
|
|
||||||
|
/* stop io if the layout is recalled */
|
||||||
|
if (layout->layout.status & PNFS_LAYOUT_CHANGED) {
|
||||||
|
status = PNFSERR_LAYOUT_CHANGED;
|
||||||
|
goto out_unlock;
|
||||||
|
}
|
||||||
|
if (layout->layout.status & PNFS_LAYOUT_RECALLED) {
|
||||||
|
status = PNFSERR_LAYOUT_RECALLED;
|
||||||
|
goto out_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* loop until we find an io unit that matches this thread */
|
||||||
|
while (thread->offset < thread->offset_end) {
|
||||||
|
pnfs_file_device_io_unit(pattern, thread->offset, io);
|
||||||
|
|
||||||
|
#ifdef PNFS_THREAD_BY_SERVER
|
||||||
|
if (io->serverid == thread->id) {
|
||||||
|
#else
|
||||||
|
if (io->stripeid == thread->id) {
|
||||||
|
#endif
|
||||||
|
status = PNFS_PENDING;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
thread->offset += io->length;
|
||||||
|
}
|
||||||
|
out_unlock:
|
||||||
|
ReleaseSRWLockShared(&layout->layout.lock);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum pnfs_status thread_data_server(
|
||||||
|
IN pnfs_io_thread *thread,
|
||||||
|
OUT pnfs_data_server **server_out)
|
||||||
|
{
|
||||||
|
pnfs_file_device *device = thread->pattern->layout->device;
|
||||||
|
#ifdef PNFS_THREAD_BY_SERVER
|
||||||
|
const uint32_t serverid = thread->id;
|
||||||
|
#else
|
||||||
|
const uint32_t serverid = data_server_index(device, thread->id);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (serverid >= device->servers.count)
|
||||||
|
return PNFSERR_INVALID_DS_INDEX;
|
||||||
|
|
||||||
|
*server_out = &device->servers.arr[serverid];
|
||||||
|
return PNFS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum pnfs_status pattern_fork(
|
||||||
|
IN pnfs_io_pattern *pattern,
|
||||||
|
IN pnfs_io_thread_fn thread_fn)
|
||||||
|
{
|
||||||
|
pnfs_io_unit io;
|
||||||
|
#ifdef PNFS_THREADING
|
||||||
|
HANDLE *threads;
|
||||||
|
uint32_t num_threads;
|
||||||
|
#endif
|
||||||
|
uint32_t i;
|
||||||
|
DWORD status;
|
||||||
|
enum pnfs_status pnfsstat = PNFS_SUCCESS;
|
||||||
|
|
||||||
|
if (pattern->count == 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
#ifdef PNFS_THREADING
|
||||||
|
/* create a thread for each unit that has actual io */
|
||||||
|
threads = calloc(pattern->count, sizeof(HANDLE));
|
||||||
|
if (threads == NULL) {
|
||||||
|
pnfsstat = PNFSERR_RESOURCES;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
num_threads = 0;
|
||||||
|
for (i = 0; i < pattern->count; i++) {
|
||||||
|
if (thread_next_unit(&pattern->threads[i], &io) == PNFS_PENDING) {
|
||||||
|
threads[num_threads++] = (HANDLE)_beginthreadex(NULL, 0,
|
||||||
|
thread_fn, &pattern->threads[i], 0, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num_threads) { /* wait on all threads to finish */
|
||||||
|
status = WaitForMultipleObjects(num_threads, threads, TRUE, INFINITE);
|
||||||
|
if (status == WAIT_OBJECT_0)
|
||||||
|
status = NO_ERROR;
|
||||||
|
|
||||||
|
for (i = 0; i < num_threads; i++) {
|
||||||
|
/* keep track of the most severe error returned by a thread */
|
||||||
|
if (GetExitCodeThread(threads[i], &status))
|
||||||
|
pnfsstat = max(pnfsstat, (enum pnfs_status)status);
|
||||||
|
|
||||||
|
CloseHandle(threads[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(threads);
|
||||||
|
#else
|
||||||
|
/* process each server that has actual io */
|
||||||
|
for (i = 0; i < pattern->count; i++) {
|
||||||
|
if (thread_next_unit(&pattern->threads[i], &io) == PNFS_PENDING) {
|
||||||
|
/* keep track of the most severe error returned by a thread */
|
||||||
|
status = thread_fn(&pattern->threads[i]);
|
||||||
|
pnfsstat = max(pnfsstat, (enum pnfs_status)status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
out:
|
||||||
|
return pnfsstat;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint64_t pattern_bytes_transferred(
|
||||||
|
IN pnfs_io_pattern *pattern,
|
||||||
|
OUT OPTIONAL enum stable_how4 *stable)
|
||||||
|
{
|
||||||
|
uint64_t lowest_offset = pattern->offset_end;
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
if (stable) *stable = DATA_SYNC4;
|
||||||
|
|
||||||
|
for (i = 0; i < pattern->count; i++) {
|
||||||
|
if (lowest_offset > pattern->threads[i].offset)
|
||||||
|
lowest_offset = pattern->threads[i].offset;
|
||||||
|
if (stable && pattern->threads[i].stable == UNSTABLE4)
|
||||||
|
*stable = UNSTABLE4;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lowest_offset - pattern->offset_start;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static enum pnfs_status map_ds_error(
|
||||||
|
IN enum nfsstat4 nfsstat,
|
||||||
|
IN pnfs_layout *layout)
|
||||||
|
{
|
||||||
|
switch (nfsstat) {
|
||||||
|
case NO_ERROR:
|
||||||
|
return PNFS_SUCCESS;
|
||||||
|
|
||||||
|
/* 13.11 Layout Revocation and Fencing
|
||||||
|
* http://tools.ietf.org/html/rfc5661#section-13.11
|
||||||
|
* if we've been fenced, we'll either get ERR_STALE when we PUTFH
|
||||||
|
* something in layout.filehandles, or ERR_PNFS_NO_LAYOUT when
|
||||||
|
* attempting to READ or WRITE */
|
||||||
|
case NFS4ERR_STALE:
|
||||||
|
case NFS4ERR_PNFS_NO_LAYOUT:
|
||||||
|
dprintf(IOLVL, "data server fencing detected!\n");
|
||||||
|
|
||||||
|
AcquireSRWLockExclusive(&layout->lock);
|
||||||
|
/* flag the layout for return once io is finished */
|
||||||
|
layout->status |= PNFS_LAYOUT_RECALLED | PNFS_LAYOUT_CHANGED;
|
||||||
|
/* reset GRANTED so we know not to try LAYOUTRETURN */
|
||||||
|
layout->status &= ~PNFS_LAYOUT_GRANTED;
|
||||||
|
ReleaseSRWLockExclusive(&layout->lock);
|
||||||
|
|
||||||
|
/* return CHANGED to prevent any further use of the layout */
|
||||||
|
return PNFSERR_LAYOUT_CHANGED;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return PNFSERR_IO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t WINAPI file_layout_read_thread(void *args)
|
||||||
|
{
|
||||||
|
pnfs_io_unit io;
|
||||||
|
pnfs_io_thread *thread = (pnfs_io_thread*)args;
|
||||||
|
pnfs_io_pattern *pattern = thread->pattern;
|
||||||
|
stateid4 *state = pattern->stateid;
|
||||||
|
pnfs_data_server *server;
|
||||||
|
nfs41_client *client;
|
||||||
|
uint32_t maxreadsize, bytes_read, total_read;
|
||||||
|
enum pnfs_status status;
|
||||||
|
enum nfsstat4 nfsstat;
|
||||||
|
bool_t eof;
|
||||||
|
|
||||||
|
dprintf(IOLVL, "--> file_layout_read_thread(%u)\n", thread->id);
|
||||||
|
|
||||||
|
/* get the data server for this thread */
|
||||||
|
status = thread_data_server(thread, &server);
|
||||||
|
if (status) {
|
||||||
|
eprintf("thread_data_server() failed with %s\n",
|
||||||
|
pnfs_error_string(status));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
/* find or establish a client for this data server */
|
||||||
|
status = pnfs_data_server_client(pattern->root,
|
||||||
|
server, pattern->default_lease, &client);
|
||||||
|
if (status) {
|
||||||
|
eprintf("pnfs_data_server_client() failed with %s\n",
|
||||||
|
pnfs_error_string(status));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
total_read = 0;
|
||||||
|
while ((status = thread_next_unit(thread, &io)) == PNFS_PENDING) {
|
||||||
|
maxreadsize = max_read_size(client->session, &io.file->fh);
|
||||||
|
if (io.length > maxreadsize)
|
||||||
|
io.length = maxreadsize;
|
||||||
|
|
||||||
|
nfsstat = nfs41_read(client->session, io.file, state, io.offset,
|
||||||
|
(uint32_t)io.length, io.buffer, &bytes_read, &eof);
|
||||||
|
if (nfsstat) {
|
||||||
|
eprintf("nfs41_read() failed with %s\n",
|
||||||
|
nfs_error_string(nfsstat));
|
||||||
|
status = map_ds_error(nfsstat, &pattern->layout->layout);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
total_read += bytes_read;
|
||||||
|
thread->offset += bytes_read;
|
||||||
|
|
||||||
|
if (eof) {
|
||||||
|
dprintf(IOLVL, "read thread %u reached eof: offset %llu\n",
|
||||||
|
thread->id, thread->offset);
|
||||||
|
status = total_read ? PNFS_SUCCESS : PNFS_READ_EOF;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
dprintf(IOLVL, "<-- file_layout_read_thread(%u) returning %s\n",
|
||||||
|
thread->id, pnfs_error_string(status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t WINAPI file_layout_write_thread(void *args)
|
||||||
|
{
|
||||||
|
pnfs_io_unit io;
|
||||||
|
nfs41_write_verf verf;
|
||||||
|
pnfs_io_thread *thread = (pnfs_io_thread*)args;
|
||||||
|
pnfs_io_pattern *pattern = thread->pattern;
|
||||||
|
stateid4 *state = pattern->stateid;
|
||||||
|
pnfs_data_server *server;
|
||||||
|
pnfs_file_layout *layout = pattern->layout;
|
||||||
|
nfs41_client *client;
|
||||||
|
nfs41_path_fh *commit_file;
|
||||||
|
const uint64_t offset_start = thread->offset;
|
||||||
|
uint64_t commit_len;
|
||||||
|
uint32_t maxwritesize, bytes_written, total_written;
|
||||||
|
enum pnfs_status status;
|
||||||
|
enum nfsstat4 nfsstat;
|
||||||
|
|
||||||
|
dprintf(IOLVL, "--> file_layout_write_thread(%u)\n", thread->id);
|
||||||
|
|
||||||
|
/* get the data server for this thread */
|
||||||
|
status = thread_data_server(thread, &server);
|
||||||
|
if (status) {
|
||||||
|
eprintf("thread_data_server() failed with %s\n",
|
||||||
|
pnfs_error_string(status));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
/* find or establish a client for this data server */
|
||||||
|
status = pnfs_data_server_client(pattern->root,
|
||||||
|
server, pattern->default_lease, &client);
|
||||||
|
if (status) {
|
||||||
|
eprintf("pnfs_data_server_client() failed with %s\n",
|
||||||
|
pnfs_error_string(status));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
retry_write:
|
||||||
|
thread->offset = offset_start;
|
||||||
|
thread->stable = DATA_SYNC4;
|
||||||
|
commit_file = NULL;
|
||||||
|
total_written = 0;
|
||||||
|
|
||||||
|
while ((status = thread_next_unit(thread, &io)) == PNFS_PENDING) {
|
||||||
|
maxwritesize = max_write_size(client->session, &io.file->fh);
|
||||||
|
if (io.length > maxwritesize)
|
||||||
|
io.length = maxwritesize;
|
||||||
|
|
||||||
|
nfsstat = nfs41_write(client->session, io.file, state, io.buffer,
|
||||||
|
(uint32_t)io.length, io.offset, UNSTABLE4, &bytes_written, &verf);
|
||||||
|
if (nfsstat) {
|
||||||
|
eprintf("nfs41_write() failed with %s\n",
|
||||||
|
nfs_error_string(nfsstat));
|
||||||
|
status = map_ds_error(nfsstat, &layout->layout);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!verify_write(&verf, &thread->stable))
|
||||||
|
goto retry_write;
|
||||||
|
|
||||||
|
total_written += bytes_written;
|
||||||
|
thread->offset += bytes_written;
|
||||||
|
commit_file = io.file;
|
||||||
|
}
|
||||||
|
|
||||||
|
commit_len = thread->offset - pattern->offset_start;
|
||||||
|
/* nothing to commit */
|
||||||
|
if (commit_len == 0)
|
||||||
|
goto out;
|
||||||
|
/* layout changed; redo all io against metadata server */
|
||||||
|
if (status == PNFSERR_LAYOUT_CHANGED)
|
||||||
|
goto out;
|
||||||
|
/* XXX: commit offsets (and possibly fh) are different in dense layouts! */
|
||||||
|
if (is_dense(layout))
|
||||||
|
goto out;
|
||||||
|
/* the data is already in stable storage */
|
||||||
|
if (thread->stable != UNSTABLE4)
|
||||||
|
goto out;
|
||||||
|
/* the metadata server expects us to commit there instead */
|
||||||
|
if (should_commit_to_mds(layout))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
dprintf(1, "sending COMMIT to data server for offset=%d and len=%d\n",
|
||||||
|
pattern->offset_start, commit_len);
|
||||||
|
nfsstat = nfs41_commit(client->session, commit_file,
|
||||||
|
pattern->offset_start, (uint32_t)commit_len, 0);
|
||||||
|
|
||||||
|
/* on successful commit, leave pnfs_status unchanged; if the layout
|
||||||
|
* was recalled, we still want to return the error */
|
||||||
|
if (nfsstat == NFS4_OK)
|
||||||
|
thread->stable = DATA_SYNC4;
|
||||||
|
else
|
||||||
|
status = map_ds_error(nfsstat, &pattern->layout->layout);
|
||||||
|
out:
|
||||||
|
dprintf(IOLVL, "<-- file_layout_write_thread(%u) returning %s\n",
|
||||||
|
thread->id, pnfs_error_string(status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enum pnfs_status pnfs_read(
|
||||||
|
IN nfs41_root *root,
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN nfs41_path_fh *file,
|
||||||
|
IN stateid4 *stateid,
|
||||||
|
IN pnfs_file_layout *layout,
|
||||||
|
IN uint64_t offset,
|
||||||
|
IN uint64_t length,
|
||||||
|
OUT unsigned char *buffer_out,
|
||||||
|
OUT ULONG *len_out)
|
||||||
|
{
|
||||||
|
pnfs_io_pattern pattern;
|
||||||
|
enum pnfs_status status;
|
||||||
|
|
||||||
|
dprintf(IOLVL, "--> pnfs_read(%llu, %llu)\n", offset, length);
|
||||||
|
|
||||||
|
*len_out = 0;
|
||||||
|
|
||||||
|
status = pattern_init(&pattern, root, file, stateid,
|
||||||
|
layout, buffer_out, offset, length, session->lease_time);
|
||||||
|
if (status) {
|
||||||
|
eprintf("pattern_init() failed with %s\n",
|
||||||
|
pnfs_error_string(status));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = pattern_fork(&pattern, file_layout_read_thread);
|
||||||
|
if (status != PNFS_SUCCESS && status != PNFS_READ_EOF)
|
||||||
|
goto out_free_pattern;
|
||||||
|
|
||||||
|
*len_out = (ULONG)pattern_bytes_transferred(&pattern, NULL);
|
||||||
|
|
||||||
|
out_free_pattern:
|
||||||
|
pattern_free(&pattern);
|
||||||
|
out:
|
||||||
|
dprintf(IOLVL, "<-- pnfs_read() returning %s\n",
|
||||||
|
pnfs_error_string(status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum pnfs_status pnfs_write(
|
||||||
|
IN nfs41_root *root,
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN nfs41_path_fh *file,
|
||||||
|
IN stateid4 *stateid,
|
||||||
|
IN pnfs_file_layout *layout,
|
||||||
|
IN uint64_t offset,
|
||||||
|
IN uint64_t length,
|
||||||
|
IN unsigned char *buffer,
|
||||||
|
OUT ULONG *len_out)
|
||||||
|
{
|
||||||
|
pnfs_io_pattern pattern;
|
||||||
|
uint64_t new_last_offset;
|
||||||
|
enum stable_how4 stable;
|
||||||
|
enum pnfs_status status;
|
||||||
|
enum nfsstat4 nfsstat;
|
||||||
|
|
||||||
|
dprintf(IOLVL, "--> pnfs_write(%llu, %llu)\n", offset, length);
|
||||||
|
|
||||||
|
*len_out = 0;
|
||||||
|
|
||||||
|
status = pattern_init(&pattern, root, file, stateid,
|
||||||
|
layout, buffer, offset, length, session->lease_time);
|
||||||
|
if (status) {
|
||||||
|
eprintf("pattern_init() failed with %s\n",
|
||||||
|
pnfs_error_string(status));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = pattern_fork(&pattern, file_layout_write_thread);
|
||||||
|
/* on layout recall, we still attempt to commit what we wrote */
|
||||||
|
if (status != PNFS_SUCCESS && status != PNFSERR_LAYOUT_RECALLED)
|
||||||
|
goto out_free_pattern;
|
||||||
|
|
||||||
|
*len_out = (ULONG)pattern_bytes_transferred(&pattern, &stable);
|
||||||
|
if (*len_out == 0)
|
||||||
|
goto out_free_pattern;
|
||||||
|
|
||||||
|
if (stable == UNSTABLE4) {
|
||||||
|
/* not all data was committed, so commit to metadata server.
|
||||||
|
* pass do_getattr=0 to nfs41_commit() because we'll GETATTR
|
||||||
|
* after LAYOUTCOMMIT */
|
||||||
|
dprintf(1, "sending COMMIT to meta server for offset=%d and len=%d\n",
|
||||||
|
offset, *len_out);
|
||||||
|
nfsstat = nfs41_commit(session, pattern.meta_file, offset, *len_out, 0);
|
||||||
|
if (nfsstat) {
|
||||||
|
dprintf(IOLVL, "nfs41_commit() failed with %s\n",
|
||||||
|
nfs_error_string(nfsstat));
|
||||||
|
status = PNFSERR_IO;
|
||||||
|
goto out_free_pattern;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* send LAYOUTCOMMIT */
|
||||||
|
new_last_offset = offset + *len_out - 1;
|
||||||
|
|
||||||
|
nfsstat = pnfs_rpc_layoutcommit(session, pattern.meta_file,
|
||||||
|
&pattern.layout->layout.state, offset, *len_out,
|
||||||
|
&new_last_offset, NULL);
|
||||||
|
if (nfsstat) {
|
||||||
|
dprintf(IOLVL, "pnfs_rpc_layoutcommit() failed with %s\n",
|
||||||
|
nfs_error_string(nfsstat));
|
||||||
|
/* acceptable failure? if COMMIT worked, return success */
|
||||||
|
}
|
||||||
|
|
||||||
|
out_free_pattern:
|
||||||
|
pattern_free(&pattern);
|
||||||
|
out:
|
||||||
|
dprintf(IOLVL, "<-- pnfs_write() returning %s\n",
|
||||||
|
pnfs_error_string(status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
835
daemon/pnfs_layout.c
Normal file
835
daemon/pnfs_layout.c
Normal file
|
|
@ -0,0 +1,835 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "nfs41_ops.h"
|
||||||
|
#include "nfs41_callback.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "daemon_debug.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define FLLVL 2 /* dprintf level for file layout logging */
|
||||||
|
|
||||||
|
|
||||||
|
/* pnfs_file_layout_list */
|
||||||
|
struct pnfs_file_layout_list {
|
||||||
|
struct list_entry head;
|
||||||
|
CRITICAL_SECTION lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define layout_entry(pos) list_container(pos, pnfs_file_layout, entry)
|
||||||
|
|
||||||
|
static enum pnfs_status layout_create(
|
||||||
|
IN const nfs41_fh *meta_fh,
|
||||||
|
OUT pnfs_file_layout **layout_out)
|
||||||
|
{
|
||||||
|
pnfs_file_layout *layout;
|
||||||
|
enum pnfs_status status = PNFS_SUCCESS;
|
||||||
|
|
||||||
|
layout = calloc(1, sizeof(pnfs_file_layout));
|
||||||
|
if (layout == NULL) {
|
||||||
|
status = PNFSERR_RESOURCES;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
layout->layout.type = PNFS_LAYOUTTYPE_FILE;
|
||||||
|
fh_copy(&layout->meta_fh, meta_fh);
|
||||||
|
InitializeSRWLock(&layout->layout.lock);
|
||||||
|
|
||||||
|
*layout_out = layout;
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void layout_free(
|
||||||
|
IN pnfs_file_layout *layout)
|
||||||
|
{
|
||||||
|
free(layout->filehandles.arr);
|
||||||
|
free(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int layout_entry_compare(
|
||||||
|
IN const struct list_entry *entry,
|
||||||
|
IN const void *value)
|
||||||
|
{
|
||||||
|
const pnfs_file_layout *layout = layout_entry(entry);
|
||||||
|
const nfs41_fh *meta_fh = (const nfs41_fh*)value;
|
||||||
|
const nfs41_fh *layout_fh = (const nfs41_fh*)&layout->meta_fh;
|
||||||
|
const uint32_t diff = layout_fh->len - meta_fh->len;
|
||||||
|
return diff ? diff : memcmp(layout_fh->fh, meta_fh->fh, meta_fh->len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum pnfs_status layout_entry_find(
|
||||||
|
IN struct pnfs_file_layout_list *layouts,
|
||||||
|
IN const nfs41_fh *meta_fh,
|
||||||
|
OUT struct list_entry **entry_out)
|
||||||
|
{
|
||||||
|
*entry_out = list_search(&layouts->head, meta_fh, layout_entry_compare);
|
||||||
|
return *entry_out ? PNFS_SUCCESS : PNFSERR_NO_LAYOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum pnfs_status pnfs_file_layout_list_create(
|
||||||
|
OUT struct pnfs_file_layout_list **layouts_out)
|
||||||
|
{
|
||||||
|
struct pnfs_file_layout_list *layouts;
|
||||||
|
enum pnfs_status status = PNFS_SUCCESS;
|
||||||
|
|
||||||
|
layouts = calloc(1, sizeof(struct pnfs_file_layout_list));
|
||||||
|
if (layouts == NULL) {
|
||||||
|
status = PNFSERR_RESOURCES;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
list_init(&layouts->head);
|
||||||
|
InitializeCriticalSection(&layouts->lock);
|
||||||
|
*layouts_out = layouts;
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pnfs_file_layout_list_free(
|
||||||
|
IN struct pnfs_file_layout_list *layouts)
|
||||||
|
{
|
||||||
|
struct list_entry *entry, *tmp;
|
||||||
|
|
||||||
|
EnterCriticalSection(&layouts->lock);
|
||||||
|
|
||||||
|
list_for_each_tmp(entry, tmp, &layouts->head)
|
||||||
|
layout_free(layout_entry(entry));
|
||||||
|
|
||||||
|
LeaveCriticalSection(&layouts->lock);
|
||||||
|
|
||||||
|
free(layouts);
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum pnfs_status file_layout_find_or_create(
|
||||||
|
IN struct pnfs_file_layout_list *layouts,
|
||||||
|
IN const nfs41_fh *meta_fh,
|
||||||
|
OUT pnfs_file_layout **layout_out)
|
||||||
|
{
|
||||||
|
struct list_entry *entry;
|
||||||
|
enum pnfs_status status;
|
||||||
|
|
||||||
|
dprintf(FLLVL, "--> file_layout_find_or_create()\n");
|
||||||
|
|
||||||
|
EnterCriticalSection(&layouts->lock);
|
||||||
|
|
||||||
|
/* search for an existing layout */
|
||||||
|
status = layout_entry_find(layouts, meta_fh, &entry);
|
||||||
|
if (status) {
|
||||||
|
/* create a new layout */
|
||||||
|
pnfs_file_layout *layout;
|
||||||
|
status = layout_create(meta_fh, &layout);
|
||||||
|
if (status == PNFS_SUCCESS) {
|
||||||
|
/* add it to the list */
|
||||||
|
list_add_head(&layouts->head, &layout->entry);
|
||||||
|
*layout_out = layout;
|
||||||
|
|
||||||
|
dprintf(FLLVL, "<-- file_layout_find_or_create() "
|
||||||
|
"returning new layout %p\n", layout);
|
||||||
|
} else {
|
||||||
|
dprintf(FLLVL, "<-- file_layout_find_or_create() "
|
||||||
|
"returning %s\n", pnfs_error_string(status));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*layout_out = layout_entry(entry);
|
||||||
|
|
||||||
|
dprintf(FLLVL, "<-- file_layout_find_or_create() "
|
||||||
|
"returning existing layout %p\n", *layout_out);
|
||||||
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection(&layouts->lock);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum pnfs_status file_layout_find_and_delete(
|
||||||
|
IN struct pnfs_file_layout_list *layouts,
|
||||||
|
IN const nfs41_fh *meta_fh)
|
||||||
|
{
|
||||||
|
struct list_entry *entry;
|
||||||
|
enum pnfs_status status;
|
||||||
|
|
||||||
|
dprintf(FLLVL, "--> file_layout_find_and_delete()\n");
|
||||||
|
|
||||||
|
EnterCriticalSection(&layouts->lock);
|
||||||
|
|
||||||
|
status = layout_entry_find(layouts, meta_fh, &entry);
|
||||||
|
if (status == PNFS_SUCCESS) {
|
||||||
|
list_remove(entry);
|
||||||
|
layout_free(layout_entry(entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection(&layouts->lock);
|
||||||
|
|
||||||
|
dprintf(FLLVL, "<-- file_layout_find_and_delete() "
|
||||||
|
"returning %s\n", pnfs_error_string(status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* pnfs_file_layout */
|
||||||
|
static enum pnfs_status file_layout_fetch(
|
||||||
|
IN OUT pnfs_file_layout *layout,
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN nfs41_path_fh *meta_file,
|
||||||
|
IN stateid4 *state,
|
||||||
|
IN enum pnfs_iomode iomode,
|
||||||
|
IN uint64_t offset,
|
||||||
|
IN uint64_t length)
|
||||||
|
{
|
||||||
|
enum pnfs_status pnfsstat = PNFS_SUCCESS;
|
||||||
|
enum nfsstat4 nfsstat;
|
||||||
|
|
||||||
|
dprintf(FLLVL, "--> file_layout_fetch(%s, seqid=%u)\n",
|
||||||
|
pnfs_iomode_string(iomode), layout->layout.state.seqid);
|
||||||
|
|
||||||
|
nfsstat = pnfs_rpc_layoutget(session, meta_file,
|
||||||
|
state, iomode, offset, length, layout);
|
||||||
|
if (nfsstat) {
|
||||||
|
dprintf(FLLVL, "pnfs_rpc_layoutget() failed with %s\n",
|
||||||
|
nfs_error_string(nfsstat));
|
||||||
|
pnfsstat = PNFSERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (nfsstat) {
|
||||||
|
case NFS4_OK:
|
||||||
|
/* mark granted and clear other flags */
|
||||||
|
layout->layout.status = PNFS_LAYOUT_GRANTED;
|
||||||
|
|
||||||
|
dprintf(FLLVL, "Received layout:\n");
|
||||||
|
dprint_layout(FLLVL, layout);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NFS4ERR_BADIOMODE:
|
||||||
|
/* don't try RW again */
|
||||||
|
if (iomode == PNFS_IOMODE_RW)
|
||||||
|
layout->layout.status |= PNFS_LAYOUT_NOT_RW;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NFS4ERR_LAYOUTUNAVAILABLE:
|
||||||
|
case NFS4ERR_UNKNOWN_LAYOUTTYPE:
|
||||||
|
case NFS4ERR_BADLAYOUT:
|
||||||
|
/* don't try again at all */
|
||||||
|
layout->layout.status |= PNFS_LAYOUT_UNAVAILABLE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
dprintf(FLLVL, "<-- file_layout_fetch() returning %s\n",
|
||||||
|
pnfs_error_string(pnfsstat));
|
||||||
|
return pnfsstat;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t layout_recalled(
|
||||||
|
IN const pnfs_layout *layout)
|
||||||
|
{
|
||||||
|
return (layout->status & PNFS_LAYOUT_RECALLED) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t layout_granted(
|
||||||
|
IN const pnfs_layout *layout)
|
||||||
|
{
|
||||||
|
return (layout->status & PNFS_LAYOUT_GRANTED) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t layout_not_rw(
|
||||||
|
IN const pnfs_layout *layout)
|
||||||
|
{
|
||||||
|
return (layout->status & PNFS_LAYOUT_NOT_RW) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t will_never_grant(
|
||||||
|
IN const pnfs_layout *layout,
|
||||||
|
IN enum pnfs_iomode iomode)
|
||||||
|
{
|
||||||
|
return (layout->status & PNFS_LAYOUT_UNAVAILABLE) != 0
|
||||||
|
|| (iomode == PNFS_IOMODE_RW && layout_not_rw(layout));
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum pnfs_status layout_grant_status(
|
||||||
|
IN const pnfs_layout *layout,
|
||||||
|
IN enum pnfs_iomode iomode)
|
||||||
|
{
|
||||||
|
enum pnfs_status status = PNFS_PENDING;
|
||||||
|
|
||||||
|
if (layout_recalled(layout)) {
|
||||||
|
/* don't use a recalled layout */
|
||||||
|
status = PNFSERR_LAYOUT_RECALLED;
|
||||||
|
} else if (layout_granted(layout)) {
|
||||||
|
/* the layout is granted; use it if it's compatible */
|
||||||
|
status = PNFS_SUCCESS;
|
||||||
|
} else if (will_never_grant(layout, iomode)) {
|
||||||
|
/* an error from LAYOUTGET indicated that the server
|
||||||
|
* won't ever grant this layout, so stop trying */
|
||||||
|
status = PNFSERR_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum pnfs_status file_layout_cache(
|
||||||
|
IN OUT pnfs_file_layout *layout,
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN nfs41_path_fh *meta_file,
|
||||||
|
IN stateid4 *state,
|
||||||
|
IN enum pnfs_iomode iomode,
|
||||||
|
IN uint64_t offset,
|
||||||
|
IN uint64_t length)
|
||||||
|
{
|
||||||
|
enum pnfs_status status;
|
||||||
|
|
||||||
|
/* use a shared lock to see if it's already been granted */
|
||||||
|
AcquireSRWLockShared(&layout->layout.lock);
|
||||||
|
status = layout_grant_status(&layout->layout, iomode);
|
||||||
|
ReleaseSRWLockShared(&layout->layout.lock);
|
||||||
|
|
||||||
|
if (status == PNFS_PENDING) {
|
||||||
|
/* use an exclusive lock while attempting to get a new layout */
|
||||||
|
AcquireSRWLockExclusive(&layout->layout.lock);
|
||||||
|
|
||||||
|
status = layout_grant_status(&layout->layout, iomode);
|
||||||
|
if (status == PNFS_PENDING) {
|
||||||
|
/* if there's an existing layout stateid, use it */
|
||||||
|
if (layout->layout.state.seqid)
|
||||||
|
state = &layout->layout.state;
|
||||||
|
|
||||||
|
if (!layout_not_rw(&layout->layout)) {
|
||||||
|
/* try to get a RW layout first */
|
||||||
|
status = file_layout_fetch(layout, session,
|
||||||
|
meta_file, state, PNFS_IOMODE_RW, offset, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status && iomode == PNFS_IOMODE_READ) {
|
||||||
|
/* fall back on READ if necessary */
|
||||||
|
status = file_layout_fetch(layout, session,
|
||||||
|
meta_file, state, iomode, offset, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseSRWLockExclusive(&layout->layout.lock);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum pnfs_status layout_compatible(
|
||||||
|
IN OUT pnfs_layout *layout,
|
||||||
|
IN enum pnfs_iomode iomode,
|
||||||
|
IN uint64_t offset,
|
||||||
|
IN uint64_t length)
|
||||||
|
{
|
||||||
|
enum pnfs_status status = PNFS_SUCCESS;
|
||||||
|
|
||||||
|
AcquireSRWLockShared(&layout->lock);
|
||||||
|
|
||||||
|
if (iomode == PNFS_IOMODE_RW && layout->iomode == PNFS_IOMODE_READ) {
|
||||||
|
status = PNFSERR_NOT_SUPPORTED;
|
||||||
|
goto out_unlock;
|
||||||
|
}
|
||||||
|
if (offset < layout->offset ||
|
||||||
|
offset + length > layout->offset + layout->length) {
|
||||||
|
status = PNFSERR_NOT_SUPPORTED;
|
||||||
|
goto out_unlock;
|
||||||
|
}
|
||||||
|
out_unlock:
|
||||||
|
ReleaseSRWLockShared(&layout->lock);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum pnfs_status file_device_status(
|
||||||
|
IN const pnfs_layout *layout)
|
||||||
|
{
|
||||||
|
enum pnfs_status status = PNFS_PENDING;
|
||||||
|
|
||||||
|
if (layout_recalled(layout)) {
|
||||||
|
/* don't fetch deviceinfo for a recalled layout */
|
||||||
|
status = PNFSERR_LAYOUT_RECALLED;
|
||||||
|
} else if (layout->status & PNFS_LAYOUT_HAS_DEVICE) {
|
||||||
|
/* deviceinfo already cached */
|
||||||
|
status = PNFS_SUCCESS;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum pnfs_status file_layout_device(
|
||||||
|
IN OUT pnfs_file_layout *layout,
|
||||||
|
IN nfs41_session *session)
|
||||||
|
{
|
||||||
|
enum pnfs_status status = PNFS_PENDING;
|
||||||
|
|
||||||
|
/* use a shared lock to see if we already have a device */
|
||||||
|
AcquireSRWLockShared(&layout->layout.lock);
|
||||||
|
status = file_device_status(&layout->layout);
|
||||||
|
ReleaseSRWLockShared(&layout->layout.lock);
|
||||||
|
|
||||||
|
if (status == PNFS_PENDING) {
|
||||||
|
/* use an exclusive lock to look up device info */
|
||||||
|
AcquireSRWLockExclusive(&layout->layout.lock);
|
||||||
|
|
||||||
|
status = file_device_status(&layout->layout);
|
||||||
|
if (status == PNFS_PENDING) {
|
||||||
|
status = pnfs_file_device_get(session, session->client->devices,
|
||||||
|
layout->deviceid, &layout->device);
|
||||||
|
if (status == PNFS_SUCCESS)
|
||||||
|
layout->layout.status |= PNFS_LAYOUT_HAS_DEVICE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseSRWLockExclusive(&layout->layout.lock);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum pnfs_status file_layout_get(
|
||||||
|
IN OUT pnfs_file_layout *layout,
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN nfs41_path_fh *meta_file,
|
||||||
|
IN stateid4 *state,
|
||||||
|
IN enum pnfs_iomode iomode,
|
||||||
|
IN uint64_t offset,
|
||||||
|
IN uint64_t length)
|
||||||
|
{
|
||||||
|
enum pnfs_status status;
|
||||||
|
|
||||||
|
/* request a range for the entire file */
|
||||||
|
status = file_layout_cache(layout, session,
|
||||||
|
meta_file, state, iomode, 0, NFS4_UINT64_MAX);
|
||||||
|
if (status) {
|
||||||
|
dprintf(FLLVL, "file_layout_cache() failed with %s\n",
|
||||||
|
pnfs_error_string(status));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fail if we don't get everything we asked for */
|
||||||
|
status = layout_compatible(&layout->layout, iomode, offset, length);
|
||||||
|
if (status) {
|
||||||
|
dprintf(FLLVL, "file_layout_compatible() failed with %s\n",
|
||||||
|
pnfs_error_string(status));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make sure we have a device for the layout */
|
||||||
|
status = file_layout_device(layout, session);
|
||||||
|
if (status) {
|
||||||
|
dprintf(FLLVL, "file_layout_device() failed with %s\n",
|
||||||
|
pnfs_error_string(status));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum pnfs_status layout_return_status(
|
||||||
|
IN const pnfs_file_layout *layout)
|
||||||
|
{
|
||||||
|
return (layout->layout.status & PNFS_LAYOUT_GRANTED) == 0
|
||||||
|
? PNFS_SUCCESS : PNFS_PENDING;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum pnfs_status file_layout_return(
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN nfs41_path_fh *file,
|
||||||
|
IN pnfs_file_layout *layout)
|
||||||
|
{
|
||||||
|
enum pnfs_status status;
|
||||||
|
enum nfsstat4 nfsstat;
|
||||||
|
|
||||||
|
dprintf(FLLVL, "--> file_layout_return()\n");
|
||||||
|
|
||||||
|
/* under shared lock, determine whether we need to return the layout */
|
||||||
|
AcquireSRWLockShared(&layout->layout.lock);
|
||||||
|
status = layout_return_status(layout);
|
||||||
|
ReleaseSRWLockShared(&layout->layout.lock);
|
||||||
|
|
||||||
|
if (status == PNFS_PENDING) {
|
||||||
|
/* under exclusive lock, return the layout and reset status flags */
|
||||||
|
AcquireSRWLockExclusive(&layout->layout.lock);
|
||||||
|
|
||||||
|
status = layout_return_status(layout);
|
||||||
|
if (status == PNFS_PENDING) {
|
||||||
|
/* reset the granted flag */
|
||||||
|
layout->layout.status &= ~PNFS_LAYOUT_GRANTED;
|
||||||
|
|
||||||
|
nfsstat = pnfs_rpc_layoutreturn(session, file, layout);
|
||||||
|
if (nfsstat) {
|
||||||
|
eprintf("pnfs_rpc_layoutreturn() failed with %s\n",
|
||||||
|
nfs_error_string(nfsstat));
|
||||||
|
status = PNFSERR_NO_LAYOUT;
|
||||||
|
} else {
|
||||||
|
status = PNFS_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseSRWLockExclusive(&layout->layout.lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
dprintf(FLLVL, "<-- file_layout_return() returning %s\n",
|
||||||
|
pnfs_error_string(status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* nfs41_open_state */
|
||||||
|
static enum pnfs_status client_supports_pnfs(
|
||||||
|
IN nfs41_client *client)
|
||||||
|
{
|
||||||
|
enum pnfs_status status;
|
||||||
|
AcquireSRWLockShared(&client->exid_lock);
|
||||||
|
status = client->roles & EXCHGID4_FLAG_USE_PNFS_MDS
|
||||||
|
? PNFS_SUCCESS : PNFSERR_NOT_SUPPORTED;
|
||||||
|
ReleaseSRWLockShared(&client->exid_lock);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum pnfs_status fs_supports_layout(
|
||||||
|
IN const nfs41_superblock *superblock,
|
||||||
|
IN enum pnfs_layout_type type)
|
||||||
|
{
|
||||||
|
const uint32_t flag = 1 << (type - 1);
|
||||||
|
return (superblock->layout_types & flag) == 0
|
||||||
|
? PNFSERR_NOT_SUPPORTED : PNFS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum pnfs_status open_state_layout_cached(
|
||||||
|
IN nfs41_open_state *state,
|
||||||
|
IN enum pnfs_iomode iomode,
|
||||||
|
IN uint64_t offset,
|
||||||
|
IN uint64_t length,
|
||||||
|
OUT pnfs_file_layout **layout_out)
|
||||||
|
{
|
||||||
|
enum pnfs_status status = PNFSERR_NO_LAYOUT;
|
||||||
|
|
||||||
|
if (state->layout) {
|
||||||
|
status = PNFS_SUCCESS;
|
||||||
|
*layout_out = state->layout;
|
||||||
|
|
||||||
|
dprintf(FLLVL, "pnfs_open_state_layout() found "
|
||||||
|
"cached layout %p\n", *layout_out);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum pnfs_status pnfs_open_state_layout(
|
||||||
|
IN struct pnfs_file_layout_list *layouts,
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN nfs41_open_state *state,
|
||||||
|
IN enum pnfs_iomode iomode,
|
||||||
|
IN uint64_t offset,
|
||||||
|
IN uint64_t length,
|
||||||
|
OUT pnfs_file_layout **layout_out)
|
||||||
|
{
|
||||||
|
pnfs_file_layout *layout;
|
||||||
|
enum pnfs_status status;
|
||||||
|
|
||||||
|
dprintf(FLLVL, "--> pnfs_open_state_layout()\n");
|
||||||
|
|
||||||
|
status = client_supports_pnfs(session->client);
|
||||||
|
if (status)
|
||||||
|
goto out;
|
||||||
|
status = fs_supports_layout(state->file.fh.superblock, PNFS_LAYOUTTYPE_FILE);
|
||||||
|
if (status)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* under shared lock, check open state for cached layouts */
|
||||||
|
AcquireSRWLockShared(&state->lock);
|
||||||
|
status = open_state_layout_cached(state, iomode, offset, length, &layout);
|
||||||
|
ReleaseSRWLockShared(&state->lock);
|
||||||
|
|
||||||
|
if (status) {
|
||||||
|
/* under exclusive lock, find or create a layout for this file */
|
||||||
|
AcquireSRWLockExclusive(&state->lock);
|
||||||
|
|
||||||
|
status = open_state_layout_cached(state, iomode, offset, length, &layout);
|
||||||
|
if (status) {
|
||||||
|
status = file_layout_find_or_create(layouts, &state->file.fh, &layout);
|
||||||
|
if (status == PNFS_SUCCESS) {
|
||||||
|
state->layout = layout;
|
||||||
|
|
||||||
|
dprintf(FLLVL, "pnfs_open_state_layout() caching layout %p\n",
|
||||||
|
state->layout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseSRWLockExclusive(&state->lock);
|
||||||
|
|
||||||
|
if (status)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make sure the layout can satisfy this request */
|
||||||
|
status = file_layout_get(layout, session, &state->file,
|
||||||
|
&state->stateid, iomode, offset, length);
|
||||||
|
if (status) {
|
||||||
|
dprintf(FLLVL, "file_layout_get() failed with %s\n",
|
||||||
|
pnfs_error_string(status));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
*layout_out = layout;
|
||||||
|
out:
|
||||||
|
dprintf(FLLVL, "<-- pnfs_open_state_layout() returning %s\n",
|
||||||
|
pnfs_error_string(status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pnfs_open_state_close(
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN nfs41_open_state *state,
|
||||||
|
IN bool_t remove)
|
||||||
|
{
|
||||||
|
pnfs_file_layout *layout;
|
||||||
|
bool_t return_on_close;
|
||||||
|
enum pnfs_status status;
|
||||||
|
|
||||||
|
AcquireSRWLockExclusive(&state->lock);
|
||||||
|
layout = state->layout;
|
||||||
|
state->layout = NULL;
|
||||||
|
ReleaseSRWLockExclusive(&state->lock);
|
||||||
|
|
||||||
|
if (layout) {
|
||||||
|
/* check if we need to return the layout on close */
|
||||||
|
AcquireSRWLockShared(&layout->layout.lock);
|
||||||
|
return_on_close = layout->layout.return_on_close;
|
||||||
|
ReleaseSRWLockShared(&layout->layout.lock);
|
||||||
|
|
||||||
|
if (return_on_close) {
|
||||||
|
status = file_layout_return(session, &state->file, layout);
|
||||||
|
if (status)
|
||||||
|
eprintf("file_layout_return() failed with %s\n",
|
||||||
|
pnfs_error_string(status));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remove && session->client->layouts) {
|
||||||
|
/* free the layout when the file is removed */
|
||||||
|
file_layout_find_and_delete(session->client->layouts, &state->file.fh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* pnfs_layout_recall */
|
||||||
|
|
||||||
|
/* expects the caller to have an exclusive lock */
|
||||||
|
static enum pnfs_status layout_recall_return(
|
||||||
|
IN pnfs_layout *layout)
|
||||||
|
{
|
||||||
|
dprintf(FLLVL, "layout_recall_return() 'forgetting' layout\n");
|
||||||
|
|
||||||
|
/* since we're forgetful, we don't actually return the layout;
|
||||||
|
* just zero the stateid since it won't be valid anymore */
|
||||||
|
ZeroMemory(&layout->state, sizeof(layout->state));
|
||||||
|
layout->status = 0;
|
||||||
|
|
||||||
|
return PNFS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum pnfs_status file_layout_recall(
|
||||||
|
IN pnfs_file_layout *layout,
|
||||||
|
IN const struct cb_layoutrecall_args *recall)
|
||||||
|
{
|
||||||
|
enum pnfs_status status = PNFS_SUCCESS;
|
||||||
|
|
||||||
|
/* under an exclusive lock, flag the layout as recalled */
|
||||||
|
AcquireSRWLockExclusive(&layout->layout.lock);
|
||||||
|
|
||||||
|
if (layout->layout.io_count == 0) {
|
||||||
|
/* if there is no pending io, return the layout now */
|
||||||
|
status = layout_recall_return(&layout->layout);
|
||||||
|
} else {
|
||||||
|
/* flag the layout as recalled so it can be returned after io */
|
||||||
|
layout->layout.status |= PNFS_LAYOUT_RECALLED;
|
||||||
|
if (recall->changed)
|
||||||
|
layout->layout.status |= PNFS_LAYOUT_CHANGED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if we got a stateid, update the layout's seqid */
|
||||||
|
if (recall->recall.type == PNFS_RETURN_FILE)
|
||||||
|
layout->layout.state.seqid = recall->recall.args.file.stateid.seqid;
|
||||||
|
|
||||||
|
ReleaseSRWLockExclusive(&layout->layout.lock);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum pnfs_status file_layout_recall_file(
|
||||||
|
IN struct pnfs_file_layout_list *layouts,
|
||||||
|
IN const struct cb_layoutrecall_args *recall)
|
||||||
|
{
|
||||||
|
struct list_entry *entry;
|
||||||
|
enum pnfs_status status;
|
||||||
|
|
||||||
|
dprintf(FLLVL, "--> file_layout_recall_file()\n");
|
||||||
|
|
||||||
|
EnterCriticalSection(&layouts->lock);
|
||||||
|
|
||||||
|
status = layout_entry_find(layouts, &recall->recall.args.file.fh, &entry);
|
||||||
|
if (status == PNFS_SUCCESS)
|
||||||
|
status = file_layout_recall(layout_entry(entry), recall);
|
||||||
|
|
||||||
|
LeaveCriticalSection(&layouts->lock);
|
||||||
|
|
||||||
|
dprintf(FLLVL, "<-- file_layout_recall_file() returning %s\n",
|
||||||
|
pnfs_error_string(status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool_t fsid_matches(
|
||||||
|
IN const nfs41_fsid *lhs,
|
||||||
|
IN const nfs41_fsid *rhs)
|
||||||
|
{
|
||||||
|
return lhs->major == rhs->major
|
||||||
|
&& lhs->minor == rhs->minor;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum pnfs_status file_layout_recall_fsid(
|
||||||
|
IN struct pnfs_file_layout_list *layouts,
|
||||||
|
IN const struct cb_layoutrecall_args *recall)
|
||||||
|
{
|
||||||
|
struct list_entry *entry;
|
||||||
|
pnfs_file_layout *layout;
|
||||||
|
nfs41_fh *fh;
|
||||||
|
enum pnfs_status status = PNFSERR_NO_LAYOUT;
|
||||||
|
|
||||||
|
dprintf(FLLVL, "--> file_layout_recall_fsid(%llu, %llu)\n",
|
||||||
|
recall->recall.args.fsid.major, recall->recall.args.fsid.minor);
|
||||||
|
|
||||||
|
EnterCriticalSection(&layouts->lock);
|
||||||
|
|
||||||
|
list_for_each(entry, &layouts->head) {
|
||||||
|
layout = layout_entry(entry);
|
||||||
|
/* no locks needed to read layout.meta_fh or superblock.fsid,
|
||||||
|
* because they are only written once on creation */
|
||||||
|
fh = &layout->meta_fh;
|
||||||
|
if (fsid_matches(&recall->recall.args.fsid, &fh->superblock->fsid))
|
||||||
|
status = file_layout_recall(layout, recall);
|
||||||
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection(&layouts->lock);
|
||||||
|
|
||||||
|
dprintf(FLLVL, "<-- file_layout_recall_fsid() returning %s\n",
|
||||||
|
pnfs_error_string(status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum pnfs_status file_layout_recall_all(
|
||||||
|
IN struct pnfs_file_layout_list *layouts,
|
||||||
|
IN const struct cb_layoutrecall_args *recall)
|
||||||
|
{
|
||||||
|
struct list_entry *entry;
|
||||||
|
enum pnfs_status status = PNFSERR_NO_LAYOUT;
|
||||||
|
|
||||||
|
dprintf(FLLVL, "--> file_layout_recall_all()\n");
|
||||||
|
|
||||||
|
EnterCriticalSection(&layouts->lock);
|
||||||
|
|
||||||
|
list_for_each(entry, &layouts->head)
|
||||||
|
status = file_layout_recall(layout_entry(entry), recall);
|
||||||
|
|
||||||
|
LeaveCriticalSection(&layouts->lock);
|
||||||
|
|
||||||
|
dprintf(FLLVL, "<-- file_layout_recall_all() returning %s\n",
|
||||||
|
pnfs_error_string(status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum pnfs_status pnfs_file_layout_recall(
|
||||||
|
IN struct pnfs_file_layout_list *layouts,
|
||||||
|
IN const struct cb_layoutrecall_args *recall)
|
||||||
|
{
|
||||||
|
enum pnfs_status status = PNFS_SUCCESS;
|
||||||
|
|
||||||
|
dprintf(FLLVL, "--> pnfs_file_layout_recall(%u, %s, %u)\n",
|
||||||
|
recall->recall.type, pnfs_iomode_string(recall->iomode),
|
||||||
|
recall->changed);
|
||||||
|
|
||||||
|
if (recall->type != PNFS_LAYOUTTYPE_FILE) {
|
||||||
|
dprintf(FLLVL, "invalid layout type %u (%s)!\n",
|
||||||
|
recall->type, pnfs_layout_type_string(recall->type));
|
||||||
|
status = PNFSERR_NOT_SUPPORTED;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (recall->recall.type) {
|
||||||
|
case PNFS_RETURN_FILE:
|
||||||
|
status = file_layout_recall_file(layouts, recall);
|
||||||
|
break;
|
||||||
|
case PNFS_RETURN_FSID:
|
||||||
|
status = file_layout_recall_fsid(layouts, recall);
|
||||||
|
break;
|
||||||
|
case PNFS_RETURN_ALL:
|
||||||
|
status = file_layout_recall_all(layouts, recall);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
dprintf(FLLVL, "invalid return type %u!\n", recall->recall);
|
||||||
|
status = PNFSERR_NOT_SUPPORTED;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* XXX: bulk layout recalls require invalidation of cached device info!
|
||||||
|
* see CB_LAYOUTRECALL: http://tools.ietf.org/html/rfc5661#section-20.3.3 */
|
||||||
|
out:
|
||||||
|
dprintf(FLLVL, "<-- pnfs_file_layout_recall() returning %s\n",
|
||||||
|
pnfs_error_string(status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
enum pnfs_status pnfs_layout_io_start(
|
||||||
|
IN pnfs_layout *layout)
|
||||||
|
{
|
||||||
|
enum pnfs_status status = PNFS_SUCCESS;
|
||||||
|
|
||||||
|
AcquireSRWLockExclusive(&layout->lock);
|
||||||
|
|
||||||
|
if (layout_recalled(layout)) {
|
||||||
|
/* don't start any more io if the layout has been recalled */
|
||||||
|
status = PNFSERR_LAYOUT_RECALLED;
|
||||||
|
dprintf(FLLVL, "pnfs_layout_io_start() failed, layout was recalled\n");
|
||||||
|
} else {
|
||||||
|
/* take a reference on the layout, so that it won't be recalled
|
||||||
|
* until all io is finished */
|
||||||
|
layout->io_count++;
|
||||||
|
dprintf(FLLVL, "pnfs_layout_io_start(): count -> %u\n",
|
||||||
|
layout->io_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReleaseSRWLockExclusive(&layout->lock);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pnfs_layout_io_finished(
|
||||||
|
IN pnfs_layout *layout)
|
||||||
|
{
|
||||||
|
AcquireSRWLockExclusive(&layout->lock);
|
||||||
|
|
||||||
|
/* return the reference to signify that an io request is finished */
|
||||||
|
layout->io_count--;
|
||||||
|
dprintf(FLLVL, "pnfs_layout_io_finished() count -> %u\n",
|
||||||
|
layout->io_count);
|
||||||
|
|
||||||
|
if (layout->io_count > 0) /* more io pending */
|
||||||
|
goto out_unlock;
|
||||||
|
|
||||||
|
/* once all io is finished, check for layout recalls */
|
||||||
|
if (layout->status & PNFS_LAYOUT_RECALLED)
|
||||||
|
layout_recall_return(layout);
|
||||||
|
|
||||||
|
out_unlock:
|
||||||
|
ReleaseSRWLockExclusive(&layout->lock);
|
||||||
|
}
|
||||||
385
daemon/rbtree.c
Normal file
385
daemon/rbtree.c
Normal file
|
|
@ -0,0 +1,385 @@
|
||||||
|
/*
|
||||||
|
Red Black Trees
|
||||||
|
(C) 1999 Andrea Arcangeli <andrea@suse.de>
|
||||||
|
(C) 2002 David Woodhouse <dwmw2@infradead.org>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
linux/lib/rbtree.c
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "rbtree.h"
|
||||||
|
|
||||||
|
#pragma warning(disable:4706)
|
||||||
|
|
||||||
|
static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
|
||||||
|
{
|
||||||
|
struct rb_node *right = node->rb_right;
|
||||||
|
struct rb_node *parent = rb_parent(node);
|
||||||
|
|
||||||
|
if ((node->rb_right = right->rb_left))
|
||||||
|
rb_set_parent(right->rb_left, node);
|
||||||
|
right->rb_left = node;
|
||||||
|
|
||||||
|
rb_set_parent(right, parent);
|
||||||
|
|
||||||
|
if (parent)
|
||||||
|
{
|
||||||
|
if (node == parent->rb_left)
|
||||||
|
parent->rb_left = right;
|
||||||
|
else
|
||||||
|
parent->rb_right = right;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
root->rb_node = right;
|
||||||
|
rb_set_parent(node, right);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
|
||||||
|
{
|
||||||
|
struct rb_node *left = node->rb_left;
|
||||||
|
struct rb_node *parent = rb_parent(node);
|
||||||
|
|
||||||
|
if ((node->rb_left = left->rb_right))
|
||||||
|
rb_set_parent(left->rb_right, node);
|
||||||
|
left->rb_right = node;
|
||||||
|
|
||||||
|
rb_set_parent(left, parent);
|
||||||
|
|
||||||
|
if (parent)
|
||||||
|
{
|
||||||
|
if (node == parent->rb_right)
|
||||||
|
parent->rb_right = left;
|
||||||
|
else
|
||||||
|
parent->rb_left = left;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
root->rb_node = left;
|
||||||
|
rb_set_parent(node, left);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rb_insert_color(struct rb_node *node, struct rb_root *root)
|
||||||
|
{
|
||||||
|
struct rb_node *parent, *gparent;
|
||||||
|
|
||||||
|
while ((parent = rb_parent(node)) && rb_is_red(parent))
|
||||||
|
{
|
||||||
|
gparent = rb_parent(parent);
|
||||||
|
|
||||||
|
if (parent == gparent->rb_left)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
register struct rb_node *uncle = gparent->rb_right;
|
||||||
|
if (uncle && rb_is_red(uncle))
|
||||||
|
{
|
||||||
|
rb_set_black(uncle);
|
||||||
|
rb_set_black(parent);
|
||||||
|
rb_set_red(gparent);
|
||||||
|
node = gparent;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parent->rb_right == node)
|
||||||
|
{
|
||||||
|
register struct rb_node *tmp;
|
||||||
|
__rb_rotate_left(parent, root);
|
||||||
|
tmp = parent;
|
||||||
|
parent = node;
|
||||||
|
node = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
rb_set_black(parent);
|
||||||
|
rb_set_red(gparent);
|
||||||
|
__rb_rotate_right(gparent, root);
|
||||||
|
} else {
|
||||||
|
{
|
||||||
|
register struct rb_node *uncle = gparent->rb_left;
|
||||||
|
if (uncle && rb_is_red(uncle))
|
||||||
|
{
|
||||||
|
rb_set_black(uncle);
|
||||||
|
rb_set_black(parent);
|
||||||
|
rb_set_red(gparent);
|
||||||
|
node = gparent;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parent->rb_left == node)
|
||||||
|
{
|
||||||
|
register struct rb_node *tmp;
|
||||||
|
__rb_rotate_right(parent, root);
|
||||||
|
tmp = parent;
|
||||||
|
parent = node;
|
||||||
|
node = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
rb_set_black(parent);
|
||||||
|
rb_set_red(gparent);
|
||||||
|
__rb_rotate_left(gparent, root);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rb_set_black(root->rb_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __rb_erase_color(struct rb_node *node, struct rb_node *parent,
|
||||||
|
struct rb_root *root)
|
||||||
|
{
|
||||||
|
struct rb_node *other;
|
||||||
|
|
||||||
|
while ((!node || rb_is_black(node)) && node != root->rb_node)
|
||||||
|
{
|
||||||
|
if (parent->rb_left == node)
|
||||||
|
{
|
||||||
|
other = parent->rb_right;
|
||||||
|
if (rb_is_red(other))
|
||||||
|
{
|
||||||
|
rb_set_black(other);
|
||||||
|
rb_set_red(parent);
|
||||||
|
__rb_rotate_left(parent, root);
|
||||||
|
other = parent->rb_right;
|
||||||
|
}
|
||||||
|
if ((!other->rb_left || rb_is_black(other->rb_left)) &&
|
||||||
|
(!other->rb_right || rb_is_black(other->rb_right)))
|
||||||
|
{
|
||||||
|
rb_set_red(other);
|
||||||
|
node = parent;
|
||||||
|
parent = rb_parent(node);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!other->rb_right || rb_is_black(other->rb_right))
|
||||||
|
{
|
||||||
|
rb_set_black(other->rb_left);
|
||||||
|
rb_set_red(other);
|
||||||
|
__rb_rotate_right(other, root);
|
||||||
|
other = parent->rb_right;
|
||||||
|
}
|
||||||
|
rb_set_color(other, rb_color(parent));
|
||||||
|
rb_set_black(parent);
|
||||||
|
rb_set_black(other->rb_right);
|
||||||
|
__rb_rotate_left(parent, root);
|
||||||
|
node = root->rb_node;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
other = parent->rb_left;
|
||||||
|
if (rb_is_red(other))
|
||||||
|
{
|
||||||
|
rb_set_black(other);
|
||||||
|
rb_set_red(parent);
|
||||||
|
__rb_rotate_right(parent, root);
|
||||||
|
other = parent->rb_left;
|
||||||
|
}
|
||||||
|
if ((!other->rb_left || rb_is_black(other->rb_left)) &&
|
||||||
|
(!other->rb_right || rb_is_black(other->rb_right)))
|
||||||
|
{
|
||||||
|
rb_set_red(other);
|
||||||
|
node = parent;
|
||||||
|
parent = rb_parent(node);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!other->rb_left || rb_is_black(other->rb_left))
|
||||||
|
{
|
||||||
|
rb_set_black(other->rb_right);
|
||||||
|
rb_set_red(other);
|
||||||
|
__rb_rotate_left(other, root);
|
||||||
|
other = parent->rb_left;
|
||||||
|
}
|
||||||
|
rb_set_color(other, rb_color(parent));
|
||||||
|
rb_set_black(parent);
|
||||||
|
rb_set_black(other->rb_left);
|
||||||
|
__rb_rotate_right(parent, root);
|
||||||
|
node = root->rb_node;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (node)
|
||||||
|
rb_set_black(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rb_erase(struct rb_node *node, struct rb_root *root)
|
||||||
|
{
|
||||||
|
struct rb_node *child, *parent;
|
||||||
|
int color;
|
||||||
|
|
||||||
|
if (!node->rb_left)
|
||||||
|
child = node->rb_right;
|
||||||
|
else if (!node->rb_right)
|
||||||
|
child = node->rb_left;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct rb_node *old = node, *left;
|
||||||
|
|
||||||
|
node = node->rb_right;
|
||||||
|
while ((left = node->rb_left) != NULL)
|
||||||
|
node = left;
|
||||||
|
|
||||||
|
if (rb_parent(old)) {
|
||||||
|
if (rb_parent(old)->rb_left == old)
|
||||||
|
rb_parent(old)->rb_left = node;
|
||||||
|
else
|
||||||
|
rb_parent(old)->rb_right = node;
|
||||||
|
} else
|
||||||
|
root->rb_node = node;
|
||||||
|
|
||||||
|
child = node->rb_right;
|
||||||
|
parent = rb_parent(node);
|
||||||
|
color = rb_color(node);
|
||||||
|
|
||||||
|
if (parent == old) {
|
||||||
|
parent = node;
|
||||||
|
} else {
|
||||||
|
if (child)
|
||||||
|
rb_set_parent(child, parent);
|
||||||
|
parent->rb_left = child;
|
||||||
|
|
||||||
|
node->rb_right = old->rb_right;
|
||||||
|
rb_set_parent(old->rb_right, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
node->rb_parent_color = old->rb_parent_color;
|
||||||
|
node->rb_left = old->rb_left;
|
||||||
|
rb_set_parent(old->rb_left, node);
|
||||||
|
|
||||||
|
goto color;
|
||||||
|
}
|
||||||
|
|
||||||
|
parent = rb_parent(node);
|
||||||
|
color = rb_color(node);
|
||||||
|
|
||||||
|
if (child)
|
||||||
|
rb_set_parent(child, parent);
|
||||||
|
if (parent)
|
||||||
|
{
|
||||||
|
if (parent->rb_left == node)
|
||||||
|
parent->rb_left = child;
|
||||||
|
else
|
||||||
|
parent->rb_right = child;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
root->rb_node = child;
|
||||||
|
|
||||||
|
color:
|
||||||
|
if (color == RB_BLACK)
|
||||||
|
__rb_erase_color(child, parent, root);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function returns the first node (in sort order) of the tree.
|
||||||
|
*/
|
||||||
|
struct rb_node *rb_first(const struct rb_root *root)
|
||||||
|
{
|
||||||
|
struct rb_node *n;
|
||||||
|
|
||||||
|
n = root->rb_node;
|
||||||
|
if (!n)
|
||||||
|
return NULL;
|
||||||
|
while (n->rb_left)
|
||||||
|
n = n->rb_left;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct rb_node *rb_last(const struct rb_root *root)
|
||||||
|
{
|
||||||
|
struct rb_node *n;
|
||||||
|
|
||||||
|
n = root->rb_node;
|
||||||
|
if (!n)
|
||||||
|
return NULL;
|
||||||
|
while (n->rb_right)
|
||||||
|
n = n->rb_right;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct rb_node *rb_next(const struct rb_node *node)
|
||||||
|
{
|
||||||
|
struct rb_node *parent;
|
||||||
|
|
||||||
|
if (rb_parent(node) == node)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* If we have a right-hand child, go down and then left as far
|
||||||
|
as we can. */
|
||||||
|
if (node->rb_right) {
|
||||||
|
node = node->rb_right;
|
||||||
|
while (node->rb_left)
|
||||||
|
node=node->rb_left;
|
||||||
|
return (struct rb_node *)node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No right-hand children. Everything down and left is
|
||||||
|
smaller than us, so any 'next' node must be in the general
|
||||||
|
direction of our parent. Go up the tree; any time the
|
||||||
|
ancestor is a right-hand child of its parent, keep going
|
||||||
|
up. First time it's a left-hand child of its parent, said
|
||||||
|
parent is our 'next' node. */
|
||||||
|
while ((parent = rb_parent(node)) && node == parent->rb_right)
|
||||||
|
node = parent;
|
||||||
|
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct rb_node *rb_prev(const struct rb_node *node)
|
||||||
|
{
|
||||||
|
struct rb_node *parent;
|
||||||
|
|
||||||
|
if (rb_parent(node) == node)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* If we have a left-hand child, go down and then right as far
|
||||||
|
as we can. */
|
||||||
|
if (node->rb_left) {
|
||||||
|
node = node->rb_left;
|
||||||
|
while (node->rb_right)
|
||||||
|
node=node->rb_right;
|
||||||
|
return (struct rb_node *)node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No left-hand children. Go up till we find an ancestor which
|
||||||
|
is a right-hand child of its parent */
|
||||||
|
while ((parent = rb_parent(node)) && node == parent->rb_left)
|
||||||
|
node = parent;
|
||||||
|
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rb_replace_node(struct rb_node *victim, struct rb_node *new,
|
||||||
|
struct rb_root *root)
|
||||||
|
{
|
||||||
|
struct rb_node *parent = rb_parent(victim);
|
||||||
|
|
||||||
|
/* Set the surrounding nodes to point to the replacement */
|
||||||
|
if (parent) {
|
||||||
|
if (victim == parent->rb_left)
|
||||||
|
parent->rb_left = new;
|
||||||
|
else
|
||||||
|
parent->rb_right = new;
|
||||||
|
} else {
|
||||||
|
root->rb_node = new;
|
||||||
|
}
|
||||||
|
if (victim->rb_left)
|
||||||
|
rb_set_parent(victim->rb_left, new);
|
||||||
|
if (victim->rb_right)
|
||||||
|
rb_set_parent(victim->rb_right, new);
|
||||||
|
|
||||||
|
/* Copy the pointers/colour from the victim to the replacement */
|
||||||
|
*new = *victim;
|
||||||
|
}
|
||||||
159
daemon/rbtree.h
Normal file
159
daemon/rbtree.h
Normal file
|
|
@ -0,0 +1,159 @@
|
||||||
|
/*
|
||||||
|
Red Black Trees
|
||||||
|
(C) 1999 Andrea Arcangeli <andrea@suse.de>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
|
||||||
|
linux/include/linux/rbtree.h
|
||||||
|
|
||||||
|
To use rbtrees you'll have to implement your own insert and search cores.
|
||||||
|
This will avoid us to use callbacks and to drop drammatically performances.
|
||||||
|
I know it's not the cleaner way, but in C (not in C++) to get
|
||||||
|
performances and genericity...
|
||||||
|
|
||||||
|
Some example of insert and search follows here. The search is a plain
|
||||||
|
normal search over an ordered tree. The insert instead must be implemented
|
||||||
|
int two steps: as first thing the code must insert the element in
|
||||||
|
order as a red leaf in the tree, then the support library function
|
||||||
|
rb_insert_color() must be called. Such function will do the
|
||||||
|
not trivial work to rebalance the rbtree if necessary.
|
||||||
|
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
static inline struct page * rb_search_page_cache(struct inode * inode,
|
||||||
|
unsigned long offset)
|
||||||
|
{
|
||||||
|
struct rb_node * n = inode->i_rb_page_cache.rb_node;
|
||||||
|
struct page * page;
|
||||||
|
|
||||||
|
while (n)
|
||||||
|
{
|
||||||
|
page = rb_entry(n, struct page, rb_page_cache);
|
||||||
|
|
||||||
|
if (offset < page->offset)
|
||||||
|
n = n->rb_left;
|
||||||
|
else if (offset > page->offset)
|
||||||
|
n = n->rb_right;
|
||||||
|
else
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct page * __rb_insert_page_cache(struct inode * inode,
|
||||||
|
unsigned long offset,
|
||||||
|
struct rb_node * node)
|
||||||
|
{
|
||||||
|
struct rb_node ** p = &inode->i_rb_page_cache.rb_node;
|
||||||
|
struct rb_node * parent = NULL;
|
||||||
|
struct page * page;
|
||||||
|
|
||||||
|
while (*p)
|
||||||
|
{
|
||||||
|
parent = *p;
|
||||||
|
page = rb_entry(parent, struct page, rb_page_cache);
|
||||||
|
|
||||||
|
if (offset < page->offset)
|
||||||
|
p = &(*p)->rb_left;
|
||||||
|
else if (offset > page->offset)
|
||||||
|
p = &(*p)->rb_right;
|
||||||
|
else
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
|
||||||
|
rb_link_node(node, parent, p);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct page * rb_insert_page_cache(struct inode * inode,
|
||||||
|
unsigned long offset,
|
||||||
|
struct rb_node * node)
|
||||||
|
{
|
||||||
|
struct page * ret;
|
||||||
|
if ((ret = __rb_insert_page_cache(inode, offset, node)))
|
||||||
|
goto out;
|
||||||
|
rb_insert_color(node, &inode->i_rb_page_cache);
|
||||||
|
out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _LINUX_RBTREE_H
|
||||||
|
#define _LINUX_RBTREE_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
struct rb_node
|
||||||
|
{
|
||||||
|
size_t rb_parent_color;
|
||||||
|
#define RB_RED 0
|
||||||
|
#define RB_BLACK 1
|
||||||
|
struct rb_node *rb_right;
|
||||||
|
struct rb_node *rb_left;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rb_root
|
||||||
|
{
|
||||||
|
struct rb_node *rb_node;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define rb_parent(r) ((struct rb_node *)((r)->rb_parent_color & ~3))
|
||||||
|
#define rb_color(r) ((r)->rb_parent_color & 1)
|
||||||
|
#define rb_is_red(r) (!rb_color(r))
|
||||||
|
#define rb_is_black(r) rb_color(r)
|
||||||
|
#define rb_set_red(r) do { (r)->rb_parent_color &= ~1; } while (0)
|
||||||
|
#define rb_set_black(r) do { (r)->rb_parent_color |= 1; } while (0)
|
||||||
|
|
||||||
|
static __inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
|
||||||
|
{
|
||||||
|
rb->rb_parent_color = (rb->rb_parent_color & 3) | (size_t)p;
|
||||||
|
}
|
||||||
|
static __inline void rb_set_color(struct rb_node *rb, int color)
|
||||||
|
{
|
||||||
|
rb->rb_parent_color = (rb->rb_parent_color & ~1) | color;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RB_ROOT (struct rb_root) { NULL, }
|
||||||
|
#define rb_entry(ptr, type, member) CONTAINING_RECORD(ptr, type, member)
|
||||||
|
|
||||||
|
#define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL)
|
||||||
|
#define RB_EMPTY_NODE(node) (rb_parent(node) == node)
|
||||||
|
#define RB_CLEAR_NODE(node) (rb_set_parent(node, node))
|
||||||
|
|
||||||
|
extern void rb_insert_color(struct rb_node *, struct rb_root *);
|
||||||
|
extern void rb_erase(struct rb_node *, struct rb_root *);
|
||||||
|
|
||||||
|
/* Find logical next and previous nodes in a tree */
|
||||||
|
extern struct rb_node *rb_next(const struct rb_node *);
|
||||||
|
extern struct rb_node *rb_prev(const struct rb_node *);
|
||||||
|
extern struct rb_node *rb_first(const struct rb_root *);
|
||||||
|
extern struct rb_node *rb_last(const struct rb_root *);
|
||||||
|
|
||||||
|
/* Fast replacement of a single node without remove/rebalance/add/rebalance */
|
||||||
|
extern void rb_replace_node(struct rb_node *victim, struct rb_node *new,
|
||||||
|
struct rb_root *root);
|
||||||
|
|
||||||
|
static __inline void rb_link_node(struct rb_node * node, struct rb_node * parent,
|
||||||
|
struct rb_node ** rb_link)
|
||||||
|
{
|
||||||
|
node->rb_parent_color = (size_t)parent;
|
||||||
|
node->rb_left = node->rb_right = NULL;
|
||||||
|
|
||||||
|
*rb_link = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _LINUX_RBTREE_H */
|
||||||
627
daemon/readdir.c
Normal file
627
daemon/readdir.c
Normal file
|
|
@ -0,0 +1,627 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <strsafe.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "from_kernel.h"
|
||||||
|
#include "nfs41_ops.h"
|
||||||
|
#include "daemon_debug.h"
|
||||||
|
#include "upcall.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef union _FILE_DIR_INFO_UNION {
|
||||||
|
ULONG NextEntryOffset;
|
||||||
|
FILE_NAMES_INFORMATION fni;
|
||||||
|
FILE_DIRECTORY_INFO fdi;
|
||||||
|
FILE_FULL_DIR_INFO ffdi;
|
||||||
|
FILE_ID_FULL_DIR_INFO fifdi;
|
||||||
|
FILE_BOTH_DIR_INFORMATION fbdi;
|
||||||
|
FILE_ID_BOTH_DIR_INFO fibdi;
|
||||||
|
} FILE_DIR_INFO_UNION, *PFILE_DIR_INFO_UNION;
|
||||||
|
|
||||||
|
|
||||||
|
/* NFS41_DIR_QUERY */
|
||||||
|
int parse_readdir(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
readdir_upcall_args *args = &upcall->args.readdir;
|
||||||
|
|
||||||
|
status = safe_read(&buffer, &length, &args->query_class, sizeof(args->query_class));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->buf_len, sizeof(args->buf_len));
|
||||||
|
if (status) goto out;
|
||||||
|
status = get_name(&buffer, &length, args->filter);
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->initial, sizeof(args->initial));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->restart, sizeof(args->restart));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->single, sizeof(args->single));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->root, sizeof(args->root));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->state, sizeof(args->state));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->cookie, sizeof(args->cookie));
|
||||||
|
if (status) goto out;
|
||||||
|
if (args->cookie == INVALID_HANDLE_VALUE) {
|
||||||
|
dprintf(1, "upcall passing empty cookie\n");
|
||||||
|
args->cookie = NULL;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
if (status)
|
||||||
|
eprintf("parsing NFS41_DIR_QUERY failed with %d\n", status);
|
||||||
|
else
|
||||||
|
dprintf(1, "parsing NFS41_DIR_QUERY: info_class=%d buf_len=%d "
|
||||||
|
"filter='%s'\n\tInitial\\Restart\\Single %d\\%d\\%d "
|
||||||
|
"root=0x%p state=0x%p cookie=0x%p\n",
|
||||||
|
args->query_class, args->buf_len, args->filter,
|
||||||
|
args->initial, args->restart, args->single,
|
||||||
|
args->root, args->state, args->cookie);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FILTER_STAR '*'
|
||||||
|
#define FILTER_QM '>'
|
||||||
|
|
||||||
|
static __inline int readdir_has_wildcards(
|
||||||
|
const char *filter)
|
||||||
|
{
|
||||||
|
return strchr(filter, FILTER_STAR) || strchr(filter, FILTER_QM);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline const char* skip_stars(
|
||||||
|
const char *filter)
|
||||||
|
{
|
||||||
|
while (*filter == FILTER_STAR)
|
||||||
|
filter++;
|
||||||
|
return filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int readdir_filter(
|
||||||
|
const char *filter,
|
||||||
|
const char *name)
|
||||||
|
{
|
||||||
|
const char *f = filter, *n = name;
|
||||||
|
|
||||||
|
while (*f && *n) {
|
||||||
|
if (*f == FILTER_STAR) {
|
||||||
|
f = skip_stars(f);
|
||||||
|
if (*f == '\0')
|
||||||
|
return 1;
|
||||||
|
while (*n && !readdir_filter(f, n))
|
||||||
|
n++;
|
||||||
|
} else if (*f == FILTER_QM || *f == *n) {
|
||||||
|
f++;
|
||||||
|
n++;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return *f == *n || *skip_stars(f) == '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t readdir_size_for_entry(
|
||||||
|
IN int query_class,
|
||||||
|
IN uint32_t wname_size)
|
||||||
|
{
|
||||||
|
uint32_t needed = wname_size;
|
||||||
|
switch (query_class)
|
||||||
|
{
|
||||||
|
case FileDirectoryInformation:
|
||||||
|
needed += FIELD_OFFSET(FILE_DIRECTORY_INFO, FileName);
|
||||||
|
break;
|
||||||
|
case FileIdFullDirectoryInformation:
|
||||||
|
needed += FIELD_OFFSET(FILE_ID_FULL_DIR_INFO, FileName);
|
||||||
|
break;
|
||||||
|
case FileFullDirectoryInformation:
|
||||||
|
needed += FIELD_OFFSET(FILE_FULL_DIR_INFO, FileName);
|
||||||
|
break;
|
||||||
|
case FileIdBothDirectoryInformation:
|
||||||
|
needed += FIELD_OFFSET(FILE_ID_BOTH_DIR_INFO, FileName);
|
||||||
|
break;
|
||||||
|
case FileBothDirectoryInformation:
|
||||||
|
needed += FIELD_OFFSET(FILE_BOTH_DIR_INFORMATION, FileName);
|
||||||
|
break;
|
||||||
|
case FileNamesInformation:
|
||||||
|
needed += FIELD_OFFSET(FILE_NAMES_INFORMATION, FileName);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
eprintf("unhandled dir query class %d\n", query_class);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return needed;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void readdir_copy_dir_info(
|
||||||
|
IN nfs41_readdir_entry *entry,
|
||||||
|
IN PFILE_DIR_INFO_UNION info)
|
||||||
|
{
|
||||||
|
info->fdi.FileIndex = 0;
|
||||||
|
nfs_time_to_file_time(&entry->attr_info.time_create,
|
||||||
|
&info->fdi.CreationTime);
|
||||||
|
nfs_time_to_file_time(&entry->attr_info.time_access,
|
||||||
|
&info->fdi.LastAccessTime);
|
||||||
|
nfs_time_to_file_time(&entry->attr_info.time_modify,
|
||||||
|
&info->fdi.LastWriteTime);
|
||||||
|
/* XXX: was using 'change' attr, but that wasn't giving a time */
|
||||||
|
nfs_time_to_file_time(&entry->attr_info.time_modify,
|
||||||
|
&info->fdi.ChangeTime);
|
||||||
|
info->fdi.EndOfFile.QuadPart =
|
||||||
|
info->fdi.AllocationSize.QuadPart =
|
||||||
|
entry->attr_info.size;
|
||||||
|
info->fdi.FileAttributes = nfs_file_info_to_attributes(
|
||||||
|
&entry->attr_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void readdir_copy_shortname(
|
||||||
|
IN LPCWSTR name,
|
||||||
|
OUT LPWSTR name_out,
|
||||||
|
OUT CCHAR *name_size_out)
|
||||||
|
{
|
||||||
|
/* GetShortPathName returns number of characters, not including \0 */
|
||||||
|
*name_size_out = (CCHAR)GetShortPathNameW(name, name_out, 12);
|
||||||
|
if (*name_size_out) {
|
||||||
|
*name_size_out++;
|
||||||
|
*name_size_out *= sizeof(WCHAR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void readdir_copy_full_dir_info(
|
||||||
|
IN nfs41_readdir_entry *entry,
|
||||||
|
IN PFILE_DIR_INFO_UNION info)
|
||||||
|
{
|
||||||
|
readdir_copy_dir_info(entry, info);
|
||||||
|
info->fifdi.EaSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void readdir_copy_both_dir_info(
|
||||||
|
IN nfs41_readdir_entry *entry,
|
||||||
|
IN LPWSTR wname,
|
||||||
|
IN PFILE_DIR_INFO_UNION info)
|
||||||
|
{
|
||||||
|
readdir_copy_full_dir_info(entry, info);
|
||||||
|
readdir_copy_shortname(wname, info->fbdi.ShortName,
|
||||||
|
&info->fbdi.ShortNameLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void readdir_copy_filename(
|
||||||
|
IN LPCWSTR name,
|
||||||
|
IN uint32_t name_size,
|
||||||
|
OUT LPWSTR name_out,
|
||||||
|
OUT ULONG *name_size_out)
|
||||||
|
{
|
||||||
|
*name_size_out = name_size;
|
||||||
|
memcpy(name_out, name, name_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int readdir_copy_entry(
|
||||||
|
IN readdir_upcall_args *args,
|
||||||
|
IN nfs41_readdir_entry *entry,
|
||||||
|
IN OUT unsigned char **dst_pos,
|
||||||
|
IN OUT uint32_t *dst_len)
|
||||||
|
{
|
||||||
|
int status = 0;
|
||||||
|
WCHAR wname[NFS4_OPAQUE_LIMIT];
|
||||||
|
uint32_t wname_len, wname_size, needed;
|
||||||
|
PFILE_DIR_INFO_UNION info;
|
||||||
|
|
||||||
|
wname_len = MultiByteToWideChar(CP_UTF8, 0,
|
||||||
|
entry->name, entry->name_len, wname, NFS4_OPAQUE_LIMIT);
|
||||||
|
wname_size = (wname_len - 1) * sizeof(WCHAR);
|
||||||
|
|
||||||
|
needed = readdir_size_for_entry(args->query_class, wname_size);
|
||||||
|
if (!needed || needed > *dst_len) {
|
||||||
|
status = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
info = (PFILE_DIR_INFO_UNION)*dst_pos;
|
||||||
|
info->NextEntryOffset = align8(needed);
|
||||||
|
*dst_pos += info->NextEntryOffset;
|
||||||
|
*dst_len -= info->NextEntryOffset;
|
||||||
|
|
||||||
|
switch (args->query_class)
|
||||||
|
{
|
||||||
|
case FileNamesInformation:
|
||||||
|
info->fni.FileIndex = 0;
|
||||||
|
readdir_copy_filename(wname, wname_size,
|
||||||
|
info->fni.FileName, &info->fni.FileNameLength);
|
||||||
|
break;
|
||||||
|
case FileDirectoryInformation:
|
||||||
|
readdir_copy_dir_info(entry, info);
|
||||||
|
readdir_copy_filename(wname, wname_size,
|
||||||
|
info->fdi.FileName, &info->fdi.FileNameLength);
|
||||||
|
break;
|
||||||
|
case FileFullDirectoryInformation:
|
||||||
|
readdir_copy_full_dir_info(entry, info);
|
||||||
|
readdir_copy_filename(wname, wname_size,
|
||||||
|
info->ffdi.FileName, &info->ffdi.FileNameLength);
|
||||||
|
break;
|
||||||
|
case FileIdFullDirectoryInformation:
|
||||||
|
readdir_copy_full_dir_info(entry, info);
|
||||||
|
info->fibdi.FileId.QuadPart = (LONGLONG)entry->attr_info.fileid;
|
||||||
|
readdir_copy_filename(wname, wname_size,
|
||||||
|
info->fifdi.FileName, &info->fifdi.FileNameLength);
|
||||||
|
break;
|
||||||
|
case FileBothDirectoryInformation:
|
||||||
|
readdir_copy_both_dir_info(entry, wname, info);
|
||||||
|
readdir_copy_filename(wname, wname_size,
|
||||||
|
info->fbdi.FileName, &info->fbdi.FileNameLength);
|
||||||
|
break;
|
||||||
|
case FileIdBothDirectoryInformation:
|
||||||
|
readdir_copy_both_dir_info(entry, wname, info);
|
||||||
|
info->fibdi.FileId.QuadPart = (LONGLONG)entry->attr_info.fileid;
|
||||||
|
readdir_copy_filename(wname, wname_size,
|
||||||
|
info->fibdi.FileName, &info->fibdi.FileNameLength);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
eprintf("unhandled dir query class %d\n", args->query_class);
|
||||||
|
status = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define COOKIE_DOT ((uint64_t)-2)
|
||||||
|
#define COOKIE_DOTDOT ((uint64_t)-1)
|
||||||
|
|
||||||
|
int readdir_add_dots(
|
||||||
|
IN readdir_upcall_args *args,
|
||||||
|
IN OUT unsigned char *entry_buf,
|
||||||
|
IN uint32_t entry_buf_len,
|
||||||
|
OUT uint32_t *len_out,
|
||||||
|
OUT uint32_t **last_offset)
|
||||||
|
{
|
||||||
|
int status = 0;
|
||||||
|
const uint32_t entry_len = (uint32_t)FIELD_OFFSET(nfs41_readdir_entry, name);
|
||||||
|
nfs41_readdir_entry *entry;
|
||||||
|
nfs41_open_state *state = args->state;
|
||||||
|
|
||||||
|
*len_out = 0;
|
||||||
|
*last_offset = NULL;
|
||||||
|
switch (args->cookie->cookie) {
|
||||||
|
case 0:
|
||||||
|
if (entry_buf_len < entry_len + 2) {
|
||||||
|
status = ERROR_BUFFER_OVERFLOW;
|
||||||
|
dprintf(1, "not enough room for '.' entry.\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry = (nfs41_readdir_entry*)entry_buf;
|
||||||
|
ZeroMemory(&entry->attr_info, sizeof(nfs41_file_info));
|
||||||
|
|
||||||
|
status = nfs41_cached_getattr(state->session,
|
||||||
|
&state->file, &entry->attr_info);
|
||||||
|
if (status) {
|
||||||
|
dprintf(1, "failed to add '.' entry.\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
entry->cookie = COOKIE_DOT;
|
||||||
|
entry->name_len = 2;
|
||||||
|
StringCbCopyA(entry->name, entry->name_len, ".");
|
||||||
|
entry->next_entry_offset = entry_len + entry->name_len;
|
||||||
|
|
||||||
|
entry_buf += entry->next_entry_offset;
|
||||||
|
entry_buf_len -= entry->next_entry_offset;
|
||||||
|
*len_out += entry->next_entry_offset;
|
||||||
|
*last_offset = &entry->next_entry_offset;
|
||||||
|
if (args->single)
|
||||||
|
break;
|
||||||
|
/* else no break! */
|
||||||
|
case COOKIE_DOT:
|
||||||
|
if (entry_buf_len < entry_len + 3) {
|
||||||
|
status = ERROR_BUFFER_OVERFLOW;
|
||||||
|
dprintf(1, "not enough room for '..' entry.\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
/* XXX: this skips '..' when listing root fh */
|
||||||
|
if (state->file.name.len == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
entry = (nfs41_readdir_entry*)entry_buf;
|
||||||
|
ZeroMemory(&entry->attr_info, sizeof(nfs41_file_info));
|
||||||
|
|
||||||
|
status = nfs41_cached_getattr(state->session,
|
||||||
|
&state->parent, &entry->attr_info);
|
||||||
|
if (status) {
|
||||||
|
status = ERROR_FILE_NOT_FOUND;
|
||||||
|
dprintf(1, "failed to add '..' entry.\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
entry->cookie = COOKIE_DOTDOT;
|
||||||
|
entry->name_len = 3;
|
||||||
|
StringCbCopyA(entry->name, entry->name_len, "..");
|
||||||
|
entry->next_entry_offset = entry_len + entry->name_len;
|
||||||
|
|
||||||
|
entry_buf += entry->next_entry_offset;
|
||||||
|
entry_buf_len -= entry->next_entry_offset;
|
||||||
|
*len_out += entry->next_entry_offset;
|
||||||
|
*last_offset = &entry->next_entry_offset;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (args->cookie->cookie == COOKIE_DOTDOT ||
|
||||||
|
args->cookie->cookie == COOKIE_DOT)
|
||||||
|
ZeroMemory(args->cookie, sizeof(nfs41_readdir_cookie));
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int single_lookup(
|
||||||
|
IN nfs41_root *root,
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN nfs41_path_fh *parent,
|
||||||
|
IN const char *filter,
|
||||||
|
IN bitmap4 *attr_request,
|
||||||
|
OUT nfs41_readdir_entry *entry)
|
||||||
|
{
|
||||||
|
nfs41_abs_path path;
|
||||||
|
nfs41_path_fh file;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
entry->cookie = 0;
|
||||||
|
entry->name_len = (uint32_t)strlen(filter) + 1;
|
||||||
|
StringCbCopyA(entry->name, entry->name_len, filter);
|
||||||
|
entry->next_entry_offset = 0;
|
||||||
|
|
||||||
|
/* format an absolute path 'parent\filter' */
|
||||||
|
InitializeSRWLock(&path.lock);
|
||||||
|
abs_path_copy(&path, parent->path);
|
||||||
|
if (path.len + entry->name_len >= NFS41_MAX_PATH_LEN) {
|
||||||
|
status = ERROR_BUFFER_OVERFLOW;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
StringCchPrintfA(path.path + path.len,
|
||||||
|
NFS41_MAX_PATH_LEN - path.len, "\\%s", entry->name);
|
||||||
|
path.len += (unsigned short)entry->name_len;
|
||||||
|
|
||||||
|
path_fh_init(&file, &path);
|
||||||
|
|
||||||
|
status = nfs41_lookup(root, session, &path,
|
||||||
|
NULL, &file, &entry->attr_info, NULL);
|
||||||
|
if (status) {
|
||||||
|
dprintf(1, "nfs41_lookup failed with %s\n", nfs_error_string(status));
|
||||||
|
status = nfs_to_windows_error(status, ERROR_BAD_NET_RESP);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int handle_readdir(nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
readdir_upcall_args *args = &upcall->args.readdir;
|
||||||
|
nfs41_open_state *state = args->state;
|
||||||
|
unsigned char *entry_buf = NULL;
|
||||||
|
uint32_t entry_buf_len;
|
||||||
|
bitmap4 attr_request;
|
||||||
|
bool_t eof;
|
||||||
|
|
||||||
|
dprintf(1, "-> handle_nfs41_dirquery(%s,%d,%d,%d)\n",
|
||||||
|
args->filter, args->initial, args->restart, args->single);
|
||||||
|
|
||||||
|
args->buf = NULL;
|
||||||
|
args->query_reply_len = 0;
|
||||||
|
|
||||||
|
if (args->cookie) { /* cookie exists */
|
||||||
|
if (args->restart) {
|
||||||
|
dprintf(1, "restarting; clearing previous cookie (%d %p)\n",
|
||||||
|
args->cookie->cookie, args->cookie);
|
||||||
|
ZeroMemory(args->cookie, sizeof(nfs41_readdir_cookie));
|
||||||
|
} else if (args->initial) { /* shouldn't happen */
|
||||||
|
dprintf(1, "*** initial; clearing previous cookie (%d %p)!\n",
|
||||||
|
args->cookie->cookie, args->cookie);
|
||||||
|
ZeroMemory(args->cookie, sizeof(nfs41_readdir_cookie));
|
||||||
|
} else
|
||||||
|
dprintf(1, "resuming enumeration with cookie %d.\n",
|
||||||
|
args->cookie->cookie);
|
||||||
|
} else { /* cookie is null */
|
||||||
|
if (args->initial || args->restart) {
|
||||||
|
dprintf(1, "allocating memory for the 1st readdir cookie\n");
|
||||||
|
args->cookie = calloc(1, sizeof(nfs41_readdir_cookie));
|
||||||
|
if (args->cookie == NULL) {
|
||||||
|
status = GetLastError();
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dprintf(1, "handle_nfs41_readdir: EOF\n");
|
||||||
|
status = ERROR_NO_MORE_FILES;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
entry_buf = malloc(args->buf_len);
|
||||||
|
if (entry_buf == NULL) {
|
||||||
|
status = GetLastError();
|
||||||
|
goto out_free_cookie;
|
||||||
|
}
|
||||||
|
fetch_entries:
|
||||||
|
entry_buf_len = args->buf_len;
|
||||||
|
|
||||||
|
init_getattr_request(&attr_request);
|
||||||
|
attr_request.arr[0] |= FATTR4_WORD0_RDATTR_ERROR;
|
||||||
|
|
||||||
|
if (readdir_has_wildcards((const char*)args->filter)) {
|
||||||
|
/* use READDIR for wildcards */
|
||||||
|
|
||||||
|
uint32_t dots_len = 0;
|
||||||
|
uint32_t *dots_next_offset = NULL;
|
||||||
|
|
||||||
|
if (args->filter[0] == '*' && args->filter[1] == '\0') {
|
||||||
|
status = readdir_add_dots(args, entry_buf,
|
||||||
|
entry_buf_len, &dots_len, &dots_next_offset);
|
||||||
|
if (status)
|
||||||
|
goto out_free_cookie;
|
||||||
|
entry_buf_len -= dots_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dots_len && args->single) {
|
||||||
|
dprintf(2, "skipping nfs41_readdir because the single query "
|
||||||
|
"will use . or ..\n");
|
||||||
|
entry_buf_len = 0;
|
||||||
|
eof = 0;
|
||||||
|
} else {
|
||||||
|
dprintf(2, "calling nfs41_readdir with cookie %d %p \n",
|
||||||
|
args->cookie->cookie, args->cookie);
|
||||||
|
status = nfs41_readdir(state->session, &state->file,
|
||||||
|
&attr_request, args->cookie, entry_buf + dots_len,
|
||||||
|
&entry_buf_len, &eof);
|
||||||
|
if (status) {
|
||||||
|
dprintf(1, "nfs41_readdir failed with %s\n",
|
||||||
|
nfs_error_string(status));
|
||||||
|
status = nfs_to_windows_error(status, ERROR_BAD_NET_RESP);
|
||||||
|
goto out_free_cookie;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!entry_buf_len && dots_next_offset)
|
||||||
|
*dots_next_offset = 0;
|
||||||
|
entry_buf_len += dots_len;
|
||||||
|
} else {
|
||||||
|
/* use LOOKUP for single files */
|
||||||
|
nfs41_readdir_entry *entry = (nfs41_readdir_entry*)entry_buf;
|
||||||
|
entry->cookie = 0;
|
||||||
|
entry->name_len = (uint32_t)strlen(args->filter) + 1;
|
||||||
|
StringCbCopyA(entry->name, entry->name_len, args->filter);
|
||||||
|
entry->next_entry_offset = 0;
|
||||||
|
|
||||||
|
status = single_lookup(args->root, state->session,
|
||||||
|
&state->file, args->filter, &attr_request, entry);
|
||||||
|
if (status) {
|
||||||
|
dprintf(1, "single_lookup failed with %d\n", status);
|
||||||
|
goto out_free_cookie;
|
||||||
|
}
|
||||||
|
entry_buf_len = entry->name_len +
|
||||||
|
FIELD_OFFSET(nfs41_readdir_entry, name);
|
||||||
|
|
||||||
|
eof = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = args->initial ? ERROR_FILE_NOT_FOUND : ERROR_NO_MORE_FILES;
|
||||||
|
|
||||||
|
if (entry_buf_len) {
|
||||||
|
unsigned char *entry_pos = entry_buf;
|
||||||
|
unsigned char *dst_pos;
|
||||||
|
uint32_t dst_len = args->buf_len;
|
||||||
|
nfs41_readdir_entry *entry;
|
||||||
|
PULONG offset, last_offset = NULL;
|
||||||
|
|
||||||
|
if (args->buf == NULL) {
|
||||||
|
args->buf = malloc(args->buf_len);
|
||||||
|
if (args->buf == NULL) {
|
||||||
|
status = GetLastError();
|
||||||
|
goto out_free_cookie;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst_pos = args->buf;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
entry = (nfs41_readdir_entry*)entry_pos;
|
||||||
|
offset = (PULONG)dst_pos; /* ULONG NextEntryOffset */
|
||||||
|
|
||||||
|
dprintf(2, "filter %s looking at %s with cookie %d\n",
|
||||||
|
args->filter, entry->name, entry->cookie);
|
||||||
|
if (readdir_filter((const char*)args->filter, entry->name)) {
|
||||||
|
if (readdir_copy_entry(args, entry, &dst_pos, &dst_len)) {
|
||||||
|
eof = 0;
|
||||||
|
dprintf(2, "not enough space to copy entry %s (cookie %d)\n",
|
||||||
|
entry->name, entry->cookie);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
last_offset = offset;
|
||||||
|
status = NO_ERROR;
|
||||||
|
}
|
||||||
|
args->cookie->cookie = entry->cookie;
|
||||||
|
|
||||||
|
/* last entry we got from the server */
|
||||||
|
if (!entry->next_entry_offset)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* we found our single entry, but the server has more */
|
||||||
|
if (args->single && last_offset) {
|
||||||
|
eof = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
entry_pos += entry->next_entry_offset;
|
||||||
|
}
|
||||||
|
args->query_reply_len = args->buf_len - dst_len;
|
||||||
|
if (last_offset) {
|
||||||
|
*last_offset = 0;
|
||||||
|
} else if (!eof) {
|
||||||
|
dprintf(1, "no entries matched; fetch more\n");
|
||||||
|
goto fetch_entries;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eof) {
|
||||||
|
dprintf(1, "we don't need to save a cookie\n");
|
||||||
|
goto out_free_cookie;
|
||||||
|
} else
|
||||||
|
dprintf(1, "saving cookie %d %p\n", args->cookie->cookie, args->cookie);
|
||||||
|
|
||||||
|
out_free_entry:
|
||||||
|
free(entry_buf);
|
||||||
|
out:
|
||||||
|
dprintf(1, "<- handle_nfs41_dirquery(%s,%d,%d,%d) returning ",
|
||||||
|
args->filter, args->initial, args->restart, args->single);
|
||||||
|
if (status) {
|
||||||
|
switch (status) {
|
||||||
|
case ERROR_FILE_NOT_FOUND:
|
||||||
|
dprintf(1, "ERROR_FILE_NOT_FOUND.\n");
|
||||||
|
break;
|
||||||
|
case ERROR_NO_MORE_FILES:
|
||||||
|
dprintf(1, "ERROR_NO_MORE_FILES.\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dprintf(1, "error code %d.\n", status);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
free(args->buf);
|
||||||
|
args->buf = NULL;
|
||||||
|
} else {
|
||||||
|
dprintf(1, "success!\n");
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
out_free_cookie:
|
||||||
|
free(args->cookie);
|
||||||
|
args->cookie = NULL;
|
||||||
|
goto out_free_entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
int marshall_readdir(unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
readdir_upcall_args *args = &upcall->args.readdir;
|
||||||
|
|
||||||
|
status = safe_write(&buffer, length, &args->query_reply_len, sizeof(args->query_reply_len));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_write(&buffer, length, args->buf, args->query_reply_len);
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_write(&buffer, length, &args->cookie, sizeof(args->cookie));
|
||||||
|
out:
|
||||||
|
free(args->buf);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
307
daemon/readwrite.c
Normal file
307
daemon/readwrite.c
Normal file
|
|
@ -0,0 +1,307 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "nfs41_ops.h"
|
||||||
|
#include "name_cache.h"
|
||||||
|
#include "upcall.h"
|
||||||
|
#include "daemon_debug.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
|
||||||
|
int parse_rw(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
readwrite_upcall_args *args = &upcall->args.rw;
|
||||||
|
|
||||||
|
status = safe_read(&buffer, &length, &args->len, sizeof(args->len));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->offset, sizeof(args->offset));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->buffer, sizeof(args->buffer));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->root, sizeof(args->root));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->state, sizeof(args->state));
|
||||||
|
out:
|
||||||
|
if (status)
|
||||||
|
eprintf("parsing %s failed with %d\n",
|
||||||
|
opcode2string(upcall->opcode), status);
|
||||||
|
else
|
||||||
|
dprintf(1, "parsing %s len=%ld offset=%ld buf=%p root=%p "
|
||||||
|
"open_state=0x%p\n", opcode2string(upcall->opcode), args->len,
|
||||||
|
args->offset, args->buffer, args->root, args->state);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NFS41_READ */
|
||||||
|
static int read_from_mds(
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN stateid4 *stateid,
|
||||||
|
IN nfs41_path_fh *file,
|
||||||
|
IN uint64_t offset,
|
||||||
|
IN uint32_t length,
|
||||||
|
OUT unsigned char *buffer,
|
||||||
|
OUT ULONG *len_out)
|
||||||
|
{
|
||||||
|
int status = 0;
|
||||||
|
bool_t eof;
|
||||||
|
unsigned char *p = buffer;
|
||||||
|
ULONG to_rcv = length, reloffset = 0, len = 0;
|
||||||
|
const uint32_t maxreadsize = max_read_size(session, &file->fh);
|
||||||
|
|
||||||
|
if (to_rcv > maxreadsize)
|
||||||
|
dprintf(1, "handle_nfs41_read: reading %d in chunks of %d\n",
|
||||||
|
to_rcv, maxreadsize);
|
||||||
|
|
||||||
|
while(to_rcv > 0) {
|
||||||
|
uint32_t bytes_read = 0, chunk = min(to_rcv, maxreadsize);
|
||||||
|
|
||||||
|
status = nfs41_read(session, file, stateid,
|
||||||
|
offset + reloffset, chunk, p, &bytes_read, &eof);
|
||||||
|
if (status && !len) {
|
||||||
|
status = nfs_to_windows_error(status, ERROR_NET_WRITE_FAULT);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
p += bytes_read;
|
||||||
|
to_rcv -= bytes_read;
|
||||||
|
len += bytes_read;
|
||||||
|
offset += bytes_read;
|
||||||
|
if (status) {
|
||||||
|
status = NO_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (eof) {
|
||||||
|
if (!len)
|
||||||
|
status = ERROR_HANDLE_EOF;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
*len_out = len;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int read_from_pnfs(
|
||||||
|
IN nfs41_root *root,
|
||||||
|
IN nfs41_open_state *state,
|
||||||
|
IN stateid4 *stateid,
|
||||||
|
IN uint64_t offset,
|
||||||
|
IN uint32_t length,
|
||||||
|
OUT unsigned char *buffer,
|
||||||
|
OUT ULONG *len_out)
|
||||||
|
{
|
||||||
|
pnfs_file_layout *layout;
|
||||||
|
enum pnfs_status pnfsstat;
|
||||||
|
int status = NO_ERROR;
|
||||||
|
|
||||||
|
pnfsstat = pnfs_open_state_layout(state->session->client->layouts,
|
||||||
|
state->session, state, PNFS_IOMODE_READ, offset, length, &layout);
|
||||||
|
if (pnfsstat) {
|
||||||
|
status = ERROR_NOT_SUPPORTED;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
pnfsstat = pnfs_read(root, state->session, &state->file, stateid,
|
||||||
|
layout, offset, length, buffer, len_out);
|
||||||
|
switch (pnfsstat) {
|
||||||
|
case PNFS_SUCCESS:
|
||||||
|
break;
|
||||||
|
case PNFS_READ_EOF:
|
||||||
|
status = ERROR_HANDLE_EOF;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
status = ERROR_READ_FAULT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int handle_read(nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
stateid4 stateid, *pstateid;
|
||||||
|
readwrite_upcall_args *args = &upcall->args.rw;
|
||||||
|
nfs41_open_state *state = args->state;
|
||||||
|
ULONG pnfs_bytes_read = 0;
|
||||||
|
int status = NO_ERROR;
|
||||||
|
|
||||||
|
pstateid = nfs41_lock_stateid_copy(&state->last_lock, &stateid);
|
||||||
|
if (pstateid == NULL)
|
||||||
|
pstateid = &state->stateid;
|
||||||
|
|
||||||
|
#ifdef PNFS_ENABLE_READ
|
||||||
|
status = read_from_pnfs(args->root, state, pstateid,
|
||||||
|
args->offset, args->len, args->buffer, &args->out_len);
|
||||||
|
|
||||||
|
if (status == NO_ERROR || status == ERROR_HANDLE_EOF)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (args->out_len) {
|
||||||
|
pnfs_bytes_read = args->out_len;
|
||||||
|
args->out_len = 0;
|
||||||
|
|
||||||
|
args->offset += pnfs_bytes_read;
|
||||||
|
args->buffer += pnfs_bytes_read;
|
||||||
|
args->len -= pnfs_bytes_read;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
status = read_from_mds(state->session, pstateid, &state->file,
|
||||||
|
args->offset, args->len, args->buffer, &args->out_len);
|
||||||
|
|
||||||
|
args->out_len += pnfs_bytes_read;
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NFS41_WRITE */
|
||||||
|
static int write_to_mds(
|
||||||
|
IN nfs41_session *session,
|
||||||
|
IN stateid4 *stateid,
|
||||||
|
IN nfs41_path_fh *file,
|
||||||
|
IN uint64_t offset,
|
||||||
|
IN uint32_t length,
|
||||||
|
IN unsigned char *buffer,
|
||||||
|
OUT ULONG *len_out)
|
||||||
|
{
|
||||||
|
nfs41_write_verf verf;
|
||||||
|
enum stable_how4 stable, committed;
|
||||||
|
unsigned char *p;
|
||||||
|
const uint32_t maxwritesize = max_write_size(session, &file->fh);
|
||||||
|
uint32_t to_send, reloffset, len;
|
||||||
|
int status = 0;
|
||||||
|
|
||||||
|
retry_write:
|
||||||
|
p = buffer;
|
||||||
|
to_send = length;
|
||||||
|
reloffset = 0;
|
||||||
|
len = 0;
|
||||||
|
stable = to_send <= maxwritesize ? DATA_SYNC4 : UNSTABLE4;
|
||||||
|
committed = DATA_SYNC4;
|
||||||
|
|
||||||
|
if (to_send > maxwritesize)
|
||||||
|
dprintf(1, "handle_nfs41_write: writing %d in chunks of %d\n",
|
||||||
|
to_send, maxwritesize);
|
||||||
|
|
||||||
|
while(to_send > 0) {
|
||||||
|
uint32_t bytes_written = 0, chunk = min(to_send, maxwritesize);
|
||||||
|
|
||||||
|
status = nfs41_write(session, file, stateid, p, chunk,
|
||||||
|
offset + reloffset, stable, &bytes_written, &verf);
|
||||||
|
if (status && !len)
|
||||||
|
goto out;
|
||||||
|
p += bytes_written;
|
||||||
|
to_send -= bytes_written;
|
||||||
|
len += bytes_written;
|
||||||
|
reloffset += bytes_written;
|
||||||
|
if (status) {
|
||||||
|
status = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!verify_write(&verf, &committed))
|
||||||
|
goto retry_write;
|
||||||
|
}
|
||||||
|
if (committed == UNSTABLE4) {
|
||||||
|
dprintf(1, "sending COMMIT for offset=%d and len=%d\n", offset, len);
|
||||||
|
status = nfs41_commit(session, file, offset, len, 1);
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
*len_out = len;
|
||||||
|
return nfs_to_windows_error(status, ERROR_NET_WRITE_FAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int write_to_pnfs(
|
||||||
|
IN nfs41_root *root,
|
||||||
|
IN nfs41_open_state *state,
|
||||||
|
IN stateid4 *stateid,
|
||||||
|
IN uint64_t offset,
|
||||||
|
IN uint32_t length,
|
||||||
|
IN unsigned char *buffer,
|
||||||
|
OUT ULONG *len_out)
|
||||||
|
{
|
||||||
|
pnfs_file_layout *layout;
|
||||||
|
enum pnfs_status pnfsstat;
|
||||||
|
int status = NO_ERROR;
|
||||||
|
|
||||||
|
pnfsstat = pnfs_open_state_layout(state->session->client->layouts,
|
||||||
|
state->session, state, PNFS_IOMODE_RW, offset, length, &layout);
|
||||||
|
if (pnfsstat) {
|
||||||
|
status = ERROR_NOT_SUPPORTED;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
pnfsstat = pnfs_write(root, state->session, &state->file, stateid,
|
||||||
|
layout, offset, length, buffer, len_out);
|
||||||
|
if (pnfsstat) {
|
||||||
|
status = ERROR_WRITE_FAULT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int handle_write(nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
stateid4 stateid, *pstateid = NULL;
|
||||||
|
readwrite_upcall_args *args = &upcall->args.rw;
|
||||||
|
nfs41_open_state *state = args->state;
|
||||||
|
ULONG pnfs_bytes_written = 0;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
pstateid = nfs41_lock_stateid_copy(&state->last_lock, &stateid);
|
||||||
|
if (pstateid == NULL)
|
||||||
|
pstateid = &state->stateid;
|
||||||
|
|
||||||
|
#ifdef PNFS_ENABLE_WRITE
|
||||||
|
status = write_to_pnfs(args->root, args->state, pstateid,
|
||||||
|
args->offset, args->len, args->buffer, &args->out_len);
|
||||||
|
|
||||||
|
if (status == NO_ERROR)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (args->out_len) {
|
||||||
|
pnfs_bytes_written = args->out_len;
|
||||||
|
args->out_len = 0;
|
||||||
|
|
||||||
|
args->offset += pnfs_bytes_written;
|
||||||
|
args->buffer += pnfs_bytes_written;
|
||||||
|
args->len -= pnfs_bytes_written;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
status = write_to_mds(state->session, pstateid, &state->file,
|
||||||
|
args->offset, args->len, args->buffer, &args->out_len);
|
||||||
|
|
||||||
|
args->out_len += pnfs_bytes_written;
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int marshall_rw(unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
readwrite_upcall_args *args = &upcall->args.rw;
|
||||||
|
return safe_write(&buffer, length, &args->out_len, sizeof(args->out_len));
|
||||||
|
}
|
||||||
491
daemon/setattr.c
Normal file
491
daemon/setattr.c
Normal file
|
|
@ -0,0 +1,491 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <strsafe.h>
|
||||||
|
|
||||||
|
#include "from_kernel.h"
|
||||||
|
#include "nfs41_ops.h"
|
||||||
|
#include "name_cache.h"
|
||||||
|
#include "upcall.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "daemon_debug.h"
|
||||||
|
|
||||||
|
|
||||||
|
int parse_setattr(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
setattr_upcall_args *args = &upcall->args.setattr;
|
||||||
|
|
||||||
|
ZeroMemory(&args->path, sizeof(nfs41_abs_path));
|
||||||
|
status = get_abs_path(&buffer, &length, &args->path);
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->set_class, sizeof(args->set_class));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->buf_len, sizeof(args->buf_len));
|
||||||
|
if (status) goto out;
|
||||||
|
args->buf = malloc(args->buf_len);
|
||||||
|
if (args->buf == NULL) {
|
||||||
|
status = GetLastError();
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
status = safe_read(&buffer, &length, args->buf, args->buf_len);
|
||||||
|
if (status) goto out_free;
|
||||||
|
status = safe_read(&buffer, &length, &args->root, sizeof(args->root));
|
||||||
|
if (status) goto out_free;
|
||||||
|
status = safe_read(&buffer, &length, &args->state, sizeof(args->state));
|
||||||
|
if (status) goto out_free;
|
||||||
|
status = safe_read(&buffer, &length, &args->open_owner_id, sizeof(ULONG));
|
||||||
|
if (status) goto out_free;
|
||||||
|
status = safe_read(&buffer, &length, &args->access_mask, sizeof(ULONG));
|
||||||
|
if (status) goto out_free;
|
||||||
|
status = safe_read(&buffer, &length, &args->access_mode, sizeof(ULONG));
|
||||||
|
out:
|
||||||
|
if (status)
|
||||||
|
eprintf("parsing NFS41_FILE_SET failed with %d\n", status);
|
||||||
|
else
|
||||||
|
dprintf(1, "parsing NFS41_FILE_SET: filename='%s' info_class=%d "
|
||||||
|
"buf_len=%d root=%p open_state=%p\nopen_owner_id=%d "
|
||||||
|
"access_mask=%x access_mode=%x\n", args->path.path, args->set_class,
|
||||||
|
args->buf_len, args->root, args->state, args->open_owner_id,
|
||||||
|
args->access_mask, args->access_mode);
|
||||||
|
return status;
|
||||||
|
out_free:
|
||||||
|
free(args->buf);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void remove_unsupported_attrs(
|
||||||
|
IN const bitmap4 *supported_attrs,
|
||||||
|
IN OUT bitmap4 *attrs)
|
||||||
|
{
|
||||||
|
uint32_t i, count = 0;
|
||||||
|
dprintf(2, "remove_unsupported_attrs\n");
|
||||||
|
for (i = 0; i < 3; i++) {
|
||||||
|
dprintf(2, "\tmask[%d] = %12u", i, attrs->arr[i]);
|
||||||
|
dprintf(2, " & %12u", supported_attrs->arr[i]);
|
||||||
|
|
||||||
|
attrs->arr[i] &= supported_attrs->arr[i];
|
||||||
|
if (attrs->arr[i])
|
||||||
|
count = i+1;
|
||||||
|
|
||||||
|
dprintf(2, " = %12d\n", attrs->arr[i]);
|
||||||
|
}
|
||||||
|
attrs->count = min(attrs->count, count);
|
||||||
|
dprintf(2, "\tcount = %d\n", attrs->count);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int handle_nfs41_setattr(setattr_upcall_args *args)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
PFILE_BASIC_INFO basic_info = (PFILE_BASIC_INFO)args->buf;
|
||||||
|
nfs41_open_state *state = args->state;
|
||||||
|
nfs41_superblock *superblock = state->file.fh.superblock;
|
||||||
|
stateid4 stateid, *pstateid;
|
||||||
|
nfs41_file_info info;
|
||||||
|
|
||||||
|
pstateid = nfs41_lock_stateid_copy(&state->last_lock, &stateid);
|
||||||
|
if (pstateid == NULL)
|
||||||
|
pstateid = &state->stateid;
|
||||||
|
|
||||||
|
ZeroMemory(&info, sizeof(info));
|
||||||
|
|
||||||
|
/* hidden */
|
||||||
|
info.hidden = basic_info->FileAttributes & FILE_ATTRIBUTE_HIDDEN ? 1 : 0;
|
||||||
|
info.attrmask.arr[0] |= FATTR4_WORD0_HIDDEN;
|
||||||
|
info.attrmask.count = 1;
|
||||||
|
/* time_create */
|
||||||
|
if (basic_info->CreationTime.QuadPart > 0) {
|
||||||
|
file_time_to_nfs_time(&basic_info->CreationTime, &info.time_create);
|
||||||
|
info.attrmask.arr[1] |= FATTR4_WORD1_TIME_CREATE;
|
||||||
|
info.attrmask.count = 2;
|
||||||
|
}
|
||||||
|
/* time_access_set */
|
||||||
|
if (basic_info->LastAccessTime.QuadPart > 0) {
|
||||||
|
file_time_to_nfs_time(&basic_info->LastAccessTime, &info.time_access);
|
||||||
|
info.attrmask.arr[1] |= FATTR4_WORD1_TIME_ACCESS_SET;
|
||||||
|
info.attrmask.count = 2;
|
||||||
|
}
|
||||||
|
/* time_modify_set */
|
||||||
|
if (basic_info->LastWriteTime.QuadPart > 0) {
|
||||||
|
file_time_to_nfs_time(&basic_info->LastWriteTime, &info.time_modify);
|
||||||
|
info.attrmask.arr[1] |= FATTR4_WORD1_TIME_MODIFY_SET;
|
||||||
|
info.attrmask.count = 2;
|
||||||
|
}
|
||||||
|
/* mode */
|
||||||
|
if (basic_info->FileAttributes & FILE_ATTRIBUTE_READONLY) {
|
||||||
|
info.mode = 0444;
|
||||||
|
info.attrmask.arr[1] |= FATTR4_WORD1_MODE;
|
||||||
|
info.attrmask.count = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
AcquireSRWLockShared(&superblock->lock);
|
||||||
|
remove_unsupported_attrs(&superblock->supported_attrs, &info.attrmask);
|
||||||
|
ReleaseSRWLockShared(&superblock->lock);
|
||||||
|
|
||||||
|
if (!info.attrmask.count)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
status = nfs41_setattr(state->session, &state->file, pstateid, &info);
|
||||||
|
if (status)
|
||||||
|
dprintf(1, "nfs41_setattr() failed with error %s.\n",
|
||||||
|
nfs_error_string(status));
|
||||||
|
|
||||||
|
return nfs_to_windows_error(status, ERROR_NOT_SUPPORTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int handle_nfs41_remove(setattr_upcall_args *args)
|
||||||
|
{
|
||||||
|
nfs41_open_state *state = args->state;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
status = nfs41_remove(state->session, &state->parent,
|
||||||
|
&state->file.name);
|
||||||
|
if (status)
|
||||||
|
dprintf(1, "nfs41_remove() failed with error %s.\n",
|
||||||
|
nfs_error_string(status));
|
||||||
|
|
||||||
|
return nfs_to_windows_error(status, ERROR_ACCESS_DENIED);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void open_state_rename(
|
||||||
|
OUT nfs41_open_state *state,
|
||||||
|
IN const nfs41_abs_path *path)
|
||||||
|
{
|
||||||
|
AcquireSRWLockExclusive(&state->path.lock);
|
||||||
|
|
||||||
|
abs_path_copy(&state->path, path);
|
||||||
|
last_component(state->path.path, state->path.path + state->path.len,
|
||||||
|
&state->file.name);
|
||||||
|
last_component(state->path.path, state->file.name.name,
|
||||||
|
&state->parent.name);
|
||||||
|
|
||||||
|
ReleaseSRWLockExclusive(&state->path.lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int handle_nfs41_rename(setattr_upcall_args *args)
|
||||||
|
{
|
||||||
|
nfs41_open_state *state = args->state;
|
||||||
|
PFILE_RENAME_INFO rename = (PFILE_RENAME_INFO)args->buf;
|
||||||
|
nfs41_abs_path dst_path;
|
||||||
|
nfs41_path_fh dst_dir;
|
||||||
|
nfs41_component dst_name, *src_name;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
ZeroMemory(&dst_path, sizeof(dst_path));
|
||||||
|
src_name = &state->file.name;
|
||||||
|
|
||||||
|
if (rename->FileNameLength == 0) {
|
||||||
|
/* start from state->path instead of args->path, in case we got
|
||||||
|
* the file from a referred server */
|
||||||
|
AcquireSRWLockShared(&state->path.lock);
|
||||||
|
abs_path_copy(&args->path, &state->path);
|
||||||
|
ReleaseSRWLockShared(&state->path.lock);
|
||||||
|
|
||||||
|
path_fh_init(&dst_dir, &args->path);
|
||||||
|
fh_copy(&dst_dir.fh, &state->parent.fh);
|
||||||
|
|
||||||
|
create_silly_rename(&args->path, &state->file.fh, &dst_name);
|
||||||
|
dprintf(1, "silly rename: %s -> %s\n", src_name->name, dst_name.name);
|
||||||
|
|
||||||
|
status = nfs41_rename(state->session,
|
||||||
|
&state->parent, src_name,
|
||||||
|
&dst_dir, &dst_name);
|
||||||
|
if (status) {
|
||||||
|
dprintf(1, "nfs41_rename() failed with error %s.\n",
|
||||||
|
nfs_error_string(status));
|
||||||
|
status = nfs_to_windows_error(status, ERROR_ACCESS_DENIED);
|
||||||
|
} else {
|
||||||
|
/* rename state->path on success */
|
||||||
|
open_state_rename(state, &args->path);
|
||||||
|
}
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst_path.len = (unsigned short)WideCharToMultiByte(CP_UTF8, 0,
|
||||||
|
rename->FileName, rename->FileNameLength/sizeof(WCHAR),
|
||||||
|
dst_path.path, NFS41_MAX_PATH_LEN, NULL, NULL);
|
||||||
|
if (dst_path.len == 0) {
|
||||||
|
eprintf("WideCharToMultiByte failed to convert destination "
|
||||||
|
"filename %S.\n", rename->FileName);
|
||||||
|
status = ERROR_INVALID_PARAMETER;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
path_fh_init(&dst_dir, &dst_path);
|
||||||
|
|
||||||
|
/* the destination path is absolute, so start from the root session */
|
||||||
|
status = nfs41_lookup(args->root, nfs41_root_session(args->root),
|
||||||
|
&dst_path, &dst_dir, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
/* get the components after lookup in case a referral changed its path */
|
||||||
|
last_component(dst_path.path, dst_path.path + dst_path.len, &dst_name);
|
||||||
|
last_component(dst_path.path, dst_name.name, &dst_dir.name);
|
||||||
|
|
||||||
|
if (status == NO_ERROR) {
|
||||||
|
if (!rename->ReplaceIfExists) {
|
||||||
|
status = ERROR_FILE_EXISTS;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
} else if (status != ERROR_FILE_NOT_FOUND) {
|
||||||
|
dprintf(1, "nfs41_lookup('%s') failed to find destination "
|
||||||
|
"directory with %d\n", dst_path.path, status);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* http://tools.ietf.org/html/rfc5661#section-18.26.3
|
||||||
|
* "Source and target directories MUST reside on the same
|
||||||
|
* file system on the server." */
|
||||||
|
if (state->parent.fh.superblock != dst_dir.fh.superblock) {
|
||||||
|
status = ERROR_NOT_SAME_DEVICE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = nfs41_rename(state->session,
|
||||||
|
&state->parent, src_name,
|
||||||
|
&dst_dir, &dst_name);
|
||||||
|
if (status) {
|
||||||
|
dprintf(1, "nfs41_rename() failed with error %s.\n",
|
||||||
|
nfs_error_string(status));
|
||||||
|
status = nfs_to_windows_error(status, ERROR_ACCESS_DENIED);
|
||||||
|
} else {
|
||||||
|
/* rename state->path on success */
|
||||||
|
open_state_rename(state, &dst_path);
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int handle_nfs41_set_size(setattr_upcall_args *args)
|
||||||
|
{
|
||||||
|
nfs41_open_state *state = args->state;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
/* note: this is called with either FILE_END_OF_FILE_INFO or
|
||||||
|
* FILE_ALLOCATION_INFO, both of which contain a single LARGE_INTEGER */
|
||||||
|
PLARGE_INTEGER size = (PLARGE_INTEGER)args->buf;
|
||||||
|
stateid4 stateid, *pstateid;
|
||||||
|
nfs41_file_info info;
|
||||||
|
|
||||||
|
pstateid = nfs41_lock_stateid_copy(&state->last_lock, &stateid);
|
||||||
|
if (pstateid == NULL)
|
||||||
|
pstateid = &state->stateid;
|
||||||
|
|
||||||
|
ZeroMemory(&info, sizeof(info));
|
||||||
|
info.size = size->QuadPart;
|
||||||
|
|
||||||
|
info.attrmask.count = 1;
|
||||||
|
info.attrmask.arr[0] = FATTR4_WORD0_SIZE;
|
||||||
|
|
||||||
|
dprintf(2, "calling setattr() with size=%lld\n", info.size);
|
||||||
|
status = nfs41_setattr(state->session, &state->file, pstateid, &info);
|
||||||
|
if (status)
|
||||||
|
dprintf(1, "nfs41_setattr() failed with error %s.\n",
|
||||||
|
nfs_error_string(status));
|
||||||
|
|
||||||
|
return status = nfs_to_windows_error(status, ERROR_NOT_SUPPORTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
int handle_nfs41_link(setattr_upcall_args *args)
|
||||||
|
{
|
||||||
|
nfs41_open_state *state = args->state;
|
||||||
|
PFILE_LINK_INFORMATION link = (PFILE_LINK_INFORMATION)args->buf;
|
||||||
|
nfs41_abs_path dst_path;
|
||||||
|
nfs41_path_fh dst_dir;
|
||||||
|
nfs41_component dst_name;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
ZeroMemory(&dst_path, sizeof(dst_path));
|
||||||
|
|
||||||
|
dst_path.len = (unsigned short)WideCharToMultiByte(CP_UTF8, 0,
|
||||||
|
link->FileName, link->FileNameLength/sizeof(WCHAR),
|
||||||
|
dst_path.path, NFS41_MAX_PATH_LEN, NULL, NULL);
|
||||||
|
if (dst_path.len == 0) {
|
||||||
|
eprintf("WideCharToMultiByte failed to convert destination "
|
||||||
|
"filename %S.\n", link->FileName);
|
||||||
|
status = ERROR_INVALID_PARAMETER;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
path_fh_init(&dst_dir, &dst_path);
|
||||||
|
|
||||||
|
/* the destination path is absolute, so start from the root session */
|
||||||
|
status = nfs41_lookup(args->root, nfs41_root_session(args->root),
|
||||||
|
&dst_path, &dst_dir, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
/* get the components after lookup in case a referral changed its path */
|
||||||
|
last_component(dst_path.path, dst_path.path + dst_path.len, &dst_name);
|
||||||
|
last_component(dst_path.path, dst_name.name, &dst_dir.name);
|
||||||
|
|
||||||
|
if (status == NO_ERROR) {
|
||||||
|
if (!link->ReplaceIfExists) {
|
||||||
|
status = ERROR_FILE_EXISTS;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
} else if (status != ERROR_FILE_NOT_FOUND) {
|
||||||
|
dprintf(1, "nfs41_lookup('%s') failed to find destination "
|
||||||
|
"directory with %d\n", dst_path.path, status);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* http://tools.ietf.org/html/rfc5661#section-18.9.3
|
||||||
|
* "The existing file and the target directory must reside within
|
||||||
|
* the same file system on the server." */
|
||||||
|
if (state->file.fh.superblock != dst_dir.fh.superblock) {
|
||||||
|
status = ERROR_NOT_SAME_DEVICE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == NO_ERROR) {
|
||||||
|
/* LINK will return NFS4ERR_EXIST if the target file exists,
|
||||||
|
* so we have to remove it ourselves */
|
||||||
|
status = nfs41_remove(state->session, &dst_dir, &dst_name);
|
||||||
|
if (status) {
|
||||||
|
dprintf(1, "nfs41_remove() failed with error %s.\n",
|
||||||
|
nfs_error_string(status));
|
||||||
|
status = ERROR_FILE_EXISTS;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
status = nfs41_link(state->session, &state->file, &dst_dir, &dst_name);
|
||||||
|
if (status) {
|
||||||
|
dprintf(1, "nfs41_link() failed with error %s.\n",
|
||||||
|
nfs_error_string(status));
|
||||||
|
status = nfs_to_windows_error(status, ERROR_INVALID_PARAMETER);
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int handle_setattr(nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
setattr_upcall_args *args = &upcall->args.setattr;
|
||||||
|
nfs41_open_state *state = args->state;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
switch (args->set_class) {
|
||||||
|
case FileAllocationInformation:
|
||||||
|
case FileEndOfFileInformation:
|
||||||
|
if (!state->do_close) {
|
||||||
|
// get a stateid
|
||||||
|
uint32_t allow = 0, deny = 0;
|
||||||
|
StringCchPrintfA((LPSTR)state->owner.owner, NFS4_OPAQUE_LIMIT,
|
||||||
|
"%u", args->open_owner_id);
|
||||||
|
state->owner.owner_len = (uint32_t)strlen(
|
||||||
|
(const char*)state->owner.owner);
|
||||||
|
map_access_2_allowdeny(args->access_mask, args->access_mode, &allow, &deny);
|
||||||
|
status = nfs41_open(state->session, allow, deny,
|
||||||
|
OPEN4_NOCREATE, 0, state, NULL);
|
||||||
|
if (status) {
|
||||||
|
dprintf(1, "nfs41_open() failed with %s\n", nfs_error_string(status));
|
||||||
|
status = nfs_to_windows_error(status, ERROR_FILE_NOT_FOUND);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
state->do_close = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (args->set_class) {
|
||||||
|
case FileBasicInformation:
|
||||||
|
status = handle_nfs41_setattr(args);
|
||||||
|
break;
|
||||||
|
case FileDispositionInformation:
|
||||||
|
status = handle_nfs41_remove(args);
|
||||||
|
break;
|
||||||
|
case FileRenameInformation:
|
||||||
|
status = handle_nfs41_rename(args);
|
||||||
|
break;
|
||||||
|
case FileAllocationInformation:
|
||||||
|
case FileEndOfFileInformation:
|
||||||
|
status = handle_nfs41_set_size(args);
|
||||||
|
break;
|
||||||
|
case FileLinkInformation:
|
||||||
|
status = handle_nfs41_link(args);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
eprintf("unknown set_file information class %d\n",
|
||||||
|
args->set_class);
|
||||||
|
status = ERROR_NOT_SUPPORTED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
free(args->buf);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int marshall_setattr(unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
int parse_setexattr(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
setexattr_upcall_args *args = &upcall->args.setexattr;
|
||||||
|
|
||||||
|
status = safe_read(&buffer, &length, &args->root, sizeof(args->root));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->state, sizeof(args->state));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &args->mode, sizeof(args->mode));
|
||||||
|
out:
|
||||||
|
if (status)
|
||||||
|
eprintf("parsing NFS41_EA_SET failed with %d\n", status);
|
||||||
|
else
|
||||||
|
dprintf(1, "parsing NFS41_EA_SET: root=%p open_state=%p mode=%o\n",
|
||||||
|
args->root, args->state, args->mode);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int handle_setexattr(nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
setexattr_upcall_args *args = &upcall->args.setexattr;
|
||||||
|
nfs41_open_state *state = args->state;
|
||||||
|
stateid4 stateid, *pstateid;
|
||||||
|
nfs41_file_info info;
|
||||||
|
|
||||||
|
pstateid = nfs41_lock_stateid_copy(&state->last_lock, &stateid);
|
||||||
|
if (pstateid == NULL)
|
||||||
|
pstateid = &state->stateid;
|
||||||
|
|
||||||
|
ZeroMemory(&info, sizeof(info));
|
||||||
|
|
||||||
|
/* mode */
|
||||||
|
info.mode = args->mode;
|
||||||
|
info.attrmask.arr[1] |= FATTR4_WORD1_MODE;
|
||||||
|
info.attrmask.count = 2;
|
||||||
|
|
||||||
|
status = nfs41_setattr(state->session, &state->file, pstateid, &info);
|
||||||
|
if (status)
|
||||||
|
dprintf(1, "nfs41_setattr() failed with error %s.\n",
|
||||||
|
nfs_error_string(status));
|
||||||
|
|
||||||
|
return nfs_to_windows_error(status, ERROR_NOT_SUPPORTED);
|
||||||
|
}
|
||||||
|
|
||||||
|
int marshall_setexattr(unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
24
daemon/sources
Normal file
24
daemon/sources
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
TARGETTYPE=PROGRAM
|
||||||
|
TARGETNAME=nfsd
|
||||||
|
SOURCES=nfs41_daemon.c daemon_debug.c nfs41_ops.c nfs41_compound.c nfs41_xdr.c \
|
||||||
|
nfs41_server.c nfs41_client.c nfs41_superblock.c nfs41_session.c lookup.c \
|
||||||
|
mount.c open.c readwrite.c lock.c readdir.c getattr.c setattr.c upcall.c \
|
||||||
|
nfs41_rpc.c util.c pnfs_layout.c pnfs_device.c pnfs_debug.c pnfs_io.c \
|
||||||
|
name_cache.c namespace.c rbtree.c volume.c callback_server.c callback_xdr.c
|
||||||
|
UMTYPE=console
|
||||||
|
USE_LIBCMT=1
|
||||||
|
#USE_MSVCRT=1
|
||||||
|
INCLUDES=..\sys;..\dll;..\libtirpc\tirpc
|
||||||
|
TARGETLIBS=$(SDK_LIB_PATH)\ws2_32.lib $(SDK_LIB_PATH)\iphlpapi.lib \
|
||||||
|
..\libtirpc\src\obj$(BUILD_ALT_DIR)\*\libtirpc.lib
|
||||||
|
|
||||||
|
!IF 0
|
||||||
|
/W3 is default level
|
||||||
|
bump to /Wall, but suppress warnings generated by system includes,
|
||||||
|
as well as the following warnings:
|
||||||
|
4100 - unused function call arguments (we have lots of stubs)
|
||||||
|
4127 - constant conditional (I like to use if(0) or if(1))
|
||||||
|
4220 - varargs matching remaining parameters
|
||||||
|
4204 - nonstandard extension
|
||||||
|
!ENDIF
|
||||||
|
MSC_WARNING_LEVEL=/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127 /wd4711 /wd4220 /wd4204
|
||||||
222
daemon/upcall.c
Normal file
222
daemon/upcall.c
Normal file
|
|
@ -0,0 +1,222 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "upcall.h"
|
||||||
|
#include "daemon_debug.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
|
||||||
|
int parse_mount(unsigned char*, uint32_t, nfs41_upcall*);
|
||||||
|
int handle_mount(nfs41_upcall*);
|
||||||
|
int marshall_mount(unsigned char*, uint32_t*, nfs41_upcall*);
|
||||||
|
|
||||||
|
int parse_unmount(unsigned char*, uint32_t, nfs41_upcall*);
|
||||||
|
int handle_unmount(nfs41_upcall*);
|
||||||
|
int marshall_unmount(unsigned char*, uint32_t*, nfs41_upcall*);
|
||||||
|
|
||||||
|
int parse_open(unsigned char*, uint32_t, nfs41_upcall*);
|
||||||
|
int handle_open(nfs41_upcall*);
|
||||||
|
int marshall_open(unsigned char*, uint32_t*, nfs41_upcall*);
|
||||||
|
int cancel_open(nfs41_upcall*);
|
||||||
|
|
||||||
|
int parse_close(unsigned char*, uint32_t, nfs41_upcall*);
|
||||||
|
int handle_close(nfs41_upcall*);
|
||||||
|
int marshall_close(unsigned char*, uint32_t*, nfs41_upcall*);
|
||||||
|
|
||||||
|
int parse_rw(unsigned char*, uint32_t, nfs41_upcall*);
|
||||||
|
int handle_read(nfs41_upcall*);
|
||||||
|
int handle_write(nfs41_upcall*);
|
||||||
|
int marshall_rw(unsigned char*, uint32_t*, nfs41_upcall*);
|
||||||
|
|
||||||
|
int parse_lock(unsigned char*, uint32_t, nfs41_upcall*);
|
||||||
|
int handle_lock(nfs41_upcall*);
|
||||||
|
int marshall_lock(unsigned char*, uint32_t*, nfs41_upcall*);
|
||||||
|
int cancel_lock(nfs41_upcall*);
|
||||||
|
|
||||||
|
int parse_unlock(unsigned char*, uint32_t, nfs41_upcall*);
|
||||||
|
int handle_unlock(nfs41_upcall*);
|
||||||
|
int marshall_unlock(unsigned char*, uint32_t*, nfs41_upcall*);
|
||||||
|
|
||||||
|
int parse_readdir(unsigned char*, uint32_t, nfs41_upcall*);
|
||||||
|
int handle_readdir(nfs41_upcall*);
|
||||||
|
int marshall_readdir(unsigned char*, uint32_t*, nfs41_upcall*);
|
||||||
|
|
||||||
|
int parse_getattr(unsigned char*, uint32_t, nfs41_upcall*);
|
||||||
|
int handle_getattr(nfs41_upcall*);
|
||||||
|
int marshall_getattr(unsigned char*, uint32_t*, nfs41_upcall*);
|
||||||
|
|
||||||
|
int parse_setattr(unsigned char*, uint32_t, nfs41_upcall*);
|
||||||
|
int handle_setattr(nfs41_upcall*);
|
||||||
|
int marshall_setattr(unsigned char*, uint32_t*, nfs41_upcall*);
|
||||||
|
|
||||||
|
int parse_setexattr(unsigned char*, uint32_t, nfs41_upcall*);
|
||||||
|
int handle_setexattr(nfs41_upcall*);
|
||||||
|
int marshall_setexattr(unsigned char*, uint32_t*, nfs41_upcall*);
|
||||||
|
|
||||||
|
int parse_volume(unsigned char*, uint32_t, nfs41_upcall*);
|
||||||
|
int handle_volume(nfs41_upcall*);
|
||||||
|
int marshall_volume(unsigned char*, uint32_t*, nfs41_upcall*);
|
||||||
|
|
||||||
|
static const nfs41_upcall_op g_upcall_op_table[] = {
|
||||||
|
{ parse_mount, handle_mount, marshall_mount, NULL },
|
||||||
|
{ parse_unmount, handle_unmount, marshall_unmount, NULL },
|
||||||
|
{ parse_open, handle_open, marshall_open, cancel_open },
|
||||||
|
{ parse_close, handle_close, marshall_close, NULL },
|
||||||
|
{ parse_rw, handle_read, marshall_rw, NULL },
|
||||||
|
{ parse_rw, handle_write, marshall_rw, NULL },
|
||||||
|
{ parse_lock, handle_lock, marshall_lock, cancel_lock },
|
||||||
|
{ parse_unlock, handle_unlock, marshall_unlock, NULL },
|
||||||
|
{ parse_readdir, handle_readdir, marshall_readdir, NULL },
|
||||||
|
{ parse_getattr, handle_getattr, marshall_getattr, NULL },
|
||||||
|
{ parse_setattr, handle_setattr, marshall_setattr, NULL },
|
||||||
|
{ parse_setexattr, handle_setexattr, marshall_setexattr, NULL },
|
||||||
|
{ parse_volume, handle_volume, marshall_volume, NULL },
|
||||||
|
{ NULL, NULL, NULL, NULL }, /* NFS41_SHUTDOWN */
|
||||||
|
{ NULL, NULL, NULL, NULL }, /* INVALID_OPCODE */
|
||||||
|
};
|
||||||
|
static const uint32_t g_upcall_op_table_size = ARRAYSIZE(g_upcall_op_table);
|
||||||
|
|
||||||
|
|
||||||
|
int upcall_parse(
|
||||||
|
IN unsigned char *buffer,
|
||||||
|
IN uint32_t length,
|
||||||
|
OUT nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
const nfs41_upcall_op *op;
|
||||||
|
|
||||||
|
ZeroMemory(upcall, sizeof(nfs41_upcall));
|
||||||
|
if (!length) {
|
||||||
|
eprintf("empty upcall\n");
|
||||||
|
upcall->status = status = 102;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
dprintf(2, "received %d bytes upcall data: processing upcall\n", length);
|
||||||
|
print_hexbuf(3, (unsigned char *)"upcall buffer: ", buffer, length);
|
||||||
|
|
||||||
|
/* parse common elements */
|
||||||
|
status = safe_read(&buffer, &length, &upcall->xid, sizeof(uint32_t));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(&buffer, &length, &upcall->opcode, sizeof(uint32_t));
|
||||||
|
if (status) goto out;
|
||||||
|
|
||||||
|
dprintf(2, "xid=%d opcode=%s\n", upcall->xid, opcode2string(upcall->opcode));
|
||||||
|
|
||||||
|
if (upcall->opcode >= g_upcall_op_table_size) {
|
||||||
|
status = ERROR_NOT_SUPPORTED;
|
||||||
|
eprintf("unrecognized upcall opcode %d!\n", upcall->opcode);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* parse the operation's arguments */
|
||||||
|
op = &g_upcall_op_table[upcall->opcode];
|
||||||
|
if (op->parse) {
|
||||||
|
status = op->parse(buffer, length, upcall);
|
||||||
|
if (status) {
|
||||||
|
eprintf("parsing of upcall '%s' failed with %d.\n",
|
||||||
|
opcode2string(upcall->opcode), status);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int upcall_handle(
|
||||||
|
IN nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
int status = NO_ERROR;
|
||||||
|
const nfs41_upcall_op *op;
|
||||||
|
|
||||||
|
op = &g_upcall_op_table[upcall->opcode];
|
||||||
|
if (op->handle == NULL) {
|
||||||
|
status = ERROR_NOT_SUPPORTED;
|
||||||
|
eprintf("upcall '%s' missing handle function!\n",
|
||||||
|
opcode2string(upcall->opcode));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
upcall->status = op->handle(upcall);
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int upcall_marshall(
|
||||||
|
IN nfs41_upcall *upcall,
|
||||||
|
OUT unsigned char *buffer,
|
||||||
|
IN uint32_t length,
|
||||||
|
OUT uint32_t *length_out)
|
||||||
|
{
|
||||||
|
int status = NO_ERROR;
|
||||||
|
const nfs41_upcall_op *op;
|
||||||
|
unsigned char *orig_buf = buffer;
|
||||||
|
const uint32_t total = length, orig_len = length;
|
||||||
|
|
||||||
|
/* marshall common elements */
|
||||||
|
write_downcall:
|
||||||
|
length = orig_len;
|
||||||
|
buffer = orig_buf;
|
||||||
|
safe_write(&buffer, &length, &upcall->xid, sizeof(upcall->xid));
|
||||||
|
safe_write(&buffer, &length, &upcall->opcode, sizeof(upcall->opcode));
|
||||||
|
safe_write(&buffer, &length, &upcall->status, sizeof(upcall->status));
|
||||||
|
safe_write(&buffer, &length, &upcall->last_error, sizeof(upcall->last_error));
|
||||||
|
|
||||||
|
if (upcall->status)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* marshall the operation's results */
|
||||||
|
op = &g_upcall_op_table[upcall->opcode];
|
||||||
|
if (op->marshall == NULL) {
|
||||||
|
status = ERROR_NOT_SUPPORTED;
|
||||||
|
eprintf("upcall '%s' missing marshall function!\n",
|
||||||
|
opcode2string(upcall->opcode));
|
||||||
|
upcall->status = status;
|
||||||
|
goto write_downcall;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = op->marshall(buffer, &length, upcall);
|
||||||
|
if (status) {
|
||||||
|
upcall->status = status;
|
||||||
|
goto write_downcall;
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
*length_out = total - length;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int upcall_cancel(
|
||||||
|
IN nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
int status = NO_ERROR;
|
||||||
|
const nfs41_upcall_op *op;
|
||||||
|
|
||||||
|
op = &g_upcall_op_table[upcall->opcode];
|
||||||
|
if (op->cancel)
|
||||||
|
status = op->cancel(upcall);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
201
daemon/upcall.h
Normal file
201
daemon/upcall.h
Normal file
|
|
@ -0,0 +1,201 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __NFS41_DAEMON_UPCALL_H__
|
||||||
|
#define __NFS41_DAEMON_UPCALL_H__
|
||||||
|
|
||||||
|
#include "nfs41_ops.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* structures for upcall arguments */
|
||||||
|
typedef struct __mount_upcall_args {
|
||||||
|
char srv_name[UPCALL_BUF_SIZE];
|
||||||
|
nfs41_abs_path path;
|
||||||
|
nfs41_root *root;
|
||||||
|
} mount_upcall_args;
|
||||||
|
|
||||||
|
typedef struct __unmount_upcall_args {
|
||||||
|
nfs41_root *root;
|
||||||
|
} unmount_upcall_args;
|
||||||
|
|
||||||
|
typedef struct __open_upcall_args {
|
||||||
|
nfs41_abs_path path;
|
||||||
|
FILE_BASIC_INFO basic_info;
|
||||||
|
FILE_STANDARD_INFO std_info;
|
||||||
|
nfs41_root *root;
|
||||||
|
nfs41_open_state *state;
|
||||||
|
ULONG access_mask;
|
||||||
|
ULONG access_mode;
|
||||||
|
ULONG file_attrs;
|
||||||
|
ULONG disposition;
|
||||||
|
ULONG create_opts;
|
||||||
|
ULONG open_owner_id;
|
||||||
|
DWORD mode;
|
||||||
|
LONGLONG changeattr;
|
||||||
|
BOOLEAN created;
|
||||||
|
} open_upcall_args;
|
||||||
|
|
||||||
|
typedef struct __close_upcall_args {
|
||||||
|
nfs41_abs_path path;
|
||||||
|
nfs41_root *root;
|
||||||
|
nfs41_open_state *state;
|
||||||
|
BOOLEAN remove;
|
||||||
|
BOOLEAN renamed;
|
||||||
|
} close_upcall_args;
|
||||||
|
|
||||||
|
typedef struct __readwrite_upcall_args {
|
||||||
|
nfs41_root *root;
|
||||||
|
nfs41_open_state *state;
|
||||||
|
unsigned char *buffer;
|
||||||
|
LONGLONG offset;
|
||||||
|
ULONG len;
|
||||||
|
ULONG out_len;
|
||||||
|
} readwrite_upcall_args;
|
||||||
|
|
||||||
|
typedef struct __lock_upcall_args {
|
||||||
|
nfs41_open_state *state;
|
||||||
|
nfs41_root *root;
|
||||||
|
LONGLONG offset;
|
||||||
|
LONGLONG length;
|
||||||
|
BOOLEAN exclusive;
|
||||||
|
BOOLEAN blocking;
|
||||||
|
} lock_upcall_args;
|
||||||
|
|
||||||
|
typedef struct __unlock_upcall_args {
|
||||||
|
nfs41_open_state *state;
|
||||||
|
nfs41_root *root;
|
||||||
|
uint32_t count;
|
||||||
|
unsigned char *buf;
|
||||||
|
uint32_t buf_len;
|
||||||
|
} unlock_upcall_args;
|
||||||
|
|
||||||
|
typedef struct __getattr_upcall_args {
|
||||||
|
FILE_BASIC_INFO basic_info;
|
||||||
|
FILE_STANDARD_INFO std_info;
|
||||||
|
FILE_ATTRIBUTE_TAG_INFO tag_info;
|
||||||
|
nfs41_root *root;
|
||||||
|
nfs41_open_state *state;
|
||||||
|
int query_class;
|
||||||
|
int buf_len;
|
||||||
|
int query_reply_len;
|
||||||
|
} getattr_upcall_args;
|
||||||
|
|
||||||
|
typedef struct __setattr_upcall_args {
|
||||||
|
nfs41_abs_path path;
|
||||||
|
nfs41_root *root;
|
||||||
|
nfs41_open_state *state;
|
||||||
|
unsigned char *buf;
|
||||||
|
uint32_t buf_len;
|
||||||
|
int set_class;
|
||||||
|
ULONG open_owner_id;
|
||||||
|
ULONG access_mask;
|
||||||
|
ULONG access_mode;
|
||||||
|
} setattr_upcall_args;
|
||||||
|
|
||||||
|
typedef struct __setexattr_upcall_args {
|
||||||
|
nfs41_root *root;
|
||||||
|
nfs41_open_state *state;
|
||||||
|
uint32_t mode;
|
||||||
|
} setexattr_upcall_args;
|
||||||
|
|
||||||
|
typedef struct __readdir_upcall_args {
|
||||||
|
char filter[UPCALL_BUF_SIZE];
|
||||||
|
FILE_BASIC_INFO basic_info;
|
||||||
|
FILE_STANDARD_INFO std_info;
|
||||||
|
FILE_ATTRIBUTE_TAG_INFO tag_info;
|
||||||
|
nfs41_readdir_cookie *cookie;
|
||||||
|
nfs41_root *root;
|
||||||
|
nfs41_open_state *state;
|
||||||
|
unsigned char *buf;
|
||||||
|
int buf_len;
|
||||||
|
int query_class;
|
||||||
|
int query_reply_len;
|
||||||
|
BOOLEAN initial;
|
||||||
|
BOOLEAN restart;
|
||||||
|
BOOLEAN single;
|
||||||
|
} readdir_upcall_args;
|
||||||
|
|
||||||
|
typedef struct __volume_upcall_args {
|
||||||
|
nfs41_root *root;
|
||||||
|
ULONGLONG total;
|
||||||
|
ULONGLONG user;
|
||||||
|
ULONGLONG avail;
|
||||||
|
} volume_upcall_args;
|
||||||
|
|
||||||
|
typedef union __upcall_args {
|
||||||
|
mount_upcall_args mount;
|
||||||
|
unmount_upcall_args unmount;
|
||||||
|
open_upcall_args open;
|
||||||
|
close_upcall_args close;
|
||||||
|
readwrite_upcall_args rw;
|
||||||
|
lock_upcall_args lock;
|
||||||
|
unlock_upcall_args unlock;
|
||||||
|
getattr_upcall_args getattr;
|
||||||
|
setattr_upcall_args setattr;
|
||||||
|
setexattr_upcall_args setexattr;
|
||||||
|
readdir_upcall_args readdir;
|
||||||
|
volume_upcall_args volume;
|
||||||
|
} upcall_args;
|
||||||
|
|
||||||
|
typedef struct __nfs41_upcall {
|
||||||
|
uint32_t xid;
|
||||||
|
uint32_t opcode;
|
||||||
|
uint32_t status;
|
||||||
|
uint32_t last_error;
|
||||||
|
upcall_args args;
|
||||||
|
} nfs41_upcall;
|
||||||
|
|
||||||
|
|
||||||
|
/* upcall operation interface */
|
||||||
|
typedef int (*upcall_parse_proc)(unsigned char*, uint32_t, nfs41_upcall*);
|
||||||
|
typedef int (*upcall_handle_proc)(nfs41_upcall*);
|
||||||
|
typedef int (*upcall_marshall_proc)(unsigned char*, uint32_t*, nfs41_upcall*);
|
||||||
|
typedef int (*upcall_cancel_proc)(nfs41_upcall*);
|
||||||
|
|
||||||
|
typedef struct __nfs41_upcall_op {
|
||||||
|
upcall_parse_proc parse;
|
||||||
|
upcall_handle_proc handle;
|
||||||
|
upcall_marshall_proc marshall;
|
||||||
|
upcall_cancel_proc cancel;
|
||||||
|
} nfs41_upcall_op;
|
||||||
|
|
||||||
|
|
||||||
|
/* upcall.c */
|
||||||
|
int upcall_parse(
|
||||||
|
IN unsigned char *buffer,
|
||||||
|
IN uint32_t length,
|
||||||
|
OUT nfs41_upcall *upcall);
|
||||||
|
|
||||||
|
int upcall_handle(
|
||||||
|
IN nfs41_upcall *upcall);
|
||||||
|
|
||||||
|
int upcall_marshall(
|
||||||
|
IN nfs41_upcall *upcall,
|
||||||
|
OUT unsigned char *buffer,
|
||||||
|
IN uint32_t length,
|
||||||
|
OUT uint32_t *length_out);
|
||||||
|
|
||||||
|
int upcall_cancel(
|
||||||
|
IN nfs41_upcall *upcall);
|
||||||
|
|
||||||
|
#endif /* !__NFS41_DAEMON_UPCALL_H__ */
|
||||||
450
daemon/util.c
Normal file
450
daemon/util.c
Normal file
|
|
@ -0,0 +1,450 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <strsafe.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "daemon_debug.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "nfs41_ops.h"
|
||||||
|
|
||||||
|
|
||||||
|
int safe_read(unsigned char **pos, uint32_t *remaining, void *dest, uint32_t dest_len)
|
||||||
|
{
|
||||||
|
if (*remaining < dest_len)
|
||||||
|
return ERROR_BUFFER_OVERFLOW;
|
||||||
|
|
||||||
|
CopyMemory(dest, *pos, dest_len);
|
||||||
|
*pos += dest_len;
|
||||||
|
*remaining -= dest_len;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int safe_write(unsigned char **pos, uint32_t *remaining, void *src, uint32_t src_len)
|
||||||
|
{
|
||||||
|
if (*remaining < src_len)
|
||||||
|
return ERROR_BUFFER_OVERFLOW;
|
||||||
|
|
||||||
|
CopyMemory(*pos, src, src_len);
|
||||||
|
*pos += src_len;
|
||||||
|
*remaining -= src_len;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int wchar2asci(WCHAR *src, char **dest, int dest_len)
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
len = WideCharToMultiByte(CP_UTF8, 0, src, -1, NULL, 0, NULL, NULL);
|
||||||
|
if (*dest == NULL) {
|
||||||
|
*dest = malloc(len + 1);
|
||||||
|
if (*dest == NULL)
|
||||||
|
return ERROR_NOT_ENOUGH_MEMORY;
|
||||||
|
} else if (len > dest_len)
|
||||||
|
return ERROR_BUFFER_OVERFLOW;
|
||||||
|
WideCharToMultiByte(CP_UTF8, 0, src, len, *dest, len + 1, NULL, NULL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_name(unsigned char **pos, uint32_t *remaining, char *out_name)
|
||||||
|
{
|
||||||
|
WCHAR name[UPCALL_BUF_SIZE];
|
||||||
|
int status, len = 0;
|
||||||
|
|
||||||
|
status = safe_read(pos, remaining, &len, sizeof(USHORT));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_read(pos, remaining, name, len);
|
||||||
|
if (status) goto out;
|
||||||
|
|
||||||
|
name[len/sizeof(WCHAR)] = L'\0';
|
||||||
|
status = wchar2asci(name, &out_name, UPCALL_BUF_SIZE);
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int get_abs_path(unsigned char **pos, uint32_t *remaining, nfs41_abs_path *path)
|
||||||
|
{
|
||||||
|
int status = get_name(pos, remaining, path->path);
|
||||||
|
path->len = status ? 0 : (unsigned short)strlen(path->path);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* strip_path(
|
||||||
|
IN const char *path,
|
||||||
|
OUT uint32_t *len_out)
|
||||||
|
{
|
||||||
|
const char *name = strrchr(path, '\\');
|
||||||
|
name = name ? name + 1 : path;
|
||||||
|
if (len_out)
|
||||||
|
*len_out = (uint32_t)strlen(name);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t max_read_size(
|
||||||
|
IN const nfs41_session *session,
|
||||||
|
IN const nfs41_fh *fh)
|
||||||
|
{
|
||||||
|
const uint32_t maxresponse = session->fore_chan_attrs.ca_maxresponsesize;
|
||||||
|
return (uint32_t)min(fh->superblock->maxread, maxresponse - READ_OVERHEAD);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t max_write_size(
|
||||||
|
IN const nfs41_session *session,
|
||||||
|
IN const nfs41_fh *fh)
|
||||||
|
{
|
||||||
|
const uint32_t maxrequest = session->fore_chan_attrs.ca_maxrequestsize;
|
||||||
|
return (uint32_t)min(fh->superblock->maxwrite, maxrequest - WRITE_OVERHEAD);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t verify_write(
|
||||||
|
IN nfs41_write_verf *verf,
|
||||||
|
IN OUT enum stable_how4 *stable)
|
||||||
|
{
|
||||||
|
if (verf->committed != UNSTABLE4) {
|
||||||
|
*stable = verf->committed;
|
||||||
|
dprintf(3, "verify_write: committed to stable storage\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*stable != UNSTABLE4) {
|
||||||
|
memcpy(verf->expected, verf->verf, NFS4_VERIFIER_SIZE);
|
||||||
|
*stable = UNSTABLE4;
|
||||||
|
dprintf(3, "verify_write: first unstable write, saving verifier\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp(verf->expected, verf->verf, NFS4_VERIFIER_SIZE) == 0) {
|
||||||
|
dprintf(3, "verify_write: verifier matches expected\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dprintf(2, "verify_write: verifier changed; writes have been lost!\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG nfs_file_info_to_attributes(
|
||||||
|
IN const nfs41_file_info *info)
|
||||||
|
{
|
||||||
|
ULONG attrs = 0;
|
||||||
|
if (info->type == NF4DIR)
|
||||||
|
attrs |= FILE_ATTRIBUTE_DIRECTORY;
|
||||||
|
else if (info->type != NF4REG)
|
||||||
|
dprintf(1, "unhandled file type %d, defaulting to NF4REG\n",
|
||||||
|
info->type);
|
||||||
|
|
||||||
|
if (info->mode == 0444) /* XXX: 0444 for READONLY */
|
||||||
|
attrs |= FILE_ATTRIBUTE_READONLY;
|
||||||
|
|
||||||
|
/* TODO: FILE_ATTRIBUTE_HIDDEN */
|
||||||
|
|
||||||
|
// FILE_ATTRIBUTE_NORMAL attribute is only set if no other attributes are present.
|
||||||
|
// all other override this value.
|
||||||
|
return attrs ? attrs : FILE_ATTRIBUTE_NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfs_to_basic_info(
|
||||||
|
IN const nfs41_file_info *info,
|
||||||
|
OUT PFILE_BASIC_INFO basic_out)
|
||||||
|
{
|
||||||
|
nfs_time_to_file_time(&info->time_create, &basic_out->CreationTime);
|
||||||
|
nfs_time_to_file_time(&info->time_access, &basic_out->LastAccessTime);
|
||||||
|
nfs_time_to_file_time(&info->time_modify, &basic_out->LastWriteTime);
|
||||||
|
/* XXX: was using 'change' attr, but that wasn't giving a time */
|
||||||
|
nfs_time_to_file_time(&info->time_modify, &basic_out->ChangeTime);
|
||||||
|
basic_out->FileAttributes = nfs_file_info_to_attributes(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfs_to_standard_info(
|
||||||
|
IN const nfs41_file_info *info,
|
||||||
|
OUT PFILE_STANDARD_INFO std_out)
|
||||||
|
{
|
||||||
|
std_out->AllocationSize.QuadPart =
|
||||||
|
std_out->EndOfFile.QuadPart = (LONGLONG)info->size;
|
||||||
|
std_out->NumberOfLinks = info->numlinks;
|
||||||
|
std_out->DeletePending = FALSE;
|
||||||
|
std_out->Directory = info->type == NF4DIR ? TRUE : FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* http://msdn.microsoft.com/en-us/library/ms724290%28VS.85%29.aspx:
|
||||||
|
* A file time is a 64-bit value that represents the number of
|
||||||
|
* 100-nanosecond intervals that have elapsed since 12:00 A.M.
|
||||||
|
* January 1, 1601 Coordinated Universal Time (UTC). */
|
||||||
|
static __inline void get_file_epoch(
|
||||||
|
OUT PLARGE_INTEGER time_out)
|
||||||
|
{
|
||||||
|
static const SYSTEMTIME jan_1_1970 = {1970, 1, 4, 1, 0, 0, 0, 0};
|
||||||
|
SystemTimeToFileTime(&jan_1_1970, (LPFILETIME)time_out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void file_time_to_nfs_time(
|
||||||
|
IN const PLARGE_INTEGER file_time,
|
||||||
|
OUT nfstime4 *nfs_time)
|
||||||
|
{
|
||||||
|
LARGE_INTEGER diff;
|
||||||
|
get_file_epoch(&diff);
|
||||||
|
diff.QuadPart = file_time->QuadPart - diff.QuadPart;
|
||||||
|
nfs_time->seconds = diff.QuadPart / 10000000;
|
||||||
|
nfs_time->nseconds = (uint32_t)((diff.QuadPart % 10000000)*100);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfs_time_to_file_time(
|
||||||
|
IN const nfstime4 *nfs_time,
|
||||||
|
OUT PLARGE_INTEGER file_time)
|
||||||
|
{
|
||||||
|
LARGE_INTEGER diff;
|
||||||
|
get_file_epoch(&diff);
|
||||||
|
file_time->QuadPart = diff.QuadPart +
|
||||||
|
nfs_time->seconds * 10000000 +
|
||||||
|
nfs_time->nseconds / 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
void get_file_time(
|
||||||
|
OUT PLARGE_INTEGER file_time)
|
||||||
|
{
|
||||||
|
GetSystemTimeAsFileTime((LPFILETIME)file_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
void get_nfs_time(
|
||||||
|
OUT nfstime4 *nfs_time)
|
||||||
|
{
|
||||||
|
LARGE_INTEGER file_time;
|
||||||
|
get_file_time(&file_time);
|
||||||
|
file_time_to_nfs_time(&file_time, nfs_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
void map_access_2_allowdeny(ULONG access_mask, ULONG access_mode,
|
||||||
|
uint32_t *allow, uint32_t *deny)
|
||||||
|
{
|
||||||
|
if ((access_mask & FILE_WRITE_DATA) &&
|
||||||
|
((access_mask & FILE_READ_DATA) ||
|
||||||
|
(access_mask & FILE_EXECUTE)))
|
||||||
|
*allow = OPEN4_SHARE_ACCESS_BOTH;
|
||||||
|
else if ((access_mask & FILE_READ_DATA) ||
|
||||||
|
(access_mask & FILE_EXECUTE))
|
||||||
|
*allow = OPEN4_SHARE_ACCESS_READ;
|
||||||
|
else if (access_mask & FILE_WRITE_DATA ||
|
||||||
|
(access_mask & FILE_APPEND_DATA) ||
|
||||||
|
(access_mask & FILE_WRITE_ATTRIBUTES))
|
||||||
|
*allow = OPEN4_SHARE_ACCESS_WRITE;
|
||||||
|
#define FIX_ALLOW_DENY_WIN2NFS_CONVERSION
|
||||||
|
#ifdef FIX_ALLOW_DENY_WIN2NFS_CONVERSION
|
||||||
|
if ((access_mode & FILE_SHARE_READ) &&
|
||||||
|
(access_mode & FILE_SHARE_WRITE))
|
||||||
|
*deny = OPEN4_SHARE_DENY_NONE;
|
||||||
|
else if (access_mode & FILE_SHARE_READ)
|
||||||
|
*deny = OPEN4_SHARE_DENY_WRITE;
|
||||||
|
else if (access_mode & FILE_SHARE_WRITE)
|
||||||
|
*deny = OPEN4_SHARE_DENY_READ;
|
||||||
|
else
|
||||||
|
*deny = OPEN4_SHARE_DENY_BOTH;
|
||||||
|
#else
|
||||||
|
// AGLO: 11/13/2009.
|
||||||
|
// readonly file that is being opened for reading with a
|
||||||
|
// share read mode given above logic translates into deny
|
||||||
|
// write and linux server does not allow it.
|
||||||
|
*deny = OPEN4_SHARE_DENY_NONE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t multi_addr_find(
|
||||||
|
IN const multi_addr4 *addrs,
|
||||||
|
IN const netaddr4 *addr,
|
||||||
|
OUT OPTIONAL uint32_t *index_out)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
for (i = 0; i < addrs->count; i++) {
|
||||||
|
const netaddr4 *saddr = &addrs->arr[i];
|
||||||
|
if (!strncmp(saddr->netid, addr->netid, NFS41_NETWORK_ID_LEN) &&
|
||||||
|
!strncmp(saddr->uaddr, addr->uaddr, NFS41_UNIVERSAL_ADDR_LEN)) {
|
||||||
|
if (index_out) *index_out = i;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nfs_to_windows_error(int status, int default_error)
|
||||||
|
{
|
||||||
|
/* make sure this is actually an nfs error */
|
||||||
|
if (status < 0 || (status > 70 && status < 10001) || status > 10087) {
|
||||||
|
eprintf("nfs_to_windows_error called with non-nfs "
|
||||||
|
"error code %d; returning the error as is\n", status);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (status) {
|
||||||
|
case NFS4_OK: return NO_ERROR;
|
||||||
|
case NFS4ERR_PERM: return ERROR_ACCESS_DENIED;
|
||||||
|
case NFS4ERR_NOENT: return ERROR_FILE_NOT_FOUND;
|
||||||
|
case NFS4ERR_IO: return ERROR_NET_WRITE_FAULT;
|
||||||
|
case NFS4ERR_ACCESS: return ERROR_ACCESS_DENIED;
|
||||||
|
case NFS4ERR_EXIST: return ERROR_FILE_EXISTS;
|
||||||
|
case NFS4ERR_XDEV: return ERROR_NOT_SAME_DEVICE;
|
||||||
|
case NFS4ERR_INVAL: return ERROR_INVALID_PARAMETER;
|
||||||
|
case NFS4ERR_FBIG: return ERROR_FILE_TOO_LARGE;
|
||||||
|
case NFS4ERR_NOSPC: return ERROR_DISK_FULL;
|
||||||
|
case NFS4ERR_ROFS: return ERROR_NETWORK_ACCESS_DENIED;
|
||||||
|
case NFS4ERR_MLINK: return ERROR_TOO_MANY_LINKS;
|
||||||
|
case NFS4ERR_NAMETOOLONG: return ERROR_FILENAME_EXCED_RANGE;
|
||||||
|
case NFS4ERR_STALE: return ERROR_NETNAME_DELETED;
|
||||||
|
case NFS4ERR_NOTEMPTY: return ERROR_NOT_EMPTY;
|
||||||
|
case NFS4ERR_DENIED: return ERROR_LOCK_FAILED;
|
||||||
|
case NFS4ERR_TOOSMALL: return ERROR_BUFFER_OVERFLOW;
|
||||||
|
case NFS4ERR_LOCKED: return ERROR_LOCK_VIOLATION;
|
||||||
|
case NFS4ERR_SHARE_DENIED: return ERROR_SHARING_VIOLATION;
|
||||||
|
case NFS4ERR_LOCK_RANGE: return ERROR_NOT_LOCKED;
|
||||||
|
case NFS4ERR_ATTRNOTSUPP: return ERROR_NOT_SUPPORTED;
|
||||||
|
case NFS4ERR_OPENMODE: return ERROR_ACCESS_DENIED;
|
||||||
|
case NFS4ERR_LOCK_NOTSUPP: return ERROR_ATOMIC_LOCKS_NOT_SUPPORTED;
|
||||||
|
|
||||||
|
case NFS4ERR_BADCHAR:
|
||||||
|
case NFS4ERR_BADNAME: return ERROR_INVALID_NAME;
|
||||||
|
|
||||||
|
case NFS4ERR_NOTDIR:
|
||||||
|
case NFS4ERR_ISDIR:
|
||||||
|
case NFS4ERR_SYMLINK:
|
||||||
|
case NFS4ERR_WRONG_TYPE: return ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
case NFS4ERR_OLD_STATEID:
|
||||||
|
case NFS4ERR_BAD_STATEID:
|
||||||
|
case NFS4ERR_ADMIN_REVOKED: return ERROR_FILE_INVALID;
|
||||||
|
|
||||||
|
default:
|
||||||
|
dprintf(1, "nfs error %s not mapped to windows error; "
|
||||||
|
"returning default error %d\n",
|
||||||
|
nfs_error_string(status), default_error);
|
||||||
|
return default_error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t next_component(
|
||||||
|
IN const char *path,
|
||||||
|
IN const char *path_end,
|
||||||
|
OUT nfs41_component *component)
|
||||||
|
{
|
||||||
|
const char *component_end;
|
||||||
|
component->name = next_non_delimiter(path, path_end);
|
||||||
|
component_end = next_delimiter(component->name, path_end);
|
||||||
|
component->len = (unsigned short)(component_end - component->name);
|
||||||
|
return component->len > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t last_component(
|
||||||
|
IN const char *path,
|
||||||
|
IN const char *path_end,
|
||||||
|
OUT nfs41_component *component)
|
||||||
|
{
|
||||||
|
const char *component_end = prev_delimiter(path_end, path);
|
||||||
|
component->name = prev_non_delimiter(component_end, path);
|
||||||
|
component->name = prev_delimiter(component->name, path);
|
||||||
|
component->name = next_non_delimiter(component->name, component_end);
|
||||||
|
component->len = (unsigned short)(component_end - component->name);
|
||||||
|
return component->len > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t is_last_component(
|
||||||
|
IN const char *path,
|
||||||
|
IN const char *path_end)
|
||||||
|
{
|
||||||
|
path = next_delimiter(path, path_end);
|
||||||
|
return next_non_delimiter(path, path_end) == path_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
void abs_path_copy(
|
||||||
|
OUT nfs41_abs_path *dst,
|
||||||
|
IN const nfs41_abs_path *src)
|
||||||
|
{
|
||||||
|
dst->len = src->len;
|
||||||
|
StringCchCopyNA(dst->path, NFS41_MAX_PATH_LEN, src->path, dst->len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void path_fh_init(
|
||||||
|
OUT nfs41_path_fh *file,
|
||||||
|
IN nfs41_abs_path *path)
|
||||||
|
{
|
||||||
|
file->path = path;
|
||||||
|
last_component(path->path, path->path + path->len, &file->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fh_copy(
|
||||||
|
OUT nfs41_fh *dst,
|
||||||
|
IN const nfs41_fh *src)
|
||||||
|
{
|
||||||
|
dst->fileid = src->fileid;
|
||||||
|
dst->superblock = src->superblock;
|
||||||
|
dst->len = src->len;
|
||||||
|
memcpy(dst->fh, src->fh, dst->len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void path_fh_copy(
|
||||||
|
OUT nfs41_path_fh *dst,
|
||||||
|
IN const nfs41_path_fh *src)
|
||||||
|
{
|
||||||
|
dst->path = src->path;
|
||||||
|
if (dst->path) {
|
||||||
|
const size_t name_start = src->name.name - src->path->path;
|
||||||
|
dst->name.name = dst->path->path + name_start;
|
||||||
|
dst->name.len = src->name.len;
|
||||||
|
} else {
|
||||||
|
dst->name.name = NULL;
|
||||||
|
dst->name.len = 0;
|
||||||
|
}
|
||||||
|
fh_copy(&dst->fh, &src->fh);
|
||||||
|
}
|
||||||
|
|
||||||
|
int create_silly_rename(
|
||||||
|
IN nfs41_abs_path *path,
|
||||||
|
IN const nfs41_fh *fh,
|
||||||
|
OUT nfs41_component *silly)
|
||||||
|
{
|
||||||
|
const char *end = path->path + NFS41_MAX_PATH_LEN;
|
||||||
|
const unsigned short extra_len = 2 + 2*(unsigned short)fh->len;
|
||||||
|
char name[NFS41_MAX_COMPONENT_LEN+1];
|
||||||
|
char *tmp;
|
||||||
|
uint32_t i;
|
||||||
|
int status = NO_ERROR;
|
||||||
|
|
||||||
|
if (path->len + extra_len >= NFS41_MAX_PATH_LEN) {
|
||||||
|
status = ERROR_BUFFER_OVERFLOW;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_component(path->path, path->path + path->len, silly);
|
||||||
|
StringCchCopyNA(name, NFS41_MAX_COMPONENT_LEN+1, silly->name, silly->len);
|
||||||
|
|
||||||
|
tmp = (char*)silly->name;
|
||||||
|
StringCchPrintf(tmp, end - tmp, ".%s.", name);
|
||||||
|
tmp += silly->len + 2;
|
||||||
|
|
||||||
|
for (i = 0; i < fh->len; i++, tmp += 2)
|
||||||
|
StringCchPrintf(tmp, end - tmp, "%02x", fh->fh[i]);
|
||||||
|
|
||||||
|
path->len += extra_len;
|
||||||
|
silly->len += extra_len;
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
166
daemon/util.h
Normal file
166
daemon/util.h
Normal file
|
|
@ -0,0 +1,166 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __NFS41_DAEMON_UTIL_H__
|
||||||
|
#define __NFS41_DAEMON_UTIL_H__
|
||||||
|
|
||||||
|
#include "nfs41_types.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct __nfs41_session;
|
||||||
|
struct __nfs41_write_verf;
|
||||||
|
enum stable_how4;
|
||||||
|
|
||||||
|
int safe_read(unsigned char **pos, uint32_t *remaining, void *dest, uint32_t dest_len);
|
||||||
|
int safe_write(unsigned char **pos, uint32_t *remaining, void *dest, uint32_t dest_len);
|
||||||
|
int get_name(unsigned char **pos, uint32_t *remaining, char *out_name);
|
||||||
|
int get_abs_path(unsigned char **pos, uint32_t *remaining, nfs41_abs_path *path);
|
||||||
|
int wchar2asci(WCHAR *src, char **dest, int dest_len);
|
||||||
|
|
||||||
|
const char* strip_path(
|
||||||
|
IN const char *path,
|
||||||
|
OUT uint32_t *len_out OPTIONAL);
|
||||||
|
|
||||||
|
uint32_t max_read_size(
|
||||||
|
IN const struct __nfs41_session *session,
|
||||||
|
IN const nfs41_fh *fh);
|
||||||
|
uint32_t max_write_size(
|
||||||
|
IN const struct __nfs41_session *session,
|
||||||
|
IN const nfs41_fh *fh);
|
||||||
|
|
||||||
|
bool_t verify_write(
|
||||||
|
IN struct __nfs41_write_verf *verf,
|
||||||
|
IN OUT enum stable_how4 *stable);
|
||||||
|
|
||||||
|
ULONG nfs_file_info_to_attributes(
|
||||||
|
IN const nfs41_file_info *info);
|
||||||
|
void nfs_to_basic_info(
|
||||||
|
IN const nfs41_file_info *info,
|
||||||
|
OUT PFILE_BASIC_INFO basic_out);
|
||||||
|
void nfs_to_standard_info(
|
||||||
|
IN const nfs41_file_info *info,
|
||||||
|
OUT PFILE_STANDARD_INFO std_out);
|
||||||
|
|
||||||
|
void file_time_to_nfs_time(
|
||||||
|
IN const PLARGE_INTEGER file_time,
|
||||||
|
OUT nfstime4 *nfs_time);
|
||||||
|
void nfs_time_to_file_time(
|
||||||
|
IN const nfstime4 *nfs_time,
|
||||||
|
OUT PLARGE_INTEGER file_time);
|
||||||
|
void get_file_time(
|
||||||
|
OUT PLARGE_INTEGER file_time);
|
||||||
|
void get_nfs_time(
|
||||||
|
OUT nfstime4 *nfs_time);
|
||||||
|
|
||||||
|
int create_silly_rename(
|
||||||
|
IN nfs41_abs_path *path,
|
||||||
|
IN const nfs41_fh *fh,
|
||||||
|
OUT nfs41_component *silly);
|
||||||
|
|
||||||
|
void map_access_2_allowdeny(
|
||||||
|
IN ULONG access_mask,
|
||||||
|
IN ULONG access_mode,
|
||||||
|
OUT uint32_t *allow,
|
||||||
|
OUT uint32_t *deny);
|
||||||
|
|
||||||
|
bool_t multi_addr_find(
|
||||||
|
IN const multi_addr4 *addrs,
|
||||||
|
IN const netaddr4 *addr,
|
||||||
|
OUT OPTIONAL uint32_t *index_out);
|
||||||
|
|
||||||
|
/* nfs_to_windows_error
|
||||||
|
* Returns a windows ERROR_ code corresponding to the given NFS4ERR_ status.
|
||||||
|
* If the status is outside the range of valid NFS4ERR_ values, it is returned
|
||||||
|
* unchanged. Otherwise, if the status does not match a value in the mapping,
|
||||||
|
* a debug warning is generated and the default_error value is returned.
|
||||||
|
*/
|
||||||
|
int nfs_to_windows_error(int status, int default_error);
|
||||||
|
|
||||||
|
|
||||||
|
__inline uint32_t align8(uint32_t offset) {
|
||||||
|
return 8 + ((offset - 1) & ~7);
|
||||||
|
}
|
||||||
|
__inline uint32_t align4(uint32_t offset) {
|
||||||
|
return 4 + ((offset - 1) & ~3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* path parsing */
|
||||||
|
__inline int is_delimiter(char c) {
|
||||||
|
return c == '\\' || c == '/' || c == '\0';
|
||||||
|
}
|
||||||
|
__inline const char* next_delimiter(const char *pos, const char *end) {
|
||||||
|
while (pos < end && !is_delimiter(*pos))
|
||||||
|
pos++;
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
__inline const char* prev_delimiter(const char *pos, const char *start) {
|
||||||
|
while (pos > start && !is_delimiter(*pos))
|
||||||
|
pos--;
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
__inline const char* next_non_delimiter(const char *pos, const char *end) {
|
||||||
|
while (pos < end && is_delimiter(*pos))
|
||||||
|
pos++;
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
__inline const char* prev_non_delimiter(const char *pos, const char *start) {
|
||||||
|
while (pos > start && is_delimiter(*pos))
|
||||||
|
pos--;
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool_t next_component(
|
||||||
|
IN const char *path,
|
||||||
|
IN const char *path_end,
|
||||||
|
OUT nfs41_component *component);
|
||||||
|
|
||||||
|
bool_t last_component(
|
||||||
|
IN const char *path,
|
||||||
|
IN const char *path_end,
|
||||||
|
OUT nfs41_component *component);
|
||||||
|
|
||||||
|
bool_t is_last_component(
|
||||||
|
IN const char *path,
|
||||||
|
IN const char *path_end);
|
||||||
|
|
||||||
|
void abs_path_copy(
|
||||||
|
OUT nfs41_abs_path *dst,
|
||||||
|
IN const nfs41_abs_path *src);
|
||||||
|
|
||||||
|
void path_fh_init(
|
||||||
|
OUT nfs41_path_fh *file,
|
||||||
|
IN nfs41_abs_path *path);
|
||||||
|
|
||||||
|
void fh_copy(
|
||||||
|
OUT nfs41_fh *dst,
|
||||||
|
IN const nfs41_fh *src);
|
||||||
|
|
||||||
|
void path_fh_copy(
|
||||||
|
OUT nfs41_path_fh *dst,
|
||||||
|
IN const nfs41_path_fh *src);
|
||||||
|
|
||||||
|
__inline int valid_handle(HANDLE handle) {
|
||||||
|
return handle != INVALID_HANDLE_VALUE && handle != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* !__NFS41_DAEMON_UTIL_H__ */
|
||||||
86
daemon/volume.c
Normal file
86
daemon/volume.c
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "nfs41_ops.h"
|
||||||
|
#include "from_kernel.h"
|
||||||
|
#include "upcall.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "daemon_debug.h"
|
||||||
|
|
||||||
|
|
||||||
|
int parse_volume(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
volume_upcall_args *args = &upcall->args.volume;
|
||||||
|
status = safe_read(&buffer, &length, &args->root, sizeof(HANDLE));
|
||||||
|
if (status)
|
||||||
|
eprintf("parsing NFS41_VOLUME_QUERY failed with %d\n",
|
||||||
|
status);
|
||||||
|
else
|
||||||
|
dprintf(1, "parsing NFS41_VOLUME_QUERY: root=0x%p\n", args->root);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int handle_volume(nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
nfs41_file_info info = { 0 };
|
||||||
|
bitmap4 attr_request = { 2, { 0, FATTR4_WORD1_SPACE_AVAIL |
|
||||||
|
FATTR4_WORD1_SPACE_FREE | FATTR4_WORD1_SPACE_TOTAL } };
|
||||||
|
volume_upcall_args *args = &upcall->args.volume;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
/* query the space_ attributes of the root filesystem */
|
||||||
|
status = nfs41_getattr(nfs41_root_session(args->root),
|
||||||
|
NULL, &attr_request, &info);
|
||||||
|
if (status) {
|
||||||
|
eprintf("nfs41_getattr() failed with %s\n",
|
||||||
|
nfs_error_string(status));
|
||||||
|
status = nfs_to_windows_error(status, ERROR_BAD_NET_RESP);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
args->total = info.space_total; /* total disk space in bytes */
|
||||||
|
args->user = info.space_avail; /* bytes available to this user */
|
||||||
|
args->avail = info.space_free; /* free disk space in bytes */
|
||||||
|
dprintf(2, "Volume: %llu user, %llu free of %llu total\n",
|
||||||
|
args->user, args->avail, args->total);
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int marshall_volume(unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
volume_upcall_args *args = &upcall->args.volume;
|
||||||
|
|
||||||
|
status = safe_write(&buffer, length, &args->total, sizeof(args->total));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_write(&buffer, length, &args->user, sizeof(args->user));
|
||||||
|
if (status) goto out;
|
||||||
|
status = safe_write(&buffer, length, &args->avail, sizeof(args->avail));
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
1
dirs
Normal file
1
dirs
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
DIRS = dll sys mount daemon libtirpc install
|
||||||
76
dll/dllmain.c
Normal file
76
dll/dllmain.c
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 1989-1999 Microsoft Corporation
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
dllmain.c
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
This module implements the initialization routines for network
|
||||||
|
provider interface
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
This module has been built and tested only in UNICODE environment
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <process.h>
|
||||||
|
|
||||||
|
|
||||||
|
// NOTE:
|
||||||
|
//
|
||||||
|
// Function:` DllMain
|
||||||
|
//
|
||||||
|
// Return: TRUE => Success
|
||||||
|
// FALSE => Failure
|
||||||
|
|
||||||
|
BOOL WINAPI DllMain(HINSTANCE hDLLInst, DWORD fdwReason, LPVOID lpvReserved)
|
||||||
|
{
|
||||||
|
BOOL bStatus = TRUE;
|
||||||
|
|
||||||
|
switch (fdwReason) {
|
||||||
|
case DLL_PROCESS_ATTACH:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DLL_PROCESS_DETACH:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DLL_THREAD_ATTACH:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DLL_THREAD_DETACH:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(bStatus);
|
||||||
|
}
|
||||||
8
dll/makefile
Normal file
8
dll/makefile
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
#
|
||||||
|
# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
|
||||||
|
# file to this component. This file merely indirects to the real make file
|
||||||
|
# that is shared by all the driver components of the Windows NT DDK
|
||||||
|
#
|
||||||
|
|
||||||
|
!INCLUDE $(NTMAKEENV)\makefile.def
|
||||||
|
|
||||||
900
dll/nfs41_np.c
Normal file
900
dll/nfs41_np.c
Normal file
|
|
@ -0,0 +1,900 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <npapi.h>
|
||||||
|
#include <devioctl.h>
|
||||||
|
#include <strsafe.h>
|
||||||
|
|
||||||
|
#include "nfs41_driver.h"
|
||||||
|
#include "nfs41_np.h"
|
||||||
|
#include "options.h"
|
||||||
|
|
||||||
|
#ifdef DBG
|
||||||
|
#define DbgP(_x_) NFS41DbgPrint _x_
|
||||||
|
#else
|
||||||
|
#define DbgP(_x_)
|
||||||
|
#endif
|
||||||
|
#define TRACE_TAG L"[NFS41_NP]"
|
||||||
|
#define WNNC_DRIVER( major, minor ) ( major * 0x00010000 + minor )
|
||||||
|
|
||||||
|
|
||||||
|
ULONG _cdecl NFS41DbgPrint( __in LPTSTR Format, ... )
|
||||||
|
{
|
||||||
|
ULONG rc = 0;
|
||||||
|
TCHAR szbuffer[256];
|
||||||
|
|
||||||
|
va_list marker;
|
||||||
|
va_start( marker, Format );
|
||||||
|
{
|
||||||
|
|
||||||
|
//StringCchVPrintfW( szbuffer, 127, Format, marker );
|
||||||
|
StringCchVPrintfW( szbuffer, 256, Format, marker );
|
||||||
|
szbuffer[255] = (TCHAR)0;
|
||||||
|
OutputDebugString( TRACE_TAG );
|
||||||
|
OutputDebugString( szbuffer );
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int filter(unsigned int code)
|
||||||
|
{
|
||||||
|
DbgP((L"####Got exception %u\n", code));
|
||||||
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD
|
||||||
|
OpenSharedMemory(
|
||||||
|
PHANDLE phMutex,
|
||||||
|
PHANDLE phMemory,
|
||||||
|
PVOID *pMemory)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
This routine opens the shared memory for exclusive manipulation
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
phMutex - the mutex handle
|
||||||
|
|
||||||
|
phMemory - the memory handle
|
||||||
|
|
||||||
|
pMemory - a ptr. to the shared memory which is set if successful
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
WN_SUCCESS -- if successful
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
DWORD dwStatus;
|
||||||
|
|
||||||
|
*phMutex = 0;
|
||||||
|
*phMemory = 0;
|
||||||
|
*pMemory = NULL;
|
||||||
|
|
||||||
|
*phMutex = OpenMutex(SYNCHRONIZE,
|
||||||
|
FALSE,
|
||||||
|
TEXT(NFS41NP_MUTEX_NAME));
|
||||||
|
|
||||||
|
if (*phMutex == NULL)
|
||||||
|
{
|
||||||
|
dwStatus = GetLastError();
|
||||||
|
DbgP((TEXT("OpenSharedMemory: OpenMutex failed\n")));
|
||||||
|
goto OpenSharedMemoryAbort1;
|
||||||
|
}
|
||||||
|
|
||||||
|
WaitForSingleObject(*phMutex, INFINITE);
|
||||||
|
|
||||||
|
*phMemory = OpenFileMapping(FILE_MAP_WRITE,
|
||||||
|
FALSE,
|
||||||
|
TEXT(NFS41_USER_SHARED_MEMORY_NAME));
|
||||||
|
if (*phMemory == NULL)
|
||||||
|
{
|
||||||
|
dwStatus = GetLastError();
|
||||||
|
DbgP((TEXT("OpenSharedMemory: OpenFileMapping failed\n")));
|
||||||
|
goto OpenSharedMemoryAbort2;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pMemory = MapViewOfFile(*phMemory, FILE_MAP_WRITE, 0, 0, 0);
|
||||||
|
if (*pMemory == NULL)
|
||||||
|
{
|
||||||
|
dwStatus = GetLastError();
|
||||||
|
DbgP((TEXT("OpenSharedMemory: MapViewOfFile failed\n")));
|
||||||
|
goto OpenSharedMemoryAbort3;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERROR_SUCCESS;
|
||||||
|
|
||||||
|
OpenSharedMemoryAbort3:
|
||||||
|
CloseHandle(*phMemory);
|
||||||
|
|
||||||
|
OpenSharedMemoryAbort2:
|
||||||
|
ReleaseMutex(*phMutex);
|
||||||
|
CloseHandle(*phMutex);
|
||||||
|
*phMutex = NULL;
|
||||||
|
|
||||||
|
OpenSharedMemoryAbort1:
|
||||||
|
DbgP((TEXT("OpenSharedMemory: return dwStatus: %d\n"), dwStatus));
|
||||||
|
|
||||||
|
return dwStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
CloseSharedMemory(
|
||||||
|
PHANDLE hMutex,
|
||||||
|
PHANDLE hMemory,
|
||||||
|
PVOID *pMemory)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
This routine relinquishes control of the shared memory after exclusive
|
||||||
|
manipulation
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
hMutex - the mutex handle
|
||||||
|
|
||||||
|
hMemory - the memory handle
|
||||||
|
|
||||||
|
pMemory - a ptr. to the shared memory which is set if successful
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
if (*pMemory)
|
||||||
|
{
|
||||||
|
UnmapViewOfFile(*pMemory);
|
||||||
|
*pMemory = NULL;
|
||||||
|
}
|
||||||
|
if (*hMemory)
|
||||||
|
{
|
||||||
|
CloseHandle(*hMemory);
|
||||||
|
*hMemory = 0;
|
||||||
|
}
|
||||||
|
if (*hMutex)
|
||||||
|
{
|
||||||
|
if (ReleaseMutex(*hMutex) == FALSE)
|
||||||
|
{
|
||||||
|
DbgP((TEXT("CloseSharedMemory: ReleaseMutex error: %d\n"), GetLastError()));
|
||||||
|
}
|
||||||
|
CloseHandle(*hMutex);
|
||||||
|
*hMutex = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static DWORD StoreConnectionInfo(
|
||||||
|
IN LPCWSTR LocalName,
|
||||||
|
IN LPCWSTR ConnectionName,
|
||||||
|
IN USHORT ConnectionNameLength,
|
||||||
|
IN LPNETRESOURCE lpNetResource)
|
||||||
|
{
|
||||||
|
DWORD status;
|
||||||
|
HANDLE hMutex, hMemory;
|
||||||
|
PNFS41NP_SHARED_MEMORY pSharedMemory;
|
||||||
|
PNFS41NP_NETRESOURCE pNfs41NetResource;
|
||||||
|
INT Index;
|
||||||
|
BOOLEAN FreeEntryFound = FALSE;
|
||||||
|
|
||||||
|
status = OpenSharedMemory(&hMutex, &hMemory, &(PVOID)pSharedMemory);
|
||||||
|
if (status)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
DbgP((TEXT("StoreConnectionInfo: NextIndex %d, NumResources %d\n"),
|
||||||
|
pSharedMemory->NextAvailableIndex,
|
||||||
|
pSharedMemory->NumberOfResourcesInUse));
|
||||||
|
|
||||||
|
for (Index = 0; Index < pSharedMemory->NextAvailableIndex; Index++)
|
||||||
|
{
|
||||||
|
if (!pSharedMemory->NetResources[Index].InUse)
|
||||||
|
{
|
||||||
|
FreeEntryFound = TRUE;
|
||||||
|
DbgP((TEXT("Reusing existing index %d\n"), Index));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!FreeEntryFound)
|
||||||
|
{
|
||||||
|
if (pSharedMemory->NextAvailableIndex >= NFS41NP_MAX_DEVICES) {
|
||||||
|
status = WN_NO_MORE_DEVICES;
|
||||||
|
goto out_close;
|
||||||
|
}
|
||||||
|
Index = pSharedMemory->NextAvailableIndex++;
|
||||||
|
DbgP((TEXT("Using new index %d\n"), Index));
|
||||||
|
}
|
||||||
|
|
||||||
|
pSharedMemory->NumberOfResourcesInUse += 1;
|
||||||
|
|
||||||
|
pNfs41NetResource = &pSharedMemory->NetResources[Index];
|
||||||
|
|
||||||
|
pNfs41NetResource->InUse = TRUE;
|
||||||
|
pNfs41NetResource->dwScope = lpNetResource->dwScope;
|
||||||
|
pNfs41NetResource->dwType = lpNetResource->dwType;
|
||||||
|
pNfs41NetResource->dwDisplayType = lpNetResource->dwDisplayType;
|
||||||
|
pNfs41NetResource->dwUsage = RESOURCEUSAGE_CONNECTABLE;
|
||||||
|
pNfs41NetResource->LocalNameLength = (USHORT)(wcslen(LocalName) + 1) * sizeof(WCHAR);
|
||||||
|
pNfs41NetResource->RemoteNameLength = (USHORT)(wcslen(lpNetResource->lpRemoteName) + 1) * sizeof(WCHAR);
|
||||||
|
pNfs41NetResource->ConnectionNameLength = ConnectionNameLength;
|
||||||
|
|
||||||
|
StringCchCopy(pNfs41NetResource->LocalName,
|
||||||
|
pNfs41NetResource->LocalNameLength,
|
||||||
|
LocalName);
|
||||||
|
StringCchCopy(pNfs41NetResource->RemoteName,
|
||||||
|
pNfs41NetResource->RemoteNameLength,
|
||||||
|
lpNetResource->lpRemoteName);
|
||||||
|
StringCchCopy(pNfs41NetResource->ConnectionName,
|
||||||
|
pNfs41NetResource->ConnectionNameLength,
|
||||||
|
ConnectionName);
|
||||||
|
|
||||||
|
// TODO: copy mount options -cbodley
|
||||||
|
|
||||||
|
out_close:
|
||||||
|
CloseSharedMemory(&hMutex, &hMemory, &(PVOID)pSharedMemory);
|
||||||
|
out:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
SendTo_NFS41Driver(
|
||||||
|
IN ULONG IoctlCode,
|
||||||
|
IN PVOID InputDataBuf,
|
||||||
|
IN ULONG InputDataLen,
|
||||||
|
IN PVOID OutputDataBuf,
|
||||||
|
IN PULONG pOutputDataLen)
|
||||||
|
{
|
||||||
|
HANDLE DeviceHandle; // The mini rdr device handle
|
||||||
|
BOOL rc = FALSE;
|
||||||
|
ULONG Status;
|
||||||
|
|
||||||
|
Status = WN_SUCCESS;
|
||||||
|
DbgP((L"[aglo] calling CreateFile\n"));
|
||||||
|
DeviceHandle = CreateFile(
|
||||||
|
NFS41_USER_DEVICE_NAME,
|
||||||
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
|
(LPSECURITY_ATTRIBUTES)NULL,
|
||||||
|
OPEN_EXISTING,
|
||||||
|
0,
|
||||||
|
(HANDLE) NULL );
|
||||||
|
|
||||||
|
DbgP((L"[aglo] after CreateFile Device Handle\n"));
|
||||||
|
if ( INVALID_HANDLE_VALUE != DeviceHandle )
|
||||||
|
{
|
||||||
|
__try {
|
||||||
|
DbgP((L"[aglo] calling DeviceIoControl\n"));
|
||||||
|
rc = DeviceIoControl(
|
||||||
|
DeviceHandle,
|
||||||
|
IoctlCode,
|
||||||
|
InputDataBuf,
|
||||||
|
InputDataLen,
|
||||||
|
OutputDataBuf,
|
||||||
|
*pOutputDataLen,
|
||||||
|
pOutputDataLen,
|
||||||
|
NULL );
|
||||||
|
} __except(filter(GetExceptionCode())) {
|
||||||
|
DbgP((L"#### In except\n"));
|
||||||
|
}
|
||||||
|
DbgP((L"[aglo] returned from DeviceIoControl %08lx\n", rc));
|
||||||
|
if ( !rc )
|
||||||
|
{
|
||||||
|
DbgP((L"[aglo] SendTo_NFS41Driver: returning error from DeviceIoctl\n"));
|
||||||
|
Status = GetLastError( );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DbgP((L"[aglo] SendTo_NFS41Driver: The DeviceIoctl call succeded\n"));
|
||||||
|
}
|
||||||
|
CloseHandle(DeviceHandle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Status = GetLastError( );
|
||||||
|
DbgP((L"[aglo] SendTo_NFS41Driver: error %08lx opening device \n", Status));
|
||||||
|
}
|
||||||
|
DbgP((L"[aglo] returned from SendTo_NFS41Driver %08lx\n", Status));
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD APIENTRY
|
||||||
|
NPGetCaps(
|
||||||
|
DWORD nIndex )
|
||||||
|
{
|
||||||
|
DWORD rc = 0;
|
||||||
|
|
||||||
|
DbgP(( L"[aglo] GetNetCaps %d\n", nIndex ));
|
||||||
|
switch ( nIndex )
|
||||||
|
{
|
||||||
|
case WNNC_SPEC_VERSION:
|
||||||
|
rc = WNNC_SPEC_VERSION51;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WNNC_NET_TYPE:
|
||||||
|
rc = WNNC_NET_RDR2SAMPLE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WNNC_DRIVER_VERSION:
|
||||||
|
rc = WNNC_DRIVER(1, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WNNC_CONNECTION:
|
||||||
|
rc = WNNC_CON_GETCONNECTIONS |
|
||||||
|
WNNC_CON_CANCELCONNECTION |
|
||||||
|
WNNC_CON_ADDCONNECTION |
|
||||||
|
WNNC_CON_ADDCONNECTION3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WNNC_ENUMERATION:
|
||||||
|
rc = WNNC_ENUM_LOCAL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WNNC_START:
|
||||||
|
rc = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WNNC_USER:
|
||||||
|
case WNNC_DIALOG:
|
||||||
|
case WNNC_ADMIN:
|
||||||
|
default:
|
||||||
|
rc = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD APIENTRY
|
||||||
|
NPLogonNotify(
|
||||||
|
__in PLUID lpLogonId,
|
||||||
|
__in PCWSTR lpAuthentInfoType,
|
||||||
|
__in PVOID lpAuthentInfo,
|
||||||
|
__in PCWSTR lpPreviousAuthentInfoType,
|
||||||
|
__in PVOID lpPreviousAuthentInfo,
|
||||||
|
__in PWSTR lpStationName,
|
||||||
|
__in PVOID StationHandle,
|
||||||
|
__out PWSTR *lpLogonScript)
|
||||||
|
{
|
||||||
|
*lpLogonScript = NULL;
|
||||||
|
DbgP(( L"[aglo] NPLogonNotify: returning WN_SUCCESS\n" ));
|
||||||
|
return WN_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD APIENTRY
|
||||||
|
NPPasswordChangeNotify (
|
||||||
|
__in LPCWSTR lpAuthentInfoType,
|
||||||
|
__in LPVOID lpAuthentInfo,
|
||||||
|
__in LPCWSTR lpPreviousAuthentInfoType,
|
||||||
|
__in LPVOID lpPreviousAuthentInfo,
|
||||||
|
__in LPWSTR lpStationName,
|
||||||
|
LPVOID StationHandle,
|
||||||
|
DWORD dwChangeInfo )
|
||||||
|
{
|
||||||
|
DbgP(( L"[aglo] NPPasswordChangeNotify: WN_NOT_SUPPORTED\n" ));
|
||||||
|
SetLastError( WN_NOT_SUPPORTED );
|
||||||
|
return WN_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD APIENTRY
|
||||||
|
NPAddConnection(
|
||||||
|
__in LPNETRESOURCE lpNetResource,
|
||||||
|
__in_opt LPWSTR lpPassword,
|
||||||
|
__in_opt LPWSTR lpUserName )
|
||||||
|
{
|
||||||
|
return NPAddConnection3( NULL, lpNetResource, lpPassword, lpUserName, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD APIENTRY
|
||||||
|
NPAddConnection3(
|
||||||
|
__in HWND hwndOwner,
|
||||||
|
__in LPNETRESOURCE lpNetResource,
|
||||||
|
__in_opt LPWSTR lpPassword,
|
||||||
|
__in_opt LPWSTR lpUserName,
|
||||||
|
__in DWORD dwFlags)
|
||||||
|
{
|
||||||
|
DWORD Status;
|
||||||
|
WCHAR wszScratch[128];
|
||||||
|
WCHAR LocalName[3];
|
||||||
|
DWORD CopyBytes = 0;
|
||||||
|
CONNECTION_INFO Connection;
|
||||||
|
LPWSTR ConnectionName;
|
||||||
|
WCHAR ServerName[MAX_PATH];
|
||||||
|
PWCHAR p;
|
||||||
|
DWORD i;
|
||||||
|
|
||||||
|
DbgP(( L"[aglo] NPAddConnection3('%s', '%s')\n",
|
||||||
|
lpNetResource->lpLocalName, lpNetResource->lpRemoteName ));
|
||||||
|
|
||||||
|
Status = InitializeConnectionInfo(&Connection,
|
||||||
|
(PMOUNT_OPTION_BUFFER)lpNetResource->lpComment,
|
||||||
|
&ConnectionName);
|
||||||
|
if (Status) {
|
||||||
|
DbgP(( L"InitializeConnectionInfo failed with %d\n", Status ));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// \device\miniredirector\;<DriveLetter>:\Server\Share
|
||||||
|
|
||||||
|
// local name, must start with "X:"
|
||||||
|
if (lstrlen(lpNetResource->lpLocalName) < 2 ||
|
||||||
|
lpNetResource->lpLocalName[1] != L':') {
|
||||||
|
Status = WN_BAD_LOCALNAME;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalName[0] = (WCHAR) toupper(lpNetResource->lpLocalName[0]);
|
||||||
|
LocalName[1] = L':';
|
||||||
|
LocalName[2] = L'\0';
|
||||||
|
StringCchCopyW( ConnectionName, MAX_PATH, NFS41_DEVICE_NAME );
|
||||||
|
StringCchCatW( ConnectionName, MAX_PATH, L"\\;" );
|
||||||
|
StringCchCatW( ConnectionName, MAX_PATH, LocalName );
|
||||||
|
|
||||||
|
// remote name, must start with "\\"
|
||||||
|
if (lpNetResource->lpRemoteName[0] == L'\0' ||
|
||||||
|
lpNetResource->lpRemoteName[0] != L'\\' ||
|
||||||
|
lpNetResource->lpRemoteName[1] != L'\\') {
|
||||||
|
Status = WN_BAD_NETNAME;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* note: remotename comes as \\server but we need to add \server thus +1 pointer */
|
||||||
|
p = lpNetResource->lpRemoteName + 1;
|
||||||
|
ServerName[0] = L'\\';
|
||||||
|
i = 1;
|
||||||
|
for(;;) {
|
||||||
|
/* convert servername ending unix slash to windows slash */
|
||||||
|
if (p[i] == L'/')
|
||||||
|
p[i] = L'\\';
|
||||||
|
/* deal with servername ending with any slash */
|
||||||
|
if (p[i] == L'\0')
|
||||||
|
p[i] = L'\\';
|
||||||
|
ServerName[i] = p[i];
|
||||||
|
if (p[i] == L'\\') break;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
ServerName[i] = L'\0';
|
||||||
|
StringCchCatW( ConnectionName, MAX_PATH, ServerName);
|
||||||
|
/* insert the "nfs4" in between the server name and the path,
|
||||||
|
* just to make sure all calls to our driver come thru this */
|
||||||
|
StringCchCatW( ConnectionName, MAX_PATH, L"\\nfs4" );
|
||||||
|
|
||||||
|
#ifdef CONVERT_2_UNIX_SLASHES
|
||||||
|
/* convert all windows slashes to unix slashes */
|
||||||
|
{
|
||||||
|
PWCHAR q = p;
|
||||||
|
DWORD j = 0;
|
||||||
|
for(;;) {
|
||||||
|
if(q[j] == L'\0') break;
|
||||||
|
if (q[j] == L'\\') q[j] = L'/';
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* convert all unix slashes to windows slashes */
|
||||||
|
{
|
||||||
|
PWCHAR q = p;
|
||||||
|
DWORD j = 0;
|
||||||
|
for(;;) {
|
||||||
|
if(q[j] == L'\0') break;
|
||||||
|
if (q[j] == L'/') q[j] = L'\\';
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
StringCchCatW( ConnectionName, MAX_PATH, &p[i]);
|
||||||
|
DbgP(( L"[aglo] Full Connect Name: %s\n", ConnectionName ));
|
||||||
|
DbgP(( L"[aglo] Full Connect Name Length: %d %d\n",
|
||||||
|
(wcslen(ConnectionName) + 1) * sizeof(WCHAR),
|
||||||
|
(lstrlen(ConnectionName) + 1) * sizeof(WCHAR)));
|
||||||
|
|
||||||
|
if ( QueryDosDevice( LocalName, wszScratch, 128 )
|
||||||
|
|| GetLastError() != ERROR_FILE_NOT_FOUND) {
|
||||||
|
Status = WN_ALREADY_CONNECTED;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
MarshalConnectionInfo(&Connection);
|
||||||
|
|
||||||
|
Status = SendTo_NFS41Driver( IOCTL_NFS41_ADDCONN,
|
||||||
|
Connection.Buffer, Connection.BufferSize,
|
||||||
|
NULL, &CopyBytes );
|
||||||
|
if (Status) {
|
||||||
|
DbgP(( L"[aglo] SendTo_NFS41Driver failed with %d\n", Status));
|
||||||
|
Status = WN_BAD_NETNAME;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
DbgP(( L"[aglo] calling DefineDosDevice\n"));
|
||||||
|
if ( !DefineDosDevice( DDD_RAW_TARGET_PATH |
|
||||||
|
DDD_NO_BROADCAST_SYSTEM,
|
||||||
|
lpNetResource->lpLocalName,
|
||||||
|
ConnectionName ) ) {
|
||||||
|
Status = GetLastError();
|
||||||
|
DbgP(( L"[aglo] DefineDosDevice failed with %d\n", Status));
|
||||||
|
goto out_delconn;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The connection was established and the local device mapping
|
||||||
|
// added. Include this in the list of mapped devices.
|
||||||
|
Status = StoreConnectionInfo(LocalName, ConnectionName,
|
||||||
|
Connection.Buffer->NameLength, lpNetResource);
|
||||||
|
if (Status) {
|
||||||
|
DbgP(( L"[aglo] StoreConnectionInfo failed with %d\n", Status));
|
||||||
|
goto out_undefine;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
FreeConnectionInfo(&Connection);
|
||||||
|
DbgP(( L"[aglo] NPAddConnection3: status %08X\n", Status));
|
||||||
|
return Status;
|
||||||
|
out_undefine:
|
||||||
|
DefineDosDevice(DDD_REMOVE_DEFINITION | DDD_RAW_TARGET_PATH |
|
||||||
|
DDD_EXACT_MATCH_ON_REMOVE, LocalName, ConnectionName);
|
||||||
|
out_delconn:
|
||||||
|
SendTo_NFS41Driver(IOCTL_NFS41_DELCONN, ConnectionName,
|
||||||
|
Connection.Buffer->NameLength, NULL, &CopyBytes);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD APIENTRY
|
||||||
|
NPCancelConnection(
|
||||||
|
__in LPWSTR lpName,
|
||||||
|
__in BOOL fForce )
|
||||||
|
{
|
||||||
|
DWORD Status = 0;
|
||||||
|
|
||||||
|
HANDLE hMutex, hMemory;
|
||||||
|
PNFS41NP_SHARED_MEMORY pSharedMemory;
|
||||||
|
|
||||||
|
DbgP((TEXT("NPCancelConnection\n")));
|
||||||
|
DbgP((TEXT("NPCancelConnection: ConnectionName: %S\n"), lpName));
|
||||||
|
|
||||||
|
Status = OpenSharedMemory( &hMutex,
|
||||||
|
&hMemory,
|
||||||
|
(PVOID)&pSharedMemory);
|
||||||
|
|
||||||
|
if (Status == WN_SUCCESS)
|
||||||
|
{
|
||||||
|
INT Index;
|
||||||
|
PNFS41NP_NETRESOURCE pNetResource;
|
||||||
|
Status = WN_NOT_CONNECTED;
|
||||||
|
|
||||||
|
DbgP((TEXT("NPCancelConnection: NextIndex %d, NumResources %d\n"),
|
||||||
|
pSharedMemory->NextAvailableIndex,
|
||||||
|
pSharedMemory->NumberOfResourcesInUse));
|
||||||
|
|
||||||
|
for (Index = 0; Index < pSharedMemory->NextAvailableIndex; Index++)
|
||||||
|
{
|
||||||
|
pNetResource = &pSharedMemory->NetResources[Index];
|
||||||
|
|
||||||
|
if (pNetResource->InUse)
|
||||||
|
{
|
||||||
|
if ( ( (wcslen(lpName) + 1) * sizeof(WCHAR) ==
|
||||||
|
pNetResource->LocalNameLength)
|
||||||
|
&& ( !wcscmp(lpName, pNetResource->LocalName) ))
|
||||||
|
{
|
||||||
|
ULONG CopyBytes;
|
||||||
|
|
||||||
|
DbgP((TEXT("NPCancelConnection: Connection Found:\n")));
|
||||||
|
|
||||||
|
CopyBytes = 0;
|
||||||
|
|
||||||
|
Status = SendTo_NFS41Driver( IOCTL_NFS41_DELCONN,
|
||||||
|
pNetResource->ConnectionName,
|
||||||
|
pNetResource->ConnectionNameLength,
|
||||||
|
NULL,
|
||||||
|
&CopyBytes );
|
||||||
|
|
||||||
|
if (Status != WN_SUCCESS)
|
||||||
|
{
|
||||||
|
DbgP((TEXT("NPCancelConnection: SendToMiniRdr returned Status %lx\n"),Status));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DefineDosDevice(DDD_REMOVE_DEFINITION | DDD_RAW_TARGET_PATH | DDD_EXACT_MATCH_ON_REMOVE,
|
||||||
|
lpName,
|
||||||
|
pNetResource->ConnectionName) == FALSE)
|
||||||
|
{
|
||||||
|
DbgP((TEXT("RemoveDosDevice: DefineDosDevice error: %d\n"), GetLastError()));
|
||||||
|
Status = GetLastError();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pNetResource->InUse = FALSE;
|
||||||
|
pSharedMemory->NumberOfResourcesInUse--;
|
||||||
|
|
||||||
|
if (Index+1 == pSharedMemory->NextAvailableIndex)
|
||||||
|
pSharedMemory->NextAvailableIndex--;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
DbgP((TEXT("NPCancelConnection: Name %S EntryName %S\n"),
|
||||||
|
lpName,pNetResource->LocalName));
|
||||||
|
DbgP((TEXT("NPCancelConnection: Name Length %d Entry Name Length %d\n"),
|
||||||
|
pNetResource->LocalNameLength,pNetResource->LocalName));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseSharedMemory( &hMutex,
|
||||||
|
&hMemory,
|
||||||
|
(PVOID)&pSharedMemory);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD APIENTRY
|
||||||
|
NPGetConnection(
|
||||||
|
__in LPWSTR lpLocalName,
|
||||||
|
__out_bcount(*lpBufferSize) LPWSTR lpRemoteName,
|
||||||
|
__inout LPDWORD lpBufferSize )
|
||||||
|
{
|
||||||
|
DWORD Status = 0;
|
||||||
|
|
||||||
|
HANDLE hMutex, hMemory;
|
||||||
|
PNFS41NP_SHARED_MEMORY pSharedMemory;
|
||||||
|
|
||||||
|
Status = OpenSharedMemory( &hMutex,
|
||||||
|
&hMemory,
|
||||||
|
(PVOID)&pSharedMemory);
|
||||||
|
|
||||||
|
if (Status == WN_SUCCESS)
|
||||||
|
{
|
||||||
|
INT Index;
|
||||||
|
PNFS41NP_NETRESOURCE pNetResource;
|
||||||
|
Status = WN_NOT_CONNECTED;
|
||||||
|
|
||||||
|
for (Index = 0; Index < pSharedMemory->NextAvailableIndex; Index++)
|
||||||
|
{
|
||||||
|
pNetResource = &pSharedMemory->NetResources[Index];
|
||||||
|
|
||||||
|
if (pNetResource->InUse)
|
||||||
|
{
|
||||||
|
if ( ( (wcslen(lpLocalName) + 1) * sizeof(WCHAR) ==
|
||||||
|
pNetResource->LocalNameLength)
|
||||||
|
&& ( !wcscmp(lpLocalName, pNetResource->LocalName) ))
|
||||||
|
{
|
||||||
|
if (*lpBufferSize < pNetResource->RemoteNameLength)
|
||||||
|
{
|
||||||
|
*lpBufferSize = pNetResource->RemoteNameLength;
|
||||||
|
Status = WN_MORE_DATA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*lpBufferSize = pNetResource->RemoteNameLength;
|
||||||
|
CopyMemory( lpRemoteName,
|
||||||
|
pNetResource->RemoteName,
|
||||||
|
pNetResource->RemoteNameLength);
|
||||||
|
Status = WN_SUCCESS;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseSharedMemory( &hMutex, &hMemory, (PVOID)&pSharedMemory);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD APIENTRY
|
||||||
|
NPOpenEnum(
|
||||||
|
DWORD dwScope,
|
||||||
|
DWORD dwType,
|
||||||
|
DWORD dwUsage,
|
||||||
|
LPNETRESOURCE lpNetResource,
|
||||||
|
LPHANDLE lphEnum )
|
||||||
|
{
|
||||||
|
DWORD Status;
|
||||||
|
|
||||||
|
DbgP((L"[aglo] NPOpenEnum\n"));
|
||||||
|
|
||||||
|
*lphEnum = NULL;
|
||||||
|
|
||||||
|
switch ( dwScope )
|
||||||
|
{
|
||||||
|
case RESOURCE_CONNECTED:
|
||||||
|
{
|
||||||
|
*lphEnum = HeapAlloc( GetProcessHeap( ), HEAP_ZERO_MEMORY, sizeof( ULONG ) );
|
||||||
|
|
||||||
|
if (*lphEnum )
|
||||||
|
{
|
||||||
|
Status = WN_SUCCESS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Status = WN_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RESOURCE_CONTEXT:
|
||||||
|
default:
|
||||||
|
Status = WN_NOT_SUPPORTED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DbgP((L"[aglo] NPOpenEnum returning Status %lx\n",Status));
|
||||||
|
|
||||||
|
return(Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD APIENTRY
|
||||||
|
NPEnumResource(
|
||||||
|
HANDLE hEnum,
|
||||||
|
LPDWORD lpcCount,
|
||||||
|
LPVOID lpBuffer,
|
||||||
|
LPDWORD lpBufferSize)
|
||||||
|
{
|
||||||
|
DWORD Status = WN_SUCCESS;
|
||||||
|
ULONG EntriesCopied;
|
||||||
|
LPNETRESOURCE pNetResource;
|
||||||
|
ULONG SpaceNeeded = 0;
|
||||||
|
ULONG SpaceAvailable;
|
||||||
|
PWCHAR StringZone;
|
||||||
|
HANDLE hMutex, hMemory;
|
||||||
|
PNFS41NP_SHARED_MEMORY pSharedMemory;
|
||||||
|
PNFS41NP_NETRESOURCE pNfsNetResource;
|
||||||
|
INT Index = *(PULONG)hEnum;
|
||||||
|
|
||||||
|
|
||||||
|
DbgP((L"[aglo] NPEnumResource\n"));
|
||||||
|
|
||||||
|
DbgP((L"[aglo] NPEnumResource Count Requested %d\n", *lpcCount));
|
||||||
|
|
||||||
|
pNetResource = (LPNETRESOURCE) lpBuffer;
|
||||||
|
SpaceAvailable = *lpBufferSize;
|
||||||
|
EntriesCopied = 0;
|
||||||
|
StringZone = (PWCHAR) ((PBYTE)lpBuffer + *lpBufferSize);
|
||||||
|
|
||||||
|
Status = OpenSharedMemory( &hMutex,
|
||||||
|
&hMemory,
|
||||||
|
(PVOID)&pSharedMemory);
|
||||||
|
|
||||||
|
if ( Status == WN_SUCCESS)
|
||||||
|
{
|
||||||
|
Status = WN_NO_MORE_ENTRIES;
|
||||||
|
for (Index = *(PULONG)hEnum; Index < pSharedMemory->NextAvailableIndex; Index++)
|
||||||
|
{
|
||||||
|
pNfsNetResource = &pSharedMemory->NetResources[Index];
|
||||||
|
|
||||||
|
if (pNfsNetResource->InUse)
|
||||||
|
{
|
||||||
|
SpaceNeeded = sizeof( NETRESOURCE );
|
||||||
|
SpaceNeeded += pNfsNetResource->LocalNameLength;
|
||||||
|
SpaceNeeded += pNfsNetResource->RemoteNameLength;
|
||||||
|
SpaceNeeded += 5 * sizeof(WCHAR); // comment
|
||||||
|
SpaceNeeded += sizeof(NFS41_PROVIDER_NAME_U); // provider name
|
||||||
|
if ( SpaceNeeded > SpaceAvailable )
|
||||||
|
{
|
||||||
|
Status = WN_MORE_DATA;
|
||||||
|
DbgP((L"[aglo] NPEnumResource More Data Needed - %d\n", SpaceNeeded));
|
||||||
|
*lpBufferSize = SpaceNeeded;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SpaceAvailable -= SpaceNeeded;
|
||||||
|
|
||||||
|
pNetResource->dwScope = pNfsNetResource->dwScope;
|
||||||
|
pNetResource->dwType = pNfsNetResource->dwType;
|
||||||
|
pNetResource->dwDisplayType = pNfsNetResource->dwDisplayType;
|
||||||
|
pNetResource->dwUsage = pNfsNetResource->dwUsage;
|
||||||
|
|
||||||
|
// setup string area at opposite end of buffer
|
||||||
|
SpaceNeeded -= sizeof( NETRESOURCE );
|
||||||
|
StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded );
|
||||||
|
// copy local name
|
||||||
|
StringCchCopy( StringZone,
|
||||||
|
pNfsNetResource->LocalNameLength,
|
||||||
|
pNfsNetResource->LocalName );
|
||||||
|
pNetResource->lpLocalName = StringZone;
|
||||||
|
StringZone += pNfsNetResource->LocalNameLength/sizeof(WCHAR);
|
||||||
|
// copy remote name
|
||||||
|
StringCchCopy( StringZone,
|
||||||
|
pNfsNetResource->RemoteNameLength,
|
||||||
|
pNfsNetResource->RemoteName );
|
||||||
|
pNetResource->lpRemoteName = StringZone;
|
||||||
|
StringZone += pNfsNetResource->RemoteNameLength/sizeof(WCHAR);
|
||||||
|
// copy comment
|
||||||
|
pNetResource->lpComment = StringZone;
|
||||||
|
*StringZone++ = L'A';
|
||||||
|
*StringZone++ = L'_';
|
||||||
|
*StringZone++ = L'O';
|
||||||
|
*StringZone++ = L'K';
|
||||||
|
*StringZone++ = L'\0';
|
||||||
|
// copy provider name
|
||||||
|
pNetResource->lpProvider = StringZone;
|
||||||
|
StringCbCopyW( StringZone, sizeof(NFS41_PROVIDER_NAME_U), NFS41_PROVIDER_NAME_U );
|
||||||
|
StringZone += sizeof(NFS41_PROVIDER_NAME_U)/sizeof(WCHAR);
|
||||||
|
EntriesCopied++;
|
||||||
|
if(EntriesCopied >= *lpcCount)
|
||||||
|
{
|
||||||
|
Status = WN_SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// set new bottom of string zone
|
||||||
|
StringZone = (PWCHAR)( (PBYTE) StringZone - SpaceNeeded );
|
||||||
|
}
|
||||||
|
pNetResource++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CloseSharedMemory( &hMutex, &hMemory, (PVOID*)&pSharedMemory);
|
||||||
|
}
|
||||||
|
|
||||||
|
*lpcCount = EntriesCopied;
|
||||||
|
*(PULONG) hEnum = Index;
|
||||||
|
|
||||||
|
DbgP((L"[aglo] NPEnumResource entries returned: %d\n", EntriesCopied));
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD APIENTRY
|
||||||
|
NPCloseEnum(
|
||||||
|
HANDLE hEnum )
|
||||||
|
{
|
||||||
|
DbgP((L"[aglo] NPCloseEnum\n"));
|
||||||
|
HeapFree( GetProcessHeap( ), 0, (PVOID) hEnum );
|
||||||
|
return WN_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD APIENTRY
|
||||||
|
NPGetResourceParent(
|
||||||
|
LPNETRESOURCE lpNetResource,
|
||||||
|
LPVOID lpBuffer,
|
||||||
|
LPDWORD lpBufferSize )
|
||||||
|
{
|
||||||
|
DbgP(( L"[aglo] NPGetResourceParent: WN_NOT_SUPPORTED\n" ));
|
||||||
|
return WN_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD APIENTRY
|
||||||
|
NPGetResourceInformation(
|
||||||
|
__in LPNETRESOURCE lpNetResource,
|
||||||
|
__out_bcount(*lpBufferSize) LPVOID lpBuffer,
|
||||||
|
__inout LPDWORD lpBufferSize,
|
||||||
|
__deref_out LPWSTR *lplpSystem )
|
||||||
|
{
|
||||||
|
DbgP(( L"[aglo] NPGetResourceInformation: WN_NOT_SUPPORTED\n" ));
|
||||||
|
return WN_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD APIENTRY
|
||||||
|
NPGetUniversalName(
|
||||||
|
LPCWSTR lpLocalPath,
|
||||||
|
DWORD dwInfoLevel,
|
||||||
|
LPVOID lpBuffer,
|
||||||
|
LPDWORD lpBufferSize )
|
||||||
|
{
|
||||||
|
DbgP(( L"[aglo] NPGetUniversalName: WN_NOT_SUPPORTED\n" ));
|
||||||
|
return WN_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
17
dll/nfs41_np.def
Normal file
17
dll/nfs41_np.def
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
SECTIONS .NFS41_NP READ WRITE SHARED
|
||||||
|
|
||||||
|
EXPORTS
|
||||||
|
NPGetCaps @13
|
||||||
|
NPAddConnection @17
|
||||||
|
NPAddConnection3 @38
|
||||||
|
NPCancelConnection @18
|
||||||
|
NPGetConnection @12
|
||||||
|
NPOpenEnum @33
|
||||||
|
NPEnumResource @34
|
||||||
|
NPCloseEnum @35
|
||||||
|
NPGetUniversalName @40
|
||||||
|
NPGetResourceParent @41
|
||||||
|
NPGetResourceInformation @52
|
||||||
|
NPLogonNotify @500
|
||||||
|
NPPasswordChangeNotify @501
|
||||||
|
|
||||||
52
dll/nfs41_np.h
Normal file
52
dll/nfs41_np.h
Normal file
|
|
@ -0,0 +1,52 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __NFS41_NP_H__
|
||||||
|
#define __NFS41_NP_H__
|
||||||
|
|
||||||
|
#define NFS41NP_MUTEX_NAME "NFS41NPMUTEX"
|
||||||
|
|
||||||
|
#define NFS41NP_MAX_DEVICES 26
|
||||||
|
|
||||||
|
typedef struct __NFS41NP_NETRESOURCE {
|
||||||
|
BOOL InUse;
|
||||||
|
USHORT LocalNameLength;
|
||||||
|
USHORT RemoteNameLength;
|
||||||
|
USHORT ConnectionNameLength;
|
||||||
|
DWORD dwScope;
|
||||||
|
DWORD dwType;
|
||||||
|
DWORD dwDisplayType;
|
||||||
|
DWORD dwUsage;
|
||||||
|
WCHAR LocalName[MAX_PATH];
|
||||||
|
WCHAR RemoteName[MAX_PATH];
|
||||||
|
WCHAR ConnectionName[MAX_PATH];
|
||||||
|
WCHAR Options[MAX_PATH];
|
||||||
|
} NFS41NP_NETRESOURCE, *PNFS41NP_NETRESOURCE;
|
||||||
|
|
||||||
|
typedef struct __NFS41NP_SHARED_MEMORY {
|
||||||
|
INT NextAvailableIndex;
|
||||||
|
INT NumberOfResourcesInUse;
|
||||||
|
NFS41NP_NETRESOURCE NetResources[NFS41NP_MAX_DEVICES];
|
||||||
|
} NFS41NP_SHARED_MEMORY, *PNFS41NP_SHARED_MEMORY;
|
||||||
|
|
||||||
|
#endif /* !__NFS41_NP_H__ */
|
||||||
100
dll/options.c
Normal file
100
dll/options.c
Normal file
|
|
@ -0,0 +1,100 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include "options.h"
|
||||||
|
|
||||||
|
|
||||||
|
DWORD InitializeConnectionInfo(
|
||||||
|
IN OUT PCONNECTION_INFO Connection,
|
||||||
|
IN PMOUNT_OPTION_BUFFER Options,
|
||||||
|
OUT LPWSTR *ConnectionName)
|
||||||
|
{
|
||||||
|
DWORD result = WN_SUCCESS;
|
||||||
|
SIZE_T size;
|
||||||
|
|
||||||
|
/* verify that this is a mount options buffer */
|
||||||
|
if (Options &&
|
||||||
|
Options->Zero == 0 &&
|
||||||
|
Options->Secret == MOUNT_OPTION_BUFFER_SECRET)
|
||||||
|
{
|
||||||
|
Connection->Options = Options;
|
||||||
|
size = MAX_CONNECTION_BUFFER_SIZE(Options->Length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Connection->Options = NULL;
|
||||||
|
size = MAX_CONNECTION_BUFFER_SIZE(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Connection->Buffer = LocalAlloc(LMEM_ZEROINIT, size);
|
||||||
|
if (Connection->Buffer)
|
||||||
|
*ConnectionName = (LPWSTR)Connection->Buffer->Buffer;
|
||||||
|
else
|
||||||
|
result = WN_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FORCEINLINE SIZE_T ConnectionBufferSize(
|
||||||
|
IN PCONNECTION_BUFFER Buffer)
|
||||||
|
{
|
||||||
|
return sizeof(USHORT) + sizeof(USHORT) + sizeof(ULONG) +
|
||||||
|
Buffer->NameLength + Buffer->EaPadding + Buffer->EaLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MarshalConnectionInfo(
|
||||||
|
IN OUT PCONNECTION_INFO Connection)
|
||||||
|
{
|
||||||
|
PCONNECTION_BUFFER Buffer = Connection->Buffer;
|
||||||
|
LPWSTR ConnectionName = (LPWSTR)Buffer->Buffer;
|
||||||
|
|
||||||
|
Buffer->NameLength = (USHORT)(wcslen(ConnectionName) + 1) * sizeof(WCHAR);
|
||||||
|
|
||||||
|
/* copy the EaBuffer after the end of ConnectionName */
|
||||||
|
if (Connection->Options && Connection->Options->Length)
|
||||||
|
{
|
||||||
|
PBYTE ptr = Buffer->Buffer + Buffer->NameLength;
|
||||||
|
/* add padding so EaBuffer starts on a ULONG boundary */
|
||||||
|
Buffer->EaPadding = (USHORT)
|
||||||
|
(sizeof(ULONG) - (SIZE_T)ptr % sizeof(ULONG)) % sizeof(ULONG);
|
||||||
|
Buffer->EaLength = Connection->Options->Length;
|
||||||
|
ptr += Buffer->EaPadding;
|
||||||
|
|
||||||
|
RtlCopyMemory(ptr, Connection->Options->Buffer, Buffer->EaLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
Connection->BufferSize = (ULONG)ConnectionBufferSize(Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FreeConnectionInfo(
|
||||||
|
IN PCONNECTION_INFO Connection)
|
||||||
|
{
|
||||||
|
if (Connection->Buffer)
|
||||||
|
{
|
||||||
|
LocalFree(Connection->Buffer);
|
||||||
|
Connection->Buffer = NULL;
|
||||||
|
}
|
||||||
|
Connection->Options = NULL;
|
||||||
|
Connection->BufferSize = 0;
|
||||||
|
}
|
||||||
84
dll/options.h
Normal file
84
dll/options.h
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __NFS41_NP_OPTIONS_H__
|
||||||
|
#define __NFS41_NP_OPTIONS_H__
|
||||||
|
|
||||||
|
|
||||||
|
#define MOUNT_OPTION_BUFFER_SECRET ('n4')
|
||||||
|
|
||||||
|
/* MOUNT_OPTION_BUFFER
|
||||||
|
* The mount options buffer received by NPAddConnection3
|
||||||
|
* via NETRESOURCE.lpComment. To avoid interpreting a normal
|
||||||
|
* comment string as mount options, a NULL and secret number
|
||||||
|
* are expected at the front. */
|
||||||
|
typedef struct _MOUNT_OPTION_BUFFER {
|
||||||
|
USHORT Zero; /* = 0 */
|
||||||
|
USHORT Secret; /* = 'n4' */
|
||||||
|
ULONG Length;
|
||||||
|
BYTE Buffer[1];
|
||||||
|
} MOUNT_OPTION_BUFFER, *PMOUNT_OPTION_BUFFER;
|
||||||
|
|
||||||
|
/* CONNECTION_BUFFER
|
||||||
|
* The connection information as sent to the driver via
|
||||||
|
* IOCTL_NFS41_ADDCONN. The buffer contains the connection name
|
||||||
|
* followed by any extended attributes for mount options. */
|
||||||
|
typedef struct _CONNECTION_BUFFER {
|
||||||
|
USHORT NameLength; /* length of connection filename */
|
||||||
|
USHORT EaPadding; /* 0-3 bytes of padding to put EaBuffer
|
||||||
|
* on a ULONG boundary */
|
||||||
|
ULONG EaLength; /* length of EaBuffer */
|
||||||
|
BYTE Buffer[1];
|
||||||
|
} CONNECTION_BUFFER, *PCONNECTION_BUFFER;
|
||||||
|
|
||||||
|
/* CONNECTION_INFO
|
||||||
|
* Used in NPAddConnection3 to encapsulate the formation of
|
||||||
|
* the connection buffer. */
|
||||||
|
typedef struct _CONNECTION_INFO {
|
||||||
|
PMOUNT_OPTION_BUFFER Options;
|
||||||
|
ULONG BufferSize;
|
||||||
|
PCONNECTION_BUFFER Buffer;
|
||||||
|
} CONNECTION_INFO, *PCONNECTION_INFO;
|
||||||
|
|
||||||
|
#define MAX_CONNECTION_BUFFER_SIZE(EaSize) ( \
|
||||||
|
sizeof(CONNECTION_BUFFER) + MAX_PATH + (EaSize) )
|
||||||
|
|
||||||
|
|
||||||
|
/* options.c */
|
||||||
|
DWORD InitializeConnectionInfo(
|
||||||
|
IN OUT PCONNECTION_INFO Connection,
|
||||||
|
IN PMOUNT_OPTION_BUFFER Options,
|
||||||
|
OUT LPWSTR *ConnectionName);
|
||||||
|
|
||||||
|
void FreeConnectionInfo(
|
||||||
|
IN OUT PCONNECTION_INFO Connection);
|
||||||
|
|
||||||
|
/* MarshallConnectionInfo
|
||||||
|
* Prepares the CONNECTION_BUFFER for transmission to the driver
|
||||||
|
* by copying the extended attributes into place and updating the
|
||||||
|
* lengths accordingly. */
|
||||||
|
void MarshalConnectionInfo(
|
||||||
|
IN OUT PCONNECTION_INFO Connection);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* !__NFS41_NP_OPTIONS_H__ */
|
||||||
21
dll/sources
Normal file
21
dll/sources
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
TARGETTYPE=DYNLINK
|
||||||
|
TARGETNAME=nfs41_np
|
||||||
|
SOURCES=dllmain.c nfs41_np.c options.c
|
||||||
|
UMTYPE=console
|
||||||
|
UNICODE=1
|
||||||
|
DLLBASE=0x1010000
|
||||||
|
USE_NTDLL=1
|
||||||
|
NET_C_DEFINES=-DUNICODE
|
||||||
|
INCLUDES=..\sys; \
|
||||||
|
$(DDK_INC_PATH);
|
||||||
|
TARGETLIBS=$(DDK_LIB_PATH)\user32.lib $(DDK_LIB_PATH)\kernel32.lib
|
||||||
|
DLLDEF=nfs41_np.def
|
||||||
|
|
||||||
|
!IF 0
|
||||||
|
/W3 is default level
|
||||||
|
bump to /Wall, but suppress warnings generated by system includes,
|
||||||
|
as well as the following warnings:
|
||||||
|
4100 - unused function call arguments (we have lots of stubs)
|
||||||
|
4127 - constant conditional (I like to use if(0) or if(1))
|
||||||
|
!ENDIF
|
||||||
|
MSC_WARNING_LEVEL=/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127 /wd4711
|
||||||
2
install.bat
Normal file
2
install.bat
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
nfs_install.exe
|
||||||
|
rundll32.exe setupapi.dll,InstallHinfSection DefaultInstall 132 ./nfs41rdr.inf
|
||||||
47
install/nfs_install.c
Normal file
47
install/nfs_install.c
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* This file is just for prepending nfs41_driver to the
|
||||||
|
* correct regestry entry
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <tchar.h>
|
||||||
|
|
||||||
|
#include "nfs41_driver.h"
|
||||||
|
#include "nfsreginst.h"
|
||||||
|
|
||||||
|
void __cdecl _tmain(int argc, TCHAR *argv[])
|
||||||
|
{
|
||||||
|
if(argc == 1 || atoi(argv[1]) == 1)
|
||||||
|
{
|
||||||
|
RdrSetupProviderOrder();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while( RdrRemoveProviderFromOrder() ) {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
652
install/nfsreginst.c
Normal file
652
install/nfsreginst.c
Normal file
|
|
@ -0,0 +1,652 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
nfsreginst.c
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#include "nfsreginst.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
REGENTRY ProviderOrderKeyValues[] =
|
||||||
|
{
|
||||||
|
{ TEXT("ProviderOrder"), REG_SZ, 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
BOOL RdrSetupProviderOrder( void )
|
||||||
|
{
|
||||||
|
LPTSTR pOrderString = NULL;
|
||||||
|
ULONG_PTR len;
|
||||||
|
BOOL success = TRUE;
|
||||||
|
LPTSTR pNewOrderString;
|
||||||
|
|
||||||
|
while( RdrRemoveProviderFromOrder() ) {};
|
||||||
|
|
||||||
|
len = RdrGetProviderOrderString( &pOrderString ) * sizeof(TCHAR);
|
||||||
|
if ( len > 0 && pOrderString )
|
||||||
|
{
|
||||||
|
len += sizeof( PROVIDER_NAME ) + (2 * sizeof(TCHAR)); // add 2 for comma delimeter and null
|
||||||
|
pNewOrderString = malloc( len );
|
||||||
|
if ( pNewOrderString )
|
||||||
|
{
|
||||||
|
StringCbCopy( pNewOrderString, len, PROVIDER_NAME );
|
||||||
|
StringCbCat( pNewOrderString, len, TEXT(",") );
|
||||||
|
StringCbCat( pNewOrderString, len, pOrderString );
|
||||||
|
success = RdrSetProviderOrderString( pNewOrderString );
|
||||||
|
free( pNewOrderString );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
success = RdrSetProviderOrderString( PROVIDER_NAME );
|
||||||
|
}
|
||||||
|
if ( pOrderString )
|
||||||
|
{
|
||||||
|
free( pOrderString );
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ULONG_PTR RdrGetProviderOrderString( __out LPTSTR *OrderString )
|
||||||
|
{
|
||||||
|
HKEY hOrderKey;
|
||||||
|
ULONG_PTR len = 0;
|
||||||
|
|
||||||
|
if ( OpenKey( PROVIDER_ORDER_KEY, &hOrderKey ) )
|
||||||
|
{
|
||||||
|
ReadRegistryKeyValues( hOrderKey,
|
||||||
|
sizeof(ProviderOrderKeyValues) / sizeof(REGENTRY),
|
||||||
|
ProviderOrderKeyValues);
|
||||||
|
|
||||||
|
RegCloseKey(hOrderKey);
|
||||||
|
len = ProviderOrderKeyValues[0].dwLength / sizeof( TCHAR ) - 1;
|
||||||
|
*OrderString = (LPTSTR) ProviderOrderKeyValues[0].pvValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOL RdrSetProviderOrderString( __in LPTSTR OrderString )
|
||||||
|
{
|
||||||
|
HKEY hOrderKey;
|
||||||
|
BOOL rc = FALSE;
|
||||||
|
|
||||||
|
if ( CreateKey( PROVIDER_ORDER_KEY, &hOrderKey ) )
|
||||||
|
{
|
||||||
|
ProviderOrderKeyValues[0].dwLength = ( lstrlen( OrderString ) + 1 ) * sizeof( TCHAR );
|
||||||
|
ProviderOrderKeyValues[0].pvValue = OrderString;
|
||||||
|
WriteRegistryKeyValues( hOrderKey,
|
||||||
|
sizeof(ProviderOrderKeyValues) / sizeof(REGENTRY),
|
||||||
|
ProviderOrderKeyValues);
|
||||||
|
RegCloseKey(hOrderKey);
|
||||||
|
|
||||||
|
rc = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOL RdrRemoveProviderFromOrder( void )
|
||||||
|
{
|
||||||
|
LPTSTR pCompare, OrderString, pOrig, Provider = PROVIDER_NAME;
|
||||||
|
BOOL match = FALSE;
|
||||||
|
ULONG_PTR len = 0;
|
||||||
|
|
||||||
|
len = RdrGetProviderOrderString( &pOrig );
|
||||||
|
OrderString = pOrig;
|
||||||
|
if ( OrderString && Provider && *Provider )
|
||||||
|
{
|
||||||
|
pCompare = Provider;
|
||||||
|
|
||||||
|
while ( *OrderString )
|
||||||
|
{
|
||||||
|
if ( toupper(*OrderString) != toupper(*pCompare++) )
|
||||||
|
{
|
||||||
|
pCompare = Provider;
|
||||||
|
while ( ( *OrderString != TEXT(',') ) && ( *OrderString != TEXT('\0') ) )
|
||||||
|
{
|
||||||
|
OrderString++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( *OrderString != TEXT('\0') ) OrderString++;
|
||||||
|
if ( *pCompare == TEXT('\0') )
|
||||||
|
{
|
||||||
|
if ( ( *OrderString == TEXT(',') ) || ( *OrderString == TEXT('\0') ) )
|
||||||
|
{
|
||||||
|
LPTSTR pNewString;
|
||||||
|
pNewString = malloc( len ); //Yes, this is a little larger than necessary
|
||||||
|
//No, I don't care that much
|
||||||
|
StringCchCopy(pNewString, len, pOrig);
|
||||||
|
//if ((DWORD_PTR)OrderString - (DWORD_PTR)pOrig - (DWORD_PTR)pCompare + (DWORD_PTR)Provider == 0 ) OrderString += 1;
|
||||||
|
if ( *OrderString == TEXT(',') )
|
||||||
|
{
|
||||||
|
StringCchCopy(pNewString + (DWORD_PTR)OrderString - (DWORD_PTR)pOrig - (DWORD_PTR)pCompare + (DWORD_PTR)Provider, len, OrderString + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StringCchCopy(pNewString + (DWORD_PTR)OrderString - (DWORD_PTR)pOrig - (DWORD_PTR)pCompare + (DWORD_PTR)Provider - 1, len, OrderString);
|
||||||
|
}
|
||||||
|
match = RdrSetProviderOrderString( pNewString );
|
||||||
|
free(pNewString);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else // hmm, it's a substring of another provider name
|
||||||
|
{
|
||||||
|
while ( ( *OrderString != TEXT(',') ) && ( *OrderString != TEXT('\0') ) )
|
||||||
|
{
|
||||||
|
OrderString++;
|
||||||
|
}
|
||||||
|
pCompare = Provider;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free( pOrig );
|
||||||
|
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ReadRegistryKeyValues(
|
||||||
|
HKEY hCurrentKey,
|
||||||
|
DWORD NumberOfValues,
|
||||||
|
PREGENTRY pValues)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
This routine reads a bunch of values associated with a given key.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
hCurrentKey - the key
|
||||||
|
|
||||||
|
NumberOfValues - the number of values
|
||||||
|
|
||||||
|
pValues - the array of values
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// Iterate through table reading the values along the way
|
||||||
|
//
|
||||||
|
|
||||||
|
DWORD i;
|
||||||
|
|
||||||
|
for (i = 0; i < NumberOfValues; i++)
|
||||||
|
{
|
||||||
|
DWORD dwType;
|
||||||
|
LPTSTR pszKey;
|
||||||
|
|
||||||
|
dwType = pValues[i].dwType;
|
||||||
|
pszKey = pValues[i].pszKey;
|
||||||
|
|
||||||
|
switch (dwType)
|
||||||
|
{
|
||||||
|
case REG_SZ:
|
||||||
|
GetRegsz(hCurrentKey, pszKey, &pValues[i].pvValue,
|
||||||
|
&pValues[i].dwLength);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REG_DWORD:
|
||||||
|
GetRegdw(hCurrentKey, pszKey, &pValues[i].pvValue,
|
||||||
|
&pValues[i].dwLength);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REG_EXPAND_SZ:
|
||||||
|
GetRegesz(hCurrentKey, pszKey, &pValues[i].pvValue,
|
||||||
|
&pValues[i].dwLength);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REG_MULTI_SZ:
|
||||||
|
GetRegmsz(hCurrentKey, pszKey, &pValues[i].pvValue,
|
||||||
|
&pValues[i].dwLength);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REG_BINARY:
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get a REG_SZ value and stick it in the table entry, along with the
|
||||||
|
// length
|
||||||
|
//
|
||||||
|
|
||||||
|
BOOL GetRegsz(__in HKEY hKey, __in LPTSTR pszKey, __deref_out_bcount(*pdwLength) PVOID * ppvValue, __out DWORD *pdwLength)
|
||||||
|
{
|
||||||
|
BYTE achValue[1024];
|
||||||
|
|
||||||
|
DWORD dwLength;
|
||||||
|
LONG Status;
|
||||||
|
DWORD dwType = REG_SZ;
|
||||||
|
PBYTE pszValue = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if ( (NULL == pszKey) || (NULL == ppvValue) ||
|
||||||
|
(NULL == hKey) || (NULL == pdwLength))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
FillMemory(achValue, sizeof(achValue), 0xcd);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
dwLength = sizeof(achValue);
|
||||||
|
|
||||||
|
|
||||||
|
Status = RegGetValue( hKey,
|
||||||
|
NULL,
|
||||||
|
pszKey,
|
||||||
|
0x0000002, //RRF_RD_REG_SZ
|
||||||
|
&dwType,
|
||||||
|
(PVOID) &achValue[0],
|
||||||
|
&dwLength);
|
||||||
|
|
||||||
|
if ((ERROR_SUCCESS != Status) || (REG_SZ != dwType) )
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
pszValue = malloc(dwLength);
|
||||||
|
|
||||||
|
if (NULL == pszValue)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CopyMemory(pszValue, achValue, dwLength);
|
||||||
|
|
||||||
|
*ppvValue = pszValue;
|
||||||
|
*pdwLength = dwLength;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get the value of a REG_EXPAND_SZ and its length
|
||||||
|
//
|
||||||
|
|
||||||
|
BOOL GetRegesz(__in HKEY hKey, __in LPTSTR pszKey, __deref_out_bcount(*pdwLength) PVOID * ppvValue, __out DWORD * pdwLength)
|
||||||
|
{
|
||||||
|
BYTE achValue[1024];
|
||||||
|
|
||||||
|
DWORD dwLength;
|
||||||
|
LONG Status;
|
||||||
|
DWORD dwType = REG_EXPAND_SZ;
|
||||||
|
PBYTE pszValue = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
if ( (NULL == pszKey) || (NULL == ppvValue) ||
|
||||||
|
(NULL == hKey) || (NULL == pdwLength))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
FillMemory(achValue, sizeof(achValue), 0xcd);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
dwLength = sizeof(achValue);
|
||||||
|
|
||||||
|
Status = RegQueryValueEx( hKey,
|
||||||
|
pszKey,
|
||||||
|
NULL,
|
||||||
|
&dwType,
|
||||||
|
(PUCHAR) &achValue[0],
|
||||||
|
&dwLength);
|
||||||
|
|
||||||
|
if ((ERROR_SUCCESS != Status) || (REG_EXPAND_SZ != dwType))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
pszValue = malloc(dwLength);
|
||||||
|
|
||||||
|
if (NULL == pszValue)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyMemory(pszValue, achValue, dwLength);
|
||||||
|
|
||||||
|
*ppvValue = pszValue;
|
||||||
|
*pdwLength = dwLength;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get value and length of REG_MULTI_SZ
|
||||||
|
//
|
||||||
|
|
||||||
|
BOOL GetRegmsz(__in HKEY hKey, __in LPTSTR pszKey, __deref_out_bcount( *pdwLength) PVOID * ppvValue, __out DWORD * pdwLength)
|
||||||
|
{
|
||||||
|
//BYTE achValue[1024];
|
||||||
|
BYTE achValue[2048]; // careful, some of these strings are quite long
|
||||||
|
|
||||||
|
DWORD dwLength;
|
||||||
|
LONG Status;
|
||||||
|
DWORD dwType = REG_MULTI_SZ;
|
||||||
|
PBYTE pszValue = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
if ( (NULL == pszKey) || (NULL == ppvValue) ||
|
||||||
|
(NULL == hKey) || (NULL == pdwLength))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
FillMemory(achValue, sizeof(achValue), 0xcd);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
dwLength = sizeof(achValue);
|
||||||
|
|
||||||
|
|
||||||
|
Status = RegQueryValueEx( hKey,
|
||||||
|
pszKey,
|
||||||
|
NULL,
|
||||||
|
&dwType,
|
||||||
|
(PUCHAR) &achValue[0],
|
||||||
|
&dwLength);
|
||||||
|
|
||||||
|
if ((ERROR_SUCCESS != Status) || (REG_MULTI_SZ != dwType))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
pszValue = malloc(dwLength);
|
||||||
|
|
||||||
|
if (NULL == pszValue)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
CopyMemory(pszValue, achValue, dwLength);
|
||||||
|
|
||||||
|
*ppvValue = pszValue;
|
||||||
|
*pdwLength = dwLength;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Get value and length of REG_DWORD
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
BOOL GetRegdw(__in HKEY hKey, __in LPTSTR pszKey, __deref_out_bcount(*pdwLength) PVOID * ppvValue, __out DWORD * pdwLength)
|
||||||
|
{
|
||||||
|
DWORD dwValue = 0;
|
||||||
|
|
||||||
|
DWORD dwLength;
|
||||||
|
LONG Status;
|
||||||
|
DWORD dwType = REG_DWORD;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if ( (NULL == pszKey) || (NULL == ppvValue) ||
|
||||||
|
(NULL == hKey) || (NULL == pdwLength) )
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
dwLength = sizeof(dwValue);
|
||||||
|
|
||||||
|
|
||||||
|
Status = RegQueryValueEx( hKey,
|
||||||
|
pszKey,
|
||||||
|
NULL,
|
||||||
|
&dwType,
|
||||||
|
(PUCHAR) &dwValue,
|
||||||
|
&dwLength);
|
||||||
|
|
||||||
|
if ((ERROR_SUCCESS != Status) || (REG_DWORD != dwType))
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ppvValue = (PVOID) (ULONG_PTR) dwValue;
|
||||||
|
*pdwLength = dwLength;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
WriteRegistryKeyValues(
|
||||||
|
HKEY hCurrentKey,
|
||||||
|
DWORD NumberOfValues,
|
||||||
|
PREGENTRY pValues)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
This routine reads a bunch of values associated with a given key.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
hCurrentKey - the key
|
||||||
|
|
||||||
|
NumberOfValues - the number of values
|
||||||
|
|
||||||
|
pValues - the array of values
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
None
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
DWORD i;
|
||||||
|
|
||||||
|
|
||||||
|
for (i = 0; i < NumberOfValues; i++)
|
||||||
|
{
|
||||||
|
DWORD dwType;
|
||||||
|
PVOID pvValue;
|
||||||
|
DWORD dwLength;
|
||||||
|
LPTSTR pszKey;
|
||||||
|
|
||||||
|
pszKey = pValues[i].pszKey;
|
||||||
|
dwType = pValues[i].dwType;
|
||||||
|
dwLength = pValues[i].dwLength;
|
||||||
|
pvValue = pValues[i].pvValue;
|
||||||
|
|
||||||
|
switch (dwType)
|
||||||
|
{
|
||||||
|
case REG_SZ:
|
||||||
|
AddValue(hCurrentKey, pszKey, dwType, dwLength, pvValue);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REG_DWORD:
|
||||||
|
AddValue(hCurrentKey, pszKey, dwType, dwLength, &pvValue);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REG_EXPAND_SZ:
|
||||||
|
AddValue(hCurrentKey, pszKey, dwType, dwLength, pvValue);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REG_MULTI_SZ:
|
||||||
|
AddValue(hCurrentKey, pszKey, dwType, dwLength, pvValue);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case REG_BINARY:
|
||||||
|
//
|
||||||
|
// There are no binary values we need to copy. If we did, we'd
|
||||||
|
// put something here
|
||||||
|
//
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Open a key so we can read the values
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
BOOL OpenKey(
|
||||||
|
__in LPTSTR pszKey,
|
||||||
|
__out PHKEY phKey)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
This routine opens a registry key.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
pszKey - the name of the key relative to HKEY_LOCAL_MACHINE
|
||||||
|
|
||||||
|
phKey - the key handlle
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
TRUE if successful, otherwise FALSE
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
HKEY hNewKey = 0;
|
||||||
|
DWORD Status;
|
||||||
|
|
||||||
|
Status = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
|
||||||
|
pszKey,
|
||||||
|
0,
|
||||||
|
KEY_QUERY_VALUE,
|
||||||
|
&hNewKey);
|
||||||
|
|
||||||
|
if (ERROR_SUCCESS != Status)
|
||||||
|
{
|
||||||
|
*phKey = NULL;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*phKey = hNewKey;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BOOL CreateKey(__in LPTSTR pszKey, __out PHKEY phKey)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
This routine creates a registry key.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
pszKey - the name of the key relative to HKEY_LOCAL_MACHINE
|
||||||
|
|
||||||
|
phKey - the key handlle
|
||||||
|
|
||||||
|
Return Value:
|
||||||
|
|
||||||
|
TRUE if successful, otherwise FALSE
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
LONG Status;
|
||||||
|
DWORD Disposition;
|
||||||
|
|
||||||
|
Status = RegCreateKeyEx( HKEY_LOCAL_MACHINE,
|
||||||
|
pszKey,
|
||||||
|
0,
|
||||||
|
REG_NONE,
|
||||||
|
REG_OPTION_NON_VOLATILE,
|
||||||
|
KEY_ALL_ACCESS,
|
||||||
|
NULL,
|
||||||
|
phKey,
|
||||||
|
&Disposition);
|
||||||
|
|
||||||
|
if ( ERROR_SUCCESS == Status)
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add a value to the registry
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
BOOL AddValue(__in HKEY hKey, __in LPTSTR pszKey, __in DWORD dwType, __in DWORD dwLength, __in PVOID pvValue)
|
||||||
|
{
|
||||||
|
|
||||||
|
BOOL fSuccess = TRUE;
|
||||||
|
LONG Status = ERROR_SUCCESS;
|
||||||
|
|
||||||
|
Status = RegSetValueEx( hKey,
|
||||||
|
pszKey,
|
||||||
|
0,
|
||||||
|
dwType,
|
||||||
|
pvValue,
|
||||||
|
dwLength);
|
||||||
|
|
||||||
|
|
||||||
|
if (Status != ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
fSuccess = FALSE;
|
||||||
|
//RegCloseKey(hKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fSuccess;
|
||||||
|
}
|
||||||
98
install/nfsreginst.h
Normal file
98
install/nfsreginst.h
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
/* Copyright (c) 2010
|
||||||
|
* The Regents of the University of Michigan
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* Permission is granted to use, copy and redistribute this software
|
||||||
|
* for noncommercial education and research purposes, so long as no
|
||||||
|
* fee is charged, and so long as the name of the University of Michigan
|
||||||
|
* is not used in any advertising or publicity pertaining to the use
|
||||||
|
* or distribution of this software without specific, written prior
|
||||||
|
* authorization. Permission to modify or otherwise create derivative
|
||||||
|
* works of this software is not granted.
|
||||||
|
*
|
||||||
|
* This software is provided as is, without representation or warranty
|
||||||
|
* of any kind either express or implied, including without limitation
|
||||||
|
* the implied warranties of merchantability, fitness for a particular
|
||||||
|
* purpose, or noninfringement. The Regents of the University of
|
||||||
|
* Michigan shall not be liable for any damages, including special,
|
||||||
|
* indirect, incidental, or consequential damages, with respect to any
|
||||||
|
* claim arising out of or in connection with the use of the software,
|
||||||
|
* even if it has been or is hereafter advised of the possibility of
|
||||||
|
* such damages.
|
||||||
|
*/
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Copyright (c) 1997 - 1999 Microsoft Corporation
|
||||||
|
|
||||||
|
Module Name:
|
||||||
|
|
||||||
|
srfunc.h
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
|
||||||
|
--*/
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <strsafe.h>
|
||||||
|
|
||||||
|
#include "nfs41_driver.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
LPTSTR pszKey;
|
||||||
|
DWORD dwType;
|
||||||
|
DWORD dwLength;
|
||||||
|
PVOID pvValue;
|
||||||
|
} REGENTRY, *PREGENTRY;
|
||||||
|
|
||||||
|
void
|
||||||
|
ReadRegistryKeyValues(
|
||||||
|
HKEY hKey,
|
||||||
|
DWORD Count,
|
||||||
|
PREGENTRY pValues);
|
||||||
|
|
||||||
|
void
|
||||||
|
WriteRegistryKeyValues(
|
||||||
|
HKEY hKey,
|
||||||
|
DWORD Count,
|
||||||
|
PREGENTRY pValues);
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// routines for manipulating registry key values
|
||||||
|
//
|
||||||
|
|
||||||
|
BOOL GetRegsz(__in HKEY hKey, __in LPTSTR pszKey, __deref_out_bcount(*pdwLength) PVOID * ppvValue, __out DWORD *pdwLength);
|
||||||
|
|
||||||
|
BOOL GetRegesz(__in HKEY hKey, __in LPTSTR pszKey, __deref_out_bcount(*pdwLength) PVOID * ppvValue, __out DWORD * pdwLength);
|
||||||
|
|
||||||
|
BOOL GetRegmsz(__in HKEY hKey, __in LPTSTR pszKey, __deref_out_bcount(*pdwLength) PVOID * ppvValue, __out DWORD * pdwLength);
|
||||||
|
|
||||||
|
BOOL GetRegdw(__in HKEY hKey, __in LPTSTR pszKey, __deref_out_bcount(*pdwLength) PVOID * ppvValue, __out DWORD * pdwLength);
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// routines for manipulating registry keys
|
||||||
|
//
|
||||||
|
|
||||||
|
BOOL OpenKey(
|
||||||
|
__in LPTSTR pszKey,
|
||||||
|
__out PHKEY phKey);
|
||||||
|
|
||||||
|
BOOL CreateKey(__in LPTSTR pszKey, __out PHKEY phKey);
|
||||||
|
BOOL AddValue(__in HKEY hKey, __in LPTSTR pszKey, __in DWORD dwType, __in DWORD dwLength, __in PVOID pvValue);
|
||||||
|
|
||||||
|
BOOL RdrSetupProviderOrder( void );
|
||||||
|
BOOL RdrRemoveProviderFromOrder( void );
|
||||||
|
|
||||||
|
ULONG_PTR RdrGetProviderOrderString( __out LPTSTR *OrderString );
|
||||||
|
BOOL RdrSetProviderOrderString( __in LPTSTR OrderString );
|
||||||
|
|
||||||
|
|
||||||
|
typedef BOOL (*ACTIONVECTOR) ( void );
|
||||||
|
|
||||||
|
#define RDRSERVICE TEXT("nfs41_driver")
|
||||||
|
#define PROVIDER_NAME RDRSERVICE
|
||||||
|
|
||||||
|
#define PROVIDER_ORDER_KEY TEXT("System\\CurrentControlSet\\Control\\NetworkProvider\\Order")
|
||||||
|
|
||||||
15
install/sources
Normal file
15
install/sources
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
TARGETTYPE=PROGRAM
|
||||||
|
TARGETNAME=nfs_install
|
||||||
|
SOURCES=nfs_install.c nfsreginst.c
|
||||||
|
UMTYPE=console
|
||||||
|
USE_MSVCRT=1
|
||||||
|
INCLUDES=..\sys
|
||||||
|
|
||||||
|
!IF 0
|
||||||
|
/W3 is default level
|
||||||
|
bump to /Wall, but suppress warnings generated by system includes,
|
||||||
|
as well as the following warnings:
|
||||||
|
4100 - unused function call arguments (we have lots of stubs)
|
||||||
|
4127 - constant conditional (I like to use if(0) or if(1))
|
||||||
|
!ENDIF
|
||||||
|
MSC_WARNING_LEVEL=/Wall /wd4668 /wd4619 /wd4820 /wd4255 /wd4100 /wd4127 /wd4201 /wd4214
|
||||||
46
libtirpc/.gitignore
vendored
Normal file
46
libtirpc/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
# files generated by autoconf, automake, autoheader and libtoolize
|
||||||
|
aclocal.m4
|
||||||
|
autom4te.cache
|
||||||
|
compile
|
||||||
|
config.guess
|
||||||
|
config.log
|
||||||
|
config.sub
|
||||||
|
configure
|
||||||
|
depcomp
|
||||||
|
install-sh
|
||||||
|
libtool
|
||||||
|
ltmain.sh
|
||||||
|
Makefile.in
|
||||||
|
missing
|
||||||
|
config.h.in
|
||||||
|
# files generated by configure
|
||||||
|
confdefs.h
|
||||||
|
config.status
|
||||||
|
conftest
|
||||||
|
conftest.c
|
||||||
|
conftest.cpp
|
||||||
|
conftest.er1
|
||||||
|
conftest.err
|
||||||
|
.deps
|
||||||
|
Makefile
|
||||||
|
config.h
|
||||||
|
stamp-h1
|
||||||
|
libtirpc.pc
|
||||||
|
# file generated during compilation
|
||||||
|
*.o
|
||||||
|
.libs
|
||||||
|
lib*.a
|
||||||
|
src/libtirpc.la
|
||||||
|
src/libtirpc_la-*.lo
|
||||||
|
# generic editor backup et al
|
||||||
|
*~
|
||||||
|
# cscope database files
|
||||||
|
cscope.*
|
||||||
|
# files generated by patches
|
||||||
|
*.patch
|
||||||
|
*.rej
|
||||||
|
*.orig
|
||||||
|
# files generated by debugging
|
||||||
|
.gdb_history
|
||||||
|
.gdbinit
|
||||||
|
core
|
||||||
3
libtirpc/AUTHORS
Normal file
3
libtirpc/AUTHORS
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
Gilles Quillard <gilles.quillard@bull.net>
|
||||||
|
Antoine Fraticelli <antoine.fraticelli@bull.net>
|
||||||
|
|
||||||
359
libtirpc/COPYING
Normal file
359
libtirpc/COPYING
Normal file
|
|
@ -0,0 +1,359 @@
|
||||||
|
Sun Industry Standards Source License 1.0
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
|
||||||
|
1.1. "Commercial Use" means distribution or otherwise
|
||||||
|
making the Original Code available to a third party.
|
||||||
|
|
||||||
|
1.2. "Contributor Version" means the combination of the
|
||||||
|
Original Code, and the Modifications made by that particular
|
||||||
|
Contributor.
|
||||||
|
|
||||||
|
1.3. "Electronic Distribution Mechanism" means a mechanism
|
||||||
|
generally accepted in the software development community for
|
||||||
|
the electronic transfer of data.
|
||||||
|
|
||||||
|
1.4. "Executable" means Original Code in any form other
|
||||||
|
than Source Code.
|
||||||
|
|
||||||
|
1.5. "Initial Developer" means the individual or entity
|
||||||
|
identified as the Initial Developer in the Source Code
|
||||||
|
notice required by 2 (Exhibit A)
|
||||||
|
|
||||||
|
1.6. "Larger Work" means a work which combines Original
|
||||||
|
Code or portions thereof with code not governed by the terms
|
||||||
|
of this License.
|
||||||
|
|
||||||
|
1.7. "License" means this document.
|
||||||
|
|
||||||
|
1.8. "Licensable" means having the right to grant, to the
|
||||||
|
maximum extent possible, whether at the time of the initial
|
||||||
|
grant or subsequently acquired, any and all of the rights
|
||||||
|
conveyed herein.
|
||||||
|
|
||||||
|
1.9. "Modifications" means any addition to or deletion from
|
||||||
|
the substance or structure of either the Original Code or
|
||||||
|
any previous Modifications. A Modification is:
|
||||||
|
|
||||||
|
A. Any addition to or deletion from the contents of a file
|
||||||
|
containing Original Code or previous Modifications.
|
||||||
|
|
||||||
|
B. Any new file that contains any part of the Original Code
|
||||||
|
or previous Modifications. .
|
||||||
|
|
||||||
|
1.10. "Original Code" means Source Code of computer
|
||||||
|
software code which is described in the Source Code notice
|
||||||
|
required by Exhibit A as Original Code.
|
||||||
|
|
||||||
|
1.11. "Patent Claims" means any patent claims, now owned or
|
||||||
|
hereafter acquired, including without limitation, method,
|
||||||
|
process, and apparatus claims, in any patent Licensable by
|
||||||
|
grantor.
|
||||||
|
|
||||||
|
1.12. "Source Code" means the preferred form of the
|
||||||
|
Original Code for making modifications to it, including all
|
||||||
|
modules it contains, plus any associated interface
|
||||||
|
definition files, or scripts used to control compilation and
|
||||||
|
installation of an Executable.
|
||||||
|
|
||||||
|
1.13. "Standards" means the standard identified in Exhibit
|
||||||
|
B or a subsequent version of such standard.
|
||||||
|
|
||||||
|
1.14. "You" or "Your" means an individual or a legal entity
|
||||||
|
exercising rights under, and complying with all of the terms
|
||||||
|
of, this License or a future version of this License issued
|
||||||
|
under Section 6.1. For legal entities, "You" includes any
|
||||||
|
entity which controls, is controlled by, or is under common
|
||||||
|
control with You. For purposes of this definition,
|
||||||
|
"control" means (a) the power, direct or indirect, to cause
|
||||||
|
the direction or management of such entity, whether by
|
||||||
|
contract or otherwise, or (b) ownership of more than fifty
|
||||||
|
percent (50%) of the outstanding shares or beneficial
|
||||||
|
ownership of such entity.
|
||||||
|
|
||||||
|
2.0 SOURCE CODE LICENSE
|
||||||
|
|
||||||
|
2.1 The Initial Developer Grant: The Initial Developer
|
||||||
|
hereby grants You a world-wide, royalty-free, non-exclusive
|
||||||
|
license, subject to third party intellectual property
|
||||||
|
claims:
|
||||||
|
|
||||||
|
a) under intellectual property rights (other than patent or
|
||||||
|
trademark) Licensable by Initial Developer to use,
|
||||||
|
reproduce, modify, display, perform, sub license and
|
||||||
|
distribute the Original Code (or portions thereof )with or
|
||||||
|
without Modifications, and/or as part of a Larger Work; and
|
||||||
|
|
||||||
|
b) under Patents Claims infringed by the making, using or
|
||||||
|
selling of Original Code, to make, have made, use, practice,
|
||||||
|
sell, and offer for sale, and/or otherwise dispose of the
|
||||||
|
Original Code (or portions thereof).
|
||||||
|
|
||||||
|
c) the licenses granted in this Section 2.1(a ) and (b) are
|
||||||
|
effective on the date Initial Developer first distributes
|
||||||
|
Original Code under the terms of this License.
|
||||||
|
|
||||||
|
d) Notwithstanding Section 2.1(b )above, no patent license
|
||||||
|
is granted: 1) for code that You delete from the Original
|
||||||
|
Code; 2) separate from the Original Code; or 3) for
|
||||||
|
infringements caused by: i) the modification of the
|
||||||
|
Original Code or
|
||||||
|
|
||||||
|
ii) the combination of the Original Code with other software
|
||||||
|
or devices, including but not limited to Modifications.
|
||||||
|
|
||||||
|
3.0 DISTRIBUTION OBLIGATIONS
|
||||||
|
|
||||||
|
3.1 Application of License. The Source Code version of
|
||||||
|
Original Code may be distributed only under the terms of
|
||||||
|
this License or a future version of this License released
|
||||||
|
under Section 6.1, and You must include a copy of this
|
||||||
|
License with every copy of the Source Code You distribute.
|
||||||
|
You may not offer or impose any terms on any Source Code
|
||||||
|
version that alters or restricts the applicable version of
|
||||||
|
this License or the recipient's rights hereunder. Your
|
||||||
|
license for shipment of the Contributor Version is
|
||||||
|
conditioned upon your full compliance with this Section.
|
||||||
|
The Modifications which you create must comply with all
|
||||||
|
requirements set out by the Standards body in effect 120
|
||||||
|
days before You ship the Contributor Version. In the event
|
||||||
|
that the Modifications do not meet such requirements, You
|
||||||
|
agree to publish (i) any deviation from the Standards
|
||||||
|
protocol resulting from implementation of your Modifications
|
||||||
|
and (ii) a reference implementation of Your Modifications,
|
||||||
|
and to make any such deviation and reference implementation
|
||||||
|
available to all third parties under the same terms as the
|
||||||
|
license on a royalty free basis within thirty (30) days of
|
||||||
|
Your first customer shipment of Your Modifications.
|
||||||
|
|
||||||
|
3.2 Required Notices. You must duplicate the notice in
|
||||||
|
Exhibit A in each file of the Source Code. If it is not
|
||||||
|
possible to put such notice in a particular Source Code file
|
||||||
|
due to its structure, then You must include such notice in a
|
||||||
|
location (such as a relevant directory ) where a user would
|
||||||
|
be likely to look for such a notice. If You created one or
|
||||||
|
more Modifications ) You may add your name as a Contributor
|
||||||
|
to the notice described in Exhibit A. You must also
|
||||||
|
duplicate this License in any documentation for the Source
|
||||||
|
Code where You describe recipients' rights or ownership
|
||||||
|
rights relating to Initial Code. You may choose to offer,
|
||||||
|
and to charge a fee for, warranty, support, indemnity or
|
||||||
|
liability obligations to one or more recipients of Your
|
||||||
|
version of the Code. However, You may do so only
|
||||||
|
|
||||||
|
on Your own behalf, and not on behalf of the Initial
|
||||||
|
Developer. You must make it absolutely clear than any such
|
||||||
|
warranty, support, indemnity or liability obligation is
|
||||||
|
offered by You alone, and You hereby agree to indemnify the
|
||||||
|
Initial Developer for any liability incurred by the Initial
|
||||||
|
Developer as a result of warranty, support, indemnity or
|
||||||
|
liability terms You offer.
|
||||||
|
|
||||||
|
3.3 Distribution of Executable Versions. You may distribute
|
||||||
|
Original Code in Executable and Source form only if the
|
||||||
|
requirements of Section 3.1 and 3.2 have been met for that
|
||||||
|
Original Code, and if You include a notice stating that the
|
||||||
|
Source Code version of the Original Code is available under
|
||||||
|
the terms of this License. The notice must be conspicuously
|
||||||
|
included in any notice in an Executable or Source versions,
|
||||||
|
related documentation or collateral in which You describe
|
||||||
|
recipients' rights relating to the Original Code. You may
|
||||||
|
distribute the Executable and Source versions of Your
|
||||||
|
version of the Code or ownership rights under a license of
|
||||||
|
Your choice, which may contain terms different from this
|
||||||
|
License, provided that You are in compliance with the terms
|
||||||
|
of this License. If You distribute the Executable and
|
||||||
|
Source versions under a different license You must make it
|
||||||
|
absolutely clear that any terms which differ from this
|
||||||
|
License are offered by You alone, not by the Initial
|
||||||
|
Developer . You hereby agree to indemnify the Initial
|
||||||
|
Developer for any liability incurred by the Initial
|
||||||
|
Developer as a result of any such terms You offer .
|
||||||
|
|
||||||
|
3.4 Larger Works. You may create a Larger Work by combining
|
||||||
|
Original Code with other code not governed by the terms of
|
||||||
|
this License and distribute the Larger Work as a single
|
||||||
|
product. In such a case, You must make sure the
|
||||||
|
requirements of this License are fulfilled for the Original
|
||||||
|
Code.
|
||||||
|
|
||||||
|
4.0 INABILITY TO COMPLY DUE TO STATUTE OR REGULATION
|
||||||
|
|
||||||
|
If it is impossible for You to comply with any of the terms
|
||||||
|
of this License with respect to some or all of the Original
|
||||||
|
Code due to statute, judicial order, or regulation then You
|
||||||
|
must:
|
||||||
|
|
||||||
|
a) comply with the terms of this License to the maximum
|
||||||
|
extent possible; and
|
||||||
|
|
||||||
|
b) describe the limitations and the code they affect. Such
|
||||||
|
description must be included in the LEGAL file described in
|
||||||
|
Section 3.2 and must be included with all distributions of
|
||||||
|
the Source Code. Except to the extent prohibited by statute
|
||||||
|
or regulation, such description must be sufficiently
|
||||||
|
detailed for a recipient of ordinary skill to be able to
|
||||||
|
understand it.
|
||||||
|
|
||||||
|
5.0 APPLICATION OF THIS LICENSE This License applies to code
|
||||||
|
to which the Initial Developer has attached the notice in
|
||||||
|
Exhibit A and to related Modifications as set out in Section
|
||||||
|
3.1.
|
||||||
|
|
||||||
|
6.0 VERSIONS OF THE LICENSE
|
||||||
|
|
||||||
|
6.1 New Versions. Sun Microsystems, Inc. Sun may publish
|
||||||
|
revised and/or new versions of the License from time to
|
||||||
|
time. Each version will be given a distinguishing version
|
||||||
|
number .
|
||||||
|
|
||||||
|
6.2 Effect of New Versions. Once Original Code has been
|
||||||
|
published under a particular version of the License, You may
|
||||||
|
always continue to use it under the terms of that version.
|
||||||
|
You may also choose to use such Original Code under the
|
||||||
|
terms of any subsequent version of the License published by
|
||||||
|
Sun. No one other than Sun has the right to modify the
|
||||||
|
terms applicable to Original Code.
|
||||||
|
|
||||||
|
7. DISCLAIMER OF W ARRANTY. ORIGINAL CODE IS PROVIDED
|
||||||
|
UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY OF
|
||||||
|
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT
|
||||||
|
LIMITATION, WARRANTIES THAT THE ORIGINAL CODE IS FREE OF
|
||||||
|
DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR
|
||||||
|
NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND
|
||||||
|
PERFORMANCE OF THE ORIGINAL CODE IS WITH YOU. SHOULD ANY
|
||||||
|
ORIGINAL CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE
|
||||||
|
INITIAL DEVELOPER )ASSUME THE COST OF ANY NECESSARY
|
||||||
|
SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF
|
||||||
|
WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO
|
||||||
|
USE OF ANY ORIGINAL CODE IS AUTHORIZED HEREUNDER EXCEPT
|
||||||
|
UNDER THIS DISCLAIMER.
|
||||||
|
|
||||||
|
8.0 TERMINATION
|
||||||
|
|
||||||
|
8.1 This License and the rights granted hereunder will
|
||||||
|
terminate automatically if You fail to comply with terms
|
||||||
|
herein and fail to cure such breach within 30 days of
|
||||||
|
becoming aware of the breach. All sublicenses to the
|
||||||
|
Original Code which are properly granted shall survive any
|
||||||
|
termination of this License. Provisions which, by their
|
||||||
|
nature, must remain in effect beyond the termination of this
|
||||||
|
License shall survive.
|
||||||
|
|
||||||
|
8.2 .In the event of termination under Section 8.1 above,
|
||||||
|
all end user license agreements (excluding distributors and
|
||||||
|
resellers) which have been validly granted by You or any
|
||||||
|
distributor hereunder prior to termination shall survive
|
||||||
|
termination.
|
||||||
|
|
||||||
|
9.0 LIMIT OF LIABILITY UNDER NO CIRCUMSTANCES AND UNDER NO
|
||||||
|
LEGAL THEORY, WHETHER TORT (INCLUDING NEGLIGENCE) ,CONTRACT,
|
||||||
|
OR OTHER WISE, SHALL YOU, THE INITIAL DEVELOPER, ANY OTHER
|
||||||
|
CONTRIBUTOR, OR ANY DISTRIBUTOR OF ORIGINAL CODE, OR ANY
|
||||||
|
SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
|
||||||
|
ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||||
|
OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR
|
||||||
|
LOSS OF GOOD WILL, WORK STOPPAGE, COMPUTER FAILURE OR
|
||||||
|
MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR
|
||||||
|
LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY
|
||||||
|
SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
|
||||||
|
RESULTING FROM SUCH PARTYS NEGLIGENCE TO THE EXTENT
|
||||||
|
APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME
|
||||||
|
JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF
|
||||||
|
INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND
|
||||||
|
LIMITATION MAY NOT APPLY TO YOU.
|
||||||
|
|
||||||
|
10.0 U .S. GOVERNMENT END USERS U.S. Government: If this
|
||||||
|
Software is being acquired by or on behalf of the U.S.
|
||||||
|
Government or by a U.S. Government prime contractor or
|
||||||
|
subcontractor (at any tier), then the Government's rights in
|
||||||
|
the Software and accompanying documentation shall be only as
|
||||||
|
set forth in this license; this is in accordance with 48 C.F
|
||||||
|
.R. 227.7201 through 227.7202-4 (for Department of Defense
|
||||||
|
(DoD) acquisitions )and with 48 C.F.R.2.101 and 12.212( for
|
||||||
|
non-DoD acquisitions).
|
||||||
|
|
||||||
|
11.0 MISCELLANEOUS This License represents the complete
|
||||||
|
agreement concerning subject matter hereof. If any
|
||||||
|
provision of this License is held to be unenforceable, such
|
||||||
|
provision shall be reformed only to the extent necessary to
|
||||||
|
make it enforceable. This License shall be governed by
|
||||||
|
California law provisions (except to the extent applicable
|
||||||
|
law, if any, provides otherwise), excluding its
|
||||||
|
conflict-of-law provisions. With respect to disputes in
|
||||||
|
which at least one party is a citizen of, or an entity
|
||||||
|
chartered or registered to do business in the United States
|
||||||
|
of America, any litigation relating to this License shall be
|
||||||
|
subject to the jurisdiction of the Federal Courts of the
|
||||||
|
Northern District of California, with venue lying in Santa
|
||||||
|
Clara County, California, with the losing party responsible
|
||||||
|
for costs, including without limitation, court costs and
|
||||||
|
reasonable attorneys fees and expenses. The application of
|
||||||
|
the United Nations Convention on Contracts for the
|
||||||
|
International Sale of Goods is expressly excluded. Any law
|
||||||
|
or regulation which provides that the language of a contract
|
||||||
|
shall be construed against the drafter shall not apply to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
EXHIBIT A - Sun Standards
|
||||||
|
|
||||||
|
"The contents of this file are subject to the Sun Standards
|
||||||
|
License Version 1.0 the (the "License";) You may not use
|
||||||
|
this file except in compliance with the License. You may
|
||||||
|
obtain a copy of the License at
|
||||||
|
_______________________________.
|
||||||
|
|
||||||
|
Software distributed under the License is distributed on
|
||||||
|
an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
|
||||||
|
express or implied. See the License for the specific
|
||||||
|
language governing rights and limitations under the License.
|
||||||
|
|
||||||
|
The Original Code is Copyright 1998 by Sun Microsystems, Inc
|
||||||
|
|
||||||
|
The Initial Developer of the Original Code is: Sun
|
||||||
|
Microsystems, Inc.
|
||||||
|
|
||||||
|
Portions created by _____________________________ are
|
||||||
|
Copyright ______________________________.
|
||||||
|
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
Contributors: ______________________________________.
|
||||||
|
|
||||||
|
EXHIBIT B - Sun Standards
|
||||||
|
|
||||||
|
The Standard is defined as the following IETF RFCs:
|
||||||
|
|
||||||
|
RFC1831: RPC: Remote Procedure Call Protocol Specification
|
||||||
|
Version 2 RFC1832: XDR: External Data REpresentation
|
||||||
|
Standard RFC1833: Binding Protocols for ONC RPC Version 2
|
||||||
|
RFC2078: Generic Security Service Application Program
|
||||||
|
Interface, Version 2 RFC2203: RPCSEC_GSS Protocol
|
||||||
|
Specification RFC2695: Authentication Mechanisms for ONC RPC
|
||||||
|
|
||||||
|
*
|
||||||
|
* Copyright (c) Copyright (c) Bull S.A. 2005 All Rights Reserved.
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
206
libtirpc/ChangeLog
Normal file
206
libtirpc/ChangeLog
Normal file
|
|
@ -0,0 +1,206 @@
|
||||||
|
2008-11-19 Steve Dickson <steved@redhat.com>
|
||||||
|
|
||||||
|
* Version 0.1.10 released.
|
||||||
|
|
||||||
|
commit 32ec5931e3debf208972d5146578f08dc113a9b6
|
||||||
|
Merge: 338af7f... 92cf0dd...
|
||||||
|
Author: Steve Dickson <steved@redhat.com>
|
||||||
|
Date: Mon Nov 17 12:26:22 2008 -0500
|
||||||
|
|
||||||
|
Merge branch 'master' of git://git.infradead.org/~steved/libtirpc
|
||||||
|
|
||||||
|
commit 92cf0dde310ca341a2f29ff66b19eeb9994a649a
|
||||||
|
Author: Ian Kent <ikent@redhat.com>
|
||||||
|
Date: Tue Oct 28 11:19:07 2008 -0400
|
||||||
|
|
||||||
|
Fixed a warings the IPV6 client routines
|
||||||
|
|
||||||
|
Signed-off-by: Steve Dickson <steved@redhat.com>
|
||||||
|
|
||||||
|
commit 338af7f9f00e096b65a6d823f885c4eeaf1d1f8c
|
||||||
|
Author: Steve Dickson <steved@redhat.com>
|
||||||
|
Date: Mon Oct 27 12:46:54 2008 -0400
|
||||||
|
|
||||||
|
__rpc_taddr2uaddr_af() assumes the netbuf to always have a
|
||||||
|
non-zero data. This is a bad assumption and can lead to a
|
||||||
|
seg-fault. This patch adds a check for zero length and returns
|
||||||
|
NULL when found.
|
||||||
|
|
||||||
|
Signed-off-by: Steve Dickson <steved@redhat.com>
|
||||||
|
|
||||||
|
commit d9a5ae7079d001a9e3b9b384f9153f591a7158bd
|
||||||
|
Author: Olaf Kirch <okir@suse.de>
|
||||||
|
Date: Tue Sep 30 15:10:43 2008 -0400
|
||||||
|
|
||||||
|
Fix __rpc_getconfip
|
||||||
|
|
||||||
|
__rpc_getconfip is supposed to return the first netconf
|
||||||
|
entry supporting tcp or udp, respectively. The code will
|
||||||
|
currently return the *last* entry, plus it will leak
|
||||||
|
memory when there is more than one such entry.
|
||||||
|
|
||||||
|
This patch fixes this issue.
|
||||||
|
|
||||||
|
Signed-off-by: Olaf Kirch <okir@suse.de>
|
||||||
|
Signed-off-by: Steve Dickson <steved@redhat.com>
|
||||||
|
|
||||||
|
commit 6c487efe74adb5c29f7bee5bd51b3ebef4968f7d
|
||||||
|
Author: Olaf Kirch <okir@suse.de>
|
||||||
|
Date: Tue Sep 30 15:09:06 2008 -0400
|
||||||
|
|
||||||
|
Fix getpeereid
|
||||||
|
|
||||||
|
getpeereid fails because it uses an incorrect getsockopt call to obtain
|
||||||
|
the peer credentials on a AF_LOCAL socket. This in turn will cause all
|
||||||
|
RPC services to be registered with rpcbind to show up as having been
|
||||||
|
registered by "unknown".
|
||||||
|
|
||||||
|
This has a serious impact on security - a service owned by "unknown"
|
||||||
|
can essentially be unregistered (and thus replaced) by anyone.
|
||||||
|
|
||||||
|
Signed-off-by: Olaf Kirch <okir@suse.de>
|
||||||
|
Signed-off-by: Steve Dickson <steved@redhat.com>
|
||||||
|
|
||||||
|
commit 851b0f5c6dca22d634603f03f0a5e3e35c6db867
|
||||||
|
Author: Olaf Kirch <okir@suse.de>
|
||||||
|
Date: Tue Sep 30 15:08:07 2008 -0400
|
||||||
|
|
||||||
|
svc_getcaller_netbuf macro seems broken
|
||||||
|
|
||||||
|
I haven't found any documentation, but the comment in the header
|
||||||
|
file seems to suggest that svc_getcaller_netbuf should return the
|
||||||
|
xp_rtaddr netbuf. Returning the address of the socket descripor
|
||||||
|
seems to be wrong at any rate.
|
||||||
|
|
||||||
|
Signed-off-by: Olaf Kirch <okir@suse.de>
|
||||||
|
Signed-off-by: Steve Dickson <steved@redhat.com>
|
||||||
|
|
||||||
|
commit d94b92d5125242ce595c1baf42a1e6d1004b7756
|
||||||
|
Author: Olaf Kirch <okir@suse.de>
|
||||||
|
Date: Tue Sep 30 15:06:54 2008 -0400
|
||||||
|
|
||||||
|
Introduce __rpc_set_netbuf helper
|
||||||
|
|
||||||
|
The RPC code contains a number of places where a netbuf
|
||||||
|
is initialized with some data. All the mem_alloc/memcpy
|
||||||
|
stuff is open-coded. Introduce a helper function and
|
||||||
|
convert the code.
|
||||||
|
|
||||||
|
Signed-off-by: Olaf Kirch <okir@suse.de>
|
||||||
|
Signed-off-by: Steve Dickson <steved@redhat.com>
|
||||||
|
|
||||||
|
commit da5f9861ea3bae59c8eead26d38334721caa9f0a
|
||||||
|
Author: Olaf Kirch <okir@suse.de>
|
||||||
|
Date: Tue Sep 30 15:05:20 2008 -0400
|
||||||
|
|
||||||
|
Kill map_ipv4_to_ipv6
|
||||||
|
|
||||||
|
After the change to svc_vc.c performed in the previous patch,
|
||||||
|
this function is no longer needed.
|
||||||
|
|
||||||
|
Signed-off-by: Olaf Kirch <okir@suse.de>
|
||||||
|
Signed-off-by: Steve Dickson <steved@redhat.com>
|
||||||
|
|
||||||
|
commit 59c374c4b507aeca957ed0096d98006edf601375
|
||||||
|
Author: Olaf Kirch <okir@suse.de>
|
||||||
|
Date: Tue Sep 30 15:04:17 2008 -0400
|
||||||
|
|
||||||
|
Fix xp_raddr handling in svc_fd_create etc
|
||||||
|
|
||||||
|
Currently svc_fd_create tries to do some clever tricks
|
||||||
|
with IPv4/v6 address mapping.
|
||||||
|
|
||||||
|
This is broken for several reasons.
|
||||||
|
1. We don't want IPv4 based transport to look like IPv6
|
||||||
|
transports. Old applications compiled against tirpc
|
||||||
|
will expect AF_INET addresses, and are not equipped
|
||||||
|
to deal with AF_INET6.
|
||||||
|
2. There's a buffer overflow.
|
||||||
|
memcpy(&sin6, &ss, sizeof(ss));
|
||||||
|
copies a full struct sockaddr to a sockaddr_in6 on
|
||||||
|
the stack. Unlikely to be exploitable, but I wonder
|
||||||
|
if this ever worked....
|
||||||
|
|
||||||
|
Signed-off-by: Olaf Kirch <okir@suse.de>
|
||||||
|
Signed-off-by: Steve Dickson <steved@redhat.com>
|
||||||
|
|
||||||
|
commit 628788c1cc84c86ee4cb36ee5d4fe8954e90fca5
|
||||||
|
Author: Steve Dickson <steved@redhat.com>
|
||||||
|
Date: Tue Sep 16 11:32:31 2008 -0400
|
||||||
|
|
||||||
|
- Fixed version-info in src/Makefile.am to reflect the correct version
|
||||||
|
- Fixed some of warnings in: src/auth_time.c, src/clnt_dg.c and
|
||||||
|
src/clnt_raw.c
|
||||||
|
- Added some #ifdef NOTUSED around some code in src/rpbc_clnt.c
|
||||||
|
that was not being used...
|
||||||
|
|
||||||
|
Signed-off-by: Steve Dickson <steved@redhat.com>
|
||||||
|
|
||||||
|
commit 9e7ba0c7a02031294fefadfbca42b3dd5f2d841f
|
||||||
|
Author: Olaf Kirch <okir@suse.de>
|
||||||
|
Date: Tue Sep 16 08:46:29 2008 -0400
|
||||||
|
|
||||||
|
Fix for taddr2addr conversion bug of local addresses
|
||||||
|
|
||||||
|
When converting af_local socket addresses in taddr2uaddr, an incorrect
|
||||||
|
sizeof() would result in a truncated path string. As a result,
|
||||||
|
rpcbind will report the local /var/lib/rpcbind address to clients
|
||||||
|
as "/v" on a 32bit machine.
|
||||||
|
|
||||||
|
Signed-off-by: okir@suse.de
|
||||||
|
Signed-off-by: Steve Dickson <steved@redhat.com>
|
||||||
|
|
||||||
|
commit ea9f048761d0b9a2ab6310bffa07351f0b04d8c5
|
||||||
|
Author: Olaf Kirch <okir@suse.de>
|
||||||
|
Date: Tue Sep 2 12:11:15 2008 -0400
|
||||||
|
|
||||||
|
Always make IPv6 sockets V6ONLY
|
||||||
|
|
||||||
|
Assume you have a netconfig file looking like this:
|
||||||
|
|
||||||
|
udp tpi_clts v inet udp - -
|
||||||
|
udp6 tpi_clts v inet6 udp - -
|
||||||
|
...
|
||||||
|
|
||||||
|
a call to svc_tli_create(... &someaddr, "udp") will fail to create an
|
||||||
|
IPv6 server socket. The problem is that on Linux, passive IPv6 sockets
|
||||||
|
will also accept packets/connections from IPv4, and will simply map
|
||||||
|
the sender's address to an IPv6 mapped IPv4 address. So if you want to
|
||||||
|
bind both a UDPv4 and UDPv6 socket to the same port, this will fail with
|
||||||
|
EADDRINUSE.
|
||||||
|
|
||||||
|
The way to avoid this behavior is to change the socket to V6ONLY,
|
||||||
|
which tells the kernel to avoid the autmatic mapping.
|
||||||
|
|
||||||
|
The change proposed in the patch below does this. I *think* this is
|
||||||
|
a good place to do this, as it will also fix applications that do not
|
||||||
|
use svc_tli_create() - such as rpcbind, which creates the sockets on
|
||||||
|
its own using __rpc_nconf2fd.
|
||||||
|
|
||||||
|
I think this also improves portability, as BSD code assumes BSD
|
||||||
|
behavior, where this mapping does not occur either.
|
||||||
|
|
||||||
|
Signed-off-by: Olaf Kirch <okir@suse.de>
|
||||||
|
Signed-off-by: Steve Dickson <steved@redhat.com>
|
||||||
|
|
||||||
|
commit 95c8f7227e6b15f2e430d7b87dadc95b2acd4a61
|
||||||
|
Author: Olaf Kirch <okir@suse.de>
|
||||||
|
Date: Tue Sep 2 12:09:39 2008 -0400
|
||||||
|
|
||||||
|
Fix incorrect sizeof() in __rpc_getbroadifs
|
||||||
|
|
||||||
|
__rpc_getbroadifs returns bad broadcast addresses on 32bit
|
||||||
|
machines because when copying the broadcast addresses, ite
|
||||||
|
applies the sizeof() operator to a pointer to a sockaddr,
|
||||||
|
rather than the sockaddr itself.
|
||||||
|
|
||||||
|
Signed-off-by: Olaf Kirch <okir@suse.de>
|
||||||
|
Signed-off-by: Steve Dickson <steved@redhat.com>
|
||||||
|
|
||||||
|
2004-10-13 Antoine Fraticelli <antoine.fraticellie@bull.net>
|
||||||
|
|
||||||
|
* Version 0.1 released.
|
||||||
|
|
||||||
|
2005-01-07 Gilles Quillard <Gilles.Quillard@bull.net>
|
||||||
|
|
||||||
|
* Version 0.1.5 Fix problems links to the use of Kerberos.
|
||||||
251
libtirpc/INSTALL
Normal file
251
libtirpc/INSTALL
Normal file
|
|
@ -0,0 +1,251 @@
|
||||||
|
Copyright 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
|
||||||
|
Foundation, Inc.
|
||||||
|
|
||||||
|
This file is free documentation; the Free Software Foundation gives
|
||||||
|
unlimited permission to copy, distribute and modify it.
|
||||||
|
|
||||||
|
|
||||||
|
TI-RPC Library Quick Installation
|
||||||
|
=================================
|
||||||
|
|
||||||
|
Without GSS API
|
||||||
|
|
||||||
|
$ ./configure
|
||||||
|
$ make
|
||||||
|
# make install
|
||||||
|
|
||||||
|
To enable utilization of RPCSEC via GSS API use following commands
|
||||||
|
but you need to install libgssapi from the CITI before
|
||||||
|
|
||||||
|
$ ./configure --enable-gss
|
||||||
|
$ make
|
||||||
|
# make install
|
||||||
|
|
||||||
|
Once installed, you can customize the /etc/netconfig configuration file
|
||||||
|
to configure the supported protocols. To support INET6 udp/tcp, uncomment
|
||||||
|
the udp6/tcp6 lines.
|
||||||
|
|
||||||
|
|
||||||
|
Basic Installation
|
||||||
|
==================
|
||||||
|
|
||||||
|
These are generic installation instructions.
|
||||||
|
|
||||||
|
The `configure' shell script attempts to guess correct values for
|
||||||
|
various system-dependent variables used during compilation. It uses
|
||||||
|
those values to create a `Makefile' in each directory of the package.
|
||||||
|
It may also create one or more `.h' files containing system-dependent
|
||||||
|
definitions. Finally, it creates a shell script `config.status' that
|
||||||
|
you can run in the future to recreate the current configuration, and a
|
||||||
|
file `config.log' containing compiler output (useful mainly for
|
||||||
|
debugging `configure').
|
||||||
|
|
||||||
|
It can also use an optional file (typically called `config.cache'
|
||||||
|
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
||||||
|
the results of its tests to speed up reconfiguring. (Caching is
|
||||||
|
disabled by default to prevent problems with accidental use of stale
|
||||||
|
cache files.)
|
||||||
|
|
||||||
|
If you need to do unusual things to compile the package, please try
|
||||||
|
to figure out how `configure' could check whether to do them, and mail
|
||||||
|
diffs or instructions to the address given in the `README' so they can
|
||||||
|
be considered for the next release. If you are using the cache, and at
|
||||||
|
some point `config.cache' contains results you don't want to keep, you
|
||||||
|
may remove or edit it.
|
||||||
|
|
||||||
|
The file `configure.ac' (or `configure.in') is used to create
|
||||||
|
`configure' by a program called `autoconf'. You only need
|
||||||
|
`configure.ac' if you want to change it or regenerate `configure' using
|
||||||
|
a newer version of `autoconf'.
|
||||||
|
|
||||||
|
The simplest way to compile this package is:
|
||||||
|
|
||||||
|
1. `cd' to the directory containing the package's source code and type
|
||||||
|
`./configure' to configure the package for your system. If you're
|
||||||
|
using `csh' on an old version of System V, you might need to type
|
||||||
|
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||||
|
`configure' itself.
|
||||||
|
|
||||||
|
Running `configure' takes awhile. While running, it prints some
|
||||||
|
messages telling which features it is checking for.
|
||||||
|
|
||||||
|
2. Type `make' to compile the package.
|
||||||
|
|
||||||
|
3. Optionally, type `make check' to run any self-tests that come with
|
||||||
|
the package.
|
||||||
|
|
||||||
|
4. Type `make install' to install the programs and any data files and
|
||||||
|
documentation.
|
||||||
|
|
||||||
|
5. You can remove the program binaries and object files from the
|
||||||
|
source code directory by typing `make clean'. To also remove the
|
||||||
|
files that `configure' created (so you can compile the package for
|
||||||
|
a different kind of computer), type `make distclean'. There is
|
||||||
|
also a `make maintainer-clean' target, but that is intended mainly
|
||||||
|
for the package's developers. If you use it, you may have to get
|
||||||
|
all sorts of other programs in order to regenerate files that came
|
||||||
|
with the distribution.
|
||||||
|
|
||||||
|
Compilers and Options
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Some systems require unusual options for compilation or linking that
|
||||||
|
the `configure' script does not know about. Run `./configure --help'
|
||||||
|
for details on some of the pertinent environment variables.
|
||||||
|
|
||||||
|
You can give `configure' initial values for configuration parameters
|
||||||
|
by setting variables in the command line or in the environment. Here
|
||||||
|
is an example:
|
||||||
|
|
||||||
|
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
|
||||||
|
|
||||||
|
*Note Defining Variables::, for more details.
|
||||||
|
|
||||||
|
Compiling For Multiple Architectures
|
||||||
|
====================================
|
||||||
|
|
||||||
|
You can compile the package for more than one kind of computer at the
|
||||||
|
same time, by placing the object files for each architecture in their
|
||||||
|
own directory. To do this, you must use a version of `make' that
|
||||||
|
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||||
|
directory where you want the object files and executables to go and run
|
||||||
|
the `configure' script. `configure' automatically checks for the
|
||||||
|
source code in the directory that `configure' is in and in `..'.
|
||||||
|
|
||||||
|
If you have to use a `make' that does not support the `VPATH'
|
||||||
|
variable, you have to compile the package for one architecture at a
|
||||||
|
time in the source code directory. After you have installed the
|
||||||
|
package for one architecture, use `make distclean' before reconfiguring
|
||||||
|
for another architecture.
|
||||||
|
|
||||||
|
Installation Names
|
||||||
|
==================
|
||||||
|
|
||||||
|
By default, `make install' will install the package's files in
|
||||||
|
`/usr/local/bin', `/usr/local/man', etc. You can specify an
|
||||||
|
installation prefix other than `/usr/local' by giving `configure' the
|
||||||
|
option `--prefix=PATH'.
|
||||||
|
|
||||||
|
You can specify separate installation prefixes for
|
||||||
|
architecture-specific files and architecture-independent files. If you
|
||||||
|
give `configure' the option `--exec-prefix=PATH', the package will use
|
||||||
|
PATH as the prefix for installing programs and libraries.
|
||||||
|
Documentation and other data files will still use the regular prefix.
|
||||||
|
|
||||||
|
In addition, if you use an unusual directory layout you can give
|
||||||
|
options like `--bindir=PATH' to specify different values for particular
|
||||||
|
kinds of files. Run `configure --help' for a list of the directories
|
||||||
|
you can set and what kinds of files go in them.
|
||||||
|
|
||||||
|
If the package supports it, you can cause programs to be installed
|
||||||
|
with an extra prefix or suffix on their names by giving `configure' the
|
||||||
|
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||||
|
|
||||||
|
Optional Features
|
||||||
|
=================
|
||||||
|
|
||||||
|
Some packages pay attention to `--enable-FEATURE' options to
|
||||||
|
`configure', where FEATURE indicates an optional part of the package.
|
||||||
|
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||||
|
is something like `gnu-as' or `x' (for the X Window System). The
|
||||||
|
`README' should mention any `--enable-' and `--with-' options that the
|
||||||
|
package recognizes.
|
||||||
|
|
||||||
|
For packages that use the X Window System, `configure' can usually
|
||||||
|
find the X include and library files automatically, but if it doesn't,
|
||||||
|
you can use the `configure' options `--x-includes=DIR' and
|
||||||
|
`--x-libraries=DIR' to specify their locations.
|
||||||
|
|
||||||
|
Specifying the System Type
|
||||||
|
==========================
|
||||||
|
|
||||||
|
There may be some features `configure' cannot figure out
|
||||||
|
automatically, but needs to determine by the type of machine the package
|
||||||
|
will run on. Usually, assuming the package is built to be run on the
|
||||||
|
_same_ architectures, `configure' can figure that out, but if it prints
|
||||||
|
a message saying it cannot guess the machine type, give it the
|
||||||
|
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||||
|
type, such as `sun4', or a canonical name which has the form:
|
||||||
|
|
||||||
|
CPU-COMPANY-SYSTEM
|
||||||
|
|
||||||
|
where SYSTEM can have one of these forms:
|
||||||
|
|
||||||
|
OS KERNEL-OS
|
||||||
|
|
||||||
|
See the file `config.sub' for the possible values of each field. If
|
||||||
|
`config.sub' isn't included in this package, then this package doesn't
|
||||||
|
need to know the machine type.
|
||||||
|
|
||||||
|
If you are _building_ compiler tools for cross-compiling, you should
|
||||||
|
use the `--target=TYPE' option to select the type of system they will
|
||||||
|
produce code for.
|
||||||
|
|
||||||
|
If you want to _use_ a cross compiler, that generates code for a
|
||||||
|
platform different from the build platform, you should specify the
|
||||||
|
"host" platform (i.e., that on which the generated programs will
|
||||||
|
eventually be run) with `--host=TYPE'.
|
||||||
|
|
||||||
|
Sharing Defaults
|
||||||
|
================
|
||||||
|
|
||||||
|
If you want to set default values for `configure' scripts to share,
|
||||||
|
you can create a site shell script called `config.site' that gives
|
||||||
|
default values for variables like `CC', `cache_file', and `prefix'.
|
||||||
|
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||||
|
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||||
|
`CONFIG_SITE' environment variable to the location of the site script.
|
||||||
|
A warning: not all `configure' scripts look for a site script.
|
||||||
|
|
||||||
|
Defining Variables
|
||||||
|
==================
|
||||||
|
|
||||||
|
Variables not defined in a site shell script can be set in the
|
||||||
|
environment passed to `configure'. However, some packages may run
|
||||||
|
configure again during the build, and the customized values of these
|
||||||
|
variables may be lost. In order to avoid this problem, you should set
|
||||||
|
them in the `configure' command line, using `VAR=value'. For example:
|
||||||
|
|
||||||
|
./configure CC=/usr/local2/bin/gcc
|
||||||
|
|
||||||
|
will cause the specified gcc to be used as the C compiler (unless it is
|
||||||
|
overridden in the site shell script).
|
||||||
|
|
||||||
|
`configure' Invocation
|
||||||
|
======================
|
||||||
|
|
||||||
|
`configure' recognizes the following options to control how it
|
||||||
|
operates.
|
||||||
|
|
||||||
|
`--help'
|
||||||
|
`-h'
|
||||||
|
Print a summary of the options to `configure', and exit.
|
||||||
|
|
||||||
|
`--version'
|
||||||
|
`-V'
|
||||||
|
Print the version of Autoconf used to generate the `configure'
|
||||||
|
script, and exit.
|
||||||
|
|
||||||
|
`--cache-file=FILE'
|
||||||
|
Enable the cache: use and save the results of the tests in FILE,
|
||||||
|
traditionally `config.cache'. FILE defaults to `/dev/null' to
|
||||||
|
disable caching.
|
||||||
|
|
||||||
|
`--config-cache'
|
||||||
|
`-C'
|
||||||
|
Alias for `--cache-file=config.cache'.
|
||||||
|
|
||||||
|
`--quiet'
|
||||||
|
`--silent'
|
||||||
|
`-q'
|
||||||
|
Do not print messages saying which checks are being made. To
|
||||||
|
suppress all normal output, redirect it to `/dev/null' (any error
|
||||||
|
messages will still be shown).
|
||||||
|
|
||||||
|
`--srcdir=DIR'
|
||||||
|
Look for the package's source code in directory DIR. Usually
|
||||||
|
`configure' can determine that directory automatically.
|
||||||
|
|
||||||
|
`configure' also accepts some other, not widely useful, options. Run
|
||||||
|
`configure --help' for more details.
|
||||||
|
|
||||||
36
libtirpc/Makefile.am
Normal file
36
libtirpc/Makefile.am
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
SUBDIRS = src man doc
|
||||||
|
|
||||||
|
nobase_include_HEADERS = tirpc/netconfig.h \
|
||||||
|
tirpc/rpcsvc/crypt.x \
|
||||||
|
tirpc/rpcsvc/crypt.h \
|
||||||
|
tirpc/rpc/xdr.h \
|
||||||
|
tirpc/rpc/types.h \
|
||||||
|
tirpc/rpc/svc_soc.h \
|
||||||
|
tirpc/rpc/svc.h \
|
||||||
|
tirpc/rpc/svc_dg.h \
|
||||||
|
tirpc/rpc/svc_auth.h \
|
||||||
|
tirpc/rpc/rpc_msg.h \
|
||||||
|
tirpc/rpc/rpc.h \
|
||||||
|
tirpc/rpc/rpcent.h \
|
||||||
|
tirpc/rpc/rpc_com.h \
|
||||||
|
tirpc/rpc/rpcb_prot.x \
|
||||||
|
tirpc/rpc/rpcb_prot.h \
|
||||||
|
tirpc/rpc/rpcb_clnt.h \
|
||||||
|
tirpc/rpc/raw.h \
|
||||||
|
tirpc/rpc/pmap_rmt.h \
|
||||||
|
tirpc/rpc/pmap_prot.h \
|
||||||
|
tirpc/rpc/pmap_clnt.h \
|
||||||
|
tirpc/rpc/nettype.h \
|
||||||
|
tirpc/rpc/des.h \
|
||||||
|
tirpc/rpc/des_crypt.h \
|
||||||
|
tirpc/rpc/clnt_stat.h \
|
||||||
|
tirpc/rpc/clnt_soc.h \
|
||||||
|
tirpc/rpc/clnt.h \
|
||||||
|
tirpc/rpc/auth_unix.h \
|
||||||
|
tirpc/rpc/auth_kerb.h \
|
||||||
|
tirpc/rpc/auth.h \
|
||||||
|
tirpc/rpc/auth_gss.h \
|
||||||
|
tirpc/rpc/auth_des.h
|
||||||
|
|
||||||
|
pkgconfigdir=$(libdir)/pkgconfig
|
||||||
|
pkgconfig_DATA = libtirpc.pc
|
||||||
3
libtirpc/NEWS
Normal file
3
libtirpc/NEWS
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
New in 0.1:
|
||||||
|
* Portage from FreeBSD 5.2.1 (security part to be completed)
|
||||||
|
* Use autoconf/automake
|
||||||
44
libtirpc/README
Normal file
44
libtirpc/README
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
LIBTIRPC 0.1 FROM SUN'S TIRPCSRC 2.3 29 Aug 1994
|
||||||
|
|
||||||
|
This package contains SunLib's implementation of transport-independent
|
||||||
|
RPC (TI-RPC) documentation. This library forms a piece of the base of Open Network
|
||||||
|
Computing (ONC), and is derived directly from the Solaris 2.3 source.
|
||||||
|
|
||||||
|
TI-RPC is an enhanced version of TS-RPC that requires the UNIX System V
|
||||||
|
Transport Layer Interface (TLI) or an equivalent X/Open Transport Interface
|
||||||
|
(XTI). TI-RPC is on-the-wire compatible with the TS-RPC, which is supported
|
||||||
|
by almost 70 vendors on all major operating systems. TS-RPC source code
|
||||||
|
(RPCSRC 4.0) remains available from several internet sites.
|
||||||
|
|
||||||
|
This release was a native source release, compatible for
|
||||||
|
building on Solaris 2.3. It had been ported from FreeBSD 5.2.1 to GNU/Linux
|
||||||
|
in 2004.
|
||||||
|
|
||||||
|
Applications linked with this release's librpc must link with the United
|
||||||
|
States domestic version of libcrypt in order to resolve the cbc_crypt() and
|
||||||
|
ecb_crypt() functions. These routines are used with Secure RPC however all
|
||||||
|
RPC programs that link with this release's librpc will need to link with the
|
||||||
|
domestic libcrypt.
|
||||||
|
|
||||||
|
WHAT'S NEW IN THIS RELEASE: TIRPCSRC 2.3 FROM SUN
|
||||||
|
|
||||||
|
The previous release was TIRPCSRC 2.0.
|
||||||
|
|
||||||
|
1. This release is based on Solaris 2.3. The previous release was
|
||||||
|
based on Solaris 2.0. This release contains a siginificant number of
|
||||||
|
bug fixes and other enhancements over TIRPCSRC 2.0.
|
||||||
|
|
||||||
|
2. The RPC library is thread safe for all client-side interfaces
|
||||||
|
(clnt_create, clnt_call, etc.). The server-side interfaces
|
||||||
|
(svc_create, svc_run, etc.) are not thread safe in this release. The
|
||||||
|
server-side interfaces will be made thread safe in the next release of
|
||||||
|
TIRPCSRC. Please see the manual pages for details about which
|
||||||
|
interfaces are thread safe.
|
||||||
|
|
||||||
|
3. As part of the work to make the RPC library thread-safe, rpcgen has
|
||||||
|
been enhanced to generate thread-safe RPC stubs (the -M option). Note
|
||||||
|
that this modifies the call-signature for the stub functions; the
|
||||||
|
procedure calling the RPC stub must now pass to the stub a pointer to
|
||||||
|
an allocated structure where results will be placed by the stub. See
|
||||||
|
the rpcgen manual page and the rpcgen Programming Guide for details.
|
||||||
|
|
||||||
6
libtirpc/THANKS
Normal file
6
libtirpc/THANKS
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
Thanks to for
|
||||||
|
|
||||||
|
Aurelien Charbon <aurelien.charbon@bull.net> TI-RPC portage from NetBSD
|
||||||
|
|
||||||
|
BSD Communauty TI-RPC improvement from Sun implementation
|
||||||
|
|
||||||
3
libtirpc/TODO
Normal file
3
libtirpc/TODO
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
* Support of DES & other security part
|
||||||
|
* Provide tests
|
||||||
|
* rpcgen command missing
|
||||||
7
libtirpc/VERSION
Normal file
7
libtirpc/VERSION
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
# This file is used by configure to get version information
|
||||||
|
#
|
||||||
|
PKG_MAJOR=0
|
||||||
|
PKG_MINOR=1
|
||||||
|
PKG_REVISION=11
|
||||||
|
PKG_BUILD=0
|
||||||
|
|
||||||
42
libtirpc/autogen.sh
Normal file
42
libtirpc/autogen.sh
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
#!/bin/sh -e
|
||||||
|
|
||||||
|
echo -n cleaning up .
|
||||||
|
|
||||||
|
# Clean up the generated crud
|
||||||
|
(
|
||||||
|
for FILE in compile config.guess config.sub depcomp install-sh ltmain.sh missing mkinstalldirs; do
|
||||||
|
if test -f $FILE; then
|
||||||
|
rm -f $FILE
|
||||||
|
fi
|
||||||
|
echo -n .
|
||||||
|
done
|
||||||
|
)
|
||||||
|
|
||||||
|
for FILE in aclocal.m4 configure config.h.in; do
|
||||||
|
if test -f $FILE; then
|
||||||
|
rm -f $FILE
|
||||||
|
fi
|
||||||
|
echo -n .
|
||||||
|
done
|
||||||
|
|
||||||
|
for DIR in autom4te.cache; do
|
||||||
|
if test -d $DIR; then
|
||||||
|
rm -rf $DIR
|
||||||
|
fi
|
||||||
|
echo -n .
|
||||||
|
done
|
||||||
|
|
||||||
|
find . -type f -name 'Makefile.in' -print0 | xargs -r0 rm -f --
|
||||||
|
find . -type f -name 'Makefile' -print0 | xargs -r0 rm -f --
|
||||||
|
|
||||||
|
echo ' done'
|
||||||
|
|
||||||
|
if test x"${1}" = x"clean"; then
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
|
aclocal
|
||||||
|
libtoolize --force --copy
|
||||||
|
autoheader
|
||||||
|
automake --add-missing --copy --gnu # -Wall
|
||||||
|
autoconf # -Wall
|
||||||
10
libtirpc/bootstrap
Normal file
10
libtirpc/bootstrap
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
[ -e Makefile ] && make clean
|
||||||
|
rm -rf autom4te.cache configure Makefile stamp-h1
|
||||||
|
rm -rf src/Makefile src/.deps
|
||||||
|
rm -rf Makefile.in aclocal.m4 config.log config.h
|
||||||
|
rm -rf depcomp missing install-sh config.status
|
||||||
|
aclocal
|
||||||
|
autoheader
|
||||||
|
automake --gnu --add-missing -c
|
||||||
|
autoconf
|
||||||
|
rm -rf autom4te.cache config.log libtool stamp-h1*
|
||||||
29
libtirpc/configure.ac
Normal file
29
libtirpc/configure.ac
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
AC_INIT(libtirpc, 0.2.1)
|
||||||
|
AM_INIT_AUTOMAKE(libtirpc, 0.2.1)
|
||||||
|
AM_MAINTAINER_MODE
|
||||||
|
AC_CONFIG_SRCDIR([src/auth_des.c])
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(gss,[ --enable-gss Turn on gss api], [case "${enableval}" in
|
||||||
|
yes) gss=true ; AC_CHECK_LIB([gssapi],[gss_init_sec_context]) ;;
|
||||||
|
no) gss=false ;;
|
||||||
|
*) AC_MSG_ERROR(bad value ${enableval} for --enable-gss) ;;
|
||||||
|
esac],[gss=false])
|
||||||
|
AM_CONDITIONAL(GSS, test x$gss = xtrue)
|
||||||
|
if test x$gss = xtrue; then
|
||||||
|
AC_DEFINE(HAVE_LIBGSSAPI, 1, [])
|
||||||
|
PKG_CHECK_MODULES(GSSGLUE, libgssglue, [],
|
||||||
|
AC_MSG_ERROR([Unable to locate information required to use libgssglue.]))
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_PROG_CC
|
||||||
|
AM_CONFIG_HEADER(config.h)
|
||||||
|
AC_PROG_LIBTOOL
|
||||||
|
##AC_PROG_RANLIB
|
||||||
|
AC_HEADER_DIRENT
|
||||||
|
AC_PREFIX_DEFAULT(/usr)
|
||||||
|
AC_CHECK_HEADERS([arpa/inet.h fcntl.h libintl.h limits.h locale.h netdb.h netinet/in.h stddef.h stdint.h stdlib.h string.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h syslog.h unistd.h])
|
||||||
|
AC_CHECK_LIB([pthread], [pthread_create])
|
||||||
|
|
||||||
|
|
||||||
|
AC_CONFIG_FILES([Makefile src/Makefile man/Makefile doc/Makefile])
|
||||||
|
AC_OUTPUT(libtirpc.pc)
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue