1. 23 Jun, 2022 1 commit
  2. 17 Jun, 2022 1 commit
    • Rick Macklem's avatar
      nfscl: Clean up the code by removing unused arguments · 3c4266ed
      Rick Macklem authored
      The "void *stuff" (also called fstuff and dstuff) argument
      was used by the Mac OSX port.  For FreeBSD, this argument
      is always NULL, so remove it to clean up the code.
      
      This commit gets rid of "stuff" for assorted functions
      defined in nfs_clrpcops.c and called in nfs_clvnops.c and
      nfs_clstate.c.
      
      This commit should not result in a semantics change.
      3c4266ed
  3. 02 Jun, 2022 1 commit
    • Rick Macklem's avatar
      nfscl: Do not flush when a write delegation is held · 56b64e28
      Rick Macklem authored
      When a NFSv4 byte range write lock is unlocked, all
      data modifications need to be flushed to the server
      to satisfy the coherency requirements for byte range
      locking.  However, if a write delegation for the
      file is held by the client, flushing is not required,
      since no other NFSv4 client can have the file NFSv4
      Opened.
      
      Found by inspection as suggested by a similar change
      that was done to the Linux NFSv4 client.
      56b64e28
  4. 27 May, 2022 1 commit
    • Rick Macklem's avatar
      nfscl: Do not handle NFSERR_BADSESSION in operation code · 425e5c73
      Rick Macklem authored
      The NFSERR_BADSESSION reply from a NFSv4.1/4.2 server
      is handled by newnfs_request().  It should not be handled
      separately after newnfs_request() has returned.
      
      These two cases were spotted during code inspection.
      One of them should only redo what newnfs_request() already
      did by the same "nfscl" thread.  The other might have
      resulted in recovery being done twice, but the code is
      only used for "pnfs" mounts, so that would be rare.
      Also, since NFSERR_BADSESSION should only be replied by
      a server after the server reboots, this would be extremely
      rare.
      
      MFC after: 	2 weeks
      425e5c73
  5. 25 Feb, 2022 1 commit
    • Rick Macklem's avatar
      nfscl: Fix a use after free in nfscl_cleanupkext() · 1cedb4ea
      Rick Macklem authored
      ler@, markj@ reported a use after free in nfscl_cleanupkext().
      They also provided two possible causes:
      - In nfscl_cleanup_common(), "own" is the owner string
        owp->nfsow_owner.  If we free that particular
        owner structure, than in subsequent comparisons
        "own" will point to freed memory.
      - nfscl_cleanup_common() can free more than one owner, so the use
        of LIST_FOREACH_SAFE() in nfscl_cleanupkext() is not sufficient.
      
      I also believe there is a 3rd:
      - If nfscl_freeopenowner() or nfscl_freelockowner() is called
        without the NFSCLSTATE mutex held, this could race with
        nfscl_cleanupkext().
        This could happen when the exclusive lock is held
        on the client, such as when delegations are being returned
        or when recovering from NFSERR_EXPIRED.
      
      This patch fixes them as follows:
      1 - Copy the owner string to a local variable before the
          nfscl_cleanup_common() call.
      2 - Modify nfscl_cleanup_common() so that it will never free more
          than the first matching element.  Normally there should only
          be one element in each list with a matching open/lock owner
          anyhow (but there might be a bug that results in a duplicate).
          This should guarantee that the FOREACH_SAFE loops in
          nfscl_cleanupkext() are adequate.
      3 - Acquire the NFSCLSTATE mutex in nfscl_freeopenowner()
          and nfscl_freelockowner(), if it is not already held.
          This serializes all of these calls with the ones done in
          nfscl_cleanup_common().
      
      Reported by:	ler
      Reviewed by:	markj
      Tested by:	cy
      MFC after:	1 week
      Differential Revision:	https://reviews.freebsd.org/D34334
      1cedb4ea
  6. 24 Feb, 2022 1 commit
  7. 22 Feb, 2022 1 commit
    • Rick Macklem's avatar
      nfscl: Fix a use after free in nfscl_cleanupkext() · dd08b84e
      Rick Macklem authored
      ler@, markj@ reported a use after free in nfscl_cleanupkext().
      They also provided two possible causes:
      - In nfscl_cleanup_common(), "own" is the owner string
        owp->nfsow_owner.  If we free that particular
        owner structure, than in subsequent comparisons
        "own" will point to freed memory.
      - nfscl_cleanup_common() can free more than one owner, so the use
        of LIST_FOREACH_SAFE() in nfscl_cleanupkext() is not sufficient.
      
      I also believe there is a 3rd:
      - If nfscl_freeopenowner() or nfscl_freelockowner() is called
        without the NFSCLSTATE mutex held, this could race with
        nfscl_cleanupkext().
        This could happen when the exclusive lock is held
        on the client, such as when delegations are being returned.
      
      This patch fixes them as follows:
      1 - Copy the owner string to a local variable before the
          nfscl_cleanup_common() call.
      2 - Modify nfscl_cleanup_common() to return whether or not a
          free was done.
          When a free was done, do a goto to restart the loop, instead
          of using FOREACH_SAFE, which was not safe in this case.
      3 - Acquire the NFSCLSTATE mutex in nfscl_freeopenowner()
          and nfscl_freelockowner(), if it not already held.
          This serializes all of these calls with the ones done in
          nfscl_cleanup_common().
      
      Reported by:	ler
      Reviewed by:	markj
      MFC after:	1 week
      Differential Revision:	https://reviews.freebsd.org/D34334
      dd08b84e
  8. 16 Dec, 2021 1 commit
    • Rick Macklem's avatar
      nfscl: Handle CB_SEQUENCE not first op correctly · e0861304
      Rick Macklem authored
      The check for "not first operation" in CB_SEQUENCE
      was done after the slot, etc. was updated. This patch
      moves the check to the beginning of CB_SEQUENCE
      processing.
      
      While here, also fix the check for "no CB_SEQUENCE operation first"
      by moving the check to the beginning of callback operation parsing,
      since the check was in a couple of the other operations, but
      not all of them.
      
      Reported by:	rtm@lcs.mit.edu
      Tested by:	rtm@lcs.mit.edu
      PR:	260412
      MFC after:	2 weeks
      e0861304
  9. 09 Dec, 2021 1 commit
    • Rick Macklem's avatar
      nfscl: Sanity check the callback tag length · d9931c25
      Rick Macklem authored
      The sanity check for tag length in a callback request
      was broken in two ways:
      
      It checked for a negative value, but not a large positive
      value.
      
      It did not set taglen to -1, to indicate to the code that
      it should not be used.
      
      This patch fixes both of these issues.
      
      Reported by:	rtm@lcs.mit.edu
      Tested by:	rtm@lcs.mit.edu
      PR:	260266
      MFC after:	2 weeks
      d9931c25
  10. 13 Nov, 2021 1 commit
    • Rick Macklem's avatar
      pNFS: Add nfsstats counters for number of Layouts · ce9676de
      Rick Macklem authored
      For pNFS, Layouts are issued by the server to indicate
      where a file's data resides on the DS(s).  This patch
      adds counters for how many layouts are allocated to
      the nfsstatsv1 structure, using two reserved fields.
      
      MFC after:	2 weeks
      ce9676de
  11. 05 Nov, 2021 1 commit
    • Rick Macklem's avatar
      nfscl: Fix two more cases for forced dismount · f5d5164f
      Rick Macklem authored
      Although I was not able to cause a failure during testing, there
      are places in nfscl_removedeleg() and nfscl_renamedeleg() where
      I think a forced dismount could get hung.  This patch fixes those.
      
      This patch only affects forced dismount and only if the NFSv4
      server is issuing delegations to the client.
      
      Found by code inspection.
      
      MFC after:	2 weeks
      f5d5164f
  12. 03 Nov, 2021 2 commits
    • Rick Macklem's avatar
      nfscl: Fix use after free for forced dismount · 44122258
      Rick Macklem authored
      When a forced dismount is done and delegations are being
      issued by the server (disabled by default for FreeBSD
      servers), the delegation structure is free'd before the
      loop calling vflush().  This could result in a use after
      free of the delegation structure.
      
      This patch changes the code so that the delegation
      structures are not free'd until after the vflush()
      loop for forced dismounts.
      
      Found during a recent IETF NFSv4 working group testing event.
      
      MFC after:	2 weeks
      44122258
    • Rick Macklem's avatar
      nfscl: Check for a forced dismount in nfscl_getref() · 331883a2
      Rick Macklem authored
      The nfscl_getref() function is called within nfscl_doiods() when
      the NFSv4.1/4.2 pNFS client is doing I/O on a DS.  As such,
      nfscl_getref() needs to check for a forced dismount.
      This patch adds that check.
      
      Found during a recent IETF NFSv4 working group testing event.
      
      MFC after:	2 weeks
      331883a2
  13. 31 Oct, 2021 1 commit
    • Rick Macklem's avatar
      nfscl: Do pNFS layout return_on_close synchronously · d5d2ce1c
      Rick Macklem authored
      For pNFS servers that specify that Layouts are to be returned
      upon close, they may expect that LayoutReturn to happen before
      the associated Close.
      
      This patch modifies the NFSv4.1/4.2 pNFS client so that this
      is done.  This only affects a pNFS mount against a non-FreeBSD
      NFSv4.1/4.2 server that specifies return_on_close in LayoutGet
      replies.
      
      Found during a recent IETF NFSv4 working group testing event.
      
      MFC after:	2 weeks
      d5d2ce1c
  14. 30 Oct, 2021 1 commit
    • Rick Macklem's avatar
      nfscl: Use NFSMNTP_DELEGISSUED in two more functions · dc6dd769
      Rick Macklem authored
      Commit 5e5ca4c8 added a NFSMNTP_DELEGISSUED flag to indicate when
      a delegation has been issued to the mount.  For the common case
      where an NFSv4 server is not issuing delegations, this flag
      can be checked to avoid acquisition of the NFSCLSTATEMUTEX.
      
      This patch adds checks for NFSMNTP_DELEGISSUED being set
      to two more functions.
      
      This change appears to be performance neutral for a small number
      of opens, but should reduce lock contention for a large number of opens
      for the common case where server is not issuing delegations.
      
      MFC after:	2 week
      dc6dd769
  15. 18 Oct, 2021 1 commit
    • Rick Macklem's avatar
      nfscl: Handle NFSv4.1/4.2 Close RPC NFSERR_DELAY replies better · 52dee2bc
      Rick Macklem authored
      Without this patch, if a NFSv4.1/4.2 server replies NFSERR_DELAY to
      a Close operation, the client loops retrying the Close while holding
      a shared lock on the clientID.  This shared lock blocks returns of
      delegations, even though the server has issued a CB_RECALL to request
      the delegation return.
      
      This patch delays doing a retry of a Close that received a reply of
      NFSERR_DELAY until after the shared lock on the clientID is released,
      for NFSv4.1/4.2.  To fix this for NFSv4.0 would be very difficult and
      since the only known NFSv4 server to reply NFSERR_DELAY to Close only
      does NFSv4.1/4.2, this fix is hoped to be sufficient.
      
      This problem was detected during a recent IETF working group NFSv4
      testing event.
      
      MFC after:	2 week
      52dee2bc
  16. 16 Oct, 2021 1 commit
    • Rick Macklem's avatar
      nfscl: Move release of the clientID lock into nfscl_doclose() · e2aab5e2
      Rick Macklem authored
      This patch moves release of the shared clientID lock from nfsrpc_close()
      just after the nfscl_doclose() call to the end of nfscl_doclose() call.
      This does make the code cleaner, since the shared lock is acquired at
      the beginning of nfscl_doclose().  The only semantics change is that
      the code no longer drops and reaquires the NFSCLSTATELOCK() mutex,
      which I do not believe will have a negative effect on the NFSv4 client.
      
      This is being done to prepare the code for a future patch that fixes
      the case where an NFSv4.1/4.2 server replies NFSERR_DELAY to a Close
      operation.
      
      MFC after:	2 week
      e2aab5e2
  17. 15 Oct, 2021 2 commits
    • Rick Macklem's avatar
      nfscl: Add an argument to nfscl_tryclose() · 77c595ce
      Rick Macklem authored
      This patch adds a new argument to nfscl_tryclose() to indicate
      whether or not it should loop when a NFSERR_DELAY reply is received
      from the NFSv4 server.  Since this new argument is always passed in
      as "true" at this time, no semantics change should occur.
      
      This is being done to prepare the code for a future patch that fixes
      the case where an NFSv4.1/4.2 server replies NFSERR_DELAY to a Close
      operation.
      
      MFC after:	2 week
      77c595ce
    • Rick Macklem's avatar
      nfscl: Restructure nfscl_freeopen() slightly · 6495766a
      Rick Macklem authored
      This patch factors the unlinking of the nfsclopen structure out of
      nfscl_freeopen() into a separate function called nfscl_unlinkopen().
      It also adds a new argument to nfscl_freeopen() to conditionally do
      the unlink.  Since this new argument is always passed in as "true"
      at this time, no semantics change should occur.
      
      This is being done to prepare the code for a future patch that fixes
      the case where an NFSv4.1/4.2 server replies NFSERR_DELAY to a Close
      operation.
      
      MFC after:	2 week
      6495766a
  18. 13 Oct, 2021 2 commits
    • Rick Macklem's avatar
      nfscl: Make nfscl_getlayout() acquire the correct pNFS layout · 24af0fcd
      Rick Macklem authored
      Without this patch, if a pNFS read layout has already been acquired
      for a file, writes would be redirected to the Metadata Server (MDS),
      because nfscl_getlayout() would not acquire a read/write layout for
      the file.  This happened because there was no "mode" argument to
      nfscl_getlayout() to indicate whether reading or writing was being done.
      Since doing I/O through the Metadata Server is not encouraged for some
      pNFS servers, it is preferable to get a read/write layout for writes
      instead of redirecting the write to the MDS.
      
      This patch adds a access mode argument to nfscl_getlayout() and
      nfsrpc_getlayout(), so that nfscl_getlayout() knows to acquire a read/write
      layout for writing, even if a read layout has already been acquired.
      This patch only affects NFSv4.1/4.2 client behaviour when pNFS ("pnfs" mount
      option against a server that supports pNFS) is in use.
      
      This problem was detected during a recent NFSv4 interoperability
      testing event held by the IETF working group.
      
      MFC after:	2 week
      24af0fcd
    • Rick Macklem's avatar
      nfscl: Fix another deadlock related to the NFSv4 clientID lock · b82168e6
      Rick Macklem authored
      Without this patch, it is possible to hang the NFSv4 client,
      when a rename/remove is being done on a file where the client
      holds a delegation, if pNFS is being used.  For a delegation
      to be returned, dirty data blocks must be flushed to the NFSv4
      server.  When pNFS is in use, a shared lock on the clientID
      must be acquired while doing a write to the DS(s).
      However, if rename/remove is doing the delegation return
      an exclusive lock will be acquired on the clientID, preventing
      the write to the DS(s) from acquiring a shared lock on the clientID.
      
      This patch stops rename/remove from doing a delegation return
      if pNFS is enabled.  Since doing delegation return in the same
      compound as rename/remove is only an optimization, not doing
      so should not cause problems.
      
      This problem was detected during a recent NFSv4 interoperability
      testing event held by the IETF working group.
      
      MFC after:	1 week
      b82168e6
  19. 12 Oct, 2021 1 commit
    • Rick Macklem's avatar
      nfscl: Fix a deadlock related to the NFSv4 clientID lock · 120b20bd
      Rick Macklem authored
      Without this patch, it is possible for a process doing an NFSv4
      Open/create of a file to block to allow another process
      to acquire the exclusive lock on the clientID when holding
      a shared lock on the clientID.  As such, both processes
      deadlock, with one wanting the exclusive lock, while the
      other holds the shared lock.  This deadlock is unlikely to occur
      unless delegations are in use on the NFSv4 mount.
      
      This patch fixes the problem by not deferring to the process
      waiting for the exclusive lock when a shared lock (reference cnt)
      is already held by the process.
      
      This problem was detected during a recent NFSv4 interoperability
      testing event held by the IETF working group.
      
      MFC after:	1 week
      120b20bd
  20. 27 Sep, 2021 1 commit
    • Rick Macklem's avatar
      nfscl: Add a check for "has acquired a delegation" to nfscl_removedeleg() · 62c5be4a
      Rick Macklem authored
      Commit 5e5ca4c8 added a flag to a NFSv4 mount point that is set when
      the first delegation is acquired from the NFSv4 server.
      
      For a common case where delegations are not being issued by the
      NFSv4 server, the nfscl_removedeleg() code acquires the mutex lock for
      open/lock state, finds the delegation list empty, then just unlocks the
      mutex and returns. This patch adds a check of the flag to avoid the
      need to acquire the mutex for this common case.
      
      This change appears to be performance neutral for a small number
      of opens, but should reduce lock contention for a large number of opens
      for the common case where server is not issuing delegations.
      
      This commit should not affect the high level semantics of delegation
      handling.
      
      MFC after:      2 weeks
      62c5be4a
  21. 12 Aug, 2021 1 commit
    • Rick Macklem's avatar
      nfscl: Add a Lookup+Open RPC for NFSv4.1/4.2 · 3ad1e1c1
      Rick Macklem authored
      This patch adds a Lookup+Open compound RPC to the NFSv4.1/4.2
      NFS client, which can be used by nfs_lookup() so that a
      subsequent Open RPC is not required.
      It uses the cn_flags OPENREAD, OPENWRITE added by commit c18c74a8.
      This reduced the number of RPCs by about 15% for a kernel
      build over NFS.
      
      For now, use of Lookup+Open is only done when the "oneopenown"
      mount option is used.  It may be possible for Lookup+Open to
      be used for non-oneopenown NFSv4.1/4.2 mounts, but that will
      require extensive further testing to determine if it works.
      
      While here, I've added the changes to the nfscommon module
      that are needed to implement the Deallocate NFSv4.2 operation.
      This avoids needing another cycle of changes to the internal
      KAPI between the NFS modules.
      
      This commit has changed the internal KAPI between the NFS
      modules and, as such, all need to be rebuilt from sources.
      I have not bumped __FreeBSD_version, since it was bumped a
      few days ago.
      3ad1e1c1
  22. 28 Jul, 2021 2 commits
    • Rick Macklem's avatar
      nfscl: Cache an open stateid for the "oneopenown" mount option · efea1bc1
      Rick Macklem authored
      For NFSv4.1/4.2, if the "oneopenown" mount option is used,
      there is, at most, only one open stateid for each NFS vnode.
      When an open stateid for a file is acquired, set a pointer to
      the open structure in the NFS vnode.  This pointer can be used to
      acquire the open stateid without searching the open linked list
      when the following is true:
      - No delegations have been issued for the file.  Since delegations
        can outlive an NFS vnode for a file, use the global
        NFSMNTP_DELEGISSUED flag on the mount to determine this.
      - No lock stateid has been issued for the file.  To determine
        this, a new NFS vnode flag called NMIGHTBELOCKED is set when a lock
        stateid is issued, which can then be tested.
      
      When this open structure pointer can be used, it avoids the need to
      acquire the NFSCLSTATELOCK() and searching the open structure list for
      an open.  The NFSCLSTATELOCK() can be highly contended when there are
      a lot of opens issued for the NFSv4.1/4.2 mount.
      
      This patch only affects NFSv4.1/4.2 mounts when the "oneopenown"
      mount option is used.
      
      MFC after:	2 weeks
      efea1bc1
    • Rick Macklem's avatar
      nfscl: Set correct lockowner for "oneopenown" mount option · 54ff3b39
      Rick Macklem authored
      For NFSv4.1/4.2, the client may use either an open, lock or
      delegation stateid as the stateid argument for an I/O operation.
      RFC 5661 defines an order of preference of delegation, then lock
      and finally open stateid for the argument, although NFSv4.1/4.2
      servers are expected to handle any stateid type.
      
      For the "oneopenown" mount option, the lock owner was not being
      correctly generated and, as such, the I/O operation would use an
      open stateid, even when a lock stateid existed.  Although this
      did not and should not affect an NFSv4.1/4.2 server's behaviour,
      this patch makes the behaviour for "oneopenown" the same as when
      the mount option is not specified.
      
      Found during inspection of packet captures.  No failure during
      testing against NFSv4.1/4.2 servers of the unpatched code occurred.
      
      MFC after:	2 weeks
      54ff3b39
  23. 20 Jul, 2021 1 commit
    • Rick Macklem's avatar
      nfscl: Send stateid.seqid of 0 for NFSv4.1/4.2 mounts · 7685f834
      Rick Macklem authored
      For NFSv4.1/4.2, the client may set the "seqid" field of the
      stateid to 0 in RPC requests.  This indicates to the server that
      it should not check the "seqid" or return NFSERR_OLDSTATEID if the
      "seqid" value is not up to date w.r.t. Open/Lock operations
      on the stateid.  This "seqid" is incremented by the NFSv4 server
      for each Open/OpenDowngrade/Lock/Locku operation done on the stateid.
      
      Since a failure return of NFSERR_OLDSTATEID is of no use to
      the client for I/O operations, it makes sense to set "seqid"
      to 0 for the stateid argument for I/O operations.
      This avoids server failure replies of NFSERR_OLDSTATEID,
      although I am not aware of any case where this failure occurs.
      
      This makes the FreeBSD NFSv4.1/4.2 client compatible with the
      Linux NFSv4.1/4.2 client.
      
      MFC after:	2 weeks
      7685f834
  24. 25 Jun, 2021 1 commit
    • Rick Macklem's avatar
      nfscl: Change the default minor version for NFSv4 mounts · a145cf3f
      Rick Macklem authored
      When NFSv4.1 support was added to the client, the implementation was
      still experimental and, as such, the default minor version was set to 0.
      Since the NFSv4.1 client implementation is now believed to be solid
      and the NFSv4.1/4.2 protocol is significantly better than NFSv4.0,
      I beieve that NFSv4.1/4.2 should be used where possible.
      
      This patch changes the default minor version for NFSv4 to be the highest
      minor version supported by the NFSv4 server. If a specific minor version
      is desired, the "minorversion" mount option can be used to override
      this default.  This is compatible with the Linux NFSv4 client behaviour.
      
      This was discussed on freebsd-current@ in mid-May 2021 under
      the subject "changing the default NFSv4 minor version" and
      the consensus seemed to be support for this change.
      It also appeared that changing this for FreeBSD 13.1 was
      not considered a POLA violation, so long as UPDATING
      and RELNOTES entries were made for it.
      
      MFC after:	2 weeks
      a145cf3f
  25. 16 Jun, 2021 1 commit
    • Rick Macklem's avatar
      nfscl: Make NFSv4.0 client acquisition NFSv4.1/4.2 compatible · aed98fa5
      Rick Macklem authored
      When the NFSv4.0 client was implemented, acquisition of a clientid
      via SetClientID/SetClientIDConfirm was done upon the first Open,
      since that was when it was needed.  NFSv4.1/4.2 acquires the clientid
      during mount (via ExchangeID/CreateSession), since the associated
      session is required during mount.
      
      This patch modifies the NFSv4.0 mount so that it acquires the
      clientid during mount.  This simplifies the code and makes it
      easy to implement "find the highest minor version supported by
      the NFSv4 server", which will be done for the default minorversion
      in a future commit.
      The "start_renewthread" argument for nfscl_getcl() is replaced
      by "tryminvers", which will be used by the aforementioned
      future commit.
      
      MFC after:	2 weeks
      aed98fa5
  26. 09 Jun, 2021 1 commit
    • Rick Macklem's avatar
      nfscl: Add a "has acquired a delegation" flag for delegations · 5e5ca4c8
      Rick Macklem authored
      A problem was reported via email, where a large (130000+) accumulation
      of NFSv4 opens on an NFSv4 mount caused significant lock contention
      on the mutex used to protect the client mount's open/lock state.
      Although the root cause for the accumulation of opens was not
      resolved, it is obvious that the NFSv4 client is not designed to
      handle 100000+ opens efficiently.
      
      For a common case where delegations are not being issued by the
      NFSv4 server, the code acquires the mutex lock for open/lock state,
      finds the delegation list empty and just unlocks the mutex and returns.
      This patch adds an NFS mount point flag that is set when a delegation
      is issued for the mount.  Then the patched code checks for this flag
      before acquiring the open/lock mutex, avoiding the need to acquire
      the lock for the case where delegations are not being issued by the
      NFSv4 server.
      This change appears to be performance neutral for a small number
      of opens, but should reduce lock contention for a large number of opens
      for the common case where server is not issuing delegations.
      
      This commit should not affect the high level semantics of delegation
      handling.
      
      MFC after:      2 weeks
      5e5ca4c8
  27. 28 May, 2021 1 commit
    • Rick Macklem's avatar
      nfscl: Use hash lists to improve expected search performance for opens · 96b40b89
      Rick Macklem authored
      A problem was reported via email, where a large (130000+) accumulation
      of NFSv4 opens on an NFSv4 mount caused significant lock contention
      on the mutex used to protect the client mount's open/lock state.
      Although the root cause for the accumulation of opens was not
      resolved, it is obvious that the NFSv4 client is not designed to
      handle 100000+ opens efficiently.  When searching for an open,
      usually for a match by file handle, a linear search of all opens
      is done.
      
      Commit 3f7e14ad added a hash table of lists hashed on file handle
      for the opens.  This patch uses the hash lists for searching for
      a matching open based of file handle instead of an exhaustive
      linear search of all opens.
      This change appears to be performance neutral for a small number
      of opens, but should improve expected performance for a large
      number of opens.
      
      This commit should not affect the high level semantics of open
      handling.
      
      MFC after:	2 weeks
      96b40b89
  28. 25 May, 2021 1 commit
    • Rick Macklem's avatar
      nfscl: Use hash lists to improve expected search performance for opens · 724072ab
      Rick Macklem authored
      A problem was reported via email, where a large (130000+) accumulation
      of NFSv4 opens on an NFSv4 mount caused significant lock contention
      on the mutex used to protect the client mount's open/lock state.
      Although the root cause for the accumulation of opens was not
      resolved, it is obvious that the NFSv4 client is not designed to
      handle 100000+ opens efficiently.  When searching for an open,
      usually for a match by file handle, a linear search of all opens
      is done.
      
      Commit 3f7e14ad added a hash table of lists hashed on file handle
      for the opens.  This patch uses the hash lists for searching for
      a matching open based of file handle instead of an exhaustive
      linear search of all opens.
      This change appears to be performance neutral for a small number
      of opens, but should improve expected performance for a large
      number of opens.  This patch also moves any found match to the front
      of the hash list, to try and maintain the hash lists in recently
      used ordering (least recently used at the end of the list).
      
      This commit should not affect the high level semantics of open
      handling.
      
      MFC after:	2 weeks
      724072ab
  29. 22 May, 2021 1 commit
    • Rick Macklem's avatar
      nfscl: Add hash lists for the NFSv4 opens · 3f7e14ad
      Rick Macklem authored
      A problem was reported via email, where a large (130000+) accumulation
      of NFSv4 opens on an NFSv4 mount caused significant lock contention
      on the mutex used to protect the client mount's open/lock state.
      Although the root cause for the accumulation of opens was not
      resolved, it is obvious that the NFSv4 client is not designed to
      handle 100000+ opens efficiently.  When searching for an open,
      usually for a match by file handle, a linear search of all opens
      is done.
      
      This patch adds a table of hash lists for the opens, hashed on
      file handle.  This table will be used by future commits to
      search for an open based on file handle more efficiently.
      
      MFC after:	2 weeks
      3f7e14ad
  30. 19 May, 2021 1 commit
    • Rick Macklem's avatar
      nfscl: Fix NFSv4.1/4.2 mount recovery from an expired lease · c28cb257
      Rick Macklem authored
      The most difficult NFSv4 client recovery case happens when the
      lease has expired on the server.  For NFSv4.0, the client will
      receive a NFSERR_EXPIRED reply from the server to indicate this
      has happened.
      For NFSv4.1/4.2, most RPCs have a Sequence operation and, as such,
      the client will receive a NFSERR_BADSESSION reply when the lease
      has expired for these RPCs.  The client will then call nfscl_recover()
      to handle the NFSERR_BADSESSION reply.  However, for the expired lease
      case, the first reclaim Open will fail with NFSERR_NOGRACE.
      
      This patch recognizes this case and calls nfscl_expireclient()
      to handle the recovery from an expired lease.
      
      This patch only affects NFSv4.1/4.2 mounts when the lease
      expires on the server, due to a network partitioning that
      exceeds the lease duration or similar.
      
      MFC after:	2 weeks
      c28cb257
  31. 28 Apr, 2021 1 commit
    • Rick Macklem's avatar
      nfscl: add check for NULL clp and forced dismounts to nfscl_delegreturnvp() · f6fec55f
      Rick Macklem authored
      Commit aad78046 added a function called nfscl_delegreturnvp()
      to return delegations during the NFS VOP_RECLAIM().
      The function erroneously assumed that nm_clp would
      be non-NULL. It will be NULL for NFSV4.0 mounts until
      a regular file is opened. It will also be NULL during
      vflush() in nfs_unmount() for a forced dismount.
      
      This patch adds a check for clp == NULL to fix this.
      
      Also, since it makes no sense to call nfscl_delegreturnvp()
      during a forced dismount, the patch adds a check for that
      case and does not do the call during forced dismounts.
      
      PR:	255436
      Reported by:	ish@amail.plala.or.jp
      MFC after:	2 weeks
      f6fec55f
  32. 26 Apr, 2021 1 commit
    • Rick Macklem's avatar
      nfscl: return delegations in the NFS VOP_RECLAIM() · aad78046
      Rick Macklem authored
      After a vnode is recycled it can no longer be
      acquired via vfs_hash_get() and, as such,
      a delegation for the vnode cannot be recalled.
      
      In the unlikely event that a delegation still
      exists when the vnode is being recycled, return
      the delegation since it will no longer be
      recallable.
      
      Until you have this patch in your NFSv4 client,
      you should consider avoiding the use of delegations.
      
      MFC after:	2 weeks
      aad78046
  33. 25 Apr, 2021 1 commit
    • Rick Macklem's avatar
      nfscl: fix delegation recall when the file is not open · 02695ea8
      Rick Macklem authored
      Without this patch, if a NFSv4 server recalled a
      delegation when the file is not open, the renew
      thread would block in the NFS VOP_INACTIVE()
      trying to acquire the client state lock that it
      already holds.
      
      This patch fixes the problem by delaying the
      vrele() call until after the client state
      lock is released.
      
      This bug has been in the NFSv4 client for
      a long time, but since it only affects
      delegation when recalled due to another
      client opening the file, it got missed
      during previous testing.
      
      Until you have this patch in your client,
      you should avoid the use of delegations.
      
      MFC after:	2 weeks
      02695ea8
  34. 01 Apr, 2021 1 commit
    • Rick Macklem's avatar
      nfsv4 client: factor loop contents out into a separate function · 4e6c2a1e
      Rick Macklem authored
      Commit fdc9b2d5 replaced a couple of while loops with LIST_FOREACH()
      loops.  This patch factors the body of that loop out into a separate
      function called nfscl_checkown().
      This prepares the code for future changes to use a hash table of
      lists for open searches via file handle.
      
      This patch should not result in a semantics change.
      
      MFC after:	2 weeks
      4e6c2a1e
  35. 29 Mar, 2021 2 commits
    • Rick Macklem's avatar
      nfsv4 client: replace while loops with LIST_FOREACH() loops · fdc9b2d5
      Rick Macklem authored
      This patch replaces a couple of while() loops with LIST_FOREACH() loops.
      While here, declare a couple of variables "bool".
      I think LIST_FOREACH() is preferred and makes the code more readable.
      This also prepares the code for future changes to use a hash table of
      lists for open searches via file handle.
      
      This patch should not result in a semantics change.
      
      MFC after:	2 weeks
      fdc9b2d5
    • Rick Macklem's avatar
      nfsv4.1/4.2 client: fix handling of delegations for "oneopenown" mnt option · e61b29ab
      Rick Macklem authored
      If a delegation for a file has been acquired, the "oneopenown" option
      was ignored when the local open was issued. This could result in multiple
      openowners/opens for a file, that would be transferred to the server
      when the delegation was recalled.
      This would not be serious, but could result in more than one openowner.
      Since the Amazon/EFS does not issue delegations, this probably never
      occurs in practice.
      Spotted during code inspection.
      
      This small patch fixes the code so that it checks for "oneopenown"
      when doing client local opens on a delegation.
      
      MFC after:	2 weeks
      e61b29ab