| 13029 | } |
| 13030 | |
| 13031 | int Client::fsync(int fd, bool syncdataonly) |
| 13032 | { |
| 13033 | RWRef_t mref_reader(mount_state, CLIENT_MOUNTING); |
| 13034 | if (!mref_reader.is_state_satisfied()) |
| 13035 | return -ENOTCONN; |
| 13036 | |
| 13037 | tout(cct) << "fsync" << std::endl; |
| 13038 | tout(cct) << fd << std::endl; |
| 13039 | tout(cct) << syncdataonly << std::endl; |
| 13040 | |
| 13041 | std::scoped_lock lock(client_lock); |
| 13042 | Fh *f = get_filehandle(fd); |
| 13043 | if (!f) |
| 13044 | return -EBADF; |
| 13045 | #if defined(__linux__) && defined(O_PATH) |
| 13046 | if (f->flags & O_PATH) |
| 13047 | return -EBADF; |
| 13048 | #endif |
| 13049 | int r = _fsync(f, syncdataonly); |
| 13050 | if (r == 0) { |
| 13051 | // The IOs in this fsync were okay, but maybe something happened |
| 13052 | // in the background that we shoudl be reporting? |
| 13053 | r = f->take_async_err(); |
| 13054 | ldout(cct, 5) << "fsync(" << fd << ", " << syncdataonly |
| 13055 | << ") = 0, async_err = " << r << dendl; |
| 13056 | } else { |
| 13057 | // Assume that an error we encountered during fsync, even reported |
| 13058 | // synchronously, would also have applied the error to the Fh, and we |
| 13059 | // should clear it here to avoid returning the same error again on next |
| 13060 | // call. |
| 13061 | ldout(cct, 5) << "fsync(" << fd << ", " << syncdataonly << ") = " |
| 13062 | << r << dendl; |
| 13063 | f->take_async_err(); |
| 13064 | } |
| 13065 | return r; |
| 13066 | } |
| 13067 | |
| 13068 | void Client::C_nonblocking_fsync_state::advance() |
| 13069 | { |