Author: xedin
Date: Mon Dec 19 09:20:18 2011
New Revision: 1220663

URL: http://svn.apache.org/viewvc?rev=1220663&view=rev
Log:
fsync the directory after new sstable or commitlog segment are created
patch by Pavel Yaskevich; reviewed by Jonathan Ellis for CASSANDRA-3250

Modified:
    cassandra/branches/cassandra-1.0/CHANGES.txt
    
cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/io/util/SequentialWriter.java
    
cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/utils/CLibrary.java

Modified: cassandra/branches/cassandra-1.0/CHANGES.txt
URL: 
http://svn.apache.org/viewvc/cassandra/branches/cassandra-1.0/CHANGES.txt?rev=1220663&r1=1220662&r2=1220663&view=diff
==============================================================================
--- cassandra/branches/cassandra-1.0/CHANGES.txt (original)
+++ cassandra/branches/cassandra-1.0/CHANGES.txt Mon Dec 19 09:20:18 2011
@@ -4,6 +4,8 @@
  * CLibrary.createHardLinkWithExec() to check for errors (CASSANDRA-3101)
 Merged from 0.8:
  * prevent new nodes from thinking down nodes are up forever (CASSANDRA-3626)
+ * fsync the directory after new sstable or commitlog segment are created 
(CASSANDRA-3250)
+
 
 1.0.6
  * (CQL) fix cqlsh support for replicate_on_write (CASSANDRA-3596)

Modified: 
cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/io/util/SequentialWriter.java
URL: 
http://svn.apache.org/viewvc/cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/io/util/SequentialWriter.java?rev=1220663&r1=1220662&r2=1220663&view=diff
==============================================================================
--- 
cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/io/util/SequentialWriter.java
 (original)
+++ 
cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/io/util/SequentialWriter.java
 Mon Dec 19 09:20:18 2011
@@ -39,6 +39,9 @@ public class SequentialWriter extends Ou
     protected byte[] buffer;
     private final boolean skipIOCache;
     private final int fd;
+    private final int directoryFD;
+    // directory should be synced only after first file sync, in other words, 
only once per file
+    private boolean directorySynced = false;
 
     protected long current = 0, bufferOffset;
     protected int validBufferBytes;
@@ -60,6 +63,7 @@ public class SequentialWriter extends Ou
         buffer = new byte[bufferSize];
         this.skipIOCache = skipIOCache;
         fd = CLibrary.getfd(out.getFD());
+        directoryFD = CLibrary.tryOpenDirectory(file.getParent());
         stream = new DataOutputStream(this);
     }
 
@@ -148,6 +152,12 @@ public class SequentialWriter extends Ou
             flushInternal();
             out.getFD().sync();
 
+            if (!directorySynced)
+            {
+                CLibrary.trySync(directoryFD);
+                directorySynced = true;
+            }
+
             syncNeeded = false;
         }
     }
@@ -288,6 +298,7 @@ public class SequentialWriter extends Ou
             CLibrary.trySkipCache(fd, 0, 0);
 
         out.close();
+        CLibrary.tryCloseFD(directoryFD);
     }
 
     /**

Modified: 
cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/utils/CLibrary.java
URL: 
http://svn.apache.org/viewvc/cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/utils/CLibrary.java?rev=1220663&r1=1220662&r2=1220663&view=diff
==============================================================================
--- 
cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/utils/CLibrary.java
 (original)
+++ 
cassandra/branches/cassandra-1.0/src/java/org/apache/cassandra/utils/CLibrary.java
 Mon Dec 19 09:20:18 2011
@@ -46,6 +46,7 @@ public final class CLibrary
     private static final int F_SETFL   = 4;  /* set file status flags */
     private static final int F_NOCACHE = 48; /* Mac OS X specific flag, turns 
cache on/off */
     private static final int O_DIRECT  = 040000; /* fcntl.h */
+    private static final int O_RDONLY  = 00000000; /* fcntl.h */
 
     private static final int POSIX_FADV_NORMAL     = 0; /* fadvise.h */
     private static final int POSIX_FADV_RANDOM     = 1; /* fadvise.h */
@@ -84,7 +85,11 @@ public final class CLibrary
 
     // fadvice
     public static native int posix_fadvise(int fd, long offset, int len, int 
flag) throws LastErrorException;
-        
+
+    public static native int open(String path, int flags) throws 
LastErrorException;
+    public static native int fsync(int fd) throws LastErrorException;
+    public static native int close(int fd) throws LastErrorException;
+
     private static int errno(RuntimeException e)
     {
         assert e instanceof LastErrorException;
@@ -261,6 +266,73 @@ public final class CLibrary
         return result;
     }
 
+    public static int tryOpenDirectory(String path)
+    {
+        int fd = -1;
+
+        try
+        {
+            return open(path, O_RDONLY);
+        }
+        catch (UnsatisfiedLinkError e)
+        {
+            // JNA is unavailable just skipping Direct I/O
+        }
+        catch (RuntimeException e)
+        {
+            if (!(e instanceof LastErrorException))
+                throw e;
+
+            logger.warn(String.format("open(%s, O_RDONLY) failed, errno 
(%d).", path, CLibrary.errno(e)));
+        }
+
+        return fd;
+    }
+
+    public static void trySync(int fd)
+    {
+        if (fd == -1)
+            return;
+
+        try
+        {
+            fsync(fd);
+        }
+        catch (UnsatisfiedLinkError e)
+        {
+            // JNA is unavailable just skipping Direct I/O
+        }
+        catch (RuntimeException e)
+        {
+            if (!(e instanceof LastErrorException))
+                throw e;
+
+            logger.warn(String.format("fsync(%d) failed, errno (%d).", fd, 
CLibrary.errno(e)));
+        }
+    }
+
+    public static void tryCloseFD(int fd)
+    {
+        if (fd == -1)
+            return;
+
+        try
+        {
+            close(fd);
+        }
+        catch (UnsatisfiedLinkError e)
+        {
+            // JNA is unavailable just skipping Direct I/O
+        }
+        catch (RuntimeException e)
+        {
+            if (!(e instanceof LastErrorException))
+                throw e;
+
+            logger.warn(String.format("close(%d) failed, errno (%d).", fd, 
CLibrary.errno(e)));
+        }
+    }
+
     /**
      * Get system file descriptor from FileDescriptor object.
      * @param descriptor - FileDescriptor objec to get fd from


Reply via email to