diff options
Diffstat (limited to 'src/os/FileStore.cc')
-rw-r--r-- | src/os/FileStore.cc | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/src/os/FileStore.cc b/src/os/FileStore.cc index 2c66a5ea7db..e2bd4988a09 100644 --- a/src/os/FileStore.cc +++ b/src/os/FileStore.cc @@ -2351,6 +2351,17 @@ unsigned FileStore::_do_transaction(Transaction& t, uint64_t op_seq, int trans_n } break; + case Transaction::OP_FALLOCATE: + { + coll_t cid = i.get_cid(); + hobject_t oid = i.get_oid(); + uint64_t off = i.get_length(); + uint64_t len = i.get_length(); + if (_check_replay_guard(cid, oid, spos) > 0) + r = _fallocate(cid, oid, off, len); + } + break; + case Transaction::OP_TRIMCACHE: { i.get_cid(); @@ -2932,6 +2943,42 @@ int FileStore::_zero(coll_t cid, const hobject_t& oid, uint64_t offset, size_t l return ret; } +int FileStore::_fallocate(coll_t cid, const hobject_t& oid, uint64_t offset, size_t len) +{ + dout(15) << "fallocate " << cid << "/" << oid << " " << offset << "~" << len << dendl; + int ret = 0; + + int fd = lfn_open(cid, oid, O_RDONLY); + if (fd < 0) { + ret = -errno; + goto out; + } + + // try the real way +#ifdef CEPH_HAVE_FALLOCATE +# if !defined(DARWIN) && !defined(__FreeBSD__) + ret = fallocate(fd, 0, offset, len); + if (ret < 0) + ret = -errno; + goto out_close; +# endif +#endif + + // oh well; just make sure we adjust i_size + struct stat st; + ret = ::fstat(fd, &st); + if (ret == 0 && st.st_size < offset + len) + ret = ::ftruncate(fd, offset + len); + if (ret < 0) + ret = -errno; + + out_close: + TEMP_FAILURE_RETRY(::close(fd)); + out: + dout(20) << "fallocate " << cid << "/" << oid << " " << offset << "~" << len << " = " << ret << dendl; + return ret; +} + int FileStore::_clone(coll_t cid, const hobject_t& oldoid, const hobject_t& newoid, const SequencerPosition& spos) { |