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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
# Filters for btrfs command output
. ./common/filter
# Some, but not all, commands emit "Btrfs <version>"
_filter_btrfs_version()
{
sed -e "s/^[Bb]trfs.*//g"
}
_filter_devid()
{
sed -e "s/\(devid\)\s\+[0-9]\+/\1 <DEVID>/g"
}
# If passed a number as first arg, filter that number of devices
# If passed a UUID as second arg, filter that exact UUID
_filter_btrfs_filesystem_show()
{
if [ ! -z $1 ]; then
NUMDEVS=$1
NUM_SUBST="<EXACTNUM>"
else
NUMDEVS="[0-9]\+"
NUM_SUBST="<NUM>"
fi
UUID=""
if [ ! -z $2 ]; then
UUID=$2
fi
# the uniq collapses all device lines into 1
_filter_uuid $UUID | _filter_scratch | _filter_scratch_pool | \
_filter_size | _filter_btrfs_version | _filter_devid | \
_filter_zero_size | \
sed -e "s/\(Total devices\) $NUMDEVS/\1 $NUM_SUBST/g" | \
uniq > $tmp.btrfs_filesystem_show
# The first two lines are Label/UUID and total devices
head -n 2 $tmp.btrfs_filesystem_show
# The remaining is the device list, first filter out the detailed
# missing device to the generic one.
# Then sort and uniq the result
tail -n +3 $tmp.btrfs_filesystem_show | \
sed -e "s/devid <DEVID> size 0 used 0 path MISSING/*** Some devices missing/" | \
sort -r | uniq
rm -f $tmp.btrfs_filesystem_show
}
# This eliminates all numbers, and shows only unique lines,
# to accomodate a varying nr. of devices.
# If given an argument, make sure we saw that many devices
# in total.
_filter_btrfs_device_stats()
{
if [ ! -z $1 ]; then
NUMDEVS=$1
UNIQ_OPT="-c"
else
NUMDEVS="thiswillnotmatch"
UNIQ_OPT=""
fi
_filter_scratch | _filter_scratch_pool | \
sed -e "s/[0-9]\+$/<NUM>/g" | sort | uniq $UNIQ_OPT | \
sed -e "s/ *$NUMDEVS /<NUMDEVS> /g"
}
_filter_transaction_commit() {
sed -e "/Transaction commit: none (default)/d" \
-e "s/Delete subvolume [0-9]\+ (.*commit):/Delete subvolume/g" \
-e "s/Delete subvolume (.*commit):/Delete subvolume/g"
}
_filter_btrfs_subvol_delete()
{
_filter_scratch | _filter_transaction_commit
}
_filter_btrfs_compress_property()
{
sed -e "s/compression=\(lzo\|zlib\|zstd\)/COMPRESSION=XXX/g"
}
# filter error messages from btrfs prop, optionally verify against $1
# recognized message(s):
# "object is not compatible with property: label"
# "invalid value for property:{, value}"
# "failed to {get,set} compression for $PATH[.:]: Invalid argument"
_filter_btrfs_prop_error()
{
if ! [ -z "$1" ]; then
sed -e "s#\(compatible with property\): $1#\1#" \
-e "s#^\(.*failed to [sg]et compression for $1\)[:.] \(.*\)#\1: \2#"
else
sed -e "s#^\(.*compatible with property\).*#\1#" \
-e "s#^\(.*invalid value for property\)[:.].*#\1#"
fi
}
# filter warning messages caused by "btrfs quota assign/remove" command.
# Since qgroup relationship change could cause qgroup inconsistency, it would
# either trigger a qgroup rescan, or warning message.
_filter_btrfs_qgroup_assign_warnings()
{
sed -e "/Quota data changed, rescan scheduled/d" \
-e "/quotas may be inconsistent, rescan needed/d"
}
# Long ago we found that attempting to clone inline extents resulted in hitting
# a BUG_ON() and then decided to not support such use cases by returning errno
# -EOPNOTSUPP to user space. Later on, clone/reflink became a VFS API too, since
# other filesystems (such as XFS) implemented this feature. After that we found
# one scenario of data corruption due to allowing cloning an EOF block into the
# middle of a file, and started to reject such scenario by returning the errno
# -EINVAL to user space (this affected both Btrfs and XFS). Such scenario often
# overlaps the detection of attempts to clone inline extents, since it is done
# early on based only on the arguments passed to the clone system call (and
# btrfs' specific ioctl) before processing the source file extents.
# So replace error messages related to errno -EOPNOTSUPP to be the same as the
# one we get from a -EINVAL errno.
_filter_btrfs_cloner_error()
{
sed -e "s/\(clone failed:\) Operation not supported/\1 Invalid argument/g"
}
# filter output of "btrfs inspect-internal dump-tree -t raid-stripe"
_filter_stripe_tree()
{
_filter_trailing_whitespace | _filter_btrfs_version |\
sed -E -e "s/leaf [0-9]+ items [0-9]+ free space [0-9]+ generation [0-9]+ owner RAID_STRIPE_TREE/leaf XXXXXXXXX items X free space XXXXX generation X owner RAID_STRIPE_TREE/" \
-e "s/leaf [0-9]+ flags 0x1\(WRITTEN\) backref revision 1/leaf XXXXXXXXX flags 0x1\(WRITTEN\) backref revision 1/" \
-e "/checksum stored [0-9a-f]+/d" \
-e "/checksum calced [0-9a-f]+/d" \
-e "s/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/<UUID>/" \
-e "s/item ([0-9]+) key \([0-9]+ RAID_STRIPE ([0-9]+)\) itemoff [0-9]+ itemsize ([0-9]+)/item \1 key \(XXXXXX RAID_STRIPE \2\) itemoff XXXXX itemsize \3/" \
-e "s/stripe ([0-9]+) devid ([0-9]+) physical [0-9]+/stripe \1 devid \2 physical XXXXXXXXX/" \
-e "s/total bytes [0-9]+/total bytes XXXXXXXX/" \
-e "s/bytes used [0-9]+/bytes used XXXXXX/"
}
# filter output of "btrfs balance start -[smd] convert
_filter_balance_convert()
{
_filter_scratch | \
sed -e "s/relocate [0-9]\+ out of [0-9]\+ chunks/relocate X out of X chunks/g"
}
# filter output of "btrfs device add"
_filter_device_add()
{
_filter_scratch | _filter_scratch_pool | \
sed -e "/Resetting device zones SCRATCH_DEV ([0-9]\+/d"
}
# make sure this script returns success
/bin/true
|