[9] RFR of 8080589: (fs) FileChannel.force should use fcntl(F_FULLFSYNC) instead of fsync on OS X

Brian Burkhalter brian.burkhalter at oracle.com
Tue May 19 18:33:04 UTC 2015


On May 19, 2015, at 7:07 AM, Brian Burkhalter <brian.burkhalter at oracle.com> wrote:

> 
> On May 18, 2015, at 7:14 PM, Robert Muir <rcmuir at gmail.com> wrote:
> 
>> On Mon, May 18, 2015 at 9:24 PM, Brian Burkhalter
>> <brian.burkhalter at oracle.com> wrote:
>>> 
>>> +#ifdef MACOSX
>>> +    result = fcntl(fd, F_FULLFSYNC);
>>> +#else
>> 
>> According to fcntl(2) on OS X, this may not be implemented for all filesystems.
>> 
>> Should code handle failure/ENOTSUP as suggested here?
>> https://community.oracle.com/thread/453477
>> I see similar code in other open-source databases (but typically not
>> checking errno for anything specific).
> 
> Thanks for pointing this out. I will look into it further and update the patch as needed.

Perhaps this is a safer approach.

Brian

--- a/src/java.base/unix/native/libnio/ch/FileDispatcherImpl.c
+++ b/src/java.base/unix/native/libnio/ch/FileDispatcherImpl.c
@@ -144,14 +144,25 @@
 JNIEXPORT jint JNICALL
 Java_sun_nio_ch_FileDispatcherImpl_force0(JNIEnv *env, jobject this,
                                           jobject fdo, jboolean md)
 {
     jint fd = fdval(env, fdo);
     int result = 0;
 
+#ifdef MACOSX
+#if defined(F_FULLFSYNC)
+    result = fcntl(fd, F_FULLFSYNC);
+    if (result == -1 && errno == ENOTSUP) {
+        /* Try fsync() in case F_FULLSYUNC is not implemented on the file system. */
+        result = fsync(fd);
+    }
+#else
+    result = fsync(fd);
+#endif /* defined(F_FULLSYNC) */
+#else
     if (md == JNI_FALSE) {
         result = fdatasync(fd);
     } else {
 #ifdef _AIX
         /* On AIX, calling fsync on a file descriptor that is opened only for
          * reading results in an error ("EBADF: The FileDescriptor parameter is
          * not a valid file descriptor open for writing.").
@@ -159,17 +170,18 @@
          * 'writable' attribute of the corresponding file channel so we have to
          * use 'fcntl'.
          */
         int getfl = fcntl(fd, F_GETFL);
         if (getfl >= 0 && (getfl & O_ACCMODE) == O_RDONLY) {
             return 0;
         }
-#endif
+#endif /* _AIX */
         result = fsync(fd);
     }
+#endif /* MACOSX */
     return handle(env, result, "Force failed");
 }

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/nio-dev/attachments/20150519/e5912edb/attachment.html>


More information about the nio-dev mailing list