1#!/system/bin/sh
2
3#
4# Copyright (C) 2019 The Android Open Source Project
5#
6# Licensed under the Apache License, Version 2.0 (the "License");
7# you may not use this file except in compliance with the License.
8# You may obtain a copy of the License at
9#
10#      http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS,
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15# See the License for the specific language governing permissions and
16# limitations under the License.
17#
18
19# This script will run as an pre-checkpointing cleanup for mounting f2fs
20# with checkpoint=disable, so that the first mount after the reboot will
21# be faster. It is unnecessary to run if the device does not use userdata
22# checkpointing on F2FS.
23
24# TARGET_SLOT="${1}"
25STATUS_FD="${2}"
26
27SLEEP=5
28TIME=0
29MAX_TIME=1200
30
31# We only need to run this if we're using f2fs
32if [ ! -f /dev/sys/fs/by-name/userdata/gc_urgent ]; then
33  exit 0
34fi
35
36# Ideally we want to track unusable, as it directly measures what we
37# care about. If it's not present, dirty_segments is the best proxy.
38if [ -f /dev/sys/fs/by-name/userdata/unusable ]; then
39  UNUSABLE=1
40  METRIC="unusable blocks"
41  THRESHOLD=25000
42  read START < /dev/sys/fs/by-name/userdata/unusable
43else
44  METRIC="dirty segments"
45  THRESHOLD=200
46  read START < /dev/sys/fs/by-name/userdata/dirty_segments
47fi
48
49log -pi -t checkpoint_gc Turning on GC for userdata
50echo 2 > /dev/sys/fs/by-name/userdata/gc_urgent || exit 1
51
52
53CURRENT=${START}
54TODO=$((${START}-${THRESHOLD}))
55while [ ${CURRENT} -gt ${THRESHOLD} ]; do
56  log -pi -t checkpoint_gc ${METRIC}:${CURRENT} \(threshold:${THRESHOLD}\)
57  PROGRESS=`echo "(${START}-${CURRENT})/${TODO}"|bc -l`
58  if [[ $PROGRESS == -* ]]; then
59      PROGRESS=0
60  fi
61  print -u${STATUS_FD} "global_progress ${PROGRESS}"
62  if [ ${UNUSABLE} -eq 1 ]; then
63    read CURRENT < /dev/sys/fs/by-name/userdata/unusable
64  else
65    read CURRENT < /dev/sys/fs/by-name/userdata/dirty_segments
66  fi
67  sleep ${SLEEP}
68  TIME=$((${TIME}+${SLEEP}))
69  if [ ${TIME} -gt ${MAX_TIME} ]; then
70    log -pi -t checkpoint_gc Timed out with gc threshold not met.
71    break
72  fi
73  # In case someone turns it off behind our back
74  echo 2 > /dev/sys/fs/by-name/userdata/gc_urgent
75done
76
77# It could be a while before the system reboots for the update...
78# Leaving on low level GC can help ensure the boot for ota is faster
79# If powerhints decides to turn it off, we'll just rely on normal GC
80log -pi -t checkpoint_gc Leaving on low GC for userdata
81echo 2 > /dev/sys/fs/by-name/userdata/gc_urgent
82sync
83
84print -u${STATUS_FD} "global_progress 1.0"
85exit 0
86