← Back to team overview

openjdk team mailing list archive

[Bug 1811324] [NEW] RandomAccessFile::setLength will not shrink sparse files

 

Public bug reported:

This bug is filed upstream already as JDK-8202261.

It was introduced by JDK-8168628.

So in bionic, it was introduced on Mon, 19 Nov 2018 when 8u191-b12
replaced 8u181-b13.

The bug is in RandomAccessFile::setLength. This method used to call
ftruncate whether it was growing or shrinking the file. It was changed
to call ftruncate when shrinking the file, and fallocate when growing.
This is a performance concern all by itself, but the more serious issue
is the bug in how they implemented the check to see if this was a grow
operation or a shrink operation:

if (fstat64(fd, &sb) == 0 && length > sb.st_blocks*512) {
    // ...
}

Which makes the assumption that st_blocks*512 is the same as st_size,
which is not true in some situations (e.g. sparse files or in a
filesystem with transparent compression like zfs).

The result is that calling randomAccessFile.setLength(length) on a
sparse file whose length is greater than the provided length will not
set the length at all. It will simply fallocate() the file and leave the
length the same.

Attached Shrink.java which reproduces the problem.

This problem is acknowledged in Alan Bateman's comment on JDK-8168628:

"This change has been backed out of JDK 11 as it break sparse files."

The change that introduced the problem is being corrected in 8u202-b1,
but I would request that bionic backport the patch to the current
openjdk-8 as this is a regression from the state of openjdk-8 at bionic
release time.

Patch is here: http://hg.openjdk.java.net/jdk/jdk/rev/117501815bed

** Affects: openjdk-8 (Ubuntu)
     Importance: Undecided
         Status: New

** Attachment added: "Java program which reproduces issue on filesystems supporting sparse files or transparent compression."
   https://bugs.launchpad.net/bugs/1811324/+attachment/5228419/+files/Shrink.java

-- 
You received this bug notification because you are a member of OpenJDK,
which is subscribed to openjdk-8 in Ubuntu.
https://bugs.launchpad.net/bugs/1811324

Title:
  RandomAccessFile::setLength will not shrink sparse files

Status in openjdk-8 package in Ubuntu:
  New

Bug description:
  This bug is filed upstream already as JDK-8202261.

  It was introduced by JDK-8168628.

  So in bionic, it was introduced on Mon, 19 Nov 2018 when 8u191-b12
  replaced 8u181-b13.

  The bug is in RandomAccessFile::setLength. This method used to call
  ftruncate whether it was growing or shrinking the file. It was changed
  to call ftruncate when shrinking the file, and fallocate when growing.
  This is a performance concern all by itself, but the more serious
  issue is the bug in how they implemented the check to see if this was
  a grow operation or a shrink operation:

  if (fstat64(fd, &sb) == 0 && length > sb.st_blocks*512) {
      // ...
  }

  Which makes the assumption that st_blocks*512 is the same as st_size,
  which is not true in some situations (e.g. sparse files or in a
  filesystem with transparent compression like zfs).

  The result is that calling randomAccessFile.setLength(length) on a
  sparse file whose length is greater than the provided length will not
  set the length at all. It will simply fallocate() the file and leave
  the length the same.

  Attached Shrink.java which reproduces the problem.

  This problem is acknowledged in Alan Bateman's comment on JDK-8168628:

  "This change has been backed out of JDK 11 as it break sparse files."

  The change that introduced the problem is being corrected in 8u202-b1,
  but I would request that bionic backport the patch to the current
  openjdk-8 as this is a regression from the state of openjdk-8 at
  bionic release time.

  Patch is here: http://hg.openjdk.java.net/jdk/jdk/rev/117501815bed

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/openjdk-8/+bug/1811324/+subscriptions


Follow ups