From 403ddac30660000f6432ab44ee8b60c8fb0576f6 Mon Sep 17 00:00:00 2001
From: Zardosht Kasheff <zardosht@tokutek.com>
Date: Tue, 3 Apr 2012 14:21:11 +0000
Subject: [PATCH] [t:4644], merge fix to main

git-svn-id: file:///svn/toku/tokudb@41513 c7de825b-a66e-492c-adef-691d508d4ae1
---
 newbrt/brt.c        | 27 +++++++++++++--------------
 newbrt/cachetable.c | 37 ++++++++++++++++++++-----------------
 2 files changed, 33 insertions(+), 31 deletions(-)

diff --git a/newbrt/brt.c b/newbrt/brt.c
index 37dade26e1..c220a456a4 100644
--- a/newbrt/brt.c
+++ b/newbrt/brt.c
@@ -4260,8 +4260,18 @@ toku_brtheader_checkpoint (CACHEFILE cf, int fd, void *header_v) {
         r = toku_serialize_brt_header_to(fd, ch);
         if (r!=0) goto handle_error;
 	ch->dirty = 0;		      // this is only place this bit is cleared (in checkpoint_header)
-    } else 
+	
+        // fsync the cachefile
+        r = toku_cachefile_fsync(cf);
+        if (r!=0) {
+            goto handle_error;
+        }
+        h->checkpoint_count++;        // checkpoint succeeded, next checkpoint will save to alternate header location
+        h->checkpoint_lsn = ch->checkpoint_lsn;  //Header updated.
+    } 
+    else {
         toku_block_translation_note_skipped_checkpoint(ch->blocktable);
+    }
     if (0) {
 handle_error:
 	if (h->panic) r = h->panic;
@@ -4277,26 +4287,15 @@ handle_error:
 
 }
 
-// Really write everything to disk (fsync dictionary), then free unused disk space 
+// free unused disk space 
 // (i.e. tell BlockAllocator to liberate blocks used by previous checkpoint).
 // Must have access to fd (protected)
 int
-toku_brtheader_end_checkpoint (CACHEFILE cachefile, int fd, void *header_v) {
+toku_brtheader_end_checkpoint (CACHEFILE UU(cachefile), int fd, void *header_v) {
     struct brt_header *h = header_v;
     int r = h->panic;
     if (r==0) {
 	assert(h->type == BRTHEADER_CURRENT);
-	struct brt_header *ch = h->checkpoint_header;
-	BOOL checkpoint_success_so_far = (BOOL)(ch->checkpoint_count==h->checkpoint_count+1 && ch->dirty==0);
-	if (checkpoint_success_so_far) {
-	    r = toku_cachefile_fsync(cachefile);
-	    if (r!=0) 
-		toku_block_translation_note_failed_checkpoint(h->blocktable);
-	    else {
-		h->checkpoint_count++;	      // checkpoint succeeded, next checkpoint will save to alternate header location
-		h->checkpoint_lsn = ch->checkpoint_lsn;	 //Header updated.
-	    }
-	}
 	toku_block_translation_note_end_checkpoint(h->blocktable, fd, h);
     }
     if (h->checkpoint_header) {	 // could be NULL only if panic was true at begin_checkpoint
diff --git a/newbrt/cachetable.c b/newbrt/cachetable.c
index 915eceba1e..8f1284363e 100644
--- a/newbrt/cachetable.c
+++ b/newbrt/cachetable.c
@@ -3844,7 +3844,6 @@ toku_cachetable_end_checkpoint(CACHETABLE ct, TOKULOGGER logger,
 
     {   // have just written data blocks, so next write the translation and header for each open dictionary
         CACHEFILE cf;
-        //cachefiles_in_checkpoint is protected by the checkpoint_safe_lock
         for (cf = ct->cachefiles_in_checkpoint; cf; cf=cf->next_in_checkpoint) {
             if (cf->checkpoint_userdata) {
                 rwlock_prefer_read_lock(&cf->fdlock, ct->mutex);
@@ -3866,9 +3865,27 @@ toku_cachetable_end_checkpoint(CACHETABLE ct, TOKULOGGER logger,
             }
         }
     }
+    
+    cachetable_unlock(ct);
+    // For testing purposes only.  Dictionary has been fsync-ed to disk but log has not yet been written.
+    if (testcallback_f) {
+        testcallback_f(testextra);      
+    }
+    if (logger) {
+        int r = toku_log_end_checkpoint(logger, NULL,
+                                        1, // want the end_checkpoint to be fsync'd
+                                        ct->lsn_of_checkpoint_in_progress.lsn, 
+                                        0,
+                                        ct->checkpoint_num_files,
+                                        ct->checkpoint_num_txns);
+        assert(r==0);
+        toku_logger_note_checkpoint(logger, ct->lsn_of_checkpoint_in_progress);
+    }
+    cachetable_lock(ct);
 
-    {   // everything has been written to file (or at least OS internal buffer)...
-        // ... so fsync and call checkpoint-end function in block translator
+    {   
+        // everything has been written to file and fsynced
+        // ... call checkpoint-end function in block translator
         //     to free obsolete blocks on disk used by previous checkpoint
         CACHEFILE cf;
         //cachefiles_in_checkpoint is protected by the checkpoint_safe_lock
@@ -3916,20 +3933,6 @@ toku_cachetable_end_checkpoint(CACHETABLE ct, TOKULOGGER logger,
         }
     }
 
-    // For testing purposes only.  Dictionary has been fsync-ed to disk but log has not yet been written.
-    if (testcallback_f) 
-        testcallback_f(testextra);      
-
-    if (logger) {
-        int r = toku_log_end_checkpoint(logger, NULL,
-                                        1, // want the end_checkpoint to be fsync'd
-                                        ct->lsn_of_checkpoint_in_progress.lsn, 
-                                        0,
-                                        ct->checkpoint_num_files,
-                                        ct->checkpoint_num_txns);
-        assert(r==0);
-        toku_logger_note_checkpoint(logger, ct->lsn_of_checkpoint_in_progress);
-    }
     
     brt_end_checkpoint();
 panic:
-- 
2.30.9