1. 11 Jul, 2014 7 commits
    • Jeff Layton's avatar
      nfsd: make deny mode enforcement more efficient and close races in it · baeb4ff0
      Jeff Layton authored
      The current enforcement of deny modes is both inefficient and scattered
      across several places, which makes it hard to guarantee atomicity. The
      inefficiency is a problem now, and the lack of atomicity will mean races
      once the client_mutex is removed.
      
      First, we address the inefficiency. We have to track deny modes on a
      per-stateid basis to ensure that open downgrades are sane, but when the
      server goes to enforce them it has to walk the entire list of stateids
      and check against each one.
      
      Instead of doing that, maintain a per-nfs4_file deny mode. When a file
      is opened, we simply set any deny bits in that mode that were specified
      in the OPEN call. We can then use that unified deny mode to do a simple
      check to see whether there are any conflicts without needing to walk the
      entire stateid list.
      
      The only time we'll need to walk the entire list of stateids is when a
      stateid that has a deny mode on it is being released, or one is having
      its deny mode downgraded. In that case, we must walk the entire list and
      recalculate the fi_share_deny field. Since deny modes are pretty rare
      today, this should be very rare under normal workloads.
      
      To address the potential for races once the client_mutex is removed,
      protect fi_share_deny with the fi_lock. In nfs4_get_vfs_file, check to
      make sure that any deny mode we want to apply won't conflict with
      existing access. If that's ok, then have nfs4_file_get_access check that
      new access to the file won't conflict with existing deny modes.
      
      If that also passes, then get file access references, set the correct
      access and deny bits in the stateid, and update the fi_share_deny field.
      If opening the file or truncating it fails, then unwind the whole mess
      and return the appropriate error.
      Signed-off-by: default avatarJeff Layton <jlayton@primarydata.com>
      Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
      Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
      baeb4ff0
    • Jeff Layton's avatar
      nfsd: always hold the fi_lock when bumping fi_access refcounts · 7214e860
      Jeff Layton authored
      Once we remove the client_mutex, there's an unlikely but possible race
      that could occur. It will be possible for nfs4_file_put_access to race
      with nfs4_file_get_access. The refcount will go to zero (briefly) and
      then bumped back to one. If that happens we set ourselves up for a
      use-after-free and the potential for a lock to race onto the i_flock
      list as a filp is being torn down.
      
      Ensure that we can safely bump the refcount on the file by holding the
      fi_lock whenever that's done. The only place it currently isn't is in
      get_lock_access.
      
      In order to ensure atomicity with finding the file, use the
      find_*_file_locked variants and then call get_lock_access to get new
      access references on the nfs4_file under the same lock.
      Signed-off-by: default avatarJeff Layton <jlayton@primarydata.com>
      Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
      Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
      7214e860
    • Jeff Layton's avatar
      nfsd: clean up reset_union_bmap_deny · 3b84240a
      Jeff Layton authored
      Fix the "deny" argument type, and start the loop at 1. The 0 iteration
      is always a noop.
      Signed-off-by: default avatarJeff Layton <jlayton@primarydata.com>
      Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
      Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
      3b84240a
    • Jeff Layton's avatar
      nfsd: set stateid access and deny bits in nfs4_get_vfs_file · 6eb3a1d0
      Jeff Layton authored
      Cleanup -- ensure that the stateid bits are set at the same time that
      the file access refcounts are incremented. Keeping them coherent like
      this makes it easier to ensure that we account for all of the
      references.
      
      Since the initialization of the st_*_bmap fields is done when it's
      hashed, we go ahead and hash the stateid before getting access to the
      file and unhash it if that function returns error. This will be
      necessary anyway in a follow-on patch that will overhaul deny mode
      handling.
      Signed-off-by: default avatarJeff Layton <jlayton@primarydata.com>
      Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
      Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
      6eb3a1d0
    • Jeff Layton's avatar
      nfsd: shrink st_access_bmap and st_deny_bmap · c11c591f
      Jeff Layton authored
      We never use anything above bit #3, so an unsigned long for each is
      wasteful. Shrink them to a char each, and add some WARN_ON_ONCE calls if
      we try to set or clear bits that would go outside those sizes.
      
      Note too that because atomic bitops work on unsigned longs, we have to
      abandon their use here. That shouldn't be a problem though since we
      don't really care about the atomicity in this code anyway. Using them
      was just a convenient way to flip bits.
      Signed-off-by: default avatarJeff Layton <jlayton@primarydata.com>
      Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
      Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
      c11c591f
    • Jeff Layton's avatar
      nfsd: remove nfs4_file_put_fd · 6d338b51
      Jeff Layton authored
      ...and replace it with a simple swap call.
      Signed-off-by: default avatarJeff Layton <jlayton@primarydata.com>
      Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
      Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
      6d338b51
    • Jeff Layton's avatar
      nfsd: refactor nfs4_file_get_access and nfs4_file_put_access · 12659651
      Jeff Layton authored
      Have them take NFS4_SHARE_ACCESS_* flags instead of an open mode. This
      spares the callers from having to convert it themselves.
      
      This also allows us to simplify these functions as we no longer need
      to do the access_to_omode conversion in either one.
      
      Note too that this patch eliminates the WARN_ON in
      __nfs4_file_get_access. It's valid for now, but in a later patch we'll
      be bumping the refcounts prior to opening the file in order to close
      some races, at which point we'll need to remove it anyway.
      Signed-off-by: default avatarJeff Layton <jlayton@primarydata.com>
      Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
      Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
      12659651
  2. 10 Jul, 2014 17 commits
  3. 08 Jul, 2014 16 commits