-
Notifications
You must be signed in to change notification settings - Fork 0
/
xfsmap.sh
60 lines (54 loc) · 1.34 KB
/
xfsmap.sh
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
#!/usr/bin/env bash
# @Description:
# For a given file (or all files in a folder) located on an XFS partition,
# writes to stdout the pairs of block offsets (in units of 512-byte blocks),
# in the following format:
#
# x1_1
# x2_1
#
# x1_2
# x2_2
#
# ...
#
# @Requires:
# * xfs_bmap
#
# @Parameters:
# * <directory | file> : To print block mapping for.
[ $# -ne 1 ] && echo "Usage:" $0 "<directory | file>" && exit
XFS_BMAP=`which xfs_bmap`
[ -z $XFS_BMAP ] && echo "xfs_bmap could not be found" && exit 1
# Receive a file name and outputs the offsets (in units of 512-byte blocks)
# of the extents occupied on disk
print_offsets() {
$XFS_BMAP "$1" | tail -n +2 | while IFS='\n' read line; do
regex='[^[:space:]]+[[:space:]]+[^[:space:]]+[[:space:]]+([[:digit:]]+)\.\.([[:digit:]]+)'
if [[ "$line" =~ $regex ]]; then
echo "${BASH_REMATCH[1]}"
echo "${BASH_REMATCH[2]}"
echo
fi
done
}
# Walk a directory recursively and call print_offsets() for each file
walk_dir() {
ls -a "$1" | while IFS= read i; do
[ "$i" == ".." -o "$i" == "." ] && continue
entry="$1/$i"
if [ -d "$entry" ]; then
walk_dir "$entry"
elif [ -f "$entry" ]; then
print_offsets "$entry"
fi
done
}
# Main
if [ -d "$1" ]; then
walk_dir "$1"
elif [ -f "$1" ]; then
print_offsets "$1"
else
echo "Directory or file does not exist" && exit 1
fi