#!/system/bin/sh # # Copyright (C) 2019 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # This script will run as an pre-checkpointing cleanup for mounting f2fs # with checkpoint=disable, so that the first mount after the reboot will # be faster. It is unnecessary to run if the device does not use userdata # checkpointing on F2FS. # TARGET_SLOT="${1}" STATUS_FD="${2}" SLEEP=5 TIME=0 MAX_TIME=1200 # We only need to run this if we're using f2fs if [ ! -f /dev/sys/fs/by-name/userdata/gc_urgent ]; then exit 0 fi # Ideally we want to track unusable, as it directly measures what we # care about. If it's not present, dirty_segments is the best proxy. if [ -f /dev/sys/fs/by-name/userdata/unusable ]; then UNUSABLE=1 METRIC="unusable blocks" THRESHOLD=25000 read START < /dev/sys/fs/by-name/userdata/unusable else METRIC="dirty segments" THRESHOLD=200 read START < /dev/sys/fs/by-name/userdata/dirty_segments fi log -pi -t checkpoint_gc Turning on GC for userdata echo 2 > /dev/sys/fs/by-name/userdata/gc_urgent || exit 1 CURRENT=${START} TODO=$((${START}-${THRESHOLD})) while [ ${CURRENT} -gt ${THRESHOLD} ]; do log -pi -t checkpoint_gc ${METRIC}:${CURRENT} \(threshold:${THRESHOLD}\) PROGRESS=`echo "(${START}-${CURRENT})/${TODO}"|bc -l` if [[ $PROGRESS == -* ]]; then PROGRESS=0 fi print -u${STATUS_FD} "global_progress ${PROGRESS}" if [ ${UNUSABLE} -eq 1 ]; then read CURRENT < /dev/sys/fs/by-name/userdata/unusable else read CURRENT < /dev/sys/fs/by-name/userdata/dirty_segments fi sleep ${SLEEP} TIME=$((${TIME}+${SLEEP})) if [ ${TIME} -gt ${MAX_TIME} ]; then log -pi -t checkpoint_gc Timed out with gc threshold not met. break fi # In case someone turns it off behind our back echo 2 > /dev/sys/fs/by-name/userdata/gc_urgent done # It could be a while before the system reboots for the update... # Leaving on low level GC can help ensure the boot for ota is faster # If powerhints decides to turn it off, we'll just rely on normal GC log -pi -t checkpoint_gc Leaving on low GC for userdata echo 2 > /dev/sys/fs/by-name/userdata/gc_urgent sync print -u${STATUS_FD} "global_progress 1.0" exit 0