From efde0fc0891e4f676cf4f48d0dbbc4867180a641 Mon Sep 17 00:00:00 2001
From: Daira Hopwood <daira@jacaranda.org>
Date: Thu, 5 Sep 2013 17:36:18 +0100
Subject: [PATCH] Fri Jun 22 16:43:54 BST 2012  david-sarah@jacaranda.org   *
 Change the maximum mutable share size to 69105 TB, and add a
 maximum-mutable-share-size field to the version announcement. Includes a
 test. refs #1778

---
 src/allmydata/mutable/layout.py    | 2 ++
 src/allmydata/storage/mutable.py   | 4 +++-
 src/allmydata/storage/server.py    | 2 ++
 src/allmydata/storage_client.py    | 1 +
 src/allmydata/test/test_storage.py | 7 +++++++
 5 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/src/allmydata/mutable/layout.py b/src/allmydata/mutable/layout.py
index 29d2fee1..47b894f1 100644
--- a/src/allmydata/mutable/layout.py
+++ b/src/allmydata/mutable/layout.py
@@ -70,6 +70,8 @@ HEADER_LENGTH = struct.calcsize(HEADER)
 OFFSETS = ">LLLLQQ"
 OFFSETS_LENGTH = struct.calcsize(OFFSETS)
 
+MAX_MUTABLE_SHARE_SIZE = 69105*1000*1000*1000*1000 # 69105 TB, kind of arbitrary
+
 
 # These are still used for some tests of SDMF files.
 def unpack_header(data):
diff --git a/src/allmydata/storage/mutable.py b/src/allmydata/storage/mutable.py
index dc057db4..1f95e515 100644
--- a/src/allmydata/storage/mutable.py
+++ b/src/allmydata/storage/mutable.py
@@ -7,6 +7,8 @@ from allmydata.util.hashutil import constant_time_compare
 from allmydata.storage.lease import LeaseInfo
 from allmydata.storage.common import UnknownMutableContainerVersionError, \
      DataTooLargeError
+from allmydata.mutable.layout import MAX_MUTABLE_SHARE_SIZE
+
 
 # the MutableShareFile is like the ShareFile, but used for mutable data. It
 # has a different layout. See docs/mutable.txt for more details.
@@ -48,7 +50,7 @@ class MutableShareFile:
     # like a sharefile.
     MAGIC = "Tahoe mutable container v1\n" + "\x75\x09\x44\x03\x8e"
     assert len(MAGIC) == 32
-    MAX_SIZE = 2*1000*1000*1000 # 2GB, kind of arbitrary
+    MAX_SIZE = MAX_MUTABLE_SHARE_SIZE
     # TODO: decide upon a policy for max share size
 
     def __init__(self, filename, parent=None):
diff --git a/src/allmydata/storage/server.py b/src/allmydata/storage/server.py
index 1f39c9ca..fd8ad8fa 100644
--- a/src/allmydata/storage/server.py
+++ b/src/allmydata/storage/server.py
@@ -13,6 +13,7 @@ _pyflakes_hush = [si_b2a, si_a2b, storage_index_to_dir] # re-exported
 from allmydata.storage.lease import LeaseInfo
 from allmydata.storage.mutable import MutableShareFile, EmptyShare, \
      create_mutable_sharefile
+from allmydata.mutable.layout import MAX_MUTABLE_SHARE_SIZE
 from allmydata.storage.immutable import ShareFile, BucketWriter, BucketReader
 from allmydata.storage.crawler import BucketCountingCrawler
 from allmydata.storage.expirer import LeaseCheckingCrawler
@@ -220,6 +221,7 @@ class StorageServer(service.MultiService, Referenceable):
 
         version = { "http://allmydata.org/tahoe/protocols/storage/v1" :
                     { "maximum-immutable-share-size": remaining_space,
+                      "maximum-mutable-share-size": MAX_MUTABLE_SHARE_SIZE,
                       "tolerates-immutable-read-overrun": True,
                       "delete-mutable-shares-with-zero-length-writev": True,
                       "fills-holes-with-zero-bytes": True,
diff --git a/src/allmydata/storage_client.py b/src/allmydata/storage_client.py
index 7a8ce0c4..b282dedd 100644
--- a/src/allmydata/storage_client.py
+++ b/src/allmydata/storage_client.py
@@ -167,6 +167,7 @@ class NativeStorageServer:
     VERSION_DEFAULTS = {
         "http://allmydata.org/tahoe/protocols/storage/v1" :
         { "maximum-immutable-share-size": 2**32,
+          "maximum-mutable-share-size": 2*1000*1000*1000, # maximum prior to v1.9.2
           "tolerates-immutable-read-overrun": False,
           "delete-mutable-shares-with-zero-length-writev": False,
           },
diff --git a/src/allmydata/test/test_storage.py b/src/allmydata/test/test_storage.py
index bf1e3fd5..cbfb988d 100644
--- a/src/allmydata/test/test_storage.py
+++ b/src/allmydata/test/test_storage.py
@@ -325,6 +325,13 @@ class Server(unittest.TestCase):
         sv1 = ver['http://allmydata.org/tahoe/protocols/storage/v1']
         self.failUnless(sv1.get('prevents-read-past-end-of-share-data'), sv1)
 
+    def test_declares_maximum_share_sizes(self):
+        ss = self.create("test_declares_maximum_share_sizes")
+        ver = ss.remote_get_version()
+        sv1 = ver['http://allmydata.org/tahoe/protocols/storage/v1']
+        self.failUnlessIn('maximum-immutable-share-size', sv1)
+        self.failUnlessIn('maximum-mutable-share-size', sv1)
+
     def allocate(self, ss, storage_index, sharenums, size, canary=None):
         renew_secret = hashutil.tagged_hash("blah", "%d" % self._lease_secret.next())
         cancel_secret = hashutil.tagged_hash("blah", "%d" % self._lease_secret.next())
-- 
2.45.2