summaryrefslogtreecommitdiff
path: root/src/btrfs-utils/btrfs-shrink
blob: 229b4783a11b62efddcf99461546785899e14813 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#!/bin/sh

die() { printf "%s: Error: %s\n" "$0" "$*" >&2; exit 1; }

[ "$(id -u)" = 0 ] || die 'you are not root'

shrink()
{
    shrinkmegs=100
    while true; do
        while ! btrfs filesystem resize -${shrinkmegs}M "$mountpoint"/; do
            shrinkmegs=$((shrinkmegs - 10 ))
            if [ $shrinkmegs -lt 10 ]; then
                return
            fi
        done
    done
}

btrfs_truncate()
{
    local img="$1" bytes
#   548044800/1176715264 bytes used
    bytes=$(file "$img" | sed -ne 's?.*/\([0-9]*\) bytes used.*?\1?p')
    if [ "$bytes" ]; then
        truncate -s "$bytes" "$img"
    fi
}

main()
{
    if [ -d "$1" ]; then
        mountpoint -q "$1" || die "not a mountpoint: $1"
        shrink "$1"
    elif [ -f "$1" ]; then
        mkdir "$1".mnt.tmp
        mount -t btrfs "$1" "$1".mnt.tmp
        result=$?
        if [ $result = 0 ]; then
            shrink "$1".mnt.tmp
            result=$?
        fi
        umount "$1".mnt.tmp
        rmdir "$1".mnt.tmp
        btrfs_truncate "$1"
        return $result
    else
        die "not a file or directory: $1"
    fi
}

main "$@"