Recent Java 9 commit (e5b66323ae45) breaks fsync on directory

Robert Muir rcmuir at gmail.com
Sat May 16 16:48:53 UTC 2015


Is it really not possible to revert the change that broke all this?

I urge you to reconsider the impacts of this. At the very least, we
can't change already-released versions of lucene code: we can't add
retroactively add "two screens of fsync code" to them to do the right
thing. That code is already out there. Users of those releases who
upgrade to java 9 will immediately be a little less safer against
power outages/crashes.

We aren't the only ones using the previous approach, a quick google
search shows other people know about this previous approach.
http://www.quora.com/Is-there-any-way-to-fsync%28%29-a-directory-from-Java

Try not to look at it as "those damn lucene devs were using an
undocumented api". Try to see it from our point of view, where the
linux fsync manual page is telling us we really need to do this, to
ensure directory entries are visible. And nothing in the java API told
you this wasn't ok: plenty of APIs take "file" where it can be a file
or directory. To me the problem is underspecification in the javadocs.

I don't understand the tradeoff being made here. The JDK will deliver
... a little bit earlier exception to morons trying to read bytes from
a directory, at the cost of damaging impact to user's data for
everyone else? What kind of tradeoff is that?

Look at http://www.slideshare.net/nan1nan1/eat-my-data. See page 117,
where its two screens of code to synchronize data to disk. This seems
to be where java is heading too... does it really have to be like
this?

Separately, the addition of an explicit api for this is a fantastic
idea, but its no solution for users on the existing api.

On Fri, May 15, 2015 at 7:00 PM, Brian Burkhalter
<brian.burkhalter at oracle.com> wrote:
>
> On May 13, 2015, at 7:51 AM, Brian Burkhalter <brian.burkhalter at oracle.com>
> wrote:
>
> I agree with Alan that adding an OpenOption would be a good possibility. In
> any case, as Files only contains static methods, we could still add a
> “utility” method that forces file/directory buffers to disk, that just uses
> the new open option under the hood. By that FileSystem SPI interfaces do not
> need to be modified and just need to take care about the new OpenOption (if
> supported).
>
>
> I started to investigate both avenues. Alan says he has some notes on
> previous work on the OpenOption avenue and I would like to see them before
> proceeding much further.
>
>
> Getting back to this topic after a few days, I don’t know what Alan had in
> mind specifically with respect to OpenOption, so I am more than likely
> missing some subtlety. The problem I have with this approach in regards to
>
> http://download.java.net/jdk9/docs/api/java/nio/file/Files.html#newByteChannel-java.nio.file.Path-java.util.Set-java.nio.file.attribute.FileAttribute...-
>
> is the nature of the return value. In general for the case of syncing
> directories will this return value not be a mostly useless stub?
>
> Before https://bugs.openjdk.java.net/browse/JDK-8066915 was fixed, in the
> case of a directory, reading from or writing to the SeekableByteChannel
> returned by newByteChannel would result in either an IOException for read()
> or a NonWritableChannelException for write(). (One wonders “why not a
> NonReadableChannelException?” for the read() case unless there used to be
> one and this was changed (I am testing with reverted code here)). Apparently
> ((FileChannel)sbc).force() would work however and cause the fsync().
>
> It seems like adding a new OpenOption specific to syncing via
> newByteChannel() is going to lead to a similar situation. The returned
> channel could be only partially functional with the non-functional methods
> either throwing appropriate exceptions (like before JDK-8066915), or simply
> being no-ops and not throwing any exceptions, the respective methods just
> doing the “correct” nothings. Another possibility is that the returned
> SeekableByteChannel is already closed, the sync having been done internally
> to newByteChannel(). None of these approaches is appealing to me personally
> as the returned value is always some form of compromised object.
>
> The other idea that was thrown about was something like Files.forceSync(Path
> path, boolean metadata). While this might force an update to the
> FileSystemProvider it seems much cleaner than returning some non- or
> partially functional object.
>
> From what I read the sync issue provoked by JDK-8066915 is a real problem
> for directories only, not files, is that correct?
>
> Any comments on the foregoing?
>
> Thanks,
>
> Brian


More information about the nio-dev mailing list