1. 13 Aug, 2022 3 commits
    • Trond Myklebust's avatar
      NFS: Remove a bogus flag setting in pnfs_write_done_resend_to_mds · edf79efc
      Trond Myklebust authored
      Since pnfs_write_done_resend_to_mds() does not actually call
      end_page_writeback() on the pages that are being redirected to the
      metadata server, callers of fsync() do not see the I/O as complete until
      the writeback to the MDS finishes. We therefore do not need to set
      NFS_CONTEXT_RESEND_WRITES, since there is nothing to redrive.
      Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
      edf79efc
    • Trond Myklebust's avatar
      NFS: Fix another fsync() issue after a server reboot · 67f4b5dc
      Trond Myklebust authored
      Currently, when the writeback code detects a server reboot, it redirties
      any pages that were not committed to disk, and it sets the flag
      NFS_CONTEXT_RESEND_WRITES in the nfs_open_context of the file descriptor
      that dirtied the file. While this allows the file descriptor in question
      to redrive its own writes, it violates the fsync() requirement that we
      should be synchronising all writes to disk.
      While the problem is infrequent, we do see corner cases where an
      untimely server reboot causes the fsync() call to abandon its attempt to
      sync data to disk and causing data corruption issues due to missed error
      conditions or similar.
      
      In order to tighted up the client's ability to deal with this situation
      without introducing livelocks, add a counter that records the number of
      times pages are redirtied due to a server reboot-like condition, and use
      that in fsync() to redrive the sync to disk.
      
      Fixes: 2197e9b0 ("NFS: Fix up fsync() when the server rebooted")
      Cc: stable@vger.kernel.org
      Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
      67f4b5dc
    • Sun Ke's avatar
      NFS: Fix missing unlock in nfs_unlink() · 2067231a
      Sun Ke authored
      Add the missing unlock before goto.
      
      Fixes: 3c59366c ("NFS: don't unhash dentry during unlink/rename")
      Signed-off-by: default avatarSun Ke <sunke32@huawei.com>
      Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
      2067231a
  2. 09 Aug, 2022 3 commits
  3. 08 Aug, 2022 1 commit
    • NeilBrown's avatar
      NFS: don't unhash dentry during unlink/rename · 3c59366c
      NeilBrown authored
      NFS unlink() (and rename over existing target) must determine if the
      file is open, and must perform a "silly rename" instead of an unlink (or
      before rename) if it is.  Otherwise the client might hold a file open
      which has been removed on the server.
      
      Consequently if it determines that the file isn't open, it must block
      any subsequent opens until the unlink/rename has been completed on the
      server.
      
      This is currently achieved by unhashing the dentry.  This forces any
      open attempt to the slow-path for lookup which will block on i_rwsem on
      the directory until the unlink/rename completes.  A future patch will
      change the VFS to only get a shared lock on i_rwsem for unlink, so this
      will no longer work.
      
      Instead we introduce an explicit interlock.  A special value is stored
      in dentry->d_fsdata while the unlink/rename is running and
      ->d_revalidate blocks while that value is present.  When ->d_revalidate
      unblocks, the dentry will be invalid.  This closes the race
      without requiring exclusion on i_rwsem.
      
      d_fsdata is already used in two different ways.
      1/ an IS_ROOT directory dentry might have a "devname" stored in
         d_fsdata.  Such a dentry doesn't have a name and so cannot be the
         target of unlink or rename.  For safety we check if an old devname
         is still stored, and remove it if it is.
      2/ a dentry with DCACHE_NFSFS_RENAMED set will have a 'struct
         nfs_unlinkdata' stored in d_fsdata.  While this is set maydelete()
         will fail, so an unlink or rename will never proceed on such
         a dentry.
      
      Neither of these can be in effect when a dentry is the target of unlink
      or rename.  So we can expect d_fsdata to be NULL, and store a special
      value ((void*)1) which is given the name NFS_FSDATA_BLOCKED to indicate
      that any lookup will be blocked.
      
      The d_count() is incremented under d_lock() when a lookup finds the
      dentry, so we check d_count() is low, and set NFS_FSDATA_BLOCKED under
      the same lock to avoid any races.
      Signed-off-by: default avatarNeilBrown <neilb@suse.de>
      Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
      3c59366c
  4. 02 Aug, 2022 2 commits
  5. 27 Jul, 2022 3 commits
  6. 25 Jul, 2022 11 commits
  7. 23 Jul, 2022 12 commits
  8. 13 Jul, 2022 1 commit
    • Trond Myklebust's avatar
      NFSv4: Fix races in the legacy idmapper upcall · 51fd2eb5
      Trond Myklebust authored
      nfs_idmap_instantiate() will cause the process that is waiting in
      request_key_with_auxdata() to wake up and exit. If there is a second
      process waiting for the idmap->idmap_mutex, then it may wake up and
      start a new call to request_key_with_auxdata(). If the call to
      idmap_pipe_downcall() from the first process has not yet finished
      calling nfs_idmap_complete_pipe_upcall_locked(), then we may end up
      triggering the WARN_ON_ONCE() in nfs_idmap_prepare_pipe_upcall().
      
      The fix is to ensure that we clear idmap->idmap_upcall_data before
      calling nfs_idmap_instantiate().
      
      Fixes: e9ab41b6 ("NFSv4: Clean up the legacy idmapper upcall")
      Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
      51fd2eb5
  9. 12 Jul, 2022 4 commits