pastebin - collaborative debugging tool
nrubsig.kpaste.net RSS


NFSv4.2+misc prototype, backup 2025-01-06
Posted by Anonymous on Mon 6th Jan 2025 17:56
raw | new post

  1. diff --git a/build.vc19/libtirpc/libtirpc.vcxproj b/build.vc19/libtirpc/libtirpc.vcxproj
  2. index 2da4efa..5a1a357 100644
  3. --- a/build.vc19/libtirpc/libtirpc.vcxproj
  4. +++ b/build.vc19/libtirpc/libtirpc.vcxproj
  5. @@ -135,6 +135,7 @@
  6.        <GenerateDebugInformation>true</GenerateDebugInformation>
  7.        <AdditionalDependencies>ws2_32.lib;secur32.lib;%(AdditionalDependencies)</AdditionalDependencies>
  8.        <ModuleDefinitionFile>..\..\libtirpc\libtirpc\libtirpc.def</ModuleDefinitionFile>
  9. +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
  10.      </Link>
  11.    </ItemDefinitionGroup>
  12.    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
  13. @@ -158,6 +159,7 @@
  14.        <GenerateDebugInformation>true</GenerateDebugInformation>
  15.        <AdditionalDependencies>ws2_32.lib;secur32.lib;%(AdditionalDependencies)</AdditionalDependencies>
  16.        <ModuleDefinitionFile>..\..\libtirpc\libtirpc\libtirpc.def</ModuleDefinitionFile>
  17. +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
  18.      </Link>
  19.    </ItemDefinitionGroup>
  20.    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
  21. @@ -206,6 +208,7 @@
  22.        <OptimizeReferences>true</OptimizeReferences>
  23.        <AdditionalDependencies>ws2_32.lib;secur32.lib;%(AdditionalDependencies)</AdditionalDependencies>
  24.        <ModuleDefinitionFile>..\..\libtirpc\libtirpc\libtirpc.def</ModuleDefinitionFile>
  25. +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
  26.      </Link>
  27.    </ItemDefinitionGroup>
  28.    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
  29. @@ -231,6 +234,7 @@
  30.        <OptimizeReferences>true</OptimizeReferences>
  31.        <AdditionalDependencies>ws2_32.lib;secur32.lib;%(AdditionalDependencies)</AdditionalDependencies>
  32.        <ModuleDefinitionFile>..\..\libtirpc\libtirpc\libtirpc.def</ModuleDefinitionFile>
  33. +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
  34.      </Link>
  35.    </ItemDefinitionGroup>
  36.    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
  37. diff --git a/build.vc19/nfsd/nfsd.vcxproj b/build.vc19/nfsd/nfsd.vcxproj
  38. index 43d07f7..50712bc 100644
  39. --- a/build.vc19/nfsd/nfsd.vcxproj
  40. +++ b/build.vc19/nfsd/nfsd.vcxproj
  41. @@ -1,20 +1,10 @@
  42.  
  43. <?xml version="1.0" encoding="utf-8"?>
  44.  <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  45.    <Target Name="generate_git_version_header" BeforeTargets="ClCompile">
  46. -    <Exec
  47. -      Command="git describe --long --always --dirty --exclude=* --abbrev=8"
  48. -      ConsoleToMSBuild="True"
  49. -      IgnoreExitCode="False">
  50. +    <Exec Command="git describe --long --always --dirty --exclude=* --abbrev=8" ConsoleToMSBuild="True" IgnoreExitCode="False">
  51.        <Output TaskParameter="ConsoleOutput" PropertyName="git_version_string" />
  52.      </Exec>
  53. -
  54. -    <WriteLinesToFile
  55. -      File="$(IntermediateOutputPath)/git_version.h"
  56. -      Overwrite="True"
  57. -      Lines="
  58. -/* Generated file, do not edit */
  59. -#define GIT_COMMIT_ID &quot;$(git_version_string)&quot;
  60. -" />
  61. +    <WriteLinesToFile File="$(IntermediateOutputPath)/git_version.h" Overwrite="True" Lines="&#xA;/* Generated file, do not edit */&#xA;#define GIT_COMMIT_ID &quot;$(git_version_string)&quot;&#xA;" />
  62.    </Target>
  63.    <ItemGroup Label="ProjectConfigurations">
  64.      <ProjectConfiguration Include="Debug|Win32">
  65. @@ -150,6 +140,7 @@
  66.        <SubSystem>Console</SubSystem>
  67.        <GenerateDebugInformation>true</GenerateDebugInformation>
  68.        <AdditionalDependencies>iphlpapi.lib;ws2_32.lib;wldap32.lib;ntdll.lib;..\$(Configuration)\libtirpc.lib;%(AdditionalDependencies)</AdditionalDependencies>
  69. +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
  70.      </Link>
  71.    </ItemDefinitionGroup>
  72.    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
  73. @@ -172,6 +163,7 @@
  74.        <SubSystem>Console</SubSystem>
  75.        <GenerateDebugInformation>true</GenerateDebugInformation>
  76.        <AdditionalDependencies>iphlpapi.lib;ws2_32.lib;wldap32.lib;ntdll.lib;..\$(Platform)\$(Configuration)\libtirpc.lib;%(AdditionalDependencies)</AdditionalDependencies>
  77. +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
  78.      </Link>
  79.    </ItemDefinitionGroup>
  80.    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
  81. @@ -218,6 +210,7 @@
  82.        <EnableCOMDATFolding>true</EnableCOMDATFolding>
  83.        <OptimizeReferences>true</OptimizeReferences>
  84.        <AdditionalDependencies>iphlpapi.lib;ws2_32.lib;wldap32.lib;ntdll.lib;..\$(Configuration)\libtirpc.lib;%(AdditionalDependencies)</AdditionalDependencies>
  85. +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
  86.      </Link>
  87.    </ItemDefinitionGroup>
  88.    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
  89. @@ -242,6 +235,7 @@
  90.        <EnableCOMDATFolding>true</EnableCOMDATFolding>
  91.        <OptimizeReferences>true</OptimizeReferences>
  92.        <AdditionalDependencies>iphlpapi.lib;ws2_32.lib;wldap32.lib;ntdll.lib;..\$(Platform)\$(Configuration)\libtirpc.lib;%(AdditionalDependencies)</AdditionalDependencies>
  93. +      <RandomizedBaseAddress>false</RandomizedBaseAddress>
  94.      </Link>
  95.    </ItemDefinitionGroup>
  96.    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
  97. diff --git a/daemon/callback_server.c b/daemon/callback_server.c
  98. index dc3139a..9b782c1 100644
  99. --- a/daemon/callback_server.c
  100. +++ b/daemon/callback_server.c
  101. @@ -387,9 +387,10 @@ static void handle_cb_compound(nfs41_rpc_clnt *rpc_clnt, cb_req *req, struct cb_
  102.      }
  103.  
  104.      DPRINTF(CBSLVL, ("CB_COMPOUND('%s', %u)\n", args.tag.str, args.argarray_count));
  105. -    if (args.minorversion != 1) {
  106. +    if ((args.minorversion != 1) && (args.minorversion != 2)) {
  107.          res->status = NFS4ERR_MINOR_VERS_MISMATCH; //XXXXX
  108. -        eprintf("args.minorversion %u != 1\n", args.minorversion);
  109. +        eprintf("handle_cb_compound: args.minorversion %u != 1/2\n",
  110. +            (unsigned int)args.minorversion);
  111.          goto out;
  112.      }
  113.  
  114. diff --git a/daemon/lookup.c b/daemon/lookup.c
  115. index ee883b9..085bc35 100644
  116. --- a/daemon/lookup.c
  117. +++ b/daemon/lookup.c
  118. @@ -135,7 +135,8 @@ static int lookup_rpc(
  119.      nfs_argop4 argops[4+MAX_LOOKUP_COMPONENTS*3];
  120.      nfs_resop4 resops[4+MAX_LOOKUP_COMPONENTS*3];
  121.  
  122. -    compound_init(&compound, argops, resops, "lookup");
  123. +    compound_init(&compound, session->client->root->nfsminorvers,
  124. +        argops, resops, "lookup");
  125.  
  126.      compound_add_op(&compound, OP_SEQUENCE, &args->sequence, &res->sequence);
  127.      nfs41_session_sequence(&args->sequence, session, 0);
  128. diff --git a/daemon/mount.c b/daemon/mount.c
  129. index 63c5e1f..be8854f 100644
  130. --- a/daemon/mount.c
  131. +++ b/daemon/mount.c
  132. @@ -52,11 +52,15 @@ static int parse_mount(unsigned char *buffer, uint32_t length, nfs41_upcall *upc
  133.      if (status) goto out;
  134.      status = safe_read(&buffer, &length, &args->use_nfspubfh, sizeof(DWORD));
  135.      if (status) goto out;
  136. +    status = safe_read(&buffer, &length, &args->nfsvers, sizeof(DWORD));
  137. +    if (status) goto out;
  138.  
  139.      DPRINTF(1, ("parsing NFS41_SYSOP_MOUNT: hostport='%s' root='%s' "
  140. -        "sec_flavor='%s' rsize=%d wsize=%d use_nfspubfh=%d\n",
  141. +        "sec_flavor='%s' rsize=%d wsize=%d use_nfspubfh=%d "
  142. +        "nfsvers=%d\n",
  143.          args->hostport, args->path, secflavorop2name(args->sec_flavor),
  144. -        args->rsize, args->wsize, args->use_nfspubfh));
  145. +        args->rsize, args->wsize, args->use_nfspubfh,
  146. +        args->nfsvers));
  147.      return status;
  148.  out:
  149.      DPRINTF(1, ("parsing NFS41_SYSOP_MOUNT: failed %d\n", status));
  150. @@ -148,7 +152,9 @@ static int handle_mount(void *daemon_context, nfs41_upcall *upcall)
  151.      } else {
  152.          // create root
  153.          status = nfs41_root_create(hostname, port,
  154. -            args->use_nfspubfh?true:false, args->sec_flavor,
  155. +            args->use_nfspubfh?true:false,
  156. +            args->nfsvers,
  157. +            args->sec_flavor,
  158.              args->wsize + WRITE_OVERHEAD, args->rsize + READ_OVERHEAD, &root);
  159.          if (status) {
  160.              eprintf("nfs41_root_create(hostname='%s', port=%d) failed %d\n",
  161. diff --git a/daemon/name_cache.c b/daemon/name_cache.c
  162. index a5e5a1e..1925304 100644
  163. --- a/daemon/name_cache.c
  164. +++ b/daemon/name_cache.c
  165. @@ -1356,7 +1356,8 @@ static int rpc_array_putfh(
  166.  
  167.      *valid_out = 0;
  168.  
  169. -    compound_init(&compound, argops, resops, "array_putfh");
  170. +    compound_init(&compound, session->client->root->nfsminorvers,
  171. +        argops, resops, "array_putfh");
  172.  
  173.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  174.      nfs41_session_sequence(&sequence_args, session, 0);
  175. diff --git a/daemon/namespace.c b/daemon/namespace.c
  176. index e0faf23..8bfba37 100644
  177. --- a/daemon/namespace.c
  178. +++ b/daemon/namespace.c
  179. @@ -26,6 +26,9 @@
  180.  #include "nfs41_ops.h"
  181.  #include "util.h"
  182.  #include "daemon_debug.h"
  183. +/* for |ERROR_NFS_VERSION_MISMATCH|+|NFS_VERSION_AUTONEGOTIATION| */
  184. +#include "nfs41_driver.h"
  185. +
  186.  
  187.  
  188.  #define NSLVL 2 /* dprintf level for namespace logging */
  189. @@ -39,6 +42,7 @@ int nfs41_root_create(
  190.      IN const char *name,
  191.      IN uint32_t port,
  192.      IN bool use_nfspubfh,
  193. +    IN DWORD nfsvers,
  194.      IN uint32_t sec_flavor,
  195.      IN uint32_t wsize,
  196.      IN uint32_t rsize,
  197. @@ -47,7 +51,10 @@ int nfs41_root_create(
  198.      int status = NO_ERROR;
  199.      nfs41_root *root;
  200.  
  201. -    DPRINTF(NSLVL, ("--> nfs41_root_create(name='%s', port=%d)\n", name, port));
  202. +    DPRINTF(NSLVL,
  203. +        ("--> nfs41_root_create(name='%s', port=%d, "
  204. +            "use_nfspubfh=%d, nfsvers=%d)\n",
  205. +            name, port, (int)use_nfspubfh, (int)nfsvers));
  206.  
  207.      root = calloc(1, sizeof(nfs41_root));
  208.      if (root == NULL) {
  209. @@ -57,6 +64,17 @@ int nfs41_root_create(
  210.  
  211.      list_init(&root->clients);
  212.      root->use_nfspubfh = use_nfspubfh;
  213. +    if (nfsvers == NFS_VERSION_AUTONEGOTIATION) {
  214. +        /*
  215. +         * Use auto negotiation, |nfs41_root_mount_addrs()| will
  216. +         * set |root->nfsminorvers| to the minor version being used
  217. +         */
  218. +        root->nfsminorvers = NFS_VERSION_AUTONEGOTIATION;
  219. +    }
  220. +    else {
  221. +        root->nfsminorvers = nfsvers % 10; /* 41 --> 1, 42 --> 2, ... */
  222. +        EASSERT((root->nfsminorvers >= 1) && (root->nfsminorvers <= 2));
  223. +    }
  224.      root->wsize = wsize;
  225.      root->rsize = rsize;
  226.      InitializeCriticalSection(&root->lock);
  227. @@ -64,7 +82,8 @@ int nfs41_root_create(
  228.      root->sec_flavor = sec_flavor;
  229.  
  230.      /* generate a unique client_owner */
  231. -    status = nfs41_client_owner(name, port, use_nfspubfh, sec_flavor, &root->client_owner);
  232. +    status = nfs41_client_owner(name, port, root->nfsminorvers,
  233. +        use_nfspubfh, sec_flavor, &root->client_owner);
  234.      if (status) {
  235.          eprintf("nfs41_client_owner() failed with %d\n", status);
  236.          free(root);
  237. @@ -368,12 +387,49 @@ int nfs41_root_mount_addrs(
  238.          goto out;
  239.      }
  240.  
  241. +    bool nfsminorvers_autonegotiate = false;
  242. +
  243. +    /*
  244. +     * NFSv4 protocol minor version "autonegotiation"
  245. +     * First try with 4.2, and if this fails try 4.1
  246. +     */
  247. +    if (root->nfsminorvers == NFS_VERSION_AUTONEGOTIATION) {
  248. +        root->nfsminorvers = 3;
  249. +        nfsminorvers_autonegotiate = true;
  250. +    }
  251. +
  252. +retry_nfs41_exchange_id:
  253. +    if (nfsminorvers_autonegotiate) {
  254. +        DPRINTF(0, ("nfs41_root_mount_addrs: "
  255. +            "Autonegotiating NFS version, "
  256. +            "trying NFSv4.%d\n",
  257. +            (int)root->nfsminorvers));
  258. +    }
  259. +
  260.      /* get a clientid with exchangeid */
  261. -    status = nfs41_exchange_id(rpc, &root->client_owner,
  262. +    status = nfs41_exchange_id(rpc, root->nfsminorvers,
  263. +        &root->client_owner,
  264.          nfs41_exchange_id_flags(is_data), &exchangeid);
  265.      if (status) {
  266. -        eprintf("nfs41_exchange_id() failed '%s'\n", nfs_error_string(status));
  267. +        if (status == NFS4ERR_MINOR_VERS_MISMATCH) {
  268. +            if (nfsminorvers_autonegotiate &&
  269. +                (root->nfsminorvers >= 1)) {
  270. +                root->nfsminorvers--;
  271. +                goto retry_nfs41_exchange_id;
  272. +            }
  273. +
  274. +            eprintf("nfs41_root_mount_addrs: "
  275. +                "nfs41_exchange_id() NFS4ERR_MINOR_VERS_MISMATCH,"
  276. +                "nfsminorvers=%d failed\n",
  277. +                (int)root->nfsminorvers);
  278. +            status = ERROR_NFS_VERSION_MISMATCH;
  279. +        }
  280. +        else {
  281. +            eprintf("nfs41_root_mount_addrs: "
  282. +                "nfs41_exchange_id() failed '%s'\n",
  283. +                nfs_error_string(status));
  284.              status = ERROR_BAD_NET_RESP;
  285. +        }
  286.          goto out_free_rpc;
  287.      }
  288.  
  289. diff --git a/daemon/nfs41.h b/daemon/nfs41.h
  290. index f5607a6..e6e82ad 100644
  291. --- a/daemon/nfs41.h
  292. +++ b/daemon/nfs41.h
  293. @@ -300,6 +300,7 @@ typedef struct __nfs41_root {
  294.      CRITICAL_SECTION lock;
  295.      struct list_entry clients;
  296.      bool use_nfspubfh;
  297. +    DWORD nfsminorvers;
  298.      uint32_t wsize;
  299.      uint32_t rsize;
  300.  #pragma warning( push )
  301. @@ -318,6 +319,7 @@ int nfs41_root_create(
  302.      IN const char *name,
  303.      IN uint32_t port,
  304.      IN bool use_nfspubfh,
  305. +    IN DWORD nfsvers,
  306.      IN uint32_t sec_flavor,
  307.      IN uint32_t wsize,
  308.      IN uint32_t rsize,
  309. @@ -436,6 +438,7 @@ void nfs41_server_addrs(
  310.  int nfs41_client_owner(
  311.      IN const char *name,
  312.      IN uint32_t port,
  313. +    IN int nfsminorvers,
  314.      IN bool use_nfspubfh,
  315.      IN uint32_t sec_flavor,
  316.      OUT client_owner4 *owner);
  317. diff --git a/daemon/nfs41_client.c b/daemon/nfs41_client.c
  318. index aa2cc25..b33a22d 100644
  319. --- a/daemon/nfs41_client.c
  320. +++ b/daemon/nfs41_client.c
  321. @@ -174,7 +174,8 @@ int nfs41_client_renew(
  322.      nfs41_exchange_id_res exchangeid = { 0 };
  323.      int status;
  324.  
  325. -    status = nfs41_exchange_id(client->rpc, &client->owner,
  326. +    status = nfs41_exchange_id(client->rpc,
  327. +        client->root->nfsminorvers, &client->owner,
  328.          nfs41_exchange_id_flags(client->is_data), &exchangeid);
  329.      if (status) {
  330.          eprintf("nfs41_exchange_id() failed with %d\n", status);
  331. @@ -362,6 +363,7 @@ out:
  332.  int nfs41_client_owner(
  333.      IN const char *name,
  334.      IN uint32_t port,
  335. +    IN int nfsminorvers,
  336.      IN bool use_nfspubfh,
  337.      IN uint32_t sec_flavor,
  338.      OUT client_owner4 *owner)
  339. @@ -421,6 +423,13 @@ int nfs41_client_owner(
  340.          goto out_context;
  341.      }
  342.  
  343. +    if (!CryptHashData(hash,
  344. +        (const BYTE*)&nfsminorvers, (DWORD)sizeof(int), 0)) {
  345. +        status = GetLastError();
  346. +        eprintf("CryptHashData() failed with %d\n", status);
  347. +        goto out_hash;
  348. +    }
  349. +
  350.      if (!CryptHashData(hash,
  351.          (const BYTE*)&use_nfspubfh, (DWORD)sizeof(bool), 0)) {
  352.          status = GetLastError();
  353. diff --git a/daemon/nfs41_compound.c b/daemon/nfs41_compound.c
  354. index 08faf55..669ae04 100644
  355. --- a/daemon/nfs41_compound.c
  356. +++ b/daemon/nfs41_compound.c
  357. @@ -40,6 +40,7 @@ int compound_error(int status)
  358.  
  359.  void compound_init(
  360.      nfs41_compound *compound,
  361. +    int minorversion,
  362.      nfs_argop4 *argops,
  363.      nfs_resop4 *resops,
  364.      const char *tag)
  365. @@ -47,7 +48,7 @@ void compound_init(
  366.      /* initialize args */
  367.      compound->args.tag_len = (uint32_t)strlen(tag);
  368.      memcpy(compound->args.tag, tag, compound->args.tag_len);
  369. -    compound->args.minorversion = 1;
  370. +    compound->args.minorversion = minorversion;
  371.      compound->args.argarray_count = 0;
  372.      compound->args.argarray = argops;
  373.  
  374. diff --git a/daemon/nfs41_compound.h b/daemon/nfs41_compound.h
  375. index d222559..9b09eba 100644
  376. --- a/daemon/nfs41_compound.h
  377. +++ b/daemon/nfs41_compound.h
  378. @@ -62,6 +62,7 @@ int compound_error(int status);
  379.  
  380.  void compound_init(
  381.      nfs41_compound *compound,
  382. +    int minorversion,
  383.      nfs_argop4 *argops,
  384.      nfs_resop4 *resops,
  385.      const char *tag);
  386. diff --git a/daemon/nfs41_ops.c b/daemon/nfs41_ops.c
  387. index 5e28c09..62a6bad 100644
  388. --- a/daemon/nfs41_ops.c
  389. +++ b/daemon/nfs41_ops.c
  390. @@ -50,6 +50,7 @@
  391.  
  392.  int nfs41_exchange_id(
  393.      IN nfs41_rpc_clnt *rpc,
  394. +    IN int nfsminorvers,
  395.      IN client_owner4 *owner,
  396.      IN uint32_t flags_in,
  397.      OUT nfs41_exchange_id_res *res_out)
  398. @@ -64,7 +65,8 @@ int nfs41_exchange_id(
  399.      /* fixme: This should be a function argument */
  400.      extern nfs41_daemon_globals nfs41_dg;
  401.  
  402. -    compound_init(&compound, &argop, &resop, "exchange_id");
  403. +    compound_init(&compound, nfsminorvers,
  404. +        &argop, &resop, "exchange_id");
  405.  
  406.      compound_add_op(&compound, OP_EXCHANGE_ID, &ex_id, res_out);
  407.  
  408. @@ -142,7 +144,8 @@ int nfs41_create_session(nfs41_client *clnt, nfs41_session *session, bool_t try_
  409.      DPRINTF(1, ("--> nfs41_create_session(clnt=0x%p,session=0x%p,try_recovery=%d)\n",
  410.          clnt, session, (int)try_recovery));
  411.  
  412. -    compound_init(&compound, &argop, &resop, "create_session");
  413. +    compound_init(&compound, clnt->root->nfsminorvers,
  414. +        &argop, &resop, "create_session");
  415.  
  416.      compound_add_op(&compound, OP_CREATE_SESSION, &req, &reply);
  417.  
  418. @@ -256,7 +259,8 @@ enum nfsstat4 nfs41_bind_conn_to_session(
  419.      nfs41_bind_conn_to_session_args bind_args = { 0 };
  420.      nfs41_bind_conn_to_session_res bind_res = { 0 };
  421.  
  422. -    compound_init(&compound, &argop, &resop, "bind_conn_to_session");
  423. +    compound_init(&compound, rpc->client->root->nfsminorvers,
  424. +        &argop, &resop, "bind_conn_to_session");
  425.  
  426.      compound_add_op(&compound, OP_BIND_CONN_TO_SESSION, &bind_args, &bind_res);
  427.      bind_args.sessionid = (unsigned char *)sessionid;
  428. @@ -283,7 +287,8 @@ int nfs41_destroy_session(
  429.      nfs41_destroy_session_args ds_args;
  430.      nfs41_destroy_session_res ds_res;
  431.  
  432. -    compound_init(&compound, &argop, &resop, "destroy_session");
  433. +    compound_init(&compound, session->client->root->nfsminorvers,
  434. +        &argop, &resop, "destroy_session");
  435.  
  436.      compound_add_op(&compound, OP_DESTROY_SESSION, &ds_args, &ds_res);
  437.      ds_args.dsa_sessionid = session->session_id;
  438. @@ -312,7 +317,8 @@ int nfs41_destroy_clientid(
  439.      nfs41_destroy_clientid_args dc_args;
  440.      nfs41_destroy_clientid_res dc_res;
  441.  
  442. -    compound_init(&compound, &argops, &resops, "destroy_clientid");
  443. +    compound_init(&compound, rpc->client->root->nfsminorvers,
  444. +        &argops, &resops, "destroy_clientid");
  445.  
  446.      compound_add_op(&compound, OP_DESTROY_CLIENTID, &dc_args, &dc_res);
  447.      dc_args.dca_clientid = clientid;
  448. @@ -338,7 +344,8 @@ enum nfsstat4 nfs41_reclaim_complete(
  449.      nfs41_sequence_res sequence_res;
  450.      nfs41_reclaim_complete_res reclaim_res;
  451.  
  452. -    compound_init(&compound, argops, resops, "reclaim_complete");
  453. +    compound_init(&compound, session->client->root->nfsminorvers,
  454. +        argops, resops, "reclaim_complete");
  455.  
  456.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  457.      nfs41_session_sequence(&sequence_args, session, 0);
  458. @@ -494,7 +501,8 @@ int nfs41_open(
  459.  
  460.      attr_request.arr[0] |= FATTR4_WORD0_FSID;
  461.  
  462. -    compound_init(&compound, argops, resops, "open");
  463. +    compound_init(&compound, session->client->root->nfsminorvers,
  464. +        argops, resops, "open");
  465.  
  466.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  467.      nfs41_session_sequence(&sequence_args, session, 1);
  468. @@ -621,7 +629,8 @@ int nfs41_create(
  469.  
  470.      nfs41_superblock_getattr_mask(parent->fh.superblock, &attr_request);
  471.  
  472. -    compound_init(&compound, argops, resops, "create");
  473. +    compound_init(&compound, session->client->root->nfsminorvers,
  474. +        argops, resops, "create");
  475.  
  476.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  477.      nfs41_session_sequence(&sequence_args, session, 1);
  478. @@ -709,7 +718,8 @@ int nfs41_close(
  479.  
  480.      nfs41_superblock_getattr_mask(file->fh.superblock, &attr_request);
  481.  
  482. -    compound_init(&compound, argops, resops, "close");
  483. +    compound_init(&compound, session->client->root->nfsminorvers,
  484. +        argops, resops, "close");
  485.  
  486.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  487.      nfs41_session_sequence(&sequence_args, session, 1);
  488. @@ -773,7 +783,8 @@ int nfs41_write(
  489.  
  490.      nfs41_superblock_getattr_mask(file->fh.superblock, &attr_request);
  491.  
  492. -    compound_init(&compound, argops, resops,
  493. +    compound_init(&compound, session->client->root->nfsminorvers,
  494. +        argops, resops,
  495.          stateid->stateid.seqid == 0 ? "ds write" : "write");
  496.  
  497.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  498. @@ -858,7 +869,8 @@ int nfs41_read(
  499.      nfs41_read_args read_args;
  500.      nfs41_read_res read_res;
  501.  
  502. -    compound_init(&compound, argops, resops,
  503. +    compound_init(&compound, session->client->root->nfsminorvers,
  504. +        argops, resops,
  505.          stateid->stateid.seqid == 0 ? "ds read" : "read");
  506.  
  507.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  508. @@ -920,7 +932,8 @@ int nfs41_commit(
  509.      bitmap4 attr_request;
  510.      nfs41_file_info info, *pinfo;
  511.  
  512. -    compound_init(&compound, argops, resops,
  513. +    compound_init(&compound, session->client->root->nfsminorvers,
  514. +        argops, resops,
  515.          do_getattr ? "commit" : "ds commit");
  516.  
  517.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  518. @@ -988,7 +1001,8 @@ int nfs41_lock(
  519.      nfs41_lock_args lock_args;
  520.      nfs41_lock_res lock_res;
  521.  
  522. -    compound_init(&compound, argops, resops, "lock");
  523. +    compound_init(&compound, session->client->root->nfsminorvers,
  524. +        argops, resops, "lock");
  525.  
  526.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  527.      nfs41_session_sequence(&sequence_args, session, 0);
  528. @@ -1046,7 +1060,8 @@ int nfs41_unlock(
  529.      nfs41_locku_args locku_args;
  530.      nfs41_locku_res locku_res;
  531.  
  532. -    compound_init(&compound, argops, resops, "unlock");
  533. +    compound_init(&compound, session->client->root->nfsminorvers,
  534. +        argops, resops, "unlock");
  535.  
  536.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  537.      nfs41_session_sequence(&sequence_args, session, 0);
  538. @@ -1092,7 +1107,8 @@ int nfs41_readdir(
  539.      nfs41_readdir_args readdir_args;
  540.      nfs41_readdir_res readdir_res;
  541.  
  542. -    compound_init(&compound, argops, resops, "readdir");
  543. +    compound_init(&compound, session->client->root->nfsminorvers,
  544. +        argops, resops, "readdir");
  545.  
  546.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  547.      nfs41_session_sequence(&sequence_args, session, 0);
  548. @@ -1142,7 +1158,8 @@ int nfs41_getattr(
  549.      nfs41_getattr_args getattr_args;
  550.      nfs41_getattr_res getattr_res NDSH(= { 0 });
  551.  
  552. -    compound_init(&compound, argops, resops, "getattr");
  553. +    compound_init(&compound, session->client->root->nfsminorvers,
  554. +        argops, resops, "getattr");
  555.  
  556.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  557.      nfs41_session_sequence(&sequence_args, session, 0);
  558. @@ -1202,7 +1219,8 @@ int nfs41_superblock_getattr(
  559.      nfs41_openattr_args openattr_args;
  560.      nfs41_openattr_res openattr_res;
  561.  
  562. -    compound_init(&compound, argops, resops, "getfsattr");
  563. +    compound_init(&compound, session->client->root->nfsminorvers,
  564. +        argops, resops, "getfsattr");
  565.  
  566.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  567.      nfs41_session_sequence(&sequence_args, session, 0);
  568. @@ -1269,7 +1287,8 @@ int nfs41_remove(
  569.  
  570.      nfs41_superblock_getattr_mask(parent->fh.superblock, &attr_request);
  571.  
  572. -    compound_init(&compound, argops, resops, "remove");
  573. +    compound_init(&compound, session->client->root->nfsminorvers,
  574. +        argops, resops, "remove");
  575.  
  576.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  577.      nfs41_session_sequence(&sequence_args, session, 1);
  578. @@ -1340,7 +1359,8 @@ int nfs41_rename(
  579.  
  580.      nfs41_superblock_getattr_mask(src_dir->fh.superblock, &attr_request);
  581.  
  582. -    compound_init(&compound, argops, resops, "rename");
  583. +    compound_init(&compound, session->client->root->nfsminorvers,
  584. +        argops, resops, "rename");
  585.  
  586.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  587.      nfs41_session_sequence(&sequence_args, session, 1);
  588. @@ -1434,7 +1454,8 @@ int nfs41_setattr(
  589.      nfs41_getattr_res getattr_res NDSH(= { 0 });
  590.      bitmap4 attr_request;
  591.  
  592. -    compound_init(&compound, argops, resops, "setattr");
  593. +    compound_init(&compound, session->client->root->nfsminorvers,
  594. +        argops, resops, "setattr");
  595.  
  596.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  597.      nfs41_session_sequence(&sequence_args, session, 0);
  598. @@ -1530,7 +1551,8 @@ int nfs41_link(
  599.      nfs41_superblock_getattr_mask(dst_dir->fh.superblock, &cinfo->attrmask);
  600.      cinfo->attrmask.arr[0] |= FATTR4_WORD0_FSID;
  601.  
  602. -    compound_init(&compound, argops, resops, "link");
  603. +    compound_init(&compound, session->client->root->nfsminorvers,
  604. +        argops, resops, "link");
  605.  
  606.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  607.      nfs41_session_sequence(&sequence_args, session, 1);
  608. @@ -1619,7 +1641,8 @@ int nfs41_readlink(
  609.      nfs41_putfh_res putfh_res;
  610.      nfs41_readlink_res readlink_res;
  611.  
  612. -    compound_init(&compound, argops, resops, "readlink");
  613. +    compound_init(&compound, session->client->root->nfsminorvers,
  614. +        argops, resops, "readlink");
  615.  
  616.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  617.      nfs41_session_sequence(&sequence_args, session, 0);
  618. @@ -1663,7 +1686,8 @@ int nfs41_access(
  619.      nfs41_access_args access_args;
  620.      nfs41_access_res access_res;
  621.  
  622. -    compound_init(&compound, argops, resops, "access");
  623. +    compound_init(&compound, session->client->root->nfsminorvers,
  624. +        argops, resops, "access");
  625.  
  626.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  627.      nfs41_session_sequence(&sequence_args, session, 0);
  628. @@ -1700,7 +1724,8 @@ int nfs41_send_sequence(
  629.      nfs41_sequence_args sequence_args;
  630.      nfs41_sequence_res sequence_res;
  631.  
  632. -    compound_init(&compound, argops, resops, "sequence");
  633. +    compound_init(&compound, session->client->root->nfsminorvers,
  634. +        argops, resops, "sequence");
  635.  
  636.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  637.      nfs41_session_sequence(&sequence_args, session, 0);
  638. @@ -1734,7 +1759,8 @@ enum nfsstat4 nfs41_want_delegation(
  639.      nfs41_want_delegation_args wd_args;
  640.      nfs41_want_delegation_res wd_res;
  641.  
  642. -    compound_init(&compound, argops, resops, "want_delegation");
  643. +    compound_init(&compound, session->client->root->nfsminorvers,
  644. +        argops, resops, "want_delegation");
  645.  
  646.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  647.      nfs41_session_sequence(&sequence_args, session, 0);
  648. @@ -1768,7 +1794,8 @@ int nfs41_delegpurge(
  649.      nfs41_sequence_res sequence_res;
  650.      nfs41_delegpurge_res dp_res;
  651.  
  652. -    compound_init(&compound, argops, resops, "delegpurge");
  653. +    compound_init(&compound, session->client->root->nfsminorvers,
  654. +        argops, resops, "delegpurge");
  655.  
  656.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  657.      nfs41_session_sequence(&sequence_args, session, 0);
  658. @@ -1801,7 +1828,8 @@ int nfs41_delegreturn(
  659.      nfs41_delegreturn_args dr_args;
  660.      nfs41_delegreturn_res dr_res;
  661.  
  662. -    compound_init(&compound, argops, resops, "delegreturn");
  663. +    compound_init(&compound, session->client->root->nfsminorvers,
  664. +        argops, resops, "delegreturn");
  665.  
  666.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  667.      nfs41_session_sequence(&sequence_args, session, 0);
  668. @@ -1849,7 +1877,8 @@ enum nfsstat4 nfs41_fs_locations(
  669.      bitmap4 attr_request = { .count=1, .arr[0]=FATTR4_WORD0_FS_LOCATIONS };
  670.      nfs41_file_info info;
  671.  
  672. -    compound_init(&compound, argops, resops, "fs_locations");
  673. +    compound_init(&compound, session->client->root->nfsminorvers,
  674. +        argops, resops, "fs_locations");
  675.  
  676.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  677.      nfs41_session_sequence(&sequence_args, session, 0);
  678. @@ -1893,7 +1922,8 @@ int nfs41_secinfo(
  679.      nfs41_secinfo_args secinfo_args;
  680.      nfs41_secinfo_no_name_res secinfo_res;
  681.  
  682. -    compound_init(&compound, argops, resops, "secinfo");
  683. +    compound_init(&compound, session->client->root->nfsminorvers,
  684. +        argops, resops, "secinfo");
  685.  
  686.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  687.      nfs41_session_sequence(&sequence_args, session, 0);
  688. @@ -1941,7 +1971,8 @@ int nfs41_secinfo_noname(
  689.      nfs41_secinfo_no_name_args noname_args;
  690.      nfs41_secinfo_no_name_res noname_res;
  691.  
  692. -    compound_init(&compound, argops, resops, "secinfo_no_name");
  693. +    compound_init(&compound, session->client->root->nfsminorvers,
  694. +        argops, resops, "secinfo_no_name");
  695.  
  696.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  697.      nfs41_session_sequence(&sequence_args, session, 0);
  698. @@ -1986,7 +2017,8 @@ enum nfsstat4 nfs41_free_stateid(
  699.      nfs41_free_stateid_args freestateid_args;
  700.      nfs41_free_stateid_res freestateid_res;
  701.  
  702. -    compound_init(&compound, argops, resops, "free_stateid");
  703. +    compound_init(&compound, session->client->root->nfsminorvers,
  704. +        argops, resops, "free_stateid");
  705.  
  706.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  707.      nfs41_session_sequence(&sequence_args, session, 0);
  708. @@ -2018,7 +2050,8 @@ enum nfsstat4 nfs41_test_stateid(
  709.      nfs41_test_stateid_args teststateid_args;
  710.      nfs41_test_stateid_res teststateid_res;
  711.  
  712. -    compound_init(&compound, argops, resops, "test_stateid");
  713. +    compound_init(&compound, session->client->root->nfsminorvers,
  714. +        argops, resops, "test_stateid");
  715.  
  716.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  717.      nfs41_session_sequence(&sequence_args, session, 0);
  718. @@ -2061,7 +2094,8 @@ enum nfsstat4 pnfs_rpc_layoutget(
  719.      uint32_t i;
  720.      struct list_entry *entry;
  721.  
  722. -    compound_init(&compound, argops, resops, "layoutget");
  723. +    compound_init(&compound, session->client->root->nfsminorvers,
  724. +        argops, resops, "layoutget");
  725.  
  726.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  727.      nfs41_session_sequence(&sequence_args, session, 0);
  728. @@ -2128,7 +2162,8 @@ enum nfsstat4 pnfs_rpc_layoutcommit(
  729.  
  730.      nfs41_superblock_getattr_mask(file->fh.superblock, &attr_request);
  731.  
  732. -    compound_init(&compound, argops, resops, "layoutcommit");
  733. +    compound_init(&compound, session->client->root->nfsminorvers,
  734. +        argops, resops, "layoutcommit");
  735.  
  736.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  737.      nfs41_session_sequence(&sequence_args, session, 0);
  738. @@ -2184,7 +2219,8 @@ enum nfsstat4 pnfs_rpc_layoutreturn(
  739.      nfs41_putfh_res putfh_res;
  740.      pnfs_layoutreturn_args layoutreturn_args;
  741.  
  742. -    compound_init(&compound, argops, resops, "layoutreturn");
  743. +    compound_init(&compound, session->client->root->nfsminorvers,
  744. +        argops, resops, "layoutreturn");
  745.  
  746.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  747.      nfs41_session_sequence(&sequence_args, session, 0);
  748. @@ -2225,7 +2261,8 @@ enum nfsstat4 pnfs_rpc_getdeviceinfo(
  749.      pnfs_getdeviceinfo_args getdeviceinfo_args;
  750.      pnfs_getdeviceinfo_res getdeviceinfo_res;
  751.  
  752. -    compound_init(&compound, argops, resops, "get_deviceinfo");
  753. +    compound_init(&compound, session->client->root->nfsminorvers,
  754. +        argops, resops, "get_deviceinfo");
  755.  
  756.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  757.      nfs41_session_sequence(&sequence_args, session, 0);
  758. @@ -2265,7 +2302,8 @@ enum nfsstat4 nfs41_rpc_openattr(
  759.      nfs41_openattr_res openattr_res;
  760.      nfs41_getfh_res getfh_res;
  761.  
  762. -    compound_init(&compound, argops, resops, "openattr");
  763. +    compound_init(&compound, session->client->root->nfsminorvers,
  764. +        argops, resops, "openattr");
  765.  
  766.      compound_add_op(&compound, OP_SEQUENCE, &sequence_args, &sequence_res);
  767.      nfs41_session_sequence(&sequence_args, session, 0);
  768. diff --git a/daemon/nfs41_ops.h b/daemon/nfs41_ops.h
  769. index 8ac81a3..d95e6b3 100644
  770. --- a/daemon/nfs41_ops.h
  771. +++ b/daemon/nfs41_ops.h
  772. @@ -1001,6 +1001,7 @@ typedef struct __pnfs_getdeviceinfo_res {
  773.  /* nfs41_ops.c */
  774.  int nfs41_exchange_id(
  775.      IN nfs41_rpc_clnt *rpc,
  776. +    IN int nfsminorvers,
  777.      IN client_owner4 *owner,
  778.      IN uint32_t flags_in,
  779.      OUT nfs41_exchange_id_res *res_out);
  780. diff --git a/daemon/readdir.c b/daemon/readdir.c
  781. index a02b70a..39b50fb 100644
  782. --- a/daemon/readdir.c
  783. +++ b/daemon/readdir.c
  784. @@ -767,6 +767,13 @@ fetch_entries:
  785.          nfs41_readdir_entry *entry = (nfs41_readdir_entry*)entry_buf;
  786.          entry->cookie = 0;
  787.          entry->name_len = (uint32_t)strlen(args->filter) + 1;
  788. +        if (entry->name_len >= NFS41_MAX_COMPONENT_LEN) {
  789. +            DPRINTF(1,
  790. +                ("entry->name_len(=%d) >= NFS41_MAX_COMPONENT_LEN\n",
  791. +                (int)entry->name_len));
  792. +            status = ERROR_FILENAME_EXCED_RANGE;
  793. +            goto out_free_cookie;
  794. +        }
  795.          StringCbCopyA(entry->name, entry->name_len, args->filter);
  796.          entry->next_entry_offset = 0;
  797.  
  798. diff --git a/daemon/upcall.h b/daemon/upcall.h
  799. index f6ac12d..5f44ede 100644
  800. --- a/daemon/upcall.h
  801. +++ b/daemon/upcall.h
  802. @@ -37,6 +37,7 @@ typedef struct __mount_upcall_args {
  803.      DWORD       rsize;
  804.      DWORD       wsize;
  805.      DWORD       use_nfspubfh;
  806. +    DWORD       nfsvers;
  807.      DWORD       lease_time;
  808.      FILE_FS_ATTRIBUTE_INFORMATION FsAttrs;
  809.  } mount_upcall_args;
  810. diff --git a/mount/mount.c b/mount/mount.c
  811. index c9b5637..2ebf8e5 100644
  812. --- a/mount/mount.c
  813. +++ b/mount/mount.c
  814. @@ -129,6 +129,9 @@ void PrintMountUsage(LPWSTR pProcess)
  815.          "\tro\tmount as read-only\n"
  816.          "\trw\tmount as read-write (default)\n"
  817.          "\tport=#\tTCP port to use (defaults to 2049)\n"
  818. +        "\tvers=#\tNFS protocol version, either 4.1 or 4.2\n"
  819. +            "\t\tIf this option is not specified, the client negotiates a\n"
  820. +            "\t\tsuitable version with the server, trying version 4.2 and then 4.1\n"
  821.          "\trsize=#\tread buffer size in bytes\n"
  822.          "\twsize=#\twrite buffer size in bytes\n"
  823.          "\tsec=sys:krb5:krb5i:krb5p\tspecify (gss) security flavor\n"
  824. diff --git a/sys/nfs41_driver.h b/sys/nfs41_driver.h
  825. index c08e8fb..7d933f0 100644
  826. --- a/sys/nfs41_driver.h
  827. +++ b/sys/nfs41_driver.h
  828. @@ -104,4 +104,12 @@ typedef enum _nfs41_start_driver_state {
  829.     NFS41_START_DRIVER_STARTED,
  830.     NFS41_START_DRIVER_STOPPED
  831.  } nfs41_start_driver_state;
  832. +
  833. +#define NFS_VERSION_AUTONEGOTIATION (0xFFFF)
  834. +
  835. +/*
  836. + * Error/Status codes
  837. + */
  838. +#define ERROR_NFS_VERSION_MISMATCH ERROR_REMOTE_FILE_VERSION_MISMATCH
  839. +#define STATUS_NFS_VERSION_MISMATCH STATUS_REMOTE_FILE_VERSION_MISMATCH
  840.  #endif
  841. diff --git a/sys/nfs41sys_driver.h b/sys/nfs41sys_driver.h
  842. index 0e0107c..79ef82c 100644
  843. --- a/sys/nfs41sys_driver.h
  844. +++ b/sys/nfs41sys_driver.h
  845. @@ -208,6 +208,7 @@ typedef struct _updowncall_entry {
  846.              DWORD wsize;
  847.              DWORD lease_time;
  848.              DWORD use_nfspubfh;
  849. +            DWORD nfsvers;
  850.          } Mount;
  851.          struct {
  852.              PMDL MdlAddress;
  853. @@ -308,6 +309,7 @@ typedef struct _NFS41_MOUNT_CREATEMODE {
  854.  
  855.  typedef struct _NFS41_MOUNT_CONFIG {
  856.      BOOLEAN use_nfspubfh;
  857. +    DWORD nfsvers;
  858.      DWORD ReadSize;
  859.      DWORD WriteSize;
  860.      BOOLEAN ReadOnly;
  861. @@ -415,6 +417,7 @@ typedef struct _NFS41_V_NET_ROOT_EXTENSION {
  862.      NFS41_MOUNT_CREATEMODE  dir_createmode;
  863.      NFS41_MOUNT_CREATEMODE  file_createmode;
  864.      USHORT                  MountPathLen;
  865. +    DWORD                   nfsvers;
  866.      BOOLEAN                 read_only;
  867.      BOOLEAN                 write_thru;
  868.      BOOLEAN                 nocache;
  869. diff --git a/sys/nfs41sys_mount.c b/sys/nfs41sys_mount.c
  870. index 8cc45f4..93a6d34 100644
  871. --- a/sys/nfs41sys_mount.c
  872. +++ b/sys/nfs41sys_mount.c
  873. @@ -112,7 +112,7 @@ NTSTATUS marshal_nfs41_mount(
  874.          goto out;
  875.      }
  876.      header_len = *len + length_as_utf8(entry->u.Mount.srv_name) +
  877. -        length_as_utf8(entry->u.Mount.root) + 4 * sizeof(DWORD);
  878. +        length_as_utf8(entry->u.Mount.root) + 5 * sizeof(DWORD);
  879.      if (header_len > buf_len) {
  880.          status = STATUS_INSUFFICIENT_RESOURCES;
  881.          goto out;
  882. @@ -128,16 +128,20 @@ NTSTATUS marshal_nfs41_mount(
  883.      RtlCopyMemory(tmp, &entry->u.Mount.wsize, sizeof(DWORD));
  884.      tmp += sizeof(DWORD);
  885.      RtlCopyMemory(tmp, &entry->u.Mount.use_nfspubfh, sizeof(DWORD));
  886. +    tmp += sizeof(DWORD);
  887. +    RtlCopyMemory(tmp, &entry->u.Mount.nfsvers, sizeof(DWORD));
  888.  
  889.      *len = header_len;
  890.  
  891.  #ifdef DEBUG_MARSHAL_DETAIL
  892.      DbgP("marshal_nfs41_mount: server name='%wZ' mount point='%wZ' "
  893. -         "sec_flavor='%s' rsize=%d wsize=%d use_nfspubfh=%d\n",
  894. +         "sec_flavor='%s' rsize=%d wsize=%d use_nfspubfh=%d "
  895. +         "nfsvers=%d\n",
  896.          entry->u.Mount.srv_name, entry->u.Mount.root,
  897.           secflavorop2name(entry->u.Mount.sec_flavor),
  898.           (int)entry->u.Mount.rsize, (int)entry->u.Mount.wsize,
  899. -         (int)entry->u.Mount.use_nfspubfh);
  900. +         (int)entry->u.Mount.use_nfspubfh,
  901. +         (int)entry->u.Mount.nfsvers);
  902.  #endif
  903.  out:
  904.      return status;
  905. @@ -227,6 +231,7 @@ NTSTATUS map_mount_errors(
  906.      case ERROR_BAD_NET_NAME:    return STATUS_BAD_NETWORK_NAME;
  907.      case ERROR_BAD_NETPATH:     return STATUS_BAD_NETWORK_PATH;
  908.      case ERROR_NOT_SUPPORTED:   return STATUS_NOT_SUPPORTED;
  909. +    case ERROR_NFS_VERSION_MISMATCH: return STATUS_NFS_VERSION_MISMATCH;
  910.      case ERROR_INTERNAL_ERROR:  return STATUS_INTERNAL_ERROR;
  911.      default:
  912.          print_error("map_mount_errors: "
  913. @@ -261,6 +266,7 @@ NTSTATUS nfs41_mount(
  914.      entry->u.Mount.rsize = config->ReadSize;
  915.      entry->u.Mount.wsize = config->WriteSize;
  916.      entry->u.Mount.use_nfspubfh = config->use_nfspubfh;
  917. +    entry->u.Mount.nfsvers = config->nfsvers;
  918.      entry->u.Mount.sec_flavor = sec_flavor;
  919.      entry->u.Mount.FsAttrs = FsAttrs;
  920.  
  921. @@ -295,6 +301,7 @@ void nfs41_MountConfig_InitDefaults(
  922.      Config->ReadSize = MOUNT_CONFIG_RW_SIZE_DEFAULT;
  923.      Config->WriteSize = MOUNT_CONFIG_RW_SIZE_DEFAULT;
  924.      Config->use_nfspubfh = FALSE;
  925. +    Config->nfsvers = NFS_VERSION_AUTONEGOTIATION;
  926.      Config->ReadOnly = FALSE;
  927.      Config->write_thru = FALSE;
  928.      Config->nocache = FALSE;
  929. @@ -484,6 +491,16 @@ NTSTATUS nfs41_MountConfig_ParseOptions(
  930.                  &Config->WriteSize, MOUNT_CONFIG_RW_SIZE_MIN,
  931.                  MOUNT_CONFIG_RW_SIZE_MAX);
  932.          }
  933. +        else if (wcsncmp(L"vers", Name, NameLen) == 0) {
  934. +            if (wcsncmp(L"4.2", usValue.Buffer, usValue.Length) == 0)
  935. +                Config->nfsvers = 42;
  936. +            else if (wcsncmp(L"4.1", usValue.Buffer, usValue.Length) == 0)
  937. +                Config->nfsvers = 41;
  938. +            else {
  939. +                status = STATUS_INVALID_PARAMETER;
  940. +                print_error("Invalid vers= string\n");
  941. +            }
  942. +        }
  943.          else if (wcsncmp(L"public", Name, NameLen) == 0) {
  944.              /*
  945.               + We ignore this value here, and instead rely on the
  946. @@ -874,6 +891,8 @@ NTSTATUS nfs41_CreateVNetRoot(
  947.              DbgP("nfs41_MountConfig_ParseOptions() failed\n");
  948.              goto out_free;
  949.          }
  950. +
  951. +        pVNetRootContext->nfsvers = Config->nfsvers;
  952.          pVNetRootContext->read_only = Config->ReadOnly;
  953.          pVNetRootContext->write_thru = Config->write_thru;
  954.          pVNetRootContext->nocache = Config->nocache;
  955. @@ -996,6 +1015,7 @@ NTSTATUS nfs41_CreateVNetRoot(
  956.              goto out_free;
  957.          }
  958.  
  959. +        pVNetRootContext->nfsvers = Config->nfsvers;
  960.          pVNetRootContext->read_only = Config->ReadOnly;
  961.          pVNetRootContext->write_thru = Config->write_thru;
  962.          pVNetRootContext->nocache = Config->nocache;
  963. @@ -1008,6 +1028,7 @@ NTSTATUS nfs41_CreateVNetRoot(
  964.          "MntPt='%wZ', "
  965.          "SrvName='%wZ', "
  966.          "usenfspubfh=%d, "
  967. +        "nfsvers=%d, "
  968.          "ro=%d, "
  969.          "writethru=%d, "
  970.          "nocache=%d "
  971. @@ -1019,6 +1040,7 @@ NTSTATUS nfs41_CreateVNetRoot(
  972.          &Config->MntPt,
  973.          &Config->SrvName,
  974.          Config->use_nfspubfh?1:0,
  975. +        (int)Config->nfsvers,
  976.          Config->ReadOnly?1:0,
  977.          Config->write_thru?1:0,
  978.          Config->nocache?1:0,

Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at