private void handleTableAcl(Set<TableName> tableNames, Set<String> users,
    Set<String> skipNamespaces, Set<TableName> skipTables,
    HDFSAclOperation.OperationType operationType)
    throws ExecutionException, InterruptedException, IOException {
    Set<TableName> filterTableNames = new HashSet<>();
    for (TableName tableName : tableNames) {
      if (
        !skipTables.contains(tableName)
          && !skipNamespaces.contains(tableName.getNamespaceAsString())
      ) {
        filterTableNames.add(tableName);
      }
    }
    List<CompletableFuture<Void>> futures = new ArrayList<>();
    // handle table HDFS acls
    for (TableName tableName : filterTableNames) {
      List<HDFSAclOperation> hdfsAclOperations = getTableRootPaths(tableName, true).stream()
        .map(path -> new HDFSAclOperation(fs, path, users, operationType, true,
          HDFSAclOperation.AclType.DEFAULT_ADN_ACCESS))
        .collect(Collectors.toList());
      CompletableFuture<Void> future = handleHDFSAclSequential(hdfsAclOperations);
      futures.add(future);
    }
    CompletableFuture<Void> future =
      CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()]));
    future.get();
  }
When op is REMOVE, remove the DEFAULT namespace ACL while keep the ACCESS for skipTables,
otherwise remove both the DEFAULT + ACCESS ACLs. When op is MODIFY, just operate the
DEFAULT + ACCESS ACLs.
hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/SnapshotScannerHDFSAclHelper.java