pastebin - collaborative debugging tool
nrubsig.kpaste.net RSS


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