summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2012-05-01 13:46:01 -0700
committerSage Weil <sage@newdream.net>2012-05-01 13:46:01 -0700
commit29399eec5f91a6796ee0084eaf839ade4beff245 (patch)
treee97e2175b3f745044deb4151e6cc845f47fdcd5a
parentbb7e5da322871bfa1ac596411c596f83083b02a6 (diff)
downloadceph-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.cc35
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;
}