]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
osd: use fsync+rename when writing meta files (during mkfs)
authorSage Weil <sage@newdream.net>
Tue, 1 May 2012 20:46:01 +0000 (13:46 -0700)
committerSage Weil <sage@newdream.net>
Tue, 1 May 2012 20:46:01 +0000 (13:46 -0700)
It's overkill to do the dir fsync on each file, but not worth making
efficient.

Signed-off-by: Sage Weil <sage@newdream.net>
src/osd/OSD.cc

index 623680969ca9d06f87c1e2dcb86c50fd6c7b63b0..be9d0998c982437def03cc414fe56f21e08502db 100644 (file)
@@ -407,29 +407,52 @@ int OSD::write_meta(const std::string &base, const std::string &file,
 {
   int ret;
   char fn[PATH_MAX];
+  char tmp[PATH_MAX];
   int fd;
 
   snprintf(fn, sizeof(fn), "%s/%s", base.c_str(), file.c_str());
-  fd = ::open(fn, O_WRONLY|O_CREAT|O_TRUNC, 0644);
+  snprintf(tmp, sizeof(tmp), "%s/%s.tmp", base.c_str(), file.c_str());
+  fd = ::open(tmp, O_WRONLY|O_CREAT|O_TRUNC, 0644);
   if (fd < 0) {
     ret = errno;
-    derr << "OSD::write_meta: error opening '" << fn << "': "
+    derr << "OSD::write_meta: error opening '" << tmp << "': "
         << cpp_strerror(ret) << dendl;
     return -ret;
   }
   ret = safe_write(fd, val, vallen);
   if (ret) {
-    derr << "OSD::write_meta: failed to write to '" << fn << "': "
+    derr << "OSD::write_meta: failed to write to '" << tmp << "': "
         << cpp_strerror(ret) << dendl;
     TEMP_FAILURE_RETRY(::close(fd));
     return ret;
   }
-  if (TEMP_FAILURE_RETRY(::close(fd)) < 0) {
-    ret = errno;
-    derr << "OSD::write_meta: close error writing to '" << fn << "': "
+
+  ret = ::fsync(fd);
+  TEMP_FAILURE_RETRY(::close(fd));
+  if (ret) {
+    ::unlink(tmp);
+    derr << "OSD::write_meta: failed to fsync to '" << tmp << "': "
+        << cpp_strerror(ret) << dendl;
+    return ret;
+  }
+  ret = ::rename(tmp, fn);
+  if (ret) {
+    ::unlink(tmp);
+    derr << "OSD::write_meta: failed to rename '" << tmp << "' to '" << fn << "': "
         << cpp_strerror(ret) << dendl;
     return ret;
   }
+
+  fd = ::open(base.c_str(), O_RDONLY);
+  if (fd < 0) {
+    ret = errno;
+    derr << "OSD::write_meta: failed to open dir '" << base << "': "
+        << cpp_strerror(ret) << dendl;
+    return -ret;
+  }
+  ::fsync(fd);
+  TEMP_FAILURE_RETRY(::close(fd));
+
   return 0;
 }