From 2511fdffaad8e7bf08328a7363e0437bf32d355b Mon Sep 17 00:00:00 2001 From: Fabricio Duarte Date: Tue, 17 Mar 2026 16:17:12 -0300 Subject: [PATCH] Implement limit validations on updateBucket --- .../storage/object/BucketApiServiceImpl.java | 47 +++++++++++-------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/server/src/main/java/org/apache/cloudstack/storage/object/BucketApiServiceImpl.java b/server/src/main/java/org/apache/cloudstack/storage/object/BucketApiServiceImpl.java index 21f01991407..900cbdfac0d 100644 --- a/server/src/main/java/org/apache/cloudstack/storage/object/BucketApiServiceImpl.java +++ b/server/src/main/java/org/apache/cloudstack/storage/object/BucketApiServiceImpl.java @@ -272,16 +272,6 @@ public class BucketApiServiceImpl extends ManagerBase implements BucketApiServic _accountMgr.checkAccess(caller, null, true, bucket); ObjectStoreVO objectStoreVO = _objectStoreDao.findById(bucket.getObjectStoreId()); ObjectStoreEntity objectStore = (ObjectStoreEntity)_dataStoreMgr.getDataStore(objectStoreVO.getId(), DataStoreRole.Object); - Integer quota = cmd.getQuota(); - Integer quotaDelta = null; - - if (quota != null) { - quotaDelta = quota - bucket.getQuota(); - if (quotaDelta > 0) { - Account owner = _accountMgr.getActiveAccountById(bucket.getAccountId()); - resourceLimitManager.checkResourceLimit(owner, Resource.ResourceType.object_storage, (quotaDelta * Resource.ResourceType.bytesToGiB)); - } - } try { if (cmd.getEncryption() != null) { @@ -307,16 +297,8 @@ public class BucketApiServiceImpl extends ManagerBase implements BucketApiServic bucket.setPolicy(cmd.getPolicy()); } - if (cmd.getQuota() != null) { - objectStore.setQuota(bucketTO, cmd.getQuota()); - bucket.setQuota(cmd.getQuota()); - if (quotaDelta > 0) { - resourceLimitManager.incrementResourceCount(bucket.getAccountId(), Resource.ResourceType.object_storage, (quotaDelta * Resource.ResourceType.bytesToGiB)); - } else { - resourceLimitManager.decrementResourceCount(bucket.getAccountId(), Resource.ResourceType.object_storage, ((-quotaDelta) * Resource.ResourceType.bytesToGiB)); - } - _objectStoreDao.updateAllocatedSize(objectStoreVO, (quotaDelta * Resource.ResourceType.bytesToGiB)); - } + updateBucketQuota(cmd, bucket, objectStore, objectStoreVO, bucketTO); + _bucketDao.update(bucket.getId(), bucket); } catch (Exception e) { throw new CloudRuntimeException("Error while updating bucket: " +bucket.getName() +". "+e.getMessage()); @@ -325,6 +307,31 @@ public class BucketApiServiceImpl extends ManagerBase implements BucketApiServic return true; } + private void updateBucketQuota(UpdateBucketCmd cmd, BucketVO bucket, ObjectStoreEntity objectStore, ObjectStoreVO objectStoreVO, BucketTO bucketTO) throws ResourceAllocationException { + Integer quota = cmd.getQuota(); + if (quota == null) { + return; + } + + int quotaDelta = quota - bucket.getQuota(); + objectStore.setQuota(bucketTO, quota); + bucket.setQuota(quota); + + long diff = quotaDelta * Resource.ResourceType.bytesToGiB; + + if (quotaDelta < 0) { + resourceLimitManager.decrementResourceCount(bucket.getAccountId(), Resource.ResourceType.object_storage, Math.abs(diff)); + _objectStoreDao.updateAllocatedSize(objectStoreVO, diff); + return; + } + + Account owner = _accountMgr.getActiveAccountById(bucket.getAccountId()); + try (CheckedReservation objectStorageReservation = new CheckedReservation(owner, Resource.ResourceType.object_storage, diff, reservationDao, resourceLimitManager)) { + resourceLimitManager.incrementResourceCount(bucket.getAccountId(), Resource.ResourceType.object_storage, diff); + _objectStoreDao.updateAllocatedSize(objectStoreVO, diff); + } + } + public void getBucketUsage() { //ToDo track usage one last time when object store or bucket is removed List objectStores = _objectStoreDao.listObjectStores();