As mentioned in https://github.com/elastic/elasticsearch/pull/96216, `LuceneVerifyingIndexOutput` always copies the last chunk byte-by-byte. This might be a pretty big chunk. We should be able to copy all the bytes up to the start of the checksum in bulk (and then I guess bulk-copy the checksum too not that this matters so much).

In the same area, `LuceneVerifyingIndexOutput` is the only subclass of `VerifyingIndexOutput` and there's no need for it to be an inner class of `Store`. `VerifyingIndexInput` also doesn't need to be an inner class.
server/src/main/java/org/elasticsearch/index/store/Store.java
public final boolean hasReferences() {
        return refCounter.hasReferences();
    }
    @Override
    public void close() {
        if (isClosed.compareAndSet(false, true)) {
            
            decRef();
            logger.debug("store reference count on close: {}", refCounter.refCount());
        }
    }
    /**
     * @return true if the {@link Store#close()} method has been called. This indicates that the current
     * store is either closed or being closed waiting for all references to it to be released.
     * You might prefer to use {@link Store#ensureOpen()} instead.
     */
    public boolean isClosing() {
        return isClosed.get();
    }
    private void closeInternal() {
        
        try (Closeable c = shardLock) {
            try {
                directory.innerClose(); 
            } finally {
                onClose.accept(shardLock);
            }
        } catch (IOException e) {
            assert false : e;
            logger.warn(() -> "exception on closing store for [" + shardId + "]", e);