How do I reset the folder metadata size without recreating the folder?
e4fsck
supports -D
flag which seems to do what you want:
try to optimize all directories, either by reindexing them if the filesystem supports directory indexing, or by sorting and compressing directories for smaller directories, or for filesystems using traditional linear directories.
Of course, you'll need to unmount the filesystem to use fsck
, meaning downtime for your server.
You'll want to use the -f
option to make sure e4fsck
processes the file system even if clean.
Testing:
# truncate -s1G a; mkfs.ext4 -q ./a; mount ./a /mnt/1
# mkdir /mnt/1/x; touch /mnt/1/x/{1..4000}
# ls -ld /mnt/1/x
drwxr-xr-x 2 root root 69632 Nov 22 12:54 /mnt/1/x/
# rm -f /mnt/1/x/*
# ls -ld /mnt/1/x
drwxr-xr-x 2 root root 69632 Nov 22 12:55 /mnt/1/x/
# umount /mnt/1
# e2fsck -f -D ./a
e2fsck 1.43.3 (04-Sep-2016)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 3A: Optimizing directories
Pass 4: Checking reference counts
Pass 5: Checking group summary information
./a: ***** FILE SYSTEM WAS MODIFIED *****
./a: 12/65536 files (0.0% non-contiguous), 12956/262144 blocks
# mount ./a /mnt/1
# ls -ld /mnt/1/x
drwxr-xr-x 2 root root 4096 Nov 22 12:55 /mnt/1/x/
The answer to your question is for all practical purposes no. ext4 doesn't truncate directories, so you need to recreate them. You can improve on your previous technique by moving rather than copying the files to the new directory, this will probably be a lot faster and will only alter the ctime of the files.
If there are no subdirectories you could even use ln
to hard link the files into the new directory.
Linux has a renameat2
system call which can be used to swap two names, so again assuming that you have no subdirectories you could create your new directory, link the files from the old to the new and then swap the old and new directories. A quick google came up with https://gist.github.com/eatnumber1/f97ac7dad7b1f5a9721f as example code for calling renameat2.
Of course everything is only data so you could use something like debugfs
or even dd
to edit the data structures directly on the disk. I would not suggest going down this route for the sake of 360KB of space.