From 4defc641a2da2b20898f15eb1c9234dcc1cbeb38 Mon Sep 17 00:00:00 2001 From: Jean-Paul Calderone Date: Wed, 20 Oct 2021 14:36:05 -0400 Subject: [PATCH] Have ShareFile only write a new lease if there is room for it StorageServer passes available space down so it can make the decision. ShareFile has to do it because `add_or_renew_lease` only *sometimes* adds a lease and only ShareFile knows when that is. --- src/allmydata/storage/immutable.py | 20 ++++++++++++++++++-- src/allmydata/storage/server.py | 2 +- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/allmydata/storage/immutable.py b/src/allmydata/storage/immutable.py index 55bcdda64..ad2d19f5f 100644 --- a/src/allmydata/storage/immutable.py +++ b/src/allmydata/storage/immutable.py @@ -21,6 +21,7 @@ from zope.interface import implementer from allmydata.interfaces import ( RIBucketWriter, RIBucketReader, ConflictingWriteError, DataTooLargeError, + NoSpace, ) from allmydata.util import base32, fileutil, log from allmydata.util.assertutil import precondition @@ -249,14 +250,29 @@ class ShareFile(object): return raise IndexError("unable to renew non-existent lease") - def add_or_renew_lease(self, lease_info): + def add_or_renew_lease(self, available_space, lease_info): + """ + Renew an existing lease if possible, otherwise allocate a new one. + + :param int available_space: The maximum number of bytes of storage to + commit in this operation. If more than this number of bytes is + required, raise ``NoSpace`` instead. + + :param LeaseInfo lease_info: The details of the lease to renew or add. + + :raise NoSpace: If more than ``available_space`` bytes is required to + complete the operation. In this case, no lease is added. + + :return: ``None`` + """ try: self.renew_lease(lease_info.renew_secret, lease_info.expiration_time) except IndexError: + if lease_info.immutable_size() > available_space: + raise NoSpace() self.add_lease(lease_info) - def cancel_lease(self, cancel_secret): """Remove a lease with the given cancel_secret. If the last lease is cancelled, the file will be removed. Return the number of bytes that diff --git a/src/allmydata/storage/server.py b/src/allmydata/storage/server.py index 21c612a59..66d9df998 100644 --- a/src/allmydata/storage/server.py +++ b/src/allmydata/storage/server.py @@ -618,7 +618,7 @@ class StorageServer(service.MultiService, Referenceable): :param LeaseInfo lease_info: The lease to put on the shares. """ for share in shares: - share.add_or_renew_lease(lease_info) + share.add_or_renew_lease(self.get_available_space(), lease_info) def slot_testv_and_readv_and_writev( # type: ignore # warner/foolscap#78 self,