Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit c6f7e9b

Browse files
committedNov 30, 2024·
Fix unhandled UnsupportedOperationException in Fallocate
1 parent ed64823 commit c6f7e9b

File tree

1 file changed

+35
-15
lines changed

1 file changed

+35
-15
lines changed
 

‎src/freenet/support/io/Fallocate.java

+35-15
Original file line numberDiff line numberDiff line change
@@ -38,49 +38,69 @@ private Fallocate(FileChannel channel, int fd, long final_filesize) {
3838
}
3939

4040
public static Fallocate forChannel(FileChannel channel, long final_filesize) {
41-
return new Fallocate(channel, getDescriptor(channel), final_filesize);
41+
try {
42+
return new Fallocate(channel, getDescriptor(channel), final_filesize);
43+
} catch (final UnsupportedOperationException exception) {
44+
// File descriptor is not supported: fd is null and unavailable
45+
return new Fallocate(channel, 0, final_filesize);
46+
}
4247
}
4348

4449
public static Fallocate forChannel(FileChannel channel, FileDescriptor fd, long final_filesize) {
45-
return new Fallocate(channel, getDescriptor(fd), final_filesize);
50+
try {
51+
return new Fallocate(channel, getDescriptor(fd), final_filesize);
52+
} catch (final UnsupportedOperationException exception) {
53+
// File descriptor is not supported: fd is null and unavailable
54+
return new Fallocate(channel, 0, final_filesize);
55+
}
4656
}
4757

48-
public Fallocate fromOffset(long offset) {
58+
public Fallocate fromOffset(long offset) throws IllegalArgumentException {
4959
if(offset < 0 || offset > final_filesize) throw new IllegalArgumentException();
5060
this.offset = offset;
5161
return this;
5262
}
5363

54-
public Fallocate keepSize() {
64+
public Fallocate keepSize() throws UnsupportedOperationException {
5565
requireLinux("fallocate keep size");
5666
mode |= FALLOC_FL_KEEP_SIZE;
5767
return this;
5868
}
5969

60-
private void requireLinux(String feature) {
70+
private void requireLinux(String feature) throws UnsupportedOperationException {
6171
if (!IS_LINUX) {
6272
throwUnsupported(feature);
6373
}
6474
}
6575

66-
private void throwUnsupported(String feature) {
76+
private void throwUnsupported(String feature) throws UnsupportedOperationException {
6777
throw new UnsupportedOperationException(feature + " is not supported on this file system");
6878
}
6979

7080
public void execute() throws IOException {
7181
int errno = 0;
7282
boolean isUnsupported = false;
73-
if (IS_LINUX) {
74-
final int result = FallocateHolder.fallocate(fd, mode, offset, final_filesize-offset);
75-
errno = result == 0 ? 0 : Native.getLastError();
76-
} else if (IS_POSIX) {
77-
errno = FallocateHolderPOSIX.posix_fallocate(fd, offset, final_filesize-offset);
83+
if (fd != 0) {
84+
if (IS_LINUX) {
85+
final int result = FallocateHolder.fallocate(fd, mode, offset, final_filesize-offset);
86+
errno = result == 0 ? 0 : Native.getLastError();
87+
} else if (IS_POSIX) {
88+
errno = FallocateHolderPOSIX.posix_fallocate(fd, offset, final_filesize-offset);
89+
} else {
90+
isUnsupported = true;
91+
}
7892
} else {
79-
isUnsupported = true;
93+
// fd is null and unavailable
94+
if (Platform.isWindows()) {
95+
// Windows do not create sparse files by default, so just write a byte at the end.
96+
channel.write(ByteBuffer.allocate(1), final_filesize - 1);
97+
} else {
98+
isUnsupported = true;
99+
}
80100
}
81101

82102
if (isUnsupported || errno != 0) {
83-
Logger.normal(this, "fallocate() failed; using legacy method; errno="+errno);
103+
Logger.normal(this, "fallocate() failed; using legacy method; errno=" + errno);
84104
legacyFill(channel, final_filesize, offset);
85105
}
86106
}
@@ -101,7 +121,7 @@ private static class FallocateHolderPOSIX {
101121
private static native int posix_fallocate(int fd, long offset, long length);
102122
}
103123

104-
private static int getDescriptor(FileChannel channel) {
124+
private static int getDescriptor(FileChannel channel) throws UnsupportedOperationException {
105125
try {
106126
// sun.nio.ch.FileChannelImpl declares private final java.io.FileDescriptor fd
107127
final Field field = channel.getClass().getDeclaredField("fd");
@@ -112,7 +132,7 @@ private static int getDescriptor(FileChannel channel) {
112132
}
113133
}
114134

115-
private static int getDescriptor(FileDescriptor descriptor) {
135+
private static int getDescriptor(FileDescriptor descriptor) throws UnsupportedOperationException {
116136
try {
117137
// Oracle java.io.FileDescriptor declares private int fd
118138
final Field field = descriptor.getClass().getDeclaredField(IS_ANDROID ? "descriptor" : "fd");

0 commit comments

Comments
 (0)
Please sign in to comment.