[ 
https://issues.apache.org/jira/browse/LUCENE-5570?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13964623#comment-13964623
 ] 

Uwe Schindler commented on LUCENE-5570:
---------------------------------------

Hi, because [~simonw] asked me: The javadocs of {{FileChannel#force(boolean)}} 
are not so nice, because they only garant that the changes made by this 
FileDescriptor are written to disk. In fact this is correct and also affects 
RandomAccessFile, although the javadocs are not so explicit (Javadocs of 
FileDescriptor class only talk about buffers owned by "this FD", but this is 
equivalent).

In fact, if you check the native C++ source code of OpenJDK, in fact, 
{{FileDescriptor#sync()}} and {{FileChannel#force(true)}} call exactly the same 
method: http://linux.die.net/man/2/fsync

{quote}
fsync() transfers ("flushes") all modified in-core data of (i.e., modified 
buffer cache pages for) the file referred to by the file descriptor fd to the 
disk device (or other permanent storage device) so that all changed information 
can be retrieved even after the system crashed or was rebooted. This includes 
writing through or flushing a disk cache if present. The call blocks until the 
device reports that the transfer has completed. It also flushes metadata 
information associated with the file (see stat(2)).

Calling fsync() does not necessarily ensure that the entry in the directory 
containing the file has also reached disk. For that an explicit fsync() on a 
file descriptor for the directory is also needed.
{quote}

{{FileChannel#force(false)}} just calls {{fdatasync()}}, also explained on this 
man page. On Windows, it does the same like {{FileChannel#force(true)}}.

Unless other JVMs implement this is a completely different way, both code paths 
are identical. In addition, the man page of fsync also states:

bq. On some UNIX systems (but not Linux), fd must be a writable file descriptor.

This is why we need to open for write and because of that we can only create 0 
byte files in Java 6, unless we check for existence before.

Please also note the following statement:

bq. Calling fsync() does not necessarily ensure that the entry in the directory 
containing the file has also reached disk. For that an explicit fsync() on a 
file descriptor for the directory is also needed.

As far as I remember, in Java 7 we can also flush the directory, we should try 
this - if it works!

> FSDirectory's fsync() is lenient
> --------------------------------
>
>                 Key: LUCENE-5570
>                 URL: https://issues.apache.org/jira/browse/LUCENE-5570
>             Project: Lucene - Core
>          Issue Type: Bug
>          Components: core/store
>            Reporter: Robert Muir
>             Fix For: 4.8, 5.0
>
>         Attachments: LUCENE-5570.patch, LUCENE-5570.patch, 
> LUCENE-5570_java6.patch, LUCENE-5570_zerobyte.patch
>
>
> This method has a lot of problems:
> 1. it tracks 'stale files' as it writes (this seems pointless), and only 
> actually fsyncs the intersection of that 'stale files' and the filenames 
> passed as argument to sync(). So any bogus names passed to sync() are just 
> silently ignored
> 2. if "something bad happens" (e.g. two indexwriters/dirs on the same path, 
> or some other shenanigans), and the file is actually in stale files, but was 
> say actually deleted on the filesystem, the underlying fsync() call will 
> create a new 0-byte file and fsync that.
> In my opinion we should do none of this. we should throw exceptions when this 
> stuff is wrong.



--
This message was sent by Atlassian JIRA
(v6.2#6252)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to