]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
cephfs-journal-tool: Fix purging when importing an zero-length journal. 22144/head
authorchenyupeng360 <chenyupeng-it@360.cn>
Tue, 22 May 2018 04:34:51 +0000 (12:34 +0800)
committerchenyupeng360 <chenyupeng-it@360.cn>
Wed, 23 May 2018 02:41:10 +0000 (10:41 +0800)
When importing a zero-length purge_queue journal exported previously, the last object and
the following one are now being purged for removing potential junks. In this case,
there will be no writing performed actually, so the purged last object get lost permanently.

This can be fixed by purging the object following the last object, and by zeroing the last object
starting from the offset determined by the write_pos.

Fixes: https://tracker.ceph.com/issues/24239
Signed-off-by: yupeng chen <chenyupeng-it@360.cn>
Signed-off-by: zhongyan gu <guzhongyan@360.cn>
src/tools/cephfs/Dumper.cc

index 67252eaa326fbee75a9d1273a9e6ff3c8b9fd2fc..746263e5d6dab3ae76d0eea24296b5e334c730e5 100644 (file)
@@ -286,8 +286,15 @@ int Dumper::undump(const char *dump_file)
   {
     uint32_t const object_size = h.layout.object_size;
     assert(object_size > 0);
-    uint64_t const last_obj = h.write_pos / object_size;
-    uint64_t const purge_count = 2;
+    uint64_t last_obj = h.write_pos / object_size;
+    uint64_t purge_count = 2;
+    /* When the length is zero, the last_obj should be zeroed 
+     * from the offset determined by the new write_pos instead of being purged.
+     */
+    if (!len) {
+        purge_count = 1;
+        ++last_obj;
+    }
     C_SaferCond purge_cond;
     cout << "Purging " << purge_count << " objects from " << last_obj << std::endl;
     lock.Lock();
@@ -296,6 +303,20 @@ int Dumper::undump(const char *dump_file)
     lock.Unlock();
     purge_cond.wait();
   }
+  /* When the length is zero, zero the last object 
+   * from the offset determined by the new write_pos.
+   */
+  if (!len) {
+    uint64_t offset_in_obj = h.write_pos % h.layout.object_size;
+    uint64_t len           = h.layout.object_size - offset_in_obj;
+    C_SaferCond zero_cond;
+    cout << "Zeroing " << len << " bytes in the last object." << std::endl;
+    
+    lock.Lock();
+    filer.zero(ino, &h.layout, snapc, h.write_pos, len, ceph::real_clock::now(), 0, &zero_cond);
+    lock.Unlock();
+    zero_cond.wait();
+  }
 
   // Stream from `fd` to `filer`
   uint64_t pos = start;