@Override
  public void setAcl(List<AclEntry> acl) throws IOException {
    // permission check
    checkAccess(file, false, true);

    // open file (will fail if file is a link and not following links)
    int fd = file.openForAttributeAccess(followLinks);
    try {
      // SECURITY: need to copy list as can change during processing
      acl = new ArrayList<AclEntry>(acl);
      int n = acl.size();

      long address = unsafe.allocateMemory(SIZEOF_ACE_T * n);
      try {
        encode(acl, address);
        facl(fd, ACE_SETACL, n, address);
      } catch (UnixException x) {
        if ((x.errno() == ENOSYS) || !isAclsEnabled(fd)) {
          throw new FileSystemException(
              file.getPathForExceptionMessage(),
              null,
              x.getMessage() + " (file system does not support NFSv4 ACLs)");
        }
        if (x.errno() == EINVAL && (n < 3))
          throw new IOException("ACL must contain at least 3 entries");
        x.rethrowAsIOException(file);
      } finally {
        unsafe.freeMemory(address);
      }
    } finally {
      close(fd);
    }
  }
  @Override
  public List<AclEntry> getAcl() throws IOException {
    // permission check
    checkAccess(file, true, false);

    // open file (will fail if file is a link and not following links)
    int fd = file.openForAttributeAccess(followLinks);
    try {
      long address = unsafe.allocateMemory(SIZEOF_ACE_T * MAX_ACL_ENTRIES);
      try {
        // read ACL and decode it
        int n = facl(fd, ACE_GETACL, MAX_ACL_ENTRIES, address);
        assert n >= 0;
        return decode(address, n);
      } catch (UnixException x) {
        if ((x.errno() == ENOSYS) || !isAclsEnabled(fd)) {
          throw new FileSystemException(
              file.getPathForExceptionMessage(),
              null,
              x.getMessage() + " (file system does not support NFSv4 ACLs)");
        }
        x.rethrowAsIOException(file);
        return null; // keep compiler happy
      } finally {
        unsafe.freeMemory(address);
      }
    } finally {
      close(fd);
    }
  }
 /** Permission checks to access file */
 private void checkAccess(UnixPath file, boolean checkRead, boolean checkWrite) {
   SecurityManager sm = System.getSecurityManager();
   if (sm != null) {
     if (checkRead) file.checkRead();
     if (checkWrite) file.checkWrite();
     sm.checkPermission(new RuntimePermission("accessUserInformation"));
   }
 }