diff options
author | Sage Weil <sage@newdream.net> | 2012-05-01 13:46:01 -0700 |
---|---|---|
committer | Sage Weil <sage@newdream.net> | 2012-05-01 13:46:01 -0700 |
commit | 29399eec5f91a6796ee0084eaf839ade4beff245 (patch) | |
tree | e97e2175b3f745044deb4151e6cc845f47fdcd5a | |
parent | bb7e5da322871bfa1ac596411c596f83083b02a6 (diff) | |
download | ceph-29399eec5f91a6796ee0084eaf839ade4beff245.tar.gz |
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 <sage@newdream.net>
-rw-r--r-- | src/osd/OSD.cc | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index 623680969ca..be9d0998c98 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; } |