@Override
  public @Nullable AttributeInputStream readAttribute(final @NotNull PersistentFSConnection connection,
                                                      final int fileId,
                                                      final @NotNull FileAttribute attribute) throws IOException {
    final Lock readLock = lock.readLock();
    //CancellationUtil.lockMaybeCancellable(readLock);
    readLock.lock();
    try {
      PersistentFSConnection.ensureIdIsValid(fileId);

      final int attrRecordId = fileAttributeRecordId(connection, fileId);
      if (attrRecordId == NON_EXISTENT_ATTRIBUTE_RECORD_ID) {
        return null;
      }
      else if (attrRecordId < NON_EXISTENT_ATTRIBUTE_RECORD_ID) {
        throw new IllegalStateException("file[id: " + fileId + "]: attributeRecordId[=" + attrRecordId + "] is negative, must be >=0");
      }
      final int encodedAttrId = connection.getAttributeId(attribute.getId());

      int page = 0;

      try (DataInputStream attrRefs = attributesBlobStorage.readStream(attrRecordId)) {
        if (bulkAttrReadSupport) skipRecordHeader(attrRefs, PersistentFSConnection.RESERVED_ATTR_ID, fileId);

        while (attrRefs.available() > 0) {
          final int attIdOnPage = DataInputOutputUtil.readINT(attrRefs);
          final int attrAddressOrSize = DataInputOutputUtil.readINT(attrRefs);

          if (attIdOnPage != encodedAttrId) {
            if (inlineAttributes && attrAddressOrSize < INLINE_ATTRIBUTE_SMALLER_THAN) {
              final int inlineAttrSize = attrAddressOrSize;
              attrRefs.skipBytes(inlineAttrSize);
            }
          }
          else {
            if (inlineAttributes && attrAddressOrSize < INLINE_ATTRIBUTE_SMALLER_THAN) {
              final int inlineAttrSize = attrAddressOrSize;
              final byte[] attrContent = ArrayUtil.newByteArray(inlineAttrSize);
              attrRefs.readFully(attrContent);
              return new AttributeInputStream(new UnsyncByteArrayInputStream(attrContent), connection.getEnumeratedAttributes());
            }
            page = inlineAttributes ? attrAddressOrSize - INLINE_ATTRIBUTE_SMALLER_THAN : attrAddressOrSize;
            break;
          }
        }
      }

      if (page == 0) {
        return null;
      }
      AttributeInputStream stream =
        new AttributeInputStream(attributesBlobStorage.readStream(page), connection.getEnumeratedAttributes());
      if (bulkAttrReadSupport) skipRecordHeader(stream, encodedAttrId, fileId);
      return stream;
    }
    finally {
      readLock.unlock();
    }
  }
@Override
  public @Nullable AttributeInputStream readAttribute(final @NotNull PersistentFSConnection connection,
                                                      final int fileId,
                                                      final @NotNull FileAttribute attribute)