diff options
| author | Christopher Tate <ctate@google.com> | 2014-11-21 13:54:45 -0800 |
|---|---|---|
| committer | Dianne Hackborn <hackbod@google.com> | 2014-11-25 16:35:06 -0800 |
| commit | 7265abe77a76f848a316640b5da106e882bdbc8a (patch) | |
| tree | 61ebe6a0c55ea02a90fe4809a73430984a52f377 /core/java | |
| parent | 1586b9c33ed8429b8dbbe15ce3316a2d1a73977a (diff) | |
Be increasingly aggressive about fstrim if it isn't being run
The current heuristics depend on devices being alive at midnight+ in
order to run periodic background fstrim operations. This unfortunately
means that people who routinely turn their devices off overnight wind
up with their devices *never* running fstrim, and this causes major
performance and disk-life problems.
We now backstop this very-friendly schedule with an increasingly
aggressive one. If the device goes a defined time without a background
fstrim, we then force the fstrim at the next reboot. Once the
device hits the midnight+ idle fstrim request time, then we already
aggressively attempt to fstrim at the first available moment
thereafter, even if it's days/weeks later without a reboot.
'Available' here means charging + device idle. If the device never
becomes idle then we can't do much without rendering an in-use device
inoperable for some number of minutes -- but we have no evidence of
devices ever failing to run fstrim due to this usage pattern.
A new Settings.Global element (type 'long', called
"fstrim_mandatory_interval") is the source of the backstop time. If
this element is zero or negative, no mandatory boot-time fstrim will
ever be performed. If the element is not supplied on a given device,
the default backstop is 3 days.
Adds a new string to display in the upgrading dialog when doing
the fstrim. Note it is too late for this to be localized, but since
this operation can take a long time it is probably better to have
it show *something* even if not localized, rather than just sit there.
Bug 18486922
Change-Id: I5b265ca0a65570fb8931251aa1ac37b530635a2c
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/android/os/storage/IMountService.java | 63 | ||||
| -rw-r--r-- | core/java/android/provider/Settings.java | 7 |
2 files changed, 70 insertions, 0 deletions
diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java index cf407f401844..116110eba74d 100644 --- a/core/java/android/os/storage/IMountService.java +++ b/core/java/android/os/storage/IMountService.java @@ -856,6 +856,38 @@ public interface IMountService extends IInterface { } return _result; } + + @Override + public long lastMaintenance() throws RemoteException { + Parcel _data = Parcel.obtain(); + Parcel _reply = Parcel.obtain(); + long _result; + try { + _data.writeInterfaceToken(DESCRIPTOR); + mRemote.transact(Stub.TRANSACTION_lastMaintenance, _data, _reply, 0); + _reply.readException(); + _result = _reply.readLong(); + } finally { + _reply.recycle(); + _data.recycle(); + } + return _result; + } + + @Override + public void runMaintenance() throws RemoteException { + Parcel _data = Parcel.obtain(); + Parcel _reply = Parcel.obtain(); + try { + _data.writeInterfaceToken(DESCRIPTOR); + mRemote.transact(Stub.TRANSACTION_runMaintenance, _data, _reply, 0); + _reply.readException(); + } finally { + _reply.recycle(); + _data.recycle(); + } + return; + } } private static final String DESCRIPTOR = "IMountService"; @@ -942,6 +974,10 @@ public interface IMountService extends IInterface { static final int TRANSACTION_resizeSecureContainer = IBinder.FIRST_CALL_TRANSACTION + 40; + static final int TRANSACTION_lastMaintenance = IBinder.FIRST_CALL_TRANSACTION + 41; + + static final int TRANSACTION_runMaintenance = IBinder.FIRST_CALL_TRANSACTION + 42; + /** * Cast an IBinder object into an IMountService interface, generating a * proxy if needed. @@ -1347,6 +1383,19 @@ public interface IMountService extends IInterface { reply.writeInt(resultCode); return true; } + case TRANSACTION_lastMaintenance: { + data.enforceInterface(DESCRIPTOR); + long lastMaintenance = lastMaintenance(); + reply.writeNoException(); + reply.writeLong(lastMaintenance); + return true; + } + case TRANSACTION_runMaintenance: { + data.enforceInterface(DESCRIPTOR); + runMaintenance(); + reply.writeNoException(); + return true; + } } return super.onTransact(code, data, reply, flags); } @@ -1617,4 +1666,18 @@ public interface IMountService extends IInterface { public String getField(String field) throws RemoteException; public int resizeSecureContainer(String id, int sizeMb, String key) throws RemoteException; + + /** + * Report the time of the last maintenance operation such as fstrim. + * @return Timestamp of the last maintenance operation, in the + * System.currentTimeMillis() time base + * @throws RemoteException + */ + public long lastMaintenance() throws RemoteException; + + /** + * Kick off an immediate maintenance operation + * @throws RemoteException + */ + public void runMaintenance() throws RemoteException; } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 79e84d959109..73c7cc38af49 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -5544,6 +5544,13 @@ public final class Settings { public static final String PACKAGE_VERIFIER_INCLUDE_ADB = "verifier_verify_adb_installs"; /** + * Time since last fstrim (milliseconds) after which we force one to happen + * during device startup. If unset, the default is 3 days. + * @hide + */ + public static final String FSTRIM_MANDATORY_INTERVAL = "fstrim_mandatory_interval"; + + /** * The interval in milliseconds at which to check packet counts on the * mobile data interface when screen is on, to detect possible data * connection problems. |
