Delay deleting the blob after the last lease is released.

Bug: 159485704
Test: atest --test-mapping apex/blobstore
Change-Id: Iab153ae00107ee35705d7c17a3e51e7308e2e823
This commit is contained in:
Sudheer Shanka
2020-06-17 05:01:38 -07:00
parent 14849cfbd4
commit fbda8d7078
2 changed files with 40 additions and 3 deletions

View File

@@ -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();

View File

@@ -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,9 +489,21 @@ public class BlobStoreManagerService extends SystemService {
Slog.v(TAG, "Released lease on " + blobHandle
+ "; callingUid=" + callingUid + ", callingPackage=" + callingPackage);
}
if (blobMetadata.shouldBeDeleted(true /* respectLeaseWaitTime */)) {
deleteBlobLocked(blobMetadata);
userBlobs.remove(blobHandle);
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();
}