From: Sage Weil Date: Tue, 1 May 2012 20:46:01 +0000 (-0700) Subject: osd: use fsync+rename when writing meta files (during mkfs) X-Git-Tag: v0.47~48^2~13 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=29399eec5f91a6796ee0084eaf839ade4beff245;p=ceph.git osd: use fsync+rename when writing meta files (during mkfs) It's overkill to do the dir fsync on each file, but not worth making efficient. Signed-off-by: Sage Weil --- diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index 623680969ca9..be9d0998c982 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -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; }