diff options
-rwxr-xr-x | btrfs-shrink | 37 |
1 files changed, 16 insertions, 21 deletions
diff --git a/btrfs-shrink b/btrfs-shrink index 1d059ff..a9bbee7 100755 --- a/btrfs-shrink +++ b/btrfs-shrink | |||
@@ -6,7 +6,7 @@ shrink() | |||
6 | { | 6 | { |
7 | local shrinkmegs=100 mountpoint="$1" | 7 | local shrinkmegs=100 mountpoint="$1" |
8 | while true; do | 8 | while true; do |
9 | while ! btrfs filesystem resize -${shrinkmegs}M "$mountpoint"/; do | 9 | while ! btrfs filesystem resize "${DEVICE_ID}:-${shrinkmegs}M" "$mountpoint"/; do |
10 | shrinkmegs=$((shrinkmegs - 10 )) | 10 | shrinkmegs=$((shrinkmegs - 10 )) |
11 | if [ $shrinkmegs -lt 10 ]; then | 11 | if [ $shrinkmegs -lt 10 ]; then |
12 | return | 12 | return |
@@ -18,47 +18,42 @@ shrink() | |||
18 | smart_shrink() | 18 | smart_shrink() |
19 | { | 19 | { |
20 | local min_dev_size mountpoint="$1" | 20 | local min_dev_size mountpoint="$1" |
21 | if min_dev_size=$(btrfs inspect-internal min-dev-size --id 1 "$mountpoint") && [ "$min_dev_size" ] | 21 | if min_dev_size=$(btrfs inspect-internal min-dev-size --id "$DEVICE_ID" "$mountpoint") && [ "$min_dev_size" ] |
22 | then | 22 | then |
23 | set -- $min_dev_size | 23 | set -- $min_dev_size |
24 | [ "$2" = bytes ] || die "Unexpected output from btrfs inspect-internal min-dev-size: '$min_dev_size'" | 24 | [ "$2" = bytes ] || die "Unexpected output from btrfs inspect-internal min-dev-size: '$min_dev_size'" |
25 | btrfs filesystem resize "$1" "$mountpoint" && return | 25 | btrfs filesystem resize "$DEVICE_ID:$1" "$mountpoint" && return |
26 | fi | 26 | fi |
27 | shrink "$mountpoint" | 27 | shrink "$mountpoint" |
28 | } | 28 | } |
29 | 29 | ||
30 | btrfs_truncate() | 30 | parse_btrfs_dev() |
31 | { | ||
32 | local img="$1" bytes | ||
33 | # 548044800/1176715264 bytes used | ||
34 | bytes=$(file "$img" | sed -ne 's?.*/\([0-9]*\) bytes used.*?\1?p') | ||
35 | if [ "$bytes" ]; then | ||
36 | truncate -s "$bytes" "$img" | ||
37 | fi | ||
38 | } | ||
39 | |||
40 | parse_btrfs_dev_size() | ||
41 | { | 31 | { |
42 | local dev="$1" | 32 | local dev="$1" |
43 | sed -n 's?.* size \([0-9]*\) .* path \([^ ]*\)$?\1 \2? p' | | 33 | sed -n 's?^ devid *\([0-9]*\) size \([0-9]*\) .* path \([^ ]*\)$?\1 \2 \3? p' | |
44 | while read size name | 34 | while read devid size name |
45 | do [ "$name" = "$dev" ] || continue | 35 | do [ "$name" = "$dev" ] || continue |
46 | echo $size | 36 | echo "$devid $size" |
47 | break | 37 | break |
48 | done | 38 | done |
49 | } | 39 | } |
50 | 40 | ||
51 | get_truncate_size() | 41 | get_btrfs_dev() |
52 | { | 42 | { |
53 | local imgfile="$1" mountpoint="$2" loop_dev dev_size | 43 | local imgfile="$1" mountpoint="$2" loop_dev dev_size |
44 | losetup -nj "$imgfile" >&2 | ||
54 | loop_dev=$(losetup -ONAME --raw -nj "$imgfile") | 45 | loop_dev=$(losetup -ONAME --raw -nj "$imgfile") |
55 | btrfs fi sh --raw "$mountpoint" | parse_btrfs_dev_size "$loop_dev" | 46 | ds=$(btrfs fi sh --raw "$mountpoint" | parse_btrfs_dev "$loop_dev") |
47 | [ "$ds" ] || return | ||
48 | DEVICE_ID=${ds% *} | ||
49 | DEVICE_SIZE=${ds#* } | ||
56 | } | 50 | } |
57 | 51 | ||
58 | main() | 52 | main() |
59 | { | 53 | { |
60 | [ "$(id -u)" = 0 ] || die 'you are not root' | 54 | [ "$(id -u)" = 0 ] || die 'you are not root' |
61 | if [ -d "$1" ]; then | 55 | if [ -d "$1" ]; then |
56 | exit 1 | ||
62 | mountpoint=$1 | 57 | mountpoint=$1 |
63 | mountpoint -q "$mountpoint" || die "not a mountpoint: $1" | 58 | mountpoint -q "$mountpoint" || die "not a mountpoint: $1" |
64 | smart_shrink "$mountpoint" | 59 | smart_shrink "$mountpoint" |
@@ -70,11 +65,11 @@ main() | |||
70 | result=$? | 65 | result=$? |
71 | 66 | ||
72 | if [ $result = 0 ]; then | 67 | if [ $result = 0 ]; then |
73 | smart_shrink "$mountpoint" | 68 | get_btrfs_dev "$1" "$mountpoint" && smart_shrink "$mountpoint" |
74 | result=$? | 69 | result=$? |
75 | if [ $result = 0 ] | 70 | if [ $result = 0 ] |
76 | then | 71 | then |
77 | truncate=$(get_truncate_size "$1" "$mountpoint") | 72 | get_btrfs_dev "$1" "$mountpoint" && truncate=$DEVICE_SIZE |
78 | fi | 73 | fi |
79 | umount "$mountpoint" | 74 | umount "$mountpoint" |
80 | fi | 75 | fi |