From 90e7f5e6484d13f55ddc0a393705b9454a5325ab Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 29 Apr 2015 14:51:00 -0700 Subject: [PATCH] os/newstore: only ftruncate if i_size is incorrect Even a no-op ftruncate can block in the kernel. Prior to this change I could frequently see ftruncate wait for an aio completion on the same file. Signed-off-by: Sage Weil --- src/os/newstore/NewStore.cc | 27 +++++++++++++++++++++------ src/os/newstore/NewStore.h | 1 + 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/os/newstore/NewStore.cc b/src/os/newstore/NewStore.cc index 33c322a2c2360..de2f893a628cd 100644 --- a/src/os/newstore/NewStore.cc +++ b/src/os/newstore/NewStore.cc @@ -3346,7 +3346,10 @@ int NewStore::_do_write(TransContext *txc, r = fd; goto out; } - ::ftruncate(fd, f.length); // in case there is trailing crap + r = _clean_fid_tail_fd(f, fd); // in case there is trailing crap + if (r < 0) { + goto out; + } f.length = (offset + length) - f.offset; x_offset = offset - f.offset; dout(20) << __func__ << " append " << f.fid << " writing " @@ -3458,12 +3461,8 @@ int NewStore::_do_write(TransContext *txc, return r; } -int NewStore::_clean_fid_tail(TransContext *txc, const fragment_t& f) +int NewStore::_clean_fid_tail_fd(const fragment_t& f, int fd) { - int fd = _open_fid(f.fid, O_RDWR); - if (fd < 0) { - return fd; - } struct stat st; int r = ::fstat(fd, &st); if (r < 0) { @@ -3481,6 +3480,22 @@ int NewStore::_clean_fid_tail(TransContext *txc, const fragment_t& f) << cpp_strerror(r) << dendl; return r; } + return 1; + } + return 0; +} + +int NewStore::_clean_fid_tail(TransContext *txc, const fragment_t& f) +{ + int fd = _open_fid(f.fid, O_RDWR); + if (fd < 0) { + return fd; + } + int r = _clean_fid_tail_fd(f, fd); + if (r < 0) { + return r; + } + if (r > 0) { txc->sync_fd(fd); } else { // all good! diff --git a/src/os/newstore/NewStore.h b/src/os/newstore/NewStore.h index c4cdc2bd3f2e8..6d6a28dabfe80 100644 --- a/src/os/newstore/NewStore.h +++ b/src/os/newstore/NewStore.h @@ -544,6 +544,7 @@ private: int _recover_next_nid(); void _assign_nid(TransContext *txc, OnodeRef o); + int _clean_fid_tail_fd(const fragment_t& f, int fd); int _clean_fid_tail(TransContext *txc, const fragment_t& f); TransContext *_txc_create(OpSequencer *osr); -- 2.39.5