]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/commitdiff
upload: don't use servers which can't support the share size we need. This ought...
authorBrian Warner <warner@allmydata.com>
Sat, 22 Nov 2008 03:28:12 +0000 (20:28 -0700)
committerBrian Warner <warner@allmydata.com>
Sat, 22 Nov 2008 03:28:12 +0000 (20:28 -0700)
src/allmydata/immutable/upload.py
src/allmydata/test/test_upload.py

index 6ebcdc689db9f6025e562b0ae7f979b82e713856..3b653d8a3734062c786d52833f8a2555c272f05c 100644 (file)
@@ -164,8 +164,6 @@ class Tahoe2PeerSelector:
         if not peers:
             raise NotEnoughSharesError("client gave us zero peers")
 
-        # figure out how much space to ask for
-
         # this needed_hashes computation should mirror
         # Encoder.send_all_share_hash_trees. We use an IncompleteHashTree
         # (instead of a HashTree) because we don't require actual hashing
@@ -173,6 +171,24 @@ class Tahoe2PeerSelector:
         ht = hashtree.IncompleteHashTree(total_shares)
         num_share_hashes = len(ht.needed_hashes(0, include_leaf=True))
 
+        # figure out how much space to ask for
+        allocated_size = layout.allocated_size(share_size,
+                                               num_segments,
+                                               num_share_hashes,
+                                               EXTENSION_SIZE)
+        # filter the list of peers according to which ones can accomodate
+        # this request. This excludes older peers (which used a 4-byte size
+        # field) from getting large shares (for files larger than about
+        # 12GiB). See #439 for details.
+        def _get_maxsize(peer):
+            (peerid, conn) = peer
+            v1 = conn.version["http://allmydata.org/tahoe/protocols/storage/v1"]
+            return v1["maximum-immutable-share-size"]
+        peers = [peer for peer in peers
+                 if _get_maxsize(peer) >= allocated_size]
+        if not peers:
+            raise NotEnoughSharesError("no peers could accept an allocated_size of %d" % allocated_size)
+
         # decide upon the renewal/cancel secrets, to include them in the
         # allocat_buckets query.
         client_renewal_secret = client.get_renewal_secret()
index 6671b36149c1b2f38ad2e60f734af103568c212d..a9536b68d8b97f9d6356cb6891fdaf8f509fb3cd 100644 (file)
@@ -7,6 +7,7 @@ from twisted.python import log
 from twisted.internet import defer
 from foolscap import eventual
 
+import allmydata
 from allmydata import uri, monitor
 from allmydata.immutable import upload
 from allmydata.interfaces import IFileURI, FileTooLargeError, NotEnoughSharesError
@@ -81,6 +82,11 @@ class FakeStorageServer:
         self.mode = mode
         self.allocated = []
         self.queries = 0
+        self.version = { "http://allmydata.org/tahoe/protocols/storage/v1" :
+                         { "maximum-immutable-share-size": 2**32 },
+                         "application-version": str(allmydata.__version__),
+                         }
+
     def callRemote(self, methname, *args, **kwargs):
         def _call():
             meth = getattr(self, methname)