RFR: 8293502: (fc) FileChannel::transfer methods fail to copy /proc files on Linux

Alan Bateman alanb at openjdk.org
Thu Sep 15 11:09:48 UTC 2022


On Wed, 14 Sep 2022 16:00:17 GMT, Brian Burkhalter <bpb at openjdk.org> wrote:

> Files in `/proc` advertise a size of zero for which direct and mapped transfers do not work. For this case, fall back to arbitrary channel transfer.

src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java line 774:

> 772:         // Adjust count only if remaining > 0, i.e.,
> 773:         // sz > position which means sz > 0
> 774:         if (remaining < count && remaining > 0)

It might be a bit more readable to swap this to test `remaining > 0 && remaining < count`.

src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java line 949:

> 947:         // System calls supporting fast transfers might not work on files
> 948:         // which advertise zero size such as those in Linux /proc
> 949:         if (src instanceof FileChannelImpl fci && fci.size() > 0) {

This means an extra fstat per transferFrom but maybe you've measured it with small files and it's okay?

test/jdk/java/nio/file/Files/CopyProcFile.java line 52:

> 50:  */
> 51: public class CopyProcFile {
> 52:     static final String SOURCE = "/proc/mounts";

I wonder how stable this is. If the mount tables change while the test is running then I assume it will fail.

test/jdk/java/nio/file/Files/CopyProcFile.java line 80:

> 78:     static long copy(String src, String dst) {
> 79:         try {
> 80:             return Files.size(Files.copy(Path.of(src), Path.of(dst)));

I think it might be clearer if you split this into

Path target = Files.copy(Path.of(src), Path.of(dst));
return Files.size(target);

only because it might not be obvious that it's the target Path that is returned.

test/jdk/java/nio/file/Files/CopyProcFile.java line 100:

> 98:         try (FileChannel fci = FileChannel.open(Path.of(src), READ);
> 99:              FileChannel fco = FileChannel.open(Path.of(dst), CREATE_NEW,
> 100:                                                 WRITE);) {

I don't know if this line break is intentional or not but it would be more readable if WRITE were moved to the previous line.

Update: Same thing in transferFrom.

-------------

PR: https://git.openjdk.org/jdk/pull/10267


More information about the nio-dev mailing list