]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
os/bluestore: fail early on very large objects
authorSage Weil <sage@redhat.com>
Tue, 8 Aug 2017 22:12:57 +0000 (18:12 -0400)
committerSage Weil <sage@redhat.com>
Sat, 12 Aug 2017 02:56:07 +0000 (22:56 -0400)
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 <sage@redhat.com>
(cherry picked from commit 70f6760d3793d5a06e3c583608d220b354e65f84)

src/os/bluestore/BlueStore.cc
src/os/bluestore/BlueStore.h

index 4d5b989ffe2e8ec28ea0b8255ebcdd7385a589d0..9672e34b0c68a892601d1b0fb955c4f003f2b65b 100644 (file)
@@ -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;
index d7a1980320ebb16151784804f71124919f802977..8c5eb4a02b4e5de2b3c7a3f00d49f2a4633194eb 100644 (file)
@@ -2591,7 +2591,7 @@ private:
                   OnodeRef o,
                   uint64_t offset,
                   set<SharedBlob*> *maybe_unshared_blobs=0);
-  void _truncate(TransContext *txc,
+  int _truncate(TransContext *txc,
                CollectionRef& c,
                OnodeRef& o,
                uint64_t offset);