static void checkAndSetFileOwnerPermissions(FileSystem fs, FileStatus fStatus,
                                              String userName, String groupName,
                                              FsPermission dirPerms, FsPermission filePerms,
                                              boolean dryRun, boolean recurse) throws IOException {
    if (fStatus == null) {
      return;
    }

    Path path = fStatus.getPath();
    boolean setOwner = false;
    if (userName != null && !userName.equals(fStatus.getOwner())) {
      setOwner = true;
    } else if (groupName != null && !groupName.equals(fStatus.getGroup())) {
      setOwner = true;
    }

    boolean isDir = fStatus.isDirectory();
    boolean setPerms = false;
    FsPermission perms = filePerms;
    if (isDir) {
      perms = dirPerms;
    }
    if (perms != null && !perms.equals(fStatus.getPermission())) {
      setPerms = true;
    }

    if (setOwner) {
      LOG.debug("Setting owner/group of {} to {}/{}", path, userName, groupName);
      if (!dryRun) {
        fs.setOwner(path, userName, groupName);
      }
    }
    if (setPerms) {
      LOG.debug("Setting perms of {} to {}", path, perms);
      if (!dryRun) {
        fs.setPermission(path, perms);
      }
    }

    if (isDir && recurse) {
      for (FileStatus subFile : fs.listStatus(path)) {
        // TODO: Use threadpool for more concurrency?
        // TODO: check/set all files, or only directories
        checkAndSetFileOwnerPermissions(fs, subFile, userName, groupName, dirPerms, filePerms, dryRun, recurse);
      }
    }
  }
Recursively check the file owner and permissions, setting them to the passed in values
if the owner/perms of the file do not match.
@param fs
@param fStatus
@param userName  Owner of the file to compare/set. Null to skip this check.
@param groupName Group of the file to compare/set. Null to skip this check.
@param dirPerms  Permissions to compare/set, if the file is a directory. Null to skip this check.
@param filePerms Permissions to compare/set, if the file is a file. Null to skip this check.
@param dryRun    Dry run - check but do not actually set
@param recurse   Whether to recursively check/set the contents of a directory
@throws IOException
ql/src/java/org/apache/hadoop/hive/ql/util/HiveStrictManagedMigration.java