{
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;
}