1. 20 Aug, 2022 2 commits
    • Olga Kornievskaia's avatar
      NFSv4.2 fix problems with __nfs42_ssc_open · fcfc8be1
      Olga Kornievskaia authored
      A destination server while doing a COPY shouldn't accept using the
      passed in filehandle if its not a regular filehandle.
      
      If alloc_file_pseudo() has failed, we need to decrement a reference
      on the newly created inode, otherwise it leaks.
      Reported-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
      Fixes: ec4b0925 ("NFS: inter ssc open")
      Signed-off-by: default avatarOlga Kornievskaia <kolga@netapp.com>
      Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
      fcfc8be1
    • NeilBrown's avatar
      NFS: unlink/rmdir shouldn't call d_delete() twice on ENOENT · f16857e6
      NeilBrown authored
      nfs_unlink() calls d_delete() twice if it receives ENOENT from the
      server - once in nfs_dentry_handle_enoent() from nfs_safe_remove and
      once in nfs_dentry_remove_handle_error().
      
      nfs_rmddir() also calls it twice - the nfs_dentry_handle_enoent() call
      is direct and inside a region locked with ->rmdir_sem
      
      It is safe to call d_delete() twice if the refcount > 1 as the dentry is
      simply unhashed.
      If the refcount is 1, the first call sets d_inode to NULL and the second
      call crashes.
      
      This patch guards the d_delete() call from nfs_dentry_handle_enoent()
      leaving the one under ->remdir_sem in case that is important.
      
      In mainline it would be safe to remove the d_delete() call.  However in
      older kernels to which this might be backported, that would change the
      behaviour of nfs_unlink().  nfs_unlink() used to unhash the dentry which
      resulted in nfs_dentry_handle_enoent() not calling d_delete().  So in
      older kernels we need the d_delete() in nfs_dentry_remove_handle_error()
      when called from nfs_unlink() but not when called from nfs_rmdir().
      
      To make the code work correctly for old and new kernels, and from both
      nfs_unlink() and nfs_rmdir(), we protect the d_delete() call with
      simple_positive().  This ensures it is never called in a circumstance
      where it could crash.
      
      Fixes: 3c59366c ("NFS: don't unhash dentry during unlink/rename")
      Fixes: 9019fb39 ("NFS: Label the dentry with a verifier in nfs_rmdir() and nfs_unlink()")
      Signed-off-by: default avatarNeilBrown <neilb@suse.de>
      Tested-by: default avatarOlga Kornievskaia <aglo@umich.edu>
      Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
      f16857e6
  2. 13 Aug, 2022 4 commits
  3. 09 Aug, 2022 3 commits
  4. 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
  5. 02 Aug, 2022 2 commits
  6. 27 Jul, 2022 3 commits
  7. 25 Jul, 2022 11 commits
  8. 23 Jul, 2022 12 commits
  9. 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
  10. 12 Jul, 2022 1 commit