The file is able to grow to a large size because it does not know that device mapper devices have been removed and will never be created again. Neither the libblkid api nor blkid command line appear to even provide a facility for removing entries if you wanted to do so manually on device removal.
Combined with no (reasonable) bound on the size of the blkid.tab file, this causes the mount command to get slower over time. To make matters worse, the cost of reading the file in to memory is n-squared (which happens every time the mount command is run, even with "-h" for help!). Here is a shell script to exemplify mount issue: mount_test.sh
#!/bin/bash dd if=/dev/zero of=/tmp/store1 bs=1024 seek=2047 count=1 losetup /dev/loop/0 /tmp/store1 size=$(blockdev --getsize /dev/loop/0) mke2fs /dev/loop/0 for i in `seq 1 100000`; do echo 0 $size linear /dev/loop/0 0 | dmsetup create test$i echo -n $i >> mount.log 2>>mount.log /usr/bin/time -f " %e %U %S" mount /dev/mapper/test$i /mnt umount /dev/mapper/test$i dmsetup remove test$i done echo 'set terminal png; set output "mount_blkid.png"; set xlabel "iteration"; plot "mount.log" using 1:3 every 5 with linespoints title "mount time (s)"' | gnuplot
It should generate a mount.log file and a graph mount_blkid.png, like this one, that shows the n-squared performance degredation:
...and
I intended to run 100,000 iterations but even 16,000 took almost a day to run on a fast computer (2.8GHz P4). Simply removing the blkid.tab immediately restores the original performance at iteration zero.
Conclusions:
This issue has been posted to the linux-ext4 mailing list.