@Override
  public void writeBytes(byte[] b, int offset, int len) throws IOException {
    long freeSpace = dir.maxSize - dir.sizeInBytes();
    long realUsage = 0;

    // If MockRAMDir crashed since we were opened, then
    // don't write anything:
    if (dir.crashed)
      throw new IOException("MockRAMDirectory was crashed; cannot write to " + name);

    // Enforce disk full:
    if (dir.maxSize != 0 && freeSpace <= len) {
      // Compute the real disk free.  This will greatly slow
      // down our test but makes it more accurate:
      realUsage = dir.getRecomputedActualSizeInBytes();
      freeSpace = dir.maxSize - realUsage;
    }

    if (dir.maxSize != 0 && freeSpace <= len) {
      if (freeSpace > 0 && freeSpace < len) {
        realUsage += freeSpace;
        super.writeBytes(b, offset, (int) freeSpace);
      }
      if (realUsage > dir.maxUsedSize) {
        dir.maxUsedSize = realUsage;
      }
      throw new IOException("fake disk full at " + dir.getRecomputedActualSizeInBytes() + " bytes when writing " + name);
    } else {
      super.writeBytes(b, offset, len);
    }

    dir.maybeThrowDeterministicException();

    if (first) {
      // Maybe throw random exception; only do this on first
      // write to a new file:
      first = false;
      dir.maybeThrowIOException();
    }
  }