How to reset the folder metadata size without recreating the folder

ext4filesystems

I have a folder (watch) that got filled with a lot of temporary files by mistake. I've cleared out all of those files but the the folder is still 356 kB in size. In the past I've moved the folder out of the way, created a new folder with the same name, and copied all the files into it to get it back down to its former small size. Is there any way to get it back down to a small size without recreating the folder?

drwxr-xr-x 2 apache apache   4096 Nov 29  2014 details
drwxr-xr-x 2 apache apache 364544 Jan 21 17:24 watch
drwxr-xr-x 3 apache apache   4096 Jan 21 17:19 settings

watch has two small files: an .htaccess and an index.php.

I have an ext4 filesystem.

Best Answer

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/
Related Question