Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fbda8d70 authored by Sudheer Shanka's avatar Sudheer Shanka
Browse files

Delay deleting the blob after the last lease is released.

Bug: 159485704
Test: atest --test-mapping apex/blobstore
Change-Id: Iab153ae00107ee35705d7c17a3e51e7308e2e823
parent 14849cfb
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -131,6 +131,16 @@ class BlobStoreConfig {
        public static boolean USE_REVOCABLE_FD_FOR_READS =
                DEFAULT_USE_REVOCABLE_FD_FOR_READS;

        /**
         * Denotes how long before a blob is deleted, once the last lease on it is released.
         */
        public static final String KEY_DELETE_ON_LAST_LEASE_DELAY_MS =
                "delete_on_last_lease_delay_ms";
        public static final long DEFAULT_DELETE_ON_LAST_LEASE_DELAY_MS =
                TimeUnit.HOURS.toMillis(6);
        public static long DELETE_ON_LAST_LEASE_DELAY_MS =
                DEFAULT_DELETE_ON_LAST_LEASE_DELAY_MS;

        static void refresh(Properties properties) {
            if (!NAMESPACE_BLOBSTORE.equals(properties.getNamespace())) {
                return;
@@ -164,6 +174,10 @@ class BlobStoreConfig {
                        USE_REVOCABLE_FD_FOR_READS = properties.getBoolean(key,
                                DEFAULT_USE_REVOCABLE_FD_FOR_READS);
                        break;
                    case KEY_DELETE_ON_LAST_LEASE_DELAY_MS:
                        DELETE_ON_LAST_LEASE_DELAY_MS = properties.getLong(key,
                                DEFAULT_DELETE_ON_LAST_LEASE_DELAY_MS);
                        break;
                    default:
                        Slog.wtf(TAG, "Unknown key in device config properties: " + key);
                }
@@ -193,6 +207,9 @@ class BlobStoreConfig {
                    TimeUtils.formatDuration(DEFAULT_COMMIT_COOL_OFF_DURATION_MS)));
            fout.println(String.format(dumpFormat, KEY_USE_REVOCABLE_FD_FOR_READS,
                    USE_REVOCABLE_FD_FOR_READS, DEFAULT_USE_REVOCABLE_FD_FOR_READS));
            fout.println(String.format(dumpFormat, KEY_DELETE_ON_LAST_LEASE_DELAY_MS,
                    TimeUtils.formatDuration(DELETE_ON_LAST_LEASE_DELAY_MS),
                    TimeUtils.formatDuration(DEFAULT_DELETE_ON_LAST_LEASE_DELAY_MS)));
        }
    }

@@ -264,6 +281,13 @@ class BlobStoreConfig {
        return DeviceConfigProperties.USE_REVOCABLE_FD_FOR_READS;
    }

    /**
     * Returns the duration to wait before a blob is deleted, once the last lease on it is released.
     */
    public static long getDeletionOnLastLeaseDelayMs() {
        return DeviceConfigProperties.DELETE_ON_LAST_LEASE_DELAY_MS;
    }

    @Nullable
    public static File prepareBlobFile(long sessionId) {
        final File blobsDir = prepareBlobsDir();
+16 −3
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import static com.android.server.blob.BlobStoreConfig.LOGV;
import static com.android.server.blob.BlobStoreConfig.TAG;
import static com.android.server.blob.BlobStoreConfig.XML_VERSION_CURRENT;
import static com.android.server.blob.BlobStoreConfig.getAdjustedCommitTimeMs;
import static com.android.server.blob.BlobStoreConfig.getDeletionOnLastLeaseDelayMs;
import static com.android.server.blob.BlobStoreSession.STATE_ABANDONED;
import static com.android.server.blob.BlobStoreSession.STATE_COMMITTED;
import static com.android.server.blob.BlobStoreSession.STATE_VERIFIED_INVALID;
@@ -488,12 +489,24 @@ public class BlobStoreManagerService extends SystemService {
                Slog.v(TAG, "Released lease on " + blobHandle
                        + "; callingUid=" + callingUid + ", callingPackage=" + callingPackage);
            }
            if (!blobMetadata.hasLeases()) {
                mHandler.postDelayed(() -> {
                    synchronized (mBlobsLock) {
                        // Check if blobMetadata object is still valid. If it is not, then
                        // it means that it was already deleted and nothing else to do here.
                        if (!Objects.equals(userBlobs.get(blobHandle), blobMetadata)) {
                            return;
                        }
                        if (blobMetadata.shouldBeDeleted(true /* respectLeaseWaitTime */)) {
                            deleteBlobLocked(blobMetadata);
                            userBlobs.remove(blobHandle);
                        }
                        writeBlobsInfoAsync();
                    }
                }, getDeletionOnLastLeaseDelayMs());
            }
            writeBlobsInfoAsync();
        }
    }

    private long getRemainingLeaseQuotaBytesInternal(int callingUid, String callingPackage) {