From 79aed5d4f8e854a8caddd074ff2cbdc73dc2b88f Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 8 Aug 2017 18:12:57 -0400 Subject: [PATCH] os/bluestore: fail early on very large objects We have a hard 4GB object size limit (although in practice we want to be *well* below that!). See http://tracker.ceph.com/issues/20923 Signed-off-by: Sage Weil (cherry picked from commit 70f6760d3793d5a06e3c583608d220b354e65f84) --- src/os/bluestore/BlueStore.cc | 41 +++++++++++++++++++++++++++-------- src/os/bluestore/BlueStore.h | 2 +- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/os/bluestore/BlueStore.cc b/src/os/bluestore/BlueStore.cc index 4d5b989ffe2e8..9672e34b0c68a 100644 --- a/src/os/bluestore/BlueStore.cc +++ b/src/os/bluestore/BlueStore.cc @@ -9013,7 +9013,7 @@ void BlueStore::_txc_add_transaction(TransContext *txc, Transaction *t) case Transaction::OP_TRUNCATE: { uint64_t off = op->off; - _truncate(txc, c, o, off); + r = _truncate(txc, c, o, off); } break; @@ -10333,10 +10333,14 @@ int BlueStore::_write(TransContext *txc, dout(15) << __func__ << " " << c->cid << " " << o->oid << " 0x" << std::hex << offset << "~" << length << std::dec << dendl; - _assign_nid(txc, o); - int r = _do_write(txc, c, o, offset, length, bl, fadvise_flags); - txc->write_onode(o); - + int r = 0; + if (offset + length >= OBJECT_MAX_SIZE) { + r = -E2BIG; + } else { + _assign_nid(txc, o); + r = _do_write(txc, c, o, offset, length, bl, fadvise_flags); + txc->write_onode(o); + } dout(10) << __func__ << " " << c->cid << " " << o->oid << " 0x" << std::hex << offset << "~" << length << std::dec << " = " << r << dendl; @@ -10351,8 +10355,13 @@ int BlueStore::_zero(TransContext *txc, dout(15) << __func__ << " " << c->cid << " " << o->oid << " 0x" << std::hex << offset << "~" << length << std::dec << dendl; - _assign_nid(txc, o); - int r = _do_zero(txc, c, o, offset, length); + int r = 0; + if (offset + length >= OBJECT_MAX_SIZE) { + r = -E2BIG; + } else { + _assign_nid(txc, o); + r = _do_zero(txc, c, o, offset, length); + } dout(10) << __func__ << " " << c->cid << " " << o->oid << " 0x" << std::hex << offset << "~" << length << std::dec << " = " << r << dendl; @@ -10427,7 +10436,7 @@ void BlueStore::_do_truncate( txc->write_onode(o); } -void BlueStore::_truncate(TransContext *txc, +int BlueStore::_truncate(TransContext *txc, CollectionRef& c, OnodeRef& o, uint64_t offset) @@ -10435,7 +10444,16 @@ void BlueStore::_truncate(TransContext *txc, dout(15) << __func__ << " " << c->cid << " " << o->oid << " 0x" << std::hex << offset << std::dec << dendl; - _do_truncate(txc, c, o, offset); + int r = 0; + if (offset >= OBJECT_MAX_SIZE) { + r = -E2BIG; + } else { + _do_truncate(txc, c, o, offset); + } + dout(10) << __func__ << " " << c->cid << " " << o->oid + << " 0x" << std::hex << offset << std::dec + << " = " << r << dendl; + return r; } int BlueStore::_do_remove( @@ -11018,6 +11036,11 @@ int BlueStore::_clone_range(TransContext *txc, << " to offset 0x" << dstoff << std::dec << dendl; int r = 0; + if (srcoff + length >= OBJECT_MAX_SIZE || + dstoff + length >= OBJECT_MAX_SIZE) { + r = -E2BIG; + goto out; + } if (srcoff + length > oldo->onode.size) { r = -EINVAL; goto out; diff --git a/src/os/bluestore/BlueStore.h b/src/os/bluestore/BlueStore.h index d7a1980320ebb..8c5eb4a02b4e5 100644 --- a/src/os/bluestore/BlueStore.h +++ b/src/os/bluestore/BlueStore.h @@ -2591,7 +2591,7 @@ private: OnodeRef o, uint64_t offset, set *maybe_unshared_blobs=0); - void _truncate(TransContext *txc, + int _truncate(TransContext *txc, CollectionRef& c, OnodeRef& o, uint64_t offset); -- 2.39.5