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
throw ex;
        } finally {
            lock.unlock();
        }
    }
    /**
     * Renames all the given files from the key of the map to the
     * value of the map. All successfully renamed files are removed from the map in-place.
     */
    public void renameTempFilesSafe(Map<String, String> tempFileMap) throws IOException {
        
        
        @SuppressWarnings({ "rawtypes", "unchecked" })
        final Map.Entry<String, String>[] entries = tempFileMap.entrySet().toArray(new Map.Entry[0]);
        ArrayUtil.timSort(entries, (o1, o2) -> {
            String left = o1.getValue();
            String right = o2.getValue();
            if (left.startsWith(IndexFileNames.SEGMENTS) || right.startsWith(IndexFileNames.SEGMENTS)) {
                if (left.startsWith(IndexFileNames.SEGMENTS) == false) {
                    return -1;
                } else if (right.startsWith(IndexFileNames.SEGMENTS) == false) {
                    return 1;
                }
            }
            return left.compareTo(right);
        });
        metadataLock.writeLock().lock();
        
        
        try (Lock writeLock = directory().obtainLock(IndexWriter.WRITE_LOCK_NAME)) {